ec82764bef
RTL (GS rasterizer, EE core stub, platform bridge, LPDDR4B path), sim regression (272 TBs), docs, and tooling. Copyrighted PS2 content (BIOS, game code, GS dumps, and all dump-derived textures/traces) is excluded via .gitignore and stays local. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
116 lines
3.6 KiB
Systemverilog
116 lines
3.6 KiB
Systemverilog
// retroDE_ps2 — tb_gs_texture_unit
|
|
//
|
|
// Verifies gs_texture_unit end-to-end against a stand-in VRAM: preload known
|
|
// 32-bit texels, stream a sequence of (u,v) coords in, and check the sampled
|
|
// color comes out aligned with out_valid and matches the preloaded texel at
|
|
// the address the unit computed. Exercises the read-latency pipeline.
|
|
|
|
`timescale 1ns/1ps
|
|
|
|
module tb_gs_texture_unit;
|
|
|
|
localparam logic [5:0] PSMCT32 = 6'h00;
|
|
localparam int RD_LATENCY = 1;
|
|
|
|
logic clk = 0, rst_n = 0;
|
|
logic in_valid;
|
|
logic [10:0] u, v;
|
|
logic [31:0] tbp0_base_bytes;
|
|
logic [13:0] tbw;
|
|
logic [5:0] psm;
|
|
logic tex_rd_en;
|
|
logic [31:0] tex_rd_addr;
|
|
logic [31:0] tex_rd_data;
|
|
logic out_valid;
|
|
logic [31:0] tex_color;
|
|
|
|
int errors = 0;
|
|
|
|
always #5 clk = ~clk;
|
|
|
|
gs_texture_unit #(.RD_LATENCY(RD_LATENCY)) dut (
|
|
.clk(clk), .rst_n(rst_n),
|
|
.in_valid(in_valid), .u(u), .v(v),
|
|
.tbp0_base_bytes(tbp0_base_bytes), .tbw(tbw), .psm(psm),
|
|
.tex_rd_en(tex_rd_en), .tex_rd_addr(tex_rd_addr), .tex_rd_data(tex_rd_data),
|
|
.out_valid(out_valid), .tex_color(tex_color)
|
|
);
|
|
|
|
// --- stand-in VRAM: byte-addressed, 32-bit word, registered 1-cycle read ---
|
|
logic [31:0] mem [0:1023]; // 4 KiB window
|
|
always_ff @(posedge clk) begin
|
|
if (tex_rd_en)
|
|
tex_rd_data <= mem[tex_rd_addr[31:2]]; // word index = byte addr >> 2
|
|
end
|
|
|
|
// expected-color shadow, delayed to align with out_valid
|
|
logic [31:0] exp_color_q;
|
|
logic exp_valid_q;
|
|
|
|
task automatic feed(input logic [10:0] uu, input logic [10:0] vv,
|
|
input logic [31:0] expect_color);
|
|
@(negedge clk);
|
|
in_valid = 1'b1;
|
|
u = uu;
|
|
v = vv;
|
|
exp_color_q = expect_color;
|
|
exp_valid_q = 1'b1;
|
|
@(posedge clk); // address presented; VRAM registers data
|
|
#1;
|
|
in_valid = 1'b0;
|
|
// out_valid + tex_color valid RD_LATENCY cycles after this posedge
|
|
endtask
|
|
|
|
// checker: whenever out_valid, compare against the pipelined expectation
|
|
logic [31:0] exp_pipe;
|
|
logic expv_pipe;
|
|
always_ff @(posedge clk) begin
|
|
if (!rst_n) begin expv_pipe <= 0; exp_pipe <= 0; end
|
|
else begin
|
|
expv_pipe <= exp_valid_q;
|
|
exp_pipe <= exp_color_q;
|
|
exp_valid_q <= 1'b0; // one-shot per feed
|
|
end
|
|
end
|
|
|
|
always_ff @(posedge clk) begin
|
|
if (out_valid) begin
|
|
if (tex_color !== exp_pipe) begin
|
|
$display("FAIL: tex_color=%08x expected=%08x (addr=%0d)",
|
|
tex_color, exp_pipe, tex_rd_addr);
|
|
errors++;
|
|
end else begin
|
|
$display("ok : tex_color=%08x", tex_color);
|
|
end
|
|
end
|
|
end
|
|
|
|
initial begin
|
|
// preload texels. tbw=1 -> 64 texels/row, base 0, PSMCT32 (4 B/texel)
|
|
// texel (u,v) lives at word index v*64 + u.
|
|
mem[2*64 + 3] = 32'hDEADBEEF; // (u=3, v=2)
|
|
mem[0] = 32'h11223344; // (u=0, v=0)
|
|
mem[1*64 + 5] = 32'hA5A5F00D; // (u=5, v=1)
|
|
|
|
tbp0_base_bytes = 0; tbw = 1; psm = PSMCT32;
|
|
in_valid = 0; u = 0; v = 0;
|
|
|
|
repeat (3) @(posedge clk);
|
|
rst_n = 1;
|
|
@(negedge clk);
|
|
|
|
feed(11'd3, 11'd2, 32'hDEADBEEF);
|
|
feed(11'd0, 11'd0, 32'h11223344);
|
|
feed(11'd5, 11'd1, 32'hA5A5F00D);
|
|
|
|
repeat (4) @(posedge clk);
|
|
|
|
if (errors == 0)
|
|
$display("\nPASS tb_gs_texture_unit");
|
|
else
|
|
$display("\nFAIL tb_gs_texture_unit (%0d errors)", errors);
|
|
$finish;
|
|
end
|
|
|
|
endmodule
|