09 Useful Modeling Techniques
๐Ÿ”ฎ

09 Useful Modeling Techniques

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

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