I am following the track “FPGA Verification Capabilities” by Ray Salemi, where he goes over 7 steps to convert a rudimentary testbench to a transaction level testbench with self checking and automatic stimulus generation. From my understanding, it is a “UVM-like” testbench, but without using any of the UVM base classes except for TLM FIFOs to manage threads, which is great for someone like me who is just starting out with learning verification.
In the playlist, the driver is a SystemVerilog module, and Input_transaction is a custom SystemVerilog class that holds all the relevant transaction fields
module driver(ref uvm_tlm_fifo #(Input_transaction) in_f,
// output ports to be connected to the DUT
...
);
Input_transaction t;
always @(negedge clk) begin
if(in_f.try_get(t))
// drive the output signals using non-blocking assignments
....
end
endmodule
The input transaction is completed in one clock tick
I’m trying to extend this same concept to a more complex transaction defined as follows:
- Assume that the DUT has an interface with - data, valid and last
- Define one transaction as one “packet” - i.e., one data packet between the first valid and last.
Now, the same concept does not seem to work when writing the driver, as the transaction spans multiple clock ticks:
module driver(ref uvm_tlm_fifo #(Input_transaction) in_f,
output logic valid,
output logic [7:0] data,
output logic last);
Input_transaction t;
always @(negedge clk) begin
if(in_f.try_get(t) begin
valid <= 1;
// what I want to do, but does it work with the always block???
foreach(t.payload[i]) data <= t.payload[i];
end
end
The above does not work the way that I expect - from what I can tell, the always block will trigger every negedge, and thus once the TLM FIFO is read, it will be empty and the foreach block will never drive the other words in the payload.
What might be the best way to extend the driver module to do something like this? Will I have to make a state machine inside the driver module as well? Or is there a cleaner way?
I would prefer not using the UVM constructs as my simulator (Xilinx Simulator) does not support it very well as far as I know.