dma: Use SV enums in DMA components

Signed-off-by: Alex Forencich <alex@alexforencich.com>
This commit is contained in:
Alex Forencich
2026-02-27 20:12:47 -08:00
parent ee204d1665
commit 901606a64d
9 changed files with 156 additions and 121 deletions

View File

@@ -80,13 +80,14 @@ if (AXI_MAX_BURST_LEN_INT < 1 || AXI_MAX_BURST_LEN_INT > 256)
if (desc_req.SRC_ADDR_W < AXI_ADDR_W || desc_req.DST_ADDR_W < AXI_ADDR_W)
$fatal(0, "Error: Descriptor address width is not sufficient (instance %m)");
localparam logic [1:0]
typedef enum logic [1:0] {
AXI_RESP_OKAY = 2'b00,
AXI_RESP_EXOKAY = 2'b01,
AXI_RESP_SLVERR = 2'b10,
AXI_RESP_DECERR = 2'b11;
AXI_RESP_DECERR = 2'b11
} axi_resp_t;
localparam logic [3:0]
typedef enum logic [3:0] {
DMA_ERROR_NONE = 4'd0,
DMA_ERROR_TIMEOUT = 4'd1,
DMA_ERROR_PARITY = 4'd2,
@@ -97,20 +98,23 @@ localparam logic [3:0]
DMA_ERROR_PCIE_FLR = 4'd8,
DMA_ERROR_PCIE_CPL_POISONED = 4'd9,
DMA_ERROR_PCIE_CPL_STATUS_UR = 4'd10,
DMA_ERROR_PCIE_CPL_STATUS_CA = 4'd11;
DMA_ERROR_PCIE_CPL_STATUS_CA = 4'd11
} dma_error_t;
localparam logic [1:0]
READ_STATE_IDLE = 2'd0,
READ_STATE_START = 2'd1,
READ_STATE_REQ = 2'd2;
typedef enum logic [1:0] {
READ_STATE_IDLE,
READ_STATE_START,
READ_STATE_REQ
} read_state_t;
logic [1:0] read_state_reg = READ_STATE_IDLE, read_state_next;
read_state_t read_state_reg = READ_STATE_IDLE, read_state_next;
localparam logic [0:0]
AXI_STATE_IDLE = 1'd0,
AXI_STATE_WRITE = 1'd1;
typedef enum logic [0:0] {
AXI_STATE_IDLE,
AXI_STATE_WRITE
} axi_state_t;
logic [0:0] axi_state_reg = AXI_STATE_IDLE, axi_state_next;
axi_state_t axi_state_reg = AXI_STATE_IDLE, axi_state_next;
// datapath control signals
logic transfer_in_save;

View File

@@ -107,13 +107,14 @@ if (AXI_MAX_BURST_LEN < 1 || AXI_MAX_BURST_LEN > 256)
if (rd_desc_req.SRC_ADDR_W < AXI_ADDR_W)
$fatal(0, "Error: Descriptor address width is not sufficient (instance %m)");
localparam logic [1:0]
typedef enum logic [1:0] {
AXI_RESP_OKAY = 2'b00,
AXI_RESP_EXOKAY = 2'b01,
AXI_RESP_SLVERR = 2'b10,
AXI_RESP_DECERR = 2'b11;
AXI_RESP_DECERR = 2'b11
} axi_resp_t;
localparam logic [3:0]
typedef enum logic [3:0] {
DMA_ERROR_NONE = 4'd0,
DMA_ERROR_TIMEOUT = 4'd1,
DMA_ERROR_PARITY = 4'd2,
@@ -124,19 +125,22 @@ localparam logic [3:0]
DMA_ERROR_PCIE_FLR = 4'd8,
DMA_ERROR_PCIE_CPL_POISONED = 4'd9,
DMA_ERROR_PCIE_CPL_STATUS_UR = 4'd10,
DMA_ERROR_PCIE_CPL_STATUS_CA = 4'd11;
DMA_ERROR_PCIE_CPL_STATUS_CA = 4'd11
} dma_error_t;
localparam logic [0:0]
AXI_STATE_IDLE = 1'd0,
AXI_STATE_START = 1'd1;
typedef enum logic [0:0] {
AXI_STATE_IDLE,
AXI_STATE_START
} axi_state_t;
logic [0:0] axi_state_reg = AXI_STATE_IDLE, axi_state_next;
axi_state_t axi_state_reg = AXI_STATE_IDLE, axi_state_next;
localparam logic [0:0]
AXIS_STATE_IDLE = 1'd0,
AXIS_STATE_READ = 1'd1;
typedef enum logic [0:0] {
AXIS_STATE_IDLE,
AXIS_STATE_READ
} axis_state_t;
logic [0:0] axis_state_reg = AXIS_STATE_IDLE, axis_state_next;
axis_state_t axis_state_reg = AXIS_STATE_IDLE, axis_state_next;
// datapath control signals
logic transfer_in_save;

