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

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.

Related

What exactly do x and z values represent in Verilog?

The Verilog standard defines four types of bit values: 0, 1, x, and z where 0 means low, 1 means high, x means unknown, and z means an undriven net.
A couple of questions:
Does x mean that we don't know if the value is 0 or 1? 0 or 1 or z? or that the value is just unknown and can be something else than 0, 1, or z?
Since z represents an undriven net, can a reg type have a z bit? If so, what does it mean?
The value X means a number of things depending on what kind of signal you are referring to and how it got that value.
For a variable with a 4-state data data type, X is the default initial state, meaning its value is unknown and has the potential to be any value. This is a symbolic state as real hardware will be in a particular state 0 or 1 at any specific point in time.
You can also assign variable to the value X because of some operation that you either don't-care what its value is, or want to consider that operation illegal. Synthesis tools use that don't-care information when optimizing your logic and it will produce deterministic logic.
Nets have values that are a resolution functions of one or more drivers or continuous assignments. The built-in net types resolves multiple drivers by looking at their drive strengths, highest strengths wins. When there is a conflict between equal strengths driving 0 and 1, a wire resolves the conflict with an X value. The absence of any strength is called the Z state.
It's possible for a variable to be assigned the X or Z state and have that value drive a net through a continuous assignment. If the wire is being driven with a stronger strength, that strong strength's value prevails.
Typically, x means that we don't know if the value is 0 or 1. I suppose it could also include z. I don't think it ever means anything other than 0/1/z.
x in simulation often means that the signal was not initialized to a 0 or a 1. This common if you are modeling a flip-flop without a reset.
Another common reason for an x is when a net is driven by multiple drivers (contention). If one is driving a 0 and the other a 1, the result is x.
Yes, a reg can have the value z. It is common to use procedural assignments to a reg. Here is a simple example of a tri-state driver:
module tb;
reg en = 0;
reg out;
always #* out = en ? 1 : 'z;
initial begin
$monitor($time, " en=%b out=%b", en, out);
#5 en = 1;
#5 en = 0;
#5 $finish;
end
endmodule
Prints:
0 en=0 out=x
5 en=1 out=1
10 en=0 out=z
This could also be modeled using a continous assignment:
wire out = en ? 1 : 'z;
In both cases (reg and wire), the z means the same thing.

When I compile my Verilog code I get this message. Anybody know what is the reason?

When I compile my code I get these error msg for following lines. can someone explain it.
This is verilog code for a processor
assign Imm = instruction[7:0];
assign OUT1addr = instruction[2:0];
assign OUT2addr = instruction[10:8];
assign INaddr = instruction[18:16];
assign address = instruction[23:16];
assign address = instruction[7:0];
The following message comes for ABOVE LINES
tgt-vvp sorry: procedural continuous assignments are not yet fully supp
orted. The RHS of this assignment will only be evaluated once, at the time the assignment statement is executed.
You did not do what I asked which is show me where that code is.
From the error message I very much suspect that code is inside an always block:
always #( ...)
...
assign Imm = instruction[7:0];
This is called "a procedural continuous assignment".
The alternative is:
always #( ...)
...
Imm = instruction[7:0];
This is a standard assignment.
There is a significant difference between the two. You would normally not use the first form (unless you really, really know what you are doing.)
Thus the solution is to remove all the 'assign' keywords if they are inside an always block.
Outside an always you need the assign:
always #( * )
begin
...
x = y ^ z;
end
assign write = valid & select;
The short answer is you should probably remove the assign keyword.
The assign keyword has two different meanings depending on context you do not show.
When used at the top level of a module, the assign keyword is a permanent process sensitive to RHS changes and assigns it to the LHS wire. The assign statement has equivalent functionality to the always block below
module mod;
...
assign Awire = B + C;
always #(B or C) begin
Areg = B + C;
end
endmodule
When used inside a procedural process, it is a temporary process that assigns the LHS variable every time the RHS changes. The two always blocks below have the same functionality
module top;
...
always #(sel)
begin
if (sel)
assign Areg = B;
else
assign Areg = C;
end
always #(sel or B or C) // #*
begin
if (sel)
Areg = B;
else
Areg = C;
end
endmodule
Unfortunately, almost all synthesis tools require you to write your code with a complete sensitivity list as in the latter always block. Thus this eliminates allowing the use of assign inside a procedural block.

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.

