`timescale 1ns/1ps module tb_control; localparam int unsigned DAC_DATA_WIDTH = 12; //------------------------------------------------------------ // clocks //------------------------------------------------------------ logic ctrl_clk; logic dac_clk_in; logic adc_clk_in; initial begin ctrl_clk = 0; forever #4 ctrl_clk = ~ctrl_clk; //125 MHz end initial begin dac_clk_in = 0; forever #3.846 dac_clk_in = ~dac_clk_in; //~130 MHz end initial begin adc_clk_in = 0; forever #7.692 adc_clk_in = ~adc_clk_in; //~65 MHz end //------------------------------------------------------------ // DUT inputs //------------------------------------------------------------ logic rst_n; logic rst_soft; logic finish; logic [127:0] cfg_bus_input; logic cfg_bus_valid; logic start; //------------------------------------------------------------ // DUT outputs //------------------------------------------------------------ logic busy; logic [31:0] dac_pulse_width; logic [31:0] dac_pulse_period; logic [DAC_DATA_WIDTH-1:0] dac_pulse_height; logic [15:0] dac_pulse_num; logic [31:0] adc_pulse_period; logic [15:0] adc_pulse_num; logic dac_start; logic adc_start; logic dac_rst; logic adc_rst; //------------------------------------------------------------ // DUT //------------------------------------------------------------ control #( .DAC_DATA_WIDTH(DAC_DATA_WIDTH) ) dut ( .ctrl_clk(ctrl_clk), .dac_clk_in(dac_clk_in), .adc_clk_in(adc_clk_in), .rst_n(rst_n), .rst_soft(rst_soft), .finish(finish), .cfg_bus_input(cfg_bus_input), .cfg_bus_valid(cfg_bus_valid), .start(start), .busy(busy), .dac_pulse_width(dac_pulse_width), .dac_pulse_period(dac_pulse_period), .dac_pulse_height(dac_pulse_height), .dac_pulse_num(dac_pulse_num), .adc_pulse_period(adc_pulse_period), .adc_pulse_num(adc_pulse_num), .dac_start(dac_start), .adc_start(adc_start), .dac_rst(dac_rst), .adc_rst(adc_rst) ); //------------------------------------------------------------ // pulse counters //------------------------------------------------------------ int dac_start_count; int adc_start_count; int dac_rst_count; int adc_rst_count; always_ff @(posedge dac_clk_in) begin if (!rst_n) begin dac_start_count <= 0; dac_rst_count <= 0; end else begin if (dac_start) dac_start_count++; if (dac_rst) dac_rst_count++; end end always_ff @(posedge adc_clk_in) begin if (!rst_n) begin adc_start_count <= 0; adc_rst_count <= 0; end else begin if (adc_start) adc_start_count++; if (adc_rst) adc_rst_count++; end end //------------------------------------------------------------ // tasks //------------------------------------------------------------ task automatic send_cfg( input logic [31:0] pulse_width, input logic [31:0] pulse_period, input logic [15:0] pulse_num, input logic [15:0] pulse_height, input logic [31:0] adc_period ); begin cfg_bus_input = { adc_period, pulse_height, pulse_num, pulse_period, pulse_width }; @(posedge ctrl_clk); cfg_bus_valid <= 1; @(posedge ctrl_clk); cfg_bus_valid <= 0; end endtask task automatic send_start; begin @(posedge ctrl_clk); start <= 1; @(posedge ctrl_clk); start <= 0; end endtask task automatic send_soft_reset; begin @(posedge ctrl_clk); rst_soft <= 1; @(posedge ctrl_clk); rst_soft <= 0; end endtask task automatic pulse_finish; begin @(posedge adc_clk_in); finish <= 1; @(posedge adc_clk_in); finish <= 0; end endtask //------------------------------------------------------------ // TEST //------------------------------------------------------------ initial begin rst_n = 0; rst_soft = 0; finish = 0; start = 0; cfg_bus_valid = 0; cfg_bus_input = 0; repeat(10) @(posedge ctrl_clk); rst_n = 1; repeat(10) @(posedge ctrl_clk); //-------------------------------------------------------- // TEST 1 RESET //-------------------------------------------------------- $display("TEST RESET"); send_soft_reset(); repeat(20) @(posedge ctrl_clk); assert(dac_rst_count==1); assert(adc_rst_count==1); //-------------------------------------------------------- // TEST 2 CONFIG //-------------------------------------------------------- $display("TEST CONFIG"); send_cfg( 32'h11223344, 32'h55667788, 16'hA1B2, 16'h0CDE, 32'h50607080 ); repeat(30) @(posedge ctrl_clk); assert(dac_pulse_width == 32'h11223344); assert(dac_pulse_period == 32'h55667788); assert(dac_pulse_num == 16'hA1B2); assert(dac_pulse_height == 12'hCDE); assert(adc_pulse_period == 32'h50607080); assert(adc_pulse_num == 16'hA1B2); //-------------------------------------------------------- // TEST 3 START //-------------------------------------------------------- $display("TEST START"); send_start(); repeat(20) @(posedge ctrl_clk); assert(busy); assert(dac_start_count==1); assert(adc_start_count==1); //-------------------------------------------------------- // TEST 4 FINISH //-------------------------------------------------------- $display("TEST FINISH"); pulse_finish(); repeat(20) @(posedge ctrl_clk); assert(!busy); //-------------------------------------------------------- // TEST 5 START AGAIN //-------------------------------------------------------- send_start(); repeat(20) @(posedge ctrl_clk); assert(dac_start_count==2); assert(adc_start_count==2); //-------------------------------------------------------- $display(""); $display("=============================="); $display("ALL TESTS PASSED"); $display("=============================="); #100; $finish; end endmodule