Sunteți pe pagina 1din 27

Verilog _3(Verilog assignments)

We have two types of assignments

- continuous assignments

- procedural assignments

The difference between continuous and procedural assignment is, continuous assignments take
place in parallel while procedural assignments take place one after the other. Continuous
assignment can model only Combinational logic while procedural assignment can model both
Combinational and Sequential logic.

Continuos Statements:

Continuous assignment can only drive wire or tri data type. Which means left-side data type
should be net data type.
Continuous assignments should appear outside procedures(always, initial, functions, tasks, etc)
It executes each time the right hand side expression changes. It overrides any procedural
assignment.
A wire should be assigned only once using continuous assignment.
Only combinational logic can be modeled using Continuous Assignment.

Assign values to nets

This assignments occurs whenever the value of the right-hand side changes.

Executes in parallel

Continuously active

Order independent

Syntax : assign assign_statement;


Continuous assignments provide a way of modeling combinational logic at a higher level of
abstraction than Gate-Level logic. It allows the use of Boolean logic rather than gate
connections.

The left-hand side of an assignment is a variable to which the right-side value is to be assigned
and must be a scalar or vector net or concatenation of both. The right-hand side of an
assignment, separated from the left-hand side by the equal (=) character, can be a net, a reg or
any expression that evaluates a value including function calls.

Continuous assignments drive values into the nets whenever the right-hand side value changes,
this means continuous assignments are always active and assignments occur whenever the right-
hand side operands changes. It drives both vector and scalar.

Continuous assignments can be used in two ways: as the net declaration statement and as the
continuous assignment statement.

In a continuous assignment statement, after the assign keyword (Example 1) the net is declared
as the left-hand side and after the equal (=) character, the right-hand side is declared as an
expression. The value of out changes whenever the values of operands In_1 or In_2 change.

Example 2 shows how to use continuous assignments with vectors. The left-hand side of an
assignment is a vector net, while the right-hand side operands are vector registers.

The left-hand side of an assignment can also be a concatenation of nets. Example 3 describes this
use.

Instead of the continuous assignment statement, the net declaration assignment can be used. This
means that in the net declaration statement we can assign expressions that occur whenever right-
hand side operands change. In this case, assign keyword is not used. Example 1can be described
as shown in Example 4. In this case a net can be declared only once, therefore only one net
declaration assignment can be made to a net.
An optional delay given to a continuous assignment specifies the time duration between the
right-hand side operand value change and the assignment to the left-hand side. Delay
specification can be used both in the continuous assignment statement and the net declaration
statement (see Example 5 and Example 6).

Also optional is strength specification. Example 7 shows a way to specify strength in a


continuous assignment. For more information about strength see the "Strength" chapter.

Examples

Example 1

wire out;
assign out = In_A & In_B ;

Continuous assignment 'out' is a net. Both In_1 and In_2 are nets.

Example 2

assign address[7:0] = address_1[7:0] ^ address_2[7:0] ;

Continuous assignment with range specification. Address_1 and address_2 are 8-bit vector
registers.

Example 3

assign {c_out, sum[7:0]} = Data_A[7:0]+Data_B[7:0]+c_in;

Continuous assignment with concatenation.

Example 4

wire out = In_A & In_B ;

The net declaration assignment. Equivalent to Example 1.


Example 5

assign #25 out = In_A & In_B ;

Delay specification in the continuous assignment statement.

Example 6

wire #25 out = In_A & In_B ;

Delay specification in the net declaration assignment.

Example 7

assign (strong1, pull0) out = Data_A | Data_B ;

Ex : wire x,y,z;

assign x=a&b;

assign y=a^b;

assign z=b||c;

Ex :

wire x,y,z;

assign z=b||c;

assigny=a^b;

assign x=a&b

Ex: wire c,a,b;


Assign #2 c=a&b; //RHS will be computed after 2

time Unit delay hen result will be

assigned to LHS

Ex : wire x,y,z;

Reg a,b,c;

assign x=a&b;

assignb=a^c; // wrong statement can not assign

values to regs.

Procedural Assignments :

Verilog behavioral code is inside procedure blocks, but there is an exception: some behavioral
code also exist outside procedure blocks. We can see this in detail as we make progress.

There are two types of procedural blocks in Verilog:

initial : initial blocks execute only once at time zero (start execution at time zero).
always : always blocks loop to execute over and over again; in other words, as the name
suggests, it executes always.

Update the value of variables under the control of the

procedural flow constructs that surround them.

Each procedure represent a separate activity flow in

Verilog ,all of which run in parallel.


Ex : begin

if(sel==0)

z=a;

else

z=b;

end

Initial Block:

Runs when simulation starts.

Terminates when control reaches the end.

Good for providing stimulus.

Execution stops when the last statement is executed.

Initial block may contain if conditions, loops, assignment statements etc., but not continuous
assignments. You can have any number of initial blocks in a module. All initial blocks execute
simultaneously.
Initial blocks are very useful in testbenches. Consider a code for counter. Actually in a
chip, initially counter will have a unpredicted value. But after sometimes, value will increase to
its maximum value, where all the bits are zero. Then it will start counting through 0 to maximum
value. But in the simulation, initially value will be 'x', and if we don't initialize, it will remain 'x'
only. So, we can use initial blocks to initialize all the signals to a valid value.

