mirror of
https://github.com/retroSoC/retroSoC.git
synced 2026-11-06 14:55:14 +00:00
- Updated to integrate a coefficient engine and additional signals for coefficient handling. - Modified to include a coefficient engine, enhancing the encoding process with new signals. - Improved to validate generated blocks against expected values and added timeout handling. - Introduced for testing SRAM wrappers in JPEG workspace. - Enhanced test coverage in to reject invalid STA net drivers. - Updated to ensure proper coverage of canonical domains in timing contracts. - Added a new test for JPEG coefficient engine in . - Improved memory map tests in to validate public active MMIO regions. - Enhanced management core specification tests in to verify high-performance core specifications. - Added behavioral-only checks in to exclude synthesis and netlist consumers. - Updated SDRAM tests in to track active firmware memory. - Enhanced STA constraints tests in to cover current clock domains and net drivers.
183 lines
5.0 KiB
Systemverilog
183 lines
5.0 KiB
Systemverilog
`timescale 1ns / 1ps
|
|
`include "axi4_define.svh"
|
|
|
|
module apb4_jpeg_ring_tb;
|
|
logic clk = 1'b0;
|
|
logic rst_n = 1'b0;
|
|
logic [63:0] memory [0:2047];
|
|
logic read_active;
|
|
logic [31:0] read_base;
|
|
logic [ 7:0] read_len;
|
|
logic [ 7:0] read_index;
|
|
logic write_active;
|
|
logic [31:0] write_base;
|
|
logic [ 7:0] write_index;
|
|
logic bvalid;
|
|
logic irq;
|
|
|
|
apb4_if apb4 (
|
|
.pclk (clk),
|
|
.presetn(rst_n)
|
|
);
|
|
axi4_if #(
|
|
.DATA_WIDTH(64),
|
|
.ID_WIDTH (3)
|
|
) axi4 (
|
|
.aclk (clk),
|
|
.aresetn(rst_n)
|
|
);
|
|
|
|
always #5 clk = ~clk;
|
|
|
|
apb4_jpeg u_dut (
|
|
.clk_i (clk),
|
|
.rst_n_i (rst_n),
|
|
.quiesce_i (1'b0),
|
|
.resource_reset_i(1'b0),
|
|
.apb4 (apb4),
|
|
.axi4 (axi4),
|
|
.idle_o (),
|
|
.irq_o (irq)
|
|
);
|
|
|
|
assign axi4.arready = !read_active;
|
|
assign axi4.rid = 3'd0;
|
|
assign axi4.rdata = memory[(read_base>>3)+read_index];
|
|
assign axi4.rresp = `AXI4_RESP_OKAY;
|
|
assign axi4.rlast = read_index == read_len;
|
|
assign axi4.ruser = '0;
|
|
assign axi4.rvalid = read_active;
|
|
assign axi4.awready = !write_active && !bvalid;
|
|
assign axi4.wready = write_active;
|
|
assign axi4.bid = 3'd0;
|
|
assign axi4.bresp = `AXI4_RESP_OKAY;
|
|
assign axi4.buser = '0;
|
|
assign axi4.bvalid = bvalid;
|
|
|
|
always @(posedge clk or negedge rst_n) begin
|
|
if (!rst_n) begin
|
|
read_active <= 1'b0;
|
|
read_base <= '0;
|
|
read_len <= '0;
|
|
read_index <= '0;
|
|
write_active <= 1'b0;
|
|
write_base <= '0;
|
|
write_index <= '0;
|
|
bvalid <= 1'b0;
|
|
end else begin
|
|
if (axi4.arvalid && axi4.arready) begin
|
|
read_active <= 1'b1;
|
|
read_base <= axi4.araddr;
|
|
read_len <= axi4.arlen;
|
|
read_index <= 8'd0;
|
|
end else if (axi4.rvalid && axi4.rready) begin
|
|
if (axi4.rlast) begin
|
|
read_active <= 1'b0;
|
|
end else begin
|
|
read_index <= read_index + 1'b1;
|
|
end
|
|
end
|
|
if (axi4.awvalid && axi4.awready) begin
|
|
write_active <= 1'b1;
|
|
write_base <= axi4.awaddr;
|
|
write_index <= 8'd0;
|
|
end
|
|
if (axi4.wvalid && axi4.wready) begin
|
|
for (int byte_index = 0; byte_index < 8; byte_index++) begin
|
|
if (axi4.wstrb[byte_index]) begin
|
|
memory[(write_base>>3)+write_index][byte_index*8+:8] <= axi4.wdata[byte_index*8+:8];
|
|
end
|
|
end
|
|
if (axi4.wlast) begin
|
|
write_active <= 1'b0;
|
|
bvalid <= 1'b1;
|
|
end else begin
|
|
write_index <= write_index + 1'b1;
|
|
end
|
|
end
|
|
if (axi4.bvalid && axi4.bready) begin
|
|
bvalid <= 1'b0;
|
|
end
|
|
end
|
|
end
|
|
|
|
task automatic apb_write(input logic [11:0] offset_i, input logic [31:0] data_i);
|
|
begin
|
|
@(negedge clk);
|
|
apb4.paddr = {20'd0, offset_i};
|
|
apb4.pwdata = data_i;
|
|
apb4.pstrb = 4'hf;
|
|
apb4.pwrite = 1'b1;
|
|
apb4.psel = 1'b1;
|
|
apb4.penable = 1'b0;
|
|
@(negedge clk);
|
|
apb4.penable = 1'b1;
|
|
#1;
|
|
if (!apb4.pready || apb4.pslverr) $fatal(1, "APB write failed at %h", offset_i);
|
|
@(negedge clk);
|
|
apb4.psel = 1'b0;
|
|
apb4.penable = 1'b0;
|
|
end
|
|
endtask
|
|
|
|
task automatic apb_read(input logic [11:0] offset_i, output logic [31:0] data_o);
|
|
begin
|
|
@(negedge clk);
|
|
apb4.paddr = {20'd0, offset_i};
|
|
apb4.pwrite = 1'b0;
|
|
apb4.psel = 1'b1;
|
|
apb4.penable = 1'b0;
|
|
@(negedge clk);
|
|
apb4.penable = 1'b1;
|
|
#1;
|
|
if (!apb4.pready || apb4.pslverr) $fatal(1, "APB read failed at %h", offset_i);
|
|
data_o = apb4.prdata;
|
|
@(negedge clk);
|
|
apb4.psel = 1'b0;
|
|
apb4.penable = 1'b0;
|
|
end
|
|
endtask
|
|
|
|
initial begin
|
|
logic [31:0] value;
|
|
int timeout;
|
|
|
|
for (int index = 0; index < 2048; index++) begin
|
|
memory[index] = 64'd0;
|
|
end
|
|
memory[32'h1000>>3] = 64'h0000000000000001;
|
|
apb4.paddr = '0;
|
|
apb4.pprot = '0;
|
|
apb4.psel = 1'b0;
|
|
apb4.penable = 1'b0;
|
|
apb4.pwrite = 1'b0;
|
|
apb4.pwdata = '0;
|
|
apb4.pstrb = '0;
|
|
repeat (3) @(posedge clk);
|
|
rst_n = 1'b1;
|
|
|
|
apb_write(12'h01c, 32'h12);
|
|
apb_write(12'h100, 32'h00001000);
|
|
apb_write(12'h104, 32'd2);
|
|
apb_write(12'h10c, 32'd1);
|
|
apb_write(12'h110, 32'd1);
|
|
apb_write(12'h11c, 32'd1);
|
|
timeout = 2000;
|
|
value = 32'd1;
|
|
while ((value[0] != 1'b0) && (timeout > 0)) begin
|
|
apb_read(12'h014, value);
|
|
timeout--;
|
|
end
|
|
if (timeout == 0) $fatal(1, "ring job did not complete");
|
|
apb_read(12'h108, value);
|
|
if (value != 32'd1) $fatal(1, "ring head was not advanced");
|
|
apb_read(12'h018, value);
|
|
if ((value & 32'h12) != 32'h12 || !irq) $fatal(1, "ring IRQ status mismatch");
|
|
if (memory[32'h1000>>3][31:0] != 32'd0 || memory[32'h1000>>3][63:32] != 32'h00000103) begin
|
|
$fatal(1, "descriptor error writeback mismatch: %h", memory[32'h1000>>3]);
|
|
end
|
|
$display("JPEG APB ring tests passed");
|
|
$finish;
|
|
end
|
|
endmodule
|