Skip to content

Commit

Permalink
Create a dataflow-oriented descriptor-based iDMA frontend supporting …
Browse files Browse the repository at this point in the history
…prefetching.

- tracer: Add WIP version of the iDMA tracer (#9), add some fixes (#14)
- frontends/desc64: Transition Regbus master to AXI master
- jobs.json: Add descriptor-based testbench to the job file
- frontends/desc64: Update synth module for descriptor frontend
- test/frontends: Add testbench for benchmarking (***caution: not to be used as VIP***)
- frontends/desc64: Remove unused shared counter
- Makefile: Quote paths to handle spaces in paths
- frontends/desc64: Add prefetching design
  • Loading branch information
thommythomaso committed Oct 31, 2022
1 parent 4456785 commit d2eeeee
Show file tree
Hide file tree
Showing 30 changed files with 3,078 additions and 916 deletions.
10 changes: 10 additions & 0 deletions .gitlab-ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -71,3 +71,13 @@ tiny-dma-run:
job: prepare-non-free
strategy: depend

frontend-descriptor-run:
stage: iDMA
needs:
- prepare-non-free
trigger:
include:
- artifact: idma-non-free/ci/gitlab-frontend-descriptor-ci.yml
job: prepare-non-free
strategy: depend

10 changes: 9 additions & 1 deletion Bender.yml
Original file line number Diff line number Diff line change
Expand Up @@ -61,13 +61,20 @@ sources:

- files: # 64bit descriptor frontend
# Level 0
- src/frontends/desc64/idma_desc64_ar_gen.sv
- src/frontends/desc64/idma_desc64_ar_gen_prefetch.sv
- src/frontends/desc64/idma_desc64_reader.sv
- src/frontends/desc64/idma_desc64_reader_gater.sv
- src/frontends/desc64/idma_desc64_reg_pkg.sv
- src/frontends/desc64/idma_desc64_reg_top.sv
- src/frontends/desc64/idma_desc64_shared_counter.sv
- src/frontends/desc64/idma_desc64_reshaper.sv
# Level 1
- src/frontends/desc64/idma_desc64_reg_wrapper.sv
# Level 2
- src/frontends/desc64/idma_desc64_top.sv
- src/systems/cva6_desc/dma_desc_wrap.sv
- src/systems/cva6_desc/dma_desc_synth_pkg.sv
- src/systems/cva6_desc/dma_desc_synth.sv

# Systems
- target: all(pulp, not(mchan))
Expand Down Expand Up @@ -99,3 +106,4 @@ sources:
files:
# Level 0
- test/frontends/tb_idma_desc64_top.sv
- test/frontends/tb_idma_desc64_bench.sv
60 changes: 30 additions & 30 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -291,39 +291,39 @@ REG_HTML_STRING = "<!DOCTYPE html>\n<html>\n<head>\n<link rel="stylesheet" href=
gen_regs: reg32_2d_regs reg64_regs desc64_regs

reg32_2d_regs:
$(PYTHON) $(REG_TOOL) $(REG32_2D_HJSON) -t $(REG32_2D_FE_DIR) -r
$(PYTHON) $(REG_TOOL) $(REG32_2D_HJSON) -D > $(REG32_2D_FE_DIR)/idma_reg32_2d_frontend.h
printf $(REG_HTML_STRING) > $(REG32_2D_FE_DIR)/idma_reg32_2d_frontend.html
$(PYTHON) $(REG_TOOL) $(REG32_2D_HJSON) -d >> $(REG32_2D_FE_DIR)/idma_reg32_2d_frontend.html
printf "</html>\n" >> $(REG32_2D_FE_DIR)/idma_reg32_2d_frontend.html
cp $(REG_PATH)/vendor/lowrisc_opentitan/util/reggen/reg_html.css $(REG32_2D_FE_DIR)
"$(PYTHON)" "$(REG_TOOL)" "$(REG32_2D_HJSON)" -t "$(REG32_2D_FE_DIR)" -r
"$(PYTHON)" "$(REG_TOOL)" "$(REG32_2D_HJSON)" -D > "$(REG32_2D_FE_DIR)/idma_reg32_2d_frontend.h"
printf $(REG_HTML_STRING) > "$(REG32_2D_FE_DIR)/idma_reg32_2d_frontend.html"
"$(PYTHON)" "$(REG_TOOL)" "$(REG32_2D_HJSON)" -d >> "$(REG32_2D_FE_DIR)/idma_reg32_2d_frontend.html"
printf "</html>\n" >> "$(REG32_2D_FE_DIR)/idma_reg32_2d_frontend.html"
cp "$(REG_PATH)/vendor/lowrisc_opentitan/util/reggen/reg_html.css" "$(REG32_2D_FE_DIR)"

reg64_regs:
$(PYTHON) $(REG_TOOL) $(REG64_HJSON) -t $(REG64_FE_DIR) -r
$(PYTHON) $(REG_TOOL) $(REG64_HJSON) -D > $(REG64_FE_DIR)/idma_reg64_frontend.h
printf $(REG_HTML_STRING) > $(REG64_FE_DIR)/idma_reg64_frontend.html
$(PYTHON) $(REG_TOOL) $(REG64_HJSON) -d >> $(REG64_FE_DIR)/idma_reg64_frontend.html
printf "</html>\n" >> $(REG64_FE_DIR)/idma_reg64_frontend.html
cp $(REG_PATH)/vendor/lowrisc_opentitan/util/reggen/reg_html.css $(REG64_FE_DIR)
"$(PYTHON)" "$(REG_TOOL)" "$(REG64_HJSON)" -t "$(REG64_FE_DIR)" -r
"$(PYTHON)" "$(REG_TOOL)" "$(REG64_HJSON)" -D > "$(REG64_FE_DIR)/idma_reg64_frontend.h"
printf $(REG_HTML_STRING) > "$(REG64_FE_DIR)/idma_reg64_frontend.html"
"$(PYTHON)" "$(REG_TOOL)" "$(REG64_HJSON)" -d >> "$(REG64_FE_DIR)/idma_reg64_frontend.html"
printf "</html>\n" >> "$(REG64_FE_DIR)/idma_reg64_frontend.html"
cp "$(REG_PATH)/vendor/lowrisc_opentitan/util/reggen/reg_html.css" "$(REG64_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
printf $(REG_HTML_STRING) > $(DESC64_FE_DIR)/idma_desc64_frontend.html
$(PYTHON) $(REG_TOOL) $(DESC64_HJSON) -d >> $(DESC64_FE_DIR)/idma_desc64_frontend.html
printf "</html>\n" >> $(DESC64_FE_DIR)/idma_desc64_frontend.html
cp $(REG_PATH)/vendor/lowrisc_opentitan/util/reggen/reg_html.css $(DESC64_FE_DIR)
"$(PYTHON)" "$(REG_TOOL)" "$(DESC64_HJSON)" -t "$(DESC64_FE_DIR)" -r
"$(PYTHON)" "$(REG_TOOL)" "$(DESC64_HJSON)" -D > "$(DESC64_FE_DIR)/idma_desc64_frontend.h"
printf $(REG_HTML_STRING) > "$(DESC64_FE_DIR)/idma_desc64_frontend.html"
"$(PYTHON)" "$(REG_TOOL)" "$(DESC64_HJSON)" -d >> "$(DESC64_FE_DIR)/idma_desc64_frontend.html"
printf "</html>\n" >> "$(DESC64_FE_DIR)/idma_desc64_frontend.html"
cp "$(REG_PATH)/vendor/lowrisc_opentitan/util/reggen/reg_html.css" "$(DESC64_FE_DIR)"

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)/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)/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)/reg_html.css
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)/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)/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)/reg_html.css"
12 changes: 12 additions & 0 deletions jobs.json
Original file line number Diff line number Diff line change
Expand Up @@ -79,5 +79,17 @@
"synth_top" : "idma_nd_backend_synth",
"overrides" : {
}
},
"frontend-descriptor": {
"seed" : 1336,
"man_jobs" : {
"simple" : "/dev/null"
},
"gen_jobs" : {
},
"testbench" : "tb_idma_desc64_top",
"synth_top" : "idma_desc64_synth",
"overrides" : {
}
}
}
24 changes: 24 additions & 0 deletions scripts/frontend/bench.tcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# Copyright 2022 ETH Zurich and University of Bologna.
# Solderpad Hardware License, Version 0.51, see LICENSE for details.
# SPDX-License-Identifier: SHL-0.51

