mirror of
https://gitlab.com/hyperglitch/jellyfish.git
synced 2025-12-24 06:36:47 +00:00
399 lines
6.5 KiB
Systemverilog
399 lines
6.5 KiB
Systemverilog
`timescale 1ns / 1ps
|
|
|
|
// SPDX-FileCopyrightText: 2025 Igor Brkic <igor@hyperglitch.com>
|
|
// SPDX-License-Identifier: GPL-3.0-or-later
|
|
|
|
// 4 command lines
|
|
// 4 address lines
|
|
// 2 dummy cycles
|
|
// 8 data lines
|
|
module qspi_decoder_tb;
|
|
|
|
localparam ADDRESS_WIDTH = 24;
|
|
localparam ADDRESS_LINES = 4;
|
|
localparam COMMAND_WIDTH = 8;
|
|
localparam COMMAND_LINES = 4;
|
|
localparam DUMMY_CYCLES = 2;
|
|
localparam DATA_WIDTH = 8;
|
|
localparam DATA_LINES = 4;
|
|
localparam DATA_BANKS = 2;
|
|
|
|
reg i_rst;
|
|
reg i_ncs;
|
|
reg i_clk;
|
|
reg i_bk1_io0;
|
|
reg i_bk1_io1;
|
|
reg i_bk1_io2;
|
|
reg i_bk1_io3;
|
|
reg i_bk2_io0;
|
|
reg i_bk2_io1;
|
|
reg i_bk2_io2;
|
|
reg i_bk2_io3;
|
|
reg rdy;
|
|
reg [COMMAND_WIDTH-1:0] o_command;
|
|
wire [DATA_WIDTH*DATA_BANKS-1:0] o_data;
|
|
|
|
qspi_decoder #(
|
|
.ADDRESS_WIDTH(ADDRESS_WIDTH),
|
|
.ADDRESS_LINES(ADDRESS_LINES),
|
|
.COMMAND_WIDTH(COMMAND_WIDTH),
|
|
.COMMAND_LINES(COMMAND_LINES),
|
|
.DUMMY_CYCLES(DUMMY_CYCLES),
|
|
.DATA_WIDTH(DATA_WIDTH),
|
|
.DATA_LINES(DATA_LINES),
|
|
.DATA_BANKS(DATA_BANKS)
|
|
) dut (
|
|
.i_rst(i_rst),
|
|
.i_ncs(i_ncs),
|
|
.i_clk(i_clk),
|
|
.i_bk1_io0(i_bk1_io0),
|
|
.i_bk1_io1(i_bk1_io1),
|
|
.i_bk1_io2(i_bk1_io2),
|
|
.i_bk1_io3(i_bk1_io3),
|
|
.i_bk2_io0(i_bk2_io0),
|
|
.i_bk2_io1(i_bk2_io1),
|
|
.i_bk2_io2(i_bk2_io2),
|
|
.i_bk2_io3(i_bk2_io3),
|
|
.rdy(rdy),
|
|
.o_command(o_command),
|
|
.o_data(o_data)
|
|
);
|
|
|
|
// generate clock
|
|
initial begin
|
|
i_clk = 0;
|
|
#25;
|
|
forever #5 i_clk = ~i_clk; // 100MHz
|
|
end
|
|
|
|
// test sequence
|
|
initial begin
|
|
i_ncs = 1;
|
|
i_bk1_io0 = 0;
|
|
i_bk1_io1 = 0;
|
|
i_bk1_io2 = 0;
|
|
i_bk1_io3 = 0;
|
|
i_bk2_io0 = 0;
|
|
i_bk2_io1 = 0;
|
|
i_bk2_io2 = 0;
|
|
i_bk2_io3 = 0;
|
|
|
|
// reset
|
|
i_rst = 1;
|
|
#10;
|
|
i_rst = 0;
|
|
#10;
|
|
|
|
// chip select
|
|
i_ncs = 0;
|
|
#5
|
|
|
|
// send command over all four lines
|
|
i_bk1_io0 = 0;
|
|
i_bk1_io1 = 1;
|
|
i_bk1_io2 = 0;
|
|
i_bk1_io3 = 1;
|
|
|
|
i_bk2_io0 = 0;
|
|
i_bk2_io1 = 1;
|
|
i_bk2_io2 = 0;
|
|
i_bk2_io3 = 1;
|
|
|
|
#10;
|
|
|
|
i_bk1_io0 = 1;
|
|
i_bk1_io1 = 0;
|
|
i_bk1_io2 = 1;
|
|
i_bk1_io3 = 1;
|
|
|
|
i_bk2_io0 = 1;
|
|
i_bk2_io1 = 0;
|
|
i_bk2_io2 = 1;
|
|
i_bk2_io3 = 1;
|
|
|
|
#10;
|
|
|
|
assert(dut.command == 8'hAD);
|
|
|
|
// send address over all four lines
|
|
i_bk1_io0 = 0;
|
|
i_bk1_io1 = 0;
|
|
i_bk1_io2 = 0;
|
|
i_bk1_io3 = 0;
|
|
|
|
i_bk2_io0 = 0;
|
|
i_bk2_io1 = 0;
|
|
i_bk2_io2 = 0;
|
|
i_bk2_io3 = 0;
|
|
#10;
|
|
|
|
i_bk1_io0 = 0;
|
|
i_bk1_io1 = 0;
|
|
i_bk1_io2 = 0;
|
|
i_bk1_io3 = 0;
|
|
|
|
i_bk2_io0 = 0;
|
|
i_bk2_io1 = 0;
|
|
i_bk2_io2 = 0;
|
|
i_bk2_io3 = 0;
|
|
#10;
|
|
|
|
i_bk1_io0 = 1;
|
|
i_bk1_io1 = 0;
|
|
i_bk1_io2 = 1;
|
|
i_bk1_io3 = 0;
|
|
|
|
i_bk2_io0 = 1;
|
|
i_bk2_io1 = 0;
|
|
i_bk2_io2 = 1;
|
|
i_bk2_io3 = 0;
|
|
#10;
|
|
|
|
i_bk1_io0 = 0;
|
|
i_bk1_io1 = 1;
|
|
i_bk1_io2 = 1;
|
|
i_bk1_io3 = 0;
|
|
|
|
i_bk2_io0 = 0;
|
|
i_bk2_io1 = 1;
|
|
i_bk2_io2 = 1;
|
|
i_bk2_io3 = 0;
|
|
#10;
|
|
|
|
i_bk1_io0 = 0;
|
|
i_bk1_io1 = 1;
|
|
i_bk1_io2 = 0;
|
|
i_bk1_io3 = 1;
|
|
|
|
i_bk2_io0 = 0;
|
|
i_bk2_io1 = 1;
|
|
i_bk2_io2 = 0;
|
|
i_bk2_io3 = 1;
|
|
#10;
|
|
|
|
i_bk1_io0 = 0;
|
|
i_bk1_io1 = 1;
|
|
i_bk1_io2 = 0;
|
|
i_bk1_io3 = 1;
|
|
|
|
i_bk2_io0 = 0;
|
|
i_bk2_io1 = 1;
|
|
i_bk2_io2 = 0;
|
|
i_bk2_io3 = 1;
|
|
#10;
|
|
|
|
assert(dut.address == 24'h0056AA);
|
|
|
|
// dummy cycles
|
|
i_bk1_io0 = 0;
|
|
i_bk1_io1 = 0;
|
|
i_bk1_io2 = 0;
|
|
i_bk1_io3 = 0;
|
|
|
|
i_bk2_io0 = 0;
|
|
i_bk2_io1 = 0;
|
|
i_bk2_io2 = 0;
|
|
i_bk2_io3 = 0;
|
|
#10;
|
|
#10;
|
|
|
|
// send data over 8 lines
|
|
|
|
// byte 0
|
|
i_bk1_io0 = 0;
|
|
i_bk1_io1 = 0;
|
|
i_bk1_io2 = 1;
|
|
i_bk1_io3 = 1;
|
|
i_bk2_io0 = 0;
|
|
i_bk2_io1 = 0;
|
|
i_bk2_io2 = 0;
|
|
i_bk2_io3 = 0;
|
|
#10;
|
|
|
|
// byte 1
|
|
i_bk1_io0 = 1;
|
|
i_bk1_io1 = 1;
|
|
i_bk1_io2 = 0;
|
|
i_bk1_io3 = 0;
|
|
i_bk2_io0 = 1;
|
|
i_bk2_io1 = 0;
|
|
i_bk2_io2 = 0;
|
|
i_bk2_io3 = 0;
|
|
#10;
|
|
|
|
// byte 2
|
|
i_bk1_io0 = 0;
|
|
i_bk1_io1 = 0;
|
|
i_bk1_io2 = 0;
|
|
i_bk1_io3 = 0;
|
|
i_bk2_io0 = 0;
|
|
i_bk2_io1 = 0;
|
|
i_bk2_io2 = 0;
|
|
i_bk2_io3 = 0;
|
|
#10;
|
|
|
|
// byte 3
|
|
i_bk1_io0 = 0;
|
|
i_bk1_io1 = 1;
|
|
i_bk1_io2 = 0;
|
|
i_bk1_io3 = 0;
|
|
i_bk2_io0 = 1;
|
|
i_bk2_io1 = 1;
|
|
i_bk2_io2 = 0;
|
|
i_bk2_io3 = 0;
|
|
#10;
|
|
|
|
// byte 4
|
|
i_bk1_io0 = 0;
|
|
i_bk1_io1 = 0;
|
|
i_bk1_io2 = 0;
|
|
i_bk1_io3 = 0;
|
|
i_bk2_io0 = 0;
|
|
i_bk2_io1 = 0;
|
|
i_bk2_io2 = 0;
|
|
i_bk2_io3 = 0;
|
|
#10;
|
|
|
|
// byte 5
|
|
i_bk1_io0 = 0;
|
|
i_bk1_io1 = 0;
|
|
i_bk1_io2 = 1;
|
|
i_bk1_io3 = 0;
|
|
i_bk2_io0 = 1;
|
|
i_bk2_io1 = 0;
|
|
i_bk2_io2 = 1;
|
|
i_bk2_io3 = 0;
|
|
#10;
|
|
|
|
// byte 6
|
|
i_bk1_io0 = 0;
|
|
i_bk1_io1 = 0;
|
|
i_bk1_io2 = 0;
|
|
i_bk1_io3 = 0;
|
|
i_bk2_io0 = 0;
|
|
i_bk2_io1 = 0;
|
|
i_bk2_io2 = 0;
|
|
i_bk2_io3 = 0;
|
|
#10;
|
|
|
|
// byte 7
|
|
i_bk1_io0 = 0;
|
|
i_bk1_io1 = 1;
|
|
i_bk1_io2 = 1;
|
|
i_bk1_io3 = 0;
|
|
i_bk2_io0 = 1;
|
|
i_bk2_io1 = 1;
|
|
i_bk2_io2 = 1;
|
|
i_bk2_io3 = 0;
|
|
#10;
|
|
|
|
// byte 8
|
|
i_bk1_io0 = 0;
|
|
i_bk1_io1 = 1;
|
|
i_bk1_io2 = 0;
|
|
i_bk1_io3 = 1;
|
|
i_bk2_io0 = 1;
|
|
i_bk2_io1 = 1;
|
|
i_bk2_io2 = 0;
|
|
i_bk2_io3 = 1;
|
|
#10;
|
|
|
|
// byte 9
|
|
i_bk1_io0 = 0;
|
|
i_bk1_io1 = 0;
|
|
i_bk1_io2 = 0;
|
|
i_bk1_io3 = 1;
|
|
i_bk2_io0 = 1;
|
|
i_bk2_io1 = 0;
|
|
i_bk2_io2 = 0;
|
|
i_bk2_io3 = 1;
|
|
#10;
|
|
|
|
// byte 10
|
|
i_bk1_io0 = 0;
|
|
i_bk1_io1 = 0;
|
|
i_bk1_io2 = 1;
|
|
i_bk1_io3 = 1;
|
|
i_bk2_io0 = 1;
|
|
i_bk2_io1 = 0;
|
|
i_bk2_io2 = 1;
|
|
i_bk2_io3 = 1;
|
|
#10;
|
|
|
|
// byte 11
|
|
i_bk1_io0 = 0;
|
|
i_bk1_io1 = 1;
|
|
i_bk1_io2 = 0;
|
|
i_bk1_io3 = 1;
|
|
i_bk2_io0 = 1;
|
|
i_bk2_io1 = 1;
|
|
i_bk2_io2 = 0;
|
|
i_bk2_io3 = 1;
|
|
#10;
|
|
|
|
// byte 12
|
|
i_bk1_io0 = 0;
|
|
i_bk1_io1 = 0;
|
|
i_bk1_io2 = 0;
|
|
i_bk1_io3 = 0;
|
|
i_bk2_io0 = 0;
|
|
i_bk2_io1 = 0;
|
|
i_bk2_io2 = 0;
|
|
i_bk2_io3 = 0;
|
|
#10;
|
|
|
|
// byte 13
|
|
i_bk1_io0 = 0;
|
|
i_bk1_io1 = 0;
|
|
i_bk1_io2 = 1;
|
|
i_bk1_io3 = 1;
|
|
i_bk2_io0 = 1;
|
|
i_bk2_io1 = 0;
|
|
i_bk2_io2 = 1;
|
|
i_bk2_io3 = 1;
|
|
#10;
|
|
|
|
// byte 14
|
|
i_bk1_io0 = 0;
|
|
i_bk1_io1 = 0;
|
|
i_bk1_io2 = 0;
|
|
i_bk1_io3 = 0;
|
|
i_bk2_io0 = 0;
|
|
i_bk2_io1 = 0;
|
|
i_bk2_io2 = 0;
|
|
i_bk2_io3 = 0;
|
|
#10;
|
|
|
|
// byte 15
|
|
i_bk1_io0 = 0;
|
|
i_bk1_io1 = 1;
|
|
i_bk1_io2 = 1;
|
|
i_bk1_io3 = 1;
|
|
i_bk2_io0 = 1;
|
|
i_bk2_io1 = 1;
|
|
i_bk2_io2 = 1;
|
|
i_bk2_io3 = 1;
|
|
#10;
|
|
|
|
i_ncs = 1;
|
|
i_bk1_io0 = 0;
|
|
i_bk1_io1 = 0;
|
|
i_bk1_io2 = 0;
|
|
i_bk1_io3 = 0;
|
|
i_bk2_io0 = 0;
|
|
i_bk2_io1 = 0;
|
|
i_bk2_io2 = 0;
|
|
i_bk2_io3 = 0;
|
|
#20;
|
|
|
|
|
|
$finish;
|
|
end
|
|
|
|
initial begin
|
|
$dumpfile("build/qspi_decoder_tb.vcd");
|
|
$dumpvars(0, qspi_decoder_tb);
|
|
end
|
|
|
|
endmodule
|