Skip to content
Closed
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
2 changes: 2 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,8 @@ jobs:
secrets: inherit

deploy:
permissions:
contents: write
needs: build
if: github.event_name == 'push'
uses: ./.github/workflows/deploy.yml
Expand Down
29 changes: 28 additions & 1 deletion .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,36 @@ name: deploy

on:
workflow_call:
inputs:
IDMA_BACKEND_IDS:
description: Backend variants to generate.
required: false
type: string
default: "rw_axi r_obi_w_axi r_axi_w_obi rw_axi_rw_axis rw_obi r_obi_rw_init_w_axi r_axi_rw_init_rw_obi rw_axi_rw_init_rw_obi"
IDMA_REG_CPUIF:
description: PeakRDL CPU interface used for generated register frontends.
required: false
type: string
default: "apb4-flat"
workflow_dispatch:
inputs:
IDMA_BACKEND_IDS:
description: Backend variants to generate.
required: false
type: string
default: "rw_axi r_obi_w_axi r_axi_w_obi rw_axi_rw_axis rw_obi r_obi_rw_init_w_axi r_axi_rw_init_rw_obi rw_axi_rw_init_rw_obi"
IDMA_REG_CPUIF:
description: PeakRDL CPU interface used for generated register frontends.
required: false
type: string
default: "apb4-flat"

jobs:

deploy:
runs-on: ubuntu-latest
permissions:
contents: write
steps:
-
name: Checkout
Expand All @@ -36,7 +60,10 @@ jobs:
version: 0.32.0
-
name: Build hardware
run: uv run --locked make -B idma_hw_all
run: |
uv run --locked make -B idma_hw_all idma_sw_all \
IDMA_BACKEND_IDS="${{ inputs.IDMA_BACKEND_IDS }}" \
IDMA_REG_CPUIF="${{ inputs.IDMA_REG_CPUIF }}"
-
name: Deploy generated files
run: |
Expand Down
30 changes: 28 additions & 2 deletions idma.mk
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ IDMA_FE_IDS ?= $(IDMA_BASE_FE_IDS) $(IDMA_ADD_FE_IDS)
# iDMA paths
IDMA_UTIL_DIR := $(IDMA_ROOT)/util
IDMA_RTL_DIR := $(IDMA_ROOT)/target/rtl
IDMA_SW_DIR := $(IDMA_ROOT)/target/sw

# job file
IDMA_JOBS_JSON := jobs/jobs.json
Expand Down Expand Up @@ -233,6 +234,21 @@ $(IDMA_HTML_DIR)/regs/idma_reg%d_reg/index.html:
$(IDMA_HTML_DIR)/regs/idma_desc64_reg/index.html:
$(PEAKRDL) html $(IDMA_FE_DIR)/desc64/idma_desc64_reg.rdl -o $(IDMA_HTML_DIR)/regs/idma_desc64_reg

# C header
$(IDMA_SW_DIR)/idma_reg%d_regs.h:
$(PEAKRDL) c-header $(IDMA_FE_DIR)/reg/idma_reg.rdl -o $@ \
-P SysAddrWidth=$(call regwidth,$*) \
-P NumDims=$(call dimension,$*) \
-P Log2NumDims=$(call log2dimension,$(call dimension,$*))


$(IDMA_SW_DIR)/idma_reg%d_raw_regs.h:
$(PEAKRDL) raw-header $(IDMA_FE_DIR)/reg/idma_reg.rdl -o $@ \
--format c \
-P SysAddrWidth=$(call regwidth,$*) \
-P NumDims=$(call dimension,$*) \
-P Log2NumDims=$(call log2dimension,$(call dimension,$*))

