Files
retroSoC/tests/rtl/rib2apb_tb.sv
T
maksyuki 6be73fa6b7 feat: refactor RIB to APB bridge and update related components
- Changed the interface from ribp to rib in soc_topology.json and related files.
- Updated formal.mk to reflect the new rib2apb naming convention.
- Implemented rib2apb module to handle RIB to APB communication.
- Modified bus.sv to integrate the new rib2apb module and adjust signal assignments accordingly.
- Updated testbench files to use the new rib interface and validate the RIB to APB functionality.
- Created rib2apb_tb for testing the direct RIB to APB bridge.
- Adjusted script tools and test scripts to accommodate the new naming and structure.
2026-08-05 16:03:41 +08:00

198 lines
5.7 KiB
Systemverilog

`timescale 1ns / 1ps
`include "rib_defs.svh"
module rib2apb_tb;
logic clk_i = 1'b0;
logic rst_n_i = 1'b0;
logic rng_ready = 1'b0;
logic rng_slverr = 1'b0;
logic [31:0] rng_rdata = 32'h1234_5678;
rib_if rib ();
apb4_pure_if archinfo ();
apb4_pure_if rng ();
apb4_pure_if uart ();
apb4_pure_if pwm ();
apb4_pure_if ps2 ();
apb4_pure_if rtc ();
apb4_pure_if wdg ();
apb4_pure_if crc ();
apb4_pure_if tmr ();
apb4_pure_if user_ip ();
always #5 clk_i = ~clk_i;
assign archinfo.pready = 1'b0;
assign archinfo.prdata = '0;
assign archinfo.pslverr = 1'b0;
assign rng.pready = rng_ready;
assign rng.prdata = rng_rdata;
assign rng.pslverr = rng_slverr;
assign uart.pready = 1'b0;
assign uart.prdata = '0;
assign uart.pslverr = 1'b0;
assign pwm.pready = 1'b0;
assign pwm.prdata = '0;
assign pwm.pslverr = 1'b0;
assign ps2.pready = 1'b0;
assign ps2.prdata = '0;
assign ps2.pslverr = 1'b0;
assign rtc.pready = 1'b0;
assign rtc.prdata = '0;
assign rtc.pslverr = 1'b0;
assign wdg.pready = 1'b0;
assign wdg.prdata = '0;
assign wdg.pslverr = 1'b0;
assign crc.pready = 1'b0;
assign crc.prdata = '0;
assign crc.pslverr = 1'b0;
assign tmr.pready = 1'b0;
assign tmr.prdata = '0;
assign tmr.pslverr = 1'b0;
assign user_ip.pready = 1'b0;
assign user_ip.prdata = '0;
assign user_ip.pslverr = 1'b0;
rib2apb u_rib2apb (
.clk_i (clk_i),
.rst_n_i (rst_n_i),
.rib (rib),
.archinfo(archinfo),
.rng (rng),
.uart (uart),
.pwm (pwm),
.ps2 (ps2),
.rtc (rtc),
.wdg (wdg),
.crc (crc),
.tmr (tmr),
.user_ip (user_ip)
);
task automatic send_command(input logic [31:0] address, input logic write,
input logic [1:0] length);
begin
@(negedge clk_i);
rib.cmd_addr = address;
rib.cmd_write = write;
rib.cmd_len = length;
rib.cmd_valid = 1'b1;
while (!rib.cmd_ready) @(posedge clk_i);
@(negedge clk_i);
rib.cmd_valid = 1'b0;
end
endtask
task automatic send_write(input logic [31:0] data, input logic [3:0] strobes, input logic last);
begin
@(negedge clk_i);
rib.wdata = data;
rib.wstrb = strobes;
rib.wlast = last;
rib.w_valid = 1'b1;
while (!rib.w_ready) @(posedge clk_i);
@(negedge clk_i);
rib.w_valid = 1'b0;
end
endtask
task automatic wait_for_rng_enable;
begin
while (!(rng.psel && rng.penable)) @(posedge clk_i);
end
endtask
task automatic expect_response(input logic expected_error, input logic [2:0] expected_code,
input logic [31:0] expected_data);
begin
while (!rib.rsp_valid) @(posedge clk_i);
#1;
if (rib.resp_err !== expected_error || rib.resp_code !== expected_code ||
rib.rdata !== expected_data || rib.rsp_beat !== 2'd0 || !rib.rsp_last) begin
$fatal(1, "unexpected RIB response error=%b/%b code=%0d/%0d data=%h/%h fsm=%0d",
rib.resp_err, expected_error, rib.resp_code, expected_code, rib.rdata,
expected_data, u_rib2apb.s_fsm_q);
end
end
endtask
initial begin
rib.cmd_valid = 1'b0;
rib.cmd_addr = '0;
rib.cmd_write = 1'b0;
rib.cmd_len = `RIB_LEN_INCR1;
rib.w_valid = 1'b0;
rib.wdata = '0;
rib.wstrb = '0;
rib.wlast = 1'b0;
rib.rsp_ready = 1'b1;
repeat (2) @(posedge clk_i);
rst_n_i = 1'b1;
send_command(32'h2000_1000, 1'b0, `RIB_LEN_INCR1);
while (!(rng.psel && !rng.penable)) @(posedge clk_i);
wait_for_rng_enable();
if (rng.paddr !== 32'h2000_1000 || rng.pwrite || rng.pstrb !== 4'd0) begin
$fatal(1, "read APB setup was not held from the RIB command");
end
repeat (2) begin
@(posedge clk_i);
if (!(rng.psel && rng.penable) || rng.paddr !== 32'h2000_1000) begin
$fatal(1, "APB read request changed while PREADY was low");
end
end
rib.rsp_ready = 1'b0;
@(negedge clk_i);
rng_ready = 1'b1;
expect_response(1'b0, `RIB_RESP_OK, 32'h1234_5678);
repeat (2) begin
@(posedge clk_i);
if (!rib.rsp_valid || rib.rdata !== 32'h1234_5678) begin
$fatal(1, "response did not remain stable under RIB backpressure");
end
end
rib.rsp_ready = 1'b1;
@(posedge clk_i);
@(negedge clk_i);
rng_ready = 1'b0;
send_command(32'h2000_1000, 1'b1, `RIB_LEN_INCR1);
send_write(32'hA5A5_5A5A, 4'hC, 1'b1);
wait_for_rng_enable();
if (!rng.pwrite || rng.pwdata !== 32'hA5A5_5A5A || rng.pstrb !== 4'hC) begin
$fatal(1, "APB write data was not held from the RIB write channel");
end
@(negedge clk_i);
rng_ready = 1'b1;
expect_response(1'b0, `RIB_RESP_OK, 32'd0);
@(posedge clk_i);
@(negedge clk_i);
rng_ready = 1'b0;
rng_slverr = 1'b1;
send_command(32'h2000_1000, 1'b0, `RIB_LEN_INCR1);
wait_for_rng_enable();
@(negedge clk_i);
rng_ready = 1'b1;
expect_response(1'b1, `RIB_RESP_SLVERR, 32'h1234_5678);
@(posedge clk_i);
@(negedge clk_i);
rng_ready = 1'b0;
rng_slverr = 1'b0;
send_command(32'h2000_1000, 1'b1, `RIB_LEN_INCR4);
send_write(32'h0000_0001, 4'hF, 1'b0);
send_write(32'h0000_0002, 4'hF, 1'b0);
send_write(32'h0000_0003, 4'hF, 1'b0);
send_write(32'h0000_0004, 4'hF, 1'b1);
if (rng.psel) $fatal(1, "illegal RIB burst reached the APB target");
expect_response(1'b1, `RIB_RESP_BURSTERR, 32'd0);
@(posedge clk_i);
$display("RIB2APB direct bridge test passed");
$finish;
end
endmodule