하만(Harman) 세미콘 반도체 설계 과정/Verilog를 이용한 RTL 시스템 반도체 설계

하만(Harman) 세미콘 아카데미 30~31일차 - Verilog HDL 설계(Stopwatch 설계 테스트벤치)

semicon_circuitdesigner 2024. 4. 19. 16:35

[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를 세그먼트에 출력할 수 있는 코드를 작성하고, 세 파일 묶어서 실행 필요