Syntax :

initial

begin

imperative statements

end

Ex : module tb_top();

reg a,b;

initial

begin

a=1b0;

b=1b0;

#10 a=1b1;

#10 b=1b1;

end
initial

#300 $finish;

endmodule

Ex : module tb_top();

reg a,b;

initial

begin

a=1b0;

b=1b0;

#10 a=1b1;

#10 b=1b1;

end

initial

#300 $finish;

Endmodule

Always Block :

Repeats continuously throughout the duration of the simulation.

Runs when simulation starts.


Restarts when control reaches the end.

Good for modeling / specifying hardware.

Syntex : always

begin

imperative statements

End

Always blocks execute always. We can use delay or sensitivity list to control the execution of
always block. Syntax is as follows:
always @ ( sencitivity_list )
statements;
Sensitivity list may contain signal names as follows:

always @ ( signal1 or signal2 )


statement;
Above statement will execute whenever signal1 or signal2 changes. we can have 1 to any
number of signals in sensitivity list.

always @ ( posedge signal )


statement;
Above statement executes at the positive edge of signal. Similarly we can use negedge for
negative edge of the signal.
Without sensitivity list, always block will look like this:
always
#5 clk = ~clk;
This will toggle the signal clk for every 5 nanoseconds.

Ex :
always

Begin

procedural statements and // loops continuously

Assignments

end

- If an always construct has no control for simulation time to advance , it will create a simulation
deadlock condition

Run until they encounter a delay.

initial begin

#10 a = 1; b = 0;

#10 a = 0; b = 1;

End

or a wait for an event

always @(posedge clk)

q = d;

always begin

wait(i);

a = 0;
wait(~i);

a = 1;

end

Event Control :

Event- a change in value on a register or net.

A negedge is detected on thetransition from 1 to

x,z, or 0, and from x or z to 0

A posedge is detected on the transition from 0 to

x,z, or 1, and from x or z to 1

In Verilog the @ character specifies an edge-sensitive event control that blocks until there is a
transition in value (an edge) for one of the identifiers in the event expression. Ive encountered a
misconception that edge events are queued and then serviced by @() guards, rather than
@() being a guard that waits on edge events, blocking until an edge event happens.

Ive needed to remind people more than once that the only edge events that matter to an @()
guard are those that happen while it is waiting. Edge events that happen before reaching the
guard are irrelevant to the guard.

For example,

@(a or b)
will block until there is a change in the value of a or b. posedge and negedge just mean to be
sensitive only to a posedge (0 to 1 transition) or negedge (1 to 0 transition).
For example,
@(posedge clk)
will block until clk transitions from 0 to 1.

A possible reason for the misunderstanding? In traditional Verilog synthesis, event expressions
with posedge/negedge qualifiers get more serious treatment than ones without.
For example, consider the following example

module test(input in, output reg previous_in);


reg temp;
always @(in) begin
previous_in = temp;
temp = in;
end
endmodule
An always procedure is an infinite loop. Usually, as here, its flow is punctuated by one or more
event controls. In this example, each time the input changes value, the infinite loop
resumes. Then previous_in is updated with the value of temp, which has saved the previous
value of in. Then temp is updated with the new value of in. And then the loop is again blocked
by the @(in) until the input changes again, and so on.
In traditional Verilog synthesis, however, this example yields the same netlist as the very
different

module test(input in, output reg previous_in);


reg temp;
always @(in) begin
previous_in = in;
end
endmodule

