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
1 change: 1 addition & 0 deletions .github/authors-cfg.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ allowed-years:

allowed-authors:
Axel Vanoni: axvanoni@ethz.ch
Daniel Keller: dankeller@iis.ee.ethz.ch
Michael Rogenmoser: michaero@iis.ee.ethz.ch
Samuel Riedel: sriedel@iis.ee.ethz.ch
Thomas Benz: tbenz@iis.ee.ethz.ch
Expand Down
7 changes: 7 additions & 0 deletions idma.mk
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ SPHINXBUILD ?= sphinx-build
VCS ?= vcs
VERILATOR ?= verilator
VLOGAN ?= vlogan
VSIM ?= vsim
Comment thread
DanielKellerM marked this conversation as resolved.

# Shell
SHELL := /bin/bash
Expand Down Expand Up @@ -308,6 +309,12 @@ endef
$(IDMA_VSIM_DIR)/compile.tcl: $(IDMA_BENDER_FILES) $(IDMA_FULL_TB) $(IDMA_FULL_RTL) $(IDMA_INCLUDE_ALL) $(IDMA_WAVE_ALL)
$(call idma_generate_vsim, $@, -t sim -t test -t idma_test -t synth -t rtl -t asic -t snitch_cluster,../../..)

.PHONY: idma_sim_tb_idma_rt_midend

idma_sim_tb_idma_rt_midend: $(IDMA_VSIM_DIR)/compile.tcl
cd $(IDMA_VSIM_DIR); $(VSIM) -c -do "source compile.tcl; quit"
cd $(IDMA_VSIM_DIR); $(VSIM) -c -t 1ps -voptargs=+acc tb_idma_rt_midend -do "run -all; quit"

Comment thread
DanielKellerM marked this conversation as resolved.
idma_sim_clean:
rm -rf $(IDMA_VSIM_DIR)/compile.tcl
rm -rf $(IDMA_VSIM_DIR)/work
Expand Down
13 changes: 8 additions & 5 deletions src/midend/idma_rt_midend.sv
Original file line number Diff line number Diff line change
Expand Up @@ -111,6 +111,9 @@ module idma_rt_midend #(
idma_rsp_t int_rsp;
logic int_valid;

// choice-FIFO backpressure signal
logic choice_fifo_ready;

// generate the counters timing the events and assemble the transfers
for (genvar c = 0; c < NumEvents; c++) begin : gen_counters
// counter instance
Expand Down Expand Up @@ -180,7 +183,7 @@ module idma_rt_midend #(
.inp_ready_o ( { nd_req_ready_o, nd_req_ready_int } ),
.oup_data_o ( out_req ),
.oup_valid_o ( nd_req_valid_o ),
.oup_ready_i ( nd_req_ready_i )
.oup_ready_i ( nd_req_ready_i & choice_fifo_ready )
);

// assemble arbiter inputs
Expand All @@ -206,11 +209,11 @@ module idma_rt_midend #(
.testmode_i ( 1'b0 ),
.usage_o ( /* NC */ ),
.data_i ( choice ),
.valid_i ( nd_req_valid_i & nd_req_ready_o ),
.ready_o ( /* HACK: NC */ ),
.valid_i ( nd_req_valid_o & nd_req_ready_i & choice_fifo_ready ),
.ready_o ( choice_fifo_ready ),
.data_o ( choice_head ),
.valid_o ( /* HACK: NC */ ),
.ready_i ( burst_rsp_valid_o & burst_rsp_ready_i )
.valid_o ( /* NC */ ),
.ready_i ( burst_rsp_valid_i & burst_rsp_ready_o )
);

// arbitration of responses
Expand Down
135 changes: 119 additions & 16 deletions test/midend/tb_idma_rt_midend.sv
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,19 @@

// Authors:
// - Thomas Benz <tbenz@iis.ee.ethz.ch>
// - Daniel Keller <dankeller@iis.ee.ethz.ch>