View File

@@ -109,13 +109,14 @@ if (AXI_MAX_BURST_LEN < 1 || AXI_MAX_BURST_LEN > 256)
if (wr_desc_req.DST_ADDR_W < AXI_ADDR_W)
$fatal(0, "Error: Descriptor address width is not sufficient (instance %m)");
localparam logic [1:0]
typedef enum logic [1:0] {
AXI_RESP_OKAY = 2'b00,
AXI_RESP_EXOKAY = 2'b01,
AXI_RESP_SLVERR = 2'b10,
AXI_RESP_DECERR = 2'b11;
AXI_RESP_DECERR = 2'b11
} axi_resp_t;
localparam logic [3:0]
typedef enum logic [3:0] {
DMA_ERROR_NONE = 4'd0,
DMA_ERROR_TIMEOUT = 4'd1,
DMA_ERROR_PARITY = 4'd2,
@@ -126,16 +127,18 @@ localparam logic [3:0]
DMA_ERROR_PCIE_FLR = 4'd8,
DMA_ERROR_PCIE_CPL_POISONED = 4'd9,
DMA_ERROR_PCIE_CPL_STATUS_UR = 4'd10,
DMA_ERROR_PCIE_CPL_STATUS_CA = 4'd11;
DMA_ERROR_PCIE_CPL_STATUS_CA = 4'd11
} dma_error_t;
localparam logic [2:0]
STATE_IDLE = 3'd0,
STATE_START = 3'd1,
STATE_WRITE = 3'd2,
STATE_FINISH_BURST = 3'd3,
STATE_DROP_DATA = 3'd4;
typedef enum logic [2:0] {
STATE_IDLE,
STATE_START,
STATE_WRITE,
STATE_FINISH_BURST,
STATE_DROP_DATA
} state_t;
logic [2:0] state_reg = STATE_IDLE, state_next;
state_t state_reg = STATE_IDLE, state_next;
// datapath control signals
logic transfer_in_save;

View File

@@ -110,12 +110,13 @@ if (AXIS_DATA_W*2**$clog2(PART_COUNT) != RAM_SEGS*RAM_SEG_DATA_W)
if (desc_req.DST_ADDR_W < RAM_ADDR_W)
$fatal(0, "Error: Descriptor address width is not sufficient (instance %m)");
localparam logic [1:0]
STATE_IDLE = 2'd0,
STATE_WRITE = 2'd1,
STATE_DROP_DATA = 2'd2;
typedef enum logic [1:0] {
STATE_IDLE,
STATE_WRITE,
STATE_DROP_DATA
} state_t;
logic [1:0] state_reg = STATE_IDLE, state_next;
state_t state_reg = STATE_IDLE, state_next;
logic [OFFSET_W:0] cycle_size;

View File

@@ -109,17 +109,19 @@ if (AXIS_DATA_W*2**$clog2(PART_COUNT) != RAM_SEGS*RAM_SEG_DATA_W)
if (desc_req.SRC_ADDR_W < RAM_ADDR_W)
$fatal(0, "Error: Descriptor address width is not sufficient (instance %m)");
localparam logic [0:0]
READ_STATE_IDLE = 1'd0,
READ_STATE_READ = 1'd1;
typedef enum logic [0:0] {
READ_STATE_IDLE,
READ_STATE_READ
} read_state_t;
logic [0:0] read_state_reg = READ_STATE_IDLE, read_state_next;
read_state_t read_state_reg = READ_STATE_IDLE, read_state_next;
localparam logic [0:0]
AXIS_STATE_IDLE = 1'd0,
AXIS_STATE_READ = 1'd1;
typedef enum logic [0:0] {
AXIS_STATE_IDLE,
AXIS_STATE_READ
} axis_state_t;
logic [0:0] axis_state_reg = AXIS_STATE_IDLE, axis_state_next;
axis_state_t axis_state_reg = AXIS_STATE_IDLE, axis_state_next;
// datapath control signals
logic axis_cmd_ready;

