diff --git a/Bender.yml b/Bender.yml index d4b3b7b4..36e428e8 100644 --- a/Bender.yml +++ b/Bender.yml @@ -61,6 +61,14 @@ sources: # Level 2 - src/frontends/register_64bit/idma_reg64_frontend.sv + - files: # 2D 64bit register frontend + # Level 0 + - src/frontends/register_64bit_2d/idma_reg64_2d_frontend_reg_pkg.sv + # Level 1 + - src/frontends/register_64bit_2d/idma_reg64_2d_frontend_reg_top.sv + # Level 2 + - src/frontends/register_64bit_2d/idma_reg64_2d_frontend.sv + - files: # 64bit descriptor frontend # Level 0 - src/frontends/desc64/idma_desc64_reg_pkg.sv diff --git a/Makefile b/Makefile index 2479e7ae..1c19606b 100644 --- a/Makefile +++ b/Makefile @@ -283,12 +283,14 @@ REG32_2D_FE_DIR = src/frontends/register_32bit_2d/ REG32_2D_HJSON = $(REG32_2D_FE_DIR)/idma_reg32_2d_frontend.hjson REG64_FE_DIR = src/frontends/register_64bit/ REG64_HJSON = $(REG64_FE_DIR)/idma_reg64_frontend.hjson +REG64_2D_FE_DIR = src/frontends/register_64bit_2d/ +REG64_2D_HJSON = $(REG64_2D_FE_DIR)/idma_reg64_2d_frontend.hjson DESC64_FE_DIR = src/frontends/desc64/ DESC64_HJSON = $(DESC64_FE_DIR)/idma_desc64_frontend.hjson REG_HTML_STRING = "\n\n\n\n\n" -gen_regs: reg32_2d_regs reg64_regs desc64_regs +gen_regs: reg32_2d_regs reg64_regs desc64_regs reg64_2d_regs reg32_2d_regs: $(PYTHON) $(REG_TOOL) $(REG32_2D_HJSON) -t $(REG32_2D_FE_DIR) -r @@ -306,6 +308,14 @@ reg64_regs: printf "\n" >> $(REG64_FE_DIR)/idma_reg64_frontend.html cp $(REG_PATH)/vendor/lowrisc_opentitan/util/reggen/reg_html.css $(REG64_FE_DIR) +reg64_2d_regs: + $(PYTHON) $(REG_TOOL) $(REG64_2D_HJSON) -t $(REG64_2D_FE_DIR) -r + $(PYTHON) $(REG_TOOL) $(REG64_2D_HJSON) -D > $(REG64_2D_FE_DIR)/idma_reg64_2d_frontend.h + printf $(REG_HTML_STRING) > $(REG64_2D_FE_DIR)/idma_reg64_2d_frontend.html + $(PYTHON) $(REG_TOOL) $(REG64_2D_HJSON) -d >> $(REG64_2D_FE_DIR)/idma_reg64_2d_frontend.html + printf "\n" >> $(REG64_2D_FE_DIR)/idma_reg64_2d_frontend.html + cp $(REG_PATH)/vendor/lowrisc_opentitan/util/reggen/reg_html.css $(REG64_2D_FE_DIR) + desc64_regs: $(PYTHON) $(REG_TOOL) $(DESC64_HJSON) -t $(DESC64_FE_DIR) -r $(PYTHON) $(REG_TOOL) $(DESC64_HJSON) -D > $(DESC64_FE_DIR)/idma_desc64_frontend.h @@ -318,12 +328,20 @@ regs_clean: rm -f $(REG32_2D_FE_DIR)/idma_reg32_2d_frontend.h rm -f $(REG32_2D_FE_DIR)/idma_reg32_2d_frontend_reg_pkg.sv rm -f $(REG32_2D_FE_DIR)/idma_reg32_2d_frontend_reg_top.sv + rm -f $(REG32_2D_FE_DIR)/idma_reg32_2d_frontend.html rm -f $(REG32_2D_FE_DIR)/reg_html.css rm -f $(REG64_FE_DIR)/idma_reg64_frontend.h - rm -f $(REG64_FE_DIR)/idma_reg32_frontend_reg_pkg.sv - rm -f $(REG64_FE_DIR)/idma_reg32_frontend_reg_top.sv + rm -f $(REG64_FE_DIR)/idma_reg64_frontend_reg_pkg.sv + rm -f $(REG64_FE_DIR)/idma_reg64_frontend_reg_top.sv + rm -f $(REG64_FE_DIR)/idma_reg64_frontend.html rm -f $(REG64_FE_DIR)/reg_html.css + rm -f $(REG64_2D_FE_DIR)/idma_reg64_2d_frontend.h + rm -f $(REG64_2D_FE_DIR)/idma_reg64_2d_frontend_reg_pkg.sv + rm -f $(REG64_2D_FE_DIR)/idma_reg64_2d_frontend_reg_top.sv + rm -f $(REG64_2D_FE_DIR)/idma_reg64_2d_frontend.html + rm -f $(REG64_2D_FE_DIR)/reg_html.css rm -f $(DESC64_FE_DIR)/idma_desc64_frontend.h rm -f $(DESC64_FE_DIR)/idma_desc64_reg_pkg.sv rm -f $(DESC64_FE_DIR)/idma_desc64_reg_top.sv + rm -f $(DESC64_FE_DIR)/idma_desc64_frontend.html rm -f $(DESC64_FE_DIR)/reg_html.css diff --git a/src/frontends/register_64bit_2d/idma_reg64_2d_frontend.h b/src/frontends/register_64bit_2d/idma_reg64_2d_frontend.h new file mode 100644 index 00000000..7aa43052 --- /dev/null +++ b/src/frontends/register_64bit_2d/idma_reg64_2d_frontend.h @@ -0,0 +1,57 @@ +// Generated register defines for idma_reg64_2d_frontend + +// Copyright information found in source file: +// Copyright 2022 ETH Zurich and University of Bologna. + +// Licensing information found in source file: +// Licensed under Solderpad Hardware License, Version 0.51 +// SPDX-License-Identifier: SHL-0.51 + +#ifndef _IDMA_REG64_2D_FRONTEND_REG_DEFS_ +#define _IDMA_REG64_2D_FRONTEND_REG_DEFS_ + +#ifdef __cplusplus +extern "C" { +#endif +// Register width +#define IDMA_REG64_2D_FRONTEND_PARAM_REG_WIDTH 64 + +// Source Address +#define IDMA_REG64_2D_FRONTEND_SRC_ADDR_REG_OFFSET 0x0 + +// Destination Address +#define IDMA_REG64_2D_FRONTEND_DST_ADDR_REG_OFFSET 0x8 + +// Number of bytes +#define IDMA_REG64_2D_FRONTEND_NUM_BYTES_REG_OFFSET 0x10 + +// Configuration Register for DMA settings +#define IDMA_REG64_2D_FRONTEND_CONF_REG_OFFSET 0x18 +#define IDMA_REG64_2D_FRONTEND_CONF_DECOUPLE_BIT 0 +#define IDMA_REG64_2D_FRONTEND_CONF_DEBURST_BIT 1 +#define IDMA_REG64_2D_FRONTEND_CONF_SERIALIZE_BIT 2 + +// DMA Status +#define IDMA_REG64_2D_FRONTEND_STATUS_REG_OFFSET 0x20 +#define IDMA_REG64_2D_FRONTEND_STATUS_BUSY_BIT 0 + +// Next ID, launches transfer, returns 0 if transfer not set up properly. +#define IDMA_REG64_2D_FRONTEND_NEXT_ID_REG_OFFSET 0x28 + +// Get ID of finished transactions. +#define IDMA_REG64_2D_FRONTEND_DONE_REG_OFFSET 0x30 + +// Source Stride +#define IDMA_REG64_2D_FRONTEND_STRIDE_SRC_REG_OFFSET 0x38 + +// Destination Stride +#define IDMA_REG64_2D_FRONTEND_STRIDE_DST_REG_OFFSET 0x40 + +// Number of 2D repetitions +#define IDMA_REG64_2D_FRONTEND_NUM_REPETITIONS_REG_OFFSET 0x48 + +#ifdef __cplusplus +} // extern "C" +#endif +#endif // _IDMA_REG64_2D_FRONTEND_REG_DEFS_ +// End generated register defines for idma_reg64_2d_frontend \ No newline at end of file diff --git a/src/frontends/register_64bit_2d/idma_reg64_2d_frontend.hjson b/src/frontends/register_64bit_2d/idma_reg64_2d_frontend.hjson new file mode 100644 index 00000000..706addc0 --- /dev/null +++ b/src/frontends/register_64bit_2d/idma_reg64_2d_frontend.hjson @@ -0,0 +1,142 @@ +// Copyright 2022 ETH Zurich and University of Bologna. +// Solderpad Hardware License, Version 0.51, see LICENSE for details. +// SPDX-License-Identifier: SHL-0.51 +// Licensed under Solderpad Hardware License, Version 0.51 + +{ + name: "idma_reg64_2d_frontend", + clock_primary: "clk_i", + reset_primary: "rst_ni", + bus_interfaces: [ + { protocol: "reg_iface", + direction: "device" + } + ], + regwidth: "64", + registers: [ + { name: "src_addr", + desc: "Source Address", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "63:0", + name: "src_addr", + desc: "Source Address" + } + ] + }, + { name: "dst_addr", + desc: "Destination Address", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "63:0", + name: "dst_addr", + desc: "Destination Address" + } + ] + }, + { name: "num_bytes", + desc: "Number of bytes", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "63:0", + name: "num_bytes", + desc: "Number of bytes" + } + ] + }, + { name: "conf", + desc: "Configuration Register for DMA settings", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "0", + name: "decouple", + desc: "Decouple enable" + }, + { bits: "1", + name: "deburst", + desc: "Deburst enable" + }, + { bits: "2", + name: "serialize", + desc: "Serialize enable" + } + ] + }, + { name: "status", + desc: "DMA Status", + swaccess: "ro", + hwaccess: "hwo", + hwext: "true", + fields: [ + { bits: "0", + name: "busy", + desc: "DMA busy" + } + ] + }, + { name: "next_id", + desc: "Next ID, launches transfer, returns 0 if transfer not set up properly.", + swaccess: "ro", + hwaccess: "hrw", + hwext: "true", + hwre: "true", + fields: [ + { bits: "63:0", + name: "next_id", + desc: "Next ID, launches transfer, returns 0 if transfer not set up properly." + } + ] + }, + { name: "done", + desc: "Get ID of finished transactions.", + swaccess: "ro", + hwaccess: "hrw", + hwext: "true", + hwre: "true", + fields: [ + { bits: "63:0", + name: "done", + desc: "Get ID of finished transactions." + } + ] + }, + { name: "stride_src", + desc: "Source Stride", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "63:0", + name: "stride_src", + desc: "Source Stride" + } + ] + }, + { name: "stride_dst" + desc: "Destination Stride", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "63:0", + name: "stride_dst", + desc: "Destination Stride" + } + ] + }, + { name: "num_repetitions" + desc: "Number of 2D repetitions", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "63:0", + name: "num_repetitions", + desc: "Number of 2D repetitions", + resval: "0" + } + ] + } + ] +} diff --git a/src/frontends/register_64bit_2d/idma_reg64_2d_frontend.html b/src/frontends/register_64bit_2d/idma_reg64_2d_frontend.html new file mode 100644 index 00000000..7a635d4e --- /dev/null +++ b/src/frontends/register_64bit_2d/idma_reg64_2d_frontend.html @@ -0,0 +1,190 @@ + + + + + + + + + + +
+
idma_reg64_2d_frontend.src_addr @ 0x0
+