`include "idma/typedef.svh"

/// Sanity testbench for the RT midend
/// Sanity testbench for the RT midend: checks bypass responses are routed
/// to the bypass output, not lost to the internal sink.
module tb_idma_rt_midend;

logic clk;
logic rst_n;

localparam int unsigned NumEvents = 5;
localparam int unsigned NumDim = 3;
localparam int unsigned NumDim = 3;
Comment thread
DanielKellerM marked this conversation as resolved.

typedef logic [5:0] axi_id_t;
typedef logic [31:0] tf_len_t;
Expand All @@ -29,6 +31,29 @@ module tb_idma_rt_midend;
tf_len_t [NumEvents-1:0] event_counts = '0;
logic [NumEvents-1:0] event_ena = '0;

// Downstream side: drains nd_req_o and supplies burst_rsp.
idma_nd_req_t out_req;
logic out_req_valid;
logic out_req_ready;

idma_rsp_t out_rsp;
logic out_rsp_valid;
logic out_rsp_ready;

// Bypass side: driven by this TB.
idma_nd_req_t byp_req;
logic byp_req_valid;
logic byp_req_ready;

idma_rsp_t byp_rsp;
logic byp_rsp_valid;
logic byp_rsp_ready;

// Counters to detect routing mismatch.
int unsigned bypass_req_issued;
int unsigned bypass_rsp_seen;
int unsigned internal_rsp_seen;

clk_rst_gen #(
.ClkPeriod ( 1ns ),
.RstClkCycles ( 1 )
Expand All @@ -41,7 +66,7 @@ module tb_idma_rt_midend;
idma_rt_midend #(
.NumEvents ( NumEvents ),
.EventCntWidth ( 32'd32 ),
.NumOutstanding ( 32'd2 ),
.NumOutstanding ( 32'd4 ),
.addr_t ( axi_addr_t ),
.idma_nd_req_t ( idma_nd_req_t ),
.idma_rsp_t ( idma_rsp_t )
Expand All @@ -59,26 +84,104 @@ module tb_idma_rt_midend;
.dst_2d_stride_i ( '0 ),
.num_2d_reps_i ( '0 ),
.event_ena_i ( event_ena ),
.event_counts_o (),
.nd_req_o (),
.nd_req_valid_o (),
.nd_req_ready_i ( 1'b1 ),
.burst_rsp_i ( '1 ),
.burst_rsp_valid_i ( 1'b1 ),
.burst_rsp_ready_o (),
.nd_req_i ( '1 ),
.nd_req_ready_o (),
.nd_req_valid_i ( 1'b0 ),
.burst_rsp_o ( ),
.burst_rsp_valid_o ( ),
.burst_rsp_ready_i ( 1'b1 )
.event_counts_o ( ),
.nd_req_o ( out_req ),
.nd_req_valid_o ( out_req_valid ),
.nd_req_ready_i ( out_req_ready ),
.burst_rsp_i ( out_rsp ),
.burst_rsp_valid_i ( out_rsp_valid ),
.burst_rsp_ready_o ( out_rsp_ready ),
.nd_req_i ( byp_req ),
.nd_req_valid_i ( byp_req_valid ),
.nd_req_ready_o ( byp_req_ready ),
.burst_rsp_o ( byp_rsp ),
.burst_rsp_valid_o ( byp_rsp_valid ),
.burst_rsp_ready_i ( byp_rsp_ready )
);

// Always accept the downstream request and acknowledge any response stream.
assign out_req_ready = 1'b1;
assign byp_rsp_ready = 1'b1;

// Drive a response one cycle after every accepted request (1:1 order).
logic out_req_handshake;
assign out_req_handshake = out_req_valid & out_req_ready;

always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
out_rsp_valid <= 1'b0;
out_rsp <= '0;
end else begin
// Hold an unconsumed response.
if (out_rsp_valid && !out_rsp_ready) begin
out_rsp_valid <= 1'b1;
end else begin
out_rsp_valid <= out_req_handshake;
out_rsp <= '1;
end
end
end

// -- Counters ------------------------------------------------------
always_ff @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
bypass_req_issued <= '0;
bypass_rsp_seen <= '0;
internal_rsp_seen <= '0;
end else begin
if (byp_req_valid && byp_req_ready)
bypass_req_issued <= bypass_req_issued + 1;
if (byp_rsp_valid && byp_rsp_ready)
bypass_rsp_seen <= bypass_rsp_seen + 1;
// Responses not routed to bypass are internal.
if (out_rsp_valid && out_rsp_ready && !byp_rsp_valid)
internal_rsp_seen <= internal_rsp_seen + 1;
end
end

// -- Bypass stimulus -----------------------------------------------
initial begin : drive_bypass
byp_req_valid = 1'b0;
byp_req = '0;
byp_req.burst_req.length = 32'h0000_1000;
byp_req.burst_req.src_addr = 32'hC000_0000;
byp_req.burst_req.dst_addr = 32'hD000_0000;

wait (rst_n === 1'b1);
@(posedge clk);

// Issue 8 bypass requests interleaved with the counter traffic.
for (int i = 0; i < 8; i++) begin
repeat (3 + (i % 4)) @(posedge clk);
byp_req_valid = 1'b1;
byp_req.burst_req.length = 32'h0000_1000 + i;
@(posedge clk);
while (!byp_req_ready) @(posedge clk);
byp_req_valid = 1'b0;
end
end

// -- Main stimulus -------------------------------------------------
initial begin
event_counts = {32'd17, 32'd300, 32'd800, 32'd1000, 32'd2000};
#10ns;
event_ena = {1'd1, 1'd1, 1'd1, 1'd1, 1'd1};
#5000ns;

// Bounded drain for outstanding bypass responses.
for (int i = 0; i < 1000; i++) begin
if (bypass_rsp_seen >= bypass_req_issued) break;
@(posedge clk);
end

// Every bypass request must produce exactly one bypass response.
if (bypass_rsp_seen != bypass_req_issued) begin
$fatal(1, "[tb_idma_rt_midend] routing mismatch: issued=%0d seen=%0d",
bypass_req_issued, bypass_rsp_seen);
end

$display("[tb_idma_rt_midend] bypass req: %0d, bypass rsp: %0d, internal rsp: %0d",
bypass_req_issued, bypass_rsp_seen, internal_rsp_seen);
$finish();
end

Expand Down
Loading