idma_reg_clean:
rm -rf $(IDMA_HTML_DIR)/regs
rm -f $(IDMA_RTL_DIR)/*_reg_top.sv
Expand All @@ -247,6 +263,11 @@ IDMA_RTL_ALL += $(foreach Y,$(IDMA_FE_REGS),$(IDMA_RTL_DIR)/idma_$Y_addrmap_
IDMA_RTL_ALL += $(foreach Y,$(IDMA_FE_REGS),$(IDMA_RTL_DIR)/idma_$Y_top.sv)
IDMA_RTL_DOC_ALL += $(foreach Y,$(IDMA_FE_REGS),$(IDMA_HTML_DIR)/regs/idma_$Y_reg/index.html)

# C headers
IDMA_SW_ALL += $(foreach Y,$(IDMA_FE_IDS),$(IDMA_SW_DIR)/idma_$Y_regs.h)

# C headers with the "raw-header" plugin
IDMA_SW_ALL += $(foreach Y,$(IDMA_FE_IDS),$(IDMA_SW_DIR)/idma_$Y_raw_regs.h)

# ---------------
# RTL assembly
Expand Down Expand Up @@ -549,9 +570,9 @@ idma_nonfree_clean:
# Misc Clean
# --------------

.PHONY: idma_clean_all idma_clean idma_misc_clean
.PHONY: idma_clean_all idma_clean idma_misc_clean idma_sw_clean

idma_clean_all idma_clean: idma_rtl_clean idma_reg_clean idma_pickle_clean idma_sim_clean idma_vcs_clean idma_verilator_clean idma_spinx_doc_clean idma_trace_clean
idma_clean_all idma_clean: idma_rtl_clean idma_reg_clean idma_pickle_clean idma_sim_clean idma_vcs_clean idma_verilator_clean idma_spinx_doc_clean idma_trace_clean idma_sw_clean

idma_misc_clean:
rm -rf scripts/__pycache__
Expand All @@ -562,6 +583,9 @@ idma_misc_clean:
idma_nuke: idma_clean idma_nonfree_clean
rm -rf .bender

idma_sw_clean:
rm -rf IDMA_SW_DIR/*.h


# --------------
# Phony Targets
Expand All @@ -575,6 +599,8 @@ idma_pickle_all: $(IDMA_PICKLE_ALL)

idma_hw_all: $(IDMA_FULL_RTL) $(IDMA_INCLUDE_ALL) $(IDMA_FULL_TB) $(IDMA_HJSON_ALL) $(IDMA_WAVE_ALL)

idma_sw_all: $(IDMA_SW_ALL)

idma_sim_all: $(IDMA_VCS_DIR)/compile.sh $(IDMA_VSIM_DIR)/compile.tcl

idma_all: idma_hw_all idma_sim_all idma_doc_all idma_pickle_all
1 change: 1 addition & 0 deletions pyproject.toml
Original file line number Diff line number Diff line change
Expand Up @@ -20,4 +20,5 @@ dependencies = [
"pylint",
"peakrdl>=1.5.0",
"peakrdl-rawheader>=0.2.4",
"peakrdl-cheader>=1.1.0",
]
92 changes: 48 additions & 44 deletions src/frontend/reg/tpl/idma_reg.sv.tpl
Original file line number Diff line number Diff line change
Expand Up @@ -95,20 +95,19 @@ module idma_${identifier} #(
idma_${identifier}_reg_pkg::idma_reg__in_t dma_hw2reg [NumRegs-1:0];

// arbitration output
dma_req_t [NumRegs-1:0] arb_dma_req;
logic [NumRegs-1:0] arb_valid;
logic [NumRegs-1:0] arb_ready;
typedef struct packed {
dma_req_t req;
stream_t stream_idx;
} arb_payload_t;

always_comb begin
stream_idx_o = '0;
for (int r = 0; r < NumRegs; r++) begin
for (int c = 0; c < NumStreams; c++) begin
if (dma_reg2hw[r].next_id[c].req && !dma_reg2hw[r].next_id[c].req_is_wr) begin
stream_idx_o = c;
end
end
end
end
arb_payload_t [NumRegs-1:0] arb_payload;
arb_payload_t arb_payload_out;
stream_t [NumRegs-1:0] arb_stream_idx;
logic [NumRegs-1:0] arb_valid;
logic [NumRegs-1:0] arb_ready;

assign dma_req_o = arb_payload_out.req;
assign stream_idx_o = arb_payload_out.stream_idx;

// generate the registers
for (genvar i = 0; i < NumRegs; i++) begin : gen_core_regs
Expand Down Expand Up @@ -181,74 +180,79 @@ module idma_${identifier} #(

always_comb begin : proc_launch
read_happens = 1'b0;
arb_stream_idx[i] = '0;
for (int c = 0; c < NumStreams; c++) begin
read_happens |= dma_reg2hw[i].next_id[c].req & ~dma_reg2hw[i].next_id[c].req_is_wr;
if (dma_reg2hw[i].next_id[c].req & ~dma_reg2hw[i].next_id[c].req_is_wr) begin
read_happens = 1'b1;
arb_stream_idx[i] = stream_t'(c);
end
end
arb_valid[i] = read_happens;
end

// assign request struct
always_comb begin : proc_hw_req_conv
// all fields are zero per default
arb_dma_req[i] = '0;
arb_payload[i] = '0;
arb_payload[i].stream_idx = arb_stream_idx[i];

// address and length
% if bit_width == '32':
arb_dma_req[i]${sep}length = dma_reg2hw[i].length[0].length.value;
arb_dma_req[i]${sep}src_addr = dma_reg2hw[i].src_addr[0].src_addr.value;
arb_dma_req[i]${sep}dst_addr = dma_reg2hw[i].dst_addr[0].dst_addr.value;
arb_payload[i].req${sep}length = dma_reg2hw[i].length[0].length.value;
arb_payload[i].req${sep}src_addr = dma_reg2hw[i].src_addr[0].src_addr.value;
arb_payload[i].req${sep}dst_addr = dma_reg2hw[i].dst_addr[0].dst_addr.value;
% else:
arb_dma_req[i]${sep}length = {dma_reg2hw[i].length[1].length.value, dma_reg2hw[i].length[0].length.value};
arb_dma_req[i]${sep}src_addr = {dma_reg2hw[i].src_addr[1].src_addr.value, dma_reg2hw[i].src_addr[0].src_addr.value};
arb_dma_req[i]${sep}dst_addr = {dma_reg2hw[i].dst_addr[1].dst_addr.value, dma_reg2hw[i].dst_addr[0].dst_addr.value};
arb_payload[i].req${sep}length = {dma_reg2hw[i].length[1].length.value, dma_reg2hw[i].length[0].length.value};
arb_payload[i].req${sep}src_addr = {dma_reg2hw[i].src_addr[1].src_addr.value, dma_reg2hw[i].src_addr[0].src_addr.value};
arb_payload[i].req${sep}dst_addr = {dma_reg2hw[i].dst_addr[1].dst_addr.value, dma_reg2hw[i].dst_addr[0].dst_addr.value};
% endif

// Protocols
arb_dma_req[i]${sep}opt.src_protocol = idma_pkg::protocol_e'(dma_reg2hw[i].conf.src_protocol.value);
arb_dma_req[i]${sep}opt.dst_protocol = idma_pkg::protocol_e'(dma_reg2hw[i].conf.dst_protocol.value);
arb_payload[i].req${sep}opt.src_protocol = idma_pkg::protocol_e'(dma_reg2hw[i].conf.src_protocol.value);
arb_payload[i].req${sep}opt.dst_protocol = idma_pkg::protocol_e'(dma_reg2hw[i].conf.dst_protocol.value);

// Current backend only supports incremental burst
arb_dma_req[i]${sep}opt.src.burst = axi_pkg::BURST_INCR;
arb_dma_req[i]${sep}opt.dst.burst = axi_pkg::BURST_INCR;
arb_payload[i].req${sep}opt.src.burst = axi_pkg::BURST_INCR;
arb_payload[i].req${sep}opt.dst.burst = axi_pkg::BURST_INCR;
// this frontend currently does not support cache variations
arb_dma_req[i]${sep}opt.src.cache = axi_pkg::CACHE_MODIFIABLE;
arb_dma_req[i]${sep}opt.dst.cache = axi_pkg::CACHE_MODIFIABLE;
arb_payload[i].req${sep}opt.src.cache = axi_pkg::CACHE_MODIFIABLE;
arb_payload[i].req${sep}opt.dst.cache = axi_pkg::CACHE_MODIFIABLE;

// Backend options
arb_dma_req[i]${sep}opt.beo.decouple_aw = dma_reg2hw[i].conf.decouple_aw.value;
arb_dma_req[i]${sep}opt.beo.decouple_rw = dma_reg2hw[i].conf.decouple_rw.value;
arb_dma_req[i]${sep}opt.beo.src_max_llen = dma_reg2hw[i].conf.src_max_llen.value;
arb_dma_req[i]${sep}opt.beo.dst_max_llen = dma_reg2hw[i].conf.dst_max_llen.value;
arb_dma_req[i]${sep}opt.beo.src_reduce_len = dma_reg2hw[i].conf.src_reduce_len.value;
arb_dma_req[i]${sep}opt.beo.dst_reduce_len = dma_reg2hw[i].conf.dst_reduce_len.value;
arb_payload[i].req${sep}opt.beo.decouple_aw = dma_reg2hw[i].conf.decouple_aw.value;
arb_payload[i].req${sep}opt.beo.decouple_rw = dma_reg2hw[i].conf.decouple_rw.value;
arb_payload[i].req${sep}opt.beo.src_max_llen = dma_reg2hw[i].conf.src_max_llen.value;
arb_payload[i].req${sep}opt.beo.dst_max_llen = dma_reg2hw[i].conf.dst_max_llen.value;
arb_payload[i].req${sep}opt.beo.src_reduce_len = dma_reg2hw[i].conf.src_reduce_len.value;
arb_payload[i].req${sep}opt.beo.dst_reduce_len = dma_reg2hw[i].conf.dst_reduce_len.value;

% if num_dim != 1:
// ND connections
% for nd in range(0, num_dim-1):
% if bit_width == '32':
arb_dma_req[i].d_req[${nd}].reps = dma_reg2hw[i].dim[${nd}].reps[0].reps.value;
arb_dma_req[i].d_req[${nd}].src_strides = dma_reg2hw[i].dim[${nd}].src_stride[0].src_stride.value;
arb_dma_req[i].d_req[${nd}].dst_strides = dma_reg2hw[i].dim[${nd}].dst_stride[0].dst_stride.value;
arb_payload[i].req.d_req[${nd}].reps = dma_reg2hw[i].dim[${nd}].reps[0].reps.value;
arb_payload[i].req.d_req[${nd}].src_strides = dma_reg2hw[i].dim[${nd}].src_stride[0].src_stride.value;
arb_payload[i].req.d_req[${nd}].dst_strides = dma_reg2hw[i].dim[${nd}].dst_stride[0].dst_stride.value;
% else:
arb_dma_req[i].d_req[${nd}].reps = {dma_reg2hw[i].dim[${nd}].reps[1].reps.value,
arb_payload[i].req.d_req[${nd}].reps = {dma_reg2hw[i].dim[${nd}].reps[1].reps.value,
dma_reg2hw[i].dim[${nd}].reps[0].reps.value };
arb_dma_req[i].d_req[${nd}].src_strides = {dma_reg2hw[i].dim[${nd}].src_stride[1].src_stride.value,
arb_payload[i].req.d_req[${nd}].src_strides = {dma_reg2hw[i].dim[${nd}].src_stride[1].src_stride.value,
dma_reg2hw[i].dim[${nd}].src_stride[0].src_stride.value};
arb_dma_req[i].d_req[${nd}].dst_strides = {dma_reg2hw[i].dim[${nd}].dst_stride[1].dst_stride.value,
arb_payload[i].req.d_req[${nd}].dst_strides = {dma_reg2hw[i].dim[${nd}].dst_stride[1].dst_stride.value,
dma_reg2hw[i].dim[${nd}].dst_stride[0].dst_stride.value};
% endif
% endfor

// Disable higher dimensions
if ( dma_reg2hw[i].conf.enable_nd.value == 0) begin
% for nd in range(0, num_dim-1):
arb_dma_req[i].d_req[${nd}].reps = ${"'0" if nd != num_dim-2 else "'d1"};
arb_payload[i].req.d_req[${nd}].reps = ${"'0" if nd != num_dim-2 else "'d1"};
% endfor
end
% for nd in range(1, num_dim-1):
else if ( dma_reg2hw[i].conf.enable_nd.value == ${nd}) begin
% for snd in range(nd, num_dim-1):
arb_dma_req[i].d_req[${snd}].reps = 'd1;
arb_payload[i].req.d_req[${snd}].reps = 'd1;
% endfor
end
% endfor
Expand Down Expand Up @@ -284,7 +288,7 @@ module idma_${identifier} #(
// arbitration
rr_arb_tree #(
.NumIn ( NumRegs ),
.DataType ( dma_req_t ),
.DataType ( arb_payload_t ),
.ExtPrio ( 0 ),
.AxiVldRdy ( 1 ),
.LockIn ( 1 )
Expand All @@ -295,10 +299,10 @@ module idma_${identifier} #(
.rr_i ( '0 ),
.req_i ( arb_valid ),
.gnt_o ( arb_ready ),
.data_i ( arb_dma_req ),
.data_i ( arb_payload ),
.gnt_i ( req_ready_i ),
.req_o ( req_valid_o ),
.data_o ( dma_req_o ),
.data_o ( arb_payload_out ),
.idx_o ( /* NC */ )
);

Expand Down
1 change: 1 addition & 0 deletions target/sw/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
*.h
Loading