Possible workaround for async negedge reset? - reset

I'd like to have a register with async reset signal, like following:
always #(posedge clk or negedge rst_n)
begin
if(!rst_n)
out <= 1'b0
else
out <= in
end
I have tried class AsyncReset() and withReset(). However, the generated code uses a posedge reset and the variable of AsyncReset() does not accept !.
Is there any workaround for this?

While you cannot invert the AsyncReset type directly (generally applying logic to an AsyncReset is bad because it can glitch), you can cast to a Bool and back:
val reset_n = (!reset.asBool).asAsyncReset
val reg = withReset(reset_n)(RegInit(0.U(8.W)))
Runnable example: https://scastie.scala-lang.org/ERy0qHt2Q3OvWIsp9qiiNg

I thought Jack's quick comment about avoiding glitches deserved a longer explanation.
Using an asynchronous reset creates a second timing arc in the design, from the reset to the end flop. The reset signal can be asserted at any time but needs to be de-asserted synchronous to the clock otherwise the flop can become metastable.
A common technique to do this is to use a reset synchronizer.
https://scastie.scala-lang.org/hutch31/EPozcu39QBOmaB5So6fyeA/13
The synchronizer shown in the above code is coded directly in Verilog as I do not know a way to keep the FIRRTL optimizer from pruning through constant optimization. The logic downstream of the reset sync can be either sync or async reset.

Related

recomend the way to write a monitor in UVM with defferent event polarity

