In reply to dave_59:
Hi Dave, thanks for the reply. That did not fix my issue unfortunately, so I am going to post the testbench code below. I am going to try and delete out the irrelevant stuff to make it easier to read.
TB Module:
timescale 1ns/1ns
import header_pkg::*;
import common_pkg::*;
import testcase_pattern_generator_pkg::*;
module tb_fpga();
// Pattern Generator interface
pattgen_if pattgen_if();
// Group: Class Constructs
//////////////////////////////////////////////////////
// Contains misc tools to add wait states and monitor interrupt on a signal
common_pkg::events #(`CLOCK_PARAM) ev; // task_wait_x_seconds, task_wait_clock_cycles
// Class used to validate the test results.
common_pkg::scoreboard scrb;
// Testcases
testcase_pattern_generator_pkg::class_testcase_pattern_generator #(`CLOCK_PARAM) testcase_pattern_gen;
// instantiate the pattern_gen_v1_0 for the pattern generator test
pattern_gen_v1_0 #(
.C_AXIS_TDATA_WIDTH(24),
.C_S_AXI_DATA_WIDTH(32),
.C_S_AXI_ADDR_WIDTH(32)
)
pattern_gen_inst
(
.i_video_vsync(pattgen_if.video_vsync),
.o_vsync_int(pattgen_if.vsync_int),
.i_axis_aclk(pattgen_if.axis_aclk),
.i_axis_aresetn(pattgen_if.axis_aresetn),
.s_axis_tdata(pattgen_if.s_axis_tdata),
.s_axis_tvalid(pattgen_if.s_axis_tvalid),
.s_axis_tready(pattgen_if.s_axis_tready),
.s_axis_tuser_sof(pattgen_if.s_axis_tuser_sof),
.s_axis_tlast(pattgen_if.s_axis_tlast),
.m_axis_tdata(pattgen_if.m_axis_tdata),
.m_axis_tvalid(pattgen_if.m_axis_tvalid),
.m_axis_tready(pattgen_if.m_axis_tready),
.m_axis_tuser_sof(pattgen_if.m_axis_tuser_sof),
.m_axis_tlast(pattgen_if.m_axis_tlast),
.s_axi_aclk(pattgen_if.s_axi_aclk),
.s_axi_aresetn(pattgen_if.s_axi_aresetn),
.s_axi_awaddr(pattgen_if.s_axi_awaddr),
.s_axi_awprot(pattgen_if.s_axi_awprot),
.s_axi_awvalid(pattgen_if.s_axi_awvalid),
.s_axi_awready(pattgen_if.s_axi_awready),
.s_axi_wdata(pattgen_if.s_axi_wdata),
.s_axi_wstrb(pattgen_if.s_axi_wstrb),
.s_axi_wvalid(pattgen_if.s_axi_wvalid),
.s_axi_wready(pattgen_if.s_axi_wready),
.s_axi_bresp(pattgen_if.s_axi_bresp),
.s_axi_bvalid(pattgen_if.s_axi_bvalid),
.s_axi_bready(pattgen_if.s_axi_bready),
.s_axi_araddr(pattgen_if.s_axi_araddr),
.s_axi_arprot(pattgen_if.s_axi_arprot),
.s_axi_arvalid(pattgen_if.s_axi_arvalid),
.s_axi_arready(pattgen_if.s_axi_arready),
.s_axi_rdata(pattgen_if.s_axi_rdata),
.s_axi_rresp(pattgen_if.s_axi_rresp),
.s_axi_rvalid(pattgen_if.s_axi_rvalid),
.s_axi_rready(pattgen_if.s_axi_rready)
);
endmodule
Interface:
/////////////////////////////////////////////////////////////
// Pattern Generator Interface
/////////////////////////////////////////////////////////////
interface pattgen_if;
// all the pattern generator IOs are connectd to the interface:
logic video_vsync;
logic vsync_int;
bit axis_aclk;
logic axis_aresetn;
logic [23:0] s_axis_tdata;
logic s_axis_tvalid;
logic s_axis_tready;
logic s_axis_tuser_sof;
logic s_axis_tlast;
logic [23:0] m_axis_tdata;
logic m_axis_tvalid;
logic m_axis_tready;
logic m_axis_tuser_sof;
logic m_axis_tlast;
bit s_axi_aclk;
logic s_axi_aresetn;
logic [31:0] s_axi_awaddr;
logic [2:0] s_axi_awprot;
logic s_axi_awvalid;
logic s_axi_awready;
logic [31:0] s_axi_wdata;
logic [3:0] s_axi_wstrb;
logic s_axi_wvalid;
logic s_axi_wready;
logic [1:0] s_axi_bresp;
logic s_axi_bvalid;
logic s_axi_bready;
logic [31:0] s_axi_araddr;
logic [2:0] s_axi_arprot;
logic s_axi_arvalid;
logic s_axi_arready;
logic [31:0] s_axi_rdata;
logic [1:0] s_axi_rresp;
logic s_axi_rvalid;
logic s_axi_rready;
endinterface
Testcase Class:
// CONTENTS
// ===========================
// 43 : ____
// 44 : Functions
// 143 : TestCases
// ---------------------------
package testcase_pattern_generator_pkg;
// Import common tools (scoreboard, events, ...)
import common_pkg::*;
class class_testcase_pattern_generator #(MONITOR_CLOCKS=0, NUM_CLOCKS=1) extends common_pkg::test_base #(.NUM_OF_TESTS(1));
// Verification class used to monitor testcases. <scoreboard>
common_pkg::scoreboard scrb;
// Used tp monitor interrupts and clocks. <events>
// System Clock
common_pkg::events #( .MONITOR_CLOCKS(MONITOR_CLOCKS), .NUM_CLOCKS(NUM_CLOCKS)) ev;
virtual ps_if vps_if;
//module interfaces
virtual pattgen_if vpattgen_if;
// INDEX: .new(clock_if, ps_if)
function new(
virtual clock_if #(MONITOR_CLOCKS, NUM_CLOCKS) vclock_if,
virtual ps_if vps_if,
virtual pattgen_if vpattgen_if
);
super.new("Pattern Generator");
scrb = new();
ev = new(vclock_if, 0);
this.vps_if = vps_if;
this.vpattgen_if = vpattgen_if;
endfunction
// INDEX: .task_call_testcase(num)
task task_call_testcase(input int num, output error);
case(num)
'd0: input_stimulus();
endcase
endtask
//----------------------------------------------------------------------------------------------------
// INDEX: ____
// INDEX: Functions
//----------------------------------------------------------------------------------------------------
//reset generation
task reset_gen();
$display("[%0t]: Reseting TPG", $time);
vpattgen_if.axis_aresetn = 0;
vpattgen_if.s_axi_aresetn = 0;
#340; //toggle the reset lines (active low) - need to be held for 16 clock cycles = 340ns
vpattgen_if.axis_aresetn = 1;
vpattgen_if.s_axi_aresetn = 1;
endtask
//50 MHz clock signal generation
task clock_gen();
fork
vpattgen_if.axis_aclk = 0;
vpattgen_if.s_axi_aclk = 0;
forever #10 vpattgen_if.axis_aclk <= ~vpattgen_if.axis_aclk;
forever #10 vpattgen_if.s_axi_aclk <= ~vpattgen_if.s_axi_aclk;
join
endtask
task signal_init();
//Video signals
vpattgen_if.video_vsync = 0; // vsync from slave video stream
vpattgen_if.s_axis_tvalid = 0; // input video valid signal
vpattgen_if.s_axis_tuser_sof = 0; // input video start of frame
vpattgen_if.s_axis_tlast = 0; // input video end of line
vpattgen_if.m_axis_tready = 1; // output ready signal
//AXI signals
vpattgen_if.s_axi_awprot = "000"; // defines the access permissions for write accesses (3 bit)
vpattgen_if.s_axi_arprot = "000"; // defines the access permissions for read accesses(3 bit)
vpattgen_if.s_axi_wstrb = 4'b1111; // write strobes - not used(4 bit)
vpattgen_if.s_axi_arvalid = 0; // read address valid
vpattgen_if.s_axi_rready = 0; // read address ready
vpattgen_if.s_axi_bready = 1; // response ready - indicates that the master can accept a write response
vpattgen_if.s_axi_awvalid = 1; // write address valid
vpattgen_if.s_axi_wvalid = 1; // write data valid
endtask
task write_reg(input int wsize, input int addr);//, output int error);
wait (vpattgen_if.s_axi_wready == 1'b1); //wait for wready signal
vpattgen_if.s_axi_awaddr = addr;
vpattgen_if.s_axi_wdata = wsize;
wait (vpattgen_if.s_axi_bvalid == 1'b1); //wait for write successful confirmation
//TO DO: display error message here if o_s_axi_bvali does not go high, indicating failed axi write
//#80;
endtask
task input_stimulus();
begin
$display("Test has started");
fork
reset_gen();
clock_gen(); //forever statements causing simulation to hang
signal_init();
join
#2000;
//$finish;
end
endtask
endclass
endpackage