Source Address

+
Reset default = 0x0, mask 0xffffffffffffffff
+
+ + + + + + +
63626160595857565554535251504948
src_addr...
47464544434241403938373635343332
...src_addr...
31302928272625242322212019181716
...src_addr...
1514131211109876543210
...src_addr
BitsTypeResetNameDescription
63:0rwxsrc_addr

Source Address

+
+ + + + + +
+
idma_reg64_2d_frontend.dst_addr @ 0x8
+

Destination Address

+
Reset default = 0x0, mask 0xffffffffffffffff
+
+ + + + + + +
63626160595857565554535251504948
dst_addr...
47464544434241403938373635343332
...dst_addr...
31302928272625242322212019181716
...dst_addr...
1514131211109876543210
...dst_addr
BitsTypeResetNameDescription
63:0rwxdst_addr

Destination Address

+
+ + + + + +
+
idma_reg64_2d_frontend.num_bytes @ 0x10
+

Number of bytes

+
Reset default = 0x0, mask 0xffffffffffffffff
+
+ + + + + + +
63626160595857565554535251504948
num_bytes...
47464544434241403938373635343332
...num_bytes...
31302928272625242322212019181716
...num_bytes...
1514131211109876543210
...num_bytes
BitsTypeResetNameDescription
63:0rwxnum_bytes

Number of bytes

+
+ + + + + +
+
idma_reg64_2d_frontend.conf @ 0x18
+

Configuration Register for DMA settings

+
Reset default = 0x0, mask 0x7
+
+ + + + + + + + + +
63626160595857565554535251504948
 
47464544434241403938373635343332
 
31302928272625242322212019181716
 
1514131211109876543210
 serializedeburstdecouple
BitsTypeResetNameDescription
0rwxdecouple

Decouple enable

1rwxdeburst

Deburst enable

2rwxserialize

Serialize enable

+
+ + + + + +
+
idma_reg64_2d_frontend.status @ 0x20
+

DMA Status

+
Reset default = 0x0, mask 0x1
+
+ + + + + + + +
63626160595857565554535251504948
 
47464544434241403938373635343332
 
31302928272625242322212019181716
 
1514131211109876543210
 busy
BitsTypeResetNameDescription
0roxbusy

DMA busy

+
+ + + + + +
+
idma_reg64_2d_frontend.next_id @ 0x28
+

Next ID, launches transfer, returns 0 if transfer not set up properly.

+
Reset default = 0x0, mask 0xffffffffffffffff
+
+ + + + + + +
63626160595857565554535251504948
next_id...
47464544434241403938373635343332
...next_id...
31302928272625242322212019181716
...next_id...
1514131211109876543210
...next_id
BitsTypeResetNameDescription
63:0roxnext_id

Next ID, launches transfer, returns 0 if transfer not set up properly.

+
+ + + + + +
+
idma_reg64_2d_frontend.done @ 0x30
+

Get ID of finished transactions.

+
Reset default = 0x0, mask 0xffffffffffffffff
+
+ + + + + + +
63626160595857565554535251504948
done...
47464544434241403938373635343332
...done...
31302928272625242322212019181716
...done...
1514131211109876543210
...done
BitsTypeResetNameDescription
63:0roxdone

Get ID of finished transactions.

+
+ + + + + +
+
idma_reg64_2d_frontend.stride_src @ 0x38
+

Source Stride

+
Reset default = 0x0, mask 0xffffffffffffffff
+
+ + + + + + +
63626160595857565554535251504948
stride_src...
47464544434241403938373635343332
...stride_src...
31302928272625242322212019181716
...stride_src...
1514131211109876543210
...stride_src
BitsTypeResetNameDescription
63:0rwxstride_src

Source Stride

+
+ + + + + +
+
idma_reg64_2d_frontend.stride_dst @ 0x40
+

Destination Stride

+
Reset default = 0x0, mask 0xffffffffffffffff
+
+ + + + + + +
63626160595857565554535251504948
stride_dst...
47464544434241403938373635343332
...stride_dst...
31302928272625242322212019181716
...stride_dst...
1514131211109876543210
...stride_dst
BitsTypeResetNameDescription
63:0rwxstride_dst

