What are the uses of force - release statements? - verilog

From a hardware point of view, what do force and release statements model? What are the uses of these statements?

The force/release statements are generally used to aid in simulations.
One scenario is to avoid X-propagation in gate simulations. The RTL code sometimes contains registers without asynchronous resets. Although the RTL simulations will run cleanly, gate simulations often do not. Either the X's never get resolved, or they take so many cycles to resolve so as to make simulations take an impractical amount of time to run. By forcing and releasing a random known value into the register during reset, the simulation is allowed to proceed cleanly and complete in a timely manner.
Another scenario involves large counters. For example, to see a 32-bit counter roll over, it requires 4 billion cycles. Typically, you want it to roll over several times in one simulation. Again, this could take an impractically long time to simulate. The force/release can be used to deposit a random value into the counter close to the roll-over value.
Another scenario involves boosting code coverage results. It can be difficult to achieve 100% coverage on all metrics, especially when using IP which can not be modified. The force can be used to toggle an unused signal.
The force/release should be used sparingly and only when you are convinced it is valid to do so.

Based on IEEE Std 1364-2005, the force procedural continuous assignment statement shall override all procedural assignments to a variable or net. The release procedural statement shall end a procedural continuous assignment to a variable or net. The value of the variable shall remain the same until the variable is assigned a new value through a procedural assignment or a procedural continuous assignment.
For example:
module test;
reg a, b, c, d;
wire e;
and and1 (e, a, b, c);
initial begin
$monitor("%d d=%b,e=%b", $stime, d, e);
assign d = a & b & c;
a = 1;
b = 0;
c = 1;
#10;
force d = (a | b | c);
force e = (a | b | c);
#10;
release d;
release e;
#10 $finish;
end
endmodule
In the example above and gate and1 is patched to work as or gate. If you simulate it, you'd get following results:
Results:
00 d=0,e=0
10 d=1,e=1
20 d=0,e=0
Without force statement, for t = 10, e should be equal to 0 (since 1 & 0 & 1 = 0). Using force statement overrides result of and1 and force e = 1. But as soon as release is applied to e, the value is change to 0 (the functionality of and gate is restored).
In the example above you can also see that force/release can be applied both to regs (d) and wires (e). This statements are used in testbenches, when you want to force determined value in reg or wire.

Related

What does <= operator do in this code?

module counter (clk,rst,enable,count);
input clk, rst, enable;
output [3:0] count;
reg [3:0] count;
always # (posedge clk or posedge rst)
if (rst) begin
count <= 0;
end else begin : COUNT
while (enable) begin
count <= count + 1;
disable COUNT;
end
end
endmodule
(Source: http://www.asic-world.com/verilog/verilog_one_day2.html#While)
From what I have learnt, <= is a relational operator and it will return 1 if true and 0 if false, but where does it return in this code?
In the context of your code, <= is not a relational operator, it is an assignment operator. There are two types of assignment in Verilog:
blocking : =
non-blocking : <=
In a Verilog design, you
always use blocking assignments for combinational logic
always use non_blocking assignments for sequential logic
If you do not, you simulation will be indeterminate - it will not necessarily behave the same way every time you run it. Which, of course, is not good.
So, why is that? Well, to start you must learn that Verilog has 4 scheduling regions:
from prev time step
|
ACTIVE
|
INACTIVE
|
NBA
|
POSTPONED
|
V
to next time step
Blocking assignments are executed in the ACTIVE region. However, while the right-hand side of a non-blocking assignment is evaluated in the ACTIVE region, the assignment does not occur until the NBA region. This is key to why you need to use them for sequential logic.
So, why do you need to use non-blocking assignments for sequential logic? The reason is because the delay between evaluation of the right-hand side and assignment of the left hand side enables a Verilog simulation to be determinate, ie to behave the same way every time you run it. This delay means that the behaviour of the simulation does not depend on the order in which the always blocks are executed, which it would if only blocking assignments were used.
A simple analogy to the delay between evaluating the right-hand side of a non-blocking assignment and assigning the left-hand side is the clock-to-Q delay of a real flip-flop. In a real flip-flop, there is always a small delay (clock-to-Q delay) between the D input being sampled (by the clock) and the Q output being driven. This is vital to the correct operation of real sequential logic. For example, if there were no clock-to-Q delay in a real flip-flop instead of it taking exactly 4 clocks for the D input of the first flip-flop in a 4-stage shift register to get to the Q output of the fourth flip-flop, it could take any number of clocks between 1 and 4: its behaviour would also be indeterminate.

Verilog module cannot calculate a&b and a|b

I am creating the verilog module that calculate either one of a+b, a-b, a & b or a | b.
The problem is that it does calculate for a+b and a-b.
but it cannot calculate a & b and a | b and return nothing.
input [31:0] a, b;
input [2:0] op;
output [31:0] z;
output ex;
wire[31:0]a0,a1,a2,a3;
assign a0 = a & b;
assign a1 = a | b;
assign a2 = a + b;
assign a3 = a - b;
assign z=a0;
//assign z=a1;
//assign z=a2;
//assign z=a3;
endmodule
the module basically calculate a+b, a-b, a&b, and a|b and assign its calculated value to z.
And it does successfully calculate for a+b and a-b and put calculated value to z.
But for a&b and a|b, it doesn't assign anything to z.
How can I solve this?
Thank you very much if you can help me.
I'm sure it does assign something to z. The problem is that you are trying to assign too much to z.
Each assign statement represents some hardware, which in this case drives the wire z. So, you are driving z 4 times in parallel from 4 separate lumps of hardware. If you like, you have a short circuit. (Remember Verilog is a hardware description language. You are designing hardware here, not writing software. If you assign to a wire from more than one place, you have shorted the outputs of some lumps of hardware together.)
I notice there is an input [2:0] op. This looks like homework to me and I guess you have been asked to design an ALU. An ALU is a lump of hardware (combinational logic in this case) that can perform various operations on it's inputs (its operands), which in this case are a and b. Which operation it performs needs to be selected by some other control input, which in this case is almost certainly supposed to be op.
So, you need some code that tests op and drives z with either a+b, a-b, a&b or a|b. The obvious construct to me for this job is a case statement:
case (op)
3'b000:
z = // some expression, eg a + b, it depends on what op code 000 is supposed to mean
3'b001:
z = // some other expression here
// etc etc
default: // perhaps...
z = // ...something to drive z if none of the other branches are used
endcase
A case statement should go inside an always block. As I suspect this is homework, I won't feed you the answer, I'll let you work out how to do that.
Finally, I see that op is 3 bits wide. This suggests that you ALU has more than 4 different operations to carry out. I also see there is an ex output, which presumably needs to do something.
There's some confusion here. Your original posted code is fine; z will be assigned as you want. The other answer is incorrect - there are no multiple drivers; they're commented out. The delay suggestion is also incorrect - a delay will make no difference whatever to your logic.

Assigning values in Verilog: difference between assign, <= and =

I have just started learning Verilog and I've seen these three lines from different sources. I am confused about the difference between the three:
c <= a&b;
assign c = ~a;
c = 1'b0;
These lines seem to assign a value to c but what's the difference? Thanks.
1) <=non-blocking and is performed on every positive edge of clock. these are evaluated in parallel so no guarantee of order. An example of this would be a register.
2) assign =continual assignment to wire outside an always statement. value of LHS is updated when RHS changes.
3) =blocking assignment, inside always statements enforces sequential order.

