Is there a way to assert that all signals in a design are initialized on rising clock during reset? - tags

Just from the tester flow (no changes to design) is there a quick way to assert that all the design signals are initialized during reset?
Design uses synchronous active low reset.
On the rising edge of reset I want to assert that every signal in the design is not 'U' without having to call out each signal or architecture.
Using VHDL 2008, Modelsim 10.1c with HDL Designer.

You can adapt the use of the Modelsim when command from this answer to look for 'U' in any signals after the synchronous reset is released. As it exists it works with scalars and arrays but cannot examine record members.
Note that the rising edge of reset is not the time that reset is released since you are using synchronous reset. I would make the test wait for the first falling edge of clock when reset is high to test for 'U'. This will ensure that you see the new state on signals when their drivers update after the reset. The when expression would be something like:
"clk'event and clk = '0' and reset = '1' and $sig = [string repeat U [string length [examine $sig]]]"
Another option would be to create a sentinel signal in the testbench that evaluates to true when reset is released and test for that in the when expression:
signal reset_inactive : boolean;
process(clk) is
begin
if rising_edge(clk) then
if reset = '1' then
reset_inactive <= true;
else
reset_inactive <= false;
end if;
end if;
end process;
...
When expression:
"reset_inactive'event and reset_inactive = true and $sig = ..."
Once complete it would be a good idea to cancel the waits with the nowait command to avoid the performance hit of having a wait on every signal in the design since you only need this test after reset.

Related

How to check in SystemVerilog that signal went high during simulation using ModelSim

