Files
retroSoC/tests/rtl/spill_register_tb.sv
T
maksyuki bef5881149 feat: enhance DMA and RIB functionality with burst support and performance tests
- Updated dma_error_tb to implement burst transfer handling and performance measurement for INCR4 transfers.
- Introduced rib_burst_bus_tb to validate RIB burst arbitration and protocol compliance.
- Added soc_rib_burst_ram_tb to test SRAM behavior with burst commands.
- Created spill_register_tb to verify the functionality of the spill register under various conditions.
- Modified test_dma.py to reflect changes in DMA error handling and performance reporting.
- Updated test_memory_map.py to include new RIB burst interfaces and spill register utilities.
- Enhanced test_rib_burst.py with directed tests for RIB burst building blocks and spill register behavior.
- Adjusted test_soc_topology.py to ensure correct instantiation counts for RIB interfaces.
- Improved test_user_extensions.py to validate the generation of isolated scalar bindings for burst interfaces.
2026-08-03 22:23:37 +08:00

114 lines
2.8 KiB
Systemverilog

`timescale 1ns / 1ps
module spill_register_tb;
logic clk_i = 1'b0;
logic rst_n_i = 1'b0;
logic flush_i = 1'b0;
logic valid_i = 1'b0;
logic ready_o;
logic [31:0] data_i = '0;
logic valid_o;
logic ready_i = 1'b0;
logic [31:0] data_o;
logic [31:0] expected [0:511];
integer head = 0;
integer tail = 0;
integer cycle;
logic held_valid = 1'b0;
logic [31:0] held_data = '0;
logic [31:0] lfsr = 32'h1ACE_B00C;
always #5 clk_i = ~clk_i;
spill_register #(
.DATA_WIDTH(32),
.BYPASS (1'b0)
) u_dut (
.clk_i (clk_i),
.rst_n_i(rst_n_i),
.flush_i(flush_i),
.valid_i(valid_i),
.ready_o(ready_o),
.data_i (data_i),
.valid_o(valid_o),
.ready_i(ready_i),
.data_o (data_o)
);
task automatic check_cycle;
begin
@(posedge clk_i);
if (held_valid && (!valid_o || (data_o !== held_data))) begin
$fatal(1, "spill register changed output while stalled");
end
if (valid_o && ready_i) begin
if (head == tail || data_o !== expected[head]) begin
$fatal(1, "spill register output ordering failure");
end
head = head + 1;
end
if (valid_i && ready_o) begin
expected[tail] = data_i;
tail = tail + 1;
end
if (flush_i) begin
head = tail;
end
held_valid = valid_o && !ready_i && !flush_i;
held_data = data_o;
end
endtask
initial begin
repeat (2) @(posedge clk_i);
@(negedge clk_i);
rst_n_i = 1'b1;
// Sustained one-word-per-cycle traffic exercises simultaneous push/pop.
for (cycle = 0; cycle < 16; cycle = cycle + 1) begin
valid_i = 1'b1;
ready_i = 1'b1;
data_i = 32'h1000_0000 + cycle;
check_cycle();
@(negedge clk_i);
end
// Fill both entries, hold the output, and check stability under pressure.
ready_i = 1'b0;
for (cycle = 0; cycle < 8; cycle = cycle + 1) begin
valid_i = 1'b1;
data_i = 32'h2000_0000 + cycle;
check_cycle();
@(negedge clk_i);
end
valid_i = 1'b0;
flush_i = 1'b1;
check_cycle();
@(negedge clk_i);
flush_i = 1'b0;
// Deterministic randomized backpressure covers all occupancy transitions.
for (cycle = 0; cycle < 256; cycle = cycle + 1) begin
lfsr = {lfsr[30:0], lfsr[31] ^ lfsr[21] ^ lfsr[1] ^ lfsr[0]};
valid_i = lfsr[0] | lfsr[3];
ready_i = lfsr[1] | lfsr[5];
data_i = 32'h3000_0000 + cycle;
check_cycle();
@(negedge clk_i);
end
valid_i = 1'b0;
ready_i = 1'b1;
while (head != tail || valid_o) begin
check_cycle();
@(negedge clk_i);
end
$display("spill register ready/valid test passed");
$finish;
end
endmodule