Low power design for adders

I have to implement a circuit that performs A+B+C+D serially.
A and B are added using the first adder, the result is added to C using the second adder and finally the result is added to D using the third adder, one after the other.
The problem is, in order to make the design low power. I have to turn off the other two adders which are not in use. All I can think is Enable and Disable signals, but this causes latency issues.
How do I synthesize this in in an effective manner in verilog?
A,B,C,D may change every clock cycle. a start signal is used to indicate when a new calculation is required.
I assume your adder has been implied via sum = A + B;. For area optimisation why do you not share a single adder unit. A+B in CLK1, SUM+C in CLK2, SUM+D in CLK3. Then you have nothing to disable or clock gate.
The majority of power is used when values change, so zeroing inputs when not used can actually increase power by creating unnecessary toggles. As adders are combinatorial logic all we can do to save power for a given architecture is hold values stable, this could be done through the use of clock gate cells controlling/sequencing input and output flip-flops clks.
Update
With the information that a new calculation may be required every clock cycle, and there is an enable signal called start. Th question made reference to adding them serially ie :
sum1 = A + B;
sum2 = sum1 + C;
sum3 = sum2 + D;
Since the result is calculated potentially every clock cycle they are all on or all off. The given serialisation (which is all to be executed in parallel) has 3 adders stringed together (ripple path of 3 adders). if we refactor to :
sum1 = A + B;
sum2 = C + D;
sum3 = sum1 + sum2;
Or ripple path is only 2 adders deep allowing a quicker settling time, which implies less ripple or transients to consume power.
I would be tempted to do this all on 1 line and allow the synthesis tool to optimise it.
sum3 = A + B + C + D;
For power saving I would turn on auto clock gating when synthesising and use a structure that worked well with this technique:
always #(posedge clk or negedge rst_n) begin
if (~rst_n) begin
sum3 <= 'b0;
end
else begin
if (start) begin //no else clause, means this signal can clk gate the flop
sum3 <= A + B + C + D;
end
end
end

What does always block #(*) means?

If I write the following code:
module POLY(CLK,RESET_n,IN_VALID,IN,OUT_VALID,OUT);
input CLK,RESET_n,IN_VALID;
input [ 3:0] IN;
output OUT_VALID;
output [12:0] OUT;
and then use it:
always #(*)
begin
.........
end
Does it mean that the input CLK,RESET_n,IN_VALID;input [ 3:0] IN; will trigger the always block or only the input that has used in the block will trigger the always block?
But it doesn't write posedge or negedge, so the two both edge will trigger the always block or not?
The (*) means "build the sensitivity list for me".
For example, if you had a statement a = b + c; then you'd want a to change every time either b or c changes. In other words, a is "sensitive" to b & c. So to set this up:
always #( b or c ) begin
a = b + c;
end
But imagine you had a large always block that was sensitive to loads of signals. Writing the sensitivity list would take ages. In fact, if you accidentally leave a signal out, the behaviour might change too! So (*) is a shorthand to solve these problems.
It considers that all the variable will be in sensitivity list. So, you don't need to worry about adding them in the sensitivity list.
It will behave like combinational logic.

Resources