161 lines
5.7 KiB
Verilog
161 lines
5.7 KiB
Verilog
`timescale 1ns/1ps
|
|
|
|
module tb_top_module_mem;
|
|
|
|
// Parameters
|
|
parameter DATA_WIDTH = 16;
|
|
parameter ROWS1 = 16;
|
|
parameter COLS1 = 12;
|
|
parameter ROWS2 = 12;
|
|
parameter COLS2 = 12;
|
|
parameter ROWS3 = 16;
|
|
parameter COLS3 = 32;
|
|
parameter COLS_USED = 4;
|
|
|
|
// DUT signals
|
|
reg clk;
|
|
|
|
reg [$clog2(ROWS1)-1:0] row_addr_1;
|
|
reg [$clog2(COLS1)-1:0] col_addr_1;
|
|
reg [$clog2(ROWS2)-1:0] row_addr_2;
|
|
reg [$clog2(COLS2)-1:0] col_addr_2;
|
|
reg [$clog2(ROWS3)-1:0] row_addr_3;
|
|
reg [$clog2(COLS3)-1:0] col_addr_3;
|
|
|
|
reg write_enable_1, write_enable_2, write_enable_3;
|
|
reg read_enable_1, read_enable_2, read_enable_3;
|
|
reg read_full_row_1, read_full_row_2, read_full_row_3;
|
|
reg write_full_row_1, write_full_row_2, write_full_row_3;
|
|
|
|
reg [DATA_WIDTH-1:0] data_input_1, data_input_2, data_input_3;
|
|
wire [DATA_WIDTH-1:0] data_output_1, data_output_2, data_output_3;
|
|
wire [DATA_WIDTH*ROWS1-1:0] full_row_output_1; //COLS1
|
|
wire [DATA_WIDTH*ROWS2-1:0] full_row_output_2; //COLS2
|
|
wire [DATA_WIDTH*ROWS3-1:0] full_row_output_3; //COLS3
|
|
reg [DATA_WIDTH*ROWS1-1:0] full_row_input_1; //COLS1
|
|
reg [DATA_WIDTH*ROWS2-1:0] full_row_input_2; //COLS2
|
|
reg [DATA_WIDTH*ROWS3-1:0] full_row_input_3; //COLS3
|
|
wire valid_1, valid_2, valid_3;
|
|
|
|
integer i;
|
|
|
|
// Instantiate DUT
|
|
top_module_mem #(
|
|
.ROWS1(ROWS1),
|
|
.COLS1(COLS1),
|
|
.ROWS2(ROWS2),
|
|
.COLS2(COLS2),
|
|
.ROWS3(ROWS3),
|
|
.COLS3(COLS3),
|
|
.DATA_WIDTH(DATA_WIDTH),
|
|
.COLS_USED(COLS_USED)
|
|
) uut (
|
|
.clk(clk),
|
|
.row_addr_1(row_addr_1), .col_addr_1(col_addr_1),
|
|
.row_addr_2(row_addr_2), .col_addr_2(col_addr_2),
|
|
.row_addr_3(row_addr_3), .col_addr_3(col_addr_3),
|
|
.write_enable_1(write_enable_1), .write_enable_2(write_enable_2), .write_enable_3(write_enable_3),
|
|
.read_enable_1(read_enable_1), .read_enable_2(read_enable_2), .read_enable_3(read_enable_3),
|
|
.write_full_row_1(write_full_row_1), .write_full_row_2(write_full_row_2), .write_full_row_3(write_full_row_3),
|
|
.read_full_row_1(read_full_row_1), .read_full_row_2(read_full_row_2), .read_full_row_3(read_full_row_3),
|
|
.data_input_1(data_input_1), .data_input_2(data_input_2), .data_input_3(data_input_3),
|
|
.data_output_1(data_output_1), .data_output_2(data_output_2), .data_output_3(data_output_3),
|
|
.full_row_input_1(full_row_input_1), .full_row_input_2(full_row_input_2), .full_row_input_3(full_row_input_3),
|
|
.full_row_output_1(full_row_output_1), .full_row_output_2(full_row_output_2), .full_row_output_3(full_row_output_3),
|
|
.valid_1(valid_1), .valid_2(valid_2), .valid_3(valid_3)
|
|
);
|
|
|
|
// Clock generation
|
|
always #5 clk = ~clk;
|
|
|
|
// Testbench body
|
|
initial begin
|
|
$display("=== Starting testbench ===");
|
|
|
|
// Initialize signals
|
|
clk = 0;
|
|
row_addr_1 = 0; col_addr_1 = 0;
|
|
row_addr_2 = 0; col_addr_2 = 0;
|
|
row_addr_3 = 0; col_addr_3 = 0;
|
|
write_enable_1 = 0; write_enable_2 = 0; write_enable_3 = 0;
|
|
read_enable_1 = 0; read_enable_2 = 0; read_enable_3 = 0;
|
|
read_full_row_1 = 0; read_full_row_2 = 0; read_full_row_3 = 0;
|
|
data_input_1 = 0; data_input_2 = 0; data_input_3 = 0;
|
|
|
|
#10;
|
|
|
|
// === Write into Matrix 1 ===
|
|
write_enable_1 = 1;
|
|
row_addr_1 = 2; col_addr_1 = 3;
|
|
data_input_1 = 16'h1234;
|
|
#10;
|
|
write_enable_1 = 0;
|
|
|
|
// === Read back single element from Matrix 1 ===
|
|
read_enable_1 = 1;
|
|
read_full_row_1 = 0; // Single element read
|
|
#10;
|
|
if (data_output_1 == 16'h1234)
|
|
$display("PASS: Single element read from Matrix 1: %h", data_output_1);
|
|
else
|
|
$display("FAIL: Expected 0x1234, got %h", data_output_1);
|
|
|
|
read_enable_1 = 0;
|
|
|
|
// === Write into Matrix 2 ===
|
|
write_enable_2 = 1;
|
|
row_addr_2 = 4; col_addr_2 = 5;
|
|
data_input_2 = 16'h5678;
|
|
#10;
|
|
write_enable_2 = 0;
|
|
|
|
// === Write into Matrix 3 ===
|
|
write_enable_3 = 1;
|
|
row_addr_3 = 6; col_addr_3 = 7;
|
|
data_input_3 = 16'h9ABC;
|
|
#10;
|
|
write_enable_3 = 0;
|
|
|
|
// === Read full row from Matrix 1 ===
|
|
read_enable_1 = 1;
|
|
read_full_row_1 = 1; // Full row read
|
|
row_addr_1 = 2; // Row where we wrote earlier
|
|
#10;
|
|
read_enable_1 = 0;
|
|
read_full_row_1 = 0;
|
|
|
|
// === Write full row into Matrix 1 ===
|
|
write_full_row_1 = 1;
|
|
row_addr_1 = 5;
|
|
// Writing row 5 with pattern: 0x0100, 0x0200, 0x0300, ..., up to COLS1
|
|
for (i = 0; i < COLS1; i = i + 1) begin
|
|
full_row_input_1[i*DATA_WIDTH +: DATA_WIDTH] = (i + 1) << 8;
|
|
end
|
|
#10;
|
|
write_full_row_1 = 0;
|
|
|
|
// === Read full row back from Matrix 1 to verify ===
|
|
read_enable_1 = 1;
|
|
read_full_row_1 = 1;
|
|
row_addr_1 = 5;
|
|
#10;
|
|
read_enable_1 = 0;
|
|
read_full_row_1 = 0;
|
|
|
|
// === Verification ===
|
|
for (i = 0; i < COLS1; i = i + 1) begin
|
|
if (full_row_output_1[i*DATA_WIDTH +: DATA_WIDTH] != ((i + 1) << 8)) begin
|
|
$display("FAIL: Full row write/read mismatch at column %0d: expected %h, got %h", i, (i + 1) << 8, full_row_output_1[i*DATA_WIDTH +: DATA_WIDTH]);
|
|
end else begin
|
|
$display("PASS: Full row element (%0d, %0d) correct: %h", 5, i, full_row_output_1[i*DATA_WIDTH +: DATA_WIDTH]);
|
|
end
|
|
end
|
|
|
|
|
|
// === Finish Test ===
|
|
#20;
|
|
$display("=== Testbench completed ===");
|
|
$finish;
|
|
end
|
|
|
|
endmodule
|