Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 6 additions & 16 deletions Bender.lock
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ packages:
dependencies:
- common_cells
axi:
revision: a256a3b86394fedf19e361047fccfdd7f6ef83e4
version: 0.39.9
revision: a8c53cee2520d328d390c507c88818e8ac144c8c
version: 0.39.10
source:
Git: https://github.com/pulp-platform/axi.git
dependencies:
Expand All @@ -23,8 +23,8 @@ packages:
dependencies:
- common_cells
common_cells:
revision: 9ca8a7655f741e7dd5736669a20a301325194c28
version: 1.39.0
revision: 1281545696eb3fcba50ec5b4275993476a3c710e
version: 1.40.0
source:
Git: https://github.com/pulp-platform/common_cells.git
dependencies:
Expand All @@ -44,19 +44,9 @@ packages:
dependencies:
- common_cells
- common_verification
register_interface:
revision: d6e1d4cdaab7870f4faf3f88a1c788eaf5ac129d
version: 0.4.7
source:
Git: https://github.com/pulp-platform/register_interface.git
dependencies:
- apb
- axi
- common_cells
- common_verification
tech_cells_generic:
revision: 7968dd6e6180df2c644636bc6d2908a49f2190cf
version: 0.2.13
revision: 3a3de73632a06826b1bd9c65a0a2e92b32016845
version: 0.2.14
source:
Git: https://github.com/pulp-platform/tech_cells_generic.git
dependencies:
Expand Down
1 change: 0 additions & 1 deletion Bender.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ dependencies:
axi_stream: { git: "https://github.com/pulp-platform/axi_stream.git", version: 0.1.1 }
common_cells: { git: "https://github.com/pulp-platform/common_cells.git", version: 1.39.0 }
common_verification: { git: "https://github.com/pulp-platform/common_verification.git", version: 0.2.5 }
register_interface: { git: "https://github.com/pulp-platform/register_interface.git", version: 0.4.7 }
apb: { git: "https://github.com/pulp-platform/apb.git", version: 0.2.4 }
obi: { git: "https://github.com/pulp-platform/obi.git", version: 0.1.7 }

Expand Down
12 changes: 9 additions & 3 deletions idma.mk
Original file line number Diff line number Diff line change
Expand Up @@ -119,7 +119,7 @@ IDMA_RTL_FILES := $(IDMA_RTL_DIR)/idma_transport_layer \
IDMA_VSIM_DIR := $(IDMA_ROOT)/target/sim/vsim

define idma_gen
$(PYTHON) $(IDMA_GEN) --entity $1 --tpl $2 --db $3 --ids $4 --fids $5 $(if $7,--compute-ids $7) > $6
$(PYTHON) $(IDMA_GEN) --entity $1 --tpl $2 --db $3 --ids $4 --fids $5 $(if $7,--compute-ids $7) $(if $8,--cpuif $8) > $6
endef

# Force an RTL regen when IDMA_VIDMA_IDS changes; rewritten only on change
Expand Down Expand Up @@ -182,14 +182,18 @@ IDMA_FE_DIR := $(IDMA_ROOT)/src/frontend
IDMA_FE_REGS := desc64
IDMA_FE_REGS += $(IDMA_FE_IDS)

# Config-bus CPUIF for the register frontend: PeakRDL regblock --cpuif + matching wrapper
# packing. apb4-flat (default, industry standard); also obi-flat / passthrough / axi4-lite-flat.
IDMA_REG_CPUIF ?= apb4-flat


regwidth = $(word 1,$(subst _, ,$1))
dimension = $(word 2,$(subst _, ,$1))
log2dimension = $(shell echo $$(( $$( echo "obase=2;$$(($(1)-1))" | bc | wc -c ) - 1 )) )

