From 8adee05cefa62d5c96a618d8a61af3b33d1e135e Mon Sep 17 00:00:00 2001 From: Riccardo Gandolfi Date: Thu, 8 Jan 2026 15:22:32 +0100 Subject: [PATCH 1/7] Add Burst_Len parameter for idma_legalizer_page_splitter module --- src/backend/idma_legalizer_page_splitter.sv | 3 +- src/backend/tpl/idma_backend.sv.tpl | 3 + src/backend/tpl/idma_backend_synth.sv.tpl | 5 +- src/backend/tpl/idma_legalizer.sv.tpl | 4 + src/frontend/reg/tpl/idma_reg.hjson.tpl | 120 ++++++++++++++++++++ src/frontend/reg/tpl/idma_reg.sv.tpl | 4 +- 6 files changed, 135 insertions(+), 4 deletions(-) create mode 100644 src/frontend/reg/tpl/idma_reg.hjson.tpl diff --git a/src/backend/idma_legalizer_page_splitter.sv b/src/backend/idma_legalizer_page_splitter.sv index 14db0e26..5805c7a6 100644 --- a/src/backend/idma_legalizer_page_splitter.sv +++ b/src/backend/idma_legalizer_page_splitter.sv @@ -7,6 +7,7 @@ /// Legalizer module implementing a page splitter module idma_legalizer_page_splitter #( + parameter int unsigned Burst_len = 4'd5, parameter int unsigned OffsetWidth = 32'd2, parameter int unsigned PageAddrWidth = 32'd5, parameter type addr_t = logic, @@ -34,7 +35,7 @@ module idma_legalizer_page_splitter #( end else begin // should the "virtual" page be reduced? e.g. the transfers split into // smaller chunks than the AXI page size? - page_addr_width = OffsetWidth + (reduce_len_i ? max_llen_i : 'd8); + page_addr_width = OffsetWidth + (reduce_len_i ? max_llen_i : Burst_len); // a page can be a maximum of 4kB (12 bit) page_addr_width = page_addr_width > 'd12 ? 'd12 : page_addr_width; end diff --git a/src/backend/tpl/idma_backend.sv.tpl b/src/backend/tpl/idma_backend.sv.tpl index f21e6e51..0d4d0d39 100644 --- a/src/backend/tpl/idma_backend.sv.tpl +++ b/src/backend/tpl/idma_backend.sv.tpl @@ -83,6 +83,8 @@ module idma_backend_${name_uniqueifier} #( % endif % endfor , + /// Burst Len (for actual burst length do 8 byte * 2^(Burst_len)) + parameter int unsigned Burst_len = 4'd5, /// Address Read Channel type parameter type read_meta_channel_t = logic, /// Address Write Channel type @@ -430,6 +432,7 @@ _rsp_t ${mh_format['aw'][protocol]}${protocol}_write_rsp_i, .CombinedShifter ( CombinedShifter ), .DataWidth ( DataWidth ), .AddrWidth ( AddrWidth ), + .Burst_len ( Burst_len ), .idma_req_t ( idma_req_t ), .idma_r_req_t ( idma_r_req_t ), .idma_w_req_t ( idma_w_req_t ), diff --git a/src/backend/tpl/idma_backend_synth.sv.tpl b/src/backend/tpl/idma_backend_synth.sv.tpl index 1fce76b6..e865f5d1 100644 --- a/src/backend/tpl/idma_backend_synth.sv.tpl +++ b/src/backend/tpl/idma_backend_synth.sv.tpl @@ -81,7 +81,9 @@ module idma_backend_synth_${name_uniqueifier} #( /// Transfer length type (do not override!) parameter type tf_len_t = logic[TFLenWidth-1:0], /// Offset type (do not override!) - parameter type offset_t = logic[OffsetWidth-1:0] + parameter type offset_t = logic[OffsetWidth-1:0], + /// Burst Len (for actual burst length do 8 byte * 2^(Burst_len)) + parameter int unsigned Burst_len = 4'd5 )( input logic clk_i, input logic rst_ni, @@ -326,6 +328,7 @@ ${p}_${database[p]['write_meta_channel']}_width\ % endif % endfor , + .Burst_len ( Burst_len ), .write_meta_channel_t ( write_meta_channel_t ), .read_meta_channel_t ( read_meta_channel_t ) ) i_idma_backend ( diff --git a/src/backend/tpl/idma_legalizer.sv.tpl b/src/backend/tpl/idma_legalizer.sv.tpl index 47441be9..2bf6af9f 100644 --- a/src/backend/tpl/idma_legalizer.sv.tpl +++ b/src/backend/tpl/idma_legalizer.sv.tpl @@ -21,6 +21,8 @@ module idma_legalizer_${name_uniqueifier} #( parameter int unsigned DataWidth = 32'd16, /// Address width parameter int unsigned AddrWidth = 32'd24, + /// Burst Len (for actual burst length do 8 byte * 2^(Burst_len)) + parameter int unsigned Burst_len = 4'd5, /// 1D iDMA request type: /// - `length`: the length of the transfer in bytes /// - `*_addr`: the source / target byte addresses of the transfer @@ -182,6 +184,7 @@ ${database[p]['max_beats_per_burst']} * StrbWidth > ${database[p]['page_size']}\ //-------------------------------------- % if no_read_bursting or has_page_read_bursting: idma_legalizer_page_splitter #( + .Burst_len ( Burst_len ), .OffsetWidth ( OffsetWidth ), .PageAddrWidth ( PageAddrWidth ), .addr_t ( addr_t ), @@ -260,6 +263,7 @@ r_num_bytes_to_pb = r_page_num_bytes_to_pb; //-------------------------------------- % if no_write_bursting or has_page_write_bursting: idma_legalizer_page_splitter #( + .Burst_len ( Burst_len ), .OffsetWidth ( OffsetWidth ), .PageAddrWidth ( PageAddrWidth ), .addr_t ( addr_t ), diff --git a/src/frontend/reg/tpl/idma_reg.hjson.tpl b/src/frontend/reg/tpl/idma_reg.hjson.tpl new file mode 100644 index 00000000..b7719725 --- /dev/null +++ b/src/frontend/reg/tpl/idma_reg.hjson.tpl @@ -0,0 +1,120 @@ +// Copyright 2023 ETH Zurich and University of Bologna. +// Solderpad Hardware License, Version 0.51, see LICENSE for details. +// SPDX-License-Identifier: SHL-0.51 + +// Authors: +// - Michael Rogenmoser +// - Thomas Benz + +{ + name: "idma_${identifier}", + clock_primary: "clk_i", + reset_primary: "rst_ni", + bus_interfaces: [ + { protocol: "reg_iface", + direction: "device" + } + ], + regwidth: "32", + param_list: [ +${params} + ], + registers: [ + { name: "conf", + desc: "Configuration Register for DMA settings", + swaccess: "rw", + hwaccess: "hro", + fields: [ + { bits: "0", + name: "decouple_aw", + desc: "Decouple R-AW" + }, + { bits: "1", + name: "decouple_rw", + desc: "Decouple R-W" + }, + { bits: "2", + name: "src_reduce_len", + desc: "Reduce maximal source burst length" + }, + { bits: "3", + name: "dst_reduce_len", + desc: "Reduce maximal destination burst length" + } + { bits: "6:4", + name: "src_max_llen", + desc: "Maximal logarithmic source burst length" + } + { bits: "9:7", + name: "dst_max_llen", + desc: "Maximal logarithmic destination burst length" + } + { bits: "${dim_range}", + name: "enable_nd", + desc: "ND-extension enabled" + } + { bits: "${src_prot_range}", + name: "src_protocol", + desc: "Selection of the source protocol" + } + { bits: "${dst_prot_range}", + name: "dst_protocol", + desc: "Selection of the destination protocol" + } + ] + }, + { multireg: + { name: "status", + desc: "DMA Status", + swaccess: "ro", + hwaccess: "hwo", + count: "2", + cname: "status", + hwext: "true", + compact: "false", + fields: [ + { bits: "9:0", + name: "busy", + desc: "DMA busy" + } + ] + } + }, + { multireg: + { name: "next_id", + desc: "Next ID, launches transfer, returns 0 if transfer not set up properly.", + swaccess: "ro", + hwaccess: "hrw", + hwre: "true", + count: "2", + cname: "next_id", + hwext: "true", + compact: "false", + fields: [ + { bits: "31:0", + name: "next_id", + desc: "Next ID, launches transfer, returns 0 if transfer not set up properly." + } + ] + } + }, + { multireg: + { name: "done_id", + desc: "Get ID of finished transactions.", + swaccess: "ro", + hwaccess: "hwo", + count: "2", + cname: "done_id", + hwext: "true", + compact: "false", + fields: [ + { bits: "31:0", + name: "done_id", + desc: "Get ID of finished transactions." + } + ] + } + }, +${registers} + ] +} diff --git a/src/frontend/reg/tpl/idma_reg.sv.tpl b/src/frontend/reg/tpl/idma_reg.sv.tpl index 3055b59d..86573735 100644 --- a/src/frontend/reg/tpl/idma_reg.sv.tpl +++ b/src/frontend/reg/tpl/idma_reg.sv.tpl @@ -47,8 +47,8 @@ module idma_${identifier} #( ); /// Maximum number of streams is set to 16. It can be enlarged, but the register file - /// needs to be adapted too. - localparam int unsigned MaxNumStreams = 32'd16; + /// needs to be adapted too. It's set to 2 here to avoid binding to 0 useless registers in the pulp_cluster instance + localparam int unsigned MaxNumStreams = 32'd2; `APB_TYPEDEF_ALL(apb, logic[31:0], logic[31:0], logic[3:0]) apb_req_t [NumRegs-1:0] apb_req; From bea4f78ac4d3fb5fd16df6b791517da19e3857aa Mon Sep 17 00:00:00 2001 From: Riccardo Gandolfi Date: Mon, 25 May 2026 10:56:19 +0200 Subject: [PATCH 2/7] Re-add registers for max 16 NumStreams support (and tie-off to 0) --- src/frontend/reg/tpl/idma_reg.hjson.tpl | 6 +++--- src/frontend/reg/tpl/idma_reg.sv.tpl | 11 +++++++++-- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/src/frontend/reg/tpl/idma_reg.hjson.tpl b/src/frontend/reg/tpl/idma_reg.hjson.tpl index b7719725..5a5a4c33 100644 --- a/src/frontend/reg/tpl/idma_reg.hjson.tpl +++ b/src/frontend/reg/tpl/idma_reg.hjson.tpl @@ -68,7 +68,7 @@ ${params} desc: "DMA Status", swaccess: "ro", hwaccess: "hwo", - count: "2", + count: "16", cname: "status", hwext: "true", compact: "false", @@ -86,7 +86,7 @@ ${params} swaccess: "ro", hwaccess: "hrw", hwre: "true", - count: "2", + count: "16", cname: "next_id", hwext: "true", compact: "false", @@ -103,7 +103,7 @@ ${params} desc: "Get ID of finished transactions.", swaccess: "ro", hwaccess: "hwo", - count: "2", + count: "16", cname: "done_id", hwext: "true", compact: "false", diff --git a/src/frontend/reg/tpl/idma_reg.sv.tpl b/src/frontend/reg/tpl/idma_reg.sv.tpl index 86573735..2bdfec08 100644 --- a/src/frontend/reg/tpl/idma_reg.sv.tpl +++ b/src/frontend/reg/tpl/idma_reg.sv.tpl @@ -47,8 +47,8 @@ module idma_${identifier} #( ); /// Maximum number of streams is set to 16. It can be enlarged, but the register file - /// needs to be adapted too. It's set to 2 here to avoid binding to 0 useless registers in the pulp_cluster instance - localparam int unsigned MaxNumStreams = 32'd2; + /// needs to be adapted too. + localparam int unsigned MaxNumStreams = 32'd16; `APB_TYPEDEF_ALL(apb, logic[31:0], logic[31:0], logic[3:0]) apb_req_t [NumRegs-1:0] apb_req; @@ -221,6 +221,13 @@ module idma_${identifier} #( assign dma_hw2reg[i].done_id[c].rd_ack = '0; end + // tie-off unused channels + for (genvar c = NumStreams; c < MaxNumStreams; c++) begin : gen_hw2reg_unused + assign dma_hw2reg[i].status[c] = '0; + assign dma_hw2reg[i].next_id[c] = '0; + assign dma_hw2reg[i].done_id[c] = '0; + end + end // arbitration From 3e28b8958ae045f21720f2a8bfc1a7007736832f Mon Sep 17 00:00:00 2001 From: Riccardo Gandolfi Date: Mon, 8 Jun 2026 15:53:42 +0200 Subject: [PATCH 3/7] Adjust name for burst length --- src/backend/idma_legalizer_page_splitter.sv | 4 ++-- src/backend/tpl/idma_backend.sv.tpl | 6 +++--- src/backend/tpl/idma_backend_synth.sv.tpl | 8 ++++---- src/backend/tpl/idma_legalizer.sv.tpl | 8 ++++---- 4 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/backend/idma_legalizer_page_splitter.sv b/src/backend/idma_legalizer_page_splitter.sv index 5805c7a6..1945ed3c 100644 --- a/src/backend/idma_legalizer_page_splitter.sv +++ b/src/backend/idma_legalizer_page_splitter.sv @@ -7,7 +7,7 @@ /// Legalizer module implementing a page splitter module idma_legalizer_page_splitter #( - parameter int unsigned Burst_len = 4'd5, + parameter int unsigned BurstLen = 4'd5, parameter int unsigned OffsetWidth = 32'd2, parameter int unsigned PageAddrWidth = 32'd5, parameter type addr_t = logic, @@ -35,7 +35,7 @@ module idma_legalizer_page_splitter #( end else begin // should the "virtual" page be reduced? e.g. the transfers split into // smaller chunks than the AXI page size? - page_addr_width = OffsetWidth + (reduce_len_i ? max_llen_i : Burst_len); + page_addr_width = OffsetWidth + (reduce_len_i ? max_llen_i : BurstLen); // a page can be a maximum of 4kB (12 bit) page_addr_width = page_addr_width > 'd12 ? 'd12 : page_addr_width; end diff --git a/src/backend/tpl/idma_backend.sv.tpl b/src/backend/tpl/idma_backend.sv.tpl index 0d4d0d39..5cbe9d60 100644 --- a/src/backend/tpl/idma_backend.sv.tpl +++ b/src/backend/tpl/idma_backend.sv.tpl @@ -29,6 +29,8 @@ module idma_backend_${name_uniqueifier} #( parameter int unsigned TFLenWidth = 32'd24, /// The depth of the memory system the backend is attached to parameter int unsigned MemSysDepth = 32'd0, + /// Burst Len (for actual burst length do 8 byte * 2^(BurstLen)) + parameter int unsigned BurstLen = 4'd5, /// Should both data shifts be done before the dataflow element? /// If this is enabled, then the data inserted into the dataflow element /// will no longer be word aligned, but only a single shifter is needed @@ -83,8 +85,6 @@ module idma_backend_${name_uniqueifier} #( % endif % endfor , - /// Burst Len (for actual burst length do 8 byte * 2^(Burst_len)) - parameter int unsigned Burst_len = 4'd5, /// Address Read Channel type parameter type read_meta_channel_t = logic, /// Address Write Channel type @@ -432,7 +432,7 @@ _rsp_t ${mh_format['aw'][protocol]}${protocol}_write_rsp_i, .CombinedShifter ( CombinedShifter ), .DataWidth ( DataWidth ), .AddrWidth ( AddrWidth ), - .Burst_len ( Burst_len ), + .BurstLen ( BurstLen ), .idma_req_t ( idma_req_t ), .idma_r_req_t ( idma_r_req_t ), .idma_w_req_t ( idma_w_req_t ), diff --git a/src/backend/tpl/idma_backend_synth.sv.tpl b/src/backend/tpl/idma_backend_synth.sv.tpl index e865f5d1..b9f68f10 100644 --- a/src/backend/tpl/idma_backend_synth.sv.tpl +++ b/src/backend/tpl/idma_backend_synth.sv.tpl @@ -32,6 +32,8 @@ module idma_backend_synth_${name_uniqueifier} #( parameter int unsigned TFLenWidth = 32'd32, /// The depth of the memory system the backend is attached to parameter int unsigned MemSysDepth = 32'd0, + /// Burst Len (for actual burst length do 8 byte * 2^(BurstLen)) + parameter int unsigned BurstLen = 4'd5, /// Should both data shifts be done before the dataflow element? /// If this is enabled, then the data inserted into the dataflow element /// will no longer be word aligned, but only a single shifter is needed @@ -81,9 +83,7 @@ module idma_backend_synth_${name_uniqueifier} #( /// Transfer length type (do not override!) parameter type tf_len_t = logic[TFLenWidth-1:0], /// Offset type (do not override!) - parameter type offset_t = logic[OffsetWidth-1:0], - /// Burst Len (for actual burst length do 8 byte * 2^(Burst_len)) - parameter int unsigned Burst_len = 4'd5 + parameter type offset_t = logic[OffsetWidth-1:0] )( input logic clk_i, input logic rst_ni, @@ -328,7 +328,7 @@ ${p}_${database[p]['write_meta_channel']}_width\ % endif % endfor , - .Burst_len ( Burst_len ), + .BurstLen ( BurstLen ), .write_meta_channel_t ( write_meta_channel_t ), .read_meta_channel_t ( read_meta_channel_t ) ) i_idma_backend ( diff --git a/src/backend/tpl/idma_legalizer.sv.tpl b/src/backend/tpl/idma_legalizer.sv.tpl index 2bf6af9f..90d430b4 100644 --- a/src/backend/tpl/idma_legalizer.sv.tpl +++ b/src/backend/tpl/idma_legalizer.sv.tpl @@ -21,8 +21,8 @@ module idma_legalizer_${name_uniqueifier} #( parameter int unsigned DataWidth = 32'd16, /// Address width parameter int unsigned AddrWidth = 32'd24, - /// Burst Len (for actual burst length do 8 byte * 2^(Burst_len)) - parameter int unsigned Burst_len = 4'd5, + /// Burst Len (for actual burst length do 8 byte * 2^(BurstLen)) + parameter int unsigned BurstLen = 4'd5, /// 1D iDMA request type: /// - `length`: the length of the transfer in bytes /// - `*_addr`: the source / target byte addresses of the transfer @@ -184,7 +184,7 @@ ${database[p]['max_beats_per_burst']} * StrbWidth > ${database[p]['page_size']}\ //-------------------------------------- % if no_read_bursting or has_page_read_bursting: idma_legalizer_page_splitter #( - .Burst_len ( Burst_len ), + .BurstLen ( BurstLen ), .OffsetWidth ( OffsetWidth ), .PageAddrWidth ( PageAddrWidth ), .addr_t ( addr_t ), @@ -263,7 +263,7 @@ r_num_bytes_to_pb = r_page_num_bytes_to_pb; //-------------------------------------- % if no_write_bursting or has_page_write_bursting: idma_legalizer_page_splitter #( - .Burst_len ( Burst_len ), + .BurstLen ( BurstLen ), .OffsetWidth ( OffsetWidth ), .PageAddrWidth ( PageAddrWidth ), .addr_t ( addr_t ), From 99f0f6a356fb1180bb8be0d5d38e89ddd1643b6c Mon Sep 17 00:00:00 2001 From: RiccardoGandolfi Date: Tue, 16 Jun 2026 08:51:12 +0200 Subject: [PATCH 4/7] Update src/backend/idma_legalizer_page_splitter.sv Co-authored-by: Daniel Keller --- src/backend/idma_legalizer_page_splitter.sv | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/idma_legalizer_page_splitter.sv b/src/backend/idma_legalizer_page_splitter.sv index 1945ed3c..a7243d61 100644 --- a/src/backend/idma_legalizer_page_splitter.sv +++ b/src/backend/idma_legalizer_page_splitter.sv @@ -7,7 +7,7 @@ /// Legalizer module implementing a page splitter module idma_legalizer_page_splitter #( - parameter int unsigned BurstLen = 4'd5, + parameter int unsigned BurstLen = 4'd8, parameter int unsigned OffsetWidth = 32'd2, parameter int unsigned PageAddrWidth = 32'd5, parameter type addr_t = logic, From 2390a5731642693a686a9c8df27c1da2bb5eb559 Mon Sep 17 00:00:00 2001 From: RiccardoGandolfi Date: Tue, 16 Jun 2026 09:56:38 +0200 Subject: [PATCH 5/7] Update src/backend/tpl/idma_backend_synth.sv.tpl Co-authored-by: Daniel Keller --- src/backend/tpl/idma_backend_synth.sv.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/tpl/idma_backend_synth.sv.tpl b/src/backend/tpl/idma_backend_synth.sv.tpl index b9f68f10..d2de84f5 100644 --- a/src/backend/tpl/idma_backend_synth.sv.tpl +++ b/src/backend/tpl/idma_backend_synth.sv.tpl @@ -33,7 +33,7 @@ module idma_backend_synth_${name_uniqueifier} #( /// The depth of the memory system the backend is attached to parameter int unsigned MemSysDepth = 32'd0, /// Burst Len (for actual burst length do 8 byte * 2^(BurstLen)) - parameter int unsigned BurstLen = 4'd5, + parameter int unsigned BurstLen = 4'd8, /// Should both data shifts be done before the dataflow element? /// If this is enabled, then the data inserted into the dataflow element /// will no longer be word aligned, but only a single shifter is needed From f0efc1edac14e16ca78ba5ce76193d1827556885 Mon Sep 17 00:00:00 2001 From: RiccardoGandolfi Date: Tue, 16 Jun 2026 09:56:51 +0200 Subject: [PATCH 6/7] Update src/backend/tpl/idma_backend.sv.tpl Co-authored-by: Daniel Keller --- src/backend/tpl/idma_backend.sv.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/tpl/idma_backend.sv.tpl b/src/backend/tpl/idma_backend.sv.tpl index 5cbe9d60..134c33e6 100644 --- a/src/backend/tpl/idma_backend.sv.tpl +++ b/src/backend/tpl/idma_backend.sv.tpl @@ -30,7 +30,7 @@ module idma_backend_${name_uniqueifier} #( /// The depth of the memory system the backend is attached to parameter int unsigned MemSysDepth = 32'd0, /// Burst Len (for actual burst length do 8 byte * 2^(BurstLen)) - parameter int unsigned BurstLen = 4'd5, + parameter int unsigned BurstLen = 4'd8, /// Should both data shifts be done before the dataflow element? /// If this is enabled, then the data inserted into the dataflow element /// will no longer be word aligned, but only a single shifter is needed From c0627e7af2cbd3b2c2eba1943f6a038aa39c8a7e Mon Sep 17 00:00:00 2001 From: RiccardoGandolfi Date: Tue, 16 Jun 2026 09:56:59 +0200 Subject: [PATCH 7/7] Update src/backend/tpl/idma_legalizer.sv.tpl Co-authored-by: Daniel Keller --- src/backend/tpl/idma_legalizer.sv.tpl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/backend/tpl/idma_legalizer.sv.tpl b/src/backend/tpl/idma_legalizer.sv.tpl index 90d430b4..9301602c 100644 --- a/src/backend/tpl/idma_legalizer.sv.tpl +++ b/src/backend/tpl/idma_legalizer.sv.tpl @@ -22,7 +22,7 @@ module idma_legalizer_${name_uniqueifier} #( /// Address width parameter int unsigned AddrWidth = 32'd24, /// Burst Len (for actual burst length do 8 byte * 2^(BurstLen)) - parameter int unsigned BurstLen = 4'd5, + parameter int unsigned BurstLen = 4'd8, /// 1D iDMA request type: /// - `length`: the length of the transfer in bytes /// - `*_addr`: the source / target byte addresses of the transfer