Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
dsd1-10 / dsd-07=Verilog / vlogmsg.pdf
Скачиваний:
79
Добавлен:
05.06.2015
Размер:
276.27 Кб
Скачать

Verilog-XL Modeling Style Guide

Modeling Your Hardware (Behavior-Level)

2.You can nest any combination of begin-end and fork-join blocks.

The if-else conditional within the fork-join block requires a begin-end block for the if statements. While you could define a block for the single else statement, a block is not required.

3.Timing specified within a fork-join block is relative to the time when Verilog-XL entered the block.

These three assignments execute concurrently. Therefore, the clr=1 statement executes at time 200, not 350.

4.End a parallel block with the join keyword.

Assigning Values to Registers (Procedural Assignments)

Update the values of registers (reg, time, integer) within procedural constructs with procedural assignments. You can specify either blocking assignments (=), which prevent execution of statements that follow the assignment in a sequential block until the assignment completes, or nonblocking assignments (<=), which do not stop the procedural flow in sequential blocks.

The followiong example shows both blocking and nonblocking procedural assignments to registers. “See Step n” comments in the example correspond to descriptive steps that follow the example.

Example: Assiging values to registers (procedural assigments)

module assignments_example; reg a,b,c,d,e,f;

initial begin

a = 1; // See Step 1 b = #2 0;

c = #4 1;

end

initial begin

d <= 1; // See Step 2 e <= #2 0;

f <= #4 1;

end

endmodule // assignments_example

1.Make blocking assignments with the equal-sign operator (=). Verilog-XL stops procedural

flow within the sequential block until a blocking assignment is complete.

January 2001

37

Product Version 3.2

Verilog-XL Modeling Style Guide

Modeling Your Hardware (Behavior-Level)