What are the uses of force - release statements?

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.

Verilog: Can you put "assign" statements within always# or begin/end statements?

Is this allowed?
input w;
input [8:0]y;
output reg [8:0]x;
always#(w)
begin
//x[0] or A is never on in any next state
assign x[0] = 0;
assign x[1]= (y[0]&~w) | (y[5]&~w) | (y[6]&~w) | (y[7]&~w) | (y[8]&~w); //B
assign x[2]= (y[1]&~w); //C
assign x[3]= (y[2]&~w); //D
assign x[4]= (y[3]&~w) | (y[4]&~w); //E
assign x[5]= (y[0]&w) | (y[1]&w) | (y[2]&w) | (y[3]&w) | (y[4]&w); //F
assign x[6]= (y[5]&w);
assign x[7]= (y[6]&w);
assign x[8]= (y[7]&w) | (y[8]&w);
end
You can, it's called a "Procedural Continuous Assignment". It overrides ordinary procedural assignments, there doesn't seem to be a call for them in the code you've posted. I'm not sure if they're synthesisable, but I never have cause to use them anyway.
A note on your code - you're missing y from your sensitivity list: eg always #( w or y ) or always #(*) is safer.
Building upon Marty's answer, you should read section 9.3 of the IEEE Verilog Standard (1364-2005, for example), where it describes "Procedural Continuous Assignment". The spec allows for assign statements within an always block. However, from my experience, it is quite rare.
Another issue with your code is that it has compile errors with two different simulators that I tried. Both generate error messages that bit-selects or part-selects cannot be used on the left hand side of the assignment.
Another possible solution is to get rid of the always block, and just use simple continuous assignments.
input w;
input [8:0] y;
output [8:0] x;
assign x[0] = 0;
assign x[1]= (y[0]&~w) | (y[5]&~w) | (y[6]&~w) | (y[7]&~w) | (y[8]&~w); //B
assign x[2]= (y[1]&~w); //C
assign x[3]= (y[2]&~w); //D
assign x[4]= (y[3]&~w) | (y[4]&~w); //E
assign x[5]= (y[0]&w) | (y[1]&w) | (y[2]&w) | (y[3]&w) | (y[4]&w); //F
assign x[6]= (y[5]&w);
assign x[7]= (y[6]&w);
assign x[8]= (y[7]&w) | (y[8]&w);
The procedural continuous assign statement was intended to be an optimized way of writing a mux-like behavior. For example, if you have
always #(A or B or select)
if (select)
out = A;
else
out = B;
You could write this as
always #(select)
assign out = A;
else
assign out = B;
But people don't like having to deal with sensitivity lists, so #(*) was added to Verilog, and SystemVerilog added always_comb.
But the real killer for this construct is that many people would write code like
always #(*)
assign out = A;
Which simulates fine, but you now have a double penalty in performance because the assign statement is already sensitive to changes in A, but so is the always block. This repeatedly executes the procedural assign statement replacing the same RHS.
Assign is a continuous assignment statement which is used with wires in Verilog. assign statements don't go inside procedural blocks such as always. Registers can be given values in an always block.
Assign statements can be viewed as:
always #(*)
statements for wires.
Yes, but you don't want to. Since x[] doesn't depend on x[] the order doesn't matter. Just use <= instead of assign =.
There is no need using assign inside a procedural block (In this case Always)
Assign is a continuous assignment, and it has to go outside a procedural block.
Thinking from the circuit level: this always(w) begin ..... end , so every code inside it will be activated whenever w is changed ie it falls or raise .
assign statement requires pin/port which it assign to some wire or reg output
its a complete combinational circuit I am unable to see how the same will only activate at w, that is who/what circuit will make it to only change when w either rises or fall
anyway you cant assign a reg output to some wire/reg output using assign statement because as I said it requires you to put pin/port to be assigned only
anyway if you go for basic verilog and not so called "Procedural Continuous Assignment" i guess its weird to use the same .

Resources