|
11.5 Procedures and Assignments
Chapter start
Previous page
Next page
11.5 Procedures and Assignments
A Verilog procedure
[Verilog LRM 9.9] is an always or initial
statement, a task , or a function . The statements
within a sequential block (statements that appear between a begin
and an end ) that is part of a procedure execute sequentially
in the order in which they appear, but the procedure executes concurrently
with other procedures. This is a fundamental difference from computer programming
languages. Think of each procedure as a microprocessor running on its own
and at the same time as all the other microprocessors (procedures). Before
I discuss procedures in more detail, I shall discuss the two different types
of assignment statements:
- continuous assignments that appear outside
procedures
- procedural assignments that appear inside
procedures
To illustrate the difference
between these two types of assignments, consider again the example used
in Section 11.4:
module holiday_1(sat, sun, weekend);
input sat, sun; output weekend;
assign weekend = sat | sun; // Assignment outside a procedure.
endmodule
We can change weekend to a
reg instead of a wire , but then we must declare weekend
and use a procedural assignment (inside a procedure--an always
statement, for example) instead of a continuous assignment. We also need
to add some delay (one time tick in the example that follows); otherwise
the computer will never be able to get out of the always procedure
to execute any other procedures:
module holiday_2(sat, sun, weekend);
input sat, sun; output weekend; reg weekend;
always #1 weekend = sat | sun; // Assignment inside a procedure.
endmodule
We shall cover the continuous
assignment statement in the next section, which is followed by an explanation
of sequential blocks and procedural assignment statements. Here is some
skeleton code that illustrates where we may use these assignment statements:
module assignments
//... Continuous assignments go here.
always // beginning of a procedure
begin // beginning of sequential block
//... Procedural assignments go here.
end
endmodule
Table 11.4
at the end of Section 11.6 summarizes
assignment statements, including two more forms of assignment--you may want
to look at this table now.
11.5.1 Continuous Assignment
Statement
A continuous assignment
statement [Verilog LRM 6.1] assigns a value to a wire in
a similar way that a real logic gate drives a real wire,
module assignment_1();
wire pwr_good, pwr_on, pwr_stable; reg Ok, Fire;
assign pwr_stable = Ok & (!Fire);
assign pwr_on = 1;
assign pwr_good = pwr_on & pwr_stable;
initial begin Ok = 0; Fire = 0; #1 Ok = 1; #5 Fire = 1; end
initial begin ("TIME=%0d",," ON=",pwr_on, " STABLE=",
pwr_stable," OK=",Ok," FIRE=",Fire," GOOD=",pwr_good);
#10 ; end
endmodule
TIME=0 ON=1 STABLE=0 OK=0 FIRE=0 GOOD=0
TIME=1 ON=1 STABLE=1 OK=1 FIRE=0 GOOD=1
TIME=6 ON=1 STABLE=0 OK=1 FIRE=1 GOOD=0
The assignment statement in
this next example models a three-state bus:
module assignment_2; reg Enable; wire [31:0] Data;
/* The following single statement is equivalent to a declaration and continuous assignment. */
wire [31:0] DataBus = Enable ? Data : 32'bz;
assign Data = 32'b10101101101011101111000010100001;
initial begin
("Enable=%b DataBus=%b ", Enable, DataBus);
Enable = 0; #1; Enable = 1; #1; end
endmodule
Enable = 0 DataBus =zzzzzzzzzzzzzzzzzzzzzzzzzzzzzzzz
Enable = 1 DataBus =10101101101011101111000010100001
11.5.2 Sequential Block
A sequential block
[Verilog LRM 9.8] is a group of statements between a begin and
an end. We may declare new variables within a sequential block, but
then we must name the block. A sequential block is considered a statement,
so that we may nest sequential blocks.
A sequential block may appear
in an always statement [Verilog LRM9.9.2], in which case the block
executes repeatedly. In contrast, an initial statement [Verilog LRM9.9.1]
executes only once, so a sequential block within an initial
statement only executes once--at the beginning of a simulation. It does
not matter where the initial statement appears--it still executes
first. Here is an example:
module always_1; reg Y, Clk;
always // Statements in an always statement execute repeatedly:
begin: my_block // Start of sequential block.
@(posedge Clk) #5 Y = 1; // At +ve edge set Y=1,
@(posedge Clk) #5 Y = 0; // at the NEXT +ve edge set Y=0.
end // End of sequential block.
always #10 Clk = ~ Clk; // We need a clock.
initial Y = 0; // These initial statements execute
initial Clk = 0; // only once, but first.
initial ("T=%2g",," Clk=",Clk," Y=",Y);
initial #70 ;
endmodule
T= 0 Clk=0 Y=0
T=10 Clk=1 Y=0
T=15 Clk=1 Y=1
T=20 Clk=0 Y=1
T=30 Clk=1 Y=1
T=35 Clk=1 Y=0
T=40 Clk=0 Y=0
T=50 Clk=1 Y=0
T=55 Clk=1 Y=1
T=60 Clk=0 Y=1
11.5.3 Procedural Assignments
A procedural assignment
[Verilog LRM 9.2] is similar to an assignment statement in a computer
programming language such as C. In Verilog the value of an expression on
the RHS of an assignment within a procedure (a procedural assignment) updates
a reg (or memory element) on the LHS. In the absence of any
timing controls (see Section 11.6),
the reg is updated immediately when the statement executes.
The reg holds its value until changed by another procedural
assignment. Here is the BNF definition:
blocking_assignment ::= reg-lvalue = [delay_or_event_control] expression
(Notice this BNF definition
is for a blocking assignment--a type of procedural assignment--see Section 11.6.4.) Here is an example of
a procedural assignment (notice that a wire can only appear
on the RHS of a procedural assignment):
module procedural_assign; reg Y, A;
always @(A)
Y = A; // Procedural assignment.
initial begin A=0; #5; A=1; #5; A=0; #5; ; end
initial ("T=%2g",,,"A=",A,,,"Y=",Y);
endmodule
T= 0 A=0 Y=0
T= 5 A=1 Y=1
T=10 A=0 Y=0
Chapter start
Previous page
Next page
|