I am trying to implement a monitor for VDU(Video display unit) and the way the VDU can be programmed says that sync signals have controllable polarity. This means than according to VDU settings monitor should react on #posedge or #negedge event. Is there any way to pass the type (means posesge or negedge) via configuration data base or do something like this. Instead of write if(truth) #posedge else #negedge. And assertion also needs to be controlled this way but assertion at list designed to take event type as an argument but I am no sure config data base calls are allowed inside interface.
On option is to conditionally trigger an event. For example, you can have the bellow in you interface:
event mon_clk_ev;
bit mon_polarity;
always #(posedge clk) if ( mon_polarity) ->mon_clk_ev;
always #(negedge clk) if (!mon_polarity) ->mon_clk_ev;
Then you can use mon_clk_ev are the clock event in your monitor, interface, clocking block, or assertion.
mon_polarity could be assigned by your monitor, uvm_config_db, or other logic.
Example using uvm_config_db (Note using uvm_bitstream_t so it can be assigned with the uvm_set_config_int plusarg):
initial begin
start_of_simulation_ph.wait_for_state( UVM_PHASE_STARTED, UVM_GTE );
if (!uvm_config_db#(uvm_bitstream_t)::exists(null,"","mon_polarity")) begin
// default if not in database
uvm_config_db#(uvm_bitstream_t)::set(null,"*","mon_polarity",1'b1);
end
forever begin
void'(uvm_config_db#(uvm_bitstream_t)::get(null,"","mon_polarity",mon_polarity));
uvm_config_db#(uvm_bitstream_t)::wait_modified(null,"","mon_polarity");
end
end
You should write your code assuming positive polarity, but feed them through an xor operator.
logic signal; // your signal from DUT
logic signal_corrected; // signal with positive polarity
bit signal_polarity; // 0 = positive ; 1 = negative
assign signal_corrected = signal ^ signal_polarity;
Now you can use signal_corrected in your assertions. You can certainly call uvm_config_db#(bit)::get() from the interface if it has been set in your testbench. You might need to use uvm_config_db#(bit)::wait_modified() to wait for it to be set before you get it.

What is the best way to check an event occurred in the past in SVA?

I want to check in my design that when signal b get asserted, then signal a should have gotten asserted 3 to 5 cycles before.
I'm looking for the different ways to check that.
Currently I'm using the following logic
sequence s_test();
##1 $rose(a) ##[3:5] 1;
endsequence
property p_test();
##1 $rose(b) |-> s_test.triggered();
Is there a way to check that property without using the sequence triggered mechanism ? I guess I could also use something like $past(a, 3) || ... || $past(a, 5), but that's cumbersome.
Also what's the difference between the sequence triggered and matched mechanism ?
We can have two approaches here: cause then effect or effect because of cause.
Cause then effect approach:
You can use a forward-time-based assertion stating that when s_test is triggered, then b should go high in 1-5 clock period of time window:
s_test.triggered |-> ##[1:5] $rose(b);
Effect then cause approach:
Alternatively, if s_test is a signal, then you can use a glue logic which monitors past 5 values of s_test. Thereafter, the assertion checks that the earlier values of s_test must have atleast 1'b1 when b rises from 0 to 1.
bit[1:5] earlier;
always #(posedge clk) begin
earlier <= {s_test, earlier[1:5]}; // shift for 5 clocks
end
p1_past20: assert property(#(posedge clk)
$rose(b) |-> $countones(earlier) >= 1);
A similar discussion is available here and a reference is over here.
You can use $past something like below.
property test_past;
#(posedge clk)
$rose(b) |-> ##[3:5] $past(a);
endproperty
triggered & matched methods differ for single clock & multi clock sequences.
Both methods show end point of a sequence, but triggered method evaluates to true if the operand sequence has reached it's end point at that particular time and false otherwise.
Whereas matched method detects endpoint of sequence, referenced in multiclocked sequence. So it provides synchronization between 2 sequences and evaluates to true after match, untill arrival of 1st clock tick of destination sequence.
triggered status of a sequence is set in observed region and is persisted through the remainder of the timestep. Whereas matched status of a sequence is set in observed region and is persisted untill the observed region of the arrival of first clock tick of destination sequence after match.

System Verilog: I am confused about the $stable statement

I understand that the $stable(expression) statement returns 'True', if the expression being evaluated has the same value as in the previous clock cycle. However, I don't understand why the following is being said in most learning materials:
assert property(#(posedge clk) enable == 0 |=> $stable(data));
states that data shouldn’t change whilst enable is 0.
As I have proved it, because |=> is being used, this will not work for the following example:
enable 1110000111
data__ ABCAAAABB
assert ______X___
(where A, B and C are some values of the data bus, and X is the point where the assertion would fail)
As you can see, the data has the value A while enable = 0, so it remains stable. But the assertion would not work as desired, because the data changes from A to B at the same time that enable changes from 0 to 1.
So my question is, how would you really implement or code the expression the data shouldn't change while enable is 0.?
Thanks in advance.
Maybe you are thinking of
assert property(#(posedge clk) (enable == 0)[*2] |-> $stable(data));
This means for two consecutive cycles when enable==0, data should not change.
I think "the desired behavior" of the original assertion is not very clear. The state of enable is one clock cycle and $stable is a condition evaluated over 2 clock cycles. There is a similar argument if overlapping implication |->was used. So the question becomes what happens if (enable==0) is true for only one clock cycle? How do you want stability of data defined?

Convert unsigned int to Time in System-verilog

I have in large part of my System-Verilog code used parameters to define different waiting times such as:
int unsigned HALF_SPI_CLOCK = ((SYSTEM_CLK_PERIOD/2)*DIVISION_FACTOR); //DEFINES THE TIME
Now since I define a timescale in my files I can directly use these params to introduce waiting cycles:
`timescale 1ns/1ns
initial begin
#HALF_SPI_CLOCK;
end
Now I want to have time-specified delays everywhere. Means that the simulation will still respect all the timings even if I change the timescale. I would like to keep the parameters but wherever I have a wait statement, I need to specify the time. Something like
#(HALF_SPI_CLOCK) ns;
But this is not accepted by Modelsim. Is there a way to cast a parameter or an Unsigned int to a variable of type time in System-Verilog? Is there a way to specify the time unit? I have looked around but could not find any workaround.
The reason why I want to have control over the time and make it independent from the timescale is because I intend to change thetimescale later to try to make my simulation faster.
Other recommendations or thoughts are very welcome*
It is possible to pass time as a parameter in SystemVerilog, like:
module my_module #(time MY_TIME = 100ns);
initial begin
#MY_TIME;
$display("[%t] End waiting", $time);
end
endmodule
Or use multiplication to get the right time units, like:
module my_module2 #(longint MY_TIME = 100);
initial begin
# (MY_TIME * 1us);
$display("[%t] End waiting 2", $time);
end
endmodule
See runnable example on EDA Playground: http://www.edaplayground.com/x/m2
This will simulate and do what you want. While not the most elegant, it works.
task wait_ns(int num);
repeat (num) #1ns;
endtask
...
wait_ns(HALF_SPI_CLOCK);
This could have a negative impact simulation speed depending on how the timescale, clock events, and the unit of delay relate to each other.

Mixing nonblocking and blocking assignments in an always_ff block of an arbiter

I'm unable to wrap my head around Example 10-3 in SystemVerilog For Design book by Stuart Sutherland (and co.).
See line 232 of :
https://code.google.com/p/vak-opensource/source/browse/trunk/hardware/systemverilog/utopia-example/squat.sv?r=185
Here is the snippet of code. My question will follow.
bit [0:NumRx-1] RoundRobin;
always_ff #(posedge clk, posedge reset) begin: FSM
bit breakVar;
if (reset) begin: reset_logic
Rxready <= '1;
Txvalid <= '0;
Txsel_out <= '0;
SquatState <= wait_rx_valid;
forward <= 0;
RoundRobin = 1;
end: reset_logic
else begin: FSM_sequencer
unique case (SquatState)
wait_rx_valid: begin: rx_valid_state
Rxready <= '1;
breakVar = 1;
for (int j=0; j<NumRx; j+=1) begin: loop1
for (int i=0; i<NumRx; i+=1) begin: loop2
if (Rxvalid[i] && RoundRobin[i] && breakVar)
begin: match
ATMcell <= RxATMcell[i];
Rxready[i] <= 0;
SquatState <= wait_rx_not_valid;
breakVar = 0;
end: match
end: loop2
if (breakVar)
RoundRobin={RoundRobin[1:$bits(RoundRobin)-1],
RoundRobin[0]};
end: loop1
end: rx_valid_state
Specifically, my question is about the blocking assignment for breakVar and RoundRobin. I read somewhere that the variables are locally evaluated, but I can't picture in terms of gates how the logic is synthesized. Does RoundRobin get synthesized to a state register?
Most guidelines state to never mix blocking and nonblocking assignments. Is there a better way to represent something like this? Is it okay now in SystemVerilog designs to mix both types of assignments given that it is in an always_ff block?
You should never mix blocking and nonblocking assignments to the same variable. breakVar is a temporary variable that will be synthesized into combinatorial logic because it is always written to first, then read. There is no state to be saved. RoundRobin is a local variable that is being used as both an intermediate and state variable. But because it is only accessed from within the always_ff block, there is no danger of a race condition.
A temporary variable is just a symbolic way to represent a piece of an equation. Here is a different but simpler example:
always_ff #(posedge clock)
begin
full = (counter == 10);
brimming = (counter > 7);
hold <= brimming && !full;
if (full)
counter <= counter + 1;
else
counter < = 0;
end
This is equivalent to writing the following (but might be harder to understand)
always_ff #(posedge clock)
begin
hold <= (counter > 7) && !(counter == 10);
if (counter == 10)
counter <= counter + 1;
else
counter < = 0;
end
In the two examples above, counter will always be synthesized as a register because it is read before written. It won't matter if we used a blocking or nonblocking assignment because we never read counter after writing it. There is no race condition within this always_ff block using blocking assignment but there could be if there was another always_ff block trying to read it. Since full and brimming are written before being read, they do not have to be registered.
To summarize, a variable get synthesized as a register if any of these conditions are true
A variable is read before being written within the same always block. Note that even if a non-blocking assignment statement appears first, the read happens first because the write get scheduled to happen later.
Due to conditional or looping statements, a variable is sometimes read without being written
A variable is written in an always_ff block and read outside the block.
Totally agreed with #jonathan answer.
You should always split your logic elements in always_comb block and sequential elements in always_ff block.
If you write a code that is so closely stitched together ( both combi
and sequential elements in same block) even though it is correct and
compliant with system verilog spec, some older versions of simulator
or newer simulators being developed may infer it in wrong way.
Your code will not be clean and comprehensible to others.
Also by writing in above style you are just compacting the lines of
code, even though the logic remains same. There is no sense in
writing a compact code if it hampers the readability of the code.
Now as far as blocking and non-blocking statements usage is concerned, I think that debate is closed now. It is now more a rule than a guideline to use blocking statements in always_comb block and non-blocking in always_ff block.
However the answer to all your questions are explained in this superb paper by Clifford E Cummings
Nonblocking Assignments in Verilog Synthesis, Coding Styles That Kill!
And if you are new to verilog/system verilog design I suggest you read all their papers, They are very useful and sets up a good base for a RTL Design Engineer.
Also it may be too much to tell here but if you are looking how to segregate your code in combi and sequential block you can have a look at code generated by bluespec
The signal names are difficult to comprehend in one go, but if you look closely the code is very neat logically and does not leave anything on the whims of simulation and synthesis tools.