ShareCG: ASICs .. the Book
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.

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.

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.

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 

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 
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 ;
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);
T= 0 A=0  Y=0
T= 5 A=1  Y=1
T=10 A=0  Y=0

Chapter start

Previous page

Next page

© 2020 Internet Business Systems, Inc.
25 North 14th Steet, Suite 710, San Jose, CA 95112
+1 (408) 882-6554 — Contact Us
ShareCG™ is a trademark of Internet Business Systems, Inc.

Report a Bug Report Abuse Make a Suggestion About Privacy Policy Contact Us User Agreement Advertise