When you use intra-assignment timing control (#, @, or wait after the assignment operator), Verilog-XL evaluates the right-hand side immediately after encountering the statement and then waits for the specified delay or event before completing the assignment. See Specifying Intra-Assignment Timing Controls for more information.

Because blocking assignments are used here, this block does not finish until time 6

(2+4).

2.Make nonblocking assignments with the less-than-or-equal operator (<=). Verilog-XL does not stop procedural flow within the sequential block for a nonblocking assignment. Because nonblocking assignments are used here, this block finishes at time 4.

Specifying Intra-Assignment Timing Controls

You can force Verilog-XL to evaluate the right-hand side of a procedural assignment immediately but wait for the assignment to take place until some specified delay or event by specifying intra-assignment timing controls (#, @). Using intra-assignment timing controls eliminates the need for temporary variables when you perform operations such as data swap and data shift.

The following example shows two code fragments. The first example shows an intraassignment delay. The second example shows how you can model a master-slave flip-flop with intra-assignment event control. “See Step n” comments in the example correspond to descriptive steps that follow the example.

Example: Specifying intra-assignment timing controls

module intra_assignment_example;

 

wire a,

in;

 

reg b, out;

 

...

 

 

initial

 

// See Step 1

b =

#10 a;

always @(posedge clk)

// See Step 2

out

= @(negedge clk) in;

...

 

 

endmodule

// intra_assignment_example

1.To specify an intra-assignment delay, place a delay specification (#) after the assignment operator (=).

Verilog-XL evaluates a immediately upon encountering this statement, but Verilog-XL does not make the assignment until 10 time units later.

2.To specify an intra-assignment event control, place an event control operator (@) after the assignment operator (=).

January 2001

38

Product Version 3.2

Verilog-XL Modeling Style Guide

Modeling Your Hardware (Behavior-Level)

This example models a master-slave flip-flop. On every positive edge of the clock,

Verilog-XL evaluates in, but does not assign that value to out until the negative edge of the clock.

Defining Conditionals ( if-else)

You can have Verilog-XL execute a different section of source code based on the value of an expression using the if-else conditional statement. When you want to select one of two values for an assignment, it is more efficient to use the conditional operator (?:). When you need more control than the true/false branching provided by if-else, use a case statement.

The following example shows how an if-else statement lets you execute a different section of source code based on the value of an expression. “See Step n” comments in the example correspond to descriptive steps that follow the example. The if and else constructs are illustrated in this example.

Example: Defining conditionals (if-else)

module

dff(q,qb,clk,d,clear)

 

input clk,

d, clear

 

output

q, qb;

 

reg q,

qb;

 

 

always

@(posedge clk)

 

begin

 

 

// See Step 1

if

(clear)

begin

 

// See Step 2

 

#8

q = d;

 

 

#1

qb = ~q;

 

end //

end if

// See Step 3

else

 

 

$display("Clear is enabled");

// See Step 4

end //

end

if-else

 

...

 

 

 

endmodule // dff

 

1.Begin an if conditional with the if keyword followed by an expression. If Verilog-XL evaluates the expression as true (nonzero), Verilog-XL executes the statements that follow the if expression. If the expression is false (0, X, or Z), Verilog-XL executes the statements following the else keyword (if present).

This if expression tests the value of clear. If clear is true (clear is asserted low), Verilog executes the if statements.

2.Follow the if expression with the statement or block of statements (begin-end or fork-join) you want Verilog-XL to execute when the expression is true.

3.You can optionally use the else keyword to introduce statements that Verilog-XL executes when your if expression evaluates to false.

January 2001

39

Product Version 3.2

Verilog-XL Modeling Style Guide

Modeling Your Hardware (Behavior-Level)

4.Follow the else keyword with the statement or block of statements (begin-end or fork-join) you want Verilog-XL to execute when the expression is false.

Defining Conditionals ( ?:)

You can have Verilog-XL evaluate one of two expressions based on the value of a third with the conditional operator (?:). The conditional operator is particularly useful for conditionally assigning a value to a register or net and is legal for gate-level modeling (if-else and case are not). While you could use an if-else statement to conditionally assign values, the conditional operator (?:) is more efficient.

The following example shows how you use the conditional operator (?:) to conditionally assign values to a register. “See Step n” comments in the example correspond to descriptive steps that follow the example. The ?: (conditional operator) construct is illustrated in this example.

Example: Defining conditionals (?:)

module alu (alu_out, zero, opcode, data, accum, clock); input [7:0] data, accum;

input [2:0] opcode; input clock;

output [7:0] alu_out; output zero;

reg [7:0] alu_out; reg zero;

...

always @(alu_out)

zero = alu_out ? 0 : 1; // See Step 1

...

endmodule // alu

1.Use the conditional operator (?:) to create a conditional assignment. The conditional operator takes three operands. If Verilog-XL evaluates the first operand as true, then Verilog-XL evaluates the second operand. If the first operand is false, then Verilog-XL evaluates the third operand.

Verilog-XL updates the zero register every time alu_out transitions. If the value of alu_out is 1, then Verilog-XL sets zero to 0. Otherwise, zero is 1.

While you can use this functionally equivalent if-else statement, the conditional operator (?:) is more efficient:

if (alu_out) zero = 0

else

zero = 1;

January 2001

40

Product Version 3.2

Verilog-XL Modeling Style Guide

Modeling Your Hardware (Behavior-Level)

Defining Conditionals ( case)

You can have Verilog-XL execute a different section of source code based on the value of an expression using the case conditional statement. Case statements let you compare specific values to your case expression, unlike

if-else statements, which allow only true/false branching.

The example shows how a case statement lets you branch to any number of statements based on the value of an expression.

“See Step n” comments in the example correspond to descriptive steps that follow the example.

Example: Defining Conditionals (case)

task decode;

 

 

 

input [2:0]

instruction;

 

input [3:0]

a, b;

 

 

output [15:0] out;

 

case(instruction)

 

// See Step 1

3’b000: out =

a + b;

// See Step 2

3’b001: out =

a - b;

 

3’b010: out =

a * b;

 

3’b011: out =

a / b;

 

3’b100: out =

a << b;

 

3’b101,

 

 

 

3’b110: out =

a >> b;

// See Step 3

default:

begin

 

 

$display("Unknown instruction");

 

end

out = 16’bx;

 

endcase

 

// See Step 4

 

 

endtask // decode

 

 

1.Begin the case conditional with the case keyword followed by an expression. Verilog-XL evaluates this expression and compares it to each case value you specify.

Verilog-XL executes statements based on the value of instruction.

2.Follow the case expression with any number of case items. A case item is a value, followed by a colon, followed by a single statement or block of statements.

These case items are 3-bit binary values, each representing a different opcode for an ALU. When a case item value matches the case expression, Verilog-XL executes the associated statements.

3.You can optionally specify a default case item with the default keyword. Verilog-XL executes the statements associated with the default item when no other case item matches the case expression.

January 2001

41

Product Version 3.2

Verilog-XL Modeling Style Guide

Modeling Your Hardware (Behavior-Level)

This default item causes Verilog-XL to display a message and assign X to all bits of the output.

4. End the case statement with the endcase keyword.

Defining Loops

You can execute statements multiple times with looping constructs. Verilog HDL provides four looping mechanisms: forever (continuous execution), repeat (execute a fixed number of times), while (repeat until an expression becomes false), and for (a cross between repeat and while). Because forever loops are infinite, use them with timing controls.

The following example shows three different implementations (repeat, while, and for loops) of a function that returns the number of 1 bits in an 8-bit register. “See Step n” comments in the example correspond to descriptive steps that follow the example.

Example: Defining loops

// ***REPEAT LOOP*** function integer count_ones; input [7:0] source_reg; begin

count_ones = 0;

repeat (8) // See Step 1 begin if (source_reg[0])

count_ones = count_ones + 1; source_reg = source_reg >> 1;

end // repeat loop

end

endfunction // count_ones repeat loop

// ***WHILE LOOP*** function integer count_ones; input [7:0] source_reg; begin

count_ones = 0;

while (source_reg) // See Step 2 begin if (source_reg[0])

count_ones = count_ones + 1; source_reg = source_reg >> 1;

end // while loop

end

endfunction // count_ones while loop

// ***FOR LOOP***

function integer count_ones; input [7:0] source_reg; integer i;

begin

count_ones = 0;

for (i=0; i < 8; i=i+1) // See Step 3 if (source_reg[i])

count_ones = count_ones + 1;

January 2001

42

Product Version 3.2

Verilog-XL Modeling Style Guide

Modeling Your Hardware (Behavior-Level)

end // for loop

endfunction // count_ones for loop

1.Begin a repeat loop with the repeat keyword and specify an expression that evaluates to the number of times you want to perform the loop.

In this example, Verilog-XL executes the loop 8 times, which is the size of the register whose 1 bits you are counting.

2.Begin a while loop with the while keyword. Following the keyword is an expression that controls the number of loop iterations. Verilog-XL evaluates the expression before each pass through the loop. When the expression becomes false, the loop ends.

In this example, the loop continues until source_reg is 0 (no 1 bits). Because the loop does not necessarily check all 8 bits, this while loop is more efficient than the previous repeat loop.

3.Begin a for loop with the for keyword. Following the keyword is a three-part expression: initial assignment, condition, and step assignment. The initial assignment initializes the counter variable. The condition is an expression that Verilog-XL evaluates on every iteration of the loop. The loop continues until the expression is false. The step assignment increments (or decrements) the counter variable.

In this example, the counter starts at 0 and is incremented at every iteration, ending when the counter is no longer less than 8. The counter is used to index into source_reg, eliminating the need to shift the register as in the previous examples.

Defining and Calling Functions

You can define procedures, called functions, that calculate and return a value (like a software function call). Functions must execute in zero time (have no delays), and must have at least one input argument. When you want to define a more general procedure that does not have the limitations imposed by functions, define a task instead of a function.

The following example shows the definition of and a call to a function that counts the number of 1 bits in an 8-bit register. “See Step n” comments in the example correspond to descriptive steps that follow the example.

Example: Defining and calling functions

module print_count; reg [7:0] areg;

// FUNCTION DEFINITION

// See Step 1

function integer

count_ones;

input [7:0] source_reg;

// See Step 2

begin

 

//

See

Step

3

count_ones =

0;

//

See

Step

4

January 2001

43

Product Version 3.2

Verilog-XL Modeling Style Guide

Modeling Your Hardware (Behavior-Level)

repeat

(8)

 

begin

 

 

if

(source_reg[0])

 

 

count_ones = count_ones + 1;

 

source_reg = source_reg >> 1;

 

end //

repeat loop

 

end

 

See Step 5

endfunction

// count_one function

initial begin

areg = 8’b01101101;

$display (“There are %0d ones in %b”, count_ones(areg), areg); // See Step 6

end

endmodule // print_count

1.Begin a function with the function keyword. Optionally specify the return value type or a range (default is a 1-bit register) and give the function a name. Verilog-XL automatically defines a local variable of the type specified with the same name as the function. This function is called count_ones and returns an integer. It counts the number of 1 bits in an 8-bit register.

2.Specify the input argument or arguments to the function using the input keyword (output and inout declarations are not legal). The count_ones function takes a single input argument.

3.If the function body contains more than one statement, define a block with begin-end

(or fork-join).

4.You assign values to the return value variable as you would any variable. The return value variable is count_ones, which Verilog-XL increments for every 1 bit in source_reg.

5.End a function definition with the endfunction keyword.

6.Call a function by specifying the name of the function, followed by the function input arguments (surrounded by parentheses and separated by commas). Use a function call in any expression where the type of the function return value is legal. This function call operates on the input argument areg, and returns an integer—the number of 1 bits in areg. The return value is an argument to the $display system task.

Defining and Enabling Tasks

You can define procedures, called tasks, that let you execute the same code from many different places in your description. Use tasks also to break up large procedures into smaller ones. Tasks are similar to software subroutines. Unlike functions, tasks can return more than one value and can contain timing controls. You can disable tasks just as you disable named blocks.

January 2001

44

Product Version 3.2

Verilog-XL Modeling Style Guide

Modeling Your Hardware (Behavior-Level)

The following example shows the definition of and a call to a task that performs a multiplication operation on two 16-bit registers. “See Step n” comments in the example correspond to descriptive steps that follow the example.

Example: Defining and enabling tasks

module alu;

 

reg[2:0] instruction;

 

reg[15:0] in1, in2;

 

reg[31:0] out;

 

// TASK DEFINITION

// See Step 1

task multiply;

input [15:0] a, b;

// See Step 2

output[31:0] product;

// See Step 3

begin

#10 product = 0;

// See Step 4

repeat (16)

 

begin

 

if (a[0])

 

product = product + {b,16’h0000};

 

product = product >> 1;

 

a = a >> 1;

 

end // repeat

 

end

// multiply See Step 5

endtask

endmodule // alu

 

...

 

case(instruction)

 

3’b000:out = in1 + in2;

// See Step 6

3’b001: multiply (in1, in2, out);

...

 

endmodule

 

1.Begin a task with the task keyword and specify a task name. This task is called multiply and returns the product of two values.

2.Specify the input, output, and inout arguments for the task. The multiply task has two inputs (the multiplicand, a, and multiplier, b) and one output (product).

3.If the task body contains more than one statement, define a block with begin-end or fork-join.

4.Unlike functions, tasks can have timing control. The task does not complete until 10 simulation time units from when you enable the task.

5.End a task definition with the endtask keyword.

6.Begin execution of a task (enable the task) by specifying the task name followed by the task input, output, and inout arguments (if any) surrounded by parentheses and separated by commas. You cannot enable a task as part of an expression. This task enable operates on the input arguments in1 and in2, and returns the product through the out argument.

January 2001

45

Product Version 3.2

Соседние файлы в папке dsd-07=Verilog