View File

@@ -142,13 +142,14 @@ if (OP_TBL_SIZE > 2**AXI_ID_W)
if (rd_desc_req.SRC_ADDR_W < AXI_ADDR_W || rd_desc_req.DST_ADDR_W < RAM_ADDR_W)
$fatal(0, "Error: Descriptor address width is not sufficient (instance %m)");
localparam logic [1:0]
typedef enum logic [1:0] {
AXI_RESP_OKAY = 2'b00,
AXI_RESP_EXOKAY = 2'b01,
AXI_RESP_SLVERR = 2'b10,
AXI_RESP_DECERR = 2'b11;
AXI_RESP_DECERR = 2'b11
} axi_resp_t;
localparam logic [3:0]
typedef enum logic [3:0] {
DMA_ERROR_NONE = 4'd0,
DMA_ERROR_TIMEOUT = 4'd1,
DMA_ERROR_PARITY = 4'd2,
@@ -159,19 +160,22 @@ localparam logic [3:0]
DMA_ERROR_PCIE_FLR = 4'd8,
DMA_ERROR_PCIE_CPL_POISONED = 4'd9,
DMA_ERROR_PCIE_CPL_STATUS_UR = 4'd10,
DMA_ERROR_PCIE_CPL_STATUS_CA = 4'd11;
DMA_ERROR_PCIE_CPL_STATUS_CA = 4'd11
} dma_error_t;
localparam logic [0:0]
REQ_STATE_IDLE = 1'd0,
REQ_STATE_START = 1'd1;
typedef enum logic [0:0] {
REQ_STATE_IDLE,
REQ_STATE_START
} req_state_t;
logic [0:0] req_state_reg = REQ_STATE_IDLE, req_state_next;
req_state_t req_state_reg = REQ_STATE_IDLE, req_state_next;
localparam logic [0:0]
AXI_STATE_IDLE = 1'd0,
AXI_STATE_WRITE = 1'd1;
typedef enum logic [0:0] {
AXI_STATE_IDLE,
AXI_STATE_WRITE
} axi_state_t;
logic [0:0] axi_state_reg = AXI_STATE_IDLE, axi_state_next;
axi_state_t axi_state_reg = AXI_STATE_IDLE, axi_state_next;
logic [AXI_ADDR_W-1:0] req_axi_addr_reg = '0, req_axi_addr_next;
logic [RAM_SEL_W-1:0] req_ram_sel_reg = '0, req_ram_sel_next;

View File

@@ -146,13 +146,14 @@ if (IMM_EN && IMM_W > AXI_DATA_W)
if (wr_desc_req.SRC_ADDR_W < RAM_ADDR_W || wr_desc_req.DST_ADDR_W < AXI_ADDR_W)
$fatal(0, "Error: Descriptor address width is not sufficient (instance %m)");
localparam logic [1:0]
typedef enum logic [1:0] {
AXI_RESP_OKAY = 2'b00,
AXI_RESP_EXOKAY = 2'b01,
AXI_RESP_SLVERR = 2'b10,
AXI_RESP_DECERR = 2'b11;
AXI_RESP_DECERR = 2'b11
} axi_resp_t;
localparam logic [3:0]
typedef enum logic [3:0] {
DMA_ERROR_NONE = 4'd0,
DMA_ERROR_TIMEOUT = 4'd1,
DMA_ERROR_PARITY = 4'd2,
@@ -163,25 +164,29 @@ localparam logic [3:0]
DMA_ERROR_PCIE_FLR = 4'd8,
DMA_ERROR_PCIE_CPL_POISONED = 4'd9,
DMA_ERROR_PCIE_CPL_STATUS_UR = 4'd10,
DMA_ERROR_PCIE_CPL_STATUS_CA = 4'd11;
DMA_ERROR_PCIE_CPL_STATUS_CA = 4'd11
} dma_error_t;
localparam logic [0:0]
REQ_STATE_IDLE = 1'd0,
REQ_STATE_START = 1'd1;
typedef enum logic [0:0] {
REQ_STATE_IDLE,
REQ_STATE_START
} req_state_t;
logic [0:0] req_state_reg = REQ_STATE_IDLE, req_state_next;
req_state_t req_state_reg = REQ_STATE_IDLE, req_state_next;
localparam logic [0:0]
READ_STATE_IDLE = 1'd0,
READ_STATE_READ = 1'd1;
typedef enum logic [0:0] {
READ_STATE_IDLE,
READ_STATE_READ
} read_state_t;
logic [0:0] read_state_reg = READ_STATE_IDLE, read_state_next;
read_state_t read_state_reg = READ_STATE_IDLE, read_state_next;
localparam logic [0:0]
AXI_STATE_IDLE = 1'd0,
AXI_STATE_TRANSFER = 1'd1;
typedef enum logic [0:0] {
AXI_STATE_IDLE,
AXI_STATE_TRANSFER
} axi_state_t;
logic [0:0] axi_state_reg = AXI_STATE_IDLE, axi_state_next;
axi_state_t axi_state_reg = AXI_STATE_IDLE, axi_state_next;
// datapath control signals
logic mask_fifo_we;