$(IDMA_RTL_DIR)/idma_reg%d_reg_pkg.sv $(IDMA_RTL_DIR)/idma_reg%d_reg_top.sv $(IDMA_RTL_DIR)/idma_reg%d_addrmap_pkg.sv:
$(PEAKRDL) regblock $(IDMA_FE_DIR)/reg/idma_reg.rdl -o $(IDMA_RTL_DIR) \
--default-reset arst_n --cpuif apb4-flat \
--default-reset arst_n --cpuif $(IDMA_REG_CPUIF) \
--module-name idma_reg$*d_reg_top \
--package idma_reg$*d_reg_pkg \
-P SysAddrWidth=$(call regwidth,$*) \
Expand All @@ -205,6 +209,8 @@ $(IDMA_RTL_DIR)/idma_reg%d_reg_pkg.sv $(IDMA_RTL_DIR)/idma_reg%d_reg_top.sv $(ID
-P Log2NumDims=$(call log2dimension,$(call dimension,$*))

$(IDMA_RTL_DIR)/idma_desc64_reg_pkg.sv $(IDMA_RTL_DIR)/idma_desc64_reg_top.sv $(IDMA_RTL_DIR)/idma_desc64_addrmap_pkg.sv:
# desc64 has static, hand-written APB reg wrappers (idma_desc64_reg_wrapper.sv); it is
# APB-native and not part of the CPUIF selector — keep its reg_top apb4-flat.
$(PEAKRDL) regblock $(IDMA_FE_DIR)/desc64/idma_desc64_reg.rdl -o $(IDMA_RTL_DIR) \
--default-reset arst_n --cpuif apb4-flat \
--module-name idma_desc64_reg_top \
Expand All @@ -216,7 +222,7 @@ $(IDMA_RTL_DIR)/idma_desc64_reg_pkg.sv $(IDMA_RTL_DIR)/idma_desc64_reg_top.sv $(
--license_str="Copyright 2025 ETH Zurich and University of Bologna.\nSolderpad Hardware License, Version 0.51, see LICENSE for details.\nSPDX-License-Identifier: SHL-0.51"

$(IDMA_RTL_DIR)/idma_%_top.sv: $(IDMA_GEN) $(IDMA_FE_DIR)/reg/tpl/idma_reg.sv.tpl
$(call idma_gen,reg_top,$(IDMA_FE_DIR)/reg/tpl/idma_reg.sv.tpl,,,$*,$@)
$(call idma_gen,reg_top,$(IDMA_FE_DIR)/reg/tpl/idma_reg.sv.tpl,,,$*,$@,,$(if $(filter desc64,$*),apb4-flat,$(IDMA_REG_CPUIF)))

$(IDMA_HTML_DIR)/regs/idma_reg%d_reg/index.html:
$(PEAKRDL) html $(IDMA_FE_DIR)/reg/idma_reg.rdl -o $(IDMA_HTML_DIR)/regs/idma_reg$*d_reg \
Expand Down
147 changes: 100 additions & 47 deletions src/frontend/reg/tpl/idma_reg.sv.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,26 @@
// - Michael Rogenmoser <michaero@iis.ee.ethz.ch>
// - Thomas Benz <tbenz@iis.ee.ethz.ch>

<%
# Config-bus CPUIF family, derived from --cpuif (idma.mk IDMA_REG_CPUIF). The wrapper packs
# the PeakRDL reg_top's flat CPUIF signals into the matching req/rsp struct; the reg_top is
# generated with the same --cpuif so its port set matches the branch selected here.
if cpuif.startswith('apb'):
_fam = 'apb'
elif cpuif.startswith('obi'):
_fam = 'obi'
elif cpuif.startswith('axi4-lite'):
_fam = 'axil'
else:
raise Exception("idma_reg.sv.tpl: unsupported register CPUIF '%s' (add a branch)" % cpuif)
%>\
% if _fam == 'apb':
`include "apb/typedef.svh"
% elif _fam == 'obi':
`include "obi/typedef.svh"
% elif _fam == 'axil':
`include "axi/typedef.svh"
% endif

/// Description: Register-based front-end for iDMA
module idma_${identifier} #(
Expand All @@ -18,10 +37,22 @@ module idma_${identifier} #(
parameter int unsigned IdCounterWidth = 32'd32,
/// Dependent parameter: Stream Idx
parameter int unsigned StreamWidth = cf_math_pkg::idx_width(NumStreams),
/// Register_interface request type
parameter type reg_req_t = logic,
/// Register_interface response type
parameter type reg_rsp_t = logic,
% if _fam == 'apb':
/// APB4 request type
parameter type apb_req_t = logic,
/// APB4 response type
parameter type apb_rsp_t = logic,
% elif _fam == 'obi':
/// OBI request type
parameter type obi_req_t = logic,
/// OBI response type
parameter type obi_rsp_t = logic,
% elif _fam == 'axil':
/// AXI4-Lite request type
parameter type axi_lite_req_t = logic,
/// AXI4-Lite response type
parameter type axi_lite_rsp_t = logic,
% endif
/// DMA 1d or ND burst request type
parameter type dma_req_t = logic,
/// Dependent type for IdCounterWidth
Expand All @@ -31,9 +62,17 @@ module idma_${identifier} #(
) (
input logic clk_i,
input logic rst_ni,
/// Register interface control slave
input reg_req_t [NumRegs-1:0] dma_ctrl_req_i,
output reg_rsp_t [NumRegs-1:0] dma_ctrl_rsp_o,
/// Configuration control slave (${cpuif})
% if _fam == 'apb':
input apb_req_t [NumRegs-1:0] dma_ctrl_req_i,
output apb_rsp_t [NumRegs-1:0] dma_ctrl_rsp_o,
% elif _fam == 'obi':
input obi_req_t [NumRegs-1:0] dma_ctrl_req_i,
output obi_rsp_t [NumRegs-1:0] dma_ctrl_rsp_o,
% elif _fam == 'axil':
input axi_lite_req_t [NumRegs-1:0] dma_ctrl_req_i,
output axi_lite_rsp_t [NumRegs-1:0] dma_ctrl_rsp_o,
% endif
/// Request signals
output dma_req_t dma_req_o,
output logic req_valid_o,
Expand All @@ -51,11 +90,6 @@ module idma_${identifier} #(
localparam int unsigned MaxNumStreams = 32'd16;
localparam int unsigned RegAddrWidth = idma_${identifier}_reg_pkg::IDMA_${identifier.upper()}_REG_TOP_MIN_ADDR_WIDTH;

`APB_TYPEDEF_ALL(apb, logic[31:0], logic[31:0], logic[3:0])
apb_req_t [NumRegs-1:0] apb_req;
apb_resp_t [NumRegs-1:0] apb_rsp;


// register connections
idma_${identifier}_reg_pkg::idma_reg__out_t dma_reg2hw [NumRegs-1:0];
idma_${identifier}_reg_pkg::idma_reg__in_t dma_hw2reg [NumRegs-1:0];
Expand All @@ -65,9 +99,6 @@ module idma_${identifier} #(
logic [NumRegs-1:0] arb_valid;
logic [NumRegs-1:0] arb_ready;

// register signals
reg_rsp_t [NumRegs-1:0] dma_ctrl_rsp;

always_comb begin
stream_idx_o = '0;
for (int r = 0; r < NumRegs; r++) begin
Expand All @@ -83,48 +114,70 @@ module idma_${identifier} #(
for (genvar i = 0; i < NumRegs; i++) begin : gen_core_regs


reg_to_apb #(
.reg_req_t ( reg_req_t ),
.reg_rsp_t ( reg_rsp_t ),
.apb_req_t ( apb_req_t ),
.apb_rsp_t ( apb_resp_t )
) chs_regs_reg_to_apb (
.clk_i,
.rst_ni,
.reg_req_i ( dma_ctrl_req_i [i] ),
.reg_rsp_o ( dma_ctrl_rsp [i] ),
.apb_req_o ( apb_req [i] ),
.apb_rsp_i ( apb_rsp [i] )
);

% if _fam == 'obi':
// override the reg_top ID width so s_obi_aid/s_obi_rid match the OBI bus id width
idma_${identifier}_reg_top #(
.ID_WIDTH ( $bits(dma_ctrl_req_i[i].a.aid) )
) i_idma_${identifier}_reg_top (
% else:
idma_${identifier}_reg_top i_idma_${identifier}_reg_top (
% endif
.clk ( clk_i ),
.arst_n ( rst_ni ),

.s_apb_psel (apb_req[i].psel),
.s_apb_penable (apb_req[i].penable),
.s_apb_pwrite (apb_req[i].pwrite),
.s_apb_pprot (apb_req[i].pprot),
.s_apb_paddr (apb_req[i].paddr[RegAddrWidth-1:0]),
.s_apb_pwdata (apb_req[i].pwdata),
.s_apb_pstrb (apb_req[i].pstrb),
.s_apb_pready (apb_rsp[i].pready),
.s_apb_prdata (apb_rsp[i].prdata),
.s_apb_pslverr (apb_rsp[i].pslverr),
% if _fam == 'apb':
.s_apb_psel ( dma_ctrl_req_i[i].psel ),
.s_apb_penable ( dma_ctrl_req_i[i].penable ),
.s_apb_pwrite ( dma_ctrl_req_i[i].pwrite ),
.s_apb_pprot ( dma_ctrl_req_i[i].pprot ),
.s_apb_paddr ( dma_ctrl_req_i[i].paddr[RegAddrWidth-1:0] ),
.s_apb_pwdata ( dma_ctrl_req_i[i].pwdata ),
.s_apb_pstrb ( dma_ctrl_req_i[i].pstrb ),
.s_apb_pready ( dma_ctrl_rsp_o[i].pready ),
.s_apb_prdata ( dma_ctrl_rsp_o[i].prdata ),
.s_apb_pslverr ( dma_ctrl_rsp_o[i].pslverr ),
% elif _fam == 'obi':
.s_obi_req ( dma_ctrl_req_i[i].req ),
.s_obi_gnt ( dma_ctrl_rsp_o[i].gnt ),
.s_obi_addr ( dma_ctrl_req_i[i].a.addr[RegAddrWidth-1:0] ),
.s_obi_we ( dma_ctrl_req_i[i].a.we ),
.s_obi_be ( dma_ctrl_req_i[i].a.be ),
.s_obi_wdata ( dma_ctrl_req_i[i].a.wdata ),
.s_obi_aid ( dma_ctrl_req_i[i].a.aid ),
.s_obi_rvalid ( dma_ctrl_rsp_o[i].rvalid ),
.s_obi_rready ( dma_ctrl_req_i[i].rready ),
.s_obi_rdata ( dma_ctrl_rsp_o[i].r.rdata ),
.s_obi_err ( dma_ctrl_rsp_o[i].r.err ),
.s_obi_rid ( dma_ctrl_rsp_o[i].r.rid ),
% elif _fam == 'axil':
.s_axil_awvalid ( dma_ctrl_req_i[i].aw_valid ),
.s_axil_awready ( dma_ctrl_rsp_o[i].aw_ready ),
.s_axil_awaddr ( dma_ctrl_req_i[i].aw.addr[RegAddrWidth-1:0] ),
.s_axil_awprot ( dma_ctrl_req_i[i].aw.prot ),
.s_axil_wvalid ( dma_ctrl_req_i[i].w_valid ),
.s_axil_wready ( dma_ctrl_rsp_o[i].w_ready ),
.s_axil_wdata ( dma_ctrl_req_i[i].w.data ),
.s_axil_wstrb ( dma_ctrl_req_i[i].w.strb ),
.s_axil_bvalid ( dma_ctrl_rsp_o[i].b_valid ),
.s_axil_bready ( dma_ctrl_req_i[i].b_ready ),
.s_axil_bresp ( dma_ctrl_rsp_o[i].b.resp ),
.s_axil_arvalid ( dma_ctrl_req_i[i].ar_valid ),
.s_axil_arready ( dma_ctrl_rsp_o[i].ar_ready ),
.s_axil_araddr ( dma_ctrl_req_i[i].ar.addr[RegAddrWidth-1:0] ),
.s_axil_arprot ( dma_ctrl_req_i[i].ar.prot ),
.s_axil_rvalid ( dma_ctrl_rsp_o[i].r_valid ),
.s_axil_rready ( dma_ctrl_req_i[i].r_ready ),
.s_axil_rdata ( dma_ctrl_rsp_o[i].r.data ),
.s_axil_rresp ( dma_ctrl_rsp_o[i].r.resp ),
% endif

.hwif_out ( dma_reg2hw [i] ),
.hwif_in ( dma_hw2reg [i] )
);

logic read_happens;
// DMA backpressure
always_comb begin : proc_dma_backpressure
// ready signal
dma_ctrl_rsp_o[i] = dma_ctrl_rsp[i];
dma_ctrl_rsp_o[i].ready = read_happens ? arb_ready[i] : dma_ctrl_rsp[i];
end

// valid signals
// launch-stall: hold the reg read-ack until the arbiter accepts the request
// (protocol-agnostic — driven into hwif rd_ack below, see gen_hw2reg_connections)

always_comb begin : proc_launch
read_happens = 1'b0;
Expand Down
4 changes: 3 additions & 1 deletion util/gen_idma.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,8 @@ def main():
parser.add_argument('--fids', dest='fids', nargs='*', help='frontend IDs')
parser.add_argument('--db', dest='db', nargs='*', help='Database files')
parser.add_argument('--tpl', dest='tpl', required=True, help='Template file')
parser.add_argument('--cpuif', dest='cpuif', default='apb4-flat',
help='Register-frontend config-bus CPUIF (must match the PeakRDL regblock --cpuif)')
args = parser.parse_args()

# prepare database and ids
Expand All @@ -73,7 +75,7 @@ def main():
elif args.entity == 'reg_hjson':
print(render_reg_hjson(frontend_ids, args.tpl))
elif args.entity == 'reg_top':
print(render_reg_top(frontend_ids, args.tpl))
print(render_reg_top(frontend_ids, args.tpl, args.cpuif))
elif args.entity == 'tracer':
print(render_tracer(protocol_ids, protocol_db, args.tpl))
else:
Expand Down
5 changes: 3 additions & 2 deletions util/mario/frontend.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,7 @@ def render_reg_hjson(fe_ids: dict, tpl_file: str) -> str:
return reg_hjson_rendered


def render_reg_top(fe_ids: dict, tpl_file: str) -> str:
def render_reg_top(fe_ids: dict, tpl_file: str, cpuif: str = 'apb4-flat') -> str:
"""Generate register top"""
reg_top_rendered = ''

Expand All @@ -162,7 +162,8 @@ def render_reg_top(fe_ids: dict, tpl_file: str) -> str:
'identifier': fe_id,
'num_dim': int(fe_ids[fe_id][1]),
'sep': sep,
'bit_width': fe_ids[fe_id][0]
'bit_width': fe_ids[fe_id][0],
'cpuif': cpuif
}

# render
Expand Down