# Axel Vanoni <[email protected]>

source scripts/compile_vsim.tcl
vsim tb_idma_desc64_bench -t 1ps \
-GNumberOfTests=150 \
-GChainedDescriptors=20 \
-GSimulationTimeoutCycles=300000 \
-GTransferLength=24 \
-GDoIRQ=0 \
+trace_file=trace-test.log \
-voptargs=+acc
#-voptargs=-pedantic

set StdArithNoWarnings 1
set NumericStdNoWarnings 1
log -r /*

source scripts/waves/vsim_fe_desc64.do

run -all
22 changes: 22 additions & 0 deletions scripts/frontend/run-no-chain.tcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# Copyright 2022 ETH Zurich and University of Bologna.
# Solderpad Hardware License, Version 0.51, see LICENSE for details.
# SPDX-License-Identifier: SHL-0.51

# Axel Vanoni <[email protected]>

# run frontend tests without chaining
source scripts/compile_vsim.tcl
vsim tb_idma_desc64_top -t 1ps \
-GNumberOfTests=20 \
-GMaxChainedDescriptors=1 \
-GSimulationTimeoutCycles=2000 \
-voptargs=+acc
#-voptargs=-pedantic

set StdArithNoWarnings 1
set NumericStdNoWarnings 1
log -r /*

source scripts/waves/vsim_fe_desc64.do

run -all
21 changes: 21 additions & 0 deletions scripts/frontend/run-one.tcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# Copyright 2022 ETH Zurich and University of Bologna.
# Solderpad Hardware License, Version 0.51, see LICENSE for details.
# SPDX-License-Identifier: SHL-0.51

# Axel Vanoni <[email protected]>

# run frontend tests with one transfer
source scripts/compile_vsim.tcl
vsim tb_idma_desc64_top -t 1ps -GNumberOfTests=1 \
-GSimulationTimeoutCycles=200 \
-GMaxChainedDescriptors=1 \
-voptargs=+acc
#-voptargs=-pedantic

set StdArithNoWarnings 1
set NumericStdNoWarnings 1
log -r /*

source scripts/waves/vsim_fe_desc64.do

run -all
23 changes: 23 additions & 0 deletions scripts/frontend/run-only-chain.tcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# Copyright 2022 ETH Zurich and University of Bologna.
# Solderpad Hardware License, Version 0.51, see LICENSE for details.
# SPDX-License-Identifier: SHL-0.51

# Axel Vanoni <[email protected]>

# run tests with only chaining
source scripts/compile_vsim.tcl
vsim tb_idma_desc64_top -t 1ps \
-GMaxChainedDescriptors=100 \
-GMinChainedDescriptors=100 \
-GSimulationTimeoutCycles=2000 \
-GNumberOfTests=1 \
-voptargs=+acc
#-voptargs=-pedantic

set StdArithNoWarnings 1
set NumericStdNoWarnings 1
log -r /*

source scripts/waves/vsim_fe_desc64.do

run -all
18 changes: 18 additions & 0 deletions scripts/frontend/run.tcl
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# Copyright 2022 ETH Zurich and University of Bologna.
# Solderpad Hardware License, Version 0.51, see LICENSE for details.
# SPDX-License-Identifier: SHL-0.51

# Axel Vanoni <[email protected]>

# run frontend tests with default settings
source scripts/compile_vsim.tcl

vsim tb_idma_desc64_top -t 1ps -voptargs=+acc
#-voptargs=-pedantic

source scripts/waves/vsim_fe_desc64.do

set StdArithNoWarnings 1
set NumericStdNoWarnings 1
log -r /*
run -all
17 changes: 17 additions & 0 deletions scripts/waves/vsim_fe_desc64.do
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
onerror {resume}
quietly WaveActivateNextPane {} 0
add wave -position end i_dut/clk_i
add wave -position end i_dut/rst_ni
add wave -position end i_dut/master_req_o
add wave -position end i_dut/master_rsp_i
add wave -position end i_dut/slave_req_i
add wave -position end i_dut/slave_rsp_o
add wave -position end i_dut/idma_req_o
add wave -position end i_dut/idma_req_ready_i
add wave -position end i_dut/idma_req_valid_o
add wave -position end i_dut/idma_rsp_ready_o
add wave -position end i_dut/idma_rsp_valid_i
add wave -position end i_dut/idma_busy_i
add wave -position end i_dut/irq_o

quietly wave cursor active 1
132 changes: 132 additions & 0 deletions src/frontends/desc64/idma_desc64_ar_gen.sv
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
// Copyright 2022 ETH Zurich and University of Bologna.
// Solderpad Hardware License, Version 0.51, see LICENSE for details.
// SPDX-License-Identifier: SHL-0.51

// Axel Vanoni <[email protected]>

`include "common_cells/assertions.svh"
`include "common_cells/registers.svh"

/// This module generates AR packets to fetch descriptors from memory
module idma_desc64_ar_gen #(
/// AXI Data width
parameter int unsigned DataWidth = 64,
/// Descriptor type. `$bits(descriptor_t)` must be a power of two
parameter type descriptor_t = logic,
/// AXI AR channel type
parameter type axi_ar_chan_t = logic,
/// AXI AR id type
parameter type axi_id_t = logic,
/// Type that can hold the usage information of the idma_req fifo
parameter type usage_t = logic,
/// AXI Address type
parameter type addr_t = logic
)(
/// Clock
input logic clk_i,
/// Reset
input logic rst_ni,
/// AXI AR channel
output axi_ar_chan_t axi_ar_chan_o,
/// AXI AR valid
output logic axi_ar_chan_valid_o,
/// AXI AR ready
input logic axi_ar_chan_ready_i,
/// AXI ID to use when requesting
input axi_id_t axi_ar_id_i,
/// queued address to use when we reach the last in a chain
input addr_t queued_address_i,
/// queued address valid
input logic queued_address_valid_i,
/// queued address ready
output logic queued_address_ready_o,
/// next address as read from descriptor
input addr_t next_address_from_descriptor_i,
/// next address valid
input logic next_address_from_descriptor_valid_i,
/// number of available slots in the idma request fifo
input usage_t idma_req_available_slots_i,
/// address for feedback for the next request
output addr_t feedback_addr_o,
/// feedback address valid
output logic feedback_addr_valid_o,
/// whether the unit is busy
output logic busy_o
);

`define MIN(a, b) ((a) < (b) ? a : b)

localparam int unsigned DataWidthBytes = DataWidth / 8;
localparam int unsigned DescriptorSize = $bits(descriptor_t) / 8;

localparam logic [2:0] AxiSize = `MIN(`MIN($clog2(DataWidthBytes),
$clog2(DescriptorSize)), 3'b111);
localparam logic [7:0] AxiLength = DescriptorSize / DataWidthBytes - 1;

logic inflight_q, inflight_d;
logic next_addr_from_desc_valid_q, next_addr_from_desc_valid_d;
logic next_addr_from_desc_valid_this_cycle;
logic take_from_queued;
logic may_send_ar;
addr_t next_addr_q, next_addr_d;
addr_t ar_addr;

assign next_addr_from_desc_valid_d = next_address_from_descriptor_valid_i;
assign next_addr_from_desc_valid_this_cycle = !next_addr_from_desc_valid_q &&
next_address_from_descriptor_valid_i;

assign next_addr_d = next_addr_from_desc_valid_this_cycle ?
next_address_from_descriptor_i :
next_addr_q;

assign take_from_queued = (next_addr_from_desc_valid_this_cycle ?
next_address_from_descriptor_i == '1 :
next_addr_q == '1);

assign ar_addr = take_from_queued ? queued_address_i :
(next_addr_from_desc_valid_this_cycle ?
next_address_from_descriptor_i : next_addr_q);

assign may_send_ar = idma_req_available_slots_i > 0 &&
(!inflight_q || next_addr_from_desc_valid_this_cycle);

always_comb begin : proc_inflight
inflight_d = inflight_q;
if (axi_ar_chan_ready_i && axi_ar_chan_valid_o) begin
inflight_d = 1'b1;
end else if (next_addr_from_desc_valid_this_cycle) begin
inflight_d = 1'b0;
end
end

always_comb begin : proc_ready_valid
axi_ar_chan_valid_o = 1'b0;
queued_address_ready_o = 1'b0;
if (may_send_ar) begin
if (take_from_queued) begin
axi_ar_chan_valid_o = queued_address_valid_i;
queued_address_ready_o = axi_ar_chan_ready_i;
end else begin
axi_ar_chan_valid_o = 1'b1;
end
end
end

always_comb begin : proc_ar
axi_ar_chan_o = '0;
axi_ar_chan_o.id = axi_ar_id_i;
axi_ar_chan_o.addr = ar_addr;
axi_ar_chan_o.len = AxiLength;
axi_ar_chan_o.size = AxiSize;
axi_ar_chan_o.burst = axi_pkg::BURST_INCR;
end

`FF(inflight_q, inflight_d, 1'b0);
`FF(next_addr_from_desc_valid_q, next_addr_from_desc_valid_d, 1'b0);
`FF(next_addr_q, next_addr_d, '1);

assign feedback_addr_o = ar_addr;
assign feedback_addr_valid_o = axi_ar_chan_ready_i && axi_ar_chan_valid_o;
assign busy_o = !take_from_queued || inflight_q;

endmodule : idma_desc64_ar_gen
Loading

0 comments on commit d2eeeee

Please sign in to comment.