diff --git a/src/backend/idma_legalizer_page_splitter.sv b/src/backend/idma_legalizer_page_splitter.sv index 14db0e26..a7243d61 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 BurstLen = 4'd8, 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 : 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 f21e6e51..134c33e6 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'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 @@ -430,6 +432,7 @@ _rsp_t ${mh_format['aw'][protocol]}${protocol}_write_rsp_i, .CombinedShifter ( CombinedShifter ), .DataWidth ( DataWidth ), .AddrWidth ( AddrWidth ), + .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 1fce76b6..d2de84f5 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'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 @@ -326,6 +328,7 @@ ${p}_${database[p]['write_meta_channel']}_width\ % endif % endfor , + .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 47441be9..9301602c 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^(BurstLen)) + 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 @@ -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 #( + .BurstLen ( BurstLen ), .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 #( + .BurstLen ( BurstLen ), .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..5a5a4c33 --- /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: "16", + 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: "16", + 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: "16", + 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..2bdfec08 100644 --- a/src/frontend/reg/tpl/idma_reg.sv.tpl +++ b/src/frontend/reg/tpl/idma_reg.sv.tpl @@ -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