View File

@@ -213,7 +213,7 @@ if (PCIE_TAG_CNT < 1 || PCIE_TAG_CNT > 256)
if (rd_desc_req.SRC_ADDR_W < PCIE_ADDR_W || rd_desc_req.DST_ADDR_W < RAM_ADDR_W)
$fatal(0, "Error: Descriptor address width is not sufficient (instance %m)");
localparam logic [3:0]
typedef enum logic [3:0] {
REQ_MEM_READ = 4'b0000,
REQ_MEM_WRITE = 4'b0001,
REQ_IO_READ = 4'b0010,
@@ -221,22 +221,24 @@ localparam logic [3:0]
REQ_MEM_FETCH_ADD = 4'b0100,
REQ_MEM_SWAP = 4'b0101,
REQ_MEM_CAS = 4'b0110,
REQ_MEM_RD_LOCKED = 4'b0111,
REQ_CFG_RD_0 = 4'b1000,
REQ_CFG_RD_1 = 4'b1001,
REQ_MEM_READ_LOCKED = 4'b0111,
REQ_CFG_READ_0 = 4'b1000,
REQ_CFG_READ_1 = 4'b1001,
REQ_CFG_WRITE_0 = 4'b1010,
REQ_CFG_WRITE_1 = 4'b1011,
REQ_MSG = 4'b1100,
REQ_MSG_VENDOR = 4'b1101,
REQ_MSG_ATS = 4'b1110;
REQ_MSG_ATS = 4'b1110
} req_type_t;
localparam logic [2:0]
typedef enum logic [2:0] {
CPL_STATUS_SC = 3'b000, // successful completion
CPL_STATUS_UR = 3'b001, // unsupported request
CPL_STATUS_CRS = 3'b010, // configuration request retry status
CPL_STATUS_CA = 3'b100; // completer abort
CPL_STATUS_CA = 3'b100 // completer abort
} cpl_status_t;
localparam logic [3:0]
typedef enum logic [3:0] {
RC_ERR_NORMAL_TERM = 4'b0000,
RC_ERR_POISONED = 4'b0001,
RC_ERR_BAD_STATUS = 4'b0010,
@@ -245,9 +247,10 @@ localparam logic [3:0]
RC_ERR_INVALID_ADDR = 4'b0101,
RC_ERR_INVALID_TAG = 4'b0110,
RC_ERR_TIMEOUT = 4'b1001,
RC_ERR_FLR = 4'b1000;
RC_ERR_FLR = 4'b1000
} rc_err_t;
localparam logic [3:0]
typedef enum logic [3:0] {
DMA_ERR_NONE = 4'd0,
DMA_ERR_TIMEOUT = 4'd1,
DMA_ERR_PARITY = 4'd2,
@@ -258,22 +261,25 @@ localparam logic [3:0]
DMA_ERR_PCIE_FLR = 4'd8,
DMA_ERR_PCIE_CPL_POISONED = 4'd9,
DMA_ERR_PCIE_CPL_STATUS_UR = 4'd10,
DMA_ERR_PCIE_CPL_STATUS_CA = 4'd11;
DMA_ERR_PCIE_CPL_STATUS_CA = 4'd11
} dma_err_t;
localparam logic [1:0]
REQ_STATE_IDLE = 2'd0,
REQ_STATE_START = 2'd1,
REQ_STATE_HEADER = 2'd2;
typedef enum logic [1:0] {
REQ_STATE_IDLE,
REQ_STATE_START,
REQ_STATE_HEADER
} req_state_t;
logic [1:0] req_state_reg = REQ_STATE_IDLE, req_state_next;
req_state_t req_state_reg = REQ_STATE_IDLE, req_state_next;
localparam logic [1:0]
typedef enum logic [1:0] {
TLP_STATE_IDLE = 2'd0,
TLP_STATE_HEADER = 2'd1,
TLP_STATE_WRITE = 2'd2,
TLP_STATE_WAIT_END = 2'd3;
TLP_STATE_WAIT_END = 2'd3
} tlp_state_t;
logic [1:0] tlp_state_reg = TLP_STATE_IDLE, tlp_state_next;
tlp_state_t tlp_state_reg = TLP_STATE_IDLE, tlp_state_next;
// datapath control signals
logic last_cycle;

