You are on page 1of 6

module simple_task();

task convert;
input [7:0] temp_in;
output [7:0] temp_out;
begin
temp_out = (9/5) *( temp_in + 32)
end
endtask
endmodule
module task_calling (temp_a, temp_b, temp_c, temp_d);
input [7:0] temp_a, temp_c;
output [7:0] temp_b, temp_d;
reg [7:0] temp_b, temp_d;
`include "mytask.v"
always @ (temp_a)
begin
convert (temp_a, temp_b);
end
always @ (temp_c)
begin
convert (temp_c, temp_d);
end
endmodule
Functions
Functions are declared within a module, and can be called from continuous assignments, always
blocks or other functions. In a continuous assignment, they are evaluated when any of its
declared inputs change. In a procedure, they are evaluated when invoked.
Functions describe combinational logic, and by do not generate latches. Thus an if without an
else will simulate as though it had a latch but synthesize without one. This is a particularly bad
case of synthesis not following the simulation. It is a good idea to code functions so they would
not generate latches if the code were used in a procedure.
Functions are a good way to reuse procedural code, since modules cannot be invoked from a
procedure.
Function Declaration
A function declaration specifies the name of the function, the width of the function return value,
the function input arguments, the variables (reg) used within the function, and the function local
parameters and integers.

Syntax, Function Declaration


function [msb:lsb]
function_name;
input [msb:lsb]
input_arguments;
reg [msb:lsb] reg_variable_list;
parameter [msb:lsb]
parameter_list;
integer [msb:lsb] integer_list;
... statements ...
endfunction

Function Return Value


When you declare a function, a variable is also implicitly declared with the same name as the
function name, and with the width specified for the function name (The default width is 1-bit).
This variable is my_func . At least one statement in the function must assign the function
return value to this variable.
Function Call
A function call is an operand in an expression. A function call must specify in its terminal list all
the input parameters.
Function Rules
The following are some of the general rules for functions:
- Functions must contain at least one input argument.
- Functions cannot contain an inout or output declaration.
- Functions cannot contain time controlled statements (#, @, wait).
- Functions cannot enable tasks.
- Functions must contain a statement that assigns the return value to the implicit function name
register.
Function Example
A Function has only one output. If more than one return value is required, the outputs should be
concatenated into one vector before assigning it to the function name. The calling module
program can then extract (unbundle) the individual outputs from the concatenated form. Example
11.2 shows how this is done, and also illustrates the general use and syntax of functions in
Verilog modeling.
Syntax
function_name = expression
The following rules distinguish tasks from functions:
A function must execute in one simulation time unit; a task can contain time-controlling
statements.
A function cannot enable a task; a task can enable other tasks and functions.
A function must have at least one input argument; a task can have zero or more arguments of
any type.
A function returns a single value; a task does not return a value.
The purpose of a function is to respond to an input value by returning a
single value. A task can support multiple goals and can calculate multiple result values.

module fsm_full(
clock , // Clock
reset , // Active high reset
req_0 , // Active high request from agent 0
req_1 , // Active high request from agent 1
req_2 , // Active high request from agent 2
req_3 , // Active high request from agent 3
gnt_0 , // Active high grant to agent 0
gnt_1 , // Active high grant to agent 1
gnt_2 , // Active high grant to agent 2
gnt_3 // Active high grant to agent 3
);
// Port declaration here
input clock ; // Clock
input reset ; // Active high reset
input req_0 ; // Active high request from agent 0
input req_1 ; // Active high request from agent 1
input req_2 ; // Active high request from agent 2
input req_3 ; // Active high request from agent 3
output gnt_0 ; // Active high grant to agent 0
output gnt_1 ; // Active high grant to agent 1
output gnt_2 ; // Active high grant to agent 2
output gnt_3 ; // Active high grant to agent
// Internal Variables
reg gnt_0 ; // Active high grant to agent 0
reg gnt_1 ; // Active high grant to agent 1
reg gnt_2 ; // Active high grant to agent 2
reg gnt_3 ; // Active high grant to agent
parameter
parameter
parameter
parameter
parameter

[2:0]
[2:0]
[2:0]
[2:0]
[2:0]

IDLE = 3'b000;
GNT0 = 3'b001;
GNT1 = 3'b010;
GNT2 = 3'b011;
GNT3 = 3'b100;

reg [2:0] state, next_state;

always @ (state or req_0 or req_1 or req_2 or req_3)


begin
next_state = 0;
case(state)
IDLE : if (req_0 == 1'b1) begin
next_state = GNT0;
end else if (req_1 == 1'b1) begin
next_state= GNT1;
end else if (req_2 == 1'b1) begin
next_state= GNT2;
end else if (req_3 == 1'b1) begin
next_state= GNT3;
end else begin
next_state = IDLE;
end
GNT0 : if (req_0 == 1'b0) begin
next_state = IDLE;
end else begin
next_state = GNT0;
end
GNT1 : if (req_1 == 1'b0) begin
next_state = IDLE;
end else begin
next_state = GNT1;
end
GNT2 : if (req_2 == 1'b0) begin
next_state = IDLE;
end else begin
next_state = GNT2;
end
GNT3 : if (req_3 == 1'b0) begin
next_state = IDLE;
end else begin
next_state = GNT3;
end
default : next_state = IDLE;
endcase
end
always @ (posedge clock)
begin : OUTPUT_LOGIC
if (reset) begin
gnt_0 <= #1 1'b0;
gnt_1 <= #1 1'b0;
gnt_2 <= #1 1'b0;
gnt_3 <= #1 1'b0;
state <= #1 IDLE;
end else begin
state <= #1 next_state;
case(state)

IDLE : begin
gnt_0 <= #1 1'b0;
gnt_1 <= #1 1'b0;
gnt_2 <= #1 1'b0;
gnt_3 <= #1 1'b0;
end
GNT0 : begin
gnt_0 <= #1 1'b1;
end
GNT1 : begin
gnt_1 <= #1 1'b1;
end
GNT2 : begin
gnt_2 <= #1 1'b1;
end
GNT3 : begin
gnt_3 <= #1 1'b1;
end
default : begin
state <= #1 IDLE;
end
endcase
end
end
endmodule
TEST BENCH
`include "fsm_full.v"
module fsm_full_tb();
reg clock , reset ;
reg req_0 , req_1 , req_2 , req_3;
wire gnt_0 , gnt_1 , gnt_2 , gnt_3 ;
initial begin
$display("Time\t R0 R1 R2 R3 G0 G1 G2 G3");
$monitor("%g\t %b %b %b %b %b %b %b %b",
$time, req_0, req_1, req_2, req_3, gnt_0, gnt_1, gnt_2, gnt_3);
clock = 0;
reset = 0;
req_0 = 0;
req_1 = 0;
req_2 = 0;
req_3 = 0;
#10 reset = 1;
#10 reset = 0;
#10 req_0 = 1;
#20 req_0 = 0;
#10 req_1 = 1;
#20 req_1 = 0;

#10 req_2 = 1;
#20 req_2 = 0;
#10 req_3 = 1;
#20 req_3 = 0;
#10 $finish;
end
always
#2 clock = ~clock;
fsm_full U_fsm_full(
clock , // Clock
reset , // Active high reset
req_0 , // Active high request from agent 0
req_1 , // Active high request from agent 1
req_2 , // Active high request from agent 2
req_3 , // Active high request from agent 3
gnt_0 , // Active high grant to agent 0
gnt_1 , // Active high grant to agent 1
gnt_2 , // Active high grant to agent 2
gnt_3 // Active high grant to agent 3
);

endmodule

You might also like