assign๊ณผ deassign
- ์ ์ฐจ์ ์ง์ ํ ๋น์ ํตํด ๊ฐ์ด ํ์ ๋ ์๊ฐ ๋์ ์ฐ์์ ์ผ๋ก ๋ ์ง์คํฐ๋ ๋คํธ์ ๊ตฌ๋๋ ์ ์์ต๋๋ค.
- ์ด๋ค์ ๋ ์ง์คํฐ๋ ๋คํธ์ ๋ํ ๊ธฐ์กด ํ ๋น์ ๋ฎ์ด์๋๋ค.
- assign๊ณผ deassign์ ๋ ์ง์คํฐ๋ ๋ ์ง์คํฐ์ ์ฐ๊ฒฐ์ ๋ํ ํ ๋น์ ๋ฎ์ด์ฐ๋ ๋ฐ ์ฌ์ฉ๋ฉ๋๋ค.
- ์ด๋ค์ ์ผ๋ฐ์ ์ธ ์ ์ฐจ์ ํ ๋น์ ํจ๊ณผ๋ฅผ ๋ฎ์ด์๋๋ค.
module edge_dff(q, qbar, d, clk, reset); // ์ ๋ ฅ ๋ฐ ์ถ๋ ฅ output q, qbar; input d, clk, reset; reg q, qbar; // q์ qbar ์ ์ธ always @(negedge clk) // ํด๋ก์ ์์ ์์ง์ ๊ฐ์ ํ ๋น begin q = d; qbar = ~d; end always @(reset) // q์ qbar์ ๋ํ ์ผ๋ฐ ํ ๋น ๋ฎ์ด์ฐ๊ธฐ if (reset) begin // ๋ฆฌ์ ์ด ๋์ ๋, q์ ๋ํ ์ผ๋ฐ ํ ๋น ๋ฎ์ด์ฐ๊ธฐ assign q = 1'b0; assign qbar = 1'b1; end else begin // ๋ฆฌ์ ์ด ๋ฎ์์ง๋ฉด, ๋ ์ง์คํฐ์ ๋ฎ์ด์ฐ๊ธฐ ๊ฐ์ ์ ๊ฑฐ deassign q; deassign qbar; end endmodule
force์ release
- force์ release๋ ๋ ์ง์คํฐ์ ๋คํธ ๋ชจ๋์ ๋ํ ๋ฎ์ด์ฐ๊ธฐ์ ์ฌ์ฉ๋ ์ ์์ต๋๋ค.
- ์ผ๋ฐ์ ์ผ๋ก ๋ํ์ ๋๋ฒ๊น ๊ณผ์ ์ด๋ ์๊ทน์ ์ฌ์ฉ๋ฉ๋๋ค.
- ๋์์ธ ๋ธ๋ก ๋ด์์ force์ release ์ฌ์ฉ์ ๊ถ์ฅํ์ง ์์ต๋๋ค.
module stimulus; // d-flipflop ์ธ์คํด์คํ edge_dff dff(q, qbar, D, CLK, RESET); ... initial begin // ์ด ๋ฌธ์ฅ๋ค์ q๋ฅผ ๊ฐ์ ๋ก ์ค์ #50 force dff.q = 1'b1; #50 release dff.q; // ๋ฆด๋ฆฌ์ค end ... endmodule
- ๋ ์ง์คํฐ์ ๋คํธ์ ๋ํ force์ release
- ๋ ์ง์คํฐ๋ ๋ฆด๋ฆฌ์ค๋ ํ์๋ ๊ฐ์ ๋ ๊ฐ์ ๊ณ์ ์ ์ฅํฉ๋๋ค.
- ๋คํธ๋ ๋ฆด๋ฆฌ์ค๋ ๋ ์ฆ์ ์ ์ ๊ตฌ๋ ๊ฐ์ผ๋ก ๋์๊ฐ์ง๋ง, ๋ฏธ๋์ ํ ๋น์ ์ํด ๋ณ๊ฒฝ๋ ์ ์์ต๋๋ค.
module top; assign out = a & b & c; // ์ฐ๊ฒฐ ... initial #50 force out = a | b & c; #50 release out; end ... endmodule
defparam ๋ฌธ
- ๋์์ธ์ ์ด๋ค ๋ชจ๋ ์ธ์คํด์ค์์๋ defparam ํค์๋๋ฅผ ์ฌ์ฉํ์ฌ ๋งค๊ฐ๋ณ์ ๊ฐ์ ๋ณ๊ฒฝํ ์ ์์ต๋๋ค.
module hello_world; parameter id_num = 0; // ๋ชจ๋ ์๋ณ ๋ฒํธ = 0์ผ๋ก ์ ์ initial // ๋ชจ๋ ์๋ณ ๋ฒํธ ํ์ $display("Displaying hello world id number = %d", id_num); endmodule // ์์ ๋ ๋ฒจ ๋ชจ๋ ์ ์ module top; // ์ธ์คํด์คํ๋ ๋ชจ๋๋ค์ ๋งค๊ฐ๋ณ์ ๊ฐ์ ๋ณ๊ฒฝ defparam w1.id_num = 1, w2.id_num = 2; // hello_world ๋ชจ๋ ๋ ๊ฐ ์ธ์คํด์คํ hello_world w1(); hello_world w2(); endmodule
ย
๋ชจ๋ ์ธ์คํด์ค ๋งค๊ฐ๋ณ์ ๊ฐ
๋ชจ๋์ด ์ธ์คํด์คํ๋ ๋ ๋งค๊ฐ๋ณ์ ๊ฐ์ ๋ฎ์ด์ธ ์ ์๋ค. ์๋ก์ด ๋งค๊ฐ๋ณ์ ๊ฐ์ ๋ชจ๋ ์ธ์คํด์คํ ์ค์ ์ ๋ฌ๋๋ค.
defparam
์ ํ์ํ์ง ์๋ค.module top; // hello_world ๋ชจ๋ ๋ ๊ฐ ์ธ์คํด์คํ // ๋งค๊ฐ๋ณ์ ๊ฐ ํ ๋น hello_world #(1) w1; // y ์ ๋ฌ hello_world #(.id_num(2)) w2; endmodule module bus_master; parameter delay1 = 2; parameter delay2 = 3; parameter delay3 = 7; ... <module internals> ... endmodule // ์์ ๋ชจ๋; ๋ bus_master ๋ชจ๋ ์ธ์คํด์คํ module top; // ์๋ก์ด ์ง์ฐ ๊ฐ์ผ๋ก ๋ชจ๋ ์ธ์คํด์คํ // ์ ๋ ฌ๋ ๋ชฉ๋ก์ผ๋ก ๋งค๊ฐ๋ณ์ ๊ฐ ํ ๋น bus_master #(4, 5, 6) b1(); // b1: delay1 = 4, delay2 = 5, delay3 = 6 bus_master #(9, 4) b2(); // b2: delay1 = 9, delay2 = 4, delay3 = ๊ธฐ๋ณธ๊ฐ // ์ด๋ฆ์ผ๋ก ๋งค๊ฐ๋ณ์ ๊ฐ ํ ๋น bus_master #(.delay2(4), .delay3(7)) b3(); // b3: delay2 = 4, delay3 = 7, delay1 = ๊ธฐ๋ณธ๊ฐ(2) // ์ด๋ฆ์ผ๋ก ๋งค๊ฐ๋ณ์ ๊ฐ์ ํ ๋นํ๋ ๊ฒ์ด ๊ถ์ฅ๋จ // ์ด๋ ์ค๋ฅ ๊ฐ๋ฅ์ฑ์ ์ต์ํํ๊ณ , ๋งค๊ฐ๋ณ์๋ฅผ ์ถ๊ฐํ๊ฑฐ๋ ์ญ์ ํ ๋ ์์๋ฅผ ๊ณ ๋ คํ ํ์๊ฐ ์๋ค. endmodule
ย
์กฐ๊ฑด๋ถ ์ปดํ์ผ
์กฐ๊ฑด๋ถ ์ปดํ์ผ์
`ifdef
, `ifndef
, `else
, `elsif
, `endif
์ปดํ์ผ ์ง์๋ฌธ์ ์ฌ์ฉํ์ฌ ์ํํ ์ ์๋ค. ๋์์ด๋๋ ๋ฌธ์ฅ, ๋ชจ๋, ๋ธ๋ก, ์ ์ธ ๋ฐ ๊ธฐํ ์ปดํ์ผ ์ง์๋ฌธ์ ์กฐ๊ฑด๋ถ๋ก ์ปดํ์ผํ ์ ์๋ค. ์ด๋ C/C++์ #if
, #elif
, #else
, #endif
์ ์ ์ฌํ๋ค.// ์์ 1 `ifdef TEST // TEST๊ฐ ์ ์๋์ด ์์ผ๋ฉด test ๋ชจ๋ ์ปดํ์ผ module test; endmodule `else // ๊ทธ๋ ์ง ์์ผ๋ฉด stimulus ๋ชจ๋ ์ปดํ์ผ module stimulus; ... endmodule `endif // ์์ 2 module top; bus_master b1(); `ifdef ADD_B2 bus_master b2(); `elsif ADD_B3 bus_master b3(); `else bus_master b4(); `endif `ifndef IGNORE_B5 bus_master b5(); `endif endmodule
ย
์กฐ๊ฑด๋ถ ์คํ
์กฐ๊ฑด๋ถ ์คํ ํ๋๊ทธ๋ ๋์์ด๋๊ฐ ๋ฐํ์์ ์คํ ํ๋ฆ์ ์ ์ดํ ์ ์๊ฒ ํ๋ค. ์ด๋ ํ๋์ ๋ฌธ์ฅ์๋ง ์ฌ์ฉ๋ ์ ์๋ค.
// ์กฐ๊ฑด๋ถ ์คํ ๋ชจ๋ module test; ... initial begin if ($test$plusargs("DISPLAY_VAR")) $display("Display = %b", (a, b, c)); else $display("No Display"); // ๊ทธ๋ ์ง ์์ผ๋ฉด end endmodule // ์๋ฎฌ๋ ์ด์ ์ต์ : DISPLAY_VAR module test; reg [8*128-1:0] test_string; integer clk_period; ... initial begin if ($value$plusargs("testname=%s", test_string)) $readmemh(test_string, vectors); // ํ ์คํธ ๋ฒกํฐ ์ฝ๊ธฐ else $display("Test name option not specified"); if ($value$plusargs("clk_t=%d", clk_period)) forever #(clk_period/2) clk = ~clk; // ํด๋ก ์ค์ else $display("Clock period option not specified"); end // ์์๋ก, ์ด ์ต์ ๋ค์ ํ์ฑํํ๊ธฐ ์ํด ์๋ฎฌ๋ ์ดํฐ ํธ์ถ: +testname=test1.vec +clk_t=10 // ํ ์คํธ ์ด๋ฆ = "test1.vec" ๊ณผ clk_period = 10 endmodule
์๊ฐ ์ค์ผ์ผ
Verilog๋
`timescale
์ปดํ์ผ ์ง์๋ฌธ์ ์ฌ์ฉํ์ฌ ๋ชจ๋์ ๋ํ ์ฐธ์กฐ ์๊ฐ ๋จ์๋ฅผ ์ง์ ํ ์ ์์module dummy1; reg toggle; // toggle ์ด๊ธฐํ initial toggle = 1'b0; // 5 ์๊ฐ ๋จ์๋ง๋ค toggle ๋ ์ง์คํฐ ๋ฐ์ // ์ด ๋ชจ๋์์ 5 ์๊ฐ ๋จ์ = 500 ns = 0.5 us always #5 begin toggle = ~toggle; $display("%d, In dummy1 toggle = %b", $time, toggle); end endmodule `timescale 1us / 10ns module dummy2; reg toggle; // 1.1 โ 1100ns, 1.11 โ 1110ns, 1.111 โ 1110ns // toggle ์ด๊ธฐํ // 5 ์๊ฐ ๋จ์๋ง๋ค toggle ๋ ์ง์คํฐ ๋ฐ์ // ์ด ๋ชจ๋์์ 5 ์๊ฐ ๋จ์ = 5 us = 5000 ns always #5 begin toggle = ~toggle; $display("%d, In dummy2 toggle = %b", $time, toggle); end endmodule
ย
ํ์ผ ์ถ๋ ฅ
ํ์ผ ์ด๊ธฐ
- ์์คํ
์์
$fopen
์ ์ฌ์ฉํ์ฌ ํ์ผ์ ์ด ์ ์์ผ๋ฉฐ, 32๋นํธ ๊ฐ์ผ๋ก ํธ๋ค์ ๋ฐํํจ
integer handle1, handle2, handle3; initial begin handle1 = $fopen("file1.out"); // handle1 = 32'h0000_0002 (bit 1 set) handle2 = $fopen("file2.out"); // handle2 = 32'h0000_0004 (bit 2 set) handle3 = $fopen("file3.out"); // handle3 = 32'h0000_0008 (bit 3 set) end
ย
ํ์ผ์ ์ฐ๊ธฐ
- ํ์ผ์ ์ฐ๊ธฐ ์ํด ์์คํ
์์
$fdisplay
,$fmonitor
,$fwrite
,$fstrobe
๊ฐ ์ฌ์ฉ๋๋ค.
integer desc1, desc2, desc3; initial begin desc1 = handle1 | 1; // ๋นํธ ์ฐ์ฐ or; desc1 = 32'h0000_0003 $display(desc1, "Display 1"); // file1.out๊ณผ stdout์ ์ฐ๊ธฐ desc2 = handle2 | handle1; // desc2 = 32'h0000_0006 $fdisplay(desc2, "Display 2"); // file1.out๊ณผ file2.out์ ์ฐ๊ธฐ desc3 = handle3; // desc3 = 32'h0000_0008 $display(desc3, "Display 3"); // file3.out์๋ง ์ฐ๊ธฐ end
ย
๊ณ์ธต ๊ตฌ์กฐ ๋ฐ ์คํธ๋ก๋น ํ์
๊ณ์ธต ๊ตฌ์กฐ ํ์
- ๋ชจ๋ ๋์คํ๋ ์ด ์์
์์
%m
์ต์ ์ ์ฌ์ฉํ์ฌ ์ด๋ ์์ค์ ๊ณ์ธต ๊ตฌ์กฐ๋ ํ์ํ ์ ์์
module M; initial $display("Displaying in %m"); endmodule // M ๋ชจ๋ ์ธ์คํด์คํ module top; M m1(); M m2(); M m3(); endmodule
ย
์คํธ๋ก๋น
- ์คํธ๋ก๋น์ ์์คํ
์์
ํค์๋
$strobe
๋ก ์ํ๋จ
$strobe
๋ ๋์ผํ ์๊ฐ ๋จ์์์ ๋ค๋ฅธ ๋ชจ๋ ํ ๋น ๋ฌธ์ด ์คํ๋ ํ ํญ์ ์คํ๋์ด ๋๊ธฐํ ๋ฉ์ปค๋์ฆ์ ์ ๊ณตํจ
always @(posedge clock) begin a = b; c = d; end always @(posedge clock) $strobe("Displaying a = %b, c = %b", a, c);
ย
๋์ ์์ฑ
- ๋์ ์์ฑ์ ์ํด ์์คํ
์์
$random
์ด ์ฌ์ฉ๋จ
$random
์ 32๋นํธ ๋ถํธ ์๋ ์ ์๋ฅผ ๋ฐํํจ
module test; integer r_seed; reg [31:0] addr; wire [31:0] data; ROM rom1(data, addr); initial begin r_seed = 2; // ์์๋ก ์๋๋ฅผ 2๋ก ์ ์ always @(posedge clock) addr = $random(r_seed); // ๋์ ์์ฑ // ROM์ ์ถ๋ ฅ๊ณผ ์์ ๊ฒฐ๊ณผ ํ์ธ end endmodule reg [23:0] rand1, rand2; rand1 = $random % 60; // -59์ 59 ์ฌ์ด์ ๋์ ์์ฑ rand2 = {$random} & 60; // $random์ ์ฐ๊ฒฐ ์ฐ์ฐ์ ์ถ๊ฐํ์ฌ 0๊ณผ 59 ์ฌ์ด์ ์์ ๊ฐ ์์ฑ
ย
ํ์ผ์์ ๋ฉ๋ชจ๋ฆฌ ์ด๊ธฐํ
- ๋ฉ๋ชจ๋ฆฌ๋ฅผ ์ด๊ธฐํํ๊ธฐ ์ํด
$readmemb
์$readmemh
ํค์๋๊ฐ ์ฌ์ฉ๋จ
<start_addr>
,<finish_addr>
๋ ์ ํ์ ์
module test; reg [7:0] memory[0:7]; integer i; initial begin $readmemb("init.dat", memory); for (i = 0; i < 8; i = i + 1) $display("Memory [%d] = %b", i, memory[i]); end endmodule
ย
๊ฐ ๋ณ๊ฒฝ ๋คํ ํ์ผ
- ๊ฐ ๋ณ๊ฒฝ ๋คํ(VCD) ํ์ผ์ ASCII ํ์ผ๋ก์ ๋ค์ ์ ๋ณด๋ฅผ ํฌํจํจ:
- ์๋ฎฌ๋ ์ด์ ์๊ฐ, ๋ฒ์, ์ ํธ ์ ์, ์๋ฎฌ๋ ์ด์ ์คํ ์ค์ ์ ํธ ๊ฐ ๋ณ๊ฒฝ
$dumpvars
,$dumpfile
,$dumpon/off
์ฌ์ฉ- ๋คํ ๋ ๋ฒจ ์ง์ (0โall, 1โcurrent)
initial $dumpfile("myfile.dmp"); initial $dumpvars; // ์๋ฌด ์ธ์ ์์ initial $dumpvars(1, top); // 1๋ฒ ๊ณ์ธต ๋ ๋ฒจ์์ top ๋คํ initial $dumpvars(0, top.m1); // top.m1๊ณผ ๊ทธ ์๋ ๋ชจ๋ ๋คํ // ๋คํ ํ๋ก์ธ์ค ์์ ๋ฐ ์ค์ง initial begin $dumpon; #100000 $dumpoff; end