Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
115
Добавлен:
26.03.2016
Размер:
7.4 Mб
Скачать

11.7 Tasks and Functions

A task [Verilog LRM 10.2] is a type of procedure, called from another procedure. A task has both inputs and outputs but does not return a value. A task may call other tasks and functions. A function [Verilog LRM 10.3] is a procedure used in any expression, has at least one input, no outputs, and returns a single value. A function may not call a task. In Section 11.5 we covered all of the different Verilog procedures except for tasks and functions. Now that we have covered timing controls, we can explain the difference between tasks and functions: Tasks may contain timing controls but functions may not. The following two statements help illustrate the difference between a function and a task:

Call_A_Task_And_Wait (Input1, Input2, Output);

Result_Immediate = Call_A_Function (All_Inputs);

Functions are useful to model combinational logic (rather like a subroutine):

module F_subset_decode; reg [2:0]A, B, C, D, E, F; initial begin A = 1; B = 0; D = 2; E = 3;

C = subset_decode(A, B); F = subset_decode(D,E); $display("A B C D E F"); $display(A,,B,,C,,D,,E,,F); end

function [2:0] subset_decode; input [2:0] a, b;

begin if (a <= b) subset_decode = a; else subset_decode = b; end endfunction

endmodule

A B C D E F 1 0 0 2 3 2

11.8 Control Statements

In this section we shall discuss the Verilog if , case , loop , disable , fork , and join statements that control the flow of code execution.

11.8.1 Case and If Statement

An if statement [Verilog LRM 9.4] represents a two-way branch. In the following example, switch has to be true to execute 'Y = 1' ; otherwise 'Y = 0' is executed:

if(switch) Y = 1; else Y = 0;

The case statement [Verilog LRM 9.5] represents a multiway branch. A controlling expression is matched with case expressions in each of the case items (or arms) to determine a match,

module test_mux; reg a, b, select; wire out; mux mux_1(a, b, out, select);

initial begin #2; select = 0; a = 0; b = 1;

#2; select = 1'bx; #2; select = 1'bz; #2; select = 1; end initial $monitor("T=%2g",$time," Select=",select," Out=",out); initial #10 $finish;

endmodule

module mux(a, b, mux_output, mux_select); input a, b, mux_select; output mux_output; reg mux_output;

always begin case(mux_select)

0:mux_output = a;

1:mux_output = b;

default mux_output = 1'bx; // If select = x or z set output to x. endcase

#1; // Need some delay, otherwise we'll spin forever. end

endmodule

T= 0 Select=x Out=x

T= 2 Select=0 Out=x

T= 3 Select=0 Out=0

T= 4 Select=x Out=0

T= 5 Select=x Out=x

T= 6 Select=z Out=x

T= 8 Select=1 Out=x

T= 9 Select=1 Out=1

Notice that the case statement must be inside a sequential block (inside an always statement). Because the case statement is inside an always statement, it needs some delay; otherwise the simulation runs forever without advancing simulation time. The casex statement handles both 'z' and 'x' as don't care (so that they match any bit value), the casez statement handles 'z' bits, and only 'z' bits, as don't care. Bits in case expressions may be set to '?' representing don't care values, as follows:

casex (instruction_register[31:29]) 3b'??1 : add;

3b'?1? : subtract; 3b'1?? : branch;

endcase

11.8.2 Loop Statement

A loop statement [Verilog LRM 9.6] is a for, while, repeat, or forever statement. Here are four examples, one for each different type of loop statement, each of which performs the same function. The comments with each type of loop statement

illustrate how the controls work:

module loop_1;

integer i; reg [31:0] DataBus; initial DataBus = 0; initial begin

/************** Insert loop code after here. ******************/

/* for(Execute this assignment once before starting loop; exit loop if this expression is false; execute this assignment at end of loop before the check for end of loop.) */

for(i = 0; i <= 15; i = i+1) DataBus[i] = 1;

/*************** Insert loop code before here. ****************/

end

initial begin

$display("DataBus = %b",DataBus);

#2; $display("DataBus = %b",DataBus); $finish; end

endmodule

Here is the while statement code (to replace line 4 in module loop_1 ):

i = 0;

/* while(Execute next statement while this expression is true.) */ while(i <= 15) begin DataBus[i] = 1; i = i+1; end

Here is the repeat statement code (to replace line 4 in module loop_1 ):

i = 0;

/* repeat(Execute next statement the number of times corresponding to the evaluation of this expression at the beginning of the loop.) */

repeat(16) begin DataBus[i] = 1; i = i+1; end

Here is the forever statement code (to replace line 4 in module loop_1 ):

i = 0;

/* A forever statement loops continuously. */ forever begin : my_loop

DataBus[i] = 1;

if (i == 15) #1 disable my_loop; // Need to let time advance to exit. i = i+1;

end

The output for all four forms of looping statement is the same:

DataBus = 00000000000000000000000000000000

DataBus = 00000000000000001111111111111111

11.8.3 Disable

The disable statement [Verilog LRM 11] stops the execution of a labeled sequential block and skips to the end of the block:

forever

begin: microprocessor_block // Labeled sequential block. @(posedge clock)

if (reset) disable microprocessor_block; // Skip to end of block. else Execute_code;

end

Use the disable statement with caution in ASIC design. It is difficult to implement directly in hardware.

11.8.4 Fork and Join

The fork statement and join statement [Verilog LRM 9.8.2] allows the execution of two or more parallel threads in a parallel block:

module fork_1

event eat_breakfast, read_paper; initial begin

fork

@eat_breakfast; @read_paper; join

end endmodule

This is another Verilog language feature that should be used with care in ASIC design, because it is difficult to implement in hardware.

Соседние файлы в папке Для магистратуры