xmas-snoopy/gateware/sim/led_ctrl_tb.v

155 lines
2.6 KiB
Verilog

/*
* led_ctrl_tb.v
*
* vim: ts=4 sw=4
*
* Copyright (C) 2022-2023 Sylvain Munaut <tnt@246tNt.com>
* SPDX-License-Identifier: CERN-OHL-P-2.0
*/
`default_nettype none
`timescale 1ns / 100ps
module led_ctrl_tb;
// Signals
// -------
// DUT
wire [13:0] led_a;
wire [2:0] led_c;
wire trig_out;
// Wishbone interface
reg [31:0] wb_wdata;
wire [31:0] wb_rdata;
reg [15:0] wb_addr;
reg wb_we;
reg wb_cyc;
wire wb_ack;
// Clocks / Sync
reg pll_lock = 1'b0;
reg led_clk = 1'b0;
wire led_rst;
reg [3:0] led_rst_cnt = 4'h8;
reg wb_clk = 1'b0;
wire wb_rst;
reg [3:0] wb_rst_cnt = 4'h8;
// Recording setup
// ---------------
initial begin
$dumpfile("led_ctrl_tb.vcd");
$dumpvars(0,led_ctrl_tb);
end
// DUT
// ---
led_ctrl dut_I (
.led_a (led_a),
.led_c (led_c),
.led_clk (led_clk),
.led_rst (led_rst),
.trig_out (trig_out),
.wb_addr (wb_addr),
.wb_rdata (wb_rdata),
.wb_wdata (wb_wdata),
.wb_we (wb_we),
.wb_cyc (wb_cyc),
.wb_ack (wb_ack),
.wb_clk (wb_clk),
.wb_rst (wb_rst)
);
// Stimulus
// --------
task wb_write;
input [15:0] addr;
input [31:0] data;
begin
wb_addr <= addr;
wb_wdata <= data;
wb_we <= 1'b1;
wb_cyc <= 1'b1;
while (~wb_ack)
@(posedge wb_clk);
wb_addr <= 4'hx;
wb_wdata <= 32'hxxxxxxxx;
wb_we <= 1'bx;
wb_cyc <= 1'b0;
@(posedge wb_clk);
end
endtask
initial begin
// Defaults
wb_addr <= 4'hx;
wb_wdata <= 32'hxxxxxxxx;
wb_we <= 1'bx;
wb_cyc <= 1'b0;
@(negedge wb_rst);
@(negedge led_rst);
@(posedge wb_clk);
// Write to frame memory
// Anode 4
// C0 [00-7f] (all ON)
// C1 (all OFF)
// C2 [40-4f] (16 cycles)
wb_write(16'h0200, 32'h7f_00_00_04);
wb_write(16'h0201, 32'h4f_40_00_7f);
wb_write(16'h0202, 32'h01_01_00_0a);
wb_write(16'h0203, 32'h01_00_00_01);
// Enable
wb_write(16'h0000, 32'hc0000007);
end
// Clock / Reset
// -------------
// Clocks
initial begin
# 200 pll_lock = 1'b1;
# 1000000 $finish;
//# 35000000 $finish;
end
always #20 wb_clk = ~wb_clk; // 25 MHz
always #83 led_clk = ~led_clk; // 6 MHz
// Reset
always @(posedge wb_clk or negedge pll_lock)
if (~pll_lock)
wb_rst_cnt <= 4'h8;
else if (wb_rst_cnt[3])
wb_rst_cnt <= wb_rst_cnt + 1;
assign wb_rst = wb_rst_cnt[3];
always @(posedge led_clk or negedge pll_lock)
if (~pll_lock)
led_rst_cnt <= 4'h8;
else if (led_rst_cnt[3])
led_rst_cnt <= led_rst_cnt + 1;
assign led_rst = led_rst_cnt[3];
endmodule