[2024.04.18.목~] 인천인력개발원 하만 세미콘 아카데미
Verilog를 이용한 RTL 시스템 반도체 설계
Stopwatch 모듈 설계
1. 버튼이 눌리면 STR_STP변수를 1과 0으로 변경하여 모드를 Start, Stop으로 변경하는 모듈 작성
- Switch를 누르면 CLK의 rising edge에 맞춰 ss_1d를 1로
- 다음 CLK의 rising edge에서도 switch가 1이면 ss_2d를 1로
- enable = ss_1d & ~ss_2d를 이용하면 CLK 주기동안 버튼이 눌려있으면 start/stop 작동하도록 신호 생성
- RST == 0이고, enable = 1이면 STR_STP신호를 반전(STR_STP = ~STR_STP)하여 start/stop 모드 전환
2. key_proc.v 코드 작성
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2024/04/19 09:49:38
// Design Name:
// Module Name: key_proc
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module key_proc(
input RST,
input CLK,
input KEY,
output reg STR_STP //start: 1, stop: 0
);
reg ss_1d, ss_2d, enable;
always @(posedge CLK) begin
ss_1d <= KEY;
ss_2d <= ss_1d;
enable = ss_1d & ~ss_2d;
if (RST) STR_STP = 1'b0;
else begin
if (enable) STR_STP = ~STR_STP;
end
end
endmodule
3. 테스트벤치를 위한 key_proc_tb.v 코드 작성
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2024/04/19 09:53:12
// Design Name:
// Module Name: key_proc_tb
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module key_proc_tb( );
reg RST, CLK, KEY;
wire STR_STP;
initial begin
RST = 1'b1;
#200;
RST = 1'b0;
end
initial CLK = 1'b0;
always #10 CLK = ~CLK;
initial begin
KEY = 1'b0;
wait (RST == 1'b0);
#300;
KEY = 1'b1;
#300;
KEY = 1'b0;
#300;
KEY = 1'b1;
#300;
KEY = 1'b0;
$finish;
end
key_proc uut(
.RST (RST),
.CLK (CLK),
.KEY (KEY),
.STR_STP (STR_STP)
);
endmodule
4. 시뮬레이션 실행 결과: KEY에 입력 시 start/stop이 전환되기 위해 값이 1과 0으로 변경되는 것 확인

5. 위 회로의 Schematic

6. Start/Stop에 따라 초가 진행되는 블럭 구상
- 125MHz CLK을 이용하여 1초짜리 tick_1s 생성
- RST가 1이면 num_1s = 0, tick_1s가 1일때마다 num_1s 1씩 증가
- testbench에서는 CLK를 125MHz로 하면 시간이 오래 걸리므로 시간을 변경하여 tick에 num_1s가 정상적으로 증가하는지 확인
- stopwatch.v 코드
`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 2024/04/19 12:25:36 // Design Name: // Module Name: stopwatch // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module stopwatch( input RST, input CLK, input START, output reg[3:0] NUM_1S = 3'b0, output reg[2:0] NUM_10S = 2'b0 ); parameter CLK_FREQ = 125_000_000; reg tick_1s = 1'b0; reg [25:0] timing = 7'b0; always @(posedge CLK) begin if(START) begin timing = timing + 1; end //if( timing % 125_000_000 == 0 ) tick_1s = 1'b1; if( timing % 100 == 0 ) tick_1s = 1'b1; //else if (timing % 125_000_000 == 1000000 ) tick_1s = 1'b0; else tick_1s = 1'b0; end always @(posedge tick_1s) begin if (NUM_1S < 9) begin NUM_1S = NUM_1S + 3'b1; end else begin NUM_1S = 3'b0; NUM_10S = NUM_10S + 2'b1; end end endmodule
- stopwatch_tb.v 코드
`timescale 1ns / 1ps ////////////////////////////////////////////////////////////////////////////////// // Company: // Engineer: // // Create Date: 2024/04/19 12:39:36 // Design Name: // Module Name: stopwatch_tb // Project Name: // Target Devices: // Tool Versions: // Description: // // Dependencies: // // Revision: // Revision 0.01 - File Created // Additional Comments: // ////////////////////////////////////////////////////////////////////////////////// module stopwatch_tb( ); reg RST, CLK, START; wire NUM_1S, NUM_10S; initial begin RST = 1'b1; #200; RST = 1'b0; end initial CLK = 1'b0; always #4000 CLK = ~CLK; initial begin START = 1'b0; wait (RST == 1'b0); #50000; START = 1'b1; #500000000; START = 1'b0; #5000; START = 1'b1; #500; START = 1'b0; $finish; end stopwatch uut( .RST (RST), .CLK (CLK), .START (START), .NUM_1S (NUM_1S), .NUM_10S (NUM_10S) ); endmodule
- 테스트벤치 작동: tick에 따라 NUM_1S가 0~9까지 정상 증가하고, 10S도 정상증가 확인
7. 마지막으로 위에서 받은 NUM_1S와 NUM_10S를 세그먼트에 출력할 수 있는 코드를 작성하고, 세 파일 묶어서 실행 필요