Verilog HDL
2007/07/02 14:32
http://blog.naver.com/PostPrint.nhn?blogId=babojay&logNo=40039354008#
Chapter 8.
Tasks and Functions
- CodingÀ» ÇÏ´Ùº¸¸é °°Àº ±â´ÉÀ» ÇÏ´Â ºí·°À» ¿©·¯¹ø ÀÛ¼ºÇØÁÖ¾î¾ß ÇÏ´Â °æ¿ìµéÀÌ ¹ß»ýÇÑ´Ù. C programming¿¡¼´Â ±×·¡¼ Macro¿Í FunctionÀÌ »ý°Ü³µ°í, FORTRAN¿¡¼´Â Subroutine°ú FunctionÀÌ ÀÖ´Ù. Verilog¿¡¼µµ ºñ½ÁÇÑ ±â´ÉÀ» ÇÏ´Â °ÍÀÌ ÀÖÀ¸´Ï, ±×°ÍÀÌ ¹Ù·Î task¿Í functionÀÌ´Ù.
*Objectives
- Task¿Í functionÀÇ Â÷À̸¦ ¼³¸íÇÑ´Ù.
-
Task¸¦ Á¤ÀÇÇϱâ À§ÇØ ÇÊ¿äÇÑ Á¶°ÇÀ» ¾Ë°í ¼±¾ð°ú È£ÃâÀ» ÀÌÇØÇÑ´Ù.
- FunctionÀ» Á¤ÀÇÇϱâ À§ÇØ ÇÊ¿äÇÑ Á¶°ÇÀ» ¾Ë°í
¼±¾ð°ú È£ÃâÀ» ÀÌÇØÇÑ´Ù.
8.1 Differences between Tasks and Functions
Ç¥ 8.1 Tasks and Functions
8.2 Tasks
- task, endtask
: task ¼±¾ðÇÏ´Â keyword
- ´ÙÀ½¿¡ ¿°ÅÇÑ Á¶°Çµé Áß¿¡¼ Àû¾îµµ Çϳª¶óµµ ¸¸Á·ÇÑ´Ù¸é task¸¦ »ç¿ëÇؾß
ÇÑ´Ù.
* Delay, timing, event Á¦¾î±¸Á¶°¡ ÀÖ´Ù
* outputÀÌ ¾ø°Å³ª ÇϳªÀÌ»óÀÇ outputÀÌ Àִ°æ¿ì
* inputÀÌ ¾ø´Â °æ¿ì
8.2.1 Task Declaration and Invocation
Syntax]
// Task
Declaration
<task>
::= task
<name_of_task>;
<tf_declaration>*
<statement_or_null>
endtask
<name_of_task>
::=<IDENTIFIER>
<tf_declaration>
::=<parameter_declaration>
||=<input_declaration>
||=<output_declaration>
||=<inout_declaration>
||=<reg_declaration>
||=<time_declaration>
||=<integer_declaration>
||=<real_declaration>
||=<event_declaration>
// Task
Invocation
<task_enable>
::=<name_of_task>;
||=<name_of_task>
(<expression><,<expression>>*);
- input, output,
inout : I/O ¼±¾ð keyword.
-
module port¸¦ ¼±¾ðÇÏ´Â keyword¿Í °°Àº ²ÃÀÌÁö¸¸ task¿¡¼´Â °ªÀÇ Àü´ÞÀÇ ¿ªÇÒÀÌ´Ù. Âü°í·Î module port´Â ¿ÜºÎ¿ÍÀÇ ½ÅÈ£
¿¬°áÀ» ÀǹÌÇÑ´Ù.
- task´Â ´Ù¸¥ task³ª functionÀ» È£Ãâ ÇÒ ¼ö ÀÖ´Ù.
8.2.2 Task Examples
¡á Use of input and output arguments
Ex)
// Input and
Output Arguments in Task
module operation;
parameter delay = 10;
reg [15:0] A,
B;
reg [15:0] AB_AND, AB_OR, AB_XOR;
always @(A or
B)
begin
// Task È£Ãâ. argumen´Â task ¼±¾ð¿¡¼ ¸í½ÃµÈ ¼ø¼¿¡ ÀÇÇØ
Àü´ÞµÈ´Ù.
// output arg : AB_AND, AB_OR, AB_XOR. input arg = A,
B
bitwise_oper(AB_AND, AB_OR,
AB_XOR, A, B);
end
// define
task
task bitwise_oper;
output
[15:0] ab_and, ab_or, ab_xor;
input [15:0] a,
b;
begin
#delay ab_and = a & b;
ab_or =
a | b;
ab_xor = a ^
b;
end
endtask
endmodule
* task°¡ È£ÃâµÇ¸é¼ a, b´Â °¢°¢ A¿Í BÀÇ °ªÀ» Àü´Þ¹Þ´Â´Ù.
** 10ÀÇ delay½Ã°£
ÈÄ¿¡ ¿¬»ê°á°ú ab_and, ab_or, ab_xor´Â °¢°¢ AB_AND, AB_OR, AB_XOR·Î Àü´ÞµÈ´Ù.
¡á Asymmetric Sequence Generator
Ex)
// regº¯¼öÀÇ Á÷Á¢
¿¬»ê
module sequence;
reg clock;
initial
init_sequence;
always
begin
asymmetric_sequence;
end
// Initialization
sequence
task init_sequence;
begin
clock =
1'b0;
end
endtask
// operating directly
on the clock in the module
task
asymmetric_sequence;
begin
#12 clock =
1'b0;
#5 clock =
1'b1;
#3 clock =
1'b0;
#10 clock =
1'b1;
end
endtask
endmodule
* module¿¡¼ Á¤ÀÇÇÑ regº¯¼ö clockÀ» task¿¡¼ Á÷Á¢ °Çµå¸± ¼ö ÀÖ´Ù.
8.3 Functions
- function, endfunction
: functionÀ» ¼±¾ðÇÏ´Â keyword.
- ´ÙÀ½¿¡ ¿°ÅÇÑ Á¶°Çµé Áß ¾î´À Çϳª¶óµµ ¸¸Á·ÇÑ´Ù¸é functionÀ» »ç¿ëÇؾß
ÇÑ´Ù.
* delay, timing, eventÁ¦¾î°¡ ¾ø´Â °æ¿ì
* ´Ü ÇÑ°³ÀÇ °ª¸¸À» µÇµ¹·ÁÁÖ´Â °æ¿ì
* Àû¾îµµ ÇÑ°³ÀÇ inputÀÌ ÀÖ´Â °æ¿ì
8.3.1 Function Declaration and Invocation
Syntax]
// Function Declaration
<function>
::= function <range_or_type>?
<name_of_functions>;
<tf_declaration>+
<statement>
endfunction
<range_or_type>
::=
<range>
||=<INTEGER>
||=<REAL>
<name_of_function>
::= <IDENTIFIER>
<tf_declaration>
::=<parameter_declaration>
||=<input_declaration>
||=<reg_declaration>
||=<time_declaration>
||=<integer_declaration>
||=<real_declaration>
// Function
Invocation
<function_call>
::= <name_of_function>
(<expression><,<expression>>*);
- functionÀÌ ¼±¾ðµÉ¶§ <name_of_function>ÀÇ À̸§À¸·Î ³»ºÎÀûÀ¸·Î register°¡ Çϳª
¼±¾ðµÈ´Ù.
- functionÀÇ return value°¡ À§ÀÇ ·¹Áö½ºÅ͸¦ ÅëÇØ Àü´ÞµÈ´Ù.
- <range_or_type>Àº functionÀÇ return value¿¡ ´ëÇÑ
width³ª typeÀ» ÁöÁ¤ÇÑ´Ù. ¸í½ÃÇÏÁö ¾Ê´Â °æ¿ì width´Â 1ÀÌ´Ù.
- functionÀº ´Ù¸¥ task´Â È£Ãâ ÇÒ ¼ö
¾øÀ¸¸ç, ¿ÀÁ÷ ´Ù¸¥ function¸¸ È£Ãâ °¡´ÉÇÏ´Ù.
8.3.2 Function Examples
¡á Parity Calculation
Ex)
// Parity
Calculation
module parity;
reg [31:0] addr;
reg
parity;
always
@(addr)
begin
parity =
calc_parity(addr);
// ù ¹ø° È£Ãâ
$display("Parity
calculated \ %b", calc_parity(addr)); // µÎ¹ø°
È£Ãâ
end
function
calc_parity;
// function ¼±¾ð. calc_parity¶ó´Â º¯¼ö »ý¼º
input [31:0]
address;
begin
calc_parity =
^address; // ÀÚµ¿ÀûÀ¸·Î ¸¸µé¾îÁö´Â º¯¼ö calc_parity¿¡
// return value¸¦ ÀúÀå
end
endfunction
endmodule
¡á Left/Right Shifter
Ex)
//Left/Right
Shifter
module shifter;
'define
LEFT_SHIFT 1'b0
'define
RIGHT_SHIFT 1'b1
reg [31:0] addr, left_addr,
right_addr;
reg control;
always
@(addr)
begin
left_addr = shift(addr,
'LEFT_SHIFT);
rifht_addr =
shift(addr, 'RIFHT_SHIFT);
end
function [31:0]
shift; // return value:
32bit º¯¼ö
input [31:0] address;
input control;
begin
shift = (control ==
'LEFT_SHIFT)? (address << 1) : <address
>>1);
end
endfunction
endmodule