Destination Stride

+
+ + + + + +
+
idma_reg64_2d_frontend.num_repetitions @ 0x48
+

Number of 2D repetitions

+
Reset default = 0x0, mask 0xffffffffffffffff
+
+ + + + + + +
63626160595857565554535251504948
num_repetitions...
47464544434241403938373635343332
...num_repetitions...
31302928272625242322212019181716
...num_repetitions...
1514131211109876543210
...num_repetitions
BitsTypeResetNameDescription
63:0rw0x0num_repetitions

Number of 2D repetitions

+
+ diff --git a/src/frontends/register_64bit_2d/idma_reg64_2d_frontend.sv b/src/frontends/register_64bit_2d/idma_reg64_2d_frontend.sv new file mode 100644 index 00000000..9b78ba56 --- /dev/null +++ b/src/frontends/register_64bit_2d/idma_reg64_2d_frontend.sv @@ -0,0 +1,163 @@ +// Copyright 2022 ETH Zurich and University of Bologna. +// Solderpad Hardware License, Version 0.51, see LICENSE for details. +// SPDX-License-Identifier: SHL-0.51 +// +// Michael Rogenmoser +// +// Description: 2D DMA frontend module that includes 64bit config and status reg handling + +module idma_reg64_2d_frontend #( + /// register_interface request type + parameter type dma_regs_req_t = logic, + /// register_interface response type + parameter type dma_regs_rsp_t = logic, + /// dma burst request type + parameter type burst_req_t = logic, + parameter type idma_nd_req_t = logic +) ( + input logic clk_i, + input logic rst_ni, + /// register interface control slave + input dma_regs_req_t dma_ctrl_req_i, + output dma_regs_rsp_t dma_ctrl_rsp_o, + /// DMA backend signals + output idma_nd_req_t idma_nd_req_o, + output logic valid_o, + input logic ready_i, + input logic backend_idle_i, + input logic trans_complete_i +); + + localparam int unsigned DmaRegisterWidth = 64; + + /* + * Signal and register definitions + */ + idma_reg64_2d_frontend_reg_pkg::idma_reg64_2d_frontend_reg2hw_t dma_reg2hw; + idma_reg64_2d_frontend_reg_pkg::idma_reg64_2d_frontend_hw2reg_t dma_hw2reg; + + // transaction id + logic [DmaRegisterWidth-1:0] next_id, done_id; + logic issue; + + dma_regs_rsp_t dma_ctrl_rsp_tmp; + + burst_req_t burst_req; + + /* + * DMA registers + */ + idma_reg64_2d_frontend_reg_top #( + .reg_req_t( dma_regs_req_t ), + .reg_rsp_t( dma_regs_rsp_t ) + ) i_dma_conf_regs ( + .clk_i, + .rst_ni, + .reg_req_i ( dma_ctrl_req_i ), + .reg_rsp_o ( dma_ctrl_rsp_tmp ), + .reg2hw ( dma_reg2hw ), + .hw2reg ( dma_hw2reg ), + .devmode_i ( 1'b1 ) // if 1, explicit error return for unmapped register access + ); + + /* + * DMA Control Logic + */ + always_comb begin : proc_process_regs + + // reset state + valid_o = '0; + dma_hw2reg.next_id.d = '0; + dma_hw2reg.done.d = '0; + dma_hw2reg.status.d = ~backend_idle_i; + + dma_ctrl_rsp_o = dma_ctrl_rsp_tmp; + + // start transaction upon next_id read (and having a valid config) + if (dma_reg2hw.next_id.re) begin + if (dma_reg2hw.num_bytes.q != '0) begin + valid_o = 1'b1; + dma_hw2reg.next_id.d = next_id; + dma_ctrl_rsp_o.ready = ready_i; + end + end + + // use full width id from generator + dma_hw2reg.done.d = done_id; + end : proc_process_regs + + + // map hw register onto generic burst request + always_comb begin : hw_req_conv + burst_req = '0; + + burst_req.length = dma_reg2hw.num_bytes.q; + burst_req.src_addr = dma_reg2hw.src_addr.q; + burst_req.dst_addr = dma_reg2hw.dst_addr.q; + + // Current backend only supports one ID + burst_req.opt.axi_id = '0; + // DMA only supports incremental burst + burst_req.opt.src.burst = axi_pkg::BURST_INCR; + // this frontend currently does not support cache variations + burst_req.opt.src.cache = '0; + // AXI4 does not support locked transactions, use atomics + burst_req.opt.src.lock = '0; + // unpriviledged, secure, data access + burst_req.opt.src.prot = '0; + // not participating in qos + burst_req.opt.src.qos = '0; + // only one region + burst_req.opt.src.region = '0; + // DMA only supports incremental burst + burst_req.opt.dst.burst = axi_pkg::BURST_INCR; + // this frontend currently does not support cache variations + burst_req.opt.dst.cache = '0; + // AXI4 does not support locked transactions, use atomics + burst_req.opt.dst.lock = '0; + // unpriviledged, secure, data access + burst_req.opt.dst.prot = '0; + // not participating in qos + burst_req.opt.dst.qos = '0; + // only one region in system + burst_req.opt.dst.region = '0; + // ensure coupled AW to avoid deadlocks + burst_req.opt.beo.decouple_aw = '0; + burst_req.opt.beo.decouple_rw = dma_reg2hw.conf.decouple.q; + // this frontend currently only supports completely debursting + burst_req.opt.beo.src_max_llen = '0; + // this frontend currently only supports completely debursting + burst_req.opt.beo.dst_max_llen = '0; + burst_req.opt.beo.src_reduce_len = dma_reg2hw.conf.deburst.q; + burst_req.opt.beo.dst_reduce_len = dma_reg2hw.conf.deburst.q; + + // serialization no longer supported + // burst_req.serialize = dma_reg2hw.conf.serialize.q; + end : hw_req_conv + + + // assemble 2D extension + always_comb begin : twod_hw_req_conv + idma_nd_req_o = '0; + idma_nd_req_o.burst_req = burst_req; + idma_nd_req_o.d_req[0].reps = dma_reg2hw.num_repetitions; + idma_nd_req_o.d_req[0].src_strides = dma_reg2hw.stride_src; + idma_nd_req_o.d_req[0].dst_strides = dma_reg2hw.stride_dst; + end : twod_hw_req_conv + + // only increment issue counter if we have a valid transfer + assign issue = ready_i && valid_o; + + // transfer id generator + idma_transfer_id_gen #( + .IdWidth ( DmaRegisterWidth ) + ) i_idma_transfer_id_gen ( + .clk_i, + .rst_ni, + .issue_i ( issue ), + .retire_i ( trans_complete_i ), + .next_o ( next_id ), + .completed_o ( done_id ) + ); + +endmodule : idma_reg64_2d_frontend diff --git a/src/frontends/register_64bit_2d/idma_reg64_2d_frontend_reg_pkg.sv b/src/frontends/register_64bit_2d/idma_reg64_2d_frontend_reg_pkg.sv new file mode 100644 index 00000000..7131af8e --- /dev/null +++ b/src/frontends/register_64bit_2d/idma_reg64_2d_frontend_reg_pkg.sv @@ -0,0 +1,140 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Register Package auto-generated by `reggen` containing data structure + +package idma_reg64_2d_frontend_reg_pkg; + + // Address widths within the block + parameter int BlockAw = 7; + + //////////////////////////// + // Typedefs for registers // + //////////////////////////// + + typedef struct packed { + logic [63:0] q; + } idma_reg64_2d_frontend_reg2hw_src_addr_reg_t; + + typedef struct packed { + logic [63:0] q; + } idma_reg64_2d_frontend_reg2hw_dst_addr_reg_t; + + typedef struct packed { + logic [63:0] q; + } idma_reg64_2d_frontend_reg2hw_num_bytes_reg_t; + + typedef struct packed { + struct packed { + logic q; + } decouple; + struct packed { + logic q; + } deburst; + struct packed { + logic q; + } serialize; + } idma_reg64_2d_frontend_reg2hw_conf_reg_t; + + typedef struct packed { + logic [63:0] q; + logic re; + } idma_reg64_2d_frontend_reg2hw_next_id_reg_t; + + typedef struct packed { + logic [63:0] q; + logic re; + } idma_reg64_2d_frontend_reg2hw_done_reg_t; + + typedef struct packed { + logic [63:0] q; + } idma_reg64_2d_frontend_reg2hw_stride_src_reg_t; + + typedef struct packed { + logic [63:0] q; + } idma_reg64_2d_frontend_reg2hw_stride_dst_reg_t; + + typedef struct packed { + logic [63:0] q; + } idma_reg64_2d_frontend_reg2hw_num_repetitions_reg_t; + + typedef struct packed { + logic d; + } idma_reg64_2d_frontend_hw2reg_status_reg_t; + + typedef struct packed { + logic [63:0] d; + } idma_reg64_2d_frontend_hw2reg_next_id_reg_t; + + typedef struct packed { + logic [63:0] d; + } idma_reg64_2d_frontend_hw2reg_done_reg_t; + + // Register -> HW type + typedef struct packed { + idma_reg64_2d_frontend_reg2hw_src_addr_reg_t src_addr; // [516:453] + idma_reg64_2d_frontend_reg2hw_dst_addr_reg_t dst_addr; // [452:389] + idma_reg64_2d_frontend_reg2hw_num_bytes_reg_t num_bytes; // [388:325] + idma_reg64_2d_frontend_reg2hw_conf_reg_t conf; // [324:322] + idma_reg64_2d_frontend_reg2hw_next_id_reg_t next_id; // [321:257] + idma_reg64_2d_frontend_reg2hw_done_reg_t done; // [256:192] + idma_reg64_2d_frontend_reg2hw_stride_src_reg_t stride_src; // [191:128] + idma_reg64_2d_frontend_reg2hw_stride_dst_reg_t stride_dst; // [127:64] + idma_reg64_2d_frontend_reg2hw_num_repetitions_reg_t num_repetitions; // [63:0] + } idma_reg64_2d_frontend_reg2hw_t; + + // HW -> register type + typedef struct packed { + idma_reg64_2d_frontend_hw2reg_status_reg_t status; // [128:128] + idma_reg64_2d_frontend_hw2reg_next_id_reg_t next_id; // [127:64] + idma_reg64_2d_frontend_hw2reg_done_reg_t done; // [63:0] + } idma_reg64_2d_frontend_hw2reg_t; + + // Register offsets + parameter logic [BlockAw-1:0] IDMA_REG64_2D_FRONTEND_SRC_ADDR_OFFSET = 7'h 0; + parameter logic [BlockAw-1:0] IDMA_REG64_2D_FRONTEND_DST_ADDR_OFFSET = 7'h 8; + parameter logic [BlockAw-1:0] IDMA_REG64_2D_FRONTEND_NUM_BYTES_OFFSET = 7'h 10; + parameter logic [BlockAw-1:0] IDMA_REG64_2D_FRONTEND_CONF_OFFSET = 7'h 18; + parameter logic [BlockAw-1:0] IDMA_REG64_2D_FRONTEND_STATUS_OFFSET = 7'h 20; + parameter logic [BlockAw-1:0] IDMA_REG64_2D_FRONTEND_NEXT_ID_OFFSET = 7'h 28; + parameter logic [BlockAw-1:0] IDMA_REG64_2D_FRONTEND_DONE_OFFSET = 7'h 30; + parameter logic [BlockAw-1:0] IDMA_REG64_2D_FRONTEND_STRIDE_SRC_OFFSET = 7'h 38; + parameter logic [BlockAw-1:0] IDMA_REG64_2D_FRONTEND_STRIDE_DST_OFFSET = 7'h 40; + parameter logic [BlockAw-1:0] IDMA_REG64_2D_FRONTEND_NUM_REPETITIONS_OFFSET = 7'h 48; + + // Reset values for hwext registers and their fields + parameter logic [0:0] IDMA_REG64_2D_FRONTEND_STATUS_RESVAL = 1'h 0; + parameter logic [63:0] IDMA_REG64_2D_FRONTEND_NEXT_ID_RESVAL = 64'h 0; + parameter logic [63:0] IDMA_REG64_2D_FRONTEND_DONE_RESVAL = 64'h 0; + + // Register index + typedef enum int { + IDMA_REG64_2D_FRONTEND_SRC_ADDR, + IDMA_REG64_2D_FRONTEND_DST_ADDR, + IDMA_REG64_2D_FRONTEND_NUM_BYTES, + IDMA_REG64_2D_FRONTEND_CONF, + IDMA_REG64_2D_FRONTEND_STATUS, + IDMA_REG64_2D_FRONTEND_NEXT_ID, + IDMA_REG64_2D_FRONTEND_DONE, + IDMA_REG64_2D_FRONTEND_STRIDE_SRC, + IDMA_REG64_2D_FRONTEND_STRIDE_DST, + IDMA_REG64_2D_FRONTEND_NUM_REPETITIONS + } idma_reg64_2d_frontend_id_e; + + // Register width information to check illegal writes + parameter logic [3:0] IDMA_REG64_2D_FRONTEND_PERMIT [10] = '{ + 4'b 1111, // index[0] IDMA_REG64_2D_FRONTEND_SRC_ADDR + 4'b 1111, // index[1] IDMA_REG64_2D_FRONTEND_DST_ADDR + 4'b 1111, // index[2] IDMA_REG64_2D_FRONTEND_NUM_BYTES + 4'b 0001, // index[3] IDMA_REG64_2D_FRONTEND_CONF + 4'b 0001, // index[4] IDMA_REG64_2D_FRONTEND_STATUS + 4'b 1111, // index[5] IDMA_REG64_2D_FRONTEND_NEXT_ID + 4'b 1111, // index[6] IDMA_REG64_2D_FRONTEND_DONE + 4'b 1111, // index[7] IDMA_REG64_2D_FRONTEND_STRIDE_SRC + 4'b 1111, // index[8] IDMA_REG64_2D_FRONTEND_STRIDE_DST + 4'b 1111 // index[9] IDMA_REG64_2D_FRONTEND_NUM_REPETITIONS + }; + +endpackage + diff --git a/src/frontends/register_64bit_2d/idma_reg64_2d_frontend_reg_top.sv b/src/frontends/register_64bit_2d/idma_reg64_2d_frontend_reg_top.sv new file mode 100644 index 00000000..f19a37ea --- /dev/null +++ b/src/frontends/register_64bit_2d/idma_reg64_2d_frontend_reg_top.sv @@ -0,0 +1,527 @@ +// Copyright lowRISC contributors. +// Licensed under the Apache License, Version 2.0, see LICENSE for details. +// SPDX-License-Identifier: Apache-2.0 +// +// Register Top module auto-generated by `reggen` + + +`include "common_cells/assertions.svh" + +module idma_reg64_2d_frontend_reg_top #( + parameter type reg_req_t = logic, + parameter type reg_rsp_t = logic, + parameter int AW = 7 +) ( + input clk_i, + input rst_ni, + input reg_req_t reg_req_i, + output reg_rsp_t reg_rsp_o, + // To HW + output idma_reg64_2d_frontend_reg_pkg::idma_reg64_2d_frontend_reg2hw_t reg2hw, // Write + input idma_reg64_2d_frontend_reg_pkg::idma_reg64_2d_frontend_hw2reg_t hw2reg, // Read + + + // Config + input devmode_i // If 1, explicit error return for unmapped register access +); + + import idma_reg64_2d_frontend_reg_pkg::* ; + + localparam int DW = 64; + localparam int DBW = DW/8; // Byte Width + + // register signals + logic reg_we; + logic reg_re; + logic [AW-1:0] reg_addr; + logic [DW-1:0] reg_wdata; + logic [DBW-1:0] reg_be; + logic [DW-1:0] reg_rdata; + logic reg_error; + + logic addrmiss, wr_err; + + logic [DW-1:0] reg_rdata_next; + + // Below register interface can be changed + reg_req_t reg_intf_req; + reg_rsp_t reg_intf_rsp; + + + assign reg_intf_req = reg_req_i; + assign reg_rsp_o = reg_intf_rsp; + + + assign reg_we = reg_intf_req.valid & reg_intf_req.write; + assign reg_re = reg_intf_req.valid & ~reg_intf_req.write; + assign reg_addr = reg_intf_req.addr; + assign reg_wdata = reg_intf_req.wdata; + assign reg_be = reg_intf_req.wstrb; + assign reg_intf_rsp.rdata = reg_rdata; + assign reg_intf_rsp.error = reg_error; + assign reg_intf_rsp.ready = 1'b1; + + assign reg_rdata = reg_rdata_next ; + assign reg_error = (devmode_i & addrmiss) | wr_err; + + + // Define SW related signals + // Format: __{wd|we|qs} + // or _{wd|we|qs} if field == 1 or 0 + logic [63:0] src_addr_qs; + logic [63:0] src_addr_wd; + logic src_addr_we; + logic [63:0] dst_addr_qs; + logic [63:0] dst_addr_wd; + logic dst_addr_we; + logic [63:0] num_bytes_qs; + logic [63:0] num_bytes_wd; + logic num_bytes_we; + logic conf_decouple_qs; + logic conf_decouple_wd; + logic conf_decouple_we; + logic conf_deburst_qs; + logic conf_deburst_wd; + logic conf_deburst_we; + logic conf_serialize_qs; + logic conf_serialize_wd; + logic conf_serialize_we; + logic status_qs; + logic status_re; + logic [63:0] next_id_qs; + logic next_id_re; + logic [63:0] done_qs; + logic done_re; + logic [63:0] stride_src_qs; + logic [63:0] stride_src_wd; + logic stride_src_we; + logic [63:0] stride_dst_qs; + logic [63:0] stride_dst_wd; + logic stride_dst_we; + logic [63:0] num_repetitions_qs; + logic [63:0] num_repetitions_wd; + logic num_repetitions_we; + + // Register instances + // R[src_addr]: V(False) + + prim_subreg #( + .DW (64), + .SWACCESS("RW"), + .RESVAL (64'h0) + ) u_src_addr ( + .clk_i (clk_i ), + .rst_ni (rst_ni ), + + // from register interface + .we (src_addr_we), + .wd (src_addr_wd), + + // from internal hardware + .de (1'b0), + .d ('0 ), + + // to internal hardware + .qe (), + .q (reg2hw.src_addr.q ), + + // to register interface (read) + .qs (src_addr_qs) + ); + + + // R[dst_addr]: V(False) + + prim_subreg #( + .DW (64), + .SWACCESS("RW"), + .RESVAL (64'h0) + ) u_dst_addr ( + .clk_i (clk_i ), + .rst_ni (rst_ni ), + + // from register interface + .we (dst_addr_we), + .wd (dst_addr_wd), + + // from internal hardware + .de (1'b0), + .d ('0 ), + + // to internal hardware + .qe (), + .q (reg2hw.dst_addr.q ), + + // to register interface (read) + .qs (dst_addr_qs) + ); + + + // R[num_bytes]: V(False) + + prim_subreg #( + .DW (64), + .SWACCESS("RW"), + .RESVAL (64'h0) + ) u_num_bytes ( + .clk_i (clk_i ), + .rst_ni (rst_ni ), + + // from register interface + .we (num_bytes_we), + .wd (num_bytes_wd), + + // from internal hardware + .de (1'b0), + .d ('0 ), + + // to internal hardware + .qe (), + .q (reg2hw.num_bytes.q ), + + // to register interface (read) + .qs (num_bytes_qs) + ); + + + // R[conf]: V(False) + + // F[decouple]: 0:0 + prim_subreg #( + .DW (1), + .SWACCESS("RW"), + .RESVAL (1'h0) + ) u_conf_decouple ( + .clk_i (clk_i ), + .rst_ni (rst_ni ), + + // from register interface + .we (conf_decouple_we), + .wd (conf_decouple_wd), + + // from internal hardware + .de (1'b0), + .d ('0 ), + + // to internal hardware + .qe (), + .q (reg2hw.conf.decouple.q ), + + // to register interface (read) + .qs (conf_decouple_qs) + ); + + + // F[deburst]: 1:1 + prim_subreg #( + .DW (1), + .SWACCESS("RW"), + .RESVAL (1'h0) + ) u_conf_deburst ( + .clk_i (clk_i ), + .rst_ni (rst_ni ), + + // from register interface + .we (conf_deburst_we), + .wd (conf_deburst_wd), + + // from internal hardware + .de (1'b0), + .d ('0 ), + + // to internal hardware + .qe (), + .q (reg2hw.conf.deburst.q ), + + // to register interface (read) + .qs (conf_deburst_qs) + ); + + + // F[serialize]: 2:2 + prim_subreg #( + .DW (1), + .SWACCESS("RW"), + .RESVAL (1'h0) + ) u_conf_serialize ( + .clk_i (clk_i ), + .rst_ni (rst_ni ), + + // from register interface + .we (conf_serialize_we), + .wd (conf_serialize_wd), + + // from internal hardware + .de (1'b0), + .d ('0 ), + + // to internal hardware + .qe (), + .q (reg2hw.conf.serialize.q ), + + // to register interface (read) + .qs (conf_serialize_qs) + ); + + + // R[status]: V(True) + + prim_subreg_ext #( + .DW (1) + ) u_status ( + .re (status_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.status.d), + .qre (), + .qe (), + .q (), + .qs (status_qs) + ); + + + // R[next_id]: V(True) + + prim_subreg_ext #( + .DW (64) + ) u_next_id ( + .re (next_id_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.next_id.d), + .qre (reg2hw.next_id.re), + .qe (), + .q (reg2hw.next_id.q ), + .qs (next_id_qs) + ); + + + // R[done]: V(True) + + prim_subreg_ext #( + .DW (64) + ) u_done ( + .re (done_re), + .we (1'b0), + .wd ('0), + .d (hw2reg.done.d), + .qre (reg2hw.done.re), + .qe (), + .q (reg2hw.done.q ), + .qs (done_qs) + ); + + + // R[stride_src]: V(False) + + prim_subreg #( + .DW (64), + .SWACCESS("RW"), + .RESVAL (64'h0) + ) u_stride_src ( + .clk_i (clk_i ), + .rst_ni (rst_ni ), + + // from register interface + .we (stride_src_we), + .wd (stride_src_wd), + + // from internal hardware + .de (1'b0), + .d ('0 ), + + // to internal hardware + .qe (), + .q (reg2hw.stride_src.q ), + + // to register interface (read) + .qs (stride_src_qs) + ); + + + // R[stride_dst]: V(False) + + prim_subreg #( + .DW (64), + .SWACCESS("RW"), + .RESVAL (64'h0) + ) u_stride_dst ( + .clk_i (clk_i ), + .rst_ni (rst_ni ), + + // from register interface + .we (stride_dst_we), + .wd (stride_dst_wd), + + // from internal hardware + .de (1'b0), + .d ('0 ), + + // to internal hardware + .qe (), + .q (reg2hw.stride_dst.q ), + + // to register interface (read) + .qs (stride_dst_qs) + ); + + + // R[num_repetitions]: V(False) + + prim_subreg #( + .DW (64), + .SWACCESS("RW"), + .RESVAL (64'h0) + ) u_num_repetitions ( + .clk_i (clk_i ), + .rst_ni (rst_ni ), + + // from register interface + .we (num_repetitions_we), + .wd (num_repetitions_wd), + + // from internal hardware + .de (1'b0), + .d ('0 ), + + // to internal hardware + .qe (), + .q (reg2hw.num_repetitions.q ), + + // to register interface (read) + .qs (num_repetitions_qs) + ); + + + + + logic [9:0] addr_hit; + always_comb begin + addr_hit = '0; + addr_hit[0] = (reg_addr == IDMA_REG64_2D_FRONTEND_SRC_ADDR_OFFSET); + addr_hit[1] = (reg_addr == IDMA_REG64_2D_FRONTEND_DST_ADDR_OFFSET); + addr_hit[2] = (reg_addr == IDMA_REG64_2D_FRONTEND_NUM_BYTES_OFFSET); + addr_hit[3] = (reg_addr == IDMA_REG64_2D_FRONTEND_CONF_OFFSET); + addr_hit[4] = (reg_addr == IDMA_REG64_2D_FRONTEND_STATUS_OFFSET); + addr_hit[5] = (reg_addr == IDMA_REG64_2D_FRONTEND_NEXT_ID_OFFSET); + addr_hit[6] = (reg_addr == IDMA_REG64_2D_FRONTEND_DONE_OFFSET); + addr_hit[7] = (reg_addr == IDMA_REG64_2D_FRONTEND_STRIDE_SRC_OFFSET); + addr_hit[8] = (reg_addr == IDMA_REG64_2D_FRONTEND_STRIDE_DST_OFFSET); + addr_hit[9] = (reg_addr == IDMA_REG64_2D_FRONTEND_NUM_REPETITIONS_OFFSET); + end + + assign addrmiss = (reg_re || reg_we) ? ~|addr_hit : 1'b0 ; + + // Check sub-word write is permitted + always_comb begin + wr_err = (reg_we & + ((addr_hit[0] & (|(IDMA_REG64_2D_FRONTEND_PERMIT[0] & ~reg_be))) | + (addr_hit[1] & (|(IDMA_REG64_2D_FRONTEND_PERMIT[1] & ~reg_be))) | + (addr_hit[2] & (|(IDMA_REG64_2D_FRONTEND_PERMIT[2] & ~reg_be))) | + (addr_hit[3] & (|(IDMA_REG64_2D_FRONTEND_PERMIT[3] & ~reg_be))) | + (addr_hit[4] & (|(IDMA_REG64_2D_FRONTEND_PERMIT[4] & ~reg_be))) | + (addr_hit[5] & (|(IDMA_REG64_2D_FRONTEND_PERMIT[5] & ~reg_be))) | + (addr_hit[6] & (|(IDMA_REG64_2D_FRONTEND_PERMIT[6] & ~reg_be))) | + (addr_hit[7] & (|(IDMA_REG64_2D_FRONTEND_PERMIT[7] & ~reg_be))) | + (addr_hit[8] & (|(IDMA_REG64_2D_FRONTEND_PERMIT[8] & ~reg_be))) | + (addr_hit[9] & (|(IDMA_REG64_2D_FRONTEND_PERMIT[9] & ~reg_be))))); + end + + assign src_addr_we = addr_hit[0] & reg_we & !reg_error; + assign src_addr_wd = reg_wdata[63:0]; + + assign dst_addr_we = addr_hit[1] & reg_we & !reg_error; + assign dst_addr_wd = reg_wdata[63:0]; + + assign num_bytes_we = addr_hit[2] & reg_we & !reg_error; + assign num_bytes_wd = reg_wdata[63:0]; + + assign conf_decouple_we = addr_hit[3] & reg_we & !reg_error; + assign conf_decouple_wd = reg_wdata[0]; + + assign conf_deburst_we = addr_hit[3] & reg_we & !reg_error; + assign conf_deburst_wd = reg_wdata[1]; + + assign conf_serialize_we = addr_hit[3] & reg_we & !reg_error; + assign conf_serialize_wd = reg_wdata[2]; + + assign status_re = addr_hit[4] & reg_re & !reg_error; + + assign next_id_re = addr_hit[5] & reg_re & !reg_error; + + assign done_re = addr_hit[6] & reg_re & !reg_error; + + assign stride_src_we = addr_hit[7] & reg_we & !reg_error; + assign stride_src_wd = reg_wdata[63:0]; + + assign stride_dst_we = addr_hit[8] & reg_we & !reg_error; + assign stride_dst_wd = reg_wdata[63:0]; + + assign num_repetitions_we = addr_hit[9] & reg_we & !reg_error; + assign num_repetitions_wd = reg_wdata[63:0]; + + // Read data return + always_comb begin + reg_rdata_next = '0; + unique case (1'b1) + addr_hit[0]: begin + reg_rdata_next[63:0] = src_addr_qs; + end + + addr_hit[1]: begin + reg_rdata_next[63:0] = dst_addr_qs; + end + + addr_hit[2]: begin + reg_rdata_next[63:0] = num_bytes_qs; + end + + addr_hit[3]: begin + reg_rdata_next[0] = conf_decouple_qs; + reg_rdata_next[1] = conf_deburst_qs; + reg_rdata_next[2] = conf_serialize_qs; + end + + addr_hit[4]: begin + reg_rdata_next[0] = status_qs; + end + + addr_hit[5]: begin + reg_rdata_next[63:0] = next_id_qs; + end + + addr_hit[6]: begin + reg_rdata_next[63:0] = done_qs; + end + + addr_hit[7]: begin + reg_rdata_next[63:0] = stride_src_qs; + end + + addr_hit[8]: begin + reg_rdata_next[63:0] = stride_dst_qs; + end + + addr_hit[9]: begin + reg_rdata_next[63:0] = num_repetitions_qs; + end + + default: begin + reg_rdata_next = '1; + end + endcase + end + + // Unused signal tieoff + + // wdata / byte enable are not always fully used + // add a blanket unused statement to handle lint waivers + logic unused_wdata; + logic unused_be; + assign unused_wdata = ^reg_wdata; + assign unused_be = ^reg_be; + + // Assertions for Register Interface + `ASSERT(en2addrHit, (reg_we || reg_re) |-> $onehot0(addr_hit)) + +endmodule diff --git a/src/frontends/register_64bit_2d/reg_html.css b/src/frontends/register_64bit_2d/reg_html.css new file mode 100644 index 00000000..4cb48edb --- /dev/null +++ b/src/frontends/register_64bit_2d/reg_html.css @@ -0,0 +1,74 @@ +/* Stylesheet for reggen HTML register output */ +/* Copyright lowRISC contributors. */ +/* Licensed under the Apache License, Version 2.0, see LICENSE for details. */ +/* SPDX-License-Identifier: Apache-2.0 */ + +table.regpic { + width: 95%; + border-collapse: collapse; + margin-left:auto; + margin-right:auto; + table-layout:fixed; +} + +table.regdef { + border: 1px solid black; + width: 80%; + border-collapse: collapse; + margin-left:auto; + margin-right:auto; + table-layout:auto; +} + +table.regdef th { + border: 1px solid black; + font-family: sans-serif; + +} + +td.bitnum { + font-size: 60%; + text-align: center; +} + +td.unused { + border: 1px solid black; + background-color: gray; +} + +td.fname { + border: 1px solid black; + text-align: center; + font-family: sans-serif; +} + + +td.regbits, td.regperm, td.regrv { + border: 1px solid black; + text-align: center; + font-family: sans-serif; +} + +td.regde, td.regfn { + border: 1px solid black; +} + +table.cfgtable { + border: 1px solid black; + width: 80%; + border-collapse: collapse; + margin-left:auto; + margin-right:auto; + table-layout:auto; +} + +table.cfgtable th { + border: 1px solid black; + font-family: sans-serif; + font-weight: bold; +} + +table.cfgtable td { + border: 1px solid black; + font-family: sans-serif; +} diff --git a/src/systems/cva6_reg/dma_core_wrap.sv b/src/systems/cva6_reg/dma_core_wrap.sv index 5f2a809e..9c99bdfd 100644 --- a/src/systems/cva6_reg/dma_core_wrap.sv +++ b/src/systems/cva6_reg/dma_core_wrap.sv @@ -14,15 +14,20 @@ `include "register_interface/typedef.svh" module dma_core_wrap #( - parameter int unsigned AxiAddrWidth = 0, - parameter int unsigned AxiDataWidth = 0, - parameter int unsigned AxiIdWidth = 0, - parameter int unsigned AxiUserWidth = 0, - parameter int unsigned AxiSlvIdWidth = 0, - parameter type axi_mst_req_t = logic, - parameter type axi_mst_rsp_t = logic, - parameter type axi_slv_req_t = logic, - parameter type axi_slv_rsp_t = logic + parameter int unsigned AxiAddrWidth = 32'd0, + parameter int unsigned AxiDataWidth = 32'd0, + parameter int unsigned AxiIdWidth = 32'd0, + parameter int unsigned AxiUserWidth = 32'd0, + parameter int unsigned AxiSlvIdWidth = 32'd0, + parameter int unsigned NumAxInFlight = 32'd0, + parameter int unsigned MemSysDepth = 32'd0, + parameter int unsigned JobFifoDepth = 32'd0, + parameter bit RAWCouplingAvail = 32'd0, + parameter bit IsTwoD = 32'd0, + parameter type axi_mst_req_t = logic, + parameter type axi_mst_rsp_t = logic, + parameter type axi_slv_req_t = logic, + parameter type axi_slv_rsp_t = logic ) ( input logic clk_i, input logic rst_ni, @@ -32,27 +37,41 @@ module dma_core_wrap #( input axi_slv_req_t axi_slv_req_i, output axi_slv_rsp_t axi_slv_rsp_o ); - localparam int unsigned DmaRegisterWidth = 64; + // local params + localparam int unsigned DmaRegisterWidth = 32'd64; + localparam int unsigned NumDim = 32'd2; + localparam int unsigned TFLenWidth = AxiAddrWidth; + + typedef logic [AxiDataWidth-1:0] data_t; + typedef logic [AxiDataWidth/8-1:0] strb_t; typedef logic [AxiAddrWidth-1:0] addr_t; typedef logic [AxiIdWidth-1:0] axi_id_t; typedef logic [AxiSlvIdWidth-1:0] axi_slv_id_t; typedef logic [AxiUserWidth-1:0] axi_user_t; // iDMA struct definitions - localparam int unsigned TFLenWidth = AxiAddrWidth; typedef logic [TFLenWidth-1:0] tf_len_t; // iDMA request / response types `IDMA_TYPEDEF_FULL_REQ_T(idma_req_t, axi_slv_id_t, addr_t, tf_len_t) `IDMA_TYPEDEF_FULL_RSP_T(idma_rsp_t, addr_t) - `REG_BUS_TYPEDEF_ALL(dma_regs, logic[5:0], logic[63:0], logic[7:0]) + `REG_BUS_TYPEDEF_ALL(dma_regs, addr_t, data_t, strb_t) - idma_req_t burst_req; - logic be_valid, be_ready, be_trans_complete; + idma_req_t burst_req, burst_req_d; + logic be_valid, be_valid_d; + logic be_ready, be_ready_d; + logic be_trans_complete; idma_pkg::idma_busy_t idma_busy; + idma_rsp_t idma_rsp; + logic idma_rsp_valid; + logic idma_rsp_ready; + + logic twod_trans_complete; + logic twod_busy; + dma_regs_req_t dma_regs_req; dma_regs_rsp_t dma_regs_rsp; @@ -76,26 +95,125 @@ module dma_core_wrap #( ); - /* - * DMA Frontend - */ - idma_reg64_frontend #( - .dma_regs_req_t ( dma_regs_req_t ), - .dma_regs_rsp_t ( dma_regs_rsp_t ), - .burst_req_t ( idma_req_t ) - ) i_dma_frontend ( - .clk_i, - .rst_ni, - // AXI slave: control port - .dma_ctrl_req_i ( dma_regs_req ), - .dma_ctrl_rsp_o ( dma_regs_rsp ), - // Backend control - .burst_req_o ( burst_req ), - .valid_o ( be_valid ), - .ready_i ( be_ready ), - .backend_idle_i ( ~|idma_busy ), - .trans_complete_i ( be_trans_complete ) - ); + if (!IsTwoD) begin : gen_one_d + /* + * DMA Frontend + */ + idma_reg64_frontend #( + .dma_regs_req_t ( dma_regs_req_t ), + .dma_regs_rsp_t ( dma_regs_rsp_t ), + .burst_req_t ( idma_req_t ) + ) i_dma_frontend ( + .clk_i, + .rst_ni, + // AXI slave: control port + .dma_ctrl_req_i ( dma_regs_req ), + .dma_ctrl_rsp_o ( dma_regs_rsp ), + // Backend control + .burst_req_o ( burst_req_d ), + .valid_o ( be_valid_d ), + .ready_i ( be_ready_d ), + .backend_idle_i ( ~|idma_busy ), + .trans_complete_i ( be_trans_complete ) + ); + + stream_fifo #( + .FALL_THROUGH ( 1'b0 ), + .DATA_WIDTH ( AxiDataWidth ), + .DEPTH ( JobFifoDepth ), + .T ( idma_req_t ) + ) i_stream_fifo_jobs_oned ( + .clk_i, + .rst_ni, + .testmode_i, + .flush_i ( 1'b0 ), + .usage_o ( /* NOT CONNECTED */ ), + .data_i ( burst_req_d ), + .valid_i ( be_valid_d ), + .ready_o ( be_ready_d ), + .data_o ( burst_req ), + .valid_o ( be_valid ), + .ready_i ( be_ready ) + ); + + + assign be_trans_complete = idma_rsp_valid; + assign idma_rsp_ready = 1'b1; + + end else begin : gen_two_d + + `IDMA_TYPEDEF_FULL_ND_REQ_T(idma_nd_req_t, idma_req_t, tf_len_t, tf_len_t) + + idma_nd_req_t idma_nd_req, idma_nd_req_d; + logic idma_nd_req_valid, idma_nd_req_valid_d; + logic idma_nd_req_ready, idma_nd_req_ready_d; + + // 2D frontend + idma_reg64_2d_frontend #( + .dma_regs_req_t ( dma_regs_req_t ), + .dma_regs_rsp_t ( dma_regs_rsp_t ), + .burst_req_t ( idma_req_t ), + .idma_nd_req_t ( idma_nd_req_t ) + + ) i_dma_2d_frontend ( + .clk_i, + .rst_ni, + // AXI slave: control port + .dma_ctrl_req_i ( dma_regs_req ), + .dma_ctrl_rsp_o ( dma_regs_rsp ), + // Backend control + .idma_nd_req_o ( idma_nd_req_d ), + .valid_o ( idma_nd_req_valid_d ), + .ready_i ( idma_nd_req_ready_d ), + .backend_idle_i ( ~|idma_busy & !twod_busy ), + .trans_complete_i ( twod_trans_complete ) + ); + + stream_fifo #( + .FALL_THROUGH ( 1'b0 ), + .DATA_WIDTH ( AxiDataWidth ), + .DEPTH ( JobFifoDepth ), + .T ( idma_nd_req_t ) + ) i_stream_fifo_jobs_twod ( + .clk_i, + .rst_ni, + .testmode_i, + .flush_i ( 1'b0 ), + .usage_o ( /* NOT CONNECTED */ ), + .data_i ( idma_nd_req_d ), + .valid_i ( idma_nd_req_valid_d ), + .ready_o ( idma_nd_req_ready_d ), + .data_o ( idma_nd_req ), + .valid_o ( idma_nd_req_valid ), + .ready_i ( idma_nd_req_ready ) + ); + + // Midend + idma_nd_midend #( + .NumDim ( NumDim ), + .addr_t ( addr_t ), + .idma_req_t ( idma_req_t ), + .idma_rsp_t ( idma_rsp_t ), + .idma_nd_req_t ( idma_nd_req_t ), + .RepWidths ( '{default: AxiAddrWidth} ) + ) i_idma_nd_midend ( + .clk_i, + .rst_ni, + .nd_req_i ( idma_nd_req ), + .nd_req_valid_i ( idma_nd_req_valid ), + .nd_req_ready_o ( idma_nd_req_ready ), + .nd_rsp_o ( /* NOT CONECTED */ ), + .nd_rsp_valid_o ( twod_trans_complete ), + .nd_rsp_ready_i ( 1'b1 ), + .burst_req_o ( burst_req ), + .burst_req_valid_o( be_valid ), + .burst_req_ready_i( be_ready ), + .burst_rsp_i ( idma_rsp ), + .burst_rsp_valid_i( idma_rsp_valid ), + .burst_rsp_ready_o( idma_rsp_ready ), + .busy_o ( twod_busy ) + ); + end `AXI_TYPEDEF_AW_CHAN_T(axi_mst_aw_chan_t, addr_t, axi_id_t, axi_user_t) `AXI_TYPEDEF_AR_CHAN_T(axi_mst_ar_chan_t, addr_t, axi_id_t, axi_user_t) @@ -105,14 +223,14 @@ module dma_core_wrap #( .AddrWidth ( AxiAddrWidth ), .UserWidth ( AxiUserWidth ), .AxiIdWidth ( AxiIdWidth ), - .NumAxInFlight ( 2 ), + .NumAxInFlight ( NumAxInFlight ), .BufferDepth ( 3 ), .TFLenWidth ( TFLenWidth ), - .RAWCouplingAvail ( 1'b1 ), - .MaskInvalidData ( 1'b1 ), + .RAWCouplingAvail ( RAWCouplingAvail ), + .MaskInvalidData ( 1'b0 ), .HardwareLegalizer ( 1'b1 ), .RejectZeroTransfers ( 1'b1 ), - .MemSysDepth ( 32'd0 ), + .MemSysDepth ( MemSysDepth ), .ErrorCap ( idma_pkg::NO_ERROR_HANDLING ), .idma_req_t ( idma_req_t ), .idma_rsp_t ( idma_rsp_t ), @@ -125,15 +243,15 @@ module dma_core_wrap #( ) i_idma_backend ( .clk_i, .rst_ni, - .testmode_i ( testmode_i ), + .testmode_i, .idma_req_i ( burst_req ), .req_valid_i ( be_valid ), .req_ready_o ( be_ready ), - .idma_rsp_o ( /*NOT CONNECTED*/ ), - .rsp_valid_o ( be_trans_complete ), - .rsp_ready_i ( 1'b1 ), + .idma_rsp_o ( idma_rsp ), + .rsp_valid_o ( idma_rsp_valid ), + .rsp_ready_i ( idma_rsp_ready ), .idma_eh_req_i ( '0 ), // No error handling .eh_req_valid_i( 1'b1 ), @@ -146,12 +264,19 @@ module dma_core_wrap #( endmodule : dma_core_wrap + + module dma_core_wrap_intf #( - parameter int unsigned AXI_ADDR_WIDTH = -1, - parameter int unsigned AXI_DATA_WIDTH = -1, - parameter int unsigned AXI_USER_WIDTH = -1, - parameter int unsigned AXI_ID_WIDTH = -1, - parameter int unsigned AXI_SLV_ID_WIDTH = -1 + parameter int unsigned AXI_ADDR_WIDTH = 32'd0, + parameter int unsigned AXI_DATA_WIDTH = 32'd0, + parameter int unsigned AXI_USER_WIDTH = 32'd0, + parameter int unsigned AXI_ID_WIDTH = 32'd0, + parameter int unsigned AXI_SLV_ID_WIDTH = 32'd0, + parameter int unsigned JOB_FIFO_DEPTH = 32'd0, + parameter int unsigned NUM_AX_IN_FLIGHT = 32'd0, + parameter int unsigned MEM_SYS_DEPTH = 32'd0, + parameter bit RAW_COUPLING_AVAIL = 1'b0, + parameter bit IS_TWO_D = 1'b0 ) ( input logic clk_i, input logic rst_ni, @@ -180,15 +305,20 @@ module dma_core_wrap_intf #( `AXI_ASSIGN_FROM_RESP(axi_slave, axi_slv_resp) dma_core_wrap #( - .AxiAddrWidth ( AXI_ADDR_WIDTH ), - .AxiDataWidth ( AXI_DATA_WIDTH ), - .AxiIdWidth ( AXI_USER_WIDTH ), - .AxiUserWidth ( AXI_ID_WIDTH ), - .AxiSlvIdWidth ( AXI_SLV_ID_WIDTH ), - .axi_mst_req_t ( axi_mst_req_t ), - .axi_mst_rsp_t ( axi_mst_resp_t ), - .axi_slv_req_t ( axi_slv_req_t ), - .axi_slv_rsp_t ( axi_slv_resp_t ) + .AxiAddrWidth ( AXI_ADDR_WIDTH ), + .AxiDataWidth ( AXI_DATA_WIDTH ), + .AxiIdWidth ( AXI_USER_WIDTH ), + .AxiUserWidth ( AXI_ID_WIDTH ), + .AxiSlvIdWidth ( AXI_SLV_ID_WIDTH ), + .JobFifoDepth ( JOB_FIFO_DEPTH ), + .NumAxInFlight ( NUM_AX_IN_FLIGHT ), + .MemSysDepth ( MEM_SYS_DEPTH ), + .RAWCouplingAvail ( RAW_COUPLING_AVAIL ), + .IsTwoD ( IS_TWO_D ), + .axi_mst_req_t ( axi_mst_req_t ), + .axi_mst_rsp_t ( axi_mst_resp_t ), + .axi_slv_req_t ( axi_slv_req_t ), + .axi_slv_rsp_t ( axi_slv_resp_t ) ) i_dma_core_wrap ( .clk_i, .rst_ni, diff --git a/util/licence-checker.hjson b/util/licence-checker.hjson index a18a9cd5..c29b08f3 100644 --- a/util/licence-checker.hjson +++ b/util/licence-checker.hjson @@ -19,6 +19,7 @@ 'src/frontends/register_32bit_2d/idma_reg32_2d_frontend.sv', 'src/frontends/register_64bit/idma_reg64_frontend.h', 'src/frontends/register_64bit/idma_reg64_frontend.sv', + 'src/frontends/register_64bit_2d/idma_reg64_2d_frontend.h', 'src/frontends/desc64/idma_desc64_frontend.h', 'src/systems/cva6_reg/driver/encoding.h', 'scripts/waves/*' diff --git a/util/waiver.verible b/util/waiver.verible index c702443b..a04df7c0 100644 --- a/util/waiver.verible +++ b/util/waiver.verible @@ -11,6 +11,8 @@ waive --rule=line-length --location="src/frontends/register_32bit_2d/idma_reg32_ # 64-bit frontend register file waive --rule=typedef-structs-unions --location="src/frontends/register_64bit/idma_reg64_frontend_reg_pkg.sv" waive --rule=line-length --location="src/frontends/register_64bit/idma_reg64_frontend_reg_pkg.sv" +waive --rule=typedef-structs-unions --location="src/frontends/register_64bit_2d/idma_reg64_2d_frontend_reg_pkg.sv" +waive --rule=line-length --location="src/frontends/register_64bit_2d/idma_reg64_2d_frontend_reg_pkg.sv" # 64-bit descriptor-based register file waive --rule=typedef-structs-unions --location="src/frontends/desc64/idma_desc64_reg_pkg.sv"