08 Tasks and Functions
๐Ÿ”ฎ

08 Tasks and Functions

Description
Date
Oct 23, 2023
URL
์ƒํƒœ
Done
Tags
Digital Design

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 ํ• ๋‹น์ด ์—†์Œ
notion image
ย 

ํ•จ์ˆ˜ ์˜ˆ์‹œ (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
ย 
ย 
ย 
ย 
ย