From d7c826406dc4f70483339a6ec81c7bdbb560865f Mon Sep 17 00:00:00 2001 From: otroubi Date: Thu, 3 Sep 2026 15:52:16 +0300 Subject: [PATCH] Intermediate tests and updates to the AXI modules. --- external/external/rtl_libs/.gitignore | 4 + external/external/rtl_libs/.gitmodules | 3 + external/external/rtl_libs/README.md | 3 + .../rtl_libs/axi/axi_reg/axi4l_reg_map.sv | 213 ++++ .../axi/axi_reg/axi4l_reg_map_example.sv | 67 ++ .../axi/axi_reg/axi4l_reg_map_example_pkg.sv | 68 ++ .../axi/axi_reg/dma_axil_reg_map_pkg.sv | 64 + .../rtl_libs/axi/rtl/axi4_flat_to_if.sv | 97 ++ .../rtl_libs/axi/rtl/axi4_if_to_flat.sv | 97 ++ .../rtl_libs/axi/rtl/axi4l_flat_to_if.sv | 58 + .../rtl_libs/axi/rtl/axi4l_if_to_flat.sv | 56 + .../rtl_libs/axi/rtl/axi4l_reg_map.sv | 189 +++ .../rtl_libs/axi/rtl/axi4l_to_axi4.sv | 59 + .../axi/rtl/axi_crossbar_core_wrapper.sv | 654 +++++++++++ .../rtl_libs/axi/rtl/axi_crossbar_wrapper.sv | 1045 +++++++++++++++++ .../rtl_libs/axi/rtl/axi_dma_compat.sv | 331 ++++++ .../rtl_libs/axi/rtl/axi_dma_desc_if.sv | 109 ++ .../rtl_libs/axi/rtl/axi_dma_if_wrapper.sv | 643 ++++++++++ .../rtl_libs/axi/rtl/axi_dma_wrapper.sv | 453 +++++++ external/external/rtl_libs/axi/rtl/axi_if.sv | 43 + external/external/rtl_libs/axi/rtl/axi_pkg.sv | 140 +++ .../rtl_libs/axi/rtl/axi_ram_wrapper.sv | 146 +++ .../rtl_libs/axi/rtl/axil_cdc_wrapper.sv | 165 +++ .../rtl_libs/axi/rtl/axis_flat_to_if.sv | 30 + external/external/rtl_libs/axi/rtl/axis_if.sv | 47 + .../rtl_libs/axi/rtl/axis_if_to_flat.sv | 30 + .../axi/tb/axi_dma_axis_compat/Makefile | 84 ++ .../tb_axi_dma_axis_compat.sv | 431 +++++++ .../test_axi_dma_axis_compat.py | 317 +++++ .../rtl_libs/axi/tb/axi_dma_wrapper/Makefile | 84 ++ .../tb/axi_dma_wrapper/tb_axi_dma_wrapper.sv | 429 +++++++ .../axi_dma_wrapper/test_axi_dma_wrapper.py | 392 +++++++ .../rtl_libs/axi/tb/axil_reg_cocotb/Makefile | 34 + .../tb/axil_reg_cocotb/tb_axi4l_reg_map.sv | 165 +++ .../tb/axil_reg_cocotb/test_axi4l_reg_map.py | 310 +++++ .../axis_loopback.sv | 13 + 36 files changed, 7073 insertions(+) create mode 100644 external/external/rtl_libs/.gitignore create mode 100644 external/external/rtl_libs/.gitmodules create mode 100644 external/external/rtl_libs/README.md create mode 100644 external/external/rtl_libs/axi/axi_reg/axi4l_reg_map.sv create mode 100644 external/external/rtl_libs/axi/axi_reg/axi4l_reg_map_example.sv create mode 100644 external/external/rtl_libs/axi/axi_reg/axi4l_reg_map_example_pkg.sv create mode 100644 external/external/rtl_libs/axi/axi_reg/dma_axil_reg_map_pkg.sv create mode 100644 external/external/rtl_libs/axi/rtl/axi4_flat_to_if.sv create mode 100644 external/external/rtl_libs/axi/rtl/axi4_if_to_flat.sv create mode 100644 external/external/rtl_libs/axi/rtl/axi4l_flat_to_if.sv create mode 100644 external/external/rtl_libs/axi/rtl/axi4l_if_to_flat.sv create mode 100644 external/external/rtl_libs/axi/rtl/axi4l_reg_map.sv create mode 100644 external/external/rtl_libs/axi/rtl/axi4l_to_axi4.sv create mode 100644 external/external/rtl_libs/axi/rtl/axi_crossbar_core_wrapper.sv create mode 100644 external/external/rtl_libs/axi/rtl/axi_crossbar_wrapper.sv create mode 100644 external/external/rtl_libs/axi/rtl/axi_dma_compat.sv create mode 100644 external/external/rtl_libs/axi/rtl/axi_dma_desc_if.sv create mode 100644 external/external/rtl_libs/axi/rtl/axi_dma_if_wrapper.sv create mode 100644 external/external/rtl_libs/axi/rtl/axi_dma_wrapper.sv create mode 100644 external/external/rtl_libs/axi/rtl/axi_if.sv create mode 100644 external/external/rtl_libs/axi/rtl/axi_pkg.sv create mode 100644 external/external/rtl_libs/axi/rtl/axi_ram_wrapper.sv create mode 100644 external/external/rtl_libs/axi/rtl/axil_cdc_wrapper.sv create mode 100644 external/external/rtl_libs/axi/rtl/axis_flat_to_if.sv create mode 100644 external/external/rtl_libs/axi/rtl/axis_if.sv create mode 100644 external/external/rtl_libs/axi/rtl/axis_if_to_flat.sv create mode 100644 external/external/rtl_libs/axi/tb/axi_dma_axis_compat/Makefile create mode 100644 external/external/rtl_libs/axi/tb/axi_dma_axis_compat/tb_axi_dma_axis_compat.sv create mode 100644 external/external/rtl_libs/axi/tb/axi_dma_axis_compat/test_axi_dma_axis_compat.py create mode 100644 external/external/rtl_libs/axi/tb/axi_dma_wrapper/Makefile create mode 100644 external/external/rtl_libs/axi/tb/axi_dma_wrapper/tb_axi_dma_wrapper.sv create mode 100644 external/external/rtl_libs/axi/tb/axi_dma_wrapper/test_axi_dma_wrapper.py create mode 100644 external/external/rtl_libs/axi/tb/axil_reg_cocotb/Makefile create mode 100644 external/external/rtl_libs/axi/tb/axil_reg_cocotb/tb_axi4l_reg_map.sv create mode 100644 external/external/rtl_libs/axi/tb/axil_reg_cocotb/test_axi4l_reg_map.py create mode 100644 external/external/rtl_libs/axi/tb/axis_cocotb_loopback_test/axis_loopback.sv diff --git a/external/external/rtl_libs/.gitignore b/external/external/rtl_libs/.gitignore new file mode 100644 index 0000000..9506a65 --- /dev/null +++ b/external/external/rtl_libs/.gitignore @@ -0,0 +1,4 @@ +**sim_build** +**pycache** +dump.vcd +results.xml \ No newline at end of file diff --git a/external/external/rtl_libs/.gitmodules b/external/external/rtl_libs/.gitmodules new file mode 100644 index 0000000..1e856fb --- /dev/null +++ b/external/external/rtl_libs/.gitmodules @@ -0,0 +1,3 @@ +[submodule "external/verilog-axi"] + path = external/verilog-axi + url = https://github.com/alexforencich/verilog-axi diff --git a/external/external/rtl_libs/README.md b/external/external/rtl_libs/README.md new file mode 100644 index 0000000..d300e4c --- /dev/null +++ b/external/external/rtl_libs/README.md @@ -0,0 +1,3 @@ +# RTL Libs + +## AXI Defines diff --git a/external/external/rtl_libs/axi/axi_reg/axi4l_reg_map.sv b/external/external/rtl_libs/axi/axi_reg/axi4l_reg_map.sv new file mode 100644 index 0000000..2536b80 --- /dev/null +++ b/external/external/rtl_libs/axi/axi_reg/axi4l_reg_map.sv @@ -0,0 +1,213 @@ +module axi4l_reg_map #( + parameter int unsigned ADDR_W = 16, + parameter int unsigned DATA_W = 32, + parameter int unsigned USER_W = 1, + parameter int unsigned N_REGS = 4, + + parameter logic [N_REGS-1:0][31:0][2:0] REG_MODE = '{default:'0}, + parameter logic [N_REGS-1:0][31:0] REG_RST = '{default:'0} +)( + input logic clk, + input logic rst_n, + axi4l_if.slave s_axil, + + input logic [N_REGS-1:0][31:0] reg_i, + output logic [N_REGS-1:0][31:0] reg_o, + output logic [N_REGS-1:0][31:0] reg_pulse +); + import axi_pkg::*; + + typedef enum logic [2:0] { + REG_BIT_RSVD = 3'd0, + REG_BIT_RO = 3'd1, + REG_BIT_RW = 3'd2, + REG_BIT_W1S = 3'd3, + REG_BIT_W1C = 3'd4 + } reg_bit_mode_t; + + localparam int unsigned STRB_W = DATA_W/8; + localparam int unsigned ADDR_LSB = $clog2(DATA_W/8); + localparam int unsigned REG_INDEX_W = (N_REGS <= 1) ? 1 : $clog2(N_REGS); + + logic [ADDR_W-1:0] awaddr_q; + logic aw_seen_q; + logic [DATA_W-1:0] wdata_q; + logic [STRB_W-1:0] wstrb_q; + logic w_seen_q; + + logic bvalid_q; + logic [1:0] bresp_q; + + logic rvalid_q; + logic [1:0] rresp_q; + logic [DATA_W-1:0] rdata_q; + + logic [REG_INDEX_W-1:0] wr_idx; + logic [REG_INDEX_W-1:0] rd_idx; + logic wr_addr_valid; + logic rd_addr_valid; + + integer b; + logic [31:0] wr_mask; + logic [31:0] wr_data32; + logic [31:0] rw_cur; + logic [31:0] rw_new; + logic [31:0] rd_word; + + always_comb begin + wr_idx = '0; + rd_idx = '0; + wr_addr_valid = 1'b0; + rd_addr_valid = 1'b0; + + if (awaddr_q[ADDR_LSB + REG_INDEX_W - 1 -: REG_INDEX_W] < N_REGS) begin + wr_idx = awaddr_q[ADDR_LSB + REG_INDEX_W - 1 -: REG_INDEX_W]; + wr_addr_valid = 1'b1; + end + + if (s_axil.req.ar.addr[ADDR_LSB + REG_INDEX_W - 1 -: REG_INDEX_W] < N_REGS) begin + rd_idx = s_axil.req.ar.addr[ADDR_LSB + REG_INDEX_W - 1 -: REG_INDEX_W]; + rd_addr_valid = 1'b1; + end + end + + always_comb begin + wr_mask = '0; + for (int k = 0; k < STRB_W; k++) begin + wr_mask[k*8 +: 8] = {8{wstrb_q[k]}}; + end + wr_data32 = wdata_q[31:0]; + end + + assign s_axil.resp.aw_ready = !aw_seen_q && !bvalid_q; + assign s_axil.resp.w_ready = !w_seen_q && !bvalid_q; + assign s_axil.resp.ar_ready = !rvalid_q; + + assign s_axil.resp.b.valid = bvalid_q; + assign s_axil.resp.b.resp = axi_resp_t'(bresp_q); + assign s_axil.resp.b.user = '0; + + assign s_axil.resp.r.valid = rvalid_q; + assign s_axil.resp.r.resp = axi_resp_t'(rresp_q); + assign s_axil.resp.r.data = rdata_q; + assign s_axil.resp.r.user = '0; + + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + awaddr_q <= '0; + aw_seen_q <= 1'b0; + wdata_q <= '0; + wstrb_q <= '0; + w_seen_q <= 1'b0; + bvalid_q <= 1'b0; + bresp_q <= 2'b00; + rvalid_q <= 1'b0; + rresp_q <= 2'b00; + rdata_q <= '0; + reg_o <= REG_RST; + end else begin + reg_pulse <= '0; + for (int r = 0; r < N_REGS; r++) begin + for (int bit_idx = 0; bit_idx < 32; bit_idx++) begin + if (reg_bit_mode_t'(REG_MODE[r][bit_idx]) == REG_BIT_W1S) + reg_o[r][bit_idx] <= 1'b0; + end + end + + if (s_axil.req.aw.valid && s_axil.resp.aw_ready) begin + awaddr_q <= s_axil.req.aw.addr; + aw_seen_q <= 1'b1; + end + + if (s_axil.req.w.valid && s_axil.resp.w_ready) begin + wdata_q <= s_axil.req.w.data; + wstrb_q <= s_axil.req.w.strb; + w_seen_q <= 1'b1; + end + + if (aw_seen_q && w_seen_q && !bvalid_q) begin + bvalid_q <= 1'b1; + bresp_q <= 2'b00; + + if (!wr_addr_valid) begin + bresp_q <= 2'b10; + end else begin + rw_cur = reg_o[wr_idx]; + rw_new = rw_cur; + + for (b = 0; b < 32; b = b + 1) begin + if (wr_mask[b]) begin + unique case (reg_bit_mode_t'(REG_MODE[wr_idx][b])) + REG_BIT_RSVD: begin + end + + REG_BIT_RO: begin + bresp_q <= 2'b10; + end + + REG_BIT_RW: begin + rw_new[b] = wr_data32[b]; + end + + REG_BIT_W1S: begin + if (wr_data32[b]) begin + rw_new[b] = 1'b1; + reg_pulse[wr_idx][b] <= 1'b1; + end + end + + REG_BIT_W1C: begin + if (wr_data32[b]) begin + rw_new[b] = 1'b0; + reg_pulse[wr_idx][b] <= 1'b1; + end + end + + default: begin + end + endcase + end + end + + reg_o[wr_idx] <= rw_new; + end + + aw_seen_q <= 1'b0; + w_seen_q <= 1'b0; + end + + if (bvalid_q && s_axil.req.b_ready) begin + bvalid_q <= 1'b0; + end + + if (s_axil.req.ar.valid && s_axil.resp.ar_ready) begin + rvalid_q <= 1'b1; + rresp_q <= 2'b00; + rd_word = '0; + + if (!rd_addr_valid) begin + rresp_q <= 2'b10; + end else begin + for (b = 0; b < 32; b = b + 1) begin + unique case (reg_bit_mode_t'(REG_MODE[rd_idx][b])) + REG_BIT_RSVD: rd_word[b] = 1'b0; + REG_BIT_RO : rd_word[b] = reg_i[rd_idx][b]; + REG_BIT_RW : rd_word[b] = reg_o[rd_idx][b]; + REG_BIT_W1S : rd_word[b] = 1'b0; + REG_BIT_W1C : rd_word[b] = reg_o[rd_idx][b]; + default : rd_word[b] = 1'b0; + endcase + + end + end + + rdata_q <= rd_word; + end + + if (rvalid_q && s_axil.req.r_ready) begin + rvalid_q <= 1'b0; + end + end + end + +endmodule diff --git a/external/external/rtl_libs/axi/axi_reg/axi4l_reg_map_example.sv b/external/external/rtl_libs/axi/axi_reg/axi4l_reg_map_example.sv new file mode 100644 index 0000000..78b63ef --- /dev/null +++ b/external/external/rtl_libs/axi/axi_reg/axi4l_reg_map_example.sv @@ -0,0 +1,67 @@ +module axi4l_reg_map_example #( + parameter int unsigned ADDR_W = 16, + parameter int unsigned DATA_W = 32, + parameter int unsigned USER_W = 1 +)( + input logic clk, + input logic rst_n, + axi4l_if.slave s_axil, + + output logic start_o, + output logic soft_reset_o, + output logic enable_o, + output logic irq_enable_o, + output logic [31:0] config_o, + + input logic busy_i, + input logic done_i, + input logic error_i, + input logic [7:0] error_code_i +); + import axi4l_reg_map_example_pkg::*; + + localparam int unsigned N_REGS = AXI4L_REG_MAP_EXAMPLE_N_REGS; + + logic [N_REGS-1:0][31:0] reg_i; + logic [N_REGS-1:0][31:0] reg_o; + logic [N_REGS-1:0][31:0] reg_pulse; + + axi4l_reg_map #( + .ADDR_W (ADDR_W), + .DATA_W (DATA_W), + .USER_W (USER_W), + .N_REGS (N_REGS), + .REG_MODE (AXI4L_REG_MAP_EXAMPLE_REG_MODE), + .REG_RST (AXI4L_REG_MAP_EXAMPLE_REG_RST) + ) u_reg_map ( + .clk (clk), + .rst_n (rst_n), + .s_axil (s_axil), + .reg_i (reg_i), + .reg_o (reg_o), + .reg_pulse (reg_pulse) + ); + + always_comb begin + reg_i = '0; + + // REG_STATUS @ 0x04 + reg_i[REG_STATUS][STATUS_BUSY_BIT] = busy_i; + reg_i[REG_STATUS][STATUS_DONE_BIT] = done_i; + reg_i[REG_STATUS][STATUS_ERROR_BIT] = error_i; + reg_i[REG_STATUS][STATUS_ERROR_CODE_MSB:STATUS_ERROR_CODE_LSB] = error_code_i; + + // REG_VERSION @ 0x0c + reg_i[REG_VERSION] = VERSION_VAL; + end + + // REG_CTRL @ 0x00 + assign start_o = reg_pulse[REG_CTRL][CTRL_START_BIT]; + assign soft_reset_o = reg_pulse[REG_CTRL][CTRL_SOFT_RESET_BIT]; + assign enable_o = reg_o[REG_CTRL][CTRL_ENABLE_BIT]; + assign irq_enable_o = reg_o[REG_CTRL][CTRL_IRQ_ENABLE_BIT]; + + // REG_CONFIG @ 0x08 + assign config_o = reg_o[REG_CONFIG]; + +endmodule : axi4l_reg_map_example diff --git a/external/external/rtl_libs/axi/axi_reg/axi4l_reg_map_example_pkg.sv b/external/external/rtl_libs/axi/axi_reg/axi4l_reg_map_example_pkg.sv new file mode 100644 index 0000000..76f0bdd --- /dev/null +++ b/external/external/rtl_libs/axi/axi_reg/axi4l_reg_map_example_pkg.sv @@ -0,0 +1,68 @@ +package axi4l_reg_map_example_pkg; + import axi4l_reg_map_pkg::*; + + localparam int unsigned AXI4L_REG_MAP_EXAMPLE_N_REGS = 4; + + localparam int unsigned REG_CTRL = 0; + localparam int unsigned REG_STATUS = 1; + localparam int unsigned REG_CONFIG = 2; + localparam int unsigned REG_VERSION = 3; + + localparam logic [15:0] REG_CTRL_ADDR = 16'h0000; + localparam logic [15:0] REG_STATUS_ADDR = 16'h0004; + localparam logic [15:0] REG_CONFIG_ADDR = 16'h0008; + localparam logic [15:0] REG_VERSION_ADDR = 16'h000c; + + localparam int unsigned CTRL_START_BIT = 0; + localparam int unsigned CTRL_SOFT_RESET_BIT = 1; + localparam int unsigned CTRL_ENABLE_BIT = 2; + localparam int unsigned CTRL_IRQ_ENABLE_BIT = 3; + + localparam int unsigned STATUS_BUSY_BIT = 0; + localparam int unsigned STATUS_DONE_BIT = 1; + localparam int unsigned STATUS_ERROR_BIT = 2; + + localparam int unsigned STATUS_ERROR_CODE_LSB = 8; + localparam int unsigned STATUS_ERROR_CODE_MSB = 15; + + localparam logic [31:0] CONFIG_RST = 32'h0000_0001; + localparam logic [31:0] VERSION_VAL = 32'h0001_0000; + + localparam logic [AXI4L_REG_MAP_EXAMPLE_N_REGS-1:0][31:0][2:0] AXI4L_REG_MAP_EXAMPLE_REG_MODE = '{ + REG_CTRL: '{ + CTRL_START_BIT : REG_BIT_W1S, + CTRL_SOFT_RESET_BIT : REG_BIT_W1S, + CTRL_ENABLE_BIT : REG_BIT_RW, + CTRL_IRQ_ENABLE_BIT : REG_BIT_RW, + default : REG_BIT_RSVD + }, + REG_STATUS: '{ + STATUS_BUSY_BIT : REG_BIT_RO, + STATUS_DONE_BIT : REG_BIT_RO, + STATUS_ERROR_BIT : REG_BIT_RO, + STATUS_ERROR_CODE_LSB : REG_BIT_RO, + STATUS_ERROR_CODE_LSB+1 : REG_BIT_RO, + STATUS_ERROR_CODE_LSB+2 : REG_BIT_RO, + STATUS_ERROR_CODE_LSB+3 : REG_BIT_RO, + STATUS_ERROR_CODE_LSB+4 : REG_BIT_RO, + STATUS_ERROR_CODE_LSB+5 : REG_BIT_RO, + STATUS_ERROR_CODE_LSB+6 : REG_BIT_RO, + STATUS_ERROR_CODE_LSB+7 : REG_BIT_RO, + default : REG_BIT_RSVD + }, + REG_CONFIG: '{ + default: REG_BIT_RW + }, + REG_VERSION: '{ + default: REG_BIT_RO + } + }; + + localparam logic [AXI4L_REG_MAP_EXAMPLE_N_REGS-1:0][31:0] AXI4L_REG_MAP_EXAMPLE_REG_RST = '{ + REG_CTRL : 32'h0000_0000, + REG_STATUS : 32'h0000_0000, + REG_CONFIG : CONFIG_RST, + REG_VERSION : 32'h0000_0000 + }; + +endpackage : axi4l_reg_map_example_pkg diff --git a/external/external/rtl_libs/axi/axi_reg/dma_axil_reg_map_pkg.sv b/external/external/rtl_libs/axi/axi_reg/dma_axil_reg_map_pkg.sv new file mode 100644 index 0000000..09b5b38 --- /dev/null +++ b/external/external/rtl_libs/axi/axi_reg/dma_axil_reg_map_pkg.sv @@ -0,0 +1,64 @@ +package dma_axil_reg_map_pkg; + + localparam int unsigned DMA_AXIL_REG_MAP_N_REGS = 6; + + localparam int unsigned DMA_WRITE_DESC_CONTROL_REG = 0; + localparam int unsigned DMA_WRITE_DESC_ADDR_REG = 1; + localparam int unsigned DMA_WRITE_DESC_LEN_REG = 2; + localparam int unsigned DMA_READ_DESC_CONTROL_REG = 3; + localparam int unsigned DMA_READ_DESC_ADDR_REG = 4; + localparam int unsigned DMA_READ_DESC_LEN_REG = 5; + + localparam logic [2:0] REG_BIT_RSVD = 3'd0; + localparam logic [2:0] REG_BIT_RO = 3'd1; + localparam logic [2:0] REG_BIT_RW = 3'd2; + localparam logic [2:0] REG_BIT_W1S = 3'd3; + + typedef logic [DMA_AXIL_REG_MAP_N_REGS-1:0][31:0][2:0] reg_mode_map_t; + + function automatic reg_mode_map_t make_dma_reg_mode(); + reg_mode_map_t mode; + + mode = '0; + + // По умолчанию всё reserved + for (int reg_idx = 0; reg_idx < DMA_AXIL_REG_MAP_N_REGS; reg_idx++) begin + for (int bit_idx = 0; bit_idx < 32; bit_idx++) begin + mode[reg_idx][bit_idx] = REG_BIT_RSVD; + end + end + + // WRITE CONTROL + mode[DMA_WRITE_DESC_CONTROL_REG][0] = REG_BIT_RO; + mode[DMA_WRITE_DESC_CONTROL_REG][1] = REG_BIT_W1S; + + // WRITE ADDR + for (int bit_idx = 0; bit_idx < 32; bit_idx++) begin + mode[DMA_WRITE_DESC_ADDR_REG][bit_idx] = REG_BIT_RW; + end + + // WRITE LEN + for (int bit_idx = 0; bit_idx < 32; bit_idx++) begin + mode[DMA_WRITE_DESC_LEN_REG][bit_idx] = REG_BIT_RW; + end + + // READ CONTROL + mode[DMA_READ_DESC_CONTROL_REG][0] = REG_BIT_RO; + mode[DMA_READ_DESC_CONTROL_REG][1] = REG_BIT_W1S; + + // READ ADDR + for (int bit_idx = 0; bit_idx < 32; bit_idx++) begin + mode[DMA_READ_DESC_ADDR_REG][bit_idx] = REG_BIT_RW; + end + + // READ LEN + for (int bit_idx = 0; bit_idx < 32; bit_idx++) begin + mode[DMA_READ_DESC_LEN_REG][bit_idx] = REG_BIT_RW; + end + + return mode; + endfunction + + localparam reg_mode_map_t DMA_AXIL_REG_MAP_REG_MODE = make_dma_reg_mode(); + +endpackage \ No newline at end of file diff --git a/external/external/rtl_libs/axi/rtl/axi4_flat_to_if.sv b/external/external/rtl_libs/axi/rtl/axi4_flat_to_if.sv new file mode 100644 index 0000000..31fe4c2 --- /dev/null +++ b/external/external/rtl_libs/axi/rtl/axi4_flat_to_if.sv @@ -0,0 +1,97 @@ +module axi4_flat_to_if #( + parameter int unsigned ADDR_W = 32, + parameter int unsigned DATA_W = 64, + parameter int unsigned ID_W = 4, + parameter int unsigned USER_W = 1 +)( + input logic [ID_W-1:0] s_axi_awid, + input logic [ADDR_W-1:0] s_axi_awaddr, + input logic [7:0] s_axi_awlen, + input logic [2:0] s_axi_awsize, + input logic [1:0] s_axi_awburst, + input logic s_axi_awlock, + input logic [3:0] s_axi_awcache, + input logic [2:0] s_axi_awprot, + input logic [3:0] s_axi_awqos, + input logic [3:0] s_axi_awregion, + input logic [USER_W-1:0] s_axi_awuser, + input logic s_axi_awvalid, + output logic s_axi_awready, + input logic [DATA_W-1:0] s_axi_wdata, + input logic [DATA_W/8-1:0] s_axi_wstrb, + input logic s_axi_wlast, + input logic [USER_W-1:0] s_axi_wuser, + input logic s_axi_wvalid, + output logic s_axi_wready, + output logic [ID_W-1:0] s_axi_bid, + output logic [1:0] s_axi_bresp, + output logic [USER_W-1:0] s_axi_buser, + output logic s_axi_bvalid, + input logic s_axi_bready, + input logic [ID_W-1:0] s_axi_arid, + input logic [ADDR_W-1:0] s_axi_araddr, + input logic [7:0] s_axi_arlen, + input logic [2:0] s_axi_arsize, + input logic [1:0] s_axi_arburst, + input logic s_axi_arlock, + input logic [3:0] s_axi_arcache, + input logic [2:0] s_axi_arprot, + input logic [3:0] s_axi_arqos, + input logic [3:0] s_axi_arregion, + input logic [USER_W-1:0] s_axi_aruser, + input logic s_axi_arvalid, + output logic s_axi_arready, + output logic [ID_W-1:0] s_axi_rid, + output logic [DATA_W-1:0] s_axi_rdata, + output logic [1:0] s_axi_rresp, + output logic s_axi_rlast, + output logic [USER_W-1:0] s_axi_ruser, + output logic s_axi_rvalid, + input logic s_axi_rready, + axi4_if.master m_axi +); + assign m_axi.req.aw.id = s_axi_awid; + assign m_axi.req.aw.addr = s_axi_awaddr; + assign m_axi.req.aw.len = s_axi_awlen; + assign m_axi.req.aw.size = s_axi_awsize; + assign m_axi.req.aw.burst = axi_pkg::axi_burst_t'(s_axi_awburst); + assign m_axi.req.aw.lock = s_axi_awlock; + assign m_axi.req.aw.cache = s_axi_awcache; + assign m_axi.req.aw.prot = s_axi_awprot; + assign m_axi.req.aw.qos = s_axi_awqos; + assign m_axi.req.aw.region = s_axi_awregion; + assign m_axi.req.aw.user = s_axi_awuser; + assign m_axi.req.aw.valid = s_axi_awvalid; + assign s_axi_awready = m_axi.resp.aw_ready; + assign m_axi.req.w.data = s_axi_wdata; + assign m_axi.req.w.strb = s_axi_wstrb; + assign m_axi.req.w.last = s_axi_wlast; + assign m_axi.req.w.user = s_axi_wuser; + assign m_axi.req.w.valid = s_axi_wvalid; + assign s_axi_wready = m_axi.resp.w_ready; + assign s_axi_bid = m_axi.resp.b.id; + assign s_axi_bresp = m_axi.resp.b.resp; + assign s_axi_buser = m_axi.resp.b.user; + assign s_axi_bvalid = m_axi.resp.b.valid; + assign m_axi.req.b_ready = s_axi_bready; + assign m_axi.req.ar.id = s_axi_arid; + assign m_axi.req.ar.addr = s_axi_araddr; + assign m_axi.req.ar.len = s_axi_arlen; + assign m_axi.req.ar.size = s_axi_arsize; + assign m_axi.req.ar.burst = axi_pkg::axi_burst_t'(s_axi_arburst); + assign m_axi.req.ar.lock = s_axi_arlock; + assign m_axi.req.ar.cache = s_axi_arcache; + assign m_axi.req.ar.prot = s_axi_arprot; + assign m_axi.req.ar.qos = s_axi_arqos; + assign m_axi.req.ar.region = s_axi_arregion; + assign m_axi.req.ar.user = s_axi_aruser; + assign m_axi.req.ar.valid = s_axi_arvalid; + assign s_axi_arready = m_axi.resp.ar_ready; + assign s_axi_rid = m_axi.resp.r.id; + assign s_axi_rdata = m_axi.resp.r.data; + assign s_axi_rresp = m_axi.resp.r.resp; + assign s_axi_rlast = m_axi.resp.r.last; + assign s_axi_ruser = m_axi.resp.r.user; + assign s_axi_rvalid = m_axi.resp.r.valid; + assign m_axi.req.r_ready = s_axi_rready; +endmodule diff --git a/external/external/rtl_libs/axi/rtl/axi4_if_to_flat.sv b/external/external/rtl_libs/axi/rtl/axi4_if_to_flat.sv new file mode 100644 index 0000000..b6c8ec4 --- /dev/null +++ b/external/external/rtl_libs/axi/rtl/axi4_if_to_flat.sv @@ -0,0 +1,97 @@ +module axi4_if_to_flat #( + parameter int unsigned ADDR_W = 32, + parameter int unsigned DATA_W = 64, + parameter int unsigned ID_W = 4, + parameter int unsigned USER_W = 1 +)( + axi4_if.slave s_axi, + output logic [ID_W-1:0] m_axi_awid, + output logic [ADDR_W-1:0] m_axi_awaddr, + output logic [7:0] m_axi_awlen, + output logic [2:0] m_axi_awsize, + output logic [1:0] m_axi_awburst, + output logic m_axi_awlock, + output logic [3:0] m_axi_awcache, + output logic [2:0] m_axi_awprot, + output logic [3:0] m_axi_awqos, + output logic [3:0] m_axi_awregion, + output logic [USER_W-1:0] m_axi_awuser, + output logic m_axi_awvalid, + input logic m_axi_awready, + output logic [DATA_W-1:0] m_axi_wdata, + output logic [DATA_W/8-1:0] m_axi_wstrb, + output logic m_axi_wlast, + output logic [USER_W-1:0] m_axi_wuser, + output logic m_axi_wvalid, + input logic m_axi_wready, + input logic [ID_W-1:0] m_axi_bid, + input logic [1:0] m_axi_bresp, + input logic [USER_W-1:0] m_axi_buser, + input logic m_axi_bvalid, + output logic m_axi_bready, + output logic [ID_W-1:0] m_axi_arid, + output logic [ADDR_W-1:0] m_axi_araddr, + output logic [7:0] m_axi_arlen, + output logic [2:0] m_axi_arsize, + output logic [1:0] m_axi_arburst, + output logic m_axi_arlock, + output logic [3:0] m_axi_arcache, + output logic [2:0] m_axi_arprot, + output logic [3:0] m_axi_arqos, + output logic [3:0] m_axi_arregion, + output logic [USER_W-1:0] m_axi_aruser, + output logic m_axi_arvalid, + input logic m_axi_arready, + input logic [ID_W-1:0] m_axi_rid, + input logic [DATA_W-1:0] m_axi_rdata, + input logic [1:0] m_axi_rresp, + input logic m_axi_rlast, + input logic [USER_W-1:0] m_axi_ruser, + input logic m_axi_rvalid, + output logic m_axi_rready +); + assign m_axi_awid = s_axi.req.aw.id; + assign m_axi_awaddr = s_axi.req.aw.addr; + assign m_axi_awlen = s_axi.req.aw.len; + assign m_axi_awsize = s_axi.req.aw.size; + assign m_axi_awburst = s_axi.req.aw.burst; + assign m_axi_awlock = s_axi.req.aw.lock; + assign m_axi_awcache = s_axi.req.aw.cache; + assign m_axi_awprot = s_axi.req.aw.prot; + assign m_axi_awqos = s_axi.req.aw.qos; + assign m_axi_awregion = s_axi.req.aw.region; + assign m_axi_awuser = s_axi.req.aw.user; + assign m_axi_awvalid = s_axi.req.aw.valid; + assign s_axi.resp.aw_ready = m_axi_awready; + assign m_axi_wdata = s_axi.req.w.data; + assign m_axi_wstrb = s_axi.req.w.strb; + assign m_axi_wlast = s_axi.req.w.last; + assign m_axi_wuser = s_axi.req.w.user; + assign m_axi_wvalid = s_axi.req.w.valid; + assign s_axi.resp.w_ready = m_axi_wready; + assign s_axi.resp.b.id = m_axi_bid; + assign s_axi.resp.b.resp = axi_pkg::axi_resp_t'(m_axi_bresp); + assign s_axi.resp.b.user = m_axi_buser; + assign s_axi.resp.b.valid= m_axi_bvalid; + assign m_axi_bready = s_axi.req.b_ready; + assign m_axi_arid = s_axi.req.ar.id; + assign m_axi_araddr = s_axi.req.ar.addr; + assign m_axi_arlen = s_axi.req.ar.len; + assign m_axi_arsize = s_axi.req.ar.size; + assign m_axi_arburst = s_axi.req.ar.burst; + assign m_axi_arlock = s_axi.req.ar.lock; + assign m_axi_arcache = s_axi.req.ar.cache; + assign m_axi_arprot = s_axi.req.ar.prot; + assign m_axi_arqos = s_axi.req.ar.qos; + assign m_axi_arregion = s_axi.req.ar.region; + assign m_axi_aruser = s_axi.req.ar.user; + assign m_axi_arvalid = s_axi.req.ar.valid; + assign s_axi.resp.ar_ready = m_axi_arready; + assign s_axi.resp.r.id = m_axi_rid; + assign s_axi.resp.r.data = m_axi_rdata; + assign s_axi.resp.r.resp = axi_pkg::axi_resp_t'(m_axi_rresp); + assign s_axi.resp.r.last = m_axi_rlast; + assign s_axi.resp.r.user = m_axi_ruser; + assign s_axi.resp.r.valid= m_axi_rvalid; + assign m_axi_rready = s_axi.req.r_ready; +endmodule diff --git a/external/external/rtl_libs/axi/rtl/axi4l_flat_to_if.sv b/external/external/rtl_libs/axi/rtl/axi4l_flat_to_if.sv new file mode 100644 index 0000000..982e915 --- /dev/null +++ b/external/external/rtl_libs/axi/rtl/axi4l_flat_to_if.sv @@ -0,0 +1,58 @@ +module axi4l_flat_to_if #( + parameter int unsigned ADDR_W = 32, + parameter int unsigned DATA_W = 32, + parameter int unsigned USER_W = 1 +)( + input logic aclk, + input logic aresetn, + input logic [ADDR_W-1:0] s_axil_awaddr, + input logic [2:0] s_axil_awprot, + input logic [USER_W-1:0] s_axil_awuser, + input logic s_axil_awvalid, + output logic s_axil_awready, + input logic [DATA_W-1:0] s_axil_wdata, + input logic [DATA_W/8-1:0] s_axil_wstrb, + input logic [USER_W-1:0] s_axil_wuser, + input logic s_axil_wvalid, + output logic s_axil_wready, + output logic [1:0] s_axil_bresp, + output logic [USER_W-1:0] s_axil_buser, + output logic s_axil_bvalid, + input logic s_axil_bready, + input logic [ADDR_W-1:0] s_axil_araddr, + input logic [2:0] s_axil_arprot, + input logic [USER_W-1:0] s_axil_aruser, + input logic s_axil_arvalid, + output logic s_axil_arready, + output logic [DATA_W-1:0] s_axil_rdata, + output logic [1:0] s_axil_rresp, + output logic [USER_W-1:0] s_axil_ruser, + output logic s_axil_rvalid, + input logic s_axil_rready, + axi4l_if.master m_axil +); + assign m_axil.req.aw.addr = s_axil_awaddr; + assign m_axil.req.aw.prot = s_axil_awprot; + assign m_axil.req.aw.user = s_axil_awuser; + assign m_axil.req.aw.valid = s_axil_awvalid; + assign s_axil_awready = m_axil.resp.aw_ready; + assign m_axil.req.w.data = s_axil_wdata; + assign m_axil.req.w.strb = s_axil_wstrb; + assign m_axil.req.w.user = s_axil_wuser; + assign m_axil.req.w.valid = s_axil_wvalid; + assign s_axil_wready = m_axil.resp.w_ready; + assign s_axil_bresp = m_axil.resp.b.resp; + assign s_axil_buser = m_axil.resp.b.user; + assign s_axil_bvalid = m_axil.resp.b.valid; + assign m_axil.req.b_ready = s_axil_bready; + assign m_axil.req.ar.addr = s_axil_araddr; + assign m_axil.req.ar.prot = s_axil_arprot; + assign m_axil.req.ar.user = s_axil_aruser; + assign m_axil.req.ar.valid = s_axil_arvalid; + assign s_axil_arready = m_axil.resp.ar_ready; + assign s_axil_rdata = m_axil.resp.r.data; + assign s_axil_rresp = m_axil.resp.r.resp; + assign s_axil_ruser = m_axil.resp.r.user; + assign s_axil_rvalid = m_axil.resp.r.valid; + assign m_axil.req.r_ready = s_axil_rready; +endmodule diff --git a/external/external/rtl_libs/axi/rtl/axi4l_if_to_flat.sv b/external/external/rtl_libs/axi/rtl/axi4l_if_to_flat.sv new file mode 100644 index 0000000..6af2b1b --- /dev/null +++ b/external/external/rtl_libs/axi/rtl/axi4l_if_to_flat.sv @@ -0,0 +1,56 @@ +module axi4l_if_to_flat #( + parameter int unsigned ADDR_W = 32, + parameter int unsigned DATA_W = 32, + parameter int unsigned USER_W = 1 +)( + axi4l_if.slave s_axil, + output logic [ADDR_W-1:0] m_axil_awaddr, + output logic [2:0] m_axil_awprot, + output logic [USER_W-1:0] m_axil_awuser, + output logic m_axil_awvalid, + input logic m_axil_awready, + output logic [DATA_W-1:0] m_axil_wdata, + output logic [DATA_W/8-1:0] m_axil_wstrb, + output logic [USER_W-1:0] m_axil_wuser, + output logic m_axil_wvalid, + input logic m_axil_wready, + input logic [1:0] m_axil_bresp, + input logic [USER_W-1:0] m_axil_buser, + input logic m_axil_bvalid, + output logic m_axil_bready, + output logic [ADDR_W-1:0] m_axil_araddr, + output logic [2:0] m_axil_arprot, + output logic [USER_W-1:0] m_axil_aruser, + output logic m_axil_arvalid, + input logic m_axil_arready, + input logic [DATA_W-1:0] m_axil_rdata, + input logic [1:0] m_axil_rresp, + input logic [USER_W-1:0] m_axil_ruser, + input logic m_axil_rvalid, + output logic m_axil_rready +); + assign m_axil_awaddr = s_axil.req.aw.addr; + assign m_axil_awprot = s_axil.req.aw.prot; + assign m_axil_awuser = s_axil.req.aw.user; + assign m_axil_awvalid = s_axil.req.aw.valid; + assign s_axil.resp.aw_ready = m_axil_awready; + assign m_axil_wdata = s_axil.req.w.data; + assign m_axil_wstrb = s_axil.req.w.strb; + assign m_axil_wuser = s_axil.req.w.user; + assign m_axil_wvalid = s_axil.req.w.valid; + assign s_axil.resp.w_ready = m_axil_wready; + assign s_axil.resp.b.resp = axi_pkg::axi_resp_t'(m_axil_bresp); + assign s_axil.resp.b.user = m_axil_buser; + assign s_axil.resp.b.valid = m_axil_bvalid; + assign m_axil_bready = s_axil.req.b_ready; + assign m_axil_araddr = s_axil.req.ar.addr; + assign m_axil_arprot = s_axil.req.ar.prot; + assign m_axil_aruser = s_axil.req.ar.user; + assign m_axil_arvalid = s_axil.req.ar.valid; + assign s_axil.resp.ar_ready = m_axil_arready; + assign s_axil.resp.r.data = m_axil_rdata; + assign s_axil.resp.r.resp = axi_pkg::axi_resp_t'(m_axil_rresp); + assign s_axil.resp.r.user = m_axil_ruser; + assign s_axil.resp.r.valid = m_axil_rvalid; + assign m_axil_rready = s_axil.req.r_ready; +endmodule diff --git a/external/external/rtl_libs/axi/rtl/axi4l_reg_map.sv b/external/external/rtl_libs/axi/rtl/axi4l_reg_map.sv new file mode 100644 index 0000000..36544a8 --- /dev/null +++ b/external/external/rtl_libs/axi/rtl/axi4l_reg_map.sv @@ -0,0 +1,189 @@ +module axi4l_reg_map #( + parameter int unsigned ADDR_W = 16, + parameter int unsigned DATA_W = 32, + parameter int unsigned USER_W = 1, + parameter int unsigned N_REGS = 4, + + parameter logic [N_REGS-1:0][31:0][2:0] REG_MODE = '{default:'0}, + parameter logic [N_REGS-1:0][31:0] REG_RST = '{default:'0} +)( + input logic clk, + input logic rst_n, + axi4l_if.slave s_axil, + + input logic [N_REGS-1:0][31:0] reg_i, + output logic [N_REGS-1:0][31:0] reg_o +); + import axi_pkg::*; + + typedef enum logic [2:0] { + REG_BIT_RSVD = 3'd0, + REG_BIT_RO = 3'd1, + REG_BIT_RW = 3'd2, + REG_BIT_W1S = 3'd3, + REG_BIT_W1C = 3'd4 + } reg_bit_mode_t; + + localparam int unsigned STRB_W = DATA_W/8; + localparam int unsigned ADDR_LSB = $clog2(DATA_W/8); + localparam int unsigned REG_INDEX_W = (N_REGS <= 1) ? 1 : $clog2(N_REGS); + + logic [ADDR_W-1:0] awaddr_q; + logic aw_seen_q; + logic [DATA_W-1:0] wdata_q; + logic [STRB_W-1:0] wstrb_q; + logic w_seen_q; + + logic bvalid_q; + logic [1:0] bresp_q; + + logic rvalid_q; + logic [1:0] rresp_q; + logic [DATA_W-1:0] rdata_q; + + logic [REG_INDEX_W-1:0] wr_idx; + logic [REG_INDEX_W-1:0] rd_idx; + logic wr_addr_valid; + logic rd_addr_valid; + + integer b; + logic [31:0] wr_mask; + logic [31:0] wr_data32; + logic [31:0] rw_cur; + logic [31:0] rw_new; + logic [31:0] rd_word; + + always_comb begin + wr_idx = '0; + rd_idx = '0; + wr_addr_valid = 1'b0; + rd_addr_valid = 1'b0; + + if (awaddr_q[ADDR_LSB + REG_INDEX_W - 1 -: REG_INDEX_W] < N_REGS) begin + wr_idx = awaddr_q[ADDR_LSB + REG_INDEX_W - 1 -: REG_INDEX_W]; + wr_addr_valid = 1'b1; + end + + if (s_axil.req.ar.addr[ADDR_LSB + REG_INDEX_W - 1 -: REG_INDEX_W] < N_REGS) begin + rd_idx = s_axil.req.ar.addr[ADDR_LSB + REG_INDEX_W - 1 -: REG_INDEX_W]; + rd_addr_valid = 1'b1; + end + end + + always_comb begin + wr_mask = '0; + for (int k = 0; k < STRB_W; k++) begin + wr_mask[k*8 +: 8] = {8{wstrb_q[k]}}; + end + wr_data32 = wdata_q[31:0]; + end + + assign s_axil.resp.aw_ready = !aw_seen_q && !bvalid_q; + assign s_axil.resp.w_ready = !w_seen_q && !bvalid_q; + assign s_axil.resp.ar_ready = !rvalid_q; + + assign s_axil.resp.b.valid = bvalid_q; + assign s_axil.resp.b.resp = axi_resp_t'(bresp_q); + assign s_axil.resp.b.user = '0; + + assign s_axil.resp.r.valid = rvalid_q; + assign s_axil.resp.r.resp = axi_resp_t'(rresp_q); + assign s_axil.resp.r.data = rdata_q; + assign s_axil.resp.r.user = '0; + + always_ff @(posedge clk or negedge rst_n) begin + if (!rst_n) begin + awaddr_q <= '0; + aw_seen_q <= 1'b0; + wdata_q <= '0; + wstrb_q <= '0; + w_seen_q <= 1'b0; + bvalid_q <= 1'b0; + bresp_q <= 2'b00; + rvalid_q <= 1'b0; + rresp_q <= 2'b00; + rdata_q <= '0; + reg_o <= REG_RST; + end else begin + for (int r = 0; r < N_REGS; r++) begin + for (int bit_idx = 0; bit_idx < 32; bit_idx++) begin + if (reg_bit_mode_t'(REG_MODE[r][bit_idx]) == REG_BIT_W1S) + reg_o[r][bit_idx] <= 1'b0; + end + end + + if (s_axil.req.aw.valid && s_axil.resp.aw_ready) begin + awaddr_q <= s_axil.req.aw.addr; + aw_seen_q <= 1'b1; + end + + if (s_axil.req.w.valid && s_axil.resp.w_ready) begin + wdata_q <= s_axil.req.w.data; + wstrb_q <= s_axil.req.w.strb; + w_seen_q <= 1'b1; + end + + if (aw_seen_q && w_seen_q && !bvalid_q) begin + bvalid_q <= 1'b1; + bresp_q <= 2'b00; + + if (!wr_addr_valid) begin + bresp_q <= 2'b10; + end else begin + rw_cur = reg_o[wr_idx]; + rw_new = rw_cur; + + for (b = 0; b < 32; b = b + 1) begin + if (wr_mask[b]) begin + unique case (reg_bit_mode_t'(REG_MODE[wr_idx][b])) + REG_BIT_RSVD: begin end + REG_BIT_RO : begin bresp_q <= 2'b10; end + REG_BIT_RW : rw_new[b] = wr_data32[b]; + REG_BIT_W1S : if (wr_data32[b]) rw_new[b] = 1'b1; + REG_BIT_W1C : if (wr_data32[b]) rw_new[b] = 1'b0; + default : begin end + endcase + end + end + + reg_o[wr_idx] <= rw_new; + end + + aw_seen_q <= 1'b0; + w_seen_q <= 1'b0; + end + + if (bvalid_q && s_axil.req.b_ready) begin + bvalid_q <= 1'b0; + end + + if (s_axil.req.ar.valid && s_axil.resp.ar_ready) begin + rvalid_q <= 1'b1; + rresp_q <= 2'b00; + rd_word = '0; + + if (!rd_addr_valid) begin + rresp_q <= 2'b10; + end else begin + for (b = 0; b < 32; b = b + 1) begin + unique case (reg_bit_mode_t'(REG_MODE[rd_idx][b])) + REG_BIT_RSVD: rd_word[b] = 1'b0; + REG_BIT_RO : rd_word[b] = reg_i[rd_idx][b]; + REG_BIT_RW : rd_word[b] = reg_o[rd_idx][b]; + REG_BIT_W1S : rd_word[b] = 1'b0; + REG_BIT_W1C : rd_word[b] = reg_o[rd_idx][b]; + default : rd_word[b] = 1'b0; + endcase + end + end + + rdata_q <= rd_word; + end + + if (rvalid_q && s_axil.req.r_ready) begin + rvalid_q <= 1'b0; + end + end + end + +endmodule diff --git a/external/external/rtl_libs/axi/rtl/axi4l_to_axi4.sv b/external/external/rtl_libs/axi/rtl/axi4l_to_axi4.sv new file mode 100644 index 0000000..05f295f --- /dev/null +++ b/external/external/rtl_libs/axi/rtl/axi4l_to_axi4.sv @@ -0,0 +1,59 @@ +module axi4l_to_axi4 #( + parameter int unsigned ADDR_W = 32, + parameter int unsigned DATA_W = 32, + parameter int unsigned ID_W = 4, + parameter int unsigned USER_W = 1, + parameter logic [ID_W-1:0] AXI_ID_CONST = '0, + parameter logic [3:0] AXI_CACHE_CONST = 4'b0000, + parameter logic [3:0] AXI_QOS_CONST = 4'b0000, + parameter logic [3:0] AXI_REGION_CONST = 4'b0000 +)( + axi4l_if.slave s_axil, + axi4_if.master m_axi +); + assign m_axi.req.aw.id = AXI_ID_CONST; + assign m_axi.req.aw.addr = s_axil.req.aw.addr; + assign m_axi.req.aw.len = 8'd0; + assign m_axi.req.aw.size = axi_pkg::axi_size_from_bytes(DATA_W/8); + assign m_axi.req.aw.burst = axi_pkg::AXI_BURST_INCR; + assign m_axi.req.aw.lock = 1'b0; + assign m_axi.req.aw.cache = AXI_CACHE_CONST; + assign m_axi.req.aw.prot = s_axil.req.aw.prot; + assign m_axi.req.aw.qos = AXI_QOS_CONST; + assign m_axi.req.aw.region = AXI_REGION_CONST; + assign m_axi.req.aw.user = s_axil.req.aw.user; + assign m_axi.req.aw.valid = s_axil.req.aw.valid; + assign s_axil.resp.aw_ready = m_axi.resp.aw_ready; + + assign m_axi.req.w.data = s_axil.req.w.data; + assign m_axi.req.w.strb = s_axil.req.w.strb; + assign m_axi.req.w.last = 1'b1; + assign m_axi.req.w.user = s_axil.req.w.user; + assign m_axi.req.w.valid = s_axil.req.w.valid; + assign s_axil.resp.w_ready = m_axi.resp.w_ready; + + assign s_axil.resp.b.resp = m_axi.resp.b.resp; + assign s_axil.resp.b.user = m_axi.resp.b.user; + assign s_axil.resp.b.valid = m_axi.resp.b.valid; + assign m_axi.req.b_ready = s_axil.req.b_ready; + + assign m_axi.req.ar.id = AXI_ID_CONST; + assign m_axi.req.ar.addr = s_axil.req.ar.addr; + assign m_axi.req.ar.len = 8'd0; + assign m_axi.req.ar.size = axi_pkg::axi_size_from_bytes(DATA_W/8); + assign m_axi.req.ar.burst = axi_pkg::AXI_BURST_INCR; + assign m_axi.req.ar.lock = 1'b0; + assign m_axi.req.ar.cache = AXI_CACHE_CONST; + assign m_axi.req.ar.prot = s_axil.req.ar.prot; + assign m_axi.req.ar.qos = AXI_QOS_CONST; + assign m_axi.req.ar.region = AXI_REGION_CONST; + assign m_axi.req.ar.user = s_axil.req.ar.user; + assign m_axi.req.ar.valid = s_axil.req.ar.valid; + assign s_axil.resp.ar_ready = m_axi.resp.ar_ready; + + assign s_axil.resp.r.data = m_axi.resp.r.data; + assign s_axil.resp.r.resp = m_axi.resp.r.resp; + assign s_axil.resp.r.user = m_axi.resp.r.user; + assign s_axil.resp.r.valid = m_axi.resp.r.valid; + assign m_axi.req.r_ready = s_axil.req.r_ready; +endmodule diff --git a/external/external/rtl_libs/axi/rtl/axi_crossbar_core_wrapper.sv b/external/external/rtl_libs/axi/rtl/axi_crossbar_core_wrapper.sv new file mode 100644 index 0000000..d506db9 --- /dev/null +++ b/external/external/rtl_libs/axi/rtl/axi_crossbar_core_wrapper.sv @@ -0,0 +1,654 @@ +/* + +Copyright (c) 2020 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +THE SOFTWARE. + +*/ + +// Language: Verilog 2001 + +`resetall +`timescale 1ns / 1ps +`default_nettype none + +/* + * AXI4 3x3 crossbar (wrapper) + */ +module axi_crossbar_core_wrapper # +( + // Width of data bus in bits + parameter DATA_WIDTH = 32, + // Width of address bus in bits + parameter ADDR_WIDTH = 32, + // Width of wstrb (width of data bus in words) + parameter STRB_WIDTH = (DATA_WIDTH/8), + // Input ID field width (from AXI masters) + parameter S_ID_WIDTH = 8, + // Output ID field width (towards AXI slaves) + // Additional bits required for response routing + parameter M_ID_WIDTH = S_ID_WIDTH+$clog2(S_COUNT), + // Propagate awuser signal + parameter AWUSER_ENABLE = 0, + // Width of awuser signal + parameter AWUSER_WIDTH = 1, + // Propagate wuser signal + parameter WUSER_ENABLE = 0, + // Width of wuser signal + parameter WUSER_WIDTH = 1, + // Propagate buser signal + parameter BUSER_ENABLE = 0, + // Width of buser signal + parameter BUSER_WIDTH = 1, + // Propagate aruser signal + parameter ARUSER_ENABLE = 0, + // Width of aruser signal + parameter ARUSER_WIDTH = 1, + // Propagate ruser signal + parameter RUSER_ENABLE = 0, + // Width of ruser signal + parameter RUSER_WIDTH = 1, + // Number of concurrent unique IDs + parameter S00_THREADS = 2, + // Number of concurrent operations + parameter S00_ACCEPT = 16, + // Number of concurrent unique IDs + parameter S01_THREADS = 2, + // Number of concurrent operations + parameter S01_ACCEPT = 16, + // Number of concurrent unique IDs + parameter S02_THREADS = 2, + // Number of concurrent operations + parameter S02_ACCEPT = 16, + // Number of regions per master interface + parameter M_REGIONS = 1, + // Master interface base addresses + // M_REGIONS concatenated fields of ADDR_WIDTH bits + parameter M00_BASE_ADDR = 0, + // Master interface address widths + // M_REGIONS concatenated fields of 32 bits + parameter M00_ADDR_WIDTH = {M_REGIONS{32'd24}}, + // Read connections between interfaces + // S_COUNT bits + parameter M00_CONNECT_READ = 3'b111, + // Write connections between interfaces + // S_COUNT bits + parameter M00_CONNECT_WRITE = 3'b111, + // Number of concurrent operations for each master interface + parameter M00_ISSUE = 4, + // Secure master (fail operations based on awprot/arprot) + parameter M00_SECURE = 0, + // Master interface base addresses + // M_REGIONS concatenated fields of ADDR_WIDTH bits + parameter M01_BASE_ADDR = 0, + // Master interface address widths + // M_REGIONS concatenated fields of 32 bits + parameter M01_ADDR_WIDTH = {M_REGIONS{32'd24}}, + // Read connections between interfaces + // S_COUNT bits + parameter M01_CONNECT_READ = 3'b111, + // Write connections between interfaces + // S_COUNT bits + parameter M01_CONNECT_WRITE = 3'b111, + // Number of concurrent operations for each master interface + parameter M01_ISSUE = 4, + // Secure master (fail operations based on awprot/arprot) + parameter M01_SECURE = 0, + // Master interface base addresses + // M_REGIONS concatenated fields of ADDR_WIDTH bits + parameter M02_BASE_ADDR = 0, + // Master interface address widths + // M_REGIONS concatenated fields of 32 bits + parameter M02_ADDR_WIDTH = {M_REGIONS{32'd24}}, + // Read connections between interfaces + // S_COUNT bits + parameter M02_CONNECT_READ = 3'b111, + // Write connections between interfaces + // S_COUNT bits + parameter M02_CONNECT_WRITE = 3'b111, + // Number of concurrent operations for each master interface + parameter M02_ISSUE = 4, + // Secure master (fail operations based on awprot/arprot) + parameter M02_SECURE = 0, + // Slave interface AW channel register type (input) + // 0 to bypass, 1 for simple buffer, 2 for skid buffer + parameter S00_AW_REG_TYPE = 0, + // Slave interface W channel register type (input) + // 0 to bypass, 1 for simple buffer, 2 for skid buffer + parameter S00_W_REG_TYPE = 0, + // Slave interface B channel register type (output) + // 0 to bypass, 1 for simple buffer, 2 for skid buffer + parameter S00_B_REG_TYPE = 1, + // Slave interface AR channel register type (input) + // 0 to bypass, 1 for simple buffer, 2 for skid buffer + parameter S00_AR_REG_TYPE = 0, + // Slave interface R channel register type (output) + // 0 to bypass, 1 for simple buffer, 2 for skid buffer + parameter S00_R_REG_TYPE = 2, + // Slave interface AW channel register type (input) + // 0 to bypass, 1 for simple buffer, 2 for skid buffer + parameter S01_AW_REG_TYPE = 0, + // Slave interface W channel register type (input) + // 0 to bypass, 1 for simple buffer, 2 for skid buffer + parameter S01_W_REG_TYPE = 0, + // Slave interface B channel register type (output) + // 0 to bypass, 1 for simple buffer, 2 for skid buffer + parameter S01_B_REG_TYPE = 1, + // Slave interface AR channel register type (input) + // 0 to bypass, 1 for simple buffer, 2 for skid buffer + parameter S01_AR_REG_TYPE = 0, + // Slave interface R channel register type (output) + // 0 to bypass, 1 for simple buffer, 2 for skid buffer + parameter S01_R_REG_TYPE = 2, + // Slave interface AW channel register type (input) + // 0 to bypass, 1 for simple buffer, 2 for skid buffer + parameter S02_AW_REG_TYPE = 0, + // Slave interface W channel register type (input) + // 0 to bypass, 1 for simple buffer, 2 for skid buffer + parameter S02_W_REG_TYPE = 0, + // Slave interface B channel register type (output) + // 0 to bypass, 1 for simple buffer, 2 for skid buffer + parameter S02_B_REG_TYPE = 1, + // Slave interface AR channel register type (input) + // 0 to bypass, 1 for simple buffer, 2 for skid buffer + parameter S02_AR_REG_TYPE = 0, + // Slave interface R channel register type (output) + // 0 to bypass, 1 for simple buffer, 2 for skid buffer + parameter S02_R_REG_TYPE = 2, + // Master interface AW channel register type (output) + // 0 to bypass, 1 for simple buffer, 2 for skid buffer + parameter M00_AW_REG_TYPE = 1, + // Master interface W channel register type (output) + // 0 to bypass, 1 for simple buffer, 2 for skid buffer + parameter M00_W_REG_TYPE = 2, + // Master interface B channel register type (input) + // 0 to bypass, 1 for simple buffer, 2 for skid buffer + parameter M00_B_REG_TYPE = 0, + // Master interface AR channel register type (output) + // 0 to bypass, 1 for simple buffer, 2 for skid buffer + parameter M00_AR_REG_TYPE = 1, + // Master interface R channel register type (input) + // 0 to bypass, 1 for simple buffer, 2 for skid buffer + parameter M00_R_REG_TYPE = 0, + // Master interface AW channel register type (output) + // 0 to bypass, 1 for simple buffer, 2 for skid buffer + parameter M01_AW_REG_TYPE = 1, + // Master interface W channel register type (output) + // 0 to bypass, 1 for simple buffer, 2 for skid buffer + parameter M01_W_REG_TYPE = 2, + // Master interface B channel register type (input) + // 0 to bypass, 1 for simple buffer, 2 for skid buffer + parameter M01_B_REG_TYPE = 0, + // Master interface AR channel register type (output) + // 0 to bypass, 1 for simple buffer, 2 for skid buffer + parameter M01_AR_REG_TYPE = 1, + // Master interface R channel register type (input) + // 0 to bypass, 1 for simple buffer, 2 for skid buffer + parameter M01_R_REG_TYPE = 0, + // Master interface AW channel register type (output) + // 0 to bypass, 1 for simple buffer, 2 for skid buffer + parameter M02_AW_REG_TYPE = 1, + // Master interface W channel register type (output) + // 0 to bypass, 1 for simple buffer, 2 for skid buffer + parameter M02_W_REG_TYPE = 2, + // Master interface B channel register type (input) + // 0 to bypass, 1 for simple buffer, 2 for skid buffer + parameter M02_B_REG_TYPE = 0, + // Master interface AR channel register type (output) + // 0 to bypass, 1 for simple buffer, 2 for skid buffer + parameter M02_AR_REG_TYPE = 1, + // Master interface R channel register type (input) + // 0 to bypass, 1 for simple buffer, 2 for skid buffer + parameter M02_R_REG_TYPE = 0 +) +( + input wire clk, + input wire rst, + + /* + * AXI slave interface + */ + input wire [S_ID_WIDTH-1:0] s00_axi_awid, + input wire [ADDR_WIDTH-1:0] s00_axi_awaddr, + input wire [7:0] s00_axi_awlen, + input wire [2:0] s00_axi_awsize, + input wire [1:0] s00_axi_awburst, + input wire s00_axi_awlock, + input wire [3:0] s00_axi_awcache, + input wire [2:0] s00_axi_awprot, + input wire [3:0] s00_axi_awqos, + input wire [AWUSER_WIDTH-1:0] s00_axi_awuser, + input wire s00_axi_awvalid, + output wire s00_axi_awready, + input wire [DATA_WIDTH-1:0] s00_axi_wdata, + input wire [STRB_WIDTH-1:0] s00_axi_wstrb, + input wire s00_axi_wlast, + input wire [WUSER_WIDTH-1:0] s00_axi_wuser, + input wire s00_axi_wvalid, + output wire s00_axi_wready, + output wire [S_ID_WIDTH-1:0] s00_axi_bid, + output wire [1:0] s00_axi_bresp, + output wire [BUSER_WIDTH-1:0] s00_axi_buser, + output wire s00_axi_bvalid, + input wire s00_axi_bready, + input wire [S_ID_WIDTH-1:0] s00_axi_arid, + input wire [ADDR_WIDTH-1:0] s00_axi_araddr, + input wire [7:0] s00_axi_arlen, + input wire [2:0] s00_axi_arsize, + input wire [1:0] s00_axi_arburst, + input wire s00_axi_arlock, + input wire [3:0] s00_axi_arcache, + input wire [2:0] s00_axi_arprot, + input wire [3:0] s00_axi_arqos, + input wire [ARUSER_WIDTH-1:0] s00_axi_aruser, + input wire s00_axi_arvalid, + output wire s00_axi_arready, + output wire [S_ID_WIDTH-1:0] s00_axi_rid, + output wire [DATA_WIDTH-1:0] s00_axi_rdata, + output wire [1:0] s00_axi_rresp, + output wire s00_axi_rlast, + output wire [RUSER_WIDTH-1:0] s00_axi_ruser, + output wire s00_axi_rvalid, + input wire s00_axi_rready, + + input wire [S_ID_WIDTH-1:0] s01_axi_awid, + input wire [ADDR_WIDTH-1:0] s01_axi_awaddr, + input wire [7:0] s01_axi_awlen, + input wire [2:0] s01_axi_awsize, + input wire [1:0] s01_axi_awburst, + input wire s01_axi_awlock, + input wire [3:0] s01_axi_awcache, + input wire [2:0] s01_axi_awprot, + input wire [3:0] s01_axi_awqos, + input wire [AWUSER_WIDTH-1:0] s01_axi_awuser, + input wire s01_axi_awvalid, + output wire s01_axi_awready, + input wire [DATA_WIDTH-1:0] s01_axi_wdata, + input wire [STRB_WIDTH-1:0] s01_axi_wstrb, + input wire s01_axi_wlast, + input wire [WUSER_WIDTH-1:0] s01_axi_wuser, + input wire s01_axi_wvalid, + output wire s01_axi_wready, + output wire [S_ID_WIDTH-1:0] s01_axi_bid, + output wire [1:0] s01_axi_bresp, + output wire [BUSER_WIDTH-1:0] s01_axi_buser, + output wire s01_axi_bvalid, + input wire s01_axi_bready, + input wire [S_ID_WIDTH-1:0] s01_axi_arid, + input wire [ADDR_WIDTH-1:0] s01_axi_araddr, + input wire [7:0] s01_axi_arlen, + input wire [2:0] s01_axi_arsize, + input wire [1:0] s01_axi_arburst, + input wire s01_axi_arlock, + input wire [3:0] s01_axi_arcache, + input wire [2:0] s01_axi_arprot, + input wire [3:0] s01_axi_arqos, + input wire [ARUSER_WIDTH-1:0] s01_axi_aruser, + input wire s01_axi_arvalid, + output wire s01_axi_arready, + output wire [S_ID_WIDTH-1:0] s01_axi_rid, + output wire [DATA_WIDTH-1:0] s01_axi_rdata, + output wire [1:0] s01_axi_rresp, + output wire s01_axi_rlast, + output wire [RUSER_WIDTH-1:0] s01_axi_ruser, + output wire s01_axi_rvalid, + input wire s01_axi_rready, + + input wire [S_ID_WIDTH-1:0] s02_axi_awid, + input wire [ADDR_WIDTH-1:0] s02_axi_awaddr, + input wire [7:0] s02_axi_awlen, + input wire [2:0] s02_axi_awsize, + input wire [1:0] s02_axi_awburst, + input wire s02_axi_awlock, + input wire [3:0] s02_axi_awcache, + input wire [2:0] s02_axi_awprot, + input wire [3:0] s02_axi_awqos, + input wire [AWUSER_WIDTH-1:0] s02_axi_awuser, + input wire s02_axi_awvalid, + output wire s02_axi_awready, + input wire [DATA_WIDTH-1:0] s02_axi_wdata, + input wire [STRB_WIDTH-1:0] s02_axi_wstrb, + input wire s02_axi_wlast, + input wire [WUSER_WIDTH-1:0] s02_axi_wuser, + input wire s02_axi_wvalid, + output wire s02_axi_wready, + output wire [S_ID_WIDTH-1:0] s02_axi_bid, + output wire [1:0] s02_axi_bresp, + output wire [BUSER_WIDTH-1:0] s02_axi_buser, + output wire s02_axi_bvalid, + input wire s02_axi_bready, + input wire [S_ID_WIDTH-1:0] s02_axi_arid, + input wire [ADDR_WIDTH-1:0] s02_axi_araddr, + input wire [7:0] s02_axi_arlen, + input wire [2:0] s02_axi_arsize, + input wire [1:0] s02_axi_arburst, + input wire s02_axi_arlock, + input wire [3:0] s02_axi_arcache, + input wire [2:0] s02_axi_arprot, + input wire [3:0] s02_axi_arqos, + input wire [ARUSER_WIDTH-1:0] s02_axi_aruser, + input wire s02_axi_arvalid, + output wire s02_axi_arready, + output wire [S_ID_WIDTH-1:0] s02_axi_rid, + output wire [DATA_WIDTH-1:0] s02_axi_rdata, + output wire [1:0] s02_axi_rresp, + output wire s02_axi_rlast, + output wire [RUSER_WIDTH-1:0] s02_axi_ruser, + output wire s02_axi_rvalid, + input wire s02_axi_rready, + + /* + * AXI master interface + */ + output wire [M_ID_WIDTH-1:0] m00_axi_awid, + output wire [ADDR_WIDTH-1:0] m00_axi_awaddr, + output wire [7:0] m00_axi_awlen, + output wire [2:0] m00_axi_awsize, + output wire [1:0] m00_axi_awburst, + output wire m00_axi_awlock, + output wire [3:0] m00_axi_awcache, + output wire [2:0] m00_axi_awprot, + output wire [3:0] m00_axi_awqos, + output wire [3:0] m00_axi_awregion, + output wire [AWUSER_WIDTH-1:0] m00_axi_awuser, + output wire m00_axi_awvalid, + input wire m00_axi_awready, + output wire [DATA_WIDTH-1:0] m00_axi_wdata, + output wire [STRB_WIDTH-1:0] m00_axi_wstrb, + output wire m00_axi_wlast, + output wire [WUSER_WIDTH-1:0] m00_axi_wuser, + output wire m00_axi_wvalid, + input wire m00_axi_wready, + input wire [M_ID_WIDTH-1:0] m00_axi_bid, + input wire [1:0] m00_axi_bresp, + input wire [BUSER_WIDTH-1:0] m00_axi_buser, + input wire m00_axi_bvalid, + output wire m00_axi_bready, + output wire [M_ID_WIDTH-1:0] m00_axi_arid, + output wire [ADDR_WIDTH-1:0] m00_axi_araddr, + output wire [7:0] m00_axi_arlen, + output wire [2:0] m00_axi_arsize, + output wire [1:0] m00_axi_arburst, + output wire m00_axi_arlock, + output wire [3:0] m00_axi_arcache, + output wire [2:0] m00_axi_arprot, + output wire [3:0] m00_axi_arqos, + output wire [3:0] m00_axi_arregion, + output wire [ARUSER_WIDTH-1:0] m00_axi_aruser, + output wire m00_axi_arvalid, + input wire m00_axi_arready, + input wire [M_ID_WIDTH-1:0] m00_axi_rid, + input wire [DATA_WIDTH-1:0] m00_axi_rdata, + input wire [1:0] m00_axi_rresp, + input wire m00_axi_rlast, + input wire [RUSER_WIDTH-1:0] m00_axi_ruser, + input wire m00_axi_rvalid, + output wire m00_axi_rready, + + output wire [M_ID_WIDTH-1:0] m01_axi_awid, + output wire [ADDR_WIDTH-1:0] m01_axi_awaddr, + output wire [7:0] m01_axi_awlen, + output wire [2:0] m01_axi_awsize, + output wire [1:0] m01_axi_awburst, + output wire m01_axi_awlock, + output wire [3:0] m01_axi_awcache, + output wire [2:0] m01_axi_awprot, + output wire [3:0] m01_axi_awqos, + output wire [3:0] m01_axi_awregion, + output wire [AWUSER_WIDTH-1:0] m01_axi_awuser, + output wire m01_axi_awvalid, + input wire m01_axi_awready, + output wire [DATA_WIDTH-1:0] m01_axi_wdata, + output wire [STRB_WIDTH-1:0] m01_axi_wstrb, + output wire m01_axi_wlast, + output wire [WUSER_WIDTH-1:0] m01_axi_wuser, + output wire m01_axi_wvalid, + input wire m01_axi_wready, + input wire [M_ID_WIDTH-1:0] m01_axi_bid, + input wire [1:0] m01_axi_bresp, + input wire [BUSER_WIDTH-1:0] m01_axi_buser, + input wire m01_axi_bvalid, + output wire m01_axi_bready, + output wire [M_ID_WIDTH-1:0] m01_axi_arid, + output wire [ADDR_WIDTH-1:0] m01_axi_araddr, + output wire [7:0] m01_axi_arlen, + output wire [2:0] m01_axi_arsize, + output wire [1:0] m01_axi_arburst, + output wire m01_axi_arlock, + output wire [3:0] m01_axi_arcache, + output wire [2:0] m01_axi_arprot, + output wire [3:0] m01_axi_arqos, + output wire [3:0] m01_axi_arregion, + output wire [ARUSER_WIDTH-1:0] m01_axi_aruser, + output wire m01_axi_arvalid, + input wire m01_axi_arready, + input wire [M_ID_WIDTH-1:0] m01_axi_rid, + input wire [DATA_WIDTH-1:0] m01_axi_rdata, + input wire [1:0] m01_axi_rresp, + input wire m01_axi_rlast, + input wire [RUSER_WIDTH-1:0] m01_axi_ruser, + input wire m01_axi_rvalid, + output wire m01_axi_rready, + + output wire [M_ID_WIDTH-1:0] m02_axi_awid, + output wire [ADDR_WIDTH-1:0] m02_axi_awaddr, + output wire [7:0] m02_axi_awlen, + output wire [2:0] m02_axi_awsize, + output wire [1:0] m02_axi_awburst, + output wire m02_axi_awlock, + output wire [3:0] m02_axi_awcache, + output wire [2:0] m02_axi_awprot, + output wire [3:0] m02_axi_awqos, + output wire [3:0] m02_axi_awregion, + output wire [AWUSER_WIDTH-1:0] m02_axi_awuser, + output wire m02_axi_awvalid, + input wire m02_axi_awready, + output wire [DATA_WIDTH-1:0] m02_axi_wdata, + output wire [STRB_WIDTH-1:0] m02_axi_wstrb, + output wire m02_axi_wlast, + output wire [WUSER_WIDTH-1:0] m02_axi_wuser, + output wire m02_axi_wvalid, + input wire m02_axi_wready, + input wire [M_ID_WIDTH-1:0] m02_axi_bid, + input wire [1:0] m02_axi_bresp, + input wire [BUSER_WIDTH-1:0] m02_axi_buser, + input wire m02_axi_bvalid, + output wire m02_axi_bready, + output wire [M_ID_WIDTH-1:0] m02_axi_arid, + output wire [ADDR_WIDTH-1:0] m02_axi_araddr, + output wire [7:0] m02_axi_arlen, + output wire [2:0] m02_axi_arsize, + output wire [1:0] m02_axi_arburst, + output wire m02_axi_arlock, + output wire [3:0] m02_axi_arcache, + output wire [2:0] m02_axi_arprot, + output wire [3:0] m02_axi_arqos, + output wire [3:0] m02_axi_arregion, + output wire [ARUSER_WIDTH-1:0] m02_axi_aruser, + output wire m02_axi_arvalid, + input wire m02_axi_arready, + input wire [M_ID_WIDTH-1:0] m02_axi_rid, + input wire [DATA_WIDTH-1:0] m02_axi_rdata, + input wire [1:0] m02_axi_rresp, + input wire m02_axi_rlast, + input wire [RUSER_WIDTH-1:0] m02_axi_ruser, + input wire m02_axi_rvalid, + output wire m02_axi_rready +); + +localparam S_COUNT = 3; +localparam M_COUNT = 3; + +// parameter sizing helpers +function [ADDR_WIDTH*M_REGIONS-1:0] w_a_r(input [ADDR_WIDTH*M_REGIONS-1:0] val); + w_a_r = val; +endfunction + +function [32*M_REGIONS-1:0] w_32_r(input [32*M_REGIONS-1:0] val); + w_32_r = val; +endfunction + +function [S_COUNT-1:0] w_s(input [S_COUNT-1:0] val); + w_s = val; +endfunction + +function [31:0] w_32(input [31:0] val); + w_32 = val; +endfunction + +function [1:0] w_2(input [1:0] val); + w_2 = val; +endfunction + +function w_1(input val); + w_1 = val; +endfunction + +axi_crossbar #( + .S_COUNT(S_COUNT), + .M_COUNT(M_COUNT), + .DATA_WIDTH(DATA_WIDTH), + .ADDR_WIDTH(ADDR_WIDTH), + .STRB_WIDTH(STRB_WIDTH), + .S_ID_WIDTH(S_ID_WIDTH), + .M_ID_WIDTH(M_ID_WIDTH), + .AWUSER_ENABLE(AWUSER_ENABLE), + .AWUSER_WIDTH(AWUSER_WIDTH), + .WUSER_ENABLE(WUSER_ENABLE), + .WUSER_WIDTH(WUSER_WIDTH), + .BUSER_ENABLE(BUSER_ENABLE), + .BUSER_WIDTH(BUSER_WIDTH), + .ARUSER_ENABLE(ARUSER_ENABLE), + .ARUSER_WIDTH(ARUSER_WIDTH), + .RUSER_ENABLE(RUSER_ENABLE), + .RUSER_WIDTH(RUSER_WIDTH), + .S_THREADS({ w_32(S02_THREADS), w_32(S01_THREADS), w_32(S00_THREADS) }), + .S_ACCEPT({ w_32(S02_ACCEPT), w_32(S01_ACCEPT), w_32(S00_ACCEPT) }), + .M_REGIONS(M_REGIONS), + .M_BASE_ADDR({ w_a_r(M02_BASE_ADDR), w_a_r(M01_BASE_ADDR), w_a_r(M00_BASE_ADDR) }), + .M_ADDR_WIDTH({ w_32_r(M02_ADDR_WIDTH), w_32_r(M01_ADDR_WIDTH), w_32_r(M00_ADDR_WIDTH) }), + .M_CONNECT_READ({ w_s(M02_CONNECT_READ), w_s(M01_CONNECT_READ), w_s(M00_CONNECT_READ) }), + .M_CONNECT_WRITE({ w_s(M02_CONNECT_WRITE), w_s(M01_CONNECT_WRITE), w_s(M00_CONNECT_WRITE) }), + .M_ISSUE({ w_32(M02_ISSUE), w_32(M01_ISSUE), w_32(M00_ISSUE) }), + .M_SECURE({ w_1(M02_SECURE), w_1(M01_SECURE), w_1(M00_SECURE) }), + .S_AR_REG_TYPE({ w_2(S02_AR_REG_TYPE), w_2(S01_AR_REG_TYPE), w_2(S00_AR_REG_TYPE) }), + .S_R_REG_TYPE({ w_2(S02_R_REG_TYPE), w_2(S01_R_REG_TYPE), w_2(S00_R_REG_TYPE) }), + .S_AW_REG_TYPE({ w_2(S02_AW_REG_TYPE), w_2(S01_AW_REG_TYPE), w_2(S00_AW_REG_TYPE) }), + .S_W_REG_TYPE({ w_2(S02_W_REG_TYPE), w_2(S01_W_REG_TYPE), w_2(S00_W_REG_TYPE) }), + .S_B_REG_TYPE({ w_2(S02_B_REG_TYPE), w_2(S01_B_REG_TYPE), w_2(S00_B_REG_TYPE) }), + .M_AR_REG_TYPE({ w_2(M02_AR_REG_TYPE), w_2(M01_AR_REG_TYPE), w_2(M00_AR_REG_TYPE) }), + .M_R_REG_TYPE({ w_2(M02_R_REG_TYPE), w_2(M01_R_REG_TYPE), w_2(M00_R_REG_TYPE) }), + .M_AW_REG_TYPE({ w_2(M02_AW_REG_TYPE), w_2(M01_AW_REG_TYPE), w_2(M00_AW_REG_TYPE) }), + .M_W_REG_TYPE({ w_2(M02_W_REG_TYPE), w_2(M01_W_REG_TYPE), w_2(M00_W_REG_TYPE) }), + .M_B_REG_TYPE({ w_2(M02_B_REG_TYPE), w_2(M01_B_REG_TYPE), w_2(M00_B_REG_TYPE) }) +) +axi_crossbar_inst ( + .clk(clk), + .rst(rst), + .s_axi_awid({ s02_axi_awid, s01_axi_awid, s00_axi_awid }), + .s_axi_awaddr({ s02_axi_awaddr, s01_axi_awaddr, s00_axi_awaddr }), + .s_axi_awlen({ s02_axi_awlen, s01_axi_awlen, s00_axi_awlen }), + .s_axi_awsize({ s02_axi_awsize, s01_axi_awsize, s00_axi_awsize }), + .s_axi_awburst({ s02_axi_awburst, s01_axi_awburst, s00_axi_awburst }), + .s_axi_awlock({ s02_axi_awlock, s01_axi_awlock, s00_axi_awlock }), + .s_axi_awcache({ s02_axi_awcache, s01_axi_awcache, s00_axi_awcache }), + .s_axi_awprot({ s02_axi_awprot, s01_axi_awprot, s00_axi_awprot }), + .s_axi_awqos({ s02_axi_awqos, s01_axi_awqos, s00_axi_awqos }), + .s_axi_awuser({ s02_axi_awuser, s01_axi_awuser, s00_axi_awuser }), + .s_axi_awvalid({ s02_axi_awvalid, s01_axi_awvalid, s00_axi_awvalid }), + .s_axi_awready({ s02_axi_awready, s01_axi_awready, s00_axi_awready }), + .s_axi_wdata({ s02_axi_wdata, s01_axi_wdata, s00_axi_wdata }), + .s_axi_wstrb({ s02_axi_wstrb, s01_axi_wstrb, s00_axi_wstrb }), + .s_axi_wlast({ s02_axi_wlast, s01_axi_wlast, s00_axi_wlast }), + .s_axi_wuser({ s02_axi_wuser, s01_axi_wuser, s00_axi_wuser }), + .s_axi_wvalid({ s02_axi_wvalid, s01_axi_wvalid, s00_axi_wvalid }), + .s_axi_wready({ s02_axi_wready, s01_axi_wready, s00_axi_wready }), + .s_axi_bid({ s02_axi_bid, s01_axi_bid, s00_axi_bid }), + .s_axi_bresp({ s02_axi_bresp, s01_axi_bresp, s00_axi_bresp }), + .s_axi_buser({ s02_axi_buser, s01_axi_buser, s00_axi_buser }), + .s_axi_bvalid({ s02_axi_bvalid, s01_axi_bvalid, s00_axi_bvalid }), + .s_axi_bready({ s02_axi_bready, s01_axi_bready, s00_axi_bready }), + .s_axi_arid({ s02_axi_arid, s01_axi_arid, s00_axi_arid }), + .s_axi_araddr({ s02_axi_araddr, s01_axi_araddr, s00_axi_araddr }), + .s_axi_arlen({ s02_axi_arlen, s01_axi_arlen, s00_axi_arlen }), + .s_axi_arsize({ s02_axi_arsize, s01_axi_arsize, s00_axi_arsize }), + .s_axi_arburst({ s02_axi_arburst, s01_axi_arburst, s00_axi_arburst }), + .s_axi_arlock({ s02_axi_arlock, s01_axi_arlock, s00_axi_arlock }), + .s_axi_arcache({ s02_axi_arcache, s01_axi_arcache, s00_axi_arcache }), + .s_axi_arprot({ s02_axi_arprot, s01_axi_arprot, s00_axi_arprot }), + .s_axi_arqos({ s02_axi_arqos, s01_axi_arqos, s00_axi_arqos }), + .s_axi_aruser({ s02_axi_aruser, s01_axi_aruser, s00_axi_aruser }), + .s_axi_arvalid({ s02_axi_arvalid, s01_axi_arvalid, s00_axi_arvalid }), + .s_axi_arready({ s02_axi_arready, s01_axi_arready, s00_axi_arready }), + .s_axi_rid({ s02_axi_rid, s01_axi_rid, s00_axi_rid }), + .s_axi_rdata({ s02_axi_rdata, s01_axi_rdata, s00_axi_rdata }), + .s_axi_rresp({ s02_axi_rresp, s01_axi_rresp, s00_axi_rresp }), + .s_axi_rlast({ s02_axi_rlast, s01_axi_rlast, s00_axi_rlast }), + .s_axi_ruser({ s02_axi_ruser, s01_axi_ruser, s00_axi_ruser }), + .s_axi_rvalid({ s02_axi_rvalid, s01_axi_rvalid, s00_axi_rvalid }), + .s_axi_rready({ s02_axi_rready, s01_axi_rready, s00_axi_rready }), + .m_axi_awid({ m02_axi_awid, m01_axi_awid, m00_axi_awid }), + .m_axi_awaddr({ m02_axi_awaddr, m01_axi_awaddr, m00_axi_awaddr }), + .m_axi_awlen({ m02_axi_awlen, m01_axi_awlen, m00_axi_awlen }), + .m_axi_awsize({ m02_axi_awsize, m01_axi_awsize, m00_axi_awsize }), + .m_axi_awburst({ m02_axi_awburst, m01_axi_awburst, m00_axi_awburst }), + .m_axi_awlock({ m02_axi_awlock, m01_axi_awlock, m00_axi_awlock }), + .m_axi_awcache({ m02_axi_awcache, m01_axi_awcache, m00_axi_awcache }), + .m_axi_awprot({ m02_axi_awprot, m01_axi_awprot, m00_axi_awprot }), + .m_axi_awqos({ m02_axi_awqos, m01_axi_awqos, m00_axi_awqos }), + .m_axi_awregion({ m02_axi_awregion, m01_axi_awregion, m00_axi_awregion }), + .m_axi_awuser({ m02_axi_awuser, m01_axi_awuser, m00_axi_awuser }), + .m_axi_awvalid({ m02_axi_awvalid, m01_axi_awvalid, m00_axi_awvalid }), + .m_axi_awready({ m02_axi_awready, m01_axi_awready, m00_axi_awready }), + .m_axi_wdata({ m02_axi_wdata, m01_axi_wdata, m00_axi_wdata }), + .m_axi_wstrb({ m02_axi_wstrb, m01_axi_wstrb, m00_axi_wstrb }), + .m_axi_wlast({ m02_axi_wlast, m01_axi_wlast, m00_axi_wlast }), + .m_axi_wuser({ m02_axi_wuser, m01_axi_wuser, m00_axi_wuser }), + .m_axi_wvalid({ m02_axi_wvalid, m01_axi_wvalid, m00_axi_wvalid }), + .m_axi_wready({ m02_axi_wready, m01_axi_wready, m00_axi_wready }), + .m_axi_bid({ m02_axi_bid, m01_axi_bid, m00_axi_bid }), + .m_axi_bresp({ m02_axi_bresp, m01_axi_bresp, m00_axi_bresp }), + .m_axi_buser({ m02_axi_buser, m01_axi_buser, m00_axi_buser }), + .m_axi_bvalid({ m02_axi_bvalid, m01_axi_bvalid, m00_axi_bvalid }), + .m_axi_bready({ m02_axi_bready, m01_axi_bready, m00_axi_bready }), + .m_axi_arid({ m02_axi_arid, m01_axi_arid, m00_axi_arid }), + .m_axi_araddr({ m02_axi_araddr, m01_axi_araddr, m00_axi_araddr }), + .m_axi_arlen({ m02_axi_arlen, m01_axi_arlen, m00_axi_arlen }), + .m_axi_arsize({ m02_axi_arsize, m01_axi_arsize, m00_axi_arsize }), + .m_axi_arburst({ m02_axi_arburst, m01_axi_arburst, m00_axi_arburst }), + .m_axi_arlock({ m02_axi_arlock, m01_axi_arlock, m00_axi_arlock }), + .m_axi_arcache({ m02_axi_arcache, m01_axi_arcache, m00_axi_arcache }), + .m_axi_arprot({ m02_axi_arprot, m01_axi_arprot, m00_axi_arprot }), + .m_axi_arqos({ m02_axi_arqos, m01_axi_arqos, m00_axi_arqos }), + .m_axi_arregion({ m02_axi_arregion, m01_axi_arregion, m00_axi_arregion }), + .m_axi_aruser({ m02_axi_aruser, m01_axi_aruser, m00_axi_aruser }), + .m_axi_arvalid({ m02_axi_arvalid, m01_axi_arvalid, m00_axi_arvalid }), + .m_axi_arready({ m02_axi_arready, m01_axi_arready, m00_axi_arready }), + .m_axi_rid({ m02_axi_rid, m01_axi_rid, m00_axi_rid }), + .m_axi_rdata({ m02_axi_rdata, m01_axi_rdata, m00_axi_rdata }), + .m_axi_rresp({ m02_axi_rresp, m01_axi_rresp, m00_axi_rresp }), + .m_axi_rlast({ m02_axi_rlast, m01_axi_rlast, m00_axi_rlast }), + .m_axi_ruser({ m02_axi_ruser, m01_axi_ruser, m00_axi_ruser }), + .m_axi_rvalid({ m02_axi_rvalid, m01_axi_rvalid, m00_axi_rvalid }), + .m_axi_rready({ m02_axi_rready, m01_axi_rready, m00_axi_rready }) +); + +endmodule + +`resetall diff --git a/external/external/rtl_libs/axi/rtl/axi_crossbar_wrapper.sv b/external/external/rtl_libs/axi/rtl/axi_crossbar_wrapper.sv new file mode 100644 index 0000000..c3212bd --- /dev/null +++ b/external/external/rtl_libs/axi/rtl/axi_crossbar_wrapper.sv @@ -0,0 +1,1045 @@ +module axi_crossbar_wrapper #( + parameter int SLAVE_QTY = 3, + parameter int MASTER_QTY = 3, + parameter int ADDR_WIDTH = 32, + parameter int DATA_WIDTH = 32, + parameter int STRB_WIDTH = (DATA_WIDTH/8) +)( + input wire clk, + input wire rst, + + axi4_if.slave s_axi [SLAVE_QTY], + axi4_if.master m_axi [MASTER_QTY] +); + + localparam CROSSBAR_DATA_WIDTH = DATA_WIDTH; + localparam CROSSBAR_ADDR_WIDTH = ADDR_WIDTH; + localparam CROSSBAR_STRB_WIDTH = (CROSSBAR_DATA_WIDTH/8); + localparam CROSSBAR_S_ID_WIDTH = 8; + localparam CROSSBAR_M_ID_WIDTH = S_ID_WIDTH+$clog2(S_COUNT); + localparam CROSSBAR_AWUSER_ENABLE = 0; + localparam CROSSBAR_AWUSER_WIDTH = 1; + localparam CROSSBAR_WUSER_ENABLE = 0; + localparam CROSSBAR_WUSER_WIDTH = 1; + localparam CROSSBAR_BUSER_ENABLE = 0; + localparam CROSSBAR_BUSER_WIDTH = 1; + localparam CROSSBAR_ARUSER_ENABLE = 0; + localparam CROSSBAR_ARUSER_WIDTH = 1; + localparam CROSSBAR_RUSER_ENABLE = 0; + localparam CROSSBAR_RUSER_WIDTH = 1; + localparam CROSSBAR_S00_THREADS = 2; + localparam CROSSBAR_S00_ACCEPT = 16; + localparam CROSSBAR_S01_THREADS = 2; + localparam CROSSBAR_S01_ACCEPT = 16; + localparam CROSSBAR_S02_THREADS = 2; + localparam CROSSBAR_S02_ACCEPT = 16; + localparam CROSSBAR_M_REGIONS = 1; + localparam CROSSBAR_M00_BASE_ADDR = 0; + localparam CROSSBAR_M00_ADDR_WIDTH = {M_REGIONS{32'd24}}; + localparam CROSSBAR_M00_CONNECT_READ = 3'b111; + localparam CROSSBAR_M00_CONNECT_WRITE = 3'b111; + localparam CROSSBAR_M00_ISSUE = 4; + localparam CROSSBAR_M00_SECURE = 0; + localparam CROSSBAR_M01_BASE_ADDR = 32'h00001000; + localparam CROSSBAR_M01_ADDR_WIDTH = {M_REGIONS{32'd24}}; + localparam CROSSBAR_M01_CONNECT_READ = 3'b111; + localparam CROSSBAR_M01_CONNECT_WRITE = 3'b111; + localparam CROSSBAR_M01_ISSUE = 4; + localparam CROSSBAR_M01_SECURE = 0; + localparam CROSSBAR_M02_BASE_ADDR = 32'h00002000; + localparam CROSSBAR_M02_ADDR_WIDTH = {M_REGIONS{32'd24}}; + localparam CROSSBAR_M02_CONNECT_READ = 3'b111; + localparam CROSSBAR_M02_CONNECT_WRITE = 3'b111; + localparam CROSSBAR_M02_ISSUE = 4; + localparam CROSSBAR_M02_SECURE = 0; + localparam CROSSBAR_S00_AW_REG_TYPE = 0; + localparam CROSSBAR_S00_W_REG_TYPE = 0; + localparam CROSSBAR_S00_B_REG_TYPE = 1; + localparam CROSSBAR_S00_AR_REG_TYPE = 0; + localparam CROSSBAR_S00_R_REG_TYPE = 2; + localparam CROSSBAR_S01_AW_REG_TYPE = 0; + localparam CROSSBAR_S01_W_REG_TYPE = 0; + localparam CROSSBAR_S01_B_REG_TYPE = 1; + localparam CROSSBAR_S01_AR_REG_TYPE = 0; + localparam CROSSBAR_S01_R_REG_TYPE = 2; + localparam CROSSBAR_S02_AW_REG_TYPE = 0; + localparam CROSSBAR_S02_W_REG_TYPE = 0; + localparam CROSSBAR_S02_B_REG_TYPE = 1; + localparam CROSSBAR_S02_AR_REG_TYPE = 0; + localparam CROSSBAR_S02_R_REG_TYPE = 2; + localparam CROSSBAR_M00_AW_REG_TYPE = 1; + localparam CROSSBAR_M00_W_REG_TYPE = 2; + localparam CROSSBAR_M00_B_REG_TYPE = 0; + localparam CROSSBAR_M00_AR_REG_TYPE = 1; + localparam CROSSBAR_M00_R_REG_TYPE = 0; + localparam CROSSBAR_M01_AW_REG_TYPE = 1; + localparam CROSSBAR_M01_W_REG_TYPE = 2; + localparam CROSSBAR_M01_B_REG_TYPE = 0; + localparam CROSSBAR_M01_AR_REG_TYPE = 1; + localparam CROSSBAR_M01_R_REG_TYPE = 0; + localparam CROSSBAR_M02_AW_REG_TYPE = 1; + localparam CROSSBAR_M02_W_REG_TYPE = 2; + localparam CROSSBAR_M02_B_REG_TYPE = 0; + localparam CROSSBAR_M02_AR_REG_TYPE = 1; + localparam CROSSBAR_M02_R_REG_TYPE = 0; + + wire crossbar_clk; + wire crossbar_rst; + wire [CROSSBAR_S_ID_WIDTH-1:0] crossbar_s00_axi_awid; + wire [CROSSBAR_ADDR_WIDTH-1:0] crossbar_s00_axi_awaddr; + wire [7:0] crossbar_s00_axi_awlen; + wire [2:0] crossbar_s00_axi_awsize; + wire [1:0] crossbar_s00_axi_awburst; + wire crossbar_s00_axi_awlock; + wire [3:0] crossbar_s00_axi_awcache; + wire [2:0] crossbar_s00_axi_awprot; + wire [3:0] crossbar_s00_axi_awqos; + wire [CROSSBAR_AWUSER_WIDTH-1:0] crossbar_s00_axi_awuser; + wire crossbar_s00_axi_awvalid; + wire crossbar_s00_axi_awready; + wire [CROSSBAR_DATA_WIDTH-1:0] crossbar_s00_axi_wdata; + wire [CROSSBAR_STRB_WIDTH-1:0] crossbar_s00_axi_wstrb; + wire crossbar_s00_axi_wlast; + wire [CROSSBAR_WUSER_WIDTH-1:0] crossbar_s00_axi_wuser; + wire crossbar_s00_axi_wvalid; + wire crossbar_s00_axi_wready; + wire [CROSSBAR_S_ID_WIDTH-1:0] crossbar_s00_axi_bid; + wire [1:0] crossbar_s00_axi_bresp; + wire [CROSSBAR_BUSER_WIDTH-1:0] crossbar_s00_axi_buser; + wire crossbar_s00_axi_bvalid; + wire crossbar_s00_axi_bready; + wire [CROSSBAR_S_ID_WIDTH-1:0] crossbar_s00_axi_arid; + wire [CROSSBAR_ADDR_WIDTH-1:0] crossbar_s00_axi_araddr; + wire [7:0] crossbar_s00_axi_arlen; + wire [2:0] crossbar_s00_axi_arsize; + wire [1:0] crossbar_s00_axi_arburst; + wire crossbar_s00_axi_arlock; + wire [3:0] crossbar_s00_axi_arcache; + wire [2:0] crossbar_s00_axi_arprot; + wire [3:0] crossbar_s00_axi_arqos; + wire [CROSSBAR_ARUSER_WIDTH-1:0] crossbar_s00_axi_aruser; + wire crossbar_s00_axi_arvalid; + wire crossbar_s00_axi_arready; + wire [CROSSBAR_S_ID_WIDTH-1:0] crossbar_s00_axi_rid; + wire [CROSSBAR_DATA_WIDTH-1:0] crossbar_s00_axi_rdata; + wire [1:0] crossbar_s00_axi_rresp; + wire crossbar_s00_axi_rlast; + wire [CROSSBAR_RUSER_WIDTH-1:0] crossbar_s00_axi_ruser; + wire crossbar_s00_axi_rvalid; + wire crossbar_s00_axi_rready; + wire [CROSSBAR_S_ID_WIDTH-1:0] crossbar_s01_axi_awid; + wire [CROSSBAR_ADDR_WIDTH-1:0] crossbar_s01_axi_awaddr; + wire [7:0] crossbar_s01_axi_awlen; + wire [2:0] crossbar_s01_axi_awsize; + wire [1:0] crossbar_s01_axi_awburst; + wire crossbar_s01_axi_awlock; + wire [3:0] crossbar_s01_axi_awcache; + wire [2:0] crossbar_s01_axi_awprot; + wire [3:0] crossbar_s01_axi_awqos; + wire [CROSSBAR_AWUSER_WIDTH-1:0] crossbar_s01_axi_awuser; + wire crossbar_s01_axi_awvalid; + wire crossbar_s01_axi_awready; + wire [CROSSBAR_DATA_WIDTH-1:0] crossbar_s01_axi_wdata; + wire [CROSSBAR_STRB_WIDTH-1:0] crossbar_s01_axi_wstrb; + wire crossbar_s01_axi_wlast; + wire [CROSSBAR_WUSER_WIDTH-1:0] crossbar_s01_axi_wuser; + wire crossbar_s01_axi_wvalid; + wire crossbar_s01_axi_wready; + wire [CROSSBAR_S_ID_WIDTH-1:0] crossbar_s01_axi_bid; + wire [1:0] crossbar_s01_axi_bresp; + wire [CROSSBAR_BUSER_WIDTH-1:0] crossbar_s01_axi_buser; + wire crossbar_s01_axi_bvalid; + wire crossbar_s01_axi_bready; + wire [CROSSBAR_S_ID_WIDTH-1:0] crossbar_s01_axi_arid; + wire [CROSSBAR_ADDR_WIDTH-1:0] crossbar_s01_axi_araddr; + wire [7:0] crossbar_s01_axi_arlen; + wire [2:0] crossbar_s01_axi_arsize; + wire [1:0] crossbar_s01_axi_arburst; + wire crossbar_s01_axi_arlock; + wire [3:0] crossbar_s01_axi_arcache; + wire [2:0] crossbar_s01_axi_arprot; + wire [3:0] crossbar_s01_axi_arqos; + wire [CROSSBAR_ARUSER_WIDTH-1:0] crossbar_s01_axi_aruser; + wire crossbar_s01_axi_arvalid; + wire crossbar_s01_axi_arready; + wire [CROSSBAR_S_ID_WIDTH-1:0] crossbar_s01_axi_rid; + wire [CROSSBAR_DATA_WIDTH-1:0] crossbar_s01_axi_rdata; + wire [1:0] crossbar_s01_axi_rresp; + wire crossbar_s01_axi_rlast; + wire [CROSSBAR_RUSER_WIDTH-1:0] crossbar_s01_axi_ruser; + wire crossbar_s01_axi_rvalid; + wire crossbar_s01_axi_rready; + wire [CROSSBAR_S_ID_WIDTH-1:0] crossbar_s02_axi_awid; + wire [CROSSBAR_ADDR_WIDTH-1:0] crossbar_s02_axi_awaddr; + wire [7:0] crossbar_s02_axi_awlen; + wire [2:0] crossbar_s02_axi_awsize; + wire [1:0] crossbar_s02_axi_awburst; + wire crossbar_s02_axi_awlock; + wire [3:0] crossbar_s02_axi_awcache; + wire [2:0] crossbar_s02_axi_awprot; + wire [3:0] crossbar_s02_axi_awqos; + wire [CROSSBAR_AWUSER_WIDTH-1:0] crossbar_s02_axi_awuser; + wire crossbar_s02_axi_awvalid; + wire crossbar_s02_axi_awready; + wire [CROSSBAR_DATA_WIDTH-1:0] crossbar_s02_axi_wdata; + wire [CROSSBAR_STRB_WIDTH-1:0] crossbar_s02_axi_wstrb; + wire crossbar_s02_axi_wlast; + wire [CROSSBAR_WUSER_WIDTH-1:0] crossbar_s02_axi_wuser; + wire crossbar_s02_axi_wvalid; + wire crossbar_s02_axi_wready; + wire [CROSSBAR_S_ID_WIDTH-1:0] crossbar_s02_axi_bid; + wire [1:0] crossbar_s02_axi_bresp; + wire [CROSSBAR_BUSER_WIDTH-1:0] crossbar_s02_axi_buser; + wire crossbar_s02_axi_bvalid; + wire crossbar_s02_axi_bready; + wire [CROSSBAR_S_ID_WIDTH-1:0] crossbar_s02_axi_arid; + wire [CROSSBAR_ADDR_WIDTH-1:0] crossbar_s02_axi_araddr; + wire [7:0] crossbar_s02_axi_arlen; + wire [2:0] crossbar_s02_axi_arsize; + wire [1:0] crossbar_s02_axi_arburst; + wire crossbar_s02_axi_arlock; + wire [3:0] crossbar_s02_axi_arcache; + wire [2:0] crossbar_s02_axi_arprot; + wire [3:0] crossbar_s02_axi_arqos; + wire [CROSSBAR_ARUSER_WIDTH-1:0] crossbar_s02_axi_aruser; + wire crossbar_s02_axi_arvalid; + wire crossbar_s02_axi_arready; + wire [CROSSBAR_S_ID_WIDTH-1:0] crossbar_s02_axi_rid; + wire [CROSSBAR_DATA_WIDTH-1:0] crossbar_s02_axi_rdata; + wire [1:0] crossbar_s02_axi_rresp; + wire crossbar_s02_axi_rlast; + wire [CROSSBAR_RUSER_WIDTH-1:0] crossbar_s02_axi_ruser; + wire crossbar_s02_axi_rvalid; + wire crossbar_s02_axi_rready; + wire [CROSSBAR_M_ID_WIDTH-1:0] crossbar_m00_axi_awid; + wire [CROSSBAR_ADDR_WIDTH-1:0] crossbar_m00_axi_awaddr; + wire [7:0] crossbar_m00_axi_awlen; + wire [2:0] crossbar_m00_axi_awsize; + wire [1:0] crossbar_m00_axi_awburst; + wire crossbar_m00_axi_awlock; + wire [3:0] crossbar_m00_axi_awcache; + wire [2:0] crossbar_m00_axi_awprot; + wire [3:0] crossbar_m00_axi_awqos; + wire [3:0] crossbar_m00_axi_awregion; + wire [CROSSBAR_AWUSER_WIDTH-1:0] crossbar_m00_axi_awuser; + wire crossbar_m00_axi_awvalid; + wire crossbar_m00_axi_awready; + wire [CROSSBAR_DATA_WIDTH-1:0] crossbar_m00_axi_wdata; + wire [CROSSBAR_STRB_WIDTH-1:0] crossbar_m00_axi_wstrb; + wire crossbar_m00_axi_wlast; + wire [CROSSBAR_WUSER_WIDTH-1:0] crossbar_m00_axi_wuser; + wire crossbar_m00_axi_wvalid; + wire crossbar_m00_axi_wready; + wire [CROSSBAR_M_ID_WIDTH-1:0] crossbar_m00_axi_bid; + wire [1:0] crossbar_m00_axi_bresp; + wire [CROSSBAR_BUSER_WIDTH-1:0] crossbar_m00_axi_buser; + wire crossbar_m00_axi_bvalid; + wire crossbar_m00_axi_bready; + wire [CROSSBAR_M_ID_WIDTH-1:0] crossbar_m00_axi_arid; + wire [CROSSBAR_ADDR_WIDTH-1:0] crossbar_m00_axi_araddr; + wire [7:0] crossbar_m00_axi_arlen; + wire [2:0] crossbar_m00_axi_arsize; + wire [1:0] crossbar_m00_axi_arburst; + wire crossbar_m00_axi_arlock; + wire [3:0] crossbar_m00_axi_arcache; + wire [2:0] crossbar_m00_axi_arprot; + wire [3:0] crossbar_m00_axi_arqos; + wire [3:0] crossbar_m00_axi_arregion; + wire [CROSSBAR_ARUSER_WIDTH-1:0] crossbar_m00_axi_aruser; + wire crossbar_m00_axi_arvalid; + wire crossbar_m00_axi_arready; + wire [CROSSBAR_M_ID_WIDTH-1:0] crossbar_m00_axi_rid; + wire [CROSSBAR_DATA_WIDTH-1:0] crossbar_m00_axi_rdata; + wire [1:0] crossbar_m00_axi_rresp; + wire crossbar_m00_axi_rlast; + wire [CROSSBAR_RUSER_WIDTH-1:0] crossbar_m00_axi_ruser; + wire crossbar_m00_axi_rvalid; + wire crossbar_m00_axi_rready; + wire [CROSSBAR_M_ID_WIDTH-1:0] crossbar_m01_axi_awid; + wire [CROSSBAR_ADDR_WIDTH-1:0] crossbar_m01_axi_awaddr; + wire [7:0] crossbar_m01_axi_awlen; + wire [2:0] crossbar_m01_axi_awsize; + wire [1:0] crossbar_m01_axi_awburst; + wire crossbar_m01_axi_awlock; + wire [3:0] crossbar_m01_axi_awcache; + wire [2:0] crossbar_m01_axi_awprot; + wire [3:0] crossbar_m01_axi_awqos; + wire [3:0] crossbar_m01_axi_awregion; + wire [CROSSBAR_AWUSER_WIDTH-1:0] crossbar_m01_axi_awuser; + wire crossbar_m01_axi_awvalid; + wire crossbar_m01_axi_awready; + wire [CROSSBAR_DATA_WIDTH-1:0] crossbar_m01_axi_wdata; + wire [CROSSBAR_STRB_WIDTH-1:0] crossbar_m01_axi_wstrb; + wire crossbar_m01_axi_wlast; + wire [CROSSBAR_WUSER_WIDTH-1:0] crossbar_m01_axi_wuser; + wire crossbar_m01_axi_wvalid; + wire crossbar_m01_axi_wready; + wire [CROSSBAR_M_ID_WIDTH-1:0] crossbar_m01_axi_bid; + wire [1:0] crossbar_m01_axi_bresp; + wire [CROSSBAR_BUSER_WIDTH-1:0] crossbar_m01_axi_buser; + wire crossbar_m01_axi_bvalid; + wire crossbar_m01_axi_bready; + wire [CROSSBAR_M_ID_WIDTH-1:0] crossbar_m01_axi_arid; + wire [CROSSBAR_ADDR_WIDTH-1:0] crossbar_m01_axi_araddr; + wire [7:0] crossbar_m01_axi_arlen; + wire [2:0] crossbar_m01_axi_arsize; + wire [1:0] crossbar_m01_axi_arburst; + wire crossbar_m01_axi_arlock; + wire [3:0] crossbar_m01_axi_arcache; + wire [2:0] crossbar_m01_axi_arprot; + wire [3:0] crossbar_m01_axi_arqos; + wire [3:0] crossbar_m01_axi_arregion; + wire [CROSSBAR_ARUSER_WIDTH-1:0] crossbar_m01_axi_aruser; + wire crossbar_m01_axi_arvalid; + wire crossbar_m01_axi_arready; + wire [CROSSBAR_M_ID_WIDTH-1:0] crossbar_m01_axi_rid; + wire [CROSSBAR_DATA_WIDTH-1:0] crossbar_m01_axi_rdata; + wire [1:0] crossbar_m01_axi_rresp; + wire crossbar_m01_axi_rlast; + wire [CROSSBAR_RUSER_WIDTH-1:0] crossbar_m01_axi_ruser; + wire crossbar_m01_axi_rvalid; + wire crossbar_m01_axi_rready; + wire [CROSSBAR_M_ID_WIDTH-1:0] crossbar_m02_axi_awid; + wire [CROSSBAR_ADDR_WIDTH-1:0] crossbar_m02_axi_awaddr; + wire [7:0] crossbar_m02_axi_awlen; + wire [2:0] crossbar_m02_axi_awsize; + wire [1:0] crossbar_m02_axi_awburst; + wire crossbar_m02_axi_awlock; + wire [3:0] crossbar_m02_axi_awcache; + wire [2:0] crossbar_m02_axi_awprot; + wire [3:0] crossbar_m02_axi_awqos; + wire [3:0] crossbar_m02_axi_awregion; + wire [CROSSBAR_AWUSER_WIDTH-1:0] crossbar_m02_axi_awuser; + wire crossbar_m02_axi_awvalid; + wire crossbar_m02_axi_awready; + wire [CROSSBAR_DATA_WIDTH-1:0] crossbar_m02_axi_wdata; + wire [CROSSBAR_STRB_WIDTH-1:0] crossbar_m02_axi_wstrb; + wire crossbar_m02_axi_wlast; + wire [CROSSBAR_WUSER_WIDTH-1:0] crossbar_m02_axi_wuser; + wire crossbar_m02_axi_wvalid; + wire crossbar_m02_axi_wready; + wire [CROSSBAR_M_ID_WIDTH-1:0] crossbar_m02_axi_bid; + wire [1:0] crossbar_m02_axi_bresp; + wire [CROSSBAR_BUSER_WIDTH-1:0] crossbar_m02_axi_buser; + wire crossbar_m02_axi_bvalid; + wire crossbar_m02_axi_bready; + wire [CROSSBAR_M_ID_WIDTH-1:0] crossbar_m02_axi_arid; + wire [CROSSBAR_ADDR_WIDTH-1:0] crossbar_m02_axi_araddr; + wire [7:0] crossbar_m02_axi_arlen; + wire [2:0] crossbar_m02_axi_arsize; + wire [1:0] crossbar_m02_axi_arburst; + wire crossbar_m02_axi_arlock; + wire [3:0] crossbar_m02_axi_arcache; + wire [2:0] crossbar_m02_axi_arprot; + wire [3:0] crossbar_m02_axi_arqos; + wire [3:0] crossbar_m02_axi_arregion; + wire [CROSSBAR_ARUSER_WIDTH-1:0] crossbar_m02_axi_aruser; + wire crossbar_m02_axi_arvalid; + wire crossbar_m02_axi_arready; + wire [CROSSBAR_M_ID_WIDTH-1:0] crossbar_m02_axi_rid; + wire [CROSSBAR_DATA_WIDTH-1:0] crossbar_m02_axi_rdata; + wire [1:0] crossbar_m02_axi_rresp; + wire crossbar_m02_axi_rlast; + wire [CROSSBAR_RUSER_WIDTH-1:0] crossbar_m02_axi_ruser; + wire crossbar_m02_axi_rvalid; + wire crossbar_m02_axi_rready; + + + assign crossbar_clk = clk; + assign crossbar_rst = rst; + + axi4_if_to_flat #( + .ADDR_W (ADDR_WIDTH), + .DATA_W (DATA_WIDTH) + ) i_axi4_if_to_flat_00 ( + .axi (s_axi[0]), + .m_axi_awid (crossbar_s00_axi_awid), + .m_axi_awaddr (crossbar_s00_axi_awaddr), + .m_axi_awlen (crossbar_s00_axi_awlen), + .m_axi_awsize (crossbar_s00_axi_awsize), + .m_axi_awburst (crossbar_s00_axi_awburst), + .m_axi_awlock (crossbar_s00_axi_awlock), + .m_axi_awcache (crossbar_s00_axi_awcache), + .m_axi_awprot (crossbar_s00_axi_awprot), + .m_axi_awqos (crossbar_s00_axi_awqos), + .m_axi_awregion (crossbar_s00_axi_awregion), + .m_axi_awuser (crossbar_s00_axi_awuser), + .m_axi_awvalid (crossbar_s00_axi_awvalid), + .m_axi_awready (crossbar_s00_axi_awready), + .m_axi_wdata (crossbar_s00_axi_wdata), + .m_axi_wstrb (crossbar_s00_axi_wstrb), + .m_axi_wlast (crossbar_s00_axi_wlast), + .m_axi_wuser (crossbar_s00_axi_wuser), + .m_axi_wvalid (crossbar_s00_axi_wvalid), + .m_axi_wready (crossbar_s00_axi_wready), + .m_axi_bid (crossbar_s00_axi_bid), + .m_axi_bresp (crossbar_s00_axi_bresp), + .m_axi_buser (crossbar_s00_axi_buser), + .m_axi_bvalid (crossbar_s00_axi_bvalid), + .m_axi_bready (crossbar_s00_axi_bready), + .m_axi_arid (crossbar_s00_axi_arid), + .m_axi_araddr (crossbar_s00_axi_araddr), + .m_axi_arlen (crossbar_s00_axi_arlen), + .m_axi_arsize (crossbar_s00_axi_arsize), + .m_axi_arburst (crossbar_s00_axi_arburst), + .m_axi_arlock (crossbar_s00_axi_arlock), + .m_axi_arcache (crossbar_s00_axi_arcache), + .m_axi_arprot (crossbar_s00_axi_arprot), + .m_axi_arqos (crossbar_s00_axi_arqos), + .m_axi_arregion (crossbar_s00_axi_arregion), + .m_axi_aruser (crossbar_s00_axi_aruser), + .m_axi_arvalid (crossbar_s00_axi_arvalid), + .m_axi_arready (crossbar_s00_axi_arready), + .m_axi_rid (crossbar_s00_axi_rid), + .m_axi_rdata (crossbar_s00_axi_rdata), + .m_axi_rresp (crossbar_s00_axi_rresp), + .m_axi_rlast (crossbar_s00_axi_rlast), + .m_axi_ruser (crossbar_s00_axi_ruser), + .m_axi_rvalid (crossbar_s00_axi_rvalid), + .m_axi_rready (crossbar_s00_axi_rready) + ); + + axi4_if_to_flat #( + .ADDR_W (ADDR_WIDTH), + .DATA_W (DATA_WIDTH) + ) i_axi4_if_to_flat_01 ( + .axi (s_axi[1]), + .m_axi_awid (crossbar_s01_axi_awid), + .m_axi_awaddr (crossbar_s01_axi_awaddr), + .m_axi_awlen (crossbar_s01_axi_awlen), + .m_axi_awsize (crossbar_s01_axi_awsize), + .m_axi_awburst (crossbar_s01_axi_awburst), + .m_axi_awlock (crossbar_s01_axi_awlock), + .m_axi_awcache (crossbar_s01_axi_awcache), + .m_axi_awprot (crossbar_s01_axi_awprot), + .m_axi_awqos (crossbar_s01_axi_awqos), + .m_axi_awregion (crossbar_s01_axi_awregion), + .m_axi_awuser (crossbar_s01_axi_awuser), + .m_axi_awvalid (crossbar_s01_axi_awvalid), + .m_axi_awready (crossbar_s01_axi_awready), + .m_axi_wdata (crossbar_s01_axi_wdata), + .m_axi_wstrb (crossbar_s01_axi_wstrb), + .m_axi_wlast (crossbar_s01_axi_wlast), + .m_axi_wuser (crossbar_s01_axi_wuser), + .m_axi_wvalid (crossbar_s01_axi_wvalid), + .m_axi_wready (crossbar_s01_axi_wready), + .m_axi_bid (crossbar_s01_axi_bid), + .m_axi_bresp (crossbar_s01_axi_bresp), + .m_axi_buser (crossbar_s01_axi_buser), + .m_axi_bvalid (crossbar_s01_axi_bvalid), + .m_axi_bready (crossbar_s01_axi_bready), + .m_axi_arid (crossbar_s01_axi_arid), + .m_axi_araddr (crossbar_s01_axi_araddr), + .m_axi_arlen (crossbar_s01_axi_arlen), + .m_axi_arsize (crossbar_s01_axi_arsize), + .m_axi_arburst (crossbar_s01_axi_arburst), + .m_axi_arlock (crossbar_s01_axi_arlock), + .m_axi_arcache (crossbar_s01_axi_arcache), + .m_axi_arprot (crossbar_s01_axi_arprot), + .m_axi_arqos (crossbar_s01_axi_arqos), + .m_axi_arregion (crossbar_s01_axi_arregion), + .m_axi_aruser (crossbar_s01_axi_aruser), + .m_axi_arvalid (crossbar_s01_axi_arvalid), + .m_axi_arready (crossbar_s01_axi_arready), + .m_axi_rid (crossbar_s01_axi_rid), + .m_axi_rdata (crossbar_s01_axi_rdata), + .m_axi_rresp (crossbar_s01_axi_rresp), + .m_axi_rlast (crossbar_s01_axi_rlast), + .m_axi_ruser (crossbar_s01_axi_ruser), + .m_axi_rvalid (crossbar_s01_axi_rvalid), + .m_axi_rready (crossbar_s01_axi_rready) + ); + + axi4_if_to_flat #( + .ADDR_W (ADDR_WIDTH), + .DATA_W (DATA_WIDTH) + ) i_axi4_if_to_flat_00 ( + .axi (s_axi[2]), + .m_axi_awid (crossbar_s02_axi_awid), + .m_axi_awaddr (crossbar_s02_axi_awaddr), + .m_axi_awlen (crossbar_s02_axi_awlen), + .m_axi_awsize (crossbar_s02_axi_awsize), + .m_axi_awburst (crossbar_s02_axi_awburst), + .m_axi_awlock (crossbar_s02_axi_awlock), + .m_axi_awcache (crossbar_s02_axi_awcache), + .m_axi_awprot (crossbar_s02_axi_awprot), + .m_axi_awqos (crossbar_s02_axi_awqos), + .m_axi_awregion (crossbar_s02_axi_awregion), + .m_axi_awuser (crossbar_s02_axi_awuser), + .m_axi_awvalid (crossbar_s02_axi_awvalid), + .m_axi_awready (crossbar_s02_axi_awready), + .m_axi_wdata (crossbar_s02_axi_wdata), + .m_axi_wstrb (crossbar_s02_axi_wstrb), + .m_axi_wlast (crossbar_s02_axi_wlast), + .m_axi_wuser (crossbar_s02_axi_wuser), + .m_axi_wvalid (crossbar_s02_axi_wvalid), + .m_axi_wready (crossbar_s02_axi_wready), + .m_axi_bid (crossbar_s02_axi_bid), + .m_axi_bresp (crossbar_s02_axi_bresp), + .m_axi_buser (crossbar_s02_axi_buser), + .m_axi_bvalid (crossbar_s02_axi_bvalid), + .m_axi_bready (crossbar_s02_axi_bready), + .m_axi_arid (crossbar_s02_axi_arid), + .m_axi_araddr (crossbar_s02_axi_araddr), + .m_axi_arlen (crossbar_s02_axi_arlen), + .m_axi_arsize (crossbar_s02_axi_arsize), + .m_axi_arburst (crossbar_s02_axi_arburst), + .m_axi_arlock (crossbar_s02_axi_arlock), + .m_axi_arcache (crossbar_s02_axi_arcache), + .m_axi_arprot (crossbar_s02_axi_arprot), + .m_axi_arqos (crossbar_s02_axi_arqos), + .m_axi_arregion (crossbar_s02_axi_arregion), + .m_axi_aruser (crossbar_s02_axi_aruser), + .m_axi_arvalid (crossbar_s02_axi_arvalid), + .m_axi_arready (crossbar_s02_axi_arready), + .m_axi_rid (crossbar_s02_axi_rid), + .m_axi_rdata (crossbar_s02_axi_rdata), + .m_axi_rresp (crossbar_s02_axi_rresp), + .m_axi_rlast (crossbar_s02_axi_rlast), + .m_axi_ruser (crossbar_s02_axi_ruser), + .m_axi_rvalid (crossbar_s02_axi_rvalid), + .m_axi_rready (crossbar_s02_axi_rready) + ); + + axi4_flat_to_if_slave #( + .ADDR_W (ADDR_WIDTH), + .DATA_W (DATA_WIDTH) + ) i_axi4_if_to_flat_master_00 ( + .axi (s_axi[0]), + .m_axi_awid (crossbar_s00_axi_awid), + .m_axi_awaddr (crossbar_s00_axi_awaddr), + .m_axi_awlen (crossbar_s00_axi_awlen), + .m_axi_awsize (crossbar_s00_axi_awsize), + .m_axi_awburst (crossbar_s00_axi_awburst), + .m_axi_awlock (crossbar_s00_axi_awlock), + .m_axi_awcache (crossbar_s00_axi_awcache), + .m_axi_awprot (crossbar_s00_axi_awprot), + .m_axi_awqos (crossbar_s00_axi_awqos), + .m_axi_awregion (crossbar_s00_axi_awregion), + .m_axi_awuser (crossbar_s00_axi_awuser), + .m_axi_awvalid (crossbar_s00_axi_awvalid), + .m_axi_awready (crossbar_s00_axi_awready), + .m_axi_wdata (crossbar_s00_axi_wdata), + .m_axi_wstrb (crossbar_s00_axi_wstrb), + .m_axi_wlast (crossbar_s00_axi_wlast), + .m_axi_wuser (crossbar_s00_axi_wuser), + .m_axi_wvalid (crossbar_s00_axi_wvalid), + .m_axi_wready (crossbar_s00_axi_wready), + .m_axi_bid (crossbar_s00_axi_bid), + .m_axi_bresp (crossbar_s00_axi_bresp), + .m_axi_buser (crossbar_s00_axi_buser), + .m_axi_bvalid (crossbar_s00_axi_bvalid), + .m_axi_bready (crossbar_s00_axi_bready), + .m_axi_arid (crossbar_s00_axi_arid), + .m_axi_araddr (crossbar_s00_axi_araddr), + .m_axi_arlen (crossbar_s00_axi_arlen), + .m_axi_arsize (crossbar_s00_axi_arsize), + .m_axi_arburst (crossbar_s00_axi_arburst), + .m_axi_arlock (crossbar_s00_axi_arlock), + .m_axi_arcache (crossbar_s00_axi_arcache), + .m_axi_arprot (crossbar_s00_axi_arprot), + .m_axi_arqos (crossbar_s00_axi_arqos), + .m_axi_arregion (crossbar_s00_axi_arregion), + .m_axi_aruser (crossbar_s00_axi_aruser), + .m_axi_arvalid (crossbar_s00_axi_arvalid), + .m_axi_arready (crossbar_s00_axi_arready), + .m_axi_rid (crossbar_s00_axi_rid), + .m_axi_rdata (crossbar_s00_axi_rdata), + .m_axi_rresp (crossbar_s00_axi_rresp), + .m_axi_rlast (crossbar_s00_axi_rlast), + .m_axi_ruser (crossbar_s00_axi_ruser), + .m_axi_rvalid (crossbar_s00_axi_rvalid), + .m_axi_rready (crossbar_s00_axi_rready) + ); + + axi_crossbar_core_wrapper # + ( + .DATA_WIDTH = (CROSSBAR_DATA_WIDTH), + .ADDR_WIDTH = (CROSSBAR_ADDR_WIDTH), + .STRB_WIDTH = (CROSSBAR_STRB_WIDTH), + .S_ID_WIDTH = (CROSSBAR_S_ID_WIDTH), + .M_ID_WIDTH = (CROSSBAR_M_ID_WIDTH), + .AWUSER_ENABLE = (CROSSBAR_AWUSER_ENABLE), + .AWUSER_WIDTH = (CROSSBAR_AWUSER_WIDTH), + .WUSER_ENABLE = (CROSSBAR_WUSER_ENABLE), + .WUSER_WIDTH = (CROSSBAR_WUSER_WIDTH), + .BUSER_ENABLE = (CROSSBAR_BUSER_ENABLE), + .BUSER_WIDTH = (CROSSBAR_BUSER_WIDTH), + .ARUSER_ENABLE = (CROSSBAR_ARUSER_ENABLE), + .ARUSER_WIDTH = (CROSSBAR_ARUSER_WIDTH), + .RUSER_ENABLE = (CROSSBAR_RUSER_ENABLE), + .RUSER_WIDTH = (CROSSBAR_RUSER_WIDTH), + .S00_THREADS = (CROSSBAR_S00_THREADS), + .S00_ACCEPT = (CROSSBAR_S00_ACCEPT), + .S01_THREADS = (CROSSBAR_S01_THREADS), + .S01_ACCEPT = (CROSSBAR_S01_ACCEPT), + .S02_THREADS = (CROSSBAR_S02_THREADS), + .S02_ACCEPT = (CROSSBAR_S02_ACCEPT), + .M_REGIONS = (CROSSBAR_M_REGIONS), + .M00_BASE_ADDR = (CROSSBAR_M00_BASE_ADDR), + .M00_ADDR_WIDTH = (CROSSBAR_M00_ADDR_WIDTH), + .M00_CONNECT_READ = (CROSSBAR_M00_CONNECT_READ), + .M00_CONNECT_WRITE = (CROSSBAR_M00_CONNECT_WRITE), + .M00_ISSUE = (CROSSBAR_M00_ISSUE), + .M00_SECURE = (CROSSBAR_M00_SECURE), + .M01_BASE_ADDR = (CROSSBAR_M01_BASE_ADDR), + .M01_ADDR_WIDTH = (CROSSBAR_M01_ADDR_WIDTH), + .M01_CONNECT_READ = (CROSSBAR_M01_CONNECT_READ), + .M01_CONNECT_WRITE = (CROSSBAR_M01_CONNECT_WRITE), + .M01_ISSUE = (CROSSBAR_M01_ISSUE), + .M01_SECURE = (CROSSBAR_M01_SECURE), + .M02_BASE_ADDR = (CROSSBAR_M02_BASE_ADDR), + .M02_ADDR_WIDTH = (CROSSBAR_M02_ADDR_WIDTH), + .M02_CONNECT_READ = (CROSSBAR_M02_CONNECT_READ), + .M02_CONNECT_WRITE = (CROSSBAR_M02_CONNECT_WRITE), + .M02_ISSUE = (CROSSBAR_M02_ISSUE), + .M02_SECURE = (CROSSBAR_M02_SECURE), + .S00_AW_REG_TYPE = (CROSSBAR_S00_AW_REG_TYPE), + .S00_W_REG_TYPE = (CROSSBAR_S00_W_REG_TYPE), + .S00_B_REG_TYPE = (CROSSBAR_S00_B_REG_TYPE), + .S00_AR_REG_TYPE = (CROSSBAR_S00_AR_REG_TYPE), + .S00_R_REG_TYPE = (CROSSBAR_S00_R_REG_TYPE), + .S01_AW_REG_TYPE = (CROSSBAR_S01_AW_REG_TYPE), + .S01_W_REG_TYPE = (CROSSBAR_S01_W_REG_TYPE), + .S01_B_REG_TYPE = (CROSSBAR_S01_B_REG_TYPE), + .S01_AR_REG_TYPE = (CROSSBAR_S01_AR_REG_TYPE), + .S01_R_REG_TYPE = (CROSSBAR_S01_R_REG_TYPE), + .S02_AW_REG_TYPE = (CROSSBAR_S02_AW_REG_TYPE), + .S02_W_REG_TYPE = (CROSSBAR_S02_W_REG_TYPE), + .S02_B_REG_TYPE = (CROSSBAR_S02_B_REG_TYPE), + .S02_AR_REG_TYPE = (CROSSBAR_S02_AR_REG_TYPE), + .S02_R_REG_TYPE = (CROSSBAR_S02_R_REG_TYPE), + .M00_AW_REG_TYPE = (CROSSBAR_M00_AW_REG_TYPE), + .M00_W_REG_TYPE = (CROSSBAR_M00_W_REG_TYPE), + .M00_B_REG_TYPE = (CROSSBAR_M00_B_REG_TYPE), + .M00_AR_REG_TYPE = (CROSSBAR_M00_AR_REG_TYPE), + .M00_R_REG_TYPE = (CROSSBAR_M00_R_REG_TYPE), + .M01_AW_REG_TYPE = (CROSSBAR_M01_AW_REG_TYPE), + .M01_W_REG_TYPE = (CROSSBAR_M01_W_REG_TYPE), + .M01_B_REG_TYPE = (CROSSBAR_M01_B_REG_TYPE), + .M01_AR_REG_TYPE = (CROSSBAR_M01_AR_REG_TYPE), + .M01_R_REG_TYPE = (CROSSBAR_M01_R_REG_TYPE), + .M02_AW_REG_TYPE = (CROSSBAR_M02_AW_REG_TYPE), + .M02_W_REG_TYPE = (CROSSBAR_M02_W_REG_TYPE), + .M02_B_REG_TYPE = (CROSSBAR_M02_B_REG_TYPE), + .M02_AR_REG_TYPE = (CROSSBAR_M02_AR_REG_TYPE), + .M02_R_REG_TYPE = (CROSSBAR_M02_R_REG_TYPE) + + ) i_axi_crossbar_core_wrapper ( + .clk (crossbar_clk), + .rst (crossbar_rst), + .s00_axi_awid (crossbar_s00_axi_awid), + .s00_axi_awaddr (crossbar_s00_axi_awaddr), + .s00_axi_awlen (crossbar_s00_axi_awlen), + .s00_axi_awsize (crossbar_s00_axi_awsize), + .s00_axi_awburst (crossbar_s00_axi_awburst), + .s00_axi_awlock (crossbar_s00_axi_awlock), + .s00_axi_awcache (crossbar_s00_axi_awcache), + .s00_axi_awprot (crossbar_s00_axi_awprot), + .s00_axi_awqos (crossbar_s00_axi_awqos), + .s00_axi_awuser (crossbar_s00_axi_awuser), + .s00_axi_awvalid (crossbar_s00_axi_awvalid), + .s00_axi_awready (crossbar_s00_axi_awready), + .s00_axi_wdata (crossbar_s00_axi_wdata), + .s00_axi_wstrb (crossbar_s00_axi_wstrb), + .s00_axi_wlast (crossbar_s00_axi_wlast), + .s00_axi_wuser (crossbar_s00_axi_wuser), + .s00_axi_wvalid (crossbar_s00_axi_wvalid), + .s00_axi_wready (crossbar_s00_axi_wready), + .s00_axi_bid (crossbar_s00_axi_bid), + .s00_axi_bresp (crossbar_s00_axi_bresp), + .s00_axi_buser (crossbar_s00_axi_buser), + .s00_axi_bvalid (crossbar_s00_axi_bvalid), + .s00_axi_bready (crossbar_s00_axi_bready), + .s00_axi_arid (crossbar_s00_axi_arid), + .s00_axi_araddr (crossbar_s00_axi_araddr), + .s00_axi_arlen (crossbar_s00_axi_arlen), + .s00_axi_arsize (crossbar_s00_axi_arsize), + .s00_axi_arburst (crossbar_s00_axi_arburst), + .s00_axi_arlock (crossbar_s00_axi_arlock), + .s00_axi_arcache (crossbar_s00_axi_arcache), + .s00_axi_arprot (crossbar_s00_axi_arprot), + .s00_axi_arqos (crossbar_s00_axi_arqos), + .s00_axi_aruser (crossbar_s00_axi_aruser), + .s00_axi_arvalid (crossbar_s00_axi_arvalid), + .s00_axi_arready (crossbar_s00_axi_arready), + .s00_axi_rid (crossbar_s00_axi_rid), + .s00_axi_rdata (crossbar_s00_axi_rdata), + .s00_axi_rresp (crossbar_s00_axi_rresp), + .s00_axi_rlast (crossbar_s00_axi_rlast), + .s00_axi_ruser (crossbar_s00_axi_ruser), + .s00_axi_rvalid (crossbar_s00_axi_rvalid), + .s00_axi_rready (crossbar_s00_axi_rready), + .s01_axi_awid (crossbar_s01_axi_awid), + .s01_axi_awaddr (crossbar_s01_axi_awaddr), + .s01_axi_awlen (crossbar_s01_axi_awlen), + .s01_axi_awsize (crossbar_s01_axi_awsize), + .s01_axi_awburst (crossbar_s01_axi_awburst), + .s01_axi_awlock (crossbar_s01_axi_awlock), + .s01_axi_awcache (crossbar_s01_axi_awcache), + .s01_axi_awprot (crossbar_s01_axi_awprot), + .s01_axi_awqos (crossbar_s01_axi_awqos), + .s01_axi_awuser (crossbar_s01_axi_awuser), + .s01_axi_awvalid (crossbar_s01_axi_awvalid), + .s01_axi_awready (crossbar_s01_axi_awready), + .s01_axi_wdata (crossbar_s01_axi_wdata), + .s01_axi_wstrb (crossbar_s01_axi_wstrb), + .s01_axi_wlast (crossbar_s01_axi_wlast), + .s01_axi_wuser (crossbar_s01_axi_wuser), + .s01_axi_wvalid (crossbar_s01_axi_wvalid), + .s01_axi_wready (crossbar_s01_axi_wready), + .s01_axi_bid (crossbar_s01_axi_bid), + .s01_axi_bresp (crossbar_s01_axi_bresp), + .s01_axi_buser (crossbar_s01_axi_buser), + .s01_axi_bvalid (crossbar_s01_axi_bvalid), + .s01_axi_bready (crossbar_s01_axi_bready), + .s01_axi_arid (crossbar_s01_axi_arid), + .s01_axi_araddr (crossbar_s01_axi_araddr), + .s01_axi_arlen (crossbar_s01_axi_arlen), + .s01_axi_arsize (crossbar_s01_axi_arsize), + .s01_axi_arburst (crossbar_s01_axi_arburst), + .s01_axi_arlock (crossbar_s01_axi_arlock), + .s01_axi_arcache (crossbar_s01_axi_arcache), + .s01_axi_arprot (crossbar_s01_axi_arprot), + .s01_axi_arqos (crossbar_s01_axi_arqos), + .s01_axi_aruser (crossbar_s01_axi_aruser), + .s01_axi_arvalid (crossbar_s01_axi_arvalid), + .s01_axi_arready (crossbar_s01_axi_arready), + .s01_axi_rid (crossbar_s01_axi_rid), + .s01_axi_rdata (crossbar_s01_axi_rdata), + .s01_axi_rresp (crossbar_s01_axi_rresp), + .s01_axi_rlast (crossbar_s01_axi_rlast), + .s01_axi_ruser (crossbar_s01_axi_ruser), + .s01_axi_rvalid (crossbar_s01_axi_rvalid), + .s01_axi_rready (crossbar_s01_axi_rready), + .s02_axi_awid (crossbar_s02_axi_awid), + .s02_axi_awaddr (crossbar_s02_axi_awaddr), + .s02_axi_awlen (crossbar_s02_axi_awlen), + .s02_axi_awsize (crossbar_s02_axi_awsize), + .s02_axi_awburst (crossbar_s02_axi_awburst), + .s02_axi_awlock (crossbar_s02_axi_awlock), + .s02_axi_awcache (crossbar_s02_axi_awcache), + .s02_axi_awprot (crossbar_s02_axi_awprot), + .s02_axi_awqos (crossbar_s02_axi_awqos), + .s02_axi_awuser (crossbar_s02_axi_awuser), + .s02_axi_awvalid (crossbar_s02_axi_awvalid), + .s02_axi_awready (crossbar_s02_axi_awready), + .s02_axi_wdata (crossbar_s02_axi_wdata), + .s02_axi_wstrb (crossbar_s02_axi_wstrb), + .s02_axi_wlast (crossbar_s02_axi_wlast), + .s02_axi_wuser (crossbar_s02_axi_wuser), + .s02_axi_wvalid (crossbar_s02_axi_wvalid), + .s02_axi_wready (crossbar_s02_axi_wready), + .s02_axi_bid (crossbar_s02_axi_bid), + .s02_axi_bresp (crossbar_s02_axi_bresp), + .s02_axi_buser (crossbar_s02_axi_buser), + .s02_axi_bvalid (crossbar_s02_axi_bvalid), + .s02_axi_bready (crossbar_s02_axi_bready), + .s02_axi_arid (crossbar_s02_axi_arid), + .s02_axi_araddr (crossbar_s02_axi_araddr), + .s02_axi_arlen (crossbar_s02_axi_arlen), + .s02_axi_arsize (crossbar_s02_axi_arsize), + .s02_axi_arburst (crossbar_s02_axi_arburst), + .s02_axi_arlock (crossbar_s02_axi_arlock), + .s02_axi_arcache (crossbar_s02_axi_arcache), + .s02_axi_arprot (crossbar_s02_axi_arprot), + .s02_axi_arqos (crossbar_s02_axi_arqos), + .s02_axi_aruser (crossbar_s02_axi_aruser), + .s02_axi_arvalid (crossbar_s02_axi_arvalid), + .s02_axi_arready (crossbar_s02_axi_arready), + .s02_axi_rid (crossbar_s02_axi_rid), + .s02_axi_rdata (crossbar_s02_axi_rdata), + .s02_axi_rresp (crossbar_s02_axi_rresp), + .s02_axi_rlast (crossbar_s02_axi_rlast), + .s02_axi_ruser (crossbar_s02_axi_ruser), + .s02_axi_rvalid (crossbar_s02_axi_rvalid), + .s02_axi_rready (crossbar_s02_axi_rready), + .m00_axi_awid (crossbar_m00_axi_awid), + .m00_axi_awaddr (crossbar_m00_axi_awaddr), + .m00_axi_awlen (crossbar_m00_axi_awlen), + .m00_axi_awsize (crossbar_m00_axi_awsize), + .m00_axi_awburst (crossbar_m00_axi_awburst), + .m00_axi_awlock (crossbar_m00_axi_awlock), + .m00_axi_awcache (crossbar_m00_axi_awcache), + .m00_axi_awprot (crossbar_m00_axi_awprot), + .m00_axi_awqos (crossbar_m00_axi_awqos), + .m00_axi_awregion (crossbar_m00_axi_awregion), + .m00_axi_awuser (crossbar_m00_axi_awuser), + .m00_axi_awvalid (crossbar_m00_axi_awvalid), + .m00_axi_awready (crossbar_m00_axi_awready), + .m00_axi_wdata (crossbar_m00_axi_wdata), + .m00_axi_wstrb (crossbar_m00_axi_wstrb), + .m00_axi_wlast (crossbar_m00_axi_wlast), + .m00_axi_wuser (crossbar_m00_axi_wuser), + .m00_axi_wvalid (crossbar_m00_axi_wvalid), + .m00_axi_wready (crossbar_m00_axi_wready), + .m00_axi_bid (crossbar_m00_axi_bid), + .m00_axi_bresp (crossbar_m00_axi_bresp), + .m00_axi_buser (crossbar_m00_axi_buser), + .m00_axi_bvalid (crossbar_m00_axi_bvalid), + .m00_axi_bready (crossbar_m00_axi_bready), + .m00_axi_arid (crossbar_m00_axi_arid), + .m00_axi_araddr (crossbar_m00_axi_araddr), + .m00_axi_arlen (crossbar_m00_axi_arlen), + .m00_axi_arsize (crossbar_m00_axi_arsize), + .m00_axi_arburst (crossbar_m00_axi_arburst), + .m00_axi_arlock (crossbar_m00_axi_arlock), + .m00_axi_arcache (crossbar_m00_axi_arcache), + .m00_axi_arprot (crossbar_m00_axi_arprot), + .m00_axi_arqos (crossbar_m00_axi_arqos), + .m00_axi_arregion (crossbar_m00_axi_arregion), + .m00_axi_aruser (crossbar_m00_axi_aruser), + .m00_axi_arvalid (crossbar_m00_axi_arvalid), + .m00_axi_arready (crossbar_m00_axi_arready), + .m00_axi_rid (crossbar_m00_axi_rid), + .m00_axi_rdata (crossbar_m00_axi_rdata), + .m00_axi_rresp (crossbar_m00_axi_rresp), + .m00_axi_rlast (crossbar_m00_axi_rlast), + .m00_axi_ruser (crossbar_m00_axi_ruser), + .m00_axi_rvalid (crossbar_m00_axi_rvalid), + .m00_axi_rready (crossbar_m00_axi_rready), + .m01_axi_awid (crossbar_m01_axi_awid), + .m01_axi_awaddr (crossbar_m01_axi_awaddr), + .m01_axi_awlen (crossbar_m01_axi_awlen), + .m01_axi_awsize (crossbar_m01_axi_awsize), + .m01_axi_awburst (crossbar_m01_axi_awburst), + .m01_axi_awlock (crossbar_m01_axi_awlock), + .m01_axi_awcache (crossbar_m01_axi_awcache), + .m01_axi_awprot (crossbar_m01_axi_awprot), + .m01_axi_awqos (crossbar_m01_axi_awqos), + .m01_axi_awregion (crossbar_m01_axi_awregion), + .m01_axi_awuser (crossbar_m01_axi_awuser), + .m01_axi_awvalid (crossbar_m01_axi_awvalid), + .m01_axi_awready (crossbar_m01_axi_awready), + .m01_axi_wdata (crossbar_m01_axi_wdata), + .m01_axi_wstrb (crossbar_m01_axi_wstrb), + .m01_axi_wlast (crossbar_m01_axi_wlast), + .m01_axi_wuser (crossbar_m01_axi_wuser), + .m01_axi_wvalid (crossbar_m01_axi_wvalid), + .m01_axi_wready (crossbar_m01_axi_wready), + .m01_axi_bid (crossbar_m01_axi_bid), + .m01_axi_bresp (crossbar_m01_axi_bresp), + .m01_axi_buser (crossbar_m01_axi_buser), + .m01_axi_bvalid (crossbar_m01_axi_bvalid), + .m01_axi_bready (crossbar_m01_axi_bready), + .m01_axi_arid (crossbar_m01_axi_arid), + .m01_axi_araddr (crossbar_m01_axi_araddr), + .m01_axi_arlen (crossbar_m01_axi_arlen), + .m01_axi_arsize (crossbar_m01_axi_arsize), + .m01_axi_arburst (crossbar_m01_axi_arburst), + .m01_axi_arlock (crossbar_m01_axi_arlock), + .m01_axi_arcache (crossbar_m01_axi_arcache), + .m01_axi_arprot (crossbar_m01_axi_arprot), + .m01_axi_arqos (crossbar_m01_axi_arqos), + .m01_axi_arregion (crossbar_m01_axi_arregion), + .m01_axi_aruser (crossbar_m01_axi_aruser), + .m01_axi_arvalid (crossbar_m01_axi_arvalid), + .m01_axi_arready (crossbar_m01_axi_arready), + .m01_axi_rid (crossbar_m01_axi_rid), + .m01_axi_rdata (crossbar_m01_axi_rdata), + .m01_axi_rresp (crossbar_m01_axi_rresp), + .m01_axi_rlast (crossbar_m01_axi_rlast), + .m01_axi_ruser (crossbar_m01_axi_ruser), + .m01_axi_rvalid (crossbar_m01_axi_rvalid), + .m01_axi_rready (crossbar_m01_axi_rready), + .m02_axi_awid (crossbar_m02_axi_awid), + .m02_axi_awaddr (crossbar_m02_axi_awaddr), + .m02_axi_awlen (crossbar_m02_axi_awlen), + .m02_axi_awsize (crossbar_m02_axi_awsize), + .m02_axi_awburst (crossbar_m02_axi_awburst), + .m02_axi_awlock (crossbar_m02_axi_awlock), + .m02_axi_awcache (crossbar_m02_axi_awcache), + .m02_axi_awprot (crossbar_m02_axi_awprot), + .m02_axi_awqos (crossbar_m02_axi_awqos), + .m02_axi_awregion (crossbar_m02_axi_awregion), + .m02_axi_awuser (crossbar_m02_axi_awuser), + .m02_axi_awvalid (crossbar_m02_axi_awvalid), + .m02_axi_awready (crossbar_m02_axi_awready), + .m02_axi_wdata (crossbar_m02_axi_wdata), + .m02_axi_wstrb (crossbar_m02_axi_wstrb), + .m02_axi_wlast (crossbar_m02_axi_wlast), + .m02_axi_wuser (crossbar_m02_axi_wuser), + .m02_axi_wvalid (crossbar_m02_axi_wvalid), + .m02_axi_wready (crossbar_m02_axi_wready), + .m02_axi_bid (crossbar_m02_axi_bid), + .m02_axi_bresp (crossbar_m02_axi_bresp), + .m02_axi_buser (crossbar_m02_axi_buser), + .m02_axi_bvalid (crossbar_m02_axi_bvalid), + .m02_axi_bready (crossbar_m02_axi_bready), + .m02_axi_arid (crossbar_m02_axi_arid), + .m02_axi_araddr (crossbar_m02_axi_araddr), + .m02_axi_arlen (crossbar_m02_axi_arlen), + .m02_axi_arsize (crossbar_m02_axi_arsize), + .m02_axi_arburst (crossbar_m02_axi_arburst), + .m02_axi_arlock (crossbar_m02_axi_arlock), + .m02_axi_arcache (crossbar_m02_axi_arcache), + .m02_axi_arprot (crossbar_m02_axi_arprot), + .m02_axi_arqos (crossbar_m02_axi_arqos), + .m02_axi_arregion (crossbar_m02_axi_arregion), + .m02_axi_aruser (crossbar_m02_axi_aruser), + .m02_axi_arvalid (crossbar_m02_axi_arvalid), + .m02_axi_arready (crossbar_m02_axi_arready), + .m02_axi_rid (crossbar_m02_axi_rid), + .m02_axi_rdata (crossbar_m02_axi_rdata), + .m02_axi_rresp (crossbar_m02_axi_rresp), + .m02_axi_rlast (crossbar_m02_axi_rlast), + .m02_axi_ruser (crossbar_m02_axi_ruser), + .m02_axi_rvalid (crossbar_m02_axi_rvalid), + .m02_axi_rready (crossbar_m02_axi_rready) + ); + + axi4_flat_to_if #( + .ADDR_W (ADDR_WIDTH), + .DATA_W (DATA_WIDTH) + ) i_axi4_flat_to_if_00( + .s_axi_awid (crossbar_m00_axi_awid), + .s_axi_awaddr (crossbar_m00_axi_awaddr), + .s_axi_awlen (crossbar_m00_axi_awlen), + .s_axi_awsize (crossbar_m00_axi_awsize), + .s_axi_awburst (crossbar_m00_axi_awburst), + .s_axi_awlock (crossbar_m00_axi_awlock), + .s_axi_awcache (crossbar_m00_axi_awcache), + .s_axi_awprot (crossbar_m00_axi_awprot), + .s_axi_awqos (crossbar_m00_axi_awqos), + .s_axi_awregion (crossbar_m00_axi_awregion), + .s_axi_awuser (crossbar_m00_axi_awuser), + .s_axi_awvalid (crossbar_m00_axi_awvalid), + .s_axi_awready (crossbar_m00_axi_awready), + .s_axi_wdata (crossbar_m00_axi_wdata), + .s_axi_wstrb (crossbar_m00_axi_wstrb), + .s_axi_wlast (crossbar_m00_axi_wlast), + .s_axi_wuser (crossbar_m00_axi_wuser), + .s_axi_wvalid (crossbar_m00_axi_wvalid), + .s_axi_wready (crossbar_m00_axi_wready), + .s_axi_bid (crossbar_m00_axi_bid), + .s_axi_bresp (crossbar_m00_axi_bresp), + .s_axi_buser (crossbar_m00_axi_buser), + .s_axi_bvalid (crossbar_m00_axi_bvalid), + .s_axi_bready (crossbar_m00_axi_bready), + .s_axi_arid (crossbar_m00_axi_arid), + .s_axi_araddr (crossbar_m00_axi_araddr), + .s_axi_arlen (crossbar_m00_axi_arlen), + .s_axi_arsize (crossbar_m00_axi_arsize), + .s_axi_arburst (crossbar_m00_axi_arburst), + .s_axi_arlock (crossbar_m00_axi_arlock), + .s_axi_arcache (crossbar_m00_axi_arcache), + .s_axi_arprot (crossbar_m00_axi_arprot), + .s_axi_arqos (crossbar_m00_axi_arqos), + .s_axi_arregion (crossbar_m00_axi_arregion), + .s_axi_aruser (crossbar_m00_axi_aruser), + .s_axi_arvalid (crossbar_m00_axi_arvalid), + .s_axi_arready (crossbar_m00_axi_arready), + .s_axi_rid (crossbar_m00_axi_rid), + .s_axi_rdata (crossbar_m00_axi_rdata), + .s_axi_rresp (crossbar_m00_axi_rresp), + .s_axi_rlast (crossbar_m00_axi_rlast), + .s_axi_ruser (crossbar_m00_axi_ruser), + .s_axi_rvalid (crossbar_m00_axi_rvalid), + .s_axi_rready (crossbar_m00_axi_rready), + .m_axi (m_axi[0]) + ); + + axi4_flat_to_if #( + .ADDR_W (ADDR_WIDTH), + .DATA_W (DATA_WIDTH) + ) i_axi4_flat_to_if_01( + .s_axi_awid (crossbar_m01_axi_awid), + .s_axi_awaddr (crossbar_m01_axi_awaddr), + .s_axi_awlen (crossbar_m01_axi_awlen), + .s_axi_awsize (crossbar_m01_axi_awsize), + .s_axi_awburst (crossbar_m01_axi_awburst), + .s_axi_awlock (crossbar_m01_axi_awlock), + .s_axi_awcache (crossbar_m01_axi_awcache), + .s_axi_awprot (crossbar_m01_axi_awprot), + .s_axi_awqos (crossbar_m01_axi_awqos), + .s_axi_awregion (crossbar_m01_axi_awregion), + .s_axi_awuser (crossbar_m01_axi_awuser), + .s_axi_awvalid (crossbar_m01_axi_awvalid), + .s_axi_awready (crossbar_m01_axi_awready), + .s_axi_wdata (crossbar_m01_axi_wdata), + .s_axi_wstrb (crossbar_m01_axi_wstrb), + .s_axi_wlast (crossbar_m01_axi_wlast), + .s_axi_wuser (crossbar_m01_axi_wuser), + .s_axi_wvalid (crossbar_m01_axi_wvalid), + .s_axi_wready (crossbar_m01_axi_wready), + .s_axi_bid (crossbar_m01_axi_bid), + .s_axi_bresp (crossbar_m01_axi_bresp), + .s_axi_buser (crossbar_m01_axi_buser), + .s_axi_bvalid (crossbar_m01_axi_bvalid), + .s_axi_bready (crossbar_m01_axi_bready), + .s_axi_arid (crossbar_m01_axi_arid), + .s_axi_araddr (crossbar_m01_axi_araddr), + .s_axi_arlen (crossbar_m01_axi_arlen), + .s_axi_arsize (crossbar_m01_axi_arsize), + .s_axi_arburst (crossbar_m01_axi_arburst), + .s_axi_arlock (crossbar_m01_axi_arlock), + .s_axi_arcache (crossbar_m01_axi_arcache), + .s_axi_arprot (crossbar_m01_axi_arprot), + .s_axi_arqos (crossbar_m01_axi_arqos), + .s_axi_arregion (crossbar_m01_axi_arregion), + .s_axi_aruser (crossbar_m01_axi_aruser), + .s_axi_arvalid (crossbar_m01_axi_arvalid), + .s_axi_arready (crossbar_m01_axi_arready), + .s_axi_rid (crossbar_m01_axi_rid), + .s_axi_rdata (crossbar_m01_axi_rdata), + .s_axi_rresp (crossbar_m01_axi_rresp), + .s_axi_rlast (crossbar_m01_axi_rlast), + .s_axi_ruser (crossbar_m01_axi_ruser), + .s_axi_rvalid (crossbar_m01_axi_rvalid), + .s_axi_rready (crossbar_m01_axi_rready), + .m_axi (m_axi[1]) + ); + + axi4_flat_to_if #( + .ADDR_W (ADDR_WIDTH), + .DATA_W (DATA_WIDTH) + ) i_axi4_flat_to_if_02( + .s_axi_awid (crossbar_m02_axi_awid), + .s_axi_awaddr (crossbar_m02_axi_awaddr), + .s_axi_awlen (crossbar_m02_axi_awlen), + .s_axi_awsize (crossbar_m02_axi_awsize), + .s_axi_awburst (crossbar_m02_axi_awburst), + .s_axi_awlock (crossbar_m02_axi_awlock), + .s_axi_awcache (crossbar_m02_axi_awcache), + .s_axi_awprot (crossbar_m02_axi_awprot), + .s_axi_awqos (crossbar_m02_axi_awqos), + .s_axi_awregion (crossbar_m02_axi_awregion), + .s_axi_awuser (crossbar_m02_axi_awuser), + .s_axi_awvalid (crossbar_m02_axi_awvalid), + .s_axi_awready (crossbar_m02_axi_awready), + .s_axi_wdata (crossbar_m02_axi_wdata), + .s_axi_wstrb (crossbar_m02_axi_wstrb), + .s_axi_wlast (crossbar_m02_axi_wlast), + .s_axi_wuser (crossbar_m02_axi_wuser), + .s_axi_wvalid (crossbar_m02_axi_wvalid), + .s_axi_wready (crossbar_m02_axi_wready), + .s_axi_bid (crossbar_m02_axi_bid), + .s_axi_bresp (crossbar_m02_axi_bresp), + .s_axi_buser (crossbar_m02_axi_buser), + .s_axi_bvalid (crossbar_m02_axi_bvalid), + .s_axi_bready (crossbar_m02_axi_bready), + .s_axi_arid (crossbar_m02_axi_arid), + .s_axi_araddr (crossbar_m02_axi_araddr), + .s_axi_arlen (crossbar_m02_axi_arlen), + .s_axi_arsize (crossbar_m02_axi_arsize), + .s_axi_arburst (crossbar_m02_axi_arburst), + .s_axi_arlock (crossbar_m02_axi_arlock), + .s_axi_arcache (crossbar_m02_axi_arcache), + .s_axi_arprot (crossbar_m02_axi_arprot), + .s_axi_arqos (crossbar_m02_axi_arqos), + .s_axi_arregion (crossbar_m02_axi_arregion), + .s_axi_aruser (crossbar_m02_axi_aruser), + .s_axi_arvalid (crossbar_m02_axi_arvalid), + .s_axi_arready (crossbar_m02_axi_arready), + .s_axi_rid (crossbar_m02_axi_rid), + .s_axi_rdata (crossbar_m02_axi_rdata), + .s_axi_rresp (crossbar_m02_axi_rresp), + .s_axi_rlast (crossbar_m02_axi_rlast), + .s_axi_ruser (crossbar_m02_axi_ruser), + .s_axi_rvalid (crossbar_m02_axi_rvalid), + .s_axi_rready (crossbar_m02_axi_rready), + .m_axi (m_axi[2]) + ); + + +endmodule diff --git a/external/external/rtl_libs/axi/rtl/axi_dma_compat.sv b/external/external/rtl_libs/axi/rtl/axi_dma_compat.sv new file mode 100644 index 0000000..b423bf4 --- /dev/null +++ b/external/external/rtl_libs/axi/rtl/axi_dma_compat.sv @@ -0,0 +1,331 @@ +// AXIS compat wrapper above axi_dma_if_wrapper. +// +// +// s_axis_desc_cmd = one-beat command stream carrying read + write desc +// m_axis_desc_status = one-beat status stream carrying read + write status +// +// read_enable and write_enable select which descriptor is used + +`default_nettype none + +module axi_dma_axis_compat #( + parameter int unsigned AXI_DATA_WIDTH = 32, + parameter int unsigned AXI_ADDR_WIDTH = 16, + parameter int unsigned AXI_STRB_WIDTH = AXI_DATA_WIDTH / 8, + parameter int unsigned AXI_ID_WIDTH = 8, + parameter int unsigned AXI_USER_WIDTH = 1, + parameter int unsigned AXI_MAX_BURST_LEN = 16, + + parameter int unsigned AXIS_DATA_WIDTH = AXI_DATA_WIDTH, + parameter int unsigned AXIS_KEEP_ENABLE = AXIS_DATA_WIDTH > 8, + parameter int unsigned AXIS_KEEP_WIDTH = AXIS_DATA_WIDTH / 8, + parameter int unsigned AXIS_LAST_ENABLE = 1, + parameter int unsigned AXIS_ID_ENABLE = 1, + parameter int unsigned AXIS_ID_WIDTH = 8, + parameter int unsigned AXIS_DEST_ENABLE = 0, + parameter int unsigned AXIS_DEST_WIDTH = 8, + parameter int unsigned AXIS_USER_ENABLE = 1, + parameter int unsigned AXIS_USER_WIDTH = 1, + + parameter int unsigned LEN_WIDTH = 20, + parameter int unsigned TAG_WIDTH = 8, + parameter int unsigned ENABLE_SG = 0, + parameter int unsigned ENABLE_UNALIGNED = 0, + + // Raw packed command/status widths. rounded up to full bytes + parameter int unsigned READ_DESC_WIDTH = AXI_ADDR_WIDTH + LEN_WIDTH + TAG_WIDTH + AXIS_ID_WIDTH + AXIS_DEST_WIDTH + AXIS_USER_WIDTH, + parameter int unsigned WRITE_DESC_WIDTH = AXI_ADDR_WIDTH + LEN_WIDTH + TAG_WIDTH, + parameter int unsigned DESC_CMD_RAW_WIDTH = READ_DESC_WIDTH + WRITE_DESC_WIDTH, + parameter int unsigned DESC_CMD_DATA_WIDTH = ((DESC_CMD_RAW_WIDTH + 7) / 8) * 8, + parameter int unsigned DESC_CMD_KEEP_WIDTH = DESC_CMD_DATA_WIDTH / 8, + + parameter int unsigned READ_STATUS_WIDTH = TAG_WIDTH + 4, + parameter int unsigned WRITE_STATUS_WIDTH = LEN_WIDTH + TAG_WIDTH + AXIS_ID_WIDTH + AXIS_DEST_WIDTH + AXIS_USER_WIDTH + 4, + parameter int unsigned DESC_STATUS_RAW_WIDTH = READ_STATUS_WIDTH + WRITE_STATUS_WIDTH, + parameter int unsigned DESC_STATUS_DATA_WIDTH = ((DESC_STATUS_RAW_WIDTH + 7) / 8) * 8, + parameter int unsigned DESC_STATUS_KEEP_WIDTH = DESC_STATUS_DATA_WIDTH / 8, + parameter int unsigned DESC_STATUS_USER_WIDTH = 2 +)( + input logic clk, + input logic rst, + + // Unified command stream. One beat carries both read and write descriptors. + // Which parts are used is selected by read_enable/write_enable. + axis_if.slave s_axis_desc_cmd, + + // Unified status stream. One beat can carry read status, write status, or both. + // m_axis_desc_status.tuser[0] = read status valid in this beat + // m_axis_desc_status.tuser[1] = write status valid in this beat + axis_if.master m_axis_desc_status, + + // Original DMA data streams and AXI memory master, still exposed as normal + // generic interfaces. + axis_if.master m_axis_read_data, + axis_if.slave s_axis_write_data, + axi4_if.master m_axi, + + input logic read_enable, + input logic write_enable, + input logic write_abort +); + + // -------------------------------------------------------------------------- + // packing layout + // -------------------------------------------------------------------------- + // s_axis_desc_cmd.tdata: + // [READ_DESC_*] read descriptor + // [WRITE_DESC_*] write descriptor + // + // m_axis_desc_status.tdata: + // [READ_STATUS_*] read descriptor status + // [WRITE_STATUS_*] write descriptor status + // + // offsets are LSB-first. padding in upper bits (if required) + + localparam int unsigned RD_ADDR_LSB = 0; + localparam int unsigned RD_LEN_LSB = RD_ADDR_LSB + AXI_ADDR_WIDTH; + localparam int unsigned RD_TAG_LSB = RD_LEN_LSB + LEN_WIDTH; + localparam int unsigned RD_ID_LSB = RD_TAG_LSB + TAG_WIDTH; + localparam int unsigned RD_DEST_LSB = RD_ID_LSB + AXIS_ID_WIDTH; + localparam int unsigned RD_USER_LSB = RD_DEST_LSB + AXIS_DEST_WIDTH; + + localparam int unsigned WR_BASE_LSB = READ_DESC_WIDTH; + localparam int unsigned WR_ADDR_LSB = WR_BASE_LSB; + localparam int unsigned WR_LEN_LSB = WR_ADDR_LSB + AXI_ADDR_WIDTH; + localparam int unsigned WR_TAG_LSB = WR_LEN_LSB + LEN_WIDTH; + + localparam int unsigned RD_STS_TAG_LSB = 0; + localparam int unsigned RD_STS_ERROR_LSB = RD_STS_TAG_LSB + TAG_WIDTH; + + localparam int unsigned WR_STS_BASE_LSB = READ_STATUS_WIDTH; + localparam int unsigned WR_STS_LEN_LSB = WR_STS_BASE_LSB; + localparam int unsigned WR_STS_TAG_LSB = WR_STS_LEN_LSB + LEN_WIDTH; + localparam int unsigned WR_STS_ID_LSB = WR_STS_TAG_LSB + TAG_WIDTH; + localparam int unsigned WR_STS_DEST_LSB = WR_STS_ID_LSB + AXIS_ID_WIDTH; + localparam int unsigned WR_STS_USER_LSB = WR_STS_DEST_LSB + AXIS_DEST_WIDTH; + localparam int unsigned WR_STS_ERROR_LSB = WR_STS_USER_LSB + AXIS_USER_WIDTH; + + wire rstn = ~rst; + + // -------------------------------------------------------------------------- + // Internal DMA-specific descriptor/status interfaces + // -------------------------------------------------------------------------- + + axi_dma_read_desc_if #( + .ADDR_W (AXI_ADDR_WIDTH), + .LEN_W (LEN_WIDTH), + .TAG_W (TAG_WIDTH), + .ID_W (AXIS_ID_WIDTH), + .DEST_W (AXIS_DEST_WIDTH), + .USER_W (AXIS_USER_WIDTH) + ) read_desc_if ( + .aclk (clk), + .aresetn (rstn) + ); + + axi_dma_read_desc_status_if #( + .TAG_W (TAG_WIDTH) + ) read_desc_status_if ( + .aclk (clk), + .aresetn (rstn) + ); + + axi_dma_write_desc_if #( + .ADDR_W (AXI_ADDR_WIDTH), + .LEN_W (LEN_WIDTH), + .TAG_W (TAG_WIDTH) + ) write_desc_if ( + .aclk (clk), + .aresetn (rstn) + ); + + axi_dma_write_desc_status_if #( + .LEN_W (LEN_WIDTH), + .TAG_W (TAG_WIDTH), + .ID_W (AXIS_ID_WIDTH), + .DEST_W (AXIS_DEST_WIDTH), + .USER_W (AXIS_USER_WIDTH) + ) write_desc_status_if ( + .aclk (clk), + .aresetn (rstn) + ); + + // -------------------------------------------------------------------------- + // Command AXIS -> read/write descriptors + // -------------------------------------------------------------------------- + + wire cmd_valid = s_axis_desc_cmd.req.t.valid; + wire cmd_ready = (!read_enable || read_desc_if.resp.ready) && + (!write_enable || write_desc_if.resp.ready); + + // Only assert a descriptor valid when the complete command can be accepted. + // This prevents partial consumption when both read and write are enabled. + assign read_desc_if.req.valid = cmd_valid && read_enable && (!write_enable || write_desc_if.resp.ready); + assign write_desc_if.req.valid = cmd_valid && write_enable && (!read_enable || read_desc_if.resp.ready); + + assign s_axis_desc_cmd.resp.ready = cmd_ready; + + assign read_desc_if.req.addr = s_axis_desc_cmd.req.t.data[RD_ADDR_LSB +: AXI_ADDR_WIDTH]; + assign read_desc_if.req.len = s_axis_desc_cmd.req.t.data[RD_LEN_LSB +: LEN_WIDTH]; + assign read_desc_if.req.tag = s_axis_desc_cmd.req.t.data[RD_TAG_LSB +: TAG_WIDTH]; + assign read_desc_if.req.id = s_axis_desc_cmd.req.t.data[RD_ID_LSB +: AXIS_ID_WIDTH]; + assign read_desc_if.req.dest = s_axis_desc_cmd.req.t.data[RD_DEST_LSB +: AXIS_DEST_WIDTH]; + assign read_desc_if.req.user = s_axis_desc_cmd.req.t.data[RD_USER_LSB +: AXIS_USER_WIDTH]; + + assign write_desc_if.req.addr = s_axis_desc_cmd.req.t.data[WR_ADDR_LSB +: AXI_ADDR_WIDTH]; + assign write_desc_if.req.len = s_axis_desc_cmd.req.t.data[WR_LEN_LSB +: LEN_WIDTH]; + assign write_desc_if.req.tag = s_axis_desc_cmd.req.t.data[WR_TAG_LSB +: TAG_WIDTH]; + + // -------------------------------------------------------------------------- + // Lower DMA wrapper + // -------------------------------------------------------------------------- + + axi_dma_if_wrapper #( + .AXI_DATA_WIDTH (AXI_DATA_WIDTH), + .AXI_ADDR_WIDTH (AXI_ADDR_WIDTH), + .AXI_STRB_WIDTH (AXI_STRB_WIDTH), + .AXI_ID_WIDTH (AXI_ID_WIDTH), + .AXI_USER_WIDTH (AXI_USER_WIDTH), + .AXI_MAX_BURST_LEN (AXI_MAX_BURST_LEN), + + .AXIS_DATA_WIDTH (AXIS_DATA_WIDTH), + .AXIS_KEEP_ENABLE (AXIS_KEEP_ENABLE), + .AXIS_KEEP_WIDTH (AXIS_KEEP_WIDTH), + .AXIS_LAST_ENABLE (AXIS_LAST_ENABLE), + .AXIS_ID_ENABLE (AXIS_ID_ENABLE), + .AXIS_ID_WIDTH (AXIS_ID_WIDTH), + .AXIS_DEST_ENABLE (AXIS_DEST_ENABLE), + .AXIS_DEST_WIDTH (AXIS_DEST_WIDTH), + .AXIS_USER_ENABLE (AXIS_USER_ENABLE), + .AXIS_USER_WIDTH (AXIS_USER_WIDTH), + + .LEN_WIDTH (LEN_WIDTH), + .TAG_WIDTH (TAG_WIDTH), + .ENABLE_SG (ENABLE_SG), + .ENABLE_UNALIGNED (ENABLE_UNALIGNED) + ) u_axi_dma_if_wrapper ( + .clk (clk), + .rst (rst), + + .s_axis_read_desc (read_desc_if), + .m_axis_read_desc_status (read_desc_status_if), + .m_axis_read_data (m_axis_read_data), + + .s_axis_write_desc (write_desc_if), + .m_axis_write_desc_status (write_desc_status_if), + .s_axis_write_data (s_axis_write_data), + + .m_axi (m_axi), + + .read_enable (read_enable), + .write_enable (write_enable), + .write_abort (write_abort) + ); + + // -------------------------------------------------------------------------- + // Status capture and unified AXIS output + // -------------------------------------------------------------------------- + // Forencich descriptor status channels have valid but no ready. A regular + // AXI-Stream output can be stalled + // this wrapper stores one pending read status and one pending write status. + // if you need more, please attack a fifo + + logic rd_status_pending; + logic [TAG_WIDTH-1:0] rd_status_tag_q; + logic [3:0] rd_status_error_q; + + logic wr_status_pending; + logic [LEN_WIDTH-1:0] wr_status_len_q; + logic [TAG_WIDTH-1:0] wr_status_tag_q; + logic [AXIS_ID_WIDTH-1:0] wr_status_id_q; + logic [AXIS_DEST_WIDTH-1:0] wr_status_dest_q; + logic [AXIS_USER_WIDTH-1:0] wr_status_user_q; + logic [3:0] wr_status_error_q; + + wire status_valid = rd_status_pending || wr_status_pending; + wire status_fire = status_valid && m_axis_desc_status.resp.ready; + + always_ff @(posedge clk) begin + if (rst) begin + rd_status_pending <= 1'b0; + wr_status_pending <= 1'b0; + + rd_status_tag_q <= '0; + rd_status_error_q <= '0; + + wr_status_len_q <= '0; + wr_status_tag_q <= '0; + wr_status_id_q <= '0; + wr_status_dest_q <= '0; + wr_status_user_q <= '0; + wr_status_error_q <= '0; + end else begin + if (status_fire) begin + rd_status_pending <= 1'b0; + wr_status_pending <= 1'b0; + end + + if (read_desc_status_if.req.valid) begin +`ifndef SYNTHESIS + if (rd_status_pending && !status_fire) begin + $error("axi_dma_axis_compat: read status overflow; add a FIFO or do not backpressure status output"); + end +`endif + rd_status_pending <= 1'b1; + rd_status_tag_q <= read_desc_status_if.req.tag; + rd_status_error_q <= read_desc_status_if.req.error; + end + + if (write_desc_status_if.req.valid) begin +`ifndef SYNTHESIS + if (wr_status_pending && !status_fire) begin + $error("axi_dma_axis_compat: write status overflow; add a FIFO or do not backpressure status output"); + end +`endif + wr_status_pending <= 1'b1; + wr_status_len_q <= write_desc_status_if.req.len; + wr_status_tag_q <= write_desc_status_if.req.tag; + wr_status_id_q <= write_desc_status_if.req.id; + wr_status_dest_q <= write_desc_status_if.req.dest; + wr_status_user_q <= write_desc_status_if.req.user; + wr_status_error_q <= write_desc_status_if.req.error; + end + end + end + + logic [DESC_STATUS_DATA_WIDTH-1:0] status_tdata; + logic [DESC_STATUS_USER_WIDTH-1:0] status_tuser; + + always_comb begin + status_tdata = '0; + status_tuser = '0; + + if (rd_status_pending) begin + status_tdata[RD_STS_TAG_LSB +: TAG_WIDTH] = rd_status_tag_q; + status_tdata[RD_STS_ERROR_LSB +: 4] = rd_status_error_q; + status_tuser[0] = 1'b1; + end + + if (wr_status_pending) begin + status_tdata[WR_STS_LEN_LSB +: LEN_WIDTH] = wr_status_len_q; + status_tdata[WR_STS_TAG_LSB +: TAG_WIDTH] = wr_status_tag_q; + status_tdata[WR_STS_ID_LSB +: AXIS_ID_WIDTH] = wr_status_id_q; + status_tdata[WR_STS_DEST_LSB +: AXIS_DEST_WIDTH] = wr_status_dest_q; + status_tdata[WR_STS_USER_LSB +: AXIS_USER_WIDTH] = wr_status_user_q; + status_tdata[WR_STS_ERROR_LSB +: 4] = wr_status_error_q; + status_tuser[1] = 1'b1; + end + end + + assign m_axis_desc_status.req.t.data = status_tdata; + assign m_axis_desc_status.req.t.keep = {DESC_STATUS_KEEP_WIDTH{1'b1}}; + assign m_axis_desc_status.req.t.strb = {DESC_STATUS_KEEP_WIDTH{1'b1}}; + assign m_axis_desc_status.req.t.last = 1'b1; + assign m_axis_desc_status.req.t.id = '0; + assign m_axis_desc_status.req.t.dest = '0; + assign m_axis_desc_status.req.t.user = status_tuser; + assign m_axis_desc_status.req.t.valid = status_valid; + +endmodule : axi_dma_axis_compat + +`default_nettype wire diff --git a/external/external/rtl_libs/axi/rtl/axi_dma_desc_if.sv b/external/external/rtl_libs/axi/rtl/axi_dma_desc_if.sv new file mode 100644 index 0000000..c0c608a --- /dev/null +++ b/external/external/rtl_libs/axi/rtl/axi_dma_desc_if.sv @@ -0,0 +1,109 @@ +`default_nettype none + +interface axi_dma_read_desc_if #( + parameter int unsigned ADDR_W = 64, + parameter int unsigned LEN_W = 20, + parameter int unsigned TAG_W = 8, + parameter int unsigned ID_W = 8, + parameter int unsigned DEST_W = 8, + parameter int unsigned USER_W = 1 +)( + input logic aclk, + input logic aresetn +); + typedef struct packed { + logic [ADDR_W-1:0] addr; + logic [LEN_W-1:0] len; + logic [TAG_W-1:0] tag; + logic [ID_W-1:0] id; + logic [DEST_W-1:0] dest; + logic [USER_W-1:0] user; + logic valid; + } req_t; + + typedef struct packed { + logic ready; + } resp_t; + + req_t req; + resp_t resp; + + modport master (input aclk, aresetn, output req, input resp); + modport slave (input aclk, aresetn, input req, output resp); + modport monitor (input aclk, aresetn, input req, input resp); +endinterface : axi_dma_read_desc_if + +interface axi_dma_read_desc_status_if #( + parameter int unsigned TAG_W = 8 +)( + input logic aclk, + input logic aresetn +); + typedef struct packed { + logic [TAG_W-1:0] tag; + logic [3:0] error; + logic valid; + } req_t; + + req_t req; + + modport master (input aclk, aresetn, output req); + modport slave (input aclk, aresetn, input req); + modport monitor (input aclk, aresetn, input req); +endinterface : axi_dma_read_desc_status_if + +interface axi_dma_write_desc_if #( + parameter int unsigned ADDR_W = 64, + parameter int unsigned LEN_W = 20, + parameter int unsigned TAG_W = 8 +)( + input logic aclk, + input logic aresetn +); + typedef struct packed { + logic [ADDR_W-1:0] addr; + logic [LEN_W-1:0] len; + logic [TAG_W-1:0] tag; + logic valid; + } req_t; + + typedef struct packed { + logic ready; + } resp_t; + + req_t req; + resp_t resp; + + modport master (input aclk, aresetn, output req, input resp); + modport slave (input aclk, aresetn, input req, output resp); + modport monitor (input aclk, aresetn, input req, input resp); +endinterface : axi_dma_write_desc_if + +interface axi_dma_write_desc_status_if #( + parameter int unsigned LEN_W = 20, + parameter int unsigned TAG_W = 8, + parameter int unsigned ID_W = 8, + parameter int unsigned DEST_W = 8, + parameter int unsigned USER_W = 1 +)( + input logic aclk, + input logic aresetn +); + typedef struct packed { + logic [LEN_W-1:0] len; + logic [TAG_W-1:0] tag; + logic [ID_W-1:0] id; + logic [DEST_W-1:0] dest; + logic [USER_W-1:0] user; + logic [3:0] error; + logic valid; + } req_t; + + req_t req; + + modport master (input aclk, aresetn, output req); + modport slave (input aclk, aresetn, input req); + modport monitor (input aclk, aresetn, input req); +endinterface : axi_dma_write_desc_status_if + +`default_nettype wire diff --git a/external/external/rtl_libs/axi/rtl/axi_dma_if_wrapper.sv b/external/external/rtl_libs/axi/rtl/axi_dma_if_wrapper.sv new file mode 100644 index 0000000..b5e3a1d --- /dev/null +++ b/external/external/rtl_libs/axi/rtl/axi_dma_if_wrapper.sv @@ -0,0 +1,643 @@ +// SPDX-License-Identifier: MIT +// +// SystemVerilog interface wrapper around alexforencich/verilog-axi axi_dma.v. +// +// AXI memory, AXI-Stream data, DMA descriptor, and DMA status channels are all +// exposed through compact interfaces. The original Forencich core remains +// untouched and is connected through local flat wires. + +`default_nettype none + +// DMA Specific wrappers & converters +module axi_dma_read_desc_flat_to_if #( + parameter int unsigned ADDR_W = 64, + parameter int unsigned LEN_W = 20, + parameter int unsigned TAG_W = 8, + parameter int unsigned ID_W = 8, + parameter int unsigned DEST_W = 8, + parameter int unsigned USER_W = 1 +)( + input logic [ADDR_W-1:0] s_axis_read_desc_addr, + input logic [LEN_W-1:0] s_axis_read_desc_len, + input logic [TAG_W-1:0] s_axis_read_desc_tag, + input logic [ID_W-1:0] s_axis_read_desc_id, + input logic [DEST_W-1:0] s_axis_read_desc_dest, + input logic [USER_W-1:0] s_axis_read_desc_user, + input logic s_axis_read_desc_valid, + output logic s_axis_read_desc_ready, + + axi_dma_read_desc_if.master m_axis_read_desc +); + assign m_axis_read_desc.req.addr = s_axis_read_desc_addr; + assign m_axis_read_desc.req.len = s_axis_read_desc_len; + assign m_axis_read_desc.req.tag = s_axis_read_desc_tag; + assign m_axis_read_desc.req.id = s_axis_read_desc_id; + assign m_axis_read_desc.req.dest = s_axis_read_desc_dest; + assign m_axis_read_desc.req.user = s_axis_read_desc_user; + assign m_axis_read_desc.req.valid = s_axis_read_desc_valid; + + assign s_axis_read_desc_ready = m_axis_read_desc.resp.ready; +endmodule : axi_dma_read_desc_flat_to_if + + +module axi_dma_read_desc_if_to_flat #( + parameter int unsigned ADDR_W = 64, + parameter int unsigned LEN_W = 20, + parameter int unsigned TAG_W = 8, + parameter int unsigned ID_W = 8, + parameter int unsigned DEST_W = 8, + parameter int unsigned USER_W = 1 +)( + axi_dma_read_desc_if.slave s_axis_read_desc, + + output logic [ADDR_W-1:0] m_axis_read_desc_addr, + output logic [LEN_W-1:0] m_axis_read_desc_len, + output logic [TAG_W-1:0] m_axis_read_desc_tag, + output logic [ID_W-1:0] m_axis_read_desc_id, + output logic [DEST_W-1:0] m_axis_read_desc_dest, + output logic [USER_W-1:0] m_axis_read_desc_user, + output logic m_axis_read_desc_valid, + input logic m_axis_read_desc_ready +); + assign m_axis_read_desc_addr = s_axis_read_desc.req.addr; + assign m_axis_read_desc_len = s_axis_read_desc.req.len; + assign m_axis_read_desc_tag = s_axis_read_desc.req.tag; + assign m_axis_read_desc_id = s_axis_read_desc.req.id; + assign m_axis_read_desc_dest = s_axis_read_desc.req.dest; + assign m_axis_read_desc_user = s_axis_read_desc.req.user; + assign m_axis_read_desc_valid = s_axis_read_desc.req.valid; + + assign s_axis_read_desc.resp.ready = m_axis_read_desc_ready; +endmodule : axi_dma_read_desc_if_to_flat + + +module axi_dma_read_desc_status_flat_to_if #( + parameter int unsigned TAG_W = 8 +)( + input logic [TAG_W-1:0] m_axis_read_desc_status_tag, + input logic [3:0] m_axis_read_desc_status_error, + input logic m_axis_read_desc_status_valid, + + axi_dma_read_desc_status_if.master m_axis_read_desc_status +); + assign m_axis_read_desc_status.req.tag = m_axis_read_desc_status_tag; + assign m_axis_read_desc_status.req.error = m_axis_read_desc_status_error; + assign m_axis_read_desc_status.req.valid = m_axis_read_desc_status_valid; +endmodule : axi_dma_read_desc_status_flat_to_if + + +module axi_dma_read_desc_status_if_to_flat #( + parameter int unsigned TAG_W = 8 +)( + axi_dma_read_desc_status_if.slave s_axis_read_desc_status, + + output logic [TAG_W-1:0] m_axis_read_desc_status_tag, + output logic [3:0] m_axis_read_desc_status_error, + output logic m_axis_read_desc_status_valid +); + assign m_axis_read_desc_status_tag = s_axis_read_desc_status.req.tag; + assign m_axis_read_desc_status_error = s_axis_read_desc_status.req.error; + assign m_axis_read_desc_status_valid = s_axis_read_desc_status.req.valid; +endmodule : axi_dma_read_desc_status_if_to_flat + + +module axi_dma_write_desc_flat_to_if #( + parameter int unsigned ADDR_W = 64, + parameter int unsigned LEN_W = 20, + parameter int unsigned TAG_W = 8 +)( + input logic [ADDR_W-1:0] s_axis_write_desc_addr, + input logic [LEN_W-1:0] s_axis_write_desc_len, + input logic [TAG_W-1:0] s_axis_write_desc_tag, + input logic s_axis_write_desc_valid, + output logic s_axis_write_desc_ready, + + axi_dma_write_desc_if.master m_axis_write_desc +); + assign m_axis_write_desc.req.addr = s_axis_write_desc_addr; + assign m_axis_write_desc.req.len = s_axis_write_desc_len; + assign m_axis_write_desc.req.tag = s_axis_write_desc_tag; + assign m_axis_write_desc.req.valid = s_axis_write_desc_valid; + + assign s_axis_write_desc_ready = m_axis_write_desc.resp.ready; +endmodule : axi_dma_write_desc_flat_to_if + + +module axi_dma_write_desc_if_to_flat #( + parameter int unsigned ADDR_W = 64, + parameter int unsigned LEN_W = 20, + parameter int unsigned TAG_W = 8 +)( + axi_dma_write_desc_if.slave s_axis_write_desc, + + output logic [ADDR_W-1:0] m_axis_write_desc_addr, + output logic [LEN_W-1:0] m_axis_write_desc_len, + output logic [TAG_W-1:0] m_axis_write_desc_tag, + output logic m_axis_write_desc_valid, + input logic m_axis_write_desc_ready +); + assign m_axis_write_desc_addr = s_axis_write_desc.req.addr; + assign m_axis_write_desc_len = s_axis_write_desc.req.len; + assign m_axis_write_desc_tag = s_axis_write_desc.req.tag; + assign m_axis_write_desc_valid = s_axis_write_desc.req.valid; + + assign s_axis_write_desc.resp.ready = m_axis_write_desc_ready; +endmodule : axi_dma_write_desc_if_to_flat + + +module axi_dma_write_desc_status_flat_to_if #( + parameter int unsigned LEN_W = 20, + parameter int unsigned TAG_W = 8, + parameter int unsigned ID_W = 8, + parameter int unsigned DEST_W = 8, + parameter int unsigned USER_W = 1 +)( + input logic [LEN_W-1:0] m_axis_write_desc_status_len, + input logic [TAG_W-1:0] m_axis_write_desc_status_tag, + input logic [ID_W-1:0] m_axis_write_desc_status_id, + input logic [DEST_W-1:0] m_axis_write_desc_status_dest, + input logic [USER_W-1:0] m_axis_write_desc_status_user, + input logic [3:0] m_axis_write_desc_status_error, + input logic m_axis_write_desc_status_valid, + + axi_dma_write_desc_status_if.master m_axis_write_desc_status +); + assign m_axis_write_desc_status.req.len = m_axis_write_desc_status_len; + assign m_axis_write_desc_status.req.tag = m_axis_write_desc_status_tag; + assign m_axis_write_desc_status.req.id = m_axis_write_desc_status_id; + assign m_axis_write_desc_status.req.dest = m_axis_write_desc_status_dest; + assign m_axis_write_desc_status.req.user = m_axis_write_desc_status_user; + assign m_axis_write_desc_status.req.error = m_axis_write_desc_status_error; + assign m_axis_write_desc_status.req.valid = m_axis_write_desc_status_valid; +endmodule : axi_dma_write_desc_status_flat_to_if + + +module axi_dma_write_desc_status_if_to_flat #( + parameter int unsigned LEN_W = 20, + parameter int unsigned TAG_W = 8, + parameter int unsigned ID_W = 8, + parameter int unsigned DEST_W = 8, + parameter int unsigned USER_W = 1 +)( + axi_dma_write_desc_status_if.slave s_axis_write_desc_status, + + output logic [LEN_W-1:0] m_axis_write_desc_status_len, + output logic [TAG_W-1:0] m_axis_write_desc_status_tag, + output logic [ID_W-1:0] m_axis_write_desc_status_id, + output logic [DEST_W-1:0] m_axis_write_desc_status_dest, + output logic [USER_W-1:0] m_axis_write_desc_status_user, + output logic [3:0] m_axis_write_desc_status_error, + output logic m_axis_write_desc_status_valid +); + assign m_axis_write_desc_status_len = s_axis_write_desc_status.req.len; + assign m_axis_write_desc_status_tag = s_axis_write_desc_status.req.tag; + assign m_axis_write_desc_status_id = s_axis_write_desc_status.req.id; + assign m_axis_write_desc_status_dest = s_axis_write_desc_status.req.dest; + assign m_axis_write_desc_status_user = s_axis_write_desc_status.req.user; + assign m_axis_write_desc_status_error = s_axis_write_desc_status.req.error; + assign m_axis_write_desc_status_valid = s_axis_write_desc_status.req.valid; +endmodule : axi_dma_write_desc_status_if_to_flat + + +module axi_dma_if_wrapper #( + parameter int unsigned AXI_DATA_WIDTH = 32, + parameter int unsigned AXI_ADDR_WIDTH = 16, + parameter int unsigned AXI_STRB_WIDTH = AXI_DATA_WIDTH / 8, + parameter int unsigned AXI_ID_WIDTH = 8, + parameter int unsigned AXI_USER_WIDTH = 1, + parameter int unsigned AXI_MAX_BURST_LEN = 16, + + parameter int unsigned AXIS_DATA_WIDTH = AXI_DATA_WIDTH, + parameter int unsigned AXIS_KEEP_ENABLE = AXIS_DATA_WIDTH > 8, + parameter int unsigned AXIS_KEEP_WIDTH = AXIS_DATA_WIDTH / 8, + parameter int unsigned AXIS_LAST_ENABLE = 1, + parameter int unsigned AXIS_ID_ENABLE = 1, + parameter int unsigned AXIS_ID_WIDTH = 8, + parameter int unsigned AXIS_DEST_ENABLE = 0, + parameter int unsigned AXIS_DEST_WIDTH = 8, + parameter int unsigned AXIS_USER_ENABLE = 1, + parameter int unsigned AXIS_USER_WIDTH = 1, + + parameter int unsigned LEN_WIDTH = 20, + parameter int unsigned TAG_WIDTH = 8, + parameter int unsigned ENABLE_SG = 0, + parameter int unsigned ENABLE_UNALIGNED = 0 +)( + input logic clk, + input logic rst, + + /* + * AXI read descriptor input. + */ + axi_dma_read_desc_if.slave s_axis_read_desc, + + /* + * AXI read descriptor status output. + */ + axi_dma_read_desc_status_if.master m_axis_read_desc_status, + + /* + * AXI stream read data output. + */ + axis_if.master m_axis_read_data, + + /* + * AXI write descriptor input. + */ + axi_dma_write_desc_if.slave s_axis_write_desc, + + /* + * AXI write descriptor status output. + */ + axi_dma_write_desc_status_if.master m_axis_write_desc_status, + + /* + * AXI stream write data input. + */ + axis_if.slave s_axis_write_data, + + /* + * AXI memory master interface. + */ + axi4_if.master m_axi, + + /* + * Configuration. + */ + input logic read_enable, + input logic write_enable, + input logic write_abort +); + + // -------------------------------------------------------------------------- + // Flat wires connected to original alexforencich axi_dma.v + // -------------------------------------------------------------------------- + + logic [AXI_ADDR_WIDTH-1:0] dma_s_axis_read_desc_addr; + logic [LEN_WIDTH-1:0] dma_s_axis_read_desc_len; + logic [TAG_WIDTH-1:0] dma_s_axis_read_desc_tag; + logic [AXIS_ID_WIDTH-1:0] dma_s_axis_read_desc_id; + logic [AXIS_DEST_WIDTH-1:0] dma_s_axis_read_desc_dest; + logic [AXIS_USER_WIDTH-1:0] dma_s_axis_read_desc_user; + logic dma_s_axis_read_desc_valid; + logic dma_s_axis_read_desc_ready; + + logic [TAG_WIDTH-1:0] dma_m_axis_read_desc_status_tag; + logic [3:0] dma_m_axis_read_desc_status_error; + logic dma_m_axis_read_desc_status_valid; + + logic [AXI_ADDR_WIDTH-1:0] dma_s_axis_write_desc_addr; + logic [LEN_WIDTH-1:0] dma_s_axis_write_desc_len; + logic [TAG_WIDTH-1:0] dma_s_axis_write_desc_tag; + logic dma_s_axis_write_desc_valid; + logic dma_s_axis_write_desc_ready; + + logic [LEN_WIDTH-1:0] dma_m_axis_write_desc_status_len; + logic [TAG_WIDTH-1:0] dma_m_axis_write_desc_status_tag; + logic [AXIS_ID_WIDTH-1:0] dma_m_axis_write_desc_status_id; + logic [AXIS_DEST_WIDTH-1:0] dma_m_axis_write_desc_status_dest; + logic [AXIS_USER_WIDTH-1:0] dma_m_axis_write_desc_status_user; + logic [3:0] dma_m_axis_write_desc_status_error; + logic dma_m_axis_write_desc_status_valid; + + logic [AXIS_DATA_WIDTH-1:0] dma_m_axis_read_data_tdata; + logic [AXIS_KEEP_WIDTH-1:0] dma_m_axis_read_data_tkeep; + logic dma_m_axis_read_data_tvalid; + logic dma_m_axis_read_data_tready; + logic dma_m_axis_read_data_tlast; + logic [AXIS_ID_WIDTH-1:0] dma_m_axis_read_data_tid; + logic [AXIS_DEST_WIDTH-1:0] dma_m_axis_read_data_tdest; + logic [AXIS_USER_WIDTH-1:0] dma_m_axis_read_data_tuser; + + logic [AXIS_DATA_WIDTH-1:0] dma_s_axis_write_data_tdata; + logic [AXIS_KEEP_WIDTH-1:0] dma_s_axis_write_data_tkeep; + logic [AXIS_KEEP_WIDTH-1:0] unused_s_axis_write_data_tstrb; + logic dma_s_axis_write_data_tvalid; + logic dma_s_axis_write_data_tready; + logic dma_s_axis_write_data_tlast; + logic [AXIS_ID_WIDTH-1:0] dma_s_axis_write_data_tid; + logic [AXIS_DEST_WIDTH-1:0] dma_s_axis_write_data_tdest; + logic [AXIS_USER_WIDTH-1:0] dma_s_axis_write_data_tuser; + + logic [AXI_ID_WIDTH-1:0] dma_m_axi_awid; + logic [AXI_ADDR_WIDTH-1:0] dma_m_axi_awaddr; + logic [7:0] dma_m_axi_awlen; + logic [2:0] dma_m_axi_awsize; + logic [1:0] dma_m_axi_awburst; + logic dma_m_axi_awlock; + logic [3:0] dma_m_axi_awcache; + logic [2:0] dma_m_axi_awprot; + logic dma_m_axi_awvalid; + logic dma_m_axi_awready; + + logic [AXI_DATA_WIDTH-1:0] dma_m_axi_wdata; + logic [AXI_STRB_WIDTH-1:0] dma_m_axi_wstrb; + logic dma_m_axi_wlast; + logic dma_m_axi_wvalid; + logic dma_m_axi_wready; + + logic [AXI_ID_WIDTH-1:0] dma_m_axi_bid; + logic [1:0] dma_m_axi_bresp; + logic dma_m_axi_bvalid; + logic dma_m_axi_bready; + + logic [AXI_ID_WIDTH-1:0] dma_m_axi_arid; + logic [AXI_ADDR_WIDTH-1:0] dma_m_axi_araddr; + logic [7:0] dma_m_axi_arlen; + logic [2:0] dma_m_axi_arsize; + logic [1:0] dma_m_axi_arburst; + logic dma_m_axi_arlock; + logic [3:0] dma_m_axi_arcache; + logic [2:0] dma_m_axi_arprot; + logic dma_m_axi_arvalid; + logic dma_m_axi_arready; + + logic [AXI_ID_WIDTH-1:0] dma_m_axi_rid; + logic [AXI_DATA_WIDTH-1:0] dma_m_axi_rdata; + logic [1:0] dma_m_axi_rresp; + logic dma_m_axi_rlast; + logic dma_m_axi_rvalid; + logic dma_m_axi_rready; + + logic [AXI_USER_WIDTH-1:0] unused_m_axi_buser; + logic [AXI_USER_WIDTH-1:0] unused_m_axi_ruser; + + // Original DMA: flat ports only. + axi_dma #( + .AXI_DATA_WIDTH (AXI_DATA_WIDTH), + .AXI_ADDR_WIDTH (AXI_ADDR_WIDTH), + .AXI_STRB_WIDTH (AXI_STRB_WIDTH), + .AXI_ID_WIDTH (AXI_ID_WIDTH), + .AXI_MAX_BURST_LEN (AXI_MAX_BURST_LEN), + .AXIS_DATA_WIDTH (AXIS_DATA_WIDTH), + .AXIS_KEEP_ENABLE (AXIS_KEEP_ENABLE), + .AXIS_KEEP_WIDTH (AXIS_KEEP_WIDTH), + .AXIS_LAST_ENABLE (AXIS_LAST_ENABLE), + .AXIS_ID_ENABLE (AXIS_ID_ENABLE), + .AXIS_ID_WIDTH (AXIS_ID_WIDTH), + .AXIS_DEST_ENABLE (AXIS_DEST_ENABLE), + .AXIS_DEST_WIDTH (AXIS_DEST_WIDTH), + .AXIS_USER_ENABLE (AXIS_USER_ENABLE), + .AXIS_USER_WIDTH (AXIS_USER_WIDTH), + .LEN_WIDTH (LEN_WIDTH), + .TAG_WIDTH (TAG_WIDTH), + .ENABLE_SG (ENABLE_SG), + .ENABLE_UNALIGNED (ENABLE_UNALIGNED) + ) u_axi_dma ( + .clk (clk), + .rst (rst), + + .s_axis_read_desc_addr (dma_s_axis_read_desc_addr), + .s_axis_read_desc_len (dma_s_axis_read_desc_len), + .s_axis_read_desc_tag (dma_s_axis_read_desc_tag), + .s_axis_read_desc_id (dma_s_axis_read_desc_id), + .s_axis_read_desc_dest (dma_s_axis_read_desc_dest), + .s_axis_read_desc_user (dma_s_axis_read_desc_user), + .s_axis_read_desc_valid (dma_s_axis_read_desc_valid), + .s_axis_read_desc_ready (dma_s_axis_read_desc_ready), + + .m_axis_read_desc_status_tag (dma_m_axis_read_desc_status_tag), + .m_axis_read_desc_status_error (dma_m_axis_read_desc_status_error), + .m_axis_read_desc_status_valid (dma_m_axis_read_desc_status_valid), + + .m_axis_read_data_tdata (dma_m_axis_read_data_tdata), + .m_axis_read_data_tkeep (dma_m_axis_read_data_tkeep), + .m_axis_read_data_tvalid (dma_m_axis_read_data_tvalid), + .m_axis_read_data_tready (dma_m_axis_read_data_tready), + .m_axis_read_data_tlast (dma_m_axis_read_data_tlast), + .m_axis_read_data_tid (dma_m_axis_read_data_tid), + .m_axis_read_data_tdest (dma_m_axis_read_data_tdest), + .m_axis_read_data_tuser (dma_m_axis_read_data_tuser), + + .s_axis_write_desc_addr (dma_s_axis_write_desc_addr), + .s_axis_write_desc_len (dma_s_axis_write_desc_len), + .s_axis_write_desc_tag (dma_s_axis_write_desc_tag), + .s_axis_write_desc_valid (dma_s_axis_write_desc_valid), + .s_axis_write_desc_ready (dma_s_axis_write_desc_ready), + + .m_axis_write_desc_status_len (dma_m_axis_write_desc_status_len), + .m_axis_write_desc_status_tag (dma_m_axis_write_desc_status_tag), + .m_axis_write_desc_status_id (dma_m_axis_write_desc_status_id), + .m_axis_write_desc_status_dest (dma_m_axis_write_desc_status_dest), + .m_axis_write_desc_status_user (dma_m_axis_write_desc_status_user), + .m_axis_write_desc_status_error (dma_m_axis_write_desc_status_error), + .m_axis_write_desc_status_valid (dma_m_axis_write_desc_status_valid), + + .s_axis_write_data_tdata (dma_s_axis_write_data_tdata), + .s_axis_write_data_tkeep (dma_s_axis_write_data_tkeep), + .s_axis_write_data_tvalid (dma_s_axis_write_data_tvalid), + .s_axis_write_data_tready (dma_s_axis_write_data_tready), + .s_axis_write_data_tlast (dma_s_axis_write_data_tlast), + .s_axis_write_data_tid (dma_s_axis_write_data_tid), + .s_axis_write_data_tdest (dma_s_axis_write_data_tdest), + .s_axis_write_data_tuser (dma_s_axis_write_data_tuser), + + .m_axi_awid (dma_m_axi_awid), + .m_axi_awaddr (dma_m_axi_awaddr), + .m_axi_awlen (dma_m_axi_awlen), + .m_axi_awsize (dma_m_axi_awsize), + .m_axi_awburst (dma_m_axi_awburst), + .m_axi_awlock (dma_m_axi_awlock), + .m_axi_awcache (dma_m_axi_awcache), + .m_axi_awprot (dma_m_axi_awprot), + .m_axi_awvalid (dma_m_axi_awvalid), + .m_axi_awready (dma_m_axi_awready), + + .m_axi_wdata (dma_m_axi_wdata), + .m_axi_wstrb (dma_m_axi_wstrb), + .m_axi_wlast (dma_m_axi_wlast), + .m_axi_wvalid (dma_m_axi_wvalid), + .m_axi_wready (dma_m_axi_wready), + + .m_axi_bid (dma_m_axi_bid), + .m_axi_bresp (dma_m_axi_bresp), + .m_axi_bvalid (dma_m_axi_bvalid), + .m_axi_bready (dma_m_axi_bready), + + .m_axi_arid (dma_m_axi_arid), + .m_axi_araddr (dma_m_axi_araddr), + .m_axi_arlen (dma_m_axi_arlen), + .m_axi_arsize (dma_m_axi_arsize), + .m_axi_arburst (dma_m_axi_arburst), + .m_axi_arlock (dma_m_axi_arlock), + .m_axi_arcache (dma_m_axi_arcache), + .m_axi_arprot (dma_m_axi_arprot), + .m_axi_arvalid (dma_m_axi_arvalid), + .m_axi_arready (dma_m_axi_arready), + + .m_axi_rid (dma_m_axi_rid), + .m_axi_rdata (dma_m_axi_rdata), + .m_axi_rresp (dma_m_axi_rresp), + .m_axi_rlast (dma_m_axi_rlast), + .m_axi_rvalid (dma_m_axi_rvalid), + .m_axi_rready (dma_m_axi_rready), + + .read_enable (read_enable), + .write_enable (write_enable), + .write_abort (write_abort) + ); + + // local read descriptor interface -> DMA flat input + axi_dma_read_desc_if_to_flat #( + .ADDR_W (AXI_ADDR_WIDTH), + .LEN_W (LEN_WIDTH), + .TAG_W (TAG_WIDTH), + .ID_W (AXIS_ID_WIDTH), + .DEST_W (AXIS_DEST_WIDTH), + .USER_W (AXIS_USER_WIDTH) + ) u_s_axis_read_desc_if_to_flat ( + .s_axis_read_desc (s_axis_read_desc), + .m_axis_read_desc_addr (dma_s_axis_read_desc_addr), + .m_axis_read_desc_len (dma_s_axis_read_desc_len), + .m_axis_read_desc_tag (dma_s_axis_read_desc_tag), + .m_axis_read_desc_id (dma_s_axis_read_desc_id), + .m_axis_read_desc_dest (dma_s_axis_read_desc_dest), + .m_axis_read_desc_user (dma_s_axis_read_desc_user), + .m_axis_read_desc_valid (dma_s_axis_read_desc_valid), + .m_axis_read_desc_ready (dma_s_axis_read_desc_ready) + ); + + // DMA read descriptor status flat output -> local status interface + axi_dma_read_desc_status_flat_to_if #( + .TAG_W (TAG_WIDTH) + ) u_m_axis_read_desc_status_flat_to_if ( + .m_axis_read_desc_status_tag (dma_m_axis_read_desc_status_tag), + .m_axis_read_desc_status_error (dma_m_axis_read_desc_status_error), + .m_axis_read_desc_status_valid (dma_m_axis_read_desc_status_valid), + .m_axis_read_desc_status (m_axis_read_desc_status) + ); + + // local write descriptor interface -> DMA flat input + axi_dma_write_desc_if_to_flat #( + .ADDR_W (AXI_ADDR_WIDTH), + .LEN_W (LEN_WIDTH), + .TAG_W (TAG_WIDTH) + ) u_s_axis_write_desc_if_to_flat ( + .s_axis_write_desc (s_axis_write_desc), + .m_axis_write_desc_addr (dma_s_axis_write_desc_addr), + .m_axis_write_desc_len (dma_s_axis_write_desc_len), + .m_axis_write_desc_tag (dma_s_axis_write_desc_tag), + .m_axis_write_desc_valid (dma_s_axis_write_desc_valid), + .m_axis_write_desc_ready (dma_s_axis_write_desc_ready) + ); + + // DMA write descriptor status flat output -> local status interface + axi_dma_write_desc_status_flat_to_if #( + .LEN_W (LEN_WIDTH), + .TAG_W (TAG_WIDTH), + .ID_W (AXIS_ID_WIDTH), + .DEST_W (AXIS_DEST_WIDTH), + .USER_W (AXIS_USER_WIDTH) + ) u_m_axis_write_desc_status_flat_to_if ( + .m_axis_write_desc_status_len (dma_m_axis_write_desc_status_len), + .m_axis_write_desc_status_tag (dma_m_axis_write_desc_status_tag), + .m_axis_write_desc_status_id (dma_m_axis_write_desc_status_id), + .m_axis_write_desc_status_dest (dma_m_axis_write_desc_status_dest), + .m_axis_write_desc_status_user (dma_m_axis_write_desc_status_user), + .m_axis_write_desc_status_error (dma_m_axis_write_desc_status_error), + .m_axis_write_desc_status_valid (dma_m_axis_write_desc_status_valid), + .m_axis_write_desc_status (m_axis_write_desc_status) + ); + + // DMA read data flat output -> local axis_if.master + axis_flat_to_if #( + .DATA_W (AXIS_DATA_WIDTH), + .KEEP_W (AXIS_KEEP_WIDTH), + .ID_W (AXIS_ID_WIDTH), + .DEST_W (AXIS_DEST_WIDTH), + .USER_W (AXIS_USER_WIDTH) + ) u_m_axis_read_data_flat_to_if ( + .s_axis_tdata (dma_m_axis_read_data_tdata), + .s_axis_tkeep (dma_m_axis_read_data_tkeep), + .s_axis_tstrb (dma_m_axis_read_data_tkeep), // axi_dma has no tstrb; mirror tkeep + .s_axis_tlast (dma_m_axis_read_data_tlast), + .s_axis_tid (dma_m_axis_read_data_tid), + .s_axis_tdest (dma_m_axis_read_data_tdest), + .s_axis_tuser (dma_m_axis_read_data_tuser), + .s_axis_tvalid (dma_m_axis_read_data_tvalid), + .s_axis_tready (dma_m_axis_read_data_tready), + .m_axis (m_axis_read_data) + ); + + // local axis_if.slave -> DMA write data flat input + axis_if_to_flat #( + .DATA_W (AXIS_DATA_WIDTH), + .KEEP_W (AXIS_KEEP_WIDTH), + .ID_W (AXIS_ID_WIDTH), + .DEST_W (AXIS_DEST_WIDTH), + .USER_W (AXIS_USER_WIDTH) + ) u_s_axis_write_data_if_to_flat ( + .s_axis (s_axis_write_data), + .m_axis_tdata (dma_s_axis_write_data_tdata), + .m_axis_tkeep (dma_s_axis_write_data_tkeep), + .m_axis_tstrb (unused_s_axis_write_data_tstrb), + .m_axis_tlast (dma_s_axis_write_data_tlast), + .m_axis_tid (dma_s_axis_write_data_tid), + .m_axis_tdest (dma_s_axis_write_data_tdest), + .m_axis_tuser (dma_s_axis_write_data_tuser), + .m_axis_tvalid(dma_s_axis_write_data_tvalid), + .m_axis_tready(dma_s_axis_write_data_tready) + ); + + // DMA AXI master flat output -> local axi4_if.master + axi4_flat_to_if #( + .ADDR_W (AXI_ADDR_WIDTH), + .DATA_W (AXI_DATA_WIDTH), + .ID_W (AXI_ID_WIDTH), + .USER_W (AXI_USER_WIDTH) + ) u_m_axi_flat_to_if ( + .s_axi_awid (dma_m_axi_awid), + .s_axi_awaddr (dma_m_axi_awaddr), + .s_axi_awlen (dma_m_axi_awlen), + .s_axi_awsize (dma_m_axi_awsize), + .s_axi_awburst (dma_m_axi_awburst), + .s_axi_awlock (dma_m_axi_awlock), + .s_axi_awcache (dma_m_axi_awcache), + .s_axi_awprot (dma_m_axi_awprot), + .s_axi_awqos (4'd0), + .s_axi_awregion (4'd0), + .s_axi_awuser ({AXI_USER_WIDTH{1'b0}}), + .s_axi_awvalid (dma_m_axi_awvalid), + .s_axi_awready (dma_m_axi_awready), + + .s_axi_wdata (dma_m_axi_wdata), + .s_axi_wstrb (dma_m_axi_wstrb), + .s_axi_wlast (dma_m_axi_wlast), + .s_axi_wuser ({AXI_USER_WIDTH{1'b0}}), + .s_axi_wvalid (dma_m_axi_wvalid), + .s_axi_wready (dma_m_axi_wready), + + .s_axi_bid (dma_m_axi_bid), + .s_axi_bresp (dma_m_axi_bresp), + .s_axi_buser (unused_m_axi_buser), + .s_axi_bvalid (dma_m_axi_bvalid), + .s_axi_bready (dma_m_axi_bready), + + .s_axi_arid (dma_m_axi_arid), + .s_axi_araddr (dma_m_axi_araddr), + .s_axi_arlen (dma_m_axi_arlen), + .s_axi_arsize (dma_m_axi_arsize), + .s_axi_arburst (dma_m_axi_arburst), + .s_axi_arlock (dma_m_axi_arlock), + .s_axi_arcache (dma_m_axi_arcache), + .s_axi_arprot (dma_m_axi_arprot), + .s_axi_arqos (4'd0), + .s_axi_arregion (4'd0), + .s_axi_aruser ({AXI_USER_WIDTH{1'b0}}), + .s_axi_arvalid (dma_m_axi_arvalid), + .s_axi_arready (dma_m_axi_arready), + + .s_axi_rid (dma_m_axi_rid), + .s_axi_rdata (dma_m_axi_rdata), + .s_axi_rresp (dma_m_axi_rresp), + .s_axi_rlast (dma_m_axi_rlast), + .s_axi_ruser (unused_m_axi_ruser), + .s_axi_rvalid (dma_m_axi_rvalid), + .s_axi_rready (dma_m_axi_rready), + + .m_axi (m_axi) + ); + +endmodule : axi_dma_if_wrapper + +`default_nettype wire diff --git a/external/external/rtl_libs/axi/rtl/axi_dma_wrapper.sv b/external/external/rtl_libs/axi/rtl/axi_dma_wrapper.sv new file mode 100644 index 0000000..d9c20ef --- /dev/null +++ b/external/external/rtl_libs/axi/rtl/axi_dma_wrapper.sv @@ -0,0 +1,453 @@ +// SPDX-License-Identifier: MIT +// +// SystemVerilog interface wrapper around alexforencich/verilog-axi axi_dma.v. +// +// AXI memory, AXI-Stream data, DMA descriptor, and DMA status channels are all +// exposed through compact interfaces. The original Forencich core remains +// untouched and is connected through local flat wires. + +`default_nettype none + +// DMA Specific wrappers & converters +module axi_dma_wrapper #( + parameter int unsigned AXI_DATA_WIDTH = 32, + parameter int unsigned AXI_ADDR_WIDTH = 16, + parameter int unsigned AXI_STRB_WIDTH = AXI_DATA_WIDTH / 8, + parameter int unsigned AXI_ID_WIDTH = 8, + parameter int unsigned AXI_USER_WIDTH = 1, + parameter int unsigned AXI_MAX_BURST_LEN = 16, + + parameter int unsigned AXIS_DATA_WIDTH = AXI_DATA_WIDTH, + parameter int unsigned AXIS_KEEP_ENABLE = AXIS_DATA_WIDTH > 8, + parameter int unsigned AXIS_KEEP_WIDTH = AXIS_DATA_WIDTH / 8, + parameter int unsigned AXIS_LAST_ENABLE = 1, + parameter int unsigned AXIS_ID_ENABLE = 1, + parameter int unsigned AXIS_ID_WIDTH = 8, + parameter int unsigned AXIS_DEST_ENABLE = 0, + parameter int unsigned AXIS_DEST_WIDTH = 8, + parameter int unsigned AXIS_USER_ENABLE = 1, + parameter int unsigned AXIS_USER_WIDTH = 1, + + parameter int unsigned LEN_WIDTH = 20, + parameter int unsigned TAG_WIDTH = 8, + parameter int unsigned ENABLE_SG = 0, + parameter int unsigned ENABLE_UNALIGNED = 0 +)( + input logic clk, + input logic rst, + + axis_if.slave s_axis_read_desc, + + axis_if.master m_axis_read_desc_status, + + axis_if.master m_axis_read_data, + + axis_if.slave s_axis_write_desc, + + axis_if.master m_axis_write_desc_status, + + axis_if.slave s_axis_write_data, + + axi4_if.master m_axi, + + /* + * Configuration. + */ + input logic read_enable, + input logic write_enable, + input logic write_abort +); + + // -------------------------------------------------------------------------- + // Flat wires connected to original alexforencich axi_dma.v + // -------------------------------------------------------------------------- + + logic [AXI_ADDR_WIDTH-1:0] dma_s_axis_read_desc_addr; + logic [LEN_WIDTH-1:0] dma_s_axis_read_desc_len; + logic [TAG_WIDTH-1:0] dma_s_axis_read_desc_tag; + logic [AXIS_ID_WIDTH-1:0] dma_s_axis_read_desc_id; + logic [AXIS_DEST_WIDTH-1:0] dma_s_axis_read_desc_dest; + logic [AXIS_USER_WIDTH-1:0] dma_s_axis_read_desc_user; + logic dma_s_axis_read_desc_valid; + logic dma_s_axis_read_desc_ready; + + logic [TAG_WIDTH-1:0] dma_m_axis_read_desc_status_tag; + logic [3:0] dma_m_axis_read_desc_status_error; + logic dma_m_axis_read_desc_status_valid; + + logic [AXI_ADDR_WIDTH-1:0] dma_s_axis_write_desc_addr; + logic [LEN_WIDTH-1:0] dma_s_axis_write_desc_len; + logic [TAG_WIDTH-1:0] dma_s_axis_write_desc_tag; + logic dma_s_axis_write_desc_valid; + logic dma_s_axis_write_desc_ready; + + logic [LEN_WIDTH-1:0] dma_m_axis_write_desc_status_len; + logic [TAG_WIDTH-1:0] dma_m_axis_write_desc_status_tag; + logic [AXIS_ID_WIDTH-1:0] dma_m_axis_write_desc_status_id; + logic [AXIS_DEST_WIDTH-1:0] dma_m_axis_write_desc_status_dest; + logic [AXIS_USER_WIDTH-1:0] dma_m_axis_write_desc_status_user; + logic [3:0] dma_m_axis_write_desc_status_error; + logic dma_m_axis_write_desc_status_valid; + + logic [AXIS_DATA_WIDTH-1:0] dma_m_axis_read_data_tdata; + logic [AXIS_KEEP_WIDTH-1:0] dma_m_axis_read_data_tkeep; + logic dma_m_axis_read_data_tvalid; + logic dma_m_axis_read_data_tready; + logic dma_m_axis_read_data_tlast; + logic [AXIS_ID_WIDTH-1:0] dma_m_axis_read_data_tid; + logic [AXIS_DEST_WIDTH-1:0] dma_m_axis_read_data_tdest; + logic [AXIS_USER_WIDTH-1:0] dma_m_axis_read_data_tuser; + + logic [AXIS_DATA_WIDTH-1:0] dma_s_axis_write_data_tdata; + logic [AXIS_KEEP_WIDTH-1:0] dma_s_axis_write_data_tkeep; + logic [AXIS_KEEP_WIDTH-1:0] unused_s_axis_write_data_tstrb; + logic dma_s_axis_write_data_tvalid; + logic dma_s_axis_write_data_tready; + logic dma_s_axis_write_data_tlast; + logic [AXIS_ID_WIDTH-1:0] dma_s_axis_write_data_tid; + logic [AXIS_DEST_WIDTH-1:0] dma_s_axis_write_data_tdest; + logic [AXIS_USER_WIDTH-1:0] dma_s_axis_write_data_tuser; + + logic [AXI_ID_WIDTH-1:0] dma_m_axi_awid; + logic [AXI_ADDR_WIDTH-1:0] dma_m_axi_awaddr; + logic [7:0] dma_m_axi_awlen; + logic [2:0] dma_m_axi_awsize; + logic [1:0] dma_m_axi_awburst; + logic dma_m_axi_awlock; + logic [3:0] dma_m_axi_awcache; + logic [2:0] dma_m_axi_awprot; + logic dma_m_axi_awvalid; + logic dma_m_axi_awready; + + logic [AXI_DATA_WIDTH-1:0] dma_m_axi_wdata; + logic [AXI_STRB_WIDTH-1:0] dma_m_axi_wstrb; + logic dma_m_axi_wlast; + logic dma_m_axi_wvalid; + logic dma_m_axi_wready; + + logic [AXI_ID_WIDTH-1:0] dma_m_axi_bid; + logic [1:0] dma_m_axi_bresp; + logic dma_m_axi_bvalid; + logic dma_m_axi_bready; + + logic [AXI_ID_WIDTH-1:0] dma_m_axi_arid; + logic [AXI_ADDR_WIDTH-1:0] dma_m_axi_araddr; + logic [7:0] dma_m_axi_arlen; + logic [2:0] dma_m_axi_arsize; + logic [1:0] dma_m_axi_arburst; + logic dma_m_axi_arlock; + logic [3:0] dma_m_axi_arcache; + logic [2:0] dma_m_axi_arprot; + logic dma_m_axi_arvalid; + logic dma_m_axi_arready; + + logic [AXI_ID_WIDTH-1:0] dma_m_axi_rid; + logic [AXI_DATA_WIDTH-1:0] dma_m_axi_rdata; + logic [1:0] dma_m_axi_rresp; + logic dma_m_axi_rlast; + logic dma_m_axi_rvalid; + logic dma_m_axi_rready; + + logic [AXI_USER_WIDTH-1:0] unused_m_axi_buser; + logic [AXI_USER_WIDTH-1:0] unused_m_axi_ruser; + + // Original DMA: flat ports only. + axi_dma #( + .AXI_DATA_WIDTH (AXI_DATA_WIDTH), + .AXI_ADDR_WIDTH (AXI_ADDR_WIDTH), + .AXI_STRB_WIDTH (AXI_STRB_WIDTH), + .AXI_ID_WIDTH (AXI_ID_WIDTH), + .AXI_MAX_BURST_LEN (AXI_MAX_BURST_LEN), + .AXIS_DATA_WIDTH (AXIS_DATA_WIDTH), + .AXIS_KEEP_ENABLE (AXIS_KEEP_ENABLE), + .AXIS_KEEP_WIDTH (AXIS_KEEP_WIDTH), + .AXIS_LAST_ENABLE (AXIS_LAST_ENABLE), + .AXIS_ID_ENABLE (AXIS_ID_ENABLE), + .AXIS_ID_WIDTH (AXIS_ID_WIDTH), + .AXIS_DEST_ENABLE (AXIS_DEST_ENABLE), + .AXIS_DEST_WIDTH (AXIS_DEST_WIDTH), + .AXIS_USER_ENABLE (AXIS_USER_ENABLE), + .AXIS_USER_WIDTH (AXIS_USER_WIDTH), + .LEN_WIDTH (LEN_WIDTH), + .TAG_WIDTH (TAG_WIDTH), + .ENABLE_SG (ENABLE_SG), + .ENABLE_UNALIGNED (ENABLE_UNALIGNED) + ) i_axi_dma ( + .clk (clk), + .rst (rst), + + .s_axis_read_desc_addr (dma_s_axis_read_desc_addr), + .s_axis_read_desc_len (dma_s_axis_read_desc_len), + .s_axis_read_desc_tag (dma_s_axis_read_desc_tag), + .s_axis_read_desc_id (dma_s_axis_read_desc_id), + .s_axis_read_desc_dest (dma_s_axis_read_desc_dest), + .s_axis_read_desc_user (dma_s_axis_read_desc_user), + .s_axis_read_desc_valid (dma_s_axis_read_desc_valid), + .s_axis_read_desc_ready (dma_s_axis_read_desc_ready), + + .m_axis_read_desc_status_tag (dma_m_axis_read_desc_status_tag), + .m_axis_read_desc_status_error (dma_m_axis_read_desc_status_error), + .m_axis_read_desc_status_valid (dma_m_axis_read_desc_status_valid), + + .m_axis_read_data_tdata (dma_m_axis_read_data_tdata), + .m_axis_read_data_tkeep (dma_m_axis_read_data_tkeep), + .m_axis_read_data_tvalid (dma_m_axis_read_data_tvalid), + .m_axis_read_data_tready (dma_m_axis_read_data_tready), + .m_axis_read_data_tlast (dma_m_axis_read_data_tlast), + .m_axis_read_data_tid (dma_m_axis_read_data_tid), + .m_axis_read_data_tdest (dma_m_axis_read_data_tdest), + .m_axis_read_data_tuser (dma_m_axis_read_data_tuser), + + .s_axis_write_desc_addr (dma_s_axis_write_desc_addr), + .s_axis_write_desc_len (dma_s_axis_write_desc_len), + .s_axis_write_desc_tag (dma_s_axis_write_desc_tag), + .s_axis_write_desc_valid (dma_s_axis_write_desc_valid), + .s_axis_write_desc_ready (dma_s_axis_write_desc_ready), + + .m_axis_write_desc_status_len (dma_m_axis_write_desc_status_len), + .m_axis_write_desc_status_tag (dma_m_axis_write_desc_status_tag), + .m_axis_write_desc_status_id (dma_m_axis_write_desc_status_id), + .m_axis_write_desc_status_dest (dma_m_axis_write_desc_status_dest), + .m_axis_write_desc_status_user (dma_m_axis_write_desc_status_user), + .m_axis_write_desc_status_error (dma_m_axis_write_desc_status_error), + .m_axis_write_desc_status_valid (dma_m_axis_write_desc_status_valid), + + .s_axis_write_data_tdata (dma_s_axis_write_data_tdata), + .s_axis_write_data_tkeep (dma_s_axis_write_data_tkeep), + .s_axis_write_data_tvalid (dma_s_axis_write_data_tvalid), + .s_axis_write_data_tready (dma_s_axis_write_data_tready), + .s_axis_write_data_tlast (dma_s_axis_write_data_tlast), + .s_axis_write_data_tid (dma_s_axis_write_data_tid), + .s_axis_write_data_tdest (dma_s_axis_write_data_tdest), + .s_axis_write_data_tuser (dma_s_axis_write_data_tuser), + + .m_axi_awid (dma_m_axi_awid), + .m_axi_awaddr (dma_m_axi_awaddr), + .m_axi_awlen (dma_m_axi_awlen), + .m_axi_awsize (dma_m_axi_awsize), + .m_axi_awburst (dma_m_axi_awburst), + .m_axi_awlock (dma_m_axi_awlock), + .m_axi_awcache (dma_m_axi_awcache), + .m_axi_awprot (dma_m_axi_awprot), + .m_axi_awvalid (dma_m_axi_awvalid), + .m_axi_awready (dma_m_axi_awready), + + .m_axi_wdata (dma_m_axi_wdata), + .m_axi_wstrb (dma_m_axi_wstrb), + .m_axi_wlast (dma_m_axi_wlast), + .m_axi_wvalid (dma_m_axi_wvalid), + .m_axi_wready (dma_m_axi_wready), + + .m_axi_bid (dma_m_axi_bid), + .m_axi_bresp (dma_m_axi_bresp), + .m_axi_bvalid (dma_m_axi_bvalid), + .m_axi_bready (dma_m_axi_bready), + + .m_axi_arid (dma_m_axi_arid), + .m_axi_araddr (dma_m_axi_araddr), + .m_axi_arlen (dma_m_axi_arlen), + .m_axi_arsize (dma_m_axi_arsize), + .m_axi_arburst (dma_m_axi_arburst), + .m_axi_arlock (dma_m_axi_arlock), + .m_axi_arcache (dma_m_axi_arcache), + .m_axi_arprot (dma_m_axi_arprot), + .m_axi_arvalid (dma_m_axi_arvalid), + .m_axi_arready (dma_m_axi_arready), + + .m_axi_rid (dma_m_axi_rid), + .m_axi_rdata (dma_m_axi_rdata), + .m_axi_rresp (dma_m_axi_rresp), + .m_axi_rlast (dma_m_axi_rlast), + .m_axi_rvalid (dma_m_axi_rvalid), + .m_axi_rready (dma_m_axi_rready), + + .read_enable (read_enable), + .write_enable (write_enable), + .write_abort (write_abort) + ); + + + + // local read descriptor interface -> DMA flat input + axis_if_to_flat #( + .DATA_W (AXI_ADDR_WIDTH + LEN_WIDTH + TAG_WIDTH), + .KEEP_W (AXIS_KEEP_WIDTH), + .ID_W (AXIS_ID_WIDTH), + .DEST_W (AXIS_DEST_WIDTH), + .USER_W (AXIS_USER_WIDTH) + ) i_read_desc_cmd_i2f ( + .s_axis (s_axis_read_desc), + .m_axis_tdata ({dma_s_axis_read_desc_addr, dma_s_axis_read_desc_len, dma_s_axis_read_desc_tag}), + .m_axis_tkeep (), + .m_axis_tstrb (), + .m_axis_tlast (), + .m_axis_tid (dma_s_axis_read_desc_id), + .m_axis_tdest (dma_s_axis_read_desc_dest), + .m_axis_tuser (dma_s_axis_read_desc_user), + .m_axis_tvalid (dma_s_axis_read_desc_valid), + .m_axis_tready (dma_s_axis_read_desc_ready) + ); + + // DMA read descriptor status flat output -> local status interface + axis_flat_to_if #( + .DATA_W (TAG_WIDTH + 4), + .KEEP_W (AXIS_KEEP_WIDTH), + .ID_W (AXIS_ID_WIDTH), + .DEST_W (AXIS_DEST_WIDTH), + .USER_W (AXIS_USER_WIDTH) + ) i_read_desc_status_f2i( + .s_axis_tdata ({dma_m_axis_read_desc_status_tag, dma_m_axis_read_desc_status_error}), + .s_axis_tkeep (), + .s_axis_tstrb (), + .s_axis_tlast (), + .s_axis_tid (), + .s_axis_tdest (), + .s_axis_tuser (), + .s_axis_tvalid (dma_m_axis_read_desc_status_valid), + .s_axis_tready (), + .m_axis (m_axis_read_desc_status) + ); + + // local write descriptor interface -> DMA flat input + axis_if_to_flat #( + .DATA_W (AXI_ADDR_WIDTH + LEN_WIDTH + TAG_WIDTH), + .KEEP_W (AXIS_KEEP_WIDTH), + .ID_W (AXIS_ID_WIDTH), + .DEST_W (AXIS_DEST_WIDTH), + .USER_W (AXIS_USER_WIDTH) + ) i_write_desc_cmd_i2f ( + .s_axis (s_axis_write_desc), + .m_axis_tdata ({dma_s_axis_write_desc_addr, dma_s_axis_write_desc_len, dma_s_axis_write_desc_tag}), + .m_axis_tkeep (), + .m_axis_tstrb (), + .m_axis_tlast (), + .m_axis_tid (), + .m_axis_tdest (), + .m_axis_tuser (), + .m_axis_tvalid (dma_s_axis_write_desc_valid), + .m_axis_tready (dma_s_axis_write_desc_ready) + ); + + + // DMA write descriptor status flat output -> local status interface + axis_flat_to_if #( + .DATA_W (TAG_WIDTH + LEN_WIDTH + 4), + .KEEP_W (AXIS_KEEP_WIDTH), + .ID_W (AXIS_ID_WIDTH), + .DEST_W (AXIS_DEST_WIDTH), + .USER_W (AXIS_USER_WIDTH) + ) i_write_desc_status_f2i( + .s_axis_tdata ({dma_m_axis_write_desc_status_len, dma_m_axis_write_desc_status_tag, dma_m_axis_write_desc_status_error}), + .s_axis_tkeep (), + .s_axis_tstrb (), + .s_axis_tlast (), + .s_axis_tid (dma_m_axis_write_desc_status_id), + .s_axis_tdest (dma_m_axis_write_desc_status_dest), + .s_axis_tuser (dma_m_axis_write_desc_status_user), + .s_axis_tvalid (dma_m_axis_write_desc_status_valid), + .s_axis_tready (), + .m_axis (m_axis_write_desc_status) + ); + + // DMA read data flat output -> local axis_if.master + axis_flat_to_if #( + .DATA_W (AXIS_DATA_WIDTH), + .KEEP_W (AXIS_KEEP_WIDTH), + .ID_W (AXIS_ID_WIDTH), + .DEST_W (AXIS_DEST_WIDTH), + .USER_W (AXIS_USER_WIDTH) + ) u_m_axis_read_data_flat_to_if ( + .s_axis_tdata (dma_m_axis_read_data_tdata), + .s_axis_tkeep (dma_m_axis_read_data_tkeep), + .s_axis_tstrb (dma_m_axis_read_data_tkeep), // axi_dma has no tstrb; mirror tkeep + .s_axis_tlast (dma_m_axis_read_data_tlast), + .s_axis_tid (dma_m_axis_read_data_tid), + .s_axis_tdest (dma_m_axis_read_data_tdest), + .s_axis_tuser (dma_m_axis_read_data_tuser), + .s_axis_tvalid (dma_m_axis_read_data_tvalid), + .s_axis_tready (dma_m_axis_read_data_tready), + .m_axis (m_axis_read_data) + ); + + // local axis_if.slave -> DMA write data flat input + axis_if_to_flat #( + .DATA_W (AXIS_DATA_WIDTH), + .KEEP_W (AXIS_KEEP_WIDTH), + .ID_W (AXIS_ID_WIDTH), + .DEST_W (AXIS_DEST_WIDTH), + .USER_W (AXIS_USER_WIDTH) + ) u_s_axis_write_data_if_to_flat ( + .s_axis (s_axis_write_data), + .m_axis_tdata (dma_s_axis_write_data_tdata), + .m_axis_tkeep (dma_s_axis_write_data_tkeep), + .m_axis_tstrb (unused_s_axis_write_data_tstrb), + .m_axis_tlast (dma_s_axis_write_data_tlast), + .m_axis_tid (dma_s_axis_write_data_tid), + .m_axis_tdest (dma_s_axis_write_data_tdest), + .m_axis_tuser (dma_s_axis_write_data_tuser), + .m_axis_tvalid(dma_s_axis_write_data_tvalid), + .m_axis_tready(dma_s_axis_write_data_tready) + ); + + // DMA AXI master flat output -> local axi4_if.master + axi4_flat_to_if #( + .ADDR_W (AXI_ADDR_WIDTH), + .DATA_W (AXI_DATA_WIDTH), + .ID_W (AXI_ID_WIDTH), + .USER_W (AXI_USER_WIDTH) + ) u_m_axi_flat_to_if ( + .s_axi_awid (dma_m_axi_awid), + .s_axi_awaddr (dma_m_axi_awaddr), + .s_axi_awlen (dma_m_axi_awlen), + .s_axi_awsize (dma_m_axi_awsize), + .s_axi_awburst (dma_m_axi_awburst), + .s_axi_awlock (dma_m_axi_awlock), + .s_axi_awcache (dma_m_axi_awcache), + .s_axi_awprot (dma_m_axi_awprot), + .s_axi_awqos (4'd0), + .s_axi_awregion (4'd0), + .s_axi_awuser ({AXI_USER_WIDTH{1'b0}}), + .s_axi_awvalid (dma_m_axi_awvalid), + .s_axi_awready (dma_m_axi_awready), + + .s_axi_wdata (dma_m_axi_wdata), + .s_axi_wstrb (dma_m_axi_wstrb), + .s_axi_wlast (dma_m_axi_wlast), + .s_axi_wuser ({AXI_USER_WIDTH{1'b0}}), + .s_axi_wvalid (dma_m_axi_wvalid), + .s_axi_wready (dma_m_axi_wready), + + .s_axi_bid (dma_m_axi_bid), + .s_axi_bresp (dma_m_axi_bresp), + .s_axi_buser (unused_m_axi_buser), + .s_axi_bvalid (dma_m_axi_bvalid), + .s_axi_bready (dma_m_axi_bready), + + .s_axi_arid (dma_m_axi_arid), + .s_axi_araddr (dma_m_axi_araddr), + .s_axi_arlen (dma_m_axi_arlen), + .s_axi_arsize (dma_m_axi_arsize), + .s_axi_arburst (dma_m_axi_arburst), + .s_axi_arlock (dma_m_axi_arlock), + .s_axi_arcache (dma_m_axi_arcache), + .s_axi_arprot (dma_m_axi_arprot), + .s_axi_arqos (4'd0), + .s_axi_arregion (4'd0), + .s_axi_aruser ({AXI_USER_WIDTH{1'b0}}), + .s_axi_arvalid (dma_m_axi_arvalid), + .s_axi_arready (dma_m_axi_arready), + + .s_axi_rid (dma_m_axi_rid), + .s_axi_rdata (dma_m_axi_rdata), + .s_axi_rresp (dma_m_axi_rresp), + .s_axi_rlast (dma_m_axi_rlast), + .s_axi_ruser (unused_m_axi_ruser), + .s_axi_rvalid (dma_m_axi_rvalid), + .s_axi_rready (dma_m_axi_rready), + + .m_axi (m_axi) + ); + +endmodule : axi_dma_wrapper + +`default_nettype wire diff --git a/external/external/rtl_libs/axi/rtl/axi_if.sv b/external/external/rtl_libs/axi/rtl/axi_if.sv new file mode 100644 index 0000000..af8cb7e --- /dev/null +++ b/external/external/rtl_libs/axi/rtl/axi_if.sv @@ -0,0 +1,43 @@ +interface axi4_if #( + parameter int unsigned ADDR_W = 32, + parameter int unsigned DATA_W = 32, + parameter int unsigned ID_W = 4, + parameter int unsigned USER_W = 1 +)( + input logic aclk, + input logic aresetn +); + import axi_pkg::*; + typedef logic [ADDR_W-1:0] addr_t; + typedef logic [DATA_W-1:0] data_t; + typedef logic [DATA_W/8-1:0] strb_t; + typedef logic [ID_W-1:0] id_t; + typedef logic [USER_W-1:0] user_t; + `AXI4_TYPEDEF_ALL(axi, addr_t, data_t, strb_t, id_t, user_t); + axi_req_t req; + axi_resp_t resp; + modport master (input aclk, aresetn, output req, input resp); + modport slave (input aclk, aresetn, input req, output resp); + modport monitor(input aclk, aresetn, input req, input resp); +endinterface : axi4_if + +interface axi4l_if #( + parameter int unsigned ADDR_W = 32, + parameter int unsigned DATA_W = 32, + parameter int unsigned USER_W = 1 +)( + input logic aclk, + input logic aresetn +); + import axi_pkg::*; + typedef logic [ADDR_W-1:0] addr_t; + typedef logic [DATA_W-1:0] data_t; + typedef logic [DATA_W/8-1:0] strb_t; + typedef logic [USER_W-1:0] user_t; + `AXI4L_TYPEDEF_ALL(axil, addr_t, data_t, strb_t, user_t); + axil_req_t req; + axil_resp_t resp; + modport master (input aclk, aresetn, output req, input resp); + modport slave (input aclk, aresetn, input req, output resp); + modport monitor(input aclk, aresetn, input req, input resp); +endinterface : axi4l_if diff --git a/external/external/rtl_libs/axi/rtl/axi_pkg.sv b/external/external/rtl_libs/axi/rtl/axi_pkg.sv new file mode 100644 index 0000000..26757ca --- /dev/null +++ b/external/external/rtl_libs/axi/rtl/axi_pkg.sv @@ -0,0 +1,140 @@ +package axi_pkg; + + typedef enum logic [1:0] { + AXI_BURST_FIXED = 2'b00, + AXI_BURST_INCR = 2'b01, + AXI_BURST_WRAP = 2'b10 + } axi_burst_t; + + 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_t; + + function automatic logic [2:0] axi_size_from_bytes(input int unsigned nbytes); + case (nbytes) + 1 : return 3'd0; + 2 : return 3'd1; + 4 : return 3'd2; + 8 : return 3'd3; + 16 : return 3'd4; + 32 : return 3'd5; + 64 : return 3'd6; + 128 : return 3'd7; + default: return 3'd0; + endcase + endfunction + +endpackage : axi_pkg + +`define AXI4_TYPEDEF_ALL(__name, __addr_t, __data_t, __strb_t, __id_t, __user_t) \ + typedef struct packed { \ + __id_t id; \ + __addr_t addr; \ + logic [7:0] len; \ + logic [2:0] size; \ + axi_pkg::axi_burst_t burst; \ + logic lock; \ + logic [3:0] cache; \ + logic [2:0] prot; \ + logic [3:0] qos; \ + logic [3:0] region; \ + __user_t user; \ + logic valid; \ + } __name``_aw_chan_t; \ + typedef struct packed { \ + __data_t data; \ + __strb_t strb; \ + logic last; \ + __user_t user; \ + logic valid; \ + } __name``_w_chan_t; \ + typedef struct packed { \ + __id_t id; \ + axi_pkg::axi_resp_t resp; \ + __user_t user; \ + logic valid; \ + } __name``_b_chan_t; \ + typedef struct packed { \ + __id_t id; \ + __addr_t addr; \ + logic [7:0] len; \ + logic [2:0] size; \ + axi_pkg::axi_burst_t burst; \ + logic lock; \ + logic [3:0] cache; \ + logic [2:0] prot; \ + logic [3:0] qos; \ + logic [3:0] region; \ + __user_t user; \ + logic valid; \ + } __name``_ar_chan_t; \ + typedef struct packed { \ + __id_t id; \ + __data_t data; \ + axi_pkg::axi_resp_t resp; \ + logic last; \ + __user_t user; \ + logic valid; \ + } __name``_r_chan_t; \ + typedef struct packed { \ + __name``_aw_chan_t aw; \ + __name``_w_chan_t w; \ + logic b_ready; \ + __name``_ar_chan_t ar; \ + logic r_ready; \ + } __name``_req_t; \ + typedef struct packed { \ + logic aw_ready; \ + logic w_ready; \ + __name``_b_chan_t b; \ + logic ar_ready; \ + __name``_r_chan_t r; \ + } __name``_resp_t; + +`define AXI4L_TYPEDEF_ALL(__name, __addr_t, __data_t, __strb_t, __user_t) \ + typedef struct packed { \ + __addr_t addr; \ + logic [2:0] prot; \ + __user_t user; \ + logic valid; \ + } __name``_aw_chan_t; \ + typedef struct packed { \ + __data_t data; \ + __strb_t strb; \ + __user_t user; \ + logic valid; \ + } __name``_w_chan_t; \ + typedef struct packed { \ + axi_pkg::axi_resp_t resp; \ + __user_t user; \ + logic valid; \ + } __name``_b_chan_t; \ + typedef struct packed { \ + __addr_t addr; \ + logic [2:0] prot; \ + __user_t user; \ + logic valid; \ + } __name``_ar_chan_t; \ + typedef struct packed { \ + __data_t data; \ + axi_pkg::axi_resp_t resp; \ + __user_t user; \ + logic valid; \ + } __name``_r_chan_t; \ + typedef struct packed { \ + __name``_aw_chan_t aw; \ + __name``_w_chan_t w; \ + logic b_ready; \ + __name``_ar_chan_t ar; \ + logic r_ready; \ + } __name``_req_t; \ + typedef struct packed { \ + logic aw_ready; \ + logic w_ready; \ + __name``_b_chan_t b; \ + logic ar_ready; \ + __name``_r_chan_t r; \ + } __name``_resp_t; diff --git a/external/external/rtl_libs/axi/rtl/axi_ram_wrapper.sv b/external/external/rtl_libs/axi/rtl/axi_ram_wrapper.sv new file mode 100644 index 0000000..8e5e459 --- /dev/null +++ b/external/external/rtl_libs/axi/rtl/axi_ram_wrapper.sv @@ -0,0 +1,146 @@ +module axi_ram_wrapper #( + parameter DATA_WIDTH = 32, + parameter ADDR_WIDTH = 16, + parameter ID_WIDTH = 8, + parameter PIPELINE_OUTPUT = 0 +)( + input wire clk, + input wire rst, + + axi4_if.slaver s_axi +); + + wire [ID_WIDTH-1:0] ram_s_axi_awid; + wire [ADDR_WIDTH-1:0] ram_s_axi_awaddr; + wire [7:0] ram_s_axi_awlen; + wire [2:0] ram_s_axi_awsize; + wire [1:0] ram_s_axi_awburst; + wire ram_s_axi_awlock; + wire [3:0] ram_s_axi_awcache; + wire [2:0] ram_s_axi_awprot; + wire ram_s_axi_awvalid; + wire ram_s_axi_awready; + wire [DATA_WIDTH-1:0] ram_s_axi_wdata; + wire [STRB_WIDTH-1:0] ram_s_axi_wstrb; + wire ram_s_axi_wlast; + wire ram_s_axi_wvalid; + wire ram_s_axi_wready; + wire [ID_WIDTH-1:0] ram_s_axi_bid; + wire [1:0] ram_s_axi_bresp; + wire ram_s_axi_bvalid; + wire ram_s_axi_bready; + wire [ID_WIDTH-1:0] ram_s_axi_arid; + wire [ADDR_WIDTH-1:0] ram_s_axi_araddr; + wire [7:0] ram_s_axi_arlen; + wire [2:0] ram_s_axi_arsize; + wire [1:0] ram_s_axi_arburst; + wire ram_s_axi_arlock; + wire [3:0] ram_s_axi_arcache; + wire [2:0] ram_s_axi_arprot; + wire ram_s_axi_arvalid; + wire ram_s_axi_arready; + wire [ID_WIDTH-1:0] ram_s_axi_rid; + wire [DATA_WIDTH-1:0] ram_s_axi_rdata; + wire [1:0] ram_s_axi_rresp; + wire ram_s_axi_rlast; + wire ram_s_axi_rvalid; + wire ram_s_axi_rready; + + axi4_if_to_flat #( + .ADDR_W (ADDR_WIDTH), + .DATA_W (DATA_WIDTH) + ) i_axi4_if_to_flat ( + .s_axi (s_axi), + .m_axi_awid (ram_s_axi_awid), + .m_axi_awaddr (ram_s_axi_awaddr), + .m_axi_awlen (ram_s_axi_awlen), + .m_axi_awsize (ram_s_axi_awsize), + .m_axi_awburst (ram_s_axi_awburst), + .m_axi_awlock (ram_s_axi_awlock), + .m_axi_awcache (ram_s_axi_awcache), + .m_axi_awprot (ram_s_axi_awprot), + .m_axi_awqos (ram_s_axi_awqos), + .m_axi_awregion (ram_s_axi_awregion), + .m_axi_awuser (ram_s_axi_awuser), + .m_axi_awvalid (ram_s_axi_awvalid), + .m_axi_awready (ram_s_axi_awready), + .m_axi_wdata (ram_s_axi_wdata), + .m_axi_wstrb (ram_s_axi_wstrb), + .m_axi_wlast (ram_s_axi_wlast), + .m_axi_wuser (ram_s_axi_wuser), + .m_axi_wvalid (ram_s_axi_wvalid), + .m_axi_wready (ram_s_axi_wready), + .m_axi_bid (ram_s_axi_bid), + .m_axi_bresp (ram_s_axi_bresp), + .m_axi_buser (ram_s_axi_buser), + .m_axi_bvalid (ram_s_axi_bvalid), + .m_axi_bready (ram_s_axi_bready), + .m_axi_arid (ram_s_axi_arid), + .m_axi_araddr (ram_s_axi_araddr), + .m_axi_arlen (ram_s_axi_arlen), + .m_axi_arsize (ram_s_axi_arsize), + .m_axi_arburst (ram_s_axi_arburst), + .m_axi_arlock (ram_s_axi_arlock), + .m_axi_arcache (ram_s_axi_arcache), + .m_axi_arprot (ram_s_axi_arprot), + .m_axi_arqos (ram_s_axi_arqos), + .m_axi_arregion (ram_s_axi_arregion), + .m_axi_aruser (ram_s_axi_aruser), + .m_axi_arvalid (ram_s_axi_arvalid), + .m_axi_arready (ram_s_axi_arready), + .m_axi_rid (ram_s_axi_rid), + .m_axi_rdata (ram_s_axi_rdata), + .m_axi_rresp (ram_s_axi_rresp), + .m_axi_rlast (ram_s_axi_rlast), + .m_axi_ruser (ram_s_axi_ruser), + .m_axi_rvalid (ram_s_axi_rvalid), + .m_axi_rready (ram_s_axi_rready) + ); + + axi_ram # + ( + .DATA_WIDTH (DATA_WIDTH), + .ADDR_WIDTH (ADDR_WIDTH), + .ID_WIDTH (ID_WIDTH), + .PIPELINE_OUTPUT (PIPELINE_OUTPUT) + ) i_axi_ram ( + .clk (clk), + .rst (rst), + .s_axi_awid (ram_s_axi_awid), + .s_axi_awaddr (ram_s_axi_awaddr), + .s_axi_awlen (ram_s_axi_awlen), + .s_axi_awsize (ram_s_axi_awsize), + .s_axi_awburst (ram_s_axi_awburst), + .s_axi_awlock (ram_s_axi_awlock), + .s_axi_awcache (ram_s_axi_awcache), + .s_axi_awprot (ram_s_axi_awprot), + .s_axi_awvalid (ram_s_axi_awvalid), + .s_axi_awready (ram_s_axi_awready), + .s_axi_wdata (ram_s_axi_wdata), + .s_axi_wstrb (ram_s_axi_wstrb), + .s_axi_wlast (ram_s_axi_wlast), + .s_axi_wvalid (ram_s_axi_wvalid), + .s_axi_wready (ram_s_axi_wready), + .s_axi_bid (ram_s_axi_bid), + .s_axi_bresp (ram_s_axi_bresp), + .s_axi_bvalid (ram_s_axi_bvalid), + .s_axi_bready (ram_s_axi_bready), + .s_axi_arid (ram_s_axi_arid), + .s_axi_araddr (ram_s_axi_araddr), + .s_axi_arlen (ram_s_axi_arlen), + .s_axi_arsize (ram_s_axi_arsize), + .s_axi_arburst (ram_s_axi_arburst), + .s_axi_arlock (ram_s_axi_arlock), + .s_axi_arcache (ram_s_axi_arcache), + .s_axi_arprot (ram_s_axi_arprot), + .s_axi_arvalid (ram_s_axi_arvalid), + .s_axi_arready (ram_s_axi_arready), + .s_axi_rid (ram_s_axi_rid), + .s_axi_rdata (ram_s_axi_rdata), + .s_axi_rresp (ram_s_axi_rresp), + .s_axi_rlast (ram_s_axi_rlast), + .s_axi_rvalid (ram_s_axi_rvalid), + .s_axi_rready (ram_s_axi_rready) + ); + +endmodule \ No newline at end of file diff --git a/external/external/rtl_libs/axi/rtl/axil_cdc_wrapper.sv b/external/external/rtl_libs/axi/rtl/axil_cdc_wrapper.sv new file mode 100644 index 0000000..e6012c9 --- /dev/null +++ b/external/external/rtl_libs/axi/rtl/axil_cdc_wrapper.sv @@ -0,0 +1,165 @@ +module axil_cdc_wrapper #( + parameter int ADDR_WIDTH = 32, + parameter int DATA_WIDTH = 32 +)( + input wire s_clk, + input wire s_rst, + axi4l_if.slave s_axi, + + input wire m_clk, + input wire m_rst, + axi4l_if.master m_axi +); + + localparam int STRB_WIDTH = (DATA_WIDTH/8); + wire [ADDR_WIDTH-1:0] cdc_s_axil_awaddr; + wire [2:0] cdc_s_axil_awprot; + wire cdc_s_axil_awvalid; + wire cdc_s_axil_awready; + wire [DATA_WIDTH-1:0] cdc_s_axil_wdata; + wire [STRB_WIDTH-1:0] cdc_s_axil_wstrb; + wire cdc_s_axil_wvalid; + wire cdc_s_axil_wready; + wire [1:0] cdc_s_axil_bresp; + wire cdc_s_axil_bvalid; + wire cdc_s_axil_bready; + wire [ADDR_WIDTH-1:0] cdc_s_axil_araddr; + wire [2:0] cdc_s_axil_arprot; + wire cdc_s_axil_arvalid; + wire cdc_s_axil_arready; + wire [DATA_WIDTH-1:0] cdc_s_axil_rdata; + wire [1:0] cdc_s_axil_rresp; + wire cdc_s_axil_rvalid; + wire cdc_s_axil_rready; + wire [ADDR_WIDTH-1:0] cdc_m_axil_awaddr; + wire [2:0] cdc_m_axil_awprot; + wire cdc_m_axil_awvalid; + wire cdc_m_axil_awready; + wire [DATA_WIDTH-1:0] cdc_m_axil_wdata; + wire [STRB_WIDTH-1:0] cdc_m_axil_wstrb; + wire cdc_m_axil_wvalid; + wire cdc_m_axil_wready; + wire [1:0] cdc_m_axil_bresp; + wire cdc_m_axil_bvalid; + wire cdc_m_axil_bready; + wire [ADDR_WIDTH-1:0] cdc_m_axil_araddr; + wire [2:0] cdc_m_axil_arprot; + wire cdc_m_axil_arvalid; + wire cdc_m_axil_arready; + wire [DATA_WIDTH-1:0] cdc_m_axil_rdata; + wire [1:0] cdc_m_axil_rresp; + wire cdc_m_axil_rvalid; + wire cdc_m_axil_rready; + + axi4l_if_to_flat #( + .ADDR_W (ADDR_WIDTH), + .DATA_W (DATA_WIDTH) + ) i_axi4l_if_to_flat ( + .s_axil (s_axi), + .m_axil_awaddr (cdc_m_axil_awaddr), + .m_axil_awprot (cdc_m_axil_awprot), + .m_axil_awuser (cdc_m_axil_awuser), + .m_axil_awvalid (cdc_m_axil_awvalid), + .m_axil_awready (cdc_m_axil_awready), + .m_axil_wdata (cdc_m_axil_wdata), + .m_axil_wstrb (cdc_m_axil_wstrb), + .m_axil_wuser (cdc_m_axil_wuser), + .m_axil_wvalid (cdc_m_axil_wvalid), + .m_axil_wready (cdc_m_axil_wready), + .m_axil_bresp (cdc_m_axil_bresp), + .m_axil_buser (cdc_m_axil_buser), + .m_axil_bvalid (cdc_m_axil_bvalid), + .m_axil_bready (cdc_m_axil_bready), + .m_axil_araddr (cdc_m_axil_araddr), + .m_axil_arprot (cdc_m_axil_arprot), + .m_axil_aruser (cdc_m_axil_aruser), + .m_axil_arvalid (cdc_m_axil_arvalid), + .m_axil_arready (cdc_m_axil_arready), + .m_axil_rdata (cdc_m_axil_rdata), + .m_axil_rresp (cdc_m_axil_rresp), + .m_axil_ruser (cdc_m_axil_ruser), + .m_axil_rvalid (cdc_m_axil_rvalid), + .m_axil_rready (cdc_m_axil_rready) + ); + + axil_cdc #( + .ADDR_WIDTH (ADDR_WIDTH), + .DATA_WIDTH (DATA_WIDTH) + ) i_axil_cdc ( + .s_clk (s_clk), + .s_rst (s_rst), + .s_axil_awaddr (cdc_m_axil_awaddr), + .s_axil_awprot (cdc_m_axil_awprot), + .s_axil_awvalid (cdc_m_axil_awvalid), + .s_axil_awready (cdc_m_axil_awready), + .s_axil_wdata (cdc_m_axil_wdata), + .s_axil_wstrb (cdc_m_axil_wstrb), + .s_axil_wvalid (cdc_m_axil_wvalid), + .s_axil_wready (cdc_m_axil_wready), + .s_axil_bresp (cdc_m_axil_bresp), + .s_axil_bvalid (cdc_m_axil_bvalid), + .s_axil_bready (cdc_m_axil_bready), + .s_axil_araddr (cdc_m_axil_araddr), + .s_axil_arprot (cdc_m_axil_arprot), + .s_axil_arvalid (cdc_m_axil_arvalid), + .s_axil_arready (cdc_m_axil_arready), + .s_axil_rdata (cdc_m_axil_rdata), + .s_axil_rresp (cdc_m_axil_rresp), + .s_axil_rvalid (cdc_m_axil_rvalid), + .s_axil_rready (cdc_m_axil_rready), + + .m_clk (m_clk), + .m_rst (m_rst), + .m_axil_awaddr (cdc_s_axil_awaddr), + .m_axil_awprot (cdc_s_axil_awprot), + .m_axil_awvalid (cdc_s_axil_awvalid), + .m_axil_awready (cdc_s_axil_awready), + .m_axil_wdata (cdc_s_axil_wdata), + .m_axil_wstrb (cdc_s_axil_wstrb), + .m_axil_wvalid (cdc_s_axil_wvalid), + .m_axil_wready (cdc_s_axil_wready), + .m_axil_bresp (cdc_s_axil_bresp), + .m_axil_bvalid (cdc_s_axil_bvalid), + .m_axil_bready (cdc_s_axil_bready), + .m_axil_araddr (cdc_s_axil_araddr), + .m_axil_arprot (cdc_s_axil_arprot), + .m_axil_arvalid (cdc_s_axil_arvalid), + .m_axil_arready (cdc_s_axil_arready), + .m_axil_rdata (cdc_s_axil_rdata), + .m_axil_rresp (cdc_s_axil_rresp), + .m_axil_rvalid (cdc_s_axil_rvalid), + .m_axil_rready (cdc_s_axil_rready) + ); + + axi4l_flat_to_if #( + .ADDR_W (ADDR_WIDTH), + .DATA_W (DATA_WIDTH) + ) i_axi4l_flat_to_if ( + .s_axil_awaddr (cdc_s_axil_awaddr), + .s_axil_awprot (cdc_s_axil_awprot), + .s_axil_awuser (cdc_s_axil_awuser), + .s_axil_awvalid (cdc_s_axil_awvalid), + .s_axil_awready (cdc_s_axil_awready), + .s_axil_wdata (cdc_s_axil_wdata), + .s_axil_wstrb (cdc_s_axil_wstrb), + .s_axil_wuser (cdc_s_axil_wuser), + .s_axil_wvalid (cdc_s_axil_wvalid), + .s_axil_wready (cdc_s_axil_wready), + .s_axil_bresp (cdc_s_axil_bresp), + .s_axil_buser (cdc_s_axil_buser), + .s_axil_bvalid (cdc_s_axil_bvalid), + .s_axil_bready (cdc_s_axil_bready), + .s_axil_araddr (cdc_s_axil_araddr), + .s_axil_arprot (cdc_s_axil_arprot), + .s_axil_aruser (cdc_s_axil_aruser), + .s_axil_arvalid (cdc_s_axil_arvalid), + .s_axil_arready (cdc_s_axil_arready), + .s_axil_rdata (cdc_s_axil_rdata), + .s_axil_rresp (cdc_s_axil_rresp), + .s_axil_ruser (cdc_s_axil_ruser), + .s_axil_rvalid (cdc_s_axil_rvalid), + .s_axil_rready (cdc_s_axil_rready), + .m_axil (m_axil) + ); + +endmodule \ No newline at end of file diff --git a/external/external/rtl_libs/axi/rtl/axis_flat_to_if.sv b/external/external/rtl_libs/axi/rtl/axis_flat_to_if.sv new file mode 100644 index 0000000..569e0e2 --- /dev/null +++ b/external/external/rtl_libs/axi/rtl/axis_flat_to_if.sv @@ -0,0 +1,30 @@ +module axis_flat_to_if #( + parameter int unsigned DATA_W = 64, + parameter int unsigned KEEP_W = DATA_W / 8, + parameter int unsigned ID_W = 8, + parameter int unsigned DEST_W = 8, + parameter int unsigned USER_W = 1 +)( + input logic [DATA_W-1:0] s_axis_tdata, + input logic [KEEP_W-1:0] s_axis_tkeep, + input logic [KEEP_W-1:0] s_axis_tstrb, + input logic s_axis_tlast, + input logic [ID_W-1:0] s_axis_tid, + input logic [DEST_W-1:0] s_axis_tdest, + input logic [USER_W-1:0] s_axis_tuser, + input logic s_axis_tvalid, + output logic s_axis_tready, + + axis_if.master m_axis +); + assign m_axis.req.t.data = s_axis_tdata; + assign m_axis.req.t.keep = s_axis_tkeep; + assign m_axis.req.t.strb = s_axis_tstrb; + assign m_axis.req.t.last = s_axis_tlast; + assign m_axis.req.t.id = s_axis_tid; + assign m_axis.req.t.dest = s_axis_tdest; + assign m_axis.req.t.user = s_axis_tuser; + assign m_axis.req.t.valid = s_axis_tvalid; + + assign s_axis_tready = m_axis.resp.ready; +endmodule : axis_flat_to_if diff --git a/external/external/rtl_libs/axi/rtl/axis_if.sv b/external/external/rtl_libs/axi/rtl/axis_if.sv new file mode 100644 index 0000000..a498b8d --- /dev/null +++ b/external/external/rtl_libs/axi/rtl/axis_if.sv @@ -0,0 +1,47 @@ +`define AXIS_TYPEDEF_ALL(__name, __data_t, __keep_t, __strb_t, __id_t, __dest_t, __user_t) \ + typedef struct packed { \ + __data_t data; \ + __keep_t keep; \ + __strb_t strb; \ + logic last; \ + __id_t id; \ + __dest_t dest; \ + __user_t user; \ + logic valid; \ + } __name``_chan_t; \ + typedef struct packed { \ + __name``_chan_t t; \ + } __name``_req_t; \ + typedef struct packed { \ + logic ready; \ + } __name``_resp_t; + + + +interface axis_if #( + parameter int unsigned DATA_W = 64, + parameter int unsigned KEEP_W = DATA_W / 8, + parameter int unsigned ID_W = 8, + parameter int unsigned DEST_W = 8, + parameter int unsigned USER_W = 1 +)( + input logic aclk, + input logic aresetn +); + typedef logic [DATA_W-1:0] data_t; + typedef logic [KEEP_W-1:0] keep_t; + typedef logic [KEEP_W-1:0] strb_t; + typedef logic [ID_W-1:0] id_t; + typedef logic [DEST_W-1:0] dest_t; + typedef logic [USER_W-1:0] user_t; + + `AXIS_TYPEDEF_ALL(axis, data_t, keep_t, strb_t, id_t, dest_t, user_t) + + axis_req_t req; + axis_resp_t resp; + + modport master (input aclk, aresetn, output req, input resp); + modport slave (input aclk, aresetn, input req, output resp); + modport monitor (input aclk, aresetn, input req, input resp); +endinterface : axis_if + diff --git a/external/external/rtl_libs/axi/rtl/axis_if_to_flat.sv b/external/external/rtl_libs/axi/rtl/axis_if_to_flat.sv new file mode 100644 index 0000000..e5ab45e --- /dev/null +++ b/external/external/rtl_libs/axi/rtl/axis_if_to_flat.sv @@ -0,0 +1,30 @@ +module axis_if_to_flat #( + parameter int unsigned DATA_W = 64, + parameter int unsigned KEEP_W = DATA_W / 8, + parameter int unsigned ID_W = 8, + parameter int unsigned DEST_W = 8, + parameter int unsigned USER_W = 1 +)( + axis_if.slave s_axis, + + output logic [DATA_W-1:0] m_axis_tdata, + output logic [KEEP_W-1:0] m_axis_tkeep, + output logic [KEEP_W-1:0] m_axis_tstrb, + output logic m_axis_tlast, + output logic [ID_W-1:0] m_axis_tid, + output logic [DEST_W-1:0] m_axis_tdest, + output logic [USER_W-1:0] m_axis_tuser, + output logic m_axis_tvalid, + input logic m_axis_tready +); + assign m_axis_tdata = s_axis.req.t.data; + assign m_axis_tkeep = s_axis.req.t.keep; + assign m_axis_tstrb = s_axis.req.t.strb; + assign m_axis_tlast = s_axis.req.t.last; + assign m_axis_tid = s_axis.req.t.id; + assign m_axis_tdest = s_axis.req.t.dest; + assign m_axis_tuser = s_axis.req.t.user; + assign m_axis_tvalid = s_axis.req.t.valid; + + assign s_axis.resp.ready = m_axis_tready; +endmodule : axis_if_to_flat diff --git a/external/external/rtl_libs/axi/tb/axi_dma_axis_compat/Makefile b/external/external/rtl_libs/axi/tb/axi_dma_axis_compat/Makefile new file mode 100644 index 0000000..3bc4e57 --- /dev/null +++ b/external/external/rtl_libs/axi/tb/axi_dma_axis_compat/Makefile @@ -0,0 +1,84 @@ +# Simple cocotb makefile for tb_axi_dma_axis_compat + + +TOPLEVEL_LANG = verilog +SIM ?= verilator + +PWD := $(shell pwd) +PROJECT_ROOT ?= $(abspath $(PWD)/../../..) + +AXI_IF_RTL_DIR ?= $(PROJECT_ROOT)/axi/rtl +FORENCICH_AXI_RTL_DIR ?= $(PROJECT_ROOT)/external/verilog-axi/rtl +TB_DIR ?= $(PWD) + +TOPLEVEL = tb_axi_dma_axis_compat +MODULE = test_axi_dma_axis_compat + +export PYTHONPATH := $(TB_DIR):$(PYTHONPATH) + + +AXI_DATA_WIDTH ?= 32 +AXI_ADDR_WIDTH ?= 16 +AXI_ID_WIDTH ?= 8 +AXI_USER_WIDTH ?= 1 +AXI_MAX_BURST_LEN ?= 16 +ENABLE_UNALIGNED ?= 0 + +AXI_STRB_WIDTH := $(shell expr $(AXI_DATA_WIDTH) / 8) +AXIS_DATA_WIDTH ?= $(AXI_DATA_WIDTH) +AXIS_KEEP_WIDTH := $(shell expr $(AXIS_DATA_WIDTH) / 8) +AXIS_KEEP_ENABLE := $(shell [ $(AXIS_DATA_WIDTH) -gt 8 ] && echo 1 || echo 0) + +VERILOG_SOURCES += $(AXI_IF_RTL_DIR)/axi_pkg.sv +VERILOG_SOURCES += $(AXI_IF_RTL_DIR)/axi_if.sv +VERILOG_SOURCES += $(AXI_IF_RTL_DIR)/axis_if.sv +VERILOG_SOURCES += $(AXI_IF_RTL_DIR)/axi4_flat_to_if.sv +VERILOG_SOURCES += $(AXI_IF_RTL_DIR)/axi4_if_to_flat.sv +VERILOG_SOURCES += $(AXI_IF_RTL_DIR)/axis_flat_to_if.sv +VERILOG_SOURCES += $(AXI_IF_RTL_DIR)/axis_if_to_flat.sv + +VERILOG_SOURCES += $(AXI_IF_RTL_DIR)/axi_dma_desc_if.sv + +VERILOG_SOURCES += $(FORENCICH_AXI_RTL_DIR)/axi_dma.v +VERILOG_SOURCES += $(FORENCICH_AXI_RTL_DIR)/axi_dma_rd.v +VERILOG_SOURCES += $(FORENCICH_AXI_RTL_DIR)/axi_dma_wr.v + + +VERILOG_SOURCES += $(AXI_IF_RTL_DIR)/axi_dma_wrapper.sv + +VERILOG_SOURCES += $(TB_DIR)/tb_axi_dma_axis_compat.sv + +COMPILE_ARGS += -I$(AXI_IF_RTL_DIR) + +COMPILE_ARGS += -I$(FORENCICH_AXI_RTL_DIR) +# took this from forencich to silence 100+ warnings +COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH -Wno-CASEINCOMPLETE +ifeq ($(SIM),verilator) + EXTRA_ARGS += --trace + EXTRA_ARGS += --trace-structs + EXTRA_ARGS += -GAXI_DATA_WIDTH=$(AXI_DATA_WIDTH) + EXTRA_ARGS += -GAXI_ADDR_WIDTH=$(AXI_ADDR_WIDTH) + EXTRA_ARGS += -GAXI_STRB_WIDTH=$(AXI_STRB_WIDTH) + EXTRA_ARGS += -GAXI_ID_WIDTH=$(AXI_ID_WIDTH) + EXTRA_ARGS += -GAXI_USER_WIDTH=$(AXI_USER_WIDTH) + EXTRA_ARGS += -GAXI_MAX_BURST_LEN=$(AXI_MAX_BURST_LEN) + EXTRA_ARGS += -GAXIS_DATA_WIDTH=$(AXIS_DATA_WIDTH) + EXTRA_ARGS += -GAXIS_KEEP_ENABLE=$(AXIS_KEEP_ENABLE) + EXTRA_ARGS += -GAXIS_KEEP_WIDTH=$(AXIS_KEEP_WIDTH) + EXTRA_ARGS += -GAXIS_LAST_ENABLE=1 + EXTRA_ARGS += -GAXIS_ID_ENABLE=1 + EXTRA_ARGS += -GAXIS_ID_WIDTH=8 + EXTRA_ARGS += -GAXIS_DEST_ENABLE=0 + EXTRA_ARGS += -GAXIS_DEST_WIDTH=8 + EXTRA_ARGS += -GAXIS_USER_ENABLE=1 + EXTRA_ARGS += -GAXIS_USER_WIDTH=1 + EXTRA_ARGS += -GLEN_WIDTH=20 + EXTRA_ARGS += -GTAG_WIDTH=8 + EXTRA_ARGS += -GENABLE_SG=0 + EXTRA_ARGS += -GENABLE_UNALIGNED=$(ENABLE_UNALIGNED) +endif + +export PARAM_AXI_DATA_WIDTH=$(AXI_DATA_WIDTH) +export PARAM_ENABLE_UNALIGNED=$(ENABLE_UNALIGNED) + +include $(shell cocotb-config --makefiles)/Makefile.sim diff --git a/external/external/rtl_libs/axi/tb/axi_dma_axis_compat/tb_axi_dma_axis_compat.sv b/external/external/rtl_libs/axi/tb/axi_dma_axis_compat/tb_axi_dma_axis_compat.sv new file mode 100644 index 0000000..7ce92d3 --- /dev/null +++ b/external/external/rtl_libs/axi/tb/axi_dma_axis_compat/tb_axi_dma_axis_compat.sv @@ -0,0 +1,431 @@ +// another wrapper... + +`default_nettype none + +module tb_axi_dma_axis_compat #( + parameter int unsigned AXI_DATA_WIDTH = 32, + parameter int unsigned AXI_ADDR_WIDTH = 16, + parameter int unsigned AXI_STRB_WIDTH = AXI_DATA_WIDTH / 8, + parameter int unsigned AXI_ID_WIDTH = 8, + parameter int unsigned AXI_USER_WIDTH = 1, + parameter int unsigned AXI_MAX_BURST_LEN = 16, + + parameter int unsigned AXIS_DATA_WIDTH = AXI_DATA_WIDTH, + parameter int unsigned AXIS_KEEP_ENABLE = AXIS_DATA_WIDTH > 8, + parameter int unsigned AXIS_KEEP_WIDTH = AXIS_DATA_WIDTH / 8, + parameter int unsigned AXIS_LAST_ENABLE = 1, + parameter int unsigned AXIS_ID_ENABLE = 1, + parameter int unsigned AXIS_ID_WIDTH = 8, + parameter int unsigned AXIS_DEST_ENABLE = 0, + parameter int unsigned AXIS_DEST_WIDTH = 8, + parameter int unsigned AXIS_USER_ENABLE = 1, + parameter int unsigned AXIS_USER_WIDTH = 1, + + parameter int unsigned LEN_WIDTH = 20, + parameter int unsigned TAG_WIDTH = 8, + parameter int unsigned ENABLE_SG = 0, + parameter int unsigned ENABLE_UNALIGNED = 0, + + parameter int unsigned READ_DESC_RAW_WIDTH = AXI_ADDR_WIDTH + LEN_WIDTH + TAG_WIDTH, + parameter int unsigned READ_DESC_DATA_WIDTH = ((READ_DESC_RAW_WIDTH + 7) / 8) * 8, + parameter int unsigned WRITE_DESC_RAW_WIDTH = AXI_ADDR_WIDTH + LEN_WIDTH + TAG_WIDTH, + parameter int unsigned WRITE_DESC_DATA_WIDTH = ((WRITE_DESC_RAW_WIDTH + 7) / 8) * 8, + parameter int unsigned READ_STATUS_RAW_WIDTH = TAG_WIDTH + 4, + parameter int unsigned READ_STATUS_DATA_WIDTH = ((READ_STATUS_RAW_WIDTH + 7) / 8) * 8, + parameter int unsigned WRITE_STATUS_RAW_WIDTH = LEN_WIDTH + TAG_WIDTH + 4, + parameter int unsigned WRITE_STATUS_DATA_WIDTH = ((WRITE_STATUS_RAW_WIDTH + 7) / 8) * 8 +)( + input logic clk, + input logic rst, + + input logic read_enable, + input logic write_enable, + input logic write_abort, + + // Read descriptor AXIS input, flat for cocotb. + // tdata layout: {addr, len, tag}; id/dest/user use AXIS sidebands. + input logic [READ_DESC_DATA_WIDTH-1:0] s_axis_read_desc_tdata, + input logic [AXIS_ID_WIDTH-1:0] s_axis_read_desc_tid, + input logic [AXIS_DEST_WIDTH-1:0] s_axis_read_desc_tdest, + input logic [AXIS_USER_WIDTH-1:0] s_axis_read_desc_tuser, + input logic s_axis_read_desc_tvalid, + output logic s_axis_read_desc_tready, + + // Read descriptor status AXIS output. + // tdata layout: {tag, error}. + output logic [READ_STATUS_DATA_WIDTH-1:0] m_axis_read_desc_status_tdata, + output logic m_axis_read_desc_status_tvalid, + input logic m_axis_read_desc_status_tready, + + // Write descriptor AXIS input. + // tdata layout: {addr, len, tag}. + input logic [WRITE_DESC_DATA_WIDTH-1:0] s_axis_write_desc_tdata, + input logic s_axis_write_desc_tvalid, + output logic s_axis_write_desc_tready, + + // Write descriptor status AXIS output. + // tdata layout: {len, tag, error}; id/dest/user use AXIS sidebands. + output logic [WRITE_STATUS_DATA_WIDTH-1:0] m_axis_write_desc_status_tdata, + output logic [AXIS_ID_WIDTH-1:0] m_axis_write_desc_status_tid, + output logic [AXIS_DEST_WIDTH-1:0] m_axis_write_desc_status_tdest, + output logic [AXIS_USER_WIDTH-1:0] m_axis_write_desc_status_tuser, + output logic m_axis_write_desc_status_tvalid, + input logic m_axis_write_desc_status_tready, + + // Read data AXIS output + output logic [AXIS_DATA_WIDTH-1:0] m_axis_read_data_tdata, + output logic [AXIS_KEEP_WIDTH-1:0] m_axis_read_data_tkeep, + output logic [AXIS_KEEP_WIDTH-1:0] m_axis_read_data_tstrb, + output logic m_axis_read_data_tlast, + output logic [AXIS_ID_WIDTH-1:0] m_axis_read_data_tid, + output logic [AXIS_DEST_WIDTH-1:0] m_axis_read_data_tdest, + output logic [AXIS_USER_WIDTH-1:0] m_axis_read_data_tuser, + output logic m_axis_read_data_tvalid, + input logic m_axis_read_data_tready, + + // Write data AXIS input + input logic [AXIS_DATA_WIDTH-1:0] s_axis_write_data_tdata, + input logic [AXIS_KEEP_WIDTH-1:0] s_axis_write_data_tkeep, + input logic [AXIS_KEEP_WIDTH-1:0] s_axis_write_data_tstrb, + input logic s_axis_write_data_tlast, + input logic [AXIS_ID_WIDTH-1:0] s_axis_write_data_tid, + input logic [AXIS_DEST_WIDTH-1:0] s_axis_write_data_tdest, + input logic [AXIS_USER_WIDTH-1:0] s_axis_write_data_tuser, + input logic s_axis_write_data_tvalid, + output logic s_axis_write_data_tready, + + // AXI memory master, flat for cocotb AxiRam + output logic [AXI_ID_WIDTH-1:0] m_axi_awid, + output logic [AXI_ADDR_WIDTH-1:0] m_axi_awaddr, + output logic [7:0] m_axi_awlen, + output logic [2:0] m_axi_awsize, + output logic [1:0] m_axi_awburst, + output logic m_axi_awlock, + output logic [3:0] m_axi_awcache, + output logic [2:0] m_axi_awprot, + output logic [3:0] m_axi_awqos, + output logic [3:0] m_axi_awregion, + output logic [AXI_USER_WIDTH-1:0] m_axi_awuser, + output logic m_axi_awvalid, + input logic m_axi_awready, + + output logic [AXI_DATA_WIDTH-1:0] m_axi_wdata, + output logic [AXI_STRB_WIDTH-1:0] m_axi_wstrb, + output logic m_axi_wlast, + output logic [AXI_USER_WIDTH-1:0] m_axi_wuser, + output logic m_axi_wvalid, + input logic m_axi_wready, + + input logic [AXI_ID_WIDTH-1:0] m_axi_bid, + input logic [1:0] m_axi_bresp, + input logic [AXI_USER_WIDTH-1:0] m_axi_buser, + input logic m_axi_bvalid, + output logic m_axi_bready, + + output logic [AXI_ID_WIDTH-1:0] m_axi_arid, + output logic [AXI_ADDR_WIDTH-1:0] m_axi_araddr, + output logic [7:0] m_axi_arlen, + output logic [2:0] m_axi_arsize, + output logic [1:0] m_axi_arburst, + output logic m_axi_arlock, + output logic [3:0] m_axi_arcache, + output logic [2:0] m_axi_arprot, + output logic [3:0] m_axi_arqos, + output logic [3:0] m_axi_arregion, + output logic [AXI_USER_WIDTH-1:0] m_axi_aruser, + output logic m_axi_arvalid, + input logic m_axi_arready, + + input logic [AXI_ID_WIDTH-1:0] m_axi_rid, + input logic [AXI_DATA_WIDTH-1:0] m_axi_rdata, + input logic [1:0] m_axi_rresp, + input logic m_axi_rlast, + input logic [AXI_USER_WIDTH-1:0] m_axi_ruser, + input logic m_axi_rvalid, + output logic m_axi_rready +); + + wire rstn = ~rst; + + axis_if #( + .DATA_W (READ_DESC_DATA_WIDTH), + .KEEP_W (READ_DESC_DATA_WIDTH / 8), + .ID_W (AXIS_ID_WIDTH), + .DEST_W (AXIS_DEST_WIDTH), + .USER_W (AXIS_USER_WIDTH) + ) read_desc_if ( + .aclk (clk), + .aresetn (rstn) + ); + + axis_if #( + .DATA_W (READ_STATUS_DATA_WIDTH), + .KEEP_W (READ_STATUS_DATA_WIDTH / 8), + .ID_W (1), + .DEST_W (1), + .USER_W (1) + ) read_desc_status_if ( + .aclk (clk), + .aresetn (rstn) + ); + + axis_if #( + .DATA_W (WRITE_DESC_DATA_WIDTH), + .KEEP_W (WRITE_DESC_DATA_WIDTH / 8), + .ID_W (1), + .DEST_W (1), + .USER_W (1) + ) write_desc_if ( + .aclk (clk), + .aresetn (rstn) + ); + + axis_if #( + .DATA_W (WRITE_STATUS_DATA_WIDTH), + .KEEP_W (WRITE_STATUS_DATA_WIDTH / 8), + .ID_W (AXIS_ID_WIDTH), + .DEST_W (AXIS_DEST_WIDTH), + .USER_W (AXIS_USER_WIDTH) + ) write_desc_status_if ( + .aclk (clk), + .aresetn (rstn) + ); + + axis_if #( + .DATA_W (AXIS_DATA_WIDTH), + .KEEP_W (AXIS_KEEP_WIDTH), + .ID_W (AXIS_ID_WIDTH), + .DEST_W (AXIS_DEST_WIDTH), + .USER_W (AXIS_USER_WIDTH) + ) read_data_if ( + .aclk (clk), + .aresetn (rstn) + ); + + axis_if #( + .DATA_W (AXIS_DATA_WIDTH), + .KEEP_W (AXIS_KEEP_WIDTH), + .ID_W (AXIS_ID_WIDTH), + .DEST_W (AXIS_DEST_WIDTH), + .USER_W (AXIS_USER_WIDTH) + ) write_data_if ( + .aclk (clk), + .aresetn (rstn) + ); + + axi4_if #( + .ADDR_W (AXI_ADDR_WIDTH), + .DATA_W (AXI_DATA_WIDTH), + .ID_W (AXI_ID_WIDTH), + .USER_W (AXI_USER_WIDTH) + ) m_axi_if ( + .aclk (clk), + .aresetn (rstn) + ); + + axis_flat_to_if #( + .DATA_W (READ_DESC_DATA_WIDTH), + .KEEP_W (READ_DESC_DATA_WIDTH / 8), + .ID_W (AXIS_ID_WIDTH), + .DEST_W (AXIS_DEST_WIDTH), + .USER_W (AXIS_USER_WIDTH) + ) u_read_desc_flat_to_if ( + .s_axis_tdata (s_axis_read_desc_tdata), + .s_axis_tkeep ({(READ_DESC_DATA_WIDTH/8){1'b1}}), + .s_axis_tstrb ({(READ_DESC_DATA_WIDTH/8){1'b1}}), + .s_axis_tlast (1'b1), + .s_axis_tid (s_axis_read_desc_tid), + .s_axis_tdest (s_axis_read_desc_tdest), + .s_axis_tuser (s_axis_read_desc_tuser), + .s_axis_tvalid (s_axis_read_desc_tvalid), + .s_axis_tready (s_axis_read_desc_tready), + .m_axis (read_desc_if) + ); + + axis_if_to_flat #( + .DATA_W (READ_STATUS_DATA_WIDTH), + .KEEP_W (READ_STATUS_DATA_WIDTH / 8), + .ID_W (1), + .DEST_W (1), + .USER_W (1) + ) u_read_desc_status_if_to_flat ( + .s_axis (read_desc_status_if), + .m_axis_tdata (m_axis_read_desc_status_tdata), + .m_axis_tkeep (), + .m_axis_tstrb (), + .m_axis_tlast (), + .m_axis_tid (), + .m_axis_tdest (), + .m_axis_tuser (), + .m_axis_tvalid (m_axis_read_desc_status_tvalid), + .m_axis_tready (m_axis_read_desc_status_tready) + ); + + axis_flat_to_if #( + .DATA_W (WRITE_DESC_DATA_WIDTH), + .KEEP_W (WRITE_DESC_DATA_WIDTH / 8), + .ID_W (1), + .DEST_W (1), + .USER_W (1) + ) u_write_desc_flat_to_if ( + .s_axis_tdata (s_axis_write_desc_tdata), + .s_axis_tkeep ({(WRITE_DESC_DATA_WIDTH/8){1'b1}}), + .s_axis_tstrb ({(WRITE_DESC_DATA_WIDTH/8){1'b1}}), + .s_axis_tlast (1'b1), + .s_axis_tid (1'b0), + .s_axis_tdest (1'b0), + .s_axis_tuser (1'b0), + .s_axis_tvalid (s_axis_write_desc_tvalid), + .s_axis_tready (s_axis_write_desc_tready), + .m_axis (write_desc_if) + ); + + axis_if_to_flat #( + .DATA_W (WRITE_STATUS_DATA_WIDTH), + .KEEP_W (WRITE_STATUS_DATA_WIDTH / 8), + .ID_W (AXIS_ID_WIDTH), + .DEST_W (AXIS_DEST_WIDTH), + .USER_W (AXIS_USER_WIDTH) + ) u_write_desc_status_if_to_flat ( + .s_axis (write_desc_status_if), + .m_axis_tdata (m_axis_write_desc_status_tdata), + .m_axis_tkeep (), + .m_axis_tstrb (), + .m_axis_tlast (), + .m_axis_tid (m_axis_write_desc_status_tid), + .m_axis_tdest (m_axis_write_desc_status_tdest), + .m_axis_tuser (m_axis_write_desc_status_tuser), + .m_axis_tvalid (m_axis_write_desc_status_tvalid), + .m_axis_tready (m_axis_write_desc_status_tready) + ); + + axis_if_to_flat #( + .DATA_W (AXIS_DATA_WIDTH), + .KEEP_W (AXIS_KEEP_WIDTH), + .ID_W (AXIS_ID_WIDTH), + .DEST_W (AXIS_DEST_WIDTH), + .USER_W (AXIS_USER_WIDTH) + ) u_read_data_if_to_flat ( + .s_axis (read_data_if), + .m_axis_tdata (m_axis_read_data_tdata), + .m_axis_tkeep (m_axis_read_data_tkeep), + .m_axis_tstrb (m_axis_read_data_tstrb), + .m_axis_tlast (m_axis_read_data_tlast), + .m_axis_tid (m_axis_read_data_tid), + .m_axis_tdest (m_axis_read_data_tdest), + .m_axis_tuser (m_axis_read_data_tuser), + .m_axis_tvalid (m_axis_read_data_tvalid), + .m_axis_tready (m_axis_read_data_tready) + ); + + axis_flat_to_if #( + .DATA_W (AXIS_DATA_WIDTH), + .KEEP_W (AXIS_KEEP_WIDTH), + .ID_W (AXIS_ID_WIDTH), + .DEST_W (AXIS_DEST_WIDTH), + .USER_W (AXIS_USER_WIDTH) + ) u_write_data_flat_to_if ( + .s_axis_tdata (s_axis_write_data_tdata), + .s_axis_tkeep (s_axis_write_data_tkeep), + .s_axis_tstrb (s_axis_write_data_tstrb), + .s_axis_tlast (s_axis_write_data_tlast), + .s_axis_tid (s_axis_write_data_tid), + .s_axis_tdest (s_axis_write_data_tdest), + .s_axis_tuser (s_axis_write_data_tuser), + .s_axis_tvalid (s_axis_write_data_tvalid), + .s_axis_tready (s_axis_write_data_tready), + .m_axis (write_data_if) + ); + + axi_dma_wrapper #( + .AXI_DATA_WIDTH (AXI_DATA_WIDTH), + .AXI_ADDR_WIDTH (AXI_ADDR_WIDTH), + .AXI_STRB_WIDTH (AXI_STRB_WIDTH), + .AXI_ID_WIDTH (AXI_ID_WIDTH), + .AXI_USER_WIDTH (AXI_USER_WIDTH), + .AXI_MAX_BURST_LEN (AXI_MAX_BURST_LEN), + .AXIS_DATA_WIDTH (AXIS_DATA_WIDTH), + .AXIS_KEEP_ENABLE (AXIS_KEEP_ENABLE), + .AXIS_KEEP_WIDTH (AXIS_KEEP_WIDTH), + .AXIS_LAST_ENABLE (AXIS_LAST_ENABLE), + .AXIS_ID_ENABLE (AXIS_ID_ENABLE), + .AXIS_ID_WIDTH (AXIS_ID_WIDTH), + .AXIS_DEST_ENABLE (AXIS_DEST_ENABLE), + .AXIS_DEST_WIDTH (AXIS_DEST_WIDTH), + .AXIS_USER_ENABLE (AXIS_USER_ENABLE), + .AXIS_USER_WIDTH (AXIS_USER_WIDTH), + .LEN_WIDTH (LEN_WIDTH), + .TAG_WIDTH (TAG_WIDTH), + .ENABLE_SG (ENABLE_SG), + .ENABLE_UNALIGNED (ENABLE_UNALIGNED) + ) u_dut ( + .clk (clk), + .rst (rst), + .s_axis_read_desc (read_desc_if), + .m_axis_read_desc_status (read_desc_status_if), + .m_axis_read_data (read_data_if), + .s_axis_write_desc (write_desc_if), + .m_axis_write_desc_status (write_desc_status_if), + .s_axis_write_data (write_data_if), + .m_axi (m_axi_if), + .read_enable (read_enable), + .write_enable (write_enable), + .write_abort (write_abort) + ); + + axi4_if_to_flat #( + .ADDR_W (AXI_ADDR_WIDTH), + .DATA_W (AXI_DATA_WIDTH), + .ID_W (AXI_ID_WIDTH), + .USER_W (AXI_USER_WIDTH) + ) u_m_axi_if_to_flat ( + .s_axi (m_axi_if), + .m_axi_awid (m_axi_awid), + .m_axi_awaddr (m_axi_awaddr), + .m_axi_awlen (m_axi_awlen), + .m_axi_awsize (m_axi_awsize), + .m_axi_awburst (m_axi_awburst), + .m_axi_awlock (m_axi_awlock), + .m_axi_awcache (m_axi_awcache), + .m_axi_awprot (m_axi_awprot), + .m_axi_awqos (m_axi_awqos), + .m_axi_awregion (m_axi_awregion), + .m_axi_awuser (m_axi_awuser), + .m_axi_awvalid (m_axi_awvalid), + .m_axi_awready (m_axi_awready), + .m_axi_wdata (m_axi_wdata), + .m_axi_wstrb (m_axi_wstrb), + .m_axi_wlast (m_axi_wlast), + .m_axi_wuser (m_axi_wuser), + .m_axi_wvalid (m_axi_wvalid), + .m_axi_wready (m_axi_wready), + .m_axi_bid (m_axi_bid), + .m_axi_bresp (m_axi_bresp), + .m_axi_buser (m_axi_buser), + .m_axi_bvalid (m_axi_bvalid), + .m_axi_bready (m_axi_bready), + .m_axi_arid (m_axi_arid), + .m_axi_araddr (m_axi_araddr), + .m_axi_arlen (m_axi_arlen), + .m_axi_arsize (m_axi_arsize), + .m_axi_arburst (m_axi_arburst), + .m_axi_arlock (m_axi_arlock), + .m_axi_arcache (m_axi_arcache), + .m_axi_arprot (m_axi_arprot), + .m_axi_arqos (m_axi_arqos), + .m_axi_arregion (m_axi_arregion), + .m_axi_aruser (m_axi_aruser), + .m_axi_arvalid (m_axi_arvalid), + .m_axi_arready (m_axi_arready), + .m_axi_rid (m_axi_rid), + .m_axi_rdata (m_axi_rdata), + .m_axi_rresp (m_axi_rresp), + .m_axi_rlast (m_axi_rlast), + .m_axi_ruser (m_axi_ruser), + .m_axi_rvalid (m_axi_rvalid), + .m_axi_rready (m_axi_rready) + ); + +endmodule : tb_axi_dma_axis_compat + +`default_nettype wire diff --git a/external/external/rtl_libs/axi/tb/axi_dma_axis_compat/test_axi_dma_axis_compat.py b/external/external/rtl_libs/axi/tb/axi_dma_axis_compat/test_axi_dma_axis_compat.py new file mode 100644 index 0000000..4484d47 --- /dev/null +++ b/external/external/rtl_libs/axi/tb/axi_dma_axis_compat/test_axi_dma_axis_compat.py @@ -0,0 +1,317 @@ +import logging +import os + +import cocotb +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge + +from cocotbext.axi import AxiBus, AxiRam +from cocotbext.axi import AxiStreamBus, AxiStreamFrame, AxiStreamSource, AxiStreamSink + + +AXI_ADDR_WIDTH = int(os.getenv("PARAM_AXI_ADDR_WIDTH", "16")) +LEN_WIDTH = int(os.getenv("PARAM_LEN_WIDTH", "20")) +TAG_WIDTH = int(os.getenv("PARAM_TAG_WIDTH", "8")) +AXIS_ID_WIDTH = int(os.getenv("PARAM_AXIS_ID_WIDTH", "8")) +AXIS_DEST_WIDTH = int(os.getenv("PARAM_AXIS_DEST_WIDTH", "8")) +AXIS_USER_WIDTH = int(os.getenv("PARAM_AXIS_USER_WIDTH", "1")) + +READ_DESC_RAW_WIDTH = AXI_ADDR_WIDTH + LEN_WIDTH + TAG_WIDTH +READ_DESC_DATA_WIDTH = ((READ_DESC_RAW_WIDTH + 7) // 8) * 8 +READ_DESC_BYTES = READ_DESC_DATA_WIDTH // 8 + +WRITE_DESC_RAW_WIDTH = AXI_ADDR_WIDTH + LEN_WIDTH + TAG_WIDTH +WRITE_DESC_DATA_WIDTH = ((WRITE_DESC_RAW_WIDTH + 7) // 8) * 8 +WRITE_DESC_BYTES = WRITE_DESC_DATA_WIDTH // 8 + +READ_STATUS_RAW_WIDTH = TAG_WIDTH + 4 +READ_STATUS_DATA_WIDTH = ((READ_STATUS_RAW_WIDTH + 7) // 8) * 8 + +WRITE_STATUS_RAW_WIDTH = LEN_WIDTH + TAG_WIDTH + 4 +WRITE_STATUS_DATA_WIDTH = ((WRITE_STATUS_RAW_WIDTH + 7) // 8) * 8 + +# axi_dma_wrapper maps descriptor tdata as {addr, len, tag}. +DESC_TAG_LSB = 0 +DESC_LEN_LSB = DESC_TAG_LSB + TAG_WIDTH +DESC_ADDR_LSB = DESC_LEN_LSB + LEN_WIDTH + +# Read status tdata is {tag, error}. +READ_STATUS_ERROR_LSB = 0 +READ_STATUS_TAG_LSB = READ_STATUS_ERROR_LSB + 4 + +# Write status tdata is {len, tag, error}. +WRITE_STATUS_ERROR_LSB = 0 +WRITE_STATUS_TAG_LSB = WRITE_STATUS_ERROR_LSB + 4 +WRITE_STATUS_LEN_LSB = WRITE_STATUS_TAG_LSB + TAG_WIDTH + + +def mask(width): + return (1 << width) - 1 + + +def put(value, lsb, width, field): + value &= ~(mask(width) << lsb) + value |= (int(field) & mask(width)) << lsb + return value + + +def get(value, lsb, width): + return (int(value) >> lsb) & mask(width) + + +def pack_read_desc(*, addr, length, tag, axis_id=0, dest=0, user=0): + value = 0 + value = put(value, DESC_TAG_LSB, TAG_WIDTH, tag) + value = put(value, DESC_LEN_LSB, LEN_WIDTH, length) + value = put(value, DESC_ADDR_LSB, AXI_ADDR_WIDTH, addr) + + return AxiStreamFrame( + value.to_bytes(READ_DESC_BYTES, byteorder="little"), + tid=axis_id, + tdest=dest, + tuser=user, + ) + + +def pack_write_desc(*, addr, length, tag): + value = 0 + value = put(value, DESC_TAG_LSB, TAG_WIDTH, tag) + value = put(value, DESC_LEN_LSB, LEN_WIDTH, length) + value = put(value, DESC_ADDR_LSB, AXI_ADDR_WIDTH, addr) + + return AxiStreamFrame( + value.to_bytes(WRITE_DESC_BYTES, byteorder="little") + ) + + +def frame_to_int(frame): + return int.from_bytes(bytes(frame.tdata), byteorder="little") + + +def frame_sideband(frame, name): + value = getattr(frame, name) + try: + return int(value) + except TypeError: + return int(value[0]) if value else 0 + + +def unpack_read_status(frame): + value = frame_to_int(frame) + return { + "tag": get(value, READ_STATUS_TAG_LSB, TAG_WIDTH), + "error": get(value, READ_STATUS_ERROR_LSB, 4), + } + + +def unpack_write_status(frame): + value = frame_to_int(frame) + return { + "len": get(value, WRITE_STATUS_LEN_LSB, LEN_WIDTH), + "tag": get(value, WRITE_STATUS_TAG_LSB, TAG_WIDTH), + "error": get(value, WRITE_STATUS_ERROR_LSB, 4), + "id": frame_sideband(frame, "tid"), + "dest": frame_sideband(frame, "tdest"), + "user": frame_sideband(frame, "tuser"), + } + + +class TB: + def __init__(self, dut): + self.dut = dut + self.log = logging.getLogger("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + cocotb.start_soon(Clock(dut.clk, 10, units="ns").start()) + + self.read_desc_source = AxiStreamSource( + AxiStreamBus.from_prefix(dut, "s_axis_read_desc"), + dut.clk, + dut.rst, + ) + self.read_desc_status_sink = AxiStreamSink( + AxiStreamBus.from_prefix(dut, "m_axis_read_desc_status"), + dut.clk, + dut.rst, + ) + + self.write_desc_source = AxiStreamSource( + AxiStreamBus.from_prefix(dut, "s_axis_write_desc"), + dut.clk, + dut.rst, + ) + self.write_desc_status_sink = AxiStreamSink( + AxiStreamBus.from_prefix(dut, "m_axis_write_desc_status"), + dut.clk, + dut.rst, + ) + + self.read_data_sink = AxiStreamSink( + AxiStreamBus.from_prefix(dut, "m_axis_read_data"), + dut.clk, + dut.rst, + ) + self.write_data_source = AxiStreamSource( + AxiStreamBus.from_prefix(dut, "s_axis_write_data"), + dut.clk, + dut.rst, + ) + + self.axi_ram = AxiRam( + AxiBus.from_prefix(dut, "m_axi"), + dut.clk, + dut.rst, + size=2**AXI_ADDR_WIDTH, + ) + + dut.read_enable.setimmediatevalue(0) + dut.write_enable.setimmediatevalue(0) + dut.write_abort.setimmediatevalue(0) + + async def reset(self): + self.dut.rst.setimmediatevalue(0) + await RisingEdge(self.dut.clk) + await RisingEdge(self.dut.clk) + self.dut.rst.value = 1 + await RisingEdge(self.dut.clk) + await RisingEdge(self.dut.clk) + self.dut.rst.value = 0 + await RisingEdge(self.dut.clk) + await RisingEdge(self.dut.clk) + + async def send_read_desc(self, **kwargs): + await self.read_desc_source.send(pack_read_desc(**kwargs)) + + async def send_write_desc(self, **kwargs): + await self.write_desc_source.send(pack_write_desc(**kwargs)) + + +@cocotb.test() +async def test_axis_compat_write_path(dut): + tb = TB(dut) + await tb.reset() + + dut.write_enable.value = 1 + dut.read_enable.value = 0 + + addr = 0x1000 + tag = 0x12 + data = bytes(range(1, 33)) + + tb.axi_ram.write(addr - 16, b"\xaa" * (len(data) + 32)) + + desc_task = cocotb.start_soon( + tb.send_write_desc(addr=addr, length=len(data), tag=tag) + ) + data_task = cocotb.start_soon( + tb.write_data_source.send(AxiStreamFrame(data, tid=tag)) + ) + + await desc_task + await data_task + + status = unpack_write_status(await tb.write_desc_status_sink.recv()) + + assert status["tag"] == tag + assert status["len"] == len(data) + assert status["id"] == tag + assert status["error"] == 0 + + assert tb.axi_ram.read(addr - 8, len(data) + 16) == ( + b"\xaa" * 8 + data + b"\xaa" * 8 + ) + + +@cocotb.test() +async def test_axis_compat_read_path(dut): + tb = TB(dut) + await tb.reset() + + dut.write_enable.value = 0 + dut.read_enable.value = 1 + + addr = 0x1100 + tag = 0x34 + data = bytes((x * 3) % 256 for x in range(48)) + + tb.axi_ram.write(addr, data) + + await tb.send_read_desc( + addr=addr, + length=len(data), + tag=tag, + axis_id=tag, + dest=0, + user=0, + ) + + data_frame = await tb.read_data_sink.recv() + assert bytes(data_frame.tdata) == data + assert frame_sideband(data_frame, "tid") == tag + + status = unpack_read_status(await tb.read_desc_status_sink.recv()) + assert status["tag"] == tag + assert status["error"] == 0 + + +@cocotb.test() +async def test_axis_compat_read_and_write_independent_desc_ports(dut): + tb = TB(dut) + await tb.reset() + + dut.write_enable.value = 1 + dut.read_enable.value = 1 + + read_addr = 0x1200 + write_addr = 0x1300 + read_tag = 0x41 + write_tag = 0x42 + read_data = bytes((x + 7) % 256 for x in range(24)) + write_data = bytes((x + 100) % 256 for x in range(24)) + + tb.axi_ram.write(read_addr, read_data) + tb.axi_ram.write(write_addr - 8, b"\xaa" * (len(write_data) + 16)) + + read_desc_task = cocotb.start_soon( + tb.send_read_desc( + addr=read_addr, + length=len(read_data), + tag=read_tag, + axis_id=read_tag, + dest=0, + user=0, + ) + ) + write_desc_task = cocotb.start_soon( + tb.send_write_desc( + addr=write_addr, + length=len(write_data), + tag=write_tag, + ) + ) + write_data_task = cocotb.start_soon( + tb.write_data_source.send(AxiStreamFrame(write_data, tid=write_tag)) + ) + + await read_desc_task + await write_desc_task + await write_data_task + + data_frame = await tb.read_data_sink.recv() + assert bytes(data_frame.tdata) == read_data + assert frame_sideband(data_frame, "tid") == read_tag + + read_status = unpack_read_status(await tb.read_desc_status_sink.recv()) + write_status = unpack_write_status(await tb.write_desc_status_sink.recv()) + + assert read_status["tag"] == read_tag + assert read_status["error"] == 0 + + assert write_status["tag"] == write_tag + assert write_status["len"] == len(write_data) + assert write_status["id"] == write_tag + assert write_status["error"] == 0 + + assert tb.axi_ram.read(write_addr - 8, len(write_data) + 16) == ( + b"\xaa" * 8 + write_data + b"\xaa" * 8 + ) diff --git a/external/external/rtl_libs/axi/tb/axi_dma_wrapper/Makefile b/external/external/rtl_libs/axi/tb/axi_dma_wrapper/Makefile new file mode 100644 index 0000000..c1e3a9b --- /dev/null +++ b/external/external/rtl_libs/axi/tb/axi_dma_wrapper/Makefile @@ -0,0 +1,84 @@ + +TOPLEVEL_LANG = verilog +SIM ?= verilator + +PWD := $(shell pwd) +PROJECT_ROOT ?= $(abspath $(PWD)/../../..) + +AXI_IF_RTL_DIR ?= $(PROJECT_ROOT)/axi/rtl +FORENCICH_AXI_RTL_DIR ?= $(PROJECT_ROOT)/external/verilog-axi/rtl +TB_DIR ?= $(PWD) + +TOPLEVEL = tb_axi_dma_wrapper +MODULE = test_axi_dma_wrapper + +export PYTHONPATH := $(TB_DIR):$(PYTHONPATH) + +# Parameters for a quick make-based run. The pytest entrypoint can be used for +# wider parameter sweeps. +AXI_DATA_WIDTH ?= 32 +AXI_ADDR_WIDTH ?= 16 +AXI_ID_WIDTH ?= 8 +AXI_USER_WIDTH ?= 1 +AXI_MAX_BURST_LEN ?= 16 +ENABLE_UNALIGNED ?= 0 + +AXI_STRB_WIDTH := $(shell expr $(AXI_DATA_WIDTH) / 8) +AXIS_DATA_WIDTH ?= $(AXI_DATA_WIDTH) +AXIS_KEEP_WIDTH := $(shell expr $(AXIS_DATA_WIDTH) / 8) +AXIS_KEEP_ENABLE := $(shell [ $(AXIS_DATA_WIDTH) -gt 8 ] && echo 1 || echo 0) + +VERILOG_SOURCES += $(AXI_IF_RTL_DIR)/axi_pkg.sv +VERILOG_SOURCES += $(AXI_IF_RTL_DIR)/axi_if.sv +VERILOG_SOURCES += $(AXI_IF_RTL_DIR)/axis_if.sv +VERILOG_SOURCES += $(AXI_IF_RTL_DIR)/axi4_flat_to_if.sv +VERILOG_SOURCES += $(AXI_IF_RTL_DIR)/axi4_if_to_flat.sv +VERILOG_SOURCES += $(AXI_IF_RTL_DIR)/axis_flat_to_if.sv +VERILOG_SOURCES += $(AXI_IF_RTL_DIR)/axis_if_to_flat.sv + +VERILOG_SOURCES += $(AXI_IF_RTL_DIR)/axi_dma_desc_if.sv + + +VERILOG_SOURCES += $(FORENCICH_AXI_RTL_DIR)/axi_dma.v +VERILOG_SOURCES += $(FORENCICH_AXI_RTL_DIR)/axi_dma_rd.v +VERILOG_SOURCES += $(FORENCICH_AXI_RTL_DIR)/axi_dma_wr.v + +VERILOG_SOURCES += $(AXI_IF_RTL_DIR)/axi_dma_if_wrapper.sv +VERILOG_SOURCES += $(TB_DIR)/tb_axi_dma_wrapper.sv + +COMPILE_ARGS += -I$(AXI_IF_RTL_DIR) +COMPILE_ARGS += -I$(WRAPPER_RTL_DIR) +COMPILE_ARGS += -I$(FORENCICH_AXI_RTL_DIR) + +# took this from forencich to silence 100+ warnings +COMPILE_ARGS += -Wno-SELRANGE -Wno-WIDTH -Wno-CASEINCOMPLETE + +ifeq ($(SIM),verilator) + EXTRA_ARGS += --trace + EXTRA_ARGS += --trace-structs + EXTRA_ARGS += -GAXI_DATA_WIDTH=$(AXI_DATA_WIDTH) + EXTRA_ARGS += -GAXI_ADDR_WIDTH=$(AXI_ADDR_WIDTH) + EXTRA_ARGS += -GAXI_STRB_WIDTH=$(AXI_STRB_WIDTH) + EXTRA_ARGS += -GAXI_ID_WIDTH=$(AXI_ID_WIDTH) + EXTRA_ARGS += -GAXI_USER_WIDTH=$(AXI_USER_WIDTH) + EXTRA_ARGS += -GAXI_MAX_BURST_LEN=$(AXI_MAX_BURST_LEN) + EXTRA_ARGS += -GAXIS_DATA_WIDTH=$(AXIS_DATA_WIDTH) + EXTRA_ARGS += -GAXIS_KEEP_ENABLE=$(AXIS_KEEP_ENABLE) + EXTRA_ARGS += -GAXIS_KEEP_WIDTH=$(AXIS_KEEP_WIDTH) + EXTRA_ARGS += -GAXIS_LAST_ENABLE=1 + EXTRA_ARGS += -GAXIS_ID_ENABLE=1 + EXTRA_ARGS += -GAXIS_ID_WIDTH=8 + EXTRA_ARGS += -GAXIS_DEST_ENABLE=0 + EXTRA_ARGS += -GAXIS_DEST_WIDTH=8 + EXTRA_ARGS += -GAXIS_USER_ENABLE=1 + EXTRA_ARGS += -GAXIS_USER_WIDTH=1 + EXTRA_ARGS += -GLEN_WIDTH=20 + EXTRA_ARGS += -GTAG_WIDTH=8 + EXTRA_ARGS += -GENABLE_SG=0 + EXTRA_ARGS += -GENABLE_UNALIGNED=$(ENABLE_UNALIGNED) +endif + +export PARAM_AXI_DATA_WIDTH=$(AXI_DATA_WIDTH) +export PARAM_ENABLE_UNALIGNED=$(ENABLE_UNALIGNED) + +include $(shell cocotb-config --makefiles)/Makefile.sim diff --git a/external/external/rtl_libs/axi/tb/axi_dma_wrapper/tb_axi_dma_wrapper.sv b/external/external/rtl_libs/axi/tb/axi_dma_wrapper/tb_axi_dma_wrapper.sv new file mode 100644 index 0000000..2fa6a58 --- /dev/null +++ b/external/external/rtl_libs/axi/tb/axi_dma_wrapper/tb_axi_dma_wrapper.sv @@ -0,0 +1,429 @@ +// Cocotb still sees flat Forencich-style signal names +// this top converts those flat signals to local interfaces +`default_nettype none + +module tb_axi_dma_wrapper #( + parameter int unsigned AXI_DATA_WIDTH = 32, + parameter int unsigned AXI_ADDR_WIDTH = 16, + parameter int unsigned AXI_STRB_WIDTH = AXI_DATA_WIDTH / 8, + parameter int unsigned AXI_ID_WIDTH = 8, + parameter int unsigned AXI_USER_WIDTH = 1, + parameter int unsigned AXI_MAX_BURST_LEN = 16, + + parameter int unsigned AXIS_DATA_WIDTH = AXI_DATA_WIDTH, + parameter int unsigned AXIS_KEEP_ENABLE = AXIS_DATA_WIDTH > 8, + parameter int unsigned AXIS_KEEP_WIDTH = AXIS_DATA_WIDTH / 8, + parameter int unsigned AXIS_LAST_ENABLE = 1, + parameter int unsigned AXIS_ID_ENABLE = 1, + parameter int unsigned AXIS_ID_WIDTH = 8, + parameter int unsigned AXIS_DEST_ENABLE = 0, + parameter int unsigned AXIS_DEST_WIDTH = 8, + parameter int unsigned AXIS_USER_ENABLE = 1, + parameter int unsigned AXIS_USER_WIDTH = 1, + + parameter int unsigned LEN_WIDTH = 20, + parameter int unsigned TAG_WIDTH = 8, + parameter int unsigned ENABLE_SG = 0, + parameter int unsigned ENABLE_UNALIGNED = 0 +)(); + + // cocotb drives these directly + logic clk; + logic rst; + logic rstn; + + assign rstn = ~rst; + + // -------------------------------------------------------------------------- + // Flat descriptor/status ports visible to cocotb + // -------------------------------------------------------------------------- + + logic [AXI_ADDR_WIDTH-1:0] s_axis_read_desc_addr; + logic [LEN_WIDTH-1:0] s_axis_read_desc_len; + logic [TAG_WIDTH-1:0] s_axis_read_desc_tag; + logic [AXIS_ID_WIDTH-1:0] s_axis_read_desc_id; + logic [AXIS_DEST_WIDTH-1:0] s_axis_read_desc_dest; + logic [AXIS_USER_WIDTH-1:0] s_axis_read_desc_user; + logic s_axis_read_desc_valid; + logic s_axis_read_desc_ready; + + logic [TAG_WIDTH-1:0] m_axis_read_desc_status_tag; + logic [3:0] m_axis_read_desc_status_error; + logic m_axis_read_desc_status_valid; + + logic [AXI_ADDR_WIDTH-1:0] s_axis_write_desc_addr; + logic [LEN_WIDTH-1:0] s_axis_write_desc_len; + logic [TAG_WIDTH-1:0] s_axis_write_desc_tag; + logic s_axis_write_desc_valid; + logic s_axis_write_desc_ready; + + logic [LEN_WIDTH-1:0] m_axis_write_desc_status_len; + logic [TAG_WIDTH-1:0] m_axis_write_desc_status_tag; + logic [AXIS_ID_WIDTH-1:0] m_axis_write_desc_status_id; + logic [AXIS_DEST_WIDTH-1:0] m_axis_write_desc_status_dest; + logic [AXIS_USER_WIDTH-1:0] m_axis_write_desc_status_user; + logic [3:0] m_axis_write_desc_status_error; + logic m_axis_write_desc_status_valid; + + // -------------------------------------------------------------------------- + // Flat AXIS data ports visible to cocotb + // -------------------------------------------------------------------------- + + logic [AXIS_DATA_WIDTH-1:0] m_axis_read_data_tdata; + logic [AXIS_KEEP_WIDTH-1:0] m_axis_read_data_tkeep; + logic [AXIS_KEEP_WIDTH-1:0] m_axis_read_data_tstrb; + logic m_axis_read_data_tvalid; + logic m_axis_read_data_tready; + logic m_axis_read_data_tlast; + logic [AXIS_ID_WIDTH-1:0] m_axis_read_data_tid; + logic [AXIS_DEST_WIDTH-1:0] m_axis_read_data_tdest; + logic [AXIS_USER_WIDTH-1:0] m_axis_read_data_tuser; + + logic [AXIS_DATA_WIDTH-1:0] s_axis_write_data_tdata; + logic [AXIS_KEEP_WIDTH-1:0] s_axis_write_data_tkeep; + logic [AXIS_KEEP_WIDTH-1:0] s_axis_write_data_tstrb; + logic s_axis_write_data_tvalid; + logic s_axis_write_data_tready; + logic s_axis_write_data_tlast; + logic [AXIS_ID_WIDTH-1:0] s_axis_write_data_tid; + logic [AXIS_DEST_WIDTH-1:0] s_axis_write_data_tdest; + logic [AXIS_USER_WIDTH-1:0] s_axis_write_data_tuser; + + // -------------------------------------------------------------------------- + // Flat AXI memory master ports visible to cocotb AxiRam + // -------------------------------------------------------------------------- + + logic [AXI_ID_WIDTH-1:0] m_axi_awid; + logic [AXI_ADDR_WIDTH-1:0] m_axi_awaddr; + logic [7:0] m_axi_awlen; + logic [2:0] m_axi_awsize; + logic [1:0] m_axi_awburst; + logic m_axi_awlock; + logic [3:0] m_axi_awcache; + logic [2:0] m_axi_awprot; + logic [3:0] m_axi_awqos; + logic [3:0] m_axi_awregion; + logic [AXI_USER_WIDTH-1:0] m_axi_awuser; + logic m_axi_awvalid; + logic m_axi_awready; + + logic [AXI_DATA_WIDTH-1:0] m_axi_wdata; + logic [AXI_STRB_WIDTH-1:0] m_axi_wstrb; + logic m_axi_wlast; + logic [AXI_USER_WIDTH-1:0] m_axi_wuser; + logic m_axi_wvalid; + logic m_axi_wready; + + logic [AXI_ID_WIDTH-1:0] m_axi_bid; + logic [1:0] m_axi_bresp; + logic [AXI_USER_WIDTH-1:0] m_axi_buser; + logic m_axi_bvalid; + logic m_axi_bready; + + logic [AXI_ID_WIDTH-1:0] m_axi_arid; + logic [AXI_ADDR_WIDTH-1:0] m_axi_araddr; + logic [7:0] m_axi_arlen; + logic [2:0] m_axi_arsize; + logic [1:0] m_axi_arburst; + logic m_axi_arlock; + logic [3:0] m_axi_arcache; + logic [2:0] m_axi_arprot; + logic [3:0] m_axi_arqos; + logic [3:0] m_axi_arregion; + logic [AXI_USER_WIDTH-1:0] m_axi_aruser; + logic m_axi_arvalid; + logic m_axi_arready; + + logic [AXI_ID_WIDTH-1:0] m_axi_rid; + logic [AXI_DATA_WIDTH-1:0] m_axi_rdata; + logic [1:0] m_axi_rresp; + logic m_axi_rlast; + logic [AXI_USER_WIDTH-1:0] m_axi_ruser; + logic m_axi_rvalid; + logic m_axi_rready; + + // Configuration visible to cocotb + logic read_enable; + logic write_enable; + logic write_abort; + + // -------------------------------------------------------------------------- + // Local interface instances + // -------------------------------------------------------------------------- + + axis_if #( + .DATA_W (AXIS_DATA_WIDTH), + .KEEP_W (AXIS_KEEP_WIDTH), + .ID_W (AXIS_ID_WIDTH), + .DEST_W (AXIS_DEST_WIDTH), + .USER_W (AXIS_USER_WIDTH) + ) m_axis_read_data_if ( + .aclk (clk), + .aresetn (rstn) + ); + + axis_if #( + .DATA_W (AXIS_DATA_WIDTH), + .KEEP_W (AXIS_KEEP_WIDTH), + .ID_W (AXIS_ID_WIDTH), + .DEST_W (AXIS_DEST_WIDTH), + .USER_W (AXIS_USER_WIDTH) + ) s_axis_write_data_if ( + .aclk (clk), + .aresetn (rstn) + ); + + axi4_if #( + .ADDR_W (AXI_ADDR_WIDTH), + .DATA_W (AXI_DATA_WIDTH), + .ID_W (AXI_ID_WIDTH), + .USER_W (AXI_USER_WIDTH) + ) m_axi_if ( + .aclk (clk), + .aresetn (rstn) + ); + + axi_dma_read_desc_if #( + .ADDR_W (AXI_ADDR_WIDTH), + .LEN_W (LEN_WIDTH), + .TAG_W (TAG_WIDTH), + .ID_W (AXIS_ID_WIDTH), + .DEST_W (AXIS_DEST_WIDTH), + .USER_W (AXIS_USER_WIDTH) + ) s_axis_read_desc_if ( + .aclk (clk), + .aresetn (rstn) + ); + + axi_dma_read_desc_status_if #( + .TAG_W (TAG_WIDTH) + ) m_axis_read_desc_status_if ( + .aclk (clk), + .aresetn (rstn) + ); + + axi_dma_write_desc_if #( + .ADDR_W (AXI_ADDR_WIDTH), + .LEN_W (LEN_WIDTH), + .TAG_W (TAG_WIDTH) + ) s_axis_write_desc_if ( + .aclk (clk), + .aresetn (rstn) + ); + + axi_dma_write_desc_status_if #( + .LEN_W (LEN_WIDTH), + .TAG_W (TAG_WIDTH), + .ID_W (AXIS_ID_WIDTH), + .DEST_W (AXIS_DEST_WIDTH), + .USER_W (AXIS_USER_WIDTH) + ) m_axis_write_desc_status_if ( + .aclk (clk), + .aresetn (rstn) + ); + + // cocotb flat read descriptor -> interface + axi_dma_read_desc_flat_to_if #( + .ADDR_W (AXI_ADDR_WIDTH), + .LEN_W (LEN_WIDTH), + .TAG_W (TAG_WIDTH), + .ID_W (AXIS_ID_WIDTH), + .DEST_W (AXIS_DEST_WIDTH), + .USER_W (AXIS_USER_WIDTH) + ) u_s_axis_read_desc_flat_to_if ( + .s_axis_read_desc_addr (s_axis_read_desc_addr), + .s_axis_read_desc_len (s_axis_read_desc_len), + .s_axis_read_desc_tag (s_axis_read_desc_tag), + .s_axis_read_desc_id (s_axis_read_desc_id), + .s_axis_read_desc_dest (s_axis_read_desc_dest), + .s_axis_read_desc_user (s_axis_read_desc_user), + .s_axis_read_desc_valid (s_axis_read_desc_valid), + .s_axis_read_desc_ready (s_axis_read_desc_ready), + .m_axis_read_desc (s_axis_read_desc_if) + ); + + // wrapper read descriptor status interface -> cocotb flat status + axi_dma_read_desc_status_if_to_flat #( + .TAG_W (TAG_WIDTH) + ) u_m_axis_read_desc_status_if_to_flat ( + .s_axis_read_desc_status (m_axis_read_desc_status_if), + .m_axis_read_desc_status_tag (m_axis_read_desc_status_tag), + .m_axis_read_desc_status_error (m_axis_read_desc_status_error), + .m_axis_read_desc_status_valid (m_axis_read_desc_status_valid) + ); + + // cocotb flat write descriptor -> interface + axi_dma_write_desc_flat_to_if #( + .ADDR_W (AXI_ADDR_WIDTH), + .LEN_W (LEN_WIDTH), + .TAG_W (TAG_WIDTH) + ) u_s_axis_write_desc_flat_to_if ( + .s_axis_write_desc_addr (s_axis_write_desc_addr), + .s_axis_write_desc_len (s_axis_write_desc_len), + .s_axis_write_desc_tag (s_axis_write_desc_tag), + .s_axis_write_desc_valid (s_axis_write_desc_valid), + .s_axis_write_desc_ready (s_axis_write_desc_ready), + .m_axis_write_desc (s_axis_write_desc_if) + ); + + // wrapper write descriptor status interface -> cocotb flat status + axi_dma_write_desc_status_if_to_flat #( + .LEN_W (LEN_WIDTH), + .TAG_W (TAG_WIDTH), + .ID_W (AXIS_ID_WIDTH), + .DEST_W (AXIS_DEST_WIDTH), + .USER_W (AXIS_USER_WIDTH) + ) u_m_axis_write_desc_status_if_to_flat ( + .s_axis_write_desc_status (m_axis_write_desc_status_if), + .m_axis_write_desc_status_len (m_axis_write_desc_status_len), + .m_axis_write_desc_status_tag (m_axis_write_desc_status_tag), + .m_axis_write_desc_status_id (m_axis_write_desc_status_id), + .m_axis_write_desc_status_dest (m_axis_write_desc_status_dest), + .m_axis_write_desc_status_user (m_axis_write_desc_status_user), + .m_axis_write_desc_status_error (m_axis_write_desc_status_error), + .m_axis_write_desc_status_valid (m_axis_write_desc_status_valid) + ); + + // cocotb flat write stream -> interface + axis_flat_to_if #( + .DATA_W (AXIS_DATA_WIDTH), + .KEEP_W (AXIS_KEEP_WIDTH), + .ID_W (AXIS_ID_WIDTH), + .DEST_W (AXIS_DEST_WIDTH), + .USER_W (AXIS_USER_WIDTH) + ) u_s_axis_write_data_flat_to_if ( + .s_axis_tdata (s_axis_write_data_tdata), + .s_axis_tkeep (s_axis_write_data_tkeep), + .s_axis_tstrb (s_axis_write_data_tstrb), + .s_axis_tlast (s_axis_write_data_tlast), + .s_axis_tid (s_axis_write_data_tid), + .s_axis_tdest (s_axis_write_data_tdest), + .s_axis_tuser (s_axis_write_data_tuser), + .s_axis_tvalid (s_axis_write_data_tvalid), + .s_axis_tready (s_axis_write_data_tready), + .m_axis (s_axis_write_data_if) + ); + + // wrapper read stream interface -> cocotb flat stream + axis_if_to_flat #( + .DATA_W (AXIS_DATA_WIDTH), + .KEEP_W (AXIS_KEEP_WIDTH), + .ID_W (AXIS_ID_WIDTH), + .DEST_W (AXIS_DEST_WIDTH), + .USER_W (AXIS_USER_WIDTH) + ) u_m_axis_read_data_if_to_flat ( + .s_axis (m_axis_read_data_if), + .m_axis_tdata (m_axis_read_data_tdata), + .m_axis_tkeep (m_axis_read_data_tkeep), + .m_axis_tstrb (m_axis_read_data_tstrb), + .m_axis_tlast (m_axis_read_data_tlast), + .m_axis_tid (m_axis_read_data_tid), + .m_axis_tdest (m_axis_read_data_tdest), + .m_axis_tuser (m_axis_read_data_tuser), + .m_axis_tvalid (m_axis_read_data_tvalid), + .m_axis_tready (m_axis_read_data_tready) + ); + + // wrapper AXI interface -> cocotb flat AXI memory bus + axi4_if_to_flat #( + .ADDR_W (AXI_ADDR_WIDTH), + .DATA_W (AXI_DATA_WIDTH), + .ID_W (AXI_ID_WIDTH), + .USER_W (AXI_USER_WIDTH) + ) u_m_axi_if_to_flat ( + .s_axi (m_axi_if), + + .m_axi_awid (m_axi_awid), + .m_axi_awaddr (m_axi_awaddr), + .m_axi_awlen (m_axi_awlen), + .m_axi_awsize (m_axi_awsize), + .m_axi_awburst (m_axi_awburst), + .m_axi_awlock (m_axi_awlock), + .m_axi_awcache (m_axi_awcache), + .m_axi_awprot (m_axi_awprot), + .m_axi_awqos (m_axi_awqos), + .m_axi_awregion (m_axi_awregion), + .m_axi_awuser (m_axi_awuser), + .m_axi_awvalid (m_axi_awvalid), + .m_axi_awready (m_axi_awready), + + .m_axi_wdata (m_axi_wdata), + .m_axi_wstrb (m_axi_wstrb), + .m_axi_wlast (m_axi_wlast), + .m_axi_wuser (m_axi_wuser), + .m_axi_wvalid (m_axi_wvalid), + .m_axi_wready (m_axi_wready), + + .m_axi_bid (m_axi_bid), + .m_axi_bresp (m_axi_bresp), + .m_axi_buser (m_axi_buser), + .m_axi_bvalid (m_axi_bvalid), + .m_axi_bready (m_axi_bready), + + .m_axi_arid (m_axi_arid), + .m_axi_araddr (m_axi_araddr), + .m_axi_arlen (m_axi_arlen), + .m_axi_arsize (m_axi_arsize), + .m_axi_arburst (m_axi_arburst), + .m_axi_arlock (m_axi_arlock), + .m_axi_arcache (m_axi_arcache), + .m_axi_arprot (m_axi_arprot), + .m_axi_arqos (m_axi_arqos), + .m_axi_arregion (m_axi_arregion), + .m_axi_aruser (m_axi_aruser), + .m_axi_arvalid (m_axi_arvalid), + .m_axi_arready (m_axi_arready), + + .m_axi_rid (m_axi_rid), + .m_axi_rdata (m_axi_rdata), + .m_axi_rresp (m_axi_rresp), + .m_axi_rlast (m_axi_rlast), + .m_axi_ruser (m_axi_ruser), + .m_axi_rvalid (m_axi_rvalid), + .m_axi_rready (m_axi_rready) + ); + + axi_dma_if_wrapper #( + .AXI_DATA_WIDTH (AXI_DATA_WIDTH), + .AXI_ADDR_WIDTH (AXI_ADDR_WIDTH), + .AXI_STRB_WIDTH (AXI_STRB_WIDTH), + .AXI_ID_WIDTH (AXI_ID_WIDTH), + .AXI_USER_WIDTH (AXI_USER_WIDTH), + .AXI_MAX_BURST_LEN (AXI_MAX_BURST_LEN), + .AXIS_DATA_WIDTH (AXIS_DATA_WIDTH), + .AXIS_KEEP_ENABLE (AXIS_KEEP_ENABLE), + .AXIS_KEEP_WIDTH (AXIS_KEEP_WIDTH), + .AXIS_LAST_ENABLE (AXIS_LAST_ENABLE), + .AXIS_ID_ENABLE (AXIS_ID_ENABLE), + .AXIS_ID_WIDTH (AXIS_ID_WIDTH), + .AXIS_DEST_ENABLE (AXIS_DEST_ENABLE), + .AXIS_DEST_WIDTH (AXIS_DEST_WIDTH), + .AXIS_USER_ENABLE (AXIS_USER_ENABLE), + .AXIS_USER_WIDTH (AXIS_USER_WIDTH), + .LEN_WIDTH (LEN_WIDTH), + .TAG_WIDTH (TAG_WIDTH), + .ENABLE_SG (ENABLE_SG), + .ENABLE_UNALIGNED (ENABLE_UNALIGNED) + ) u_dut ( + .clk (clk), + .rst (rst), + + .s_axis_read_desc (s_axis_read_desc_if), + .m_axis_read_desc_status (m_axis_read_desc_status_if), + + .m_axis_read_data (m_axis_read_data_if), + + .s_axis_write_desc (s_axis_write_desc_if), + .m_axis_write_desc_status (m_axis_write_desc_status_if), + + .s_axis_write_data (s_axis_write_data_if), + .m_axi (m_axi_if), + + .read_enable (read_enable), + .write_enable (write_enable), + .write_abort (write_abort) + ); + +endmodule : tb_axi_dma_wrapper + +`default_nettype wire diff --git a/external/external/rtl_libs/axi/tb/axi_dma_wrapper/test_axi_dma_wrapper.py b/external/external/rtl_libs/axi/tb/axi_dma_wrapper/test_axi_dma_wrapper.py new file mode 100644 index 0000000..c43ac9d --- /dev/null +++ b/external/external/rtl_libs/axi/tb/axi_dma_wrapper/test_axi_dma_wrapper.py @@ -0,0 +1,392 @@ +# SPDX-License-Identifier: MIT +""" +Adapted cocotb/pytest tests for tb_axi_dma_wrapper. + +This file is based on alexforencich/verilog-axi/tb/axi_dma/test_axi_dma.py +and keeps the same cocotb-facing flat prefixes. The SystemVerilog test top +routes these flat signals through local axi4_if/axis_if converters and then +through axi_dma_if_wrapper. + +Original copyright: +Copyright (c) 2020 Alex Forencich + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. +""" + +import itertools +import logging +import os + +import cocotb + +try: + import pytest +except ImportError: # pytest is only needed for the optional cocotb-test entrypoint + pytest = None +from cocotb.clock import Clock +from cocotb.triggers import RisingEdge +from cocotb.regression import TestFactory + +from cocotbext.axi import AxiBus, AxiRam +from cocotbext.axi import AxiStreamBus, AxiStreamFrame, AxiStreamSource, AxiStreamSink +from cocotbext.axi.stream import define_stream + + +DescBus, DescTransaction, DescSource, DescSink, DescMonitor = define_stream( + "Desc", + signals=["addr", "len", "tag", "valid", "ready"], + optional_signals=["id", "dest", "user"], +) + +DescStatusBus, DescStatusTransaction, DescStatusSource, DescStatusSink, DescStatusMonitor = define_stream( + "DescStatus", + signals=["tag", "error", "valid"], + optional_signals=["len", "id", "dest", "user"], +) + + +class TB: + def __init__(self, dut): + self.dut = dut + self.log = logging.getLogger("cocotb.tb") + self.log.setLevel(logging.DEBUG) + + cocotb.start_soon(Clock(dut.clk, 10, units="ns").start()) + + # Descriptor/status streams remain flat on purpose: they are specific + # to Forencich DMA, not generic AXIS interfaces in our library. + self.read_desc_source = DescSource( + DescBus.from_prefix(dut, "s_axis_read_desc"), dut.clk, dut.rst + ) + self.read_desc_status_sink = DescStatusSink( + DescStatusBus.from_prefix( + dut, "m_axis_read_desc_status"), dut.clk, dut.rst + ) + self.write_desc_source = DescSource( + DescBus.from_prefix(dut, "s_axis_write_desc"), dut.clk, dut.rst + ) + self.write_desc_status_sink = DescStatusSink( + DescStatusBus.from_prefix( + dut, "m_axis_write_desc_status"), dut.clk, dut.rst + ) + + # Data streams are flat from cocotb's point of view, but the SV top + # sends them through axis_flat_to_if/axis_if_to_flat before/after DUT. + self.read_data_sink = AxiStreamSink( + AxiStreamBus.from_prefix(dut, "m_axis_read_data"), dut.clk, dut.rst + ) + self.write_data_source = AxiStreamSource( + AxiStreamBus.from_prefix( + dut, "s_axis_write_data"), dut.clk, dut.rst + ) + + # AXI memory model. The SV top routes this through the axi4_if adapters. + self.axi_ram = AxiRam(AxiBus.from_prefix( + dut, "m_axi"), dut.clk, dut.rst, size=2**16) + + dut.read_enable.setimmediatevalue(0) + dut.write_enable.setimmediatevalue(0) + dut.write_abort.setimmediatevalue(0) + + def set_idle_generator(self, generator=None): + if generator: + self.write_desc_source.set_pause_generator(generator()) + self.write_data_source.set_pause_generator(generator()) + self.read_desc_source.set_pause_generator(generator()) + self.axi_ram.write_if.b_channel.set_pause_generator(generator()) + self.axi_ram.read_if.r_channel.set_pause_generator(generator()) + + def set_backpressure_generator(self, generator=None): + if generator: + self.read_data_sink.set_pause_generator(generator()) + self.axi_ram.write_if.aw_channel.set_pause_generator(generator()) + self.axi_ram.write_if.w_channel.set_pause_generator(generator()) + self.axi_ram.read_if.ar_channel.set_pause_generator(generator()) + + async def cycle_reset(self): + self.dut.rst.setimmediatevalue(0) + await RisingEdge(self.dut.clk) + await RisingEdge(self.dut.clk) + self.dut.rst.value = 1 + await RisingEdge(self.dut.clk) + await RisingEdge(self.dut.clk) + self.dut.rst.value = 0 + await RisingEdge(self.dut.clk) + await RisingEdge(self.dut.clk) + + +async def run_test_write(dut, data_in=None, idle_inserter=None, backpressure_inserter=None): + """DMA write path stress test adapted from Forencich's axi_dma test.""" + tb = TB(dut) + + byte_lanes = tb.axi_ram.write_if.byte_lanes + step_size = 1 if int( + os.getenv("PARAM_ENABLE_UNALIGNED", "0")) else byte_lanes + tag_count = 2 ** len(tb.write_desc_source.bus.tag) + cur_tag = 1 + + await tb.cycle_reset() + + tb.set_idle_generator(idle_inserter) + tb.set_backpressure_generator(backpressure_inserter) + + dut.write_enable.value = 1 + + for length in list(range(1, byte_lanes * 4 + 1)) + [128]: + offsets = list(range(0, byte_lanes * 2, step_size)) + offsets += list(range(4096 - byte_lanes * 2, 4096, step_size)) + + for offset in offsets: + for diff in [-8, -2, -1, 0, 1, 2, 8]: + if length + diff < 1: + continue + + tb.log.info("write: length=%d offset=%d diff=%d", + length, offset, diff) + + addr = offset + 0x1000 + expected_data = bytearray([x % 256 for x in range(length)]) + stream_data = bytearray( + [x % 256 for x in range(length + diff)]) + + tb.axi_ram.write(addr - 128, b"\xaa" * + (len(expected_data) + 256)) + + await tb.write_desc_source.send( + DescTransaction(addr=addr, len=len( + expected_data), tag=cur_tag) + ) + await tb.write_data_source.send(AxiStreamFrame(stream_data, tid=cur_tag)) + + status = await tb.write_desc_status_sink.recv() + tb.log.info("write status: %s", status) + + transferred_len = min(len(expected_data), len(stream_data)) + + assert int(status.len) == transferred_len + assert int(status.tag) == cur_tag + assert int(status.id) == cur_tag + assert int(status.error) == 0 + + tb.log.debug( + "%s", + tb.axi_ram.hexdump_str( + (addr & ~0xF) - 16, + (((addr & 0xF) + length - 1) & ~0xF) + 48, + ), + ) + + if len(expected_data) <= len(stream_data): + assert tb.axi_ram.read(addr - 8, len(expected_data) + 16) == ( + b"\xaa" * 8 + expected_data + b"\xaa" * 8 + ) + else: + assert tb.axi_ram.read(addr - 8, len(stream_data) + 16) == ( + b"\xaa" * 8 + stream_data + b"\xaa" * 8 + ) + + cur_tag = (cur_tag + 1) % tag_count + + await RisingEdge(dut.clk) + await RisingEdge(dut.clk) + + +async def run_test_read(dut, data_in=None, idle_inserter=None, backpressure_inserter=None): + """DMA read path stress test adapted from Forencich's axi_dma test.""" + tb = TB(dut) + + byte_lanes = tb.axi_ram.read_if.byte_lanes + step_size = 1 if int( + os.getenv("PARAM_ENABLE_UNALIGNED", "0")) else byte_lanes + tag_count = 2 ** len(tb.read_desc_source.bus.tag) + cur_tag = 1 + + await tb.cycle_reset() + + tb.set_idle_generator(idle_inserter) + tb.set_backpressure_generator(backpressure_inserter) + + dut.read_enable.value = 1 + + for length in list(range(1, byte_lanes * 4 + 1)) + [128]: + offsets = list(range(0, byte_lanes * 2, step_size)) + offsets += list(range(4096 - byte_lanes * 2, 4096, step_size)) + + for offset in offsets: + tb.log.info("read: length=%d offset=%d", length, offset) + + addr = offset + 0x1000 + test_data = bytearray([x % 256 for x in range(length)]) + + tb.axi_ram.write(addr - 128, b"\xaa" * (len(test_data) + 256)) + tb.axi_ram.write(addr, test_data) + + tb.log.debug( + "%s", + tb.axi_ram.hexdump_str( + (addr & ~0xF) - 16, + (((addr & 0xF) + length - 1) & ~0xF) + 48, + ), + ) + + await tb.read_desc_source.send( + DescTransaction(addr=addr, len=len( + test_data), tag=cur_tag, id=cur_tag) + ) + + status = await tb.read_desc_status_sink.recv() + read_data = await tb.read_data_sink.recv() + + tb.log.info("read status: %s", status) + tb.log.info("read data: %s", read_data) + + assert int(status.tag) == cur_tag + assert int(status.error) == 0 + assert read_data.tdata == test_data + assert int(read_data.tid) == cur_tag + + cur_tag = (cur_tag + 1) % tag_count + + await RisingEdge(dut.clk) + await RisingEdge(dut.clk) + + +def cycle_pause(): + return itertools.cycle([1, 1, 1, 0]) + + +# When imported by cocotb inside a simulator, generate the actual cocotb tests. +if cocotb.SIM_NAME: + for test in [run_test_write, run_test_read]: + factory = TestFactory(test) + factory.add_option("idle_inserter", [None, cycle_pause]) + factory.add_option("backpressure_inserter", [None, cycle_pause]) + factory.generate_tests() + + +# ----------------------------------------------------------------------------- +# Optional pytest entrypoint via cocotb-test. +# Run from this directory with: pytest -q test_axi_dma_wrapper.py +# ----------------------------------------------------------------------------- + + +def _sanitize_node_name(name): + return name.replace("[", "-").replace("]", "").replace("/", "_") + + +if pytest is not None: + @pytest.mark.parametrize("axi_data_width", [8, 16, 32]) + @pytest.mark.parametrize("unaligned", [0, 1]) + def test_axi_dma_wrapper_pytest(request, axi_data_width, unaligned): + import cocotb_test.simulator + + tests_dir = os.path.abspath(os.path.dirname(__file__)) + project_root = os.path.abspath(os.path.join(tests_dir, "..", "..")) + + axi_if_rtl_dir = os.environ.get( + "AXI_IF_RTL_DIR", os.path.join(project_root, "rtl", "axi") + ) + dma_if_rtl_dir = os.environ.get( + "DMA_IF_RTL_DIR", os.path.join(project_root, "rtl", "dma") + ) + wrapper_rtl_dir = os.environ.get( + "WRAPPER_RTL_DIR", os.path.join(project_root, "rtl", "wrappers") + ) + forencich_rtl_dir = os.environ.get( + "FORENCICH_AXI_RTL_DIR", + os.path.join(project_root, "external", "verilog-axi", "rtl"), + ) + + dut = "tb_axi_dma_wrapper" + module = os.path.splitext(os.path.basename(__file__))[0] + toplevel = dut + + parameters = { + "AXI_DATA_WIDTH": axi_data_width, + "AXI_ADDR_WIDTH": 16, + "AXI_ID_WIDTH": 8, + "AXI_USER_WIDTH": 1, + "AXI_MAX_BURST_LEN": 16, + "AXIS_ID_ENABLE": 1, + "AXIS_ID_WIDTH": 8, + "AXIS_DEST_ENABLE": 0, + "AXIS_DEST_WIDTH": 8, + "AXIS_USER_ENABLE": 1, + "AXIS_USER_WIDTH": 1, + "LEN_WIDTH": 20, + "TAG_WIDTH": 8, + "ENABLE_SG": 0, + "ENABLE_UNALIGNED": unaligned, + } + + parameters["AXI_STRB_WIDTH"] = parameters["AXI_DATA_WIDTH"] // 8 + parameters["AXIS_DATA_WIDTH"] = parameters["AXI_DATA_WIDTH"] + parameters["AXIS_KEEP_ENABLE"] = int(parameters["AXIS_DATA_WIDTH"] > 8) + parameters["AXIS_KEEP_WIDTH"] = parameters["AXIS_DATA_WIDTH"] // 8 + parameters["AXIS_LAST_ENABLE"] = 1 + + verilog_sources = [ + os.path.join(axi_if_rtl_dir, "axi_pkg.sv"), + os.path.join(axi_if_rtl_dir, "axi_if.sv"), + os.path.join(axi_if_rtl_dir, "axis_if.sv"), + os.path.join(axi_if_rtl_dir, "axi4_flat_to_if.sv"), + os.path.join(axi_if_rtl_dir, "axi4_if_to_flat.sv"), + os.path.join(axi_if_rtl_dir, "axis_flat_to_if.sv"), + os.path.join(axi_if_rtl_dir, "axis_if_to_flat.sv"), + os.path.join(dma_if_rtl_dir, "axi_dma_desc_if.sv"), + os.path.join(dma_if_rtl_dir, "axi_dma_read_desc_flat_to_if.sv"), + os.path.join(dma_if_rtl_dir, "axi_dma_read_desc_if_to_flat.sv"), + os.path.join(dma_if_rtl_dir, + "axi_dma_read_desc_status_flat_to_if.sv"), + os.path.join(dma_if_rtl_dir, + "axi_dma_read_desc_status_if_to_flat.sv"), + os.path.join(dma_if_rtl_dir, "axi_dma_write_desc_flat_to_if.sv"), + os.path.join(dma_if_rtl_dir, "axi_dma_write_desc_if_to_flat.sv"), + os.path.join(dma_if_rtl_dir, + "axi_dma_write_desc_status_flat_to_if.sv"), + os.path.join(dma_if_rtl_dir, + "axi_dma_write_desc_status_if_to_flat.sv"), + os.path.join(forencich_rtl_dir, "axi_dma.v"), + os.path.join(forencich_rtl_dir, "axi_dma_rd.v"), + os.path.join(forencich_rtl_dir, "axi_dma_wr.v"), + os.path.join(wrapper_rtl_dir, "axi_dma_if_wrapper.sv"), + os.path.join(tests_dir, "tb_axi_dma_wrapper.sv"), + ] + + extra_env = {f"PARAM_{k}": str(v) for k, v in parameters.items()} + sim_build = os.path.join( + tests_dir, "sim_build", _sanitize_node_name(request.node.name)) + + extra_args = [] + if os.getenv("SIM", "verilator") == "verilator": + extra_args += ["--trace-structs"] + + cocotb_test.simulator.run( + python_search=[tests_dir], + verilog_sources=verilog_sources, + includes=[axi_if_rtl_dir, dma_if_rtl_dir, + wrapper_rtl_dir, forencich_rtl_dir], + toplevel=toplevel, + module=module, + parameters=parameters, + sim_build=sim_build, + extra_env=extra_env, + waves=bool(int(os.getenv("WAVES", "0"))), + extra_args=extra_args, + ) diff --git a/external/external/rtl_libs/axi/tb/axil_reg_cocotb/Makefile b/external/external/rtl_libs/axi/tb/axil_reg_cocotb/Makefile new file mode 100644 index 0000000..5d37d39 --- /dev/null +++ b/external/external/rtl_libs/axi/tb/axil_reg_cocotb/Makefile @@ -0,0 +1,34 @@ +# SPDX-License-Identifier: MIT + +TOPLEVEL_LANG = verilog +SIM ?= verilator + +PWD := $(shell pwd) + +# Directory with axi_pkg.sv, axi_if.sv and axi4l_reg_map.sv. +# Override it from command line if your tree is different: +# make SIM=verilator RTL_DIR=/path/to/rtl_libs/axi +RTL_DIR ?= $(PWD)/../../../axi +TB_DIR ?= $(PWD) + +TOPLEVEL = tb_axi4l_reg_map +MODULE = test_axi4l_reg_map + +export PYTHONPATH := $(TB_DIR):$(PYTHONPATH) + +VERILOG_SOURCES += $(RTL_DIR)/rtl/axi_pkg.sv +VERILOG_SOURCES += $(RTL_DIR)/rtl/axi_if.sv +VERILOG_SOURCES += $(RTL_DIR)/axi_reg/axi4l_reg_map.sv +VERILOG_SOURCES += $(TB_DIR)/tb_axi4l_reg_map.sv + +COMPILE_ARGS += -I$(RTL_DIR) + +ifeq ($(SIM),verilator) +EXTRA_ARGS += --trace +EXTRA_ARGS += --trace-structs +EXTRA_ARGS += --public-flat-rw +EXTRA_ARGS += -Wno-fatal +EXTRA_ARGS += --timing +endif + +include $(shell cocotb-config --makefiles)/Makefile.sim diff --git a/external/external/rtl_libs/axi/tb/axil_reg_cocotb/tb_axi4l_reg_map.sv b/external/external/rtl_libs/axi/tb/axil_reg_cocotb/tb_axi4l_reg_map.sv new file mode 100644 index 0000000..278f20b --- /dev/null +++ b/external/external/rtl_libs/axi/tb/axil_reg_cocotb/tb_axi4l_reg_map.sv @@ -0,0 +1,165 @@ +module tb_axi4l_reg_map; + + localparam int unsigned ADDR_W = 16; + localparam int unsigned DATA_W = 32; + localparam int unsigned USER_W = 1; + localparam int unsigned N_REGS = 3; + + localparam logic [2:0] REG_BIT_RSVD = 3'd0; + localparam logic [2:0] REG_BIT_RO = 3'd1; + localparam logic [2:0] REG_BIT_RW = 3'd2; + localparam logic [2:0] REG_BIT_W1S = 3'd3; + localparam logic [2:0] REG_BIT_W1C = 3'd4; + + function automatic logic [N_REGS-1:0][31:0][2:0] make_reg_mode(); + logic [N_REGS-1:0][31:0][2:0] mode; + + mode = '{default: REG_BIT_RSVD}; + + // REG0 - 0x00: mixed control register + // bit 0 : W1S + // bit 1 : RW + // bit 2 : W1C + mode[0][0] = REG_BIT_W1S; + mode[0][1] = REG_BIT_RW; + mode[0][2] = REG_BIT_W1C; + + // REG1 - 0x04: status register + // bit 0 : RO busy + // bits 15:8 : RO error_code + mode[1][0] = REG_BIT_RO; + for (int i = 8; i < 16; i++) begin + mode[1][i] = REG_BIT_RO; + end + + // REG2 - 0x08: full RW config register + for (int i = 0; i < 32; i++) begin + mode[2][i] = REG_BIT_RW; + end + + return mode; + endfunction + + function automatic logic [N_REGS-1:0][31:0] make_reg_rst(); + logic [N_REGS-1:0][31:0] rst; + + rst = '{default: 32'h0000_0000}; + rst[0] = 32'h0000_0004; // W1C sticky bit starts set + rst[2] = 32'h1234_5678; // RW config reset value + + return rst; + endfunction + + localparam logic [N_REGS-1:0][31:0][2:0] REG_MODE = make_reg_mode(); + localparam logic [N_REGS-1:0][31:0] REG_RST = make_reg_rst(); + + logic clk = 1'b0; + logic rst = 1'b0; + logic rst_n; + + assign rst_n = ~rst; + + always #5ns clk = ~clk; + + // flat axil + logic [ADDR_W-1:0] s_axil_awaddr; + logic [2:0] s_axil_awprot; + logic s_axil_awvalid; + logic s_axil_awready; + + logic [DATA_W-1:0] s_axil_wdata; + logic [DATA_W/8-1:0] s_axil_wstrb; + logic s_axil_wvalid; + logic s_axil_wready; + + logic [1:0] s_axil_bresp; + logic s_axil_bvalid; + logic s_axil_bready; + + logic [ADDR_W-1:0] s_axil_araddr; + logic [2:0] s_axil_arprot; + logic s_axil_arvalid; + logic s_axil_arready; + + logic [DATA_W-1:0] s_axil_rdata; + logic [1:0] s_axil_rresp; + logic s_axil_rvalid; + logic s_axil_rready; + + // simple external status inputs driven from cocotb + logic busy_i; + logic [7:0] error_code_i; + + logic [N_REGS-1:0][31:0] reg_i; + logic [N_REGS-1:0][31:0] reg_o; + logic [N_REGS-1:0][31:0] reg_pulse; + + // debug probes visible from cocotb. they are useful for checking W1S pulse-like behavior + logic [31:0] reg0_o; + logic [31:0] reg1_o; + logic [31:0] reg2_o; + + assign reg0_o = reg_o[0]; + assign reg1_o = reg_o[1]; + assign reg2_o = reg_o[2]; + + always_comb begin + reg_i = '0; + reg_i[1][0] = busy_i; + reg_i[1][15:8] = error_code_i; + end + + axi4l_if #( + .ADDR_W(ADDR_W), + .DATA_W(DATA_W), + .USER_W(USER_W) + ) s_axil_if ( + .aclk (clk), + .aresetn (rst_n) + ); + + + assign s_axil_if.req.aw.addr = s_axil_awaddr; + assign s_axil_if.req.aw.prot = s_axil_awprot; + assign s_axil_if.req.aw.user = '0; + assign s_axil_if.req.aw.valid = s_axil_awvalid; + assign s_axil_awready = s_axil_if.resp.aw_ready; + + assign s_axil_if.req.w.data = s_axil_wdata; + assign s_axil_if.req.w.strb = s_axil_wstrb; + assign s_axil_if.req.w.user = '0; + assign s_axil_if.req.w.valid = s_axil_wvalid; + assign s_axil_wready = s_axil_if.resp.w_ready; + + assign s_axil_bresp = s_axil_if.resp.b.resp; + assign s_axil_bvalid = s_axil_if.resp.b.valid; + assign s_axil_if.req.b_ready = s_axil_bready; + + assign s_axil_if.req.ar.addr = s_axil_araddr; + assign s_axil_if.req.ar.prot = s_axil_arprot; + assign s_axil_if.req.ar.user = '0; + assign s_axil_if.req.ar.valid = s_axil_arvalid; + assign s_axil_arready = s_axil_if.resp.ar_ready; + + assign s_axil_rdata = s_axil_if.resp.r.data; + assign s_axil_rresp = s_axil_if.resp.r.resp; + assign s_axil_rvalid = s_axil_if.resp.r.valid; + assign s_axil_if.req.r_ready = s_axil_rready; + + axi4l_reg_map #( + .ADDR_W (ADDR_W), + .DATA_W (DATA_W), + .USER_W (USER_W), + .N_REGS (N_REGS), + .REG_MODE(REG_MODE), + .REG_RST (REG_RST) + ) u_reg_map ( + .clk (clk), + .rst_n (rst_n), + .s_axil (s_axil_if.slave), + .reg_i (reg_i), + .reg_o (reg_o), + .reg_pulse(reg_pulse) + ); + +endmodule diff --git a/external/external/rtl_libs/axi/tb/axil_reg_cocotb/test_axi4l_reg_map.py b/external/external/rtl_libs/axi/tb/axil_reg_cocotb/test_axi4l_reg_map.py new file mode 100644 index 0000000..5c7b411 --- /dev/null +++ b/external/external/rtl_libs/axi/tb/axil_reg_cocotb/test_axi4l_reg_map.py @@ -0,0 +1,310 @@ +import cocotb +from cocotb.clock import Clock +from cocotb.triggers import ReadOnly, RisingEdge +from cocotbext.axi import AxiLiteBus, AxiLiteMaster + +OKAY = 0 +SLVERR = 2 + +REG0_CTRL = 0x00 +REG1_STATUS = 0x04 +REG2_CONFIG = 0x08 +REG_INVALID = 0x0C # N_REGS=3, so index 3 is bad + + +def _resp_code(resp): + """Return integer AXI response code from a cocotbext-axi response object.""" + if resp is None: + return OKAY + + value = getattr(resp, "resp", OKAY) + + # common guards + try: + return int(value) + except TypeError: + return int(value.integer) + + +def _read_data(resp): + return int.from_bytes(bytes(resp.data), "little") + + +class TB: + def __init__(self, dut): + self.dut = dut + self.axil = AxiLiteMaster(AxiLiteBus.from_prefix( + dut, "s_axil"), dut.clk, dut.rst) + + async def reset(self): + self.dut.rst.value = 1 + self.dut.busy_i.value = 0 + self.dut.error_code_i.value = 0 + + for _ in range(5): + await RisingEdge(self.dut.clk) + + self.dut.rst.value = 0 + + for _ in range(5): + await RisingEdge(self.dut.clk) + + # shortcuts sorta + async def write32(self, addr, value, expected_resp=OKAY): + resp = await self.axil.write(addr, value.to_bytes(4, "little")) + assert _resp_code(resp) == expected_resp, ( + f"write addr=0x{addr:08x}: expected resp {expected_resp}, got {_resp_code(resp)}" + ) + return resp + + async def read32(self, addr, expected_resp=OKAY): + resp = await self.axil.read(addr, 4) + assert _resp_code(resp) == expected_resp, ( + f"read addr=0x{addr:08x}: expected resp {expected_resp}, got {_resp_code(resp)}" + ) + return _read_data(resp) + + +@cocotb.test() +async def test_reset_and_basic_reads(dut): + """Check reset values and RO status path via reg_i.""" + cocotb.start_soon(Clock(dut.clk, 10, units="ns").start()) + tb = TB(dut) + await tb.reset() + + # REG0 reset: W1C sticky bit set. W1S reads as 0, RW reads from reg_o + assert await tb.read32(REG0_CTRL) == 0x00000004 + + # REG2 is a normal RW config register with non-zero reset value + assert await tb.read32(REG2_CONFIG) == 0x12345678 + + # Drive external status and read it through RO bits + dut.busy_i.value = 1 + dut.error_code_i.value = 0x5A + await RisingEdge(dut.clk) + + assert await tb.read32(REG1_STATUS) == 0x00005A01 + + +@cocotb.test() +async def test_rw_and_w1c_bits(dut): + """Check RW bit update and W1C sticky clear behavior.""" + cocotb.start_soon(Clock(dut.clk, 10, units="ns").start()) + tb = TB(dut) + await tb.reset() + + # Initial REG0: bit2 W1C is set, bit1 RW is clear, bit0 W1S reads as 0 + assert await tb.read32(REG0_CTRL) == 0x00000004 + + # Set RW bit1 while preserving W1C bit2 + await tb.write32(REG0_CTRL, 0x00000002) + assert await tb.read32(REG0_CTRL) == 0x00000006 + + # Write 1 to W1C bit2, keep RW bit1 set + await tb.write32(REG0_CTRL, 0x00000006) + assert await tb.read32(REG0_CTRL) == 0x00000002 + + # Write zero clears the RW bit because REG0 is a normal word write for RW fields + await tb.write32(REG0_CTRL, 0x00000000) + assert await tb.read32(REG0_CTRL) == 0x00000000 + + # Full RW register write/read + await tb.write32(REG2_CONFIG, 0xDEADBEEF) + assert await tb.read32(REG2_CONFIG) == 0xDEADBEEF + + +def _reg0_pulse_value(dut): + """Return REG0 pulse bits regardless of how the test wrapper exposes them.""" + if hasattr(dut, "reg0_pulse"): + return int(dut.reg0_pulse.value) + + if hasattr(dut, "reg_pulse"): + # Packed SystemVerilog array [N_REGS-1:0][31:0]: REG0 occupies bits 31:0. + return int(dut.reg_pulse.value) & 0xFFFF_FFFF + + raise AssertionError( + "DUT must expose either reg0_pulse[31:0] or packed reg_pulse" + ) + + +async def _sample_reg0_pulse_cycles(dut, cycles): + """Sample REG0 pulse output after each active clock edge.""" + samples = [] + + for _ in range(cycles): + await RisingEdge(dut.clk) + await ReadOnly() + samples.append(_reg0_pulse_value(dut)) + + return samples + + +def _assert_single_cycle_bit_pulse(samples, bit, name): + """Check that one selected bit was high for exactly one sampled cycle.""" + high_cycles = [ + index for index, value in enumerate(samples) + if value & (1 << bit) + ] + assert len(high_cycles) == 1, ( + f"{name}: expected one high cycle, got {len(high_cycles)}; " + f"samples={[f'0x{value:08x}' for value in samples]}" + ) + return high_cycles[0] + + +@cocotb.test() +async def test_reg_pulse_is_zero_after_reset(dut): + """No W1 event may be reported after reset without a write.""" + cocotb.start_soon(Clock(dut.clk, 10, units="ns").start()) + tb = TB(dut) + await tb.reset() + + samples = await _sample_reg0_pulse_cycles(dut, 4) + assert not any(samples), ( + "reg_pulse was asserted without a W1 write: " + f"{[f'0x{value:08x}' for value in samples]}" + ) + + +@cocotb.test() +async def test_w1s_generates_single_cycle_reg_pulse(dut): + """Writing 1 to REG0[0] W1S must pulse REG0 pulse bit 0 once.""" + cocotb.start_soon(Clock(dut.clk, 10, units="ns").start()) + tb = TB(dut) + await tb.reset() + + monitor = cocotb.start_soon(_sample_reg0_pulse_cycles(dut, 20)) + await tb.write32(REG0_CTRL, 0x00000001) + samples = await monitor + + _assert_single_cycle_bit_pulse(samples, bit=0, name="reg_pulse[0][0]") + + # No unrelated W1 bit may pulse. + assert not any(value & (1 << 2) for value in samples) + + # W1S is a command bit and is not returned by reads. + assert await tb.read32(REG0_CTRL) == 0x00000004 + + +@cocotb.test() +async def test_w1c_generates_single_cycle_reg_pulse(dut): + """Writing 1 to REG0[2] W1C must pulse bit 2 once and clear state.""" + cocotb.start_soon(Clock(dut.clk, 10, units="ns").start()) + tb = TB(dut) + await tb.reset() + + assert await tb.read32(REG0_CTRL) == 0x00000004 + + monitor = cocotb.start_soon(_sample_reg0_pulse_cycles(dut, 20)) + await tb.write32(REG0_CTRL, 0x00000004) + samples = await monitor + + _assert_single_cycle_bit_pulse(samples, bit=2, name="reg_pulse[0][2]") + + # No unrelated W1 bit may pulse. + assert not any(value & (1 << 0) for value in samples) + + assert await tb.read32(REG0_CTRL) == 0x00000000 + + +@cocotb.test() +async def test_zero_to_w1_and_rw_write_do_not_generate_reg_pulse(dut): + """Only written ones in W1 fields may create reg_pulse.""" + cocotb.start_soon(Clock(dut.clk, 10, units="ns").start()) + tb = TB(dut) + await tb.reset() + + monitor = cocotb.start_soon(_sample_reg0_pulse_cycles(dut, 20)) + + # bit1 is RW; both W1 fields receive zero. + await tb.write32(REG0_CTRL, 0x00000002) + samples = await monitor + + assert not any(samples), ( + "RW write or zero written to W1 fields generated reg_pulse: " + f"{[f'0x{value:08x}' for value in samples]}" + ) + assert await tb.read32(REG0_CTRL) == 0x00000006 + + +@cocotb.test() +async def test_w1s_and_w1c_pulse_together(dut): + """W1S and W1C ones in one AXI write must pulse on the same cycle.""" + cocotb.start_soon(Clock(dut.clk, 10, units="ns").start()) + tb = TB(dut) + await tb.reset() + + monitor = cocotb.start_soon(_sample_reg0_pulse_cycles(dut, 20)) + await tb.write32(REG0_CTRL, 0x00000005) + samples = await monitor + + w1s_cycle = _assert_single_cycle_bit_pulse( + samples, bit=0, name="reg_pulse[0][0]" + ) + w1c_cycle = _assert_single_cycle_bit_pulse( + samples, bit=2, name="reg_pulse[0][2]" + ) + + assert w1s_cycle == w1c_cycle, ( + "W1 bits written by one transaction pulsed on different cycles: " + f"W1S={w1s_cycle}, W1C={w1c_cycle}" + ) + + # Only bits 0 and 2 are allowed to pulse. + assert samples[w1s_cycle] == 0x00000005 + assert await tb.read32(REG0_CTRL) == 0x00000000 + + +@cocotb.test() +async def test_each_w1_write_creates_a_new_pulse(dut): + """Two separate W1 writes must create two separate one-cycle pulses.""" + cocotb.start_soon(Clock(dut.clk, 10, units="ns").start()) + tb = TB(dut) + await tb.reset() + + monitor = cocotb.start_soon(_sample_reg0_pulse_cycles(dut, 40)) + + await tb.write32(REG0_CTRL, 0x00000001) + for _ in range(3): + await RisingEdge(dut.clk) + await tb.write32(REG0_CTRL, 0x00000001) + + samples = await monitor + high_cycles = [ + index for index, value in enumerate(samples) + if value & 0x1 + ] + + assert len(high_cycles) == 2, ( + f"expected two W1S pulses, got cycles {high_cycles}; " + f"samples={[f'0x{value:08x}' for value in samples]}" + ) + assert high_cycles[1] > high_cycles[0] + 1, ( + f"separate writes did not produce separate pulses: {high_cycles}" + ) + + +@cocotb.test() +async def test_write_to_ro_returns_slverr(dut): + """Writing a RO bit should return SLVERR and should not change status.""" + cocotb.start_soon(Clock(dut.clk, 10, units="ns").start()) + tb = TB(dut) + await tb.reset() + + dut.busy_i.value = 1 + dut.error_code_i.value = 0x33 + await RisingEdge(dut.clk) + + await tb.write32(REG1_STATUS, 0x00000101, expected_resp=SLVERR) + assert await tb.read32(REG1_STATUS) == 0x00003301 + + +@cocotb.test() +async def test_invalid_address_returns_slverr(dut): + """N_REGS=3, so address 0x0C selects index 3 and must fail.""" + cocotb.start_soon(Clock(dut.clk, 10, units="ns").start()) + tb = TB(dut) + await tb.reset() + + await tb.write32(REG_INVALID, 0x11223344, expected_resp=SLVERR) + assert await tb.read32(REG_INVALID, expected_resp=SLVERR) == 0x00000000 diff --git a/external/external/rtl_libs/axi/tb/axis_cocotb_loopback_test/axis_loopback.sv b/external/external/rtl_libs/axi/tb/axis_cocotb_loopback_test/axis_loopback.sv new file mode 100644 index 0000000..2418e78 --- /dev/null +++ b/external/external/rtl_libs/axi/tb/axis_cocotb_loopback_test/axis_loopback.sv @@ -0,0 +1,13 @@ +module axis_loopback #( + parameter int unsigned DATA_W = 64, + parameter int unsigned KEEP_W = DATA_W / 8, + parameter int unsigned ID_W = 8, + parameter int unsigned DEST_W = 8, + parameter int unsigned USER_W = 1 +)( + axis_if.slave s_axis, + axis_if.master m_axis +); + assign m_axis.req = s_axis.req; + assign s_axis.resp = m_axis.resp; +endmodule : axis_loopback