0
mirror of https://gitlab.com/hyperglitch/jellyfish.git synced 2025-12-24 06:36:47 +00:00
jellyfish-powersupply/gw/test/qspi_decoder_tb_1c4a8d.sv
Igor Brkic b4a27f8ac4 add ADC sampling and data transfer
- testbenches updated with TB_DEPS directive for granular dependency
definition
- async_fifo added for transferring ADC data to QSPI
- qspi reads fixed
- adc_ctrl properly sampling the ADC
- DAC tested and working
- periodic ADC trigger added
2025-04-27 21:36:04 +02:00

447 lines
8.9 KiB
Systemverilog

`timescale 1ns / 1ps
// SPDX-FileCopyrightText: 2025 Igor Brkic <igor@hyperglitch.com>
// SPDX-License-Identifier: GPL-3.0-or-later
//TB_DEPS: src/qspi_decoder.v src/async_fifo.v test/_module_sb_io.sv
// 1 command line
// 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 = 1;
localparam DUMMY_CYCLES = 2;
localparam DATA_WIDTH = 8;
localparam DATA_LINES = 4;
localparam DATA_BANKS = 2;
reg i_rst;
reg i_ncs;
reg clk_main;
reg clk_qspi;
reg ext_i_bk1_io0;
reg ext_i_bk1_io1;
reg ext_i_bk1_io2;
reg ext_i_bk1_io3;
reg ext_i_bk2_io0;
reg ext_i_bk2_io1;
reg ext_i_bk2_io2;
reg ext_i_bk2_io3;
wire i_bk1_io0;
wire i_bk1_io1;
wire i_bk1_io2;
wire i_bk1_io3;
wire i_bk2_io0;
wire i_bk2_io1;
wire i_bk2_io2;
wire i_bk2_io3;
assign i_bk1_io0 = dut.oe ? 1'bz : ext_i_bk1_io0;
assign i_bk1_io1 = dut.oe ? 1'bz : ext_i_bk1_io1;
assign i_bk1_io2 = dut.oe ? 1'bz : ext_i_bk1_io2;
assign i_bk1_io3 = dut.oe ? 1'bz : ext_i_bk1_io3;
assign i_bk2_io0 = dut.oe ? 1'bz : ext_i_bk2_io0;
assign i_bk2_io1 = dut.oe ? 1'bz : ext_i_bk2_io1;
assign i_bk2_io2 = dut.oe ? 1'bz : ext_i_bk2_io2;
assign i_bk2_io3 = dut.oe ? 1'bz : ext_i_bk2_io3;
reg o_cmd_rdy;
reg o_addr_rdy;
reg o_data_rdy;
reg [ADDRESS_WIDTH-1:0] o_address;
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(clk_qspi),
.i_main_clk(clk_main),
.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),
.o_cmd_rdy(o_cmd_rdy),
.o_addr_rdy(o_addr_rdy),
.o_data_rdy(o_data_rdy),
.o_address(o_address),
.o_command(o_command),
.o_data(o_data)
);
localparam PERIOD_QSPI_CLK = 50;
localparam PERIOD_QSPI_CLK_HALF = PERIOD_QSPI_CLK/2;
localparam PERIOD_MAIN_CLK = 41;
// generate clock
initial begin
clk_qspi = 0;
#25;
forever #PERIOD_QSPI_CLK clk_qspi = ~clk_qspi; // 20MHz
end
initial begin
clk_main = 0;
#17; // phase offset
forever #PERIOD_MAIN_CLK clk_main = ~clk_main; // 24.39MHz
end
// test sequence
initial begin
i_ncs = 0;
#5;
i_ncs = 1;
ext_i_bk1_io0 = 0;
ext_i_bk1_io1 = 0;
ext_i_bk1_io2 = 0;
ext_i_bk1_io3 = 0;
ext_i_bk2_io0 = 0;
ext_i_bk2_io1 = 0;
ext_i_bk2_io2 = 0;
ext_i_bk2_io3 = 0;
// reset
i_rst = 1;
#PERIOD_MAIN_CLK;
i_rst = 0;
#PERIOD_MAIN_CLK;
// chip select
i_ncs = 0;
#100;
// send command over io0 line
ext_i_bk1_io0 = 1;
ext_i_bk2_io0 = 1;
#PERIOD_QSPI_CLK;
ext_i_bk1_io0 = 0;
ext_i_bk2_io0 = 0;
#PERIOD_QSPI_CLK;
ext_i_bk1_io0 = 1;
ext_i_bk2_io0 = 1;
#PERIOD_QSPI_CLK;
ext_i_bk1_io0 = 0;
ext_i_bk2_io0 = 0;
#PERIOD_QSPI_CLK;
ext_i_bk1_io0 = 1;
ext_i_bk2_io0 = 1;
#PERIOD_QSPI_CLK;
#PERIOD_QSPI_CLK;
ext_i_bk1_io0 = 0;
ext_i_bk2_io0 = 0;
#PERIOD_QSPI_CLK;
ext_i_bk1_io0 = 1;
ext_i_bk2_io0 = 1;
#PERIOD_QSPI_CLK;
assert(o_command == 8'hAD);
$display("o_command: %x", o_command);
// send address over all four lines
ext_i_bk1_io0 = 0;
ext_i_bk1_io1 = 0;
ext_i_bk1_io2 = 0;
ext_i_bk1_io3 = 0;
ext_i_bk2_io0 = 0;
ext_i_bk2_io1 = 0;
ext_i_bk2_io2 = 0;
ext_i_bk2_io3 = 0;
#PERIOD_QSPI_CLK;
ext_i_bk1_io0 = 0;
ext_i_bk1_io1 = 0;
ext_i_bk1_io2 = 0;
ext_i_bk1_io3 = 0;
ext_i_bk2_io0 = 0;
ext_i_bk2_io1 = 0;
ext_i_bk2_io2 = 0;
ext_i_bk2_io3 = 0;
#PERIOD_QSPI_CLK;
ext_i_bk1_io0 = 1;
ext_i_bk1_io1 = 0;
ext_i_bk1_io2 = 1;
ext_i_bk1_io3 = 0;
ext_i_bk2_io0 = 1;
ext_i_bk2_io1 = 0;
ext_i_bk2_io2 = 1;
ext_i_bk2_io3 = 0;
#PERIOD_QSPI_CLK;
ext_i_bk1_io0 = 0;
ext_i_bk1_io1 = 1;
ext_i_bk1_io2 = 1;
ext_i_bk1_io3 = 0;
ext_i_bk2_io0 = 0;
ext_i_bk2_io1 = 1;
ext_i_bk2_io2 = 1;
ext_i_bk2_io3 = 0;
#PERIOD_QSPI_CLK;
ext_i_bk1_io0 = 0;
ext_i_bk1_io1 = 1;
ext_i_bk1_io2 = 0;
ext_i_bk1_io3 = 1;
ext_i_bk2_io0 = 0;
ext_i_bk2_io1 = 1;
ext_i_bk2_io2 = 0;
ext_i_bk2_io3 = 1;
#PERIOD_QSPI_CLK;
ext_i_bk1_io0 = 0;
ext_i_bk1_io1 = 1;
ext_i_bk1_io2 = 0;
ext_i_bk1_io3 = 1;
ext_i_bk2_io0 = 0;
ext_i_bk2_io1 = 1;
ext_i_bk2_io2 = 0;
ext_i_bk2_io3 = 1;
#PERIOD_QSPI_CLK;
assert(o_address == 24'h0056AA);
// dummy cycles
ext_i_bk1_io0 = 0;
ext_i_bk1_io1 = 0;
ext_i_bk1_io2 = 0;
ext_i_bk1_io3 = 0;
ext_i_bk2_io0 = 0;
ext_i_bk2_io1 = 0;
ext_i_bk2_io2 = 0;
ext_i_bk2_io3 = 0;
#PERIOD_QSPI_CLK;
#PERIOD_QSPI_CLK;
// send data over 8 lines
// byte 0
ext_i_bk1_io0 = 0;
ext_i_bk1_io1 = 0;
ext_i_bk1_io2 = 1;
ext_i_bk1_io3 = 1;
ext_i_bk2_io0 = 0;
ext_i_bk2_io1 = 0;
ext_i_bk2_io2 = 0;
ext_i_bk2_io3 = 0;
#PERIOD_QSPI_CLK;
// byte 1
ext_i_bk1_io0 = 1;
ext_i_bk1_io1 = 1;
ext_i_bk1_io2 = 0;
ext_i_bk1_io3 = 0;
ext_i_bk2_io0 = 1;
ext_i_bk2_io1 = 0;
ext_i_bk2_io2 = 0;
ext_i_bk2_io3 = 0;
#PERIOD_QSPI_CLK;
// byte 2
ext_i_bk1_io0 = 0;
ext_i_bk1_io1 = 0;
ext_i_bk1_io2 = 0;
ext_i_bk1_io3 = 0;
ext_i_bk2_io0 = 0;
ext_i_bk2_io1 = 0;
ext_i_bk2_io2 = 0;
ext_i_bk2_io3 = 0;
#PERIOD_QSPI_CLK;
// byte 3
ext_i_bk1_io0 = 0;
ext_i_bk1_io1 = 1;
ext_i_bk1_io2 = 0;
ext_i_bk1_io3 = 0;
ext_i_bk2_io0 = 1;
ext_i_bk2_io1 = 1;
ext_i_bk2_io2 = 0;
ext_i_bk2_io3 = 0;
#PERIOD_QSPI_CLK;
// byte 4
ext_i_bk1_io0 = 0;
ext_i_bk1_io1 = 0;
ext_i_bk1_io2 = 0;
ext_i_bk1_io3 = 0;
ext_i_bk2_io0 = 0;
ext_i_bk2_io1 = 0;
ext_i_bk2_io2 = 0;
ext_i_bk2_io3 = 0;
#PERIOD_QSPI_CLK;
// byte 5
ext_i_bk1_io0 = 0;
ext_i_bk1_io1 = 0;
ext_i_bk1_io2 = 1;
ext_i_bk1_io3 = 0;
ext_i_bk2_io0 = 1;
ext_i_bk2_io1 = 0;
ext_i_bk2_io2 = 1;
ext_i_bk2_io3 = 0;
#PERIOD_QSPI_CLK;
// byte 6
ext_i_bk1_io0 = 0;
ext_i_bk1_io1 = 0;
ext_i_bk1_io2 = 0;
ext_i_bk1_io3 = 0;
ext_i_bk2_io0 = 0;
ext_i_bk2_io1 = 0;
ext_i_bk2_io2 = 0;
ext_i_bk2_io3 = 0;
#PERIOD_QSPI_CLK;
// byte 7
ext_i_bk1_io0 = 0;
ext_i_bk1_io1 = 1;
ext_i_bk1_io2 = 1;
ext_i_bk1_io3 = 0;
ext_i_bk2_io0 = 1;
ext_i_bk2_io1 = 1;
ext_i_bk2_io2 = 1;
ext_i_bk2_io3 = 0;
#PERIOD_QSPI_CLK;
// byte 8
ext_i_bk1_io0 = 0;
ext_i_bk1_io1 = 1;
ext_i_bk1_io2 = 0;
ext_i_bk1_io3 = 1;
ext_i_bk2_io0 = 1;
ext_i_bk2_io1 = 1;
ext_i_bk2_io2 = 0;
ext_i_bk2_io3 = 1;
#PERIOD_QSPI_CLK;
// byte 9
ext_i_bk1_io0 = 0;
ext_i_bk1_io1 = 0;
ext_i_bk1_io2 = 0;
ext_i_bk1_io3 = 1;
ext_i_bk2_io0 = 1;
ext_i_bk2_io1 = 0;
ext_i_bk2_io2 = 0;
ext_i_bk2_io3 = 1;
#PERIOD_QSPI_CLK;
// byte 10
ext_i_bk1_io0 = 0;
ext_i_bk1_io1 = 0;
ext_i_bk1_io2 = 1;
ext_i_bk1_io3 = 1;
ext_i_bk2_io0 = 1;
ext_i_bk2_io1 = 0;
ext_i_bk2_io2 = 1;
ext_i_bk2_io3 = 1;
#PERIOD_QSPI_CLK;
// byte 11
ext_i_bk1_io0 = 0;
ext_i_bk1_io1 = 1;
ext_i_bk1_io2 = 0;
ext_i_bk1_io3 = 1;
ext_i_bk2_io0 = 1;
ext_i_bk2_io1 = 1;
ext_i_bk2_io2 = 0;
ext_i_bk2_io3 = 1;
#PERIOD_QSPI_CLK;
// byte 12
ext_i_bk1_io0 = 0;
ext_i_bk1_io1 = 0;
ext_i_bk1_io2 = 0;
ext_i_bk1_io3 = 0;
ext_i_bk2_io0 = 0;
ext_i_bk2_io1 = 0;
ext_i_bk2_io2 = 0;
ext_i_bk2_io3 = 0;
#PERIOD_QSPI_CLK;
// byte 13
ext_i_bk1_io0 = 0;
ext_i_bk1_io1 = 0;
ext_i_bk1_io2 = 1;
ext_i_bk1_io3 = 1;
ext_i_bk2_io0 = 1;
ext_i_bk2_io1 = 0;
ext_i_bk2_io2 = 1;
ext_i_bk2_io3 = 1;
#PERIOD_QSPI_CLK;
// byte 14
ext_i_bk1_io0 = 0;
ext_i_bk1_io1 = 0;
ext_i_bk1_io2 = 0;
ext_i_bk1_io3 = 0;
ext_i_bk2_io0 = 0;
ext_i_bk2_io1 = 0;
ext_i_bk2_io2 = 0;
ext_i_bk2_io3 = 0;
#PERIOD_QSPI_CLK;
// byte 15
ext_i_bk1_io0 = 0;
ext_i_bk1_io1 = 1;
ext_i_bk1_io2 = 1;
ext_i_bk1_io3 = 1;
ext_i_bk2_io0 = 1;
ext_i_bk2_io1 = 1;
ext_i_bk2_io2 = 1;
ext_i_bk2_io3 = 1;
#PERIOD_QSPI_CLK;
i_ncs = 1;
ext_i_bk1_io0 = 0;
ext_i_bk1_io1 = 0;
ext_i_bk1_io2 = 0;
ext_i_bk1_io3 = 0;
ext_i_bk2_io0 = 0;
ext_i_bk2_io1 = 0;
ext_i_bk2_io2 = 0;
ext_i_bk2_io3 = 0;
#20;
$finish;
end
initial begin
$dumpfile("build/qspi_decoder_tb_1c4a8d.vcd");
$dumpvars(0, qspi_decoder_tb);
end
endmodule