Tasks์ Functions์ ์ฐจ์ด์
- Verilog์์ Tasks์ Functions๋ ์๋ก ๋ค๋ฅธ ๋ชฉ์ ์ ๊ฐ์ง:
- Tasks์ Functions๋ ๋ชจ๋ ๋ชจ๋ ๋ด์ ์ ์๋์ด์ผ ํ๋ฉฐ, ํด๋น ๋ชจ๋์ ๊ตญํ๋์ด ์ฌ์ฉ๋จ.
ย
ํจ์ ๋ ํ์คํฌ
๊ตฌ๋ถ | ํจ์(Function) | ํ์คํฌ(Task) |
๋ค๋ฅธ ๊ธฐ๋ฅ ํ์ฑํ | ํจ์๋ ๋ค๋ฅธ ํจ์๋ฅผ ํ์ฑํํ ์ ์์ง๋ง, ๋ค๋ฅธ ํ์คํฌ๋ ํ์ฑํํ ์ ์์. | ํ์คํฌ๋ ๋ค๋ฅธ ํ์คํฌ ๋ฐ ํจ์๋ฅผ ํ์ฑํํ ์ ์์. |
์คํ ์๊ฐ | ํจ์๋ ํญ์ 0 ์๋ฎฌ๋ ์ด์
์๊ฐ์ ์คํ๋จ. | ํ์คํฌ๋ 0์ด ์๋ ์๋ฎฌ๋ ์ด์
์๊ฐ์ ์คํ๋ ์ ์์. |
ํฌํจํ ์ ์๋ ๋ฌธ์ฅ | ํจ์๋ ์ง์ฐ, ์ด๋ฒคํธ ๋๋ ํ์ด๋ฐ ์ ์ด ๋ฌธ์ฅ์ ํฌํจํ ์ ์์. | ํ์คํฌ๋ ์ง์ฐ, ์ด๋ฒคํธ ๋๋ ํ์ด๋ฐ ์ ์ด ๋ฌธ์ฅ์ ํฌํจํ ์ ์์. |
์
๋ ฅ ์ธ์ | ํจ์๋ ์ต์ํ ํ๋์ ์
๋ ฅ ์ธ์๋ฅผ ๊ฐ์ ธ์ผ ํจ. ์ฌ๋ฌ ๊ฐ์ ์
๋ ฅ์ ๊ฐ์ง ์ ์์. | ํ์คํฌ๋ ์
๋ ฅ, ์ถ๋ ฅ, inout ์ ํ์ ์ธ์๋ฅผ 0๊ฐ ์ด์ ๊ฐ์ง ์ ์์. |
๋ฐํ ๊ฐ | ํจ์๋ ํญ์ ๋จ์ผ ๊ฐ์ ๋ฐํํจ. ์ถ๋ ฅ ๋๋ inout ์ธ์๋ฅผ ๊ฐ์ง ์ ์์. | ํ์คํฌ๋ ๊ฐ์ ๋ฐํํ์ง ์์ง๋ง, ์ถ๋ ฅ ๋ฐ inout ์ธ์๋ฅผ ํตํด ์ฌ๋ฌ ๊ฐ์ ์ ๋ฌํ ์ ์์. |
ํ์คํฌ ์์ (1)
์ ๋ ฅ ๋ฐ ์ถ๋ ฅ ์ธ์์ ์ฌ์ฉ
module operation; ... parameter delay = 10; reg [15:0] A, B; reg [15:0] AB_AND, AB_OR, AB_XOR; always @(A or B) // A ๋๋ B๊ฐ ๊ฐ์ด ๋ณํ ๋๋ง๋ค begin // ํ์คํฌ bitwise_oper ํธ์ถ, 2๊ฐ์ ์ ๋ ฅ ์ธ์ A, B ์ ๊ณต // 3๊ฐ์ ์ถ๋ ฅ ์ธ์ AB_AND, AB_OR, AB_XOR ๊ธฐ๋ // ์ธ์๋ ํ์คํฌ ์ ์ธ์์์ ๊ฐ์ ์์๋ก ์ง์ ๋์ด์ผ ํจ. bitwise_oper(AB_AND, AB_OR, AB_XOR, A, B); end ... endmodule // ํ์คํฌ bitwise_oper ์ ์ 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
ย
๋น๋์นญ ์ํ์ค ์์ฑ๊ธฐ
- ํ์คํฌ๋ ๋ชจ๋์ ์ ์๋ reg ๋ณ์๋ค์ ์ง์ ์๋ํ ์ ์์.
module sequence; ... reg clock; ... initial init_sequence; // ํ์คํฌ init_sequence ํธ์ถ always begin asymmetric_sequence; // ํ์คํฌ asymmetric_sequence ํธ์ถ end ... endmodule // ์ด๊ธฐํ ์ํ์ค task init_sequence; begin clock = 1'b0; end endtask // ๋น๋์นญ ์ํ์ค ์์ฑ ํ์คํฌ ์ ์ // ๋ชจ๋ ๋ด์ ์ ์๋ clock์ ์ง์ ์๋ task asymmetric_sequence; begin #12 clock = 1'b0; #5 clock = 1'b1; #3 clock = 1'b0; #10 clock = 1'b1; end endtask
ย
์๋ (์ฌ์ง์ ๊ฐ๋ฅ) ํ์คํฌ
- ํ์คํฌ๋ ์ผ๋ฐ์ ์ผ๋ก ์ ์ ์ธ ์ฑ๊ฒฉ์ ๊ฐ์ง
- ์ ์ธ๋ ๋ชจ๋ ํญ๋ชฉ์ ์ ์ ์ผ๋ก ํ ๋น๋๋ฉฐ, ๋์์ ์คํ๋๋ ํ์คํฌ์์ ๊ณต์ ๋จ โ ์ด๋ฌํ ์์ ์ ๊ฒฐ๊ณผ๊ฐ ์๋ชป๋ ์ ์์.
- ์๋ ํ์คํฌ๋ ํ์คํฌ๋ฅผ ์ฌ์ง์ ๊ฐ๋ฅํ๊ฒ ๋ง๋ค์ด ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํจ.
- ๊ฐ ์๋ ํ์คํฌ ํธ์ถ์ ๋ ๋ฆฝ์ ์ธ ๊ณต๊ฐ์์ ์๋ํจ.
module top; reg [15:0] cd_xor, ef_xor; // top ๋ชจ๋ ๋ด ๋ณ์ reg [15:0] c, d, e, f; // top ๋ชจ๋ ๋ด ๋ณ์ task automatic bitwise_xor; output [15:0] ab_xor; // ํ์คํฌ์ ์ถ๋ ฅ input [15:0] a, b; // ํ์คํฌ์ ์ ๋ ฅ begin #delay ab_xor = a ^ b; end endtask ... // ์ด ๋ always ๋ธ๋ก์ clk์ ๊ฐ ์์ ์์ง์์ // bitwise_xor ํ์คํฌ๋ฅผ ๋์์ ํธ์ถํจ. // ๊ทธ๋ฌ๋ ํ์คํฌ๊ฐ ์ฌ์ง์ ๊ฐ๋ฅํ๊ธฐ ๋๋ฌธ์, // ์ด ๋์ ํธ์ถ์ ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํ ๊ฒ์. always @(posedge clk) bitwise_xor(ef_xor, e, f); ... always @(posedge clk2) // ์ด์ ๋ธ๋ก๋ณด๋ค ๋ ๋ฐฐ ๋น๋ bitwise_xor(cd_xor, c, d); endmodule
ย
ํจ์ ์ ์ธ ๋ฐ ํธ์ถ
- ํจ์๋ ๋ค์ ๋ชจ๋ ์กฐ๊ฑด์ด ์ฐธ์ผ ๋ ์ฌ์ฉ๋ฉ๋๋ค.
- ์ ์ฐจ์ ์ง์ฐ, ํ์ด๋ฐ, ์ด๋ฒคํธ ์ ์ด ๊ตฌ์กฐ๊ฐ ์์
- ์ ์ฐจ๊ฐ ๋จ์ผ ๊ฐ์ ๋ฐํํจ
- ์ต์ํ ํ๋์ ์ ๋ ฅ ์ธ์๊ฐ ์์ผ๋ฉฐ, ์ถ๋ ฅ ๋๋ inout ์ธ์๊ฐ ์๊ณ , nonblocking ํ ๋น์ด ์์
ย
ํจ์ ์์ (1)
- ํจ๋ฆฌํฐ ๊ณ์ฐ
module parity; ... reg [31:0] addr; reg parity; // ์ฃผ์ ๊ฐ์ด ๋ณ๊ฒฝ๋ ๋๋ง๋ค ์๋ก์ด ํจ๋ฆฌํฐ ๊ณ์ฐ always @(addr) begin parity = calc_parity(addr); // calc_parity์ ์ฒซ ํธ์ถ $display("Parity calculated = %b", calc_parity(addr)); // calc_parity์ ๋ ๋ฒ์งธ ํธ์ถ end ... // ํจ๋ฆฌํฐ ๊ณ์ฐ ํจ์ ์ ์ function calc_parity; input [31:0] address; begin // ๋ด๋ถ์ ์ผ๋ก ์์์ ์ผ๋ก ์ฌ์ฉ๋๋ ๋ ์ง์คํฐ calc_parity ์ค์ calc_parity = ^address; // ๋ชจ๋ ์ฃผ์ ๋นํธ์ xor ๋ฐํ end endfunction ... endmodule
ย
ํจ์ ์์ (2)
- ์ข/์ฐ ์ด๋๊ธฐ
// ์ด๋๊ธฐ ํจ์๋ฅผ ํฌํจํ๋ ๋ชจ๋ ์ ์ 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); right_addr = shift(addr, RIGHT_SHIFT); end ... // ์ด๋ ํจ์ ์ ์. ์ถ๋ ฅ์ 32๋นํธ ๊ฐ์ ๋๋ค. function [31:0] shift; input [31:0] address; input control; begin // ์ ์ด ์ ํธ๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ์ ์ ํ ์ถ๋ ฅ ๊ฐ ์ค์ shift = (control == LEFT_SHIFT) ? (address << 1) : (address >> 1); end endfunction ... endmodule
ย
์๋ (์ฌ๊ท์ ) ํจ์
- ํจ์๋ ์ผ๋ฐ์ ์ผ๋ก ๋น์ฌ๊ท์ ์ผ๋ก ์ฌ์ฉ๋จ
- ํจ์๊ฐ ๋ ์์น์์ ๋์์ ํธ์ถ๋๋ฉด ๊ฒฐ๊ณผ๋ ๋น๊ฒฐ์ ์ ์ด๋ฉฐ, ๋ ํธ์ถ ๋ชจ๋ ๋์ผํ ๋ณ์ ๊ณต๊ฐ์์ ์๋ํจ
- ์ฌ๊ท์ (์๋) ํจ์๋ ๋ ๋ฆฝ์ ์ธ ๋ณ์ ๊ณต๊ฐ์ ์์ฝํ์ฌ ์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํจ
module top; ... // ํจ์ ์ ์ function automatic integer factorial; input [31:0] operand; integer i; begin if (operand >= 2) factorial = factorial(operand - 1) * operand; // ์ฌ๊ท ํธ์ถ else factorial = 1; end endfunction // ํจ์ ํธ์ถ integer result; initial begin result = factorial(4); // 4์ ํฉํ ๋ฆฌ์ผ ํธ์ถ $display("Factorial of 4 is %d", result); // 24 ์ถ๋ ฅ end ... endmodule
ย
์์ ํจ์
- ์์ ํจ์๋ ํน์ ์ ํ์ด ์๋ ์ผ๋ฐ ํจ์
- ์ด๋ฌํ ํจ์๋ ์์ ๋์ ๋ณต์กํ ๊ฐ์ ์ฐธ์กฐํ๋ ๋ฐ ์ฌ์ฉ๋ ์ ์์
module ram(...); parameter RAM_DEPTH = 256; reg [clogb2(RAM_DEPTH) - 1:0] addr_bus; // clogb2 ํจ์ ํธ์ถ๋ก ๊ณ์ฐ๋ ๋ฒ์ค ๋๋น ... // ์์ ํจ์ ์ ์ function integer clogb2(input integer depth); begin for (clogb2 = 0; depth > 0; clogb2 = clogb2 + 1) depth = depth >> 1; end endfunction endmodule
ย
๋ถํธ ์๋ ํจ์
- ๋ถํธ ์๋ ํจ์๋ ํจ์ ๋ฐํ ๊ฐ์ ๋ํด ๋ถํธ ์๋ ์ฐ์ฐ์ ์ํํ ์ ์์
module top; ... // ๋ถํธ ์๋ ํจ์ ์ ์ธ // 64๋นํธ ๋ถํธ ์๋ ๊ฐ์ ๋ฐํ function signed [63:0] compute_signed(input [63:0] vector); endfunction // ์์ ๋ชจ๋์์ ๋ถํธ ์๋ ํจ์ ํธ์ถ if (compute_signed(vector) < -3) begin end endmodule
ย
ย
ย
ย
ย