View File

@@ -182,7 +182,7 @@ if (2**$clog2(RAM_BYTE_LANES) != RAM_BYTE_LANES)
if (wr_desc_req.SRC_ADDR_W < RAM_ADDR_W || wr_desc_req.DST_ADDR_W < PCIE_ADDR_W)
$fatal(0, "Error: Descriptor address width is not sufficient (instance %m)");
localparam logic [3:0]
typedef enum logic [3:0] {
REQ_MEM_READ = 4'b0000,
REQ_MEM_WRITE = 4'b0001,
REQ_IO_READ = 4'b0010,
@@ -193,44 +193,50 @@ localparam logic [3:0]
REQ_MEM_READ_LOCKED = 4'b0111,
REQ_CFG_READ_0 = 4'b1000,
REQ_CFG_READ_1 = 4'b1001,
REQ_CFG_WR_0 = 4'b1010,
REQ_CFG_WR_1 = 4'b1011,
REQ_CFG_WRITE_0 = 4'b1010,
REQ_CFG_WRITE_1 = 4'b1011,
REQ_MSG = 4'b1100,
REQ_MSG_VENDOR = 4'b1101,
REQ_MSG_ATS = 4'b1110;
REQ_MSG_ATS = 4'b1110
} req_type_t;
localparam logic [2:0]
typedef enum logic [2:0] {
CPL_STATUS_SC = 3'b000, // successful completion
CPL_STATUS_UR = 3'b001, // unsupported request
CPL_STATUS_CRS = 3'b010, // configuration request retry status
CPL_STATUS_CA = 3'b100; // completer abort
CPL_STATUS_CA = 3'b100 // completer abort
} cpl_status_t;
localparam logic [0:0]
REQ_STATE_IDLE = 1'd0,
REQ_STATE_START = 1'd1;
typedef enum logic [0:0] {
REQ_STATE_IDLE,
REQ_STATE_START
} req_state_t;
logic [0:0] req_state_reg = REQ_STATE_IDLE, req_state_next;
req_state_t req_state_reg = REQ_STATE_IDLE, req_state_next;
localparam logic [0:0]
READ_STATE_IDLE = 1'd0,
READ_STATE_READ = 1'd1;
typedef enum logic [0:0] {
READ_STATE_IDLE,
READ_STATE_READ
} read_state_t;
logic [0:0] read_state_reg = READ_STATE_IDLE, read_state_next;
read_state_t read_state_reg = READ_STATE_IDLE, read_state_next;
localparam logic [1:0]
TLP_STATE_IDLE = 2'd0,
TLP_STATE_HEADER = 2'd1,
TLP_STATE_TRANSFER = 2'd2;
typedef enum logic [1:0] {
TLP_STATE_IDLE,
TLP_STATE_HEADER,
TLP_STATE_TRANSFER
} tlp_state_t;
logic [1:0] tlp_state_reg = TLP_STATE_IDLE, tlp_state_next;
tlp_state_t tlp_state_reg = TLP_STATE_IDLE, tlp_state_next;
localparam logic [1:0]
TLP_OUTPUT_STATE_IDLE = 2'd0,
TLP_OUTPUT_STATE_HEADER = 2'd1,
TLP_OUTPUT_STATE_PAYLOAD = 2'd2,
TLP_OUTPUT_STATE_PASSTHROUGH = 2'd3;
typedef enum logic [1:0] {
TLP_OUTPUT_STATE_IDLE,
TLP_OUTPUT_STATE_HEADER,
TLP_OUTPUT_STATE_PAYLOAD,
TLP_OUTPUT_STATE_PASSTHROUGH
} tlp_output_state_t;
logic [1:0] tlp_output_state_reg = TLP_OUTPUT_STATE_IDLE, tlp_output_state_next;
tlp_output_state_t tlp_output_state_reg = TLP_OUTPUT_STATE_IDLE, tlp_output_state_next;
// datapath control signals
logic mask_fifo_we;