I want to compare the outputs of a module that has multiple instances in a top-level design module.
For instance, I’ve the following module.
module memory(a_i, rdata_a1_o);
...
input a_i;
output rdata_a1_o;
...
endmodule
The top-level design module (design_top) which is DUT, has multiple instances of memory module. For example,
design_top.core.grid1.tile1.memory
design_top.core.grid2.tile2.memory
An interface drives inputs to both memory modules from tb_top as follows:
force tb_top.DUT.core.grid1.tile1.memory.a_i = intf.a_i;
force tb_top.DUT.core.grid2.tile2.memory.a_i = intf.a_i;
Since both memory instances receive similar inputs from the interface, both should generate similar outputs as well.
To check this I’ve asserted both outputs at tb_top as follows:
//assigning memory instance 1 output to interface output port
assign intf.rdata_a1_o = DUT.core.grid1.tile1.memory.rdata_a1_o;
//assigning memory instance 2 output to a local var (logic)
assign READ_DATA_a1 = DUT.core.grid2.tile2.memory.rdata_a1_o;
initial begin
forever begin
#5
//check if both memory generates same output
assert (intf.rdata_a1_o === READ_DATA_a1) else `uvm_error("ERROR", "MEMORY OUT MISMATCH")
end
end
Now this works fine for me upto two memory instances. However, if there are 100+ instances of memory in design_top, driven and compared in a similar way, this doesn’t work (test get stuck)
Can anyone suggest a more efficient way to do this?
Thanks
In reply to Asraful_21:
I’m thinking you could use the bind construct to instantiate a checker module/interface in every memory.
It is not clear why in your example the output of memory_instance 1 is connected to an interface, and the output of memory_instance 2 is connected to a tb_top.READ_DATA_a1.
You use the word “similar”. Did you mean to use the word “identical”
Why are you using force statements?
In reply to dave_59:
You use the word “similar”. Did you mean to use the word “identical”
Yes, Outputs from each memory should be identical.
It is not clear why in your example the output of memory_instance 1 is connected to an interface, and the output of memory_instance 2 is connected to a tb_top.READ_DATA_a1.
The number of memory instances in design_top can vary. So I wouldn’t know for sure how many outputs (intf.rdata_a1_o) should I have to keep in the interface. So interface is not an option unless parameterized. But I prefer not to change the interface at this point.
So to make the testbench flexible for any number of memory in DUT, the outputs from memory instances are kept in a separate array of variables and compared. It looks something like as follows:
//assigning memory instances output to array
assign READ_DATA_a1[0] = DUT.core.grid1.tile1.memory.rdata_a1_o;
assign READ_DATA_a1[1] = DUT.core.grid2.tile2.memory.rdata_a1_o;
//comparing outputs from both memory
for (i=0;i<`NUM_OF_MEMORY-1;i++)
assert ( READ_DATA_a1[i] == READ_DATA_a1[i+1] )
end
Why are you using force statements?
Well, there are no top-level ports to drive into memory instances. So I had to force inputs to memory instances from tb_top.