Ex :
always(@(triggering_signal)

begin

.. //Execution is triggered each

end time triggering_signal changes

Execution trigged on positive edge of the clock

always @(posedge clk)

begin

if(reset)

q<=1b0;

else

q<=d;

end

Execution trigged on

negative edge of the clock

always @(negedge clk)

begin

if(reset)

q<=1b0;
else

q<=d;

end

Sensitivity list:

Without sensitivity list ,the always block will loop continuously without waiting for a
triggering event.

always@(a or b or sel)

begin

if(sel==1)

z=a;

else

z=b;

end

always@(posedge clk or posedge reset)

begin

if(reset==1)

z<=1b0;

else
z<=a|c;

end

All net and Variable identifiers which appears in the statement will be automatically added to the
event expression

module ev_exp_check(a,b,c,d,f,y);

input [1:0]a,b,c,d,f;

output y;

reg[1:0] y;

always@(*) //equivalent to @(a or b or c or d or f)

y=(a &b)|(c & d)|f;

endmodule

Blocking and Non Blocking Assignments :

There are two types of assignment statements are there in

Verilog:

Blocking statements

Non-blocking statements.

Blocking Assignments :
Blocking assignment are represented with the sign=.

these are executed sequentially, i.e. one statement is executed then the next statement is
executed.

one statement blocks the execution of other statements until it is executed.

any delay attached is also got added to delay in execution of next statements.

module blk_assign(); // order is importent

reg a,b;

intial begin

a=1b0; //a initialized

b=1b1; //b initialized

c=b;

b=a;

$display(a=%b,b=%b,a,b);

end

end module

simulation results:

A=1, b=1
Non Blocking Assignments :

A non blocking assignment is represented with the sign<=

Its execution is concurrent with that of the following assignment or activity.

For all the non-blocking assignments in a block, the right- hand sides are evaluated first.

Subsequently the specified assignments are scheduled.

It is illegal to use a non-blocking assignment in a continuous ssignment statement or in a net


declaration

Resulted values are stored in temporary variables and assigned to all the outputs
Simultaneously, at the end of execution of the block.

initial

Begin

a=1b1;

b=1b0;

b<=#10a; //B is scheduled to get 1after 10 time units

c<=b; //C will get 0 at the end of first time step, as

end b is not Yet assigned zero

The order of the execution of distinct non blocking assignments to a given variable shall be
preserved
module check_nonblock();

reg i;

initial

i=1;

initial begin

i<=#5 1b0; //Schedules i=0 at time 5

i<=#5 1b1; //Schedules i=1 at time 5 Over rides

end previous Assignment of same time step

endmodule

Blocking Vs Non Blocking assignments :

Module blocking(D,clock,Q1,Q2);

input D,Clock;

output reg Q2;

reg Q1;

always@(pose edge Clock)

Begin

Q1=D;

Q2=Q1;

end

end module
Module non_black(D,Clock,Q1,Q2);

input D,Clock;

output reg Q1, Q2;

always@(posedge Clock)

Begin

Q1<=D;

Q2<=Q1;

end

end module

Looping Statements ;

If else Statements :

If-else statements check a condition to decide whether or not to execute a portion of code. If a
condition is satisfied, the code is executed. Else, it runs this other portion of code.
always@(.....) begin

assignment1;

if(condition)

begin//alternative1

assignment2;

end

else

begin //alternative 2

assignment3;

end

Assignment4;

End

if(hex == 1'b1)

data <= 4'b1101;

else

data <= 4'hd;

Multiway Braching :

always@(sel)
begin

if(sel[0]==0)

z=a;

else if(sel[2:1]==2b01)

z=b;

else if(sel[2:1]==2b10)

z=c;

else if(sel[2:1]==2b11)

z=d

else

z=a;

end

Case Statements :

Multi way decision statement that tests whether an expression matches one of a number of other
expression and branches accordingly

Syntax:

case(expression)

case_item1:statement1; //Possible values for

case_item2:statement 2; the case expression

.....

Default : default _ statement; //Optional default statement


endcase

Ex :

reg[0:3] a,b,c,z;

integer x;

always@(a,b,c,x)

case(x)

0:z=a;

1:z=b;

default :z=c; //Covers all

endcase otherPossible

values

Ex :

reg[0:3] a,b,c,z;

integer x;

always@(a,b,c,x)

case(x)

0,2:z=a; //Covers multiple

1,3:z=b; conditions

default :z=c;

endcase
For Loop :

Its execution is a 3 step process as follows

Initialize a variable that controls the number of loops executed.

Evaluates an expression if the result is zero, the loop exits, and if it is not zero, the for-loop
executes its associated statements(s) and then perform step c.

Executes an assignment, normally modifies the value of the loop control variable, then repeats
step b.

for (i = 0; i < 16; i = i +1) begin

$display ("Current value of i is %d", i);

end

This code will print the numbers from 0 to 15 in order. Be careful when using for loops for
register transfer logic (RTL) and make sure your code is actually sanely implementable in
hardware... and that your loop is not infinite.

While Loop :

Executes a statement until an expression becomes false.


If the expression starts out false , the statement does not executes at all.

//Example counts the number of logic 1 value in reg a

begin reg[7:0] tempreg;

count =0;

tempreg = rega;

while(tempreg) //While tempreg is not all 0

begin

if(tempreg[0]) //If 0th bit is 1,count is incremented

count = count+1;

tempreg = tempreg>>1; //tempreg is shifted Right by one

end place

end

Coding Guide Lines :

It is best to use blocking assignment when describing combinational circuits, so as to avoid


accidentally creating a sequential circuit.

always@(a,b,sel)

begin
if(sel)

y=b;

else

y=a;

end

Use non-blocking assignments when describing sequential circuits.

always@(posedge clk or posedge reset)

begin

if(reset)

q<=1b0;

else

q<=d;

end

When combining combinational and sequential code into a single always block, code the always
block as a sequential always block with non blocking assignments

Combinational and sequential logic in a single always block

module mix_blk_nblk(q,a,b,clk,rst);

output q;

input clk,rst,a,b;
reg q;

always@(posedge clk or posedge rst)

begin

if(!rst_n)

q<=1b0;

else

q<=a|b;

end

Combinational and sequential logic in two always blocks

module mix_blk_nblk(q,a,b,clk,rst);

output q;

input clk,rst,a,b;

reg q,y;

always@(a or b)

Y=a|b;

always@(posedge clk or posedge rst) begin

if(!rst_n)

q<=1b0;

else

q<=y;
end

S-ar putea să vă placă și