I need to check, whether during the testbenching the particular signal went at least for a single clock cycle to logic 1.
I've tested following asserts, which shall be equivalent:
initial assert property (
#(posedge clk_tree_x.ClkRsBST_ix.clk)
s_eventually TS.TSUpdated) else
$error("Was not active");
and
initial begin
assert property (#(posedge clk_tree_x.ClkRsBST_ix.clk)
strong(##[*] TS.TSUpdated)) else
$error("Was not active");
end
In simulation using Mentor ModelSim SE64 2021.1 the results are extremely weird.
On first simulation pass the simulation completely ignores this assert. On second simulation pass ModelSim apparently uses results of previous simulation to announce before even the newly run simulation happens that the assert triggered:
# Time: 2005087500 ps Started: 5 ns Scope: tb_bst_provider.DUT.fook File: bst_provider.sv Line: 669
# ** Warning: (vsim-8777) Breakpointing based on severity while evaluating concurrent assertion is not supported.
# Time: 2005087500 ps Iteration: 0 Region: /tb_bst_provider/DUT File: bst_provider.sv
Not sure whether this is consistent behaviour to all strong properties, but it is hardly useful for any sort of unit testing, as the tests never run twice using the same parameters.
Is there any way how to assert that 'signal is not present through the simulation run', which actually works with modelsim?
I am not sure if you can do it with an assertion. You can detect not active signal using an assertion coverage. In any case you should not place an assertion in the initial block.
Potentially checking for activity can be done without using an assertion as in the following example.
always #(posedge clk) begin
if (sig == 1)
active <= 1;
end
final begin
if (!active)
$error("was not active");
else
$info ("it was active");
end
Just make sure that you have a normal exit from simulation or final might not be executed at all in case of interrupts.

UVM end of test

In case I want to end the simulation from my monitor (I know that it is not the recommended way) how can I do this?
lets say I got this code inside my monitor:
Virtual task monitor_run();
fork
forever begin
.....
end
forever begin
.....
end
forever begin
.....
end
join
endtask : monitor_run
Every forever loop check that outputs of the DUT came on time, in case they doesnt it should stop simulation.
This special monitor should break the simulation in case of mismatch(error) and there is no Scoreboard.
I still want to manage nice end of simulation behaviour. I tried use raise and drop objection but I get an error of OBJT_ZERO sometimes. Does anyone knows a good way to end the simulation in that case?
thanks!
The UVM is set up by default so that uvm_report_fatal ends the test immediately, and uvm_report_error lets the simulation continue until hitting an error limit that you can set. And you can control the actions of each severity for an individual component. See uvm_report_object which is the base class of uvm_component.
Upon ending the test, the UVM calls uvm_report_server::report_summarize() that dumps out all the severity counts. If you insist, you can create a final block in your testbench module that gathers the severity counts from the report server and print the last message. For example:
module top;
initial run_test();
uvm_report_server rs = uvm_report_server::get_server();
final if (rs.get_severity_count(UVM_FATAL) != 0 ||
rs.get_severity_count(UVM_ERROR) !=0 )
$display("Test Failed");
endmodule
But this is really unnecessary and may not catch other non-UVM errors like assertion failures or timing checks. Many tools have a TESTSTATUS exit code that reports the most severe message encounte, UVM or tool.

How to modify bit bash sequence for write delays and read delays of DUT?

I have a DUT were the writes takes 2 clock cycles and reads consume 2 clock cycles before it could actually happen, I use regmodel and tried using inbuilt sequence uvm_reg_bit_bash_seq but it seems that the writes and reads happens at 1 clock cycle delay, could anyone tell what is the effective way to model 2 clock cycle delays and verify this, so that the DUT delays are taken care.
Facing the following error now,
Writing a 1 in bit #0 of register "ral_pgm.DIFF_STAT_CORE1" with initial value 'h0000000000000000 yielded 'h0000000000000000 instead of 'h0000000000000001
I have found one way of doing it, took the existing uvm_reg_single_bit_bash_seq and modified by adding p_sequencer and added 2 clock cycle delays after write and read method calls as per the DUT latency, this helped me in fixing the issue as well added a get call after write method to avoid fetching old value after read operation.
...
`uvm_declare_p_sequencer(s_master_sequencer)
rg.write(status, val, UVM_FRONTDOOR, map, this);
wait_for_clock(2); // write latency
rg.read(status, val, UVM_FRONTDOOR, map, this);
wait_for_clock(2); // read latency
if (status != UVM_IS_OK) begin
`uvm_error("mtm_reg_bit_bash_seq", $sformatf("Status was %s when reading register \"%s\" through map \"%s\".",
status.name(), rg.get_full_name(), map.get_full_name()));
end
val = rg.get(); // newly added method call (get) to fetch value after read
...
task wait_for_clock( int m = 1 );
repeat ( m ) begin
#(posedge p_sequencer.vif.CLK);
end
endtask: wait_for_clock
...

inout signal doesn't change in simulation

Let's say I have an entity called "HostToDevice" which has a "ps2c" inout signal (VHDL). In this entity I only set this signal to 'Z' (high impedance) because I want an other entity to control it.
I created a test bench to check the behavior and something strange (for me) happens. In the test bench I have this code:
ps2ctemp_process :process
begin
ps2ctemp <= '0';
wait for ps2c_period/2;
ps2ctemp <= '1';
wait for ps2c_period/2;
end process;
And after:
stim_proc: process
begin
ps2c <= ps2ctemp;
wait;
end process;
When I run the simulation (behavioral) the "ps2c" inout signal is just low and doesn't change like ps2ctemp signal does.
Instead if I drive manually the ps2c signal without using another signal it works fine; like this:
ps2c <= '1';
wait for 10 ns;
ps2c <= '0';
wait for 10 ns;
ps2c <= '1';
Your "stim_proc" has no sensitivity list, and one "wait" without event or timeout, so it is intended to run once and wait forever. This seems to be what the sim is doing, so, good.
Now I'll make a wild guess here, that you actually want it to wake up every time ps2ctemp changes, and pass on the new value to ps2c.
There are two ways to do that:
(1) with a sensitivity list
stim_proc: process(psc2temp)
begin
ps2c <= ps2ctemp;
--wait;
-- no, we want the process to complete, so it can be woken up
-- and run from the start again
end process;
(2) with a wait for a specific event...
stim_proc: process
begin
ps2c <= ps2ctemp;
wait until ps2ctemp'event;
-- any activity at all on ps2ctemp should wake this process,
-- in case there is something it ought to be doing...
end process;
In this simple case, these two forms are essentially equivalent. So the simpler one (sensitivity list) is to be preferred...

Is it possible to stop or interrupt a code in MATLAB if a condition is reached and end the simulation of the program code ?

Is it possible to stop or interrupt a code in MATLAB if a condition is reached and end the simulation of the program code ? eg I have a loop that involves calculating a parameter and the moment the value becomes a complex no. I would like my code to stop executing and return the value of the counter at which the parameter value became complex.
Yes, it is possible. If you want to exit your script, you can use this:
if complex(parameter)
disp(counter);
return;
end
If you want to exit a function and return the value of the counter to the caller, you can use this:
if complex(parameter)
return(counter)
end
If you just want to break out of a loop, use this:
for ...
if complex(parameter)
break;
end
end
print(counter)