1Sec Counter 설계

설계 요구사항

- RST = 1일 경우 LED off, RST = 0일 경우 1초 마다 LED on/off

- 내부 counter를 설계하여 1초마다 enable 되는 신호 생성 enable 신호를 이용하여 출력을 반전 시키는 회로 설계

 

 

`timescale 1ns / 1ps

//////////////////////////////////////////////////////////////////////////////////


module my_1sec(
    input RST,
    input CLK,
    output reg LED
    );
    
parameter clk_freq = 125_000_000;

reg enable;
reg [31:0] cnt;

always @(posedge CLK)
begin
    if(RST) begin
        cnt <= 32'd0;
        enable <= 1'b0;
    end else begin
        if(cnt == (clk_freq-1)) begin
            cnt <= 32'd0;
            enable <= 1'b1;
        end else begin
            cnt <= cnt + 1;
            enable <= 1'b0;
        end
    end
end

always @(posedge CLK)
begin
    if(RST)
        LED <= 1'b0;
    else if (enable)
        LED <= ~LED;
end
endmodule

`timescale 1ns / 1ps

//////////////////////////////////////////////////////////////////////////////////


module my_1sec(
    input RST,
    input CLK,
    output reg LED
    );
    
parameter clk_freq = 125_000_000;   // parameter로 CLK의 125MHz 지정
   
reg  enable;                         // register로 enable
reg [31:0] cnt;                      //     ``     cnt 0~ 31bit(32bit) 지정

always @(posedge CLK)                // CLK가 상승 에지일때마다
begin                                // {
    if(RST) begin                    // Reset이 이면 {
        cnt <= 32'd0;                // cnt 32bit is zero
        enable <= 1'b0;              // enable is zero
    end else begin                   // RST가 0이면
        if(cnt == (clk_freq-1)) begin// cnt = 124_999_999라면 {
            cnt <= 32'd0;            // cnt 32bit is zero (초기화)
            enable <= 1'b1;          // enable = 1
        end else begin               // } cnt가 124_999_999가 아니면
            cnt <= cnt + 1;          // cnt = cnt++;
            enable <= 1'b0;          // enable = 0;
        end                          //         }
    end                              //     }
end                                  // }

always @(posedge CLK)                // CLK가 상승 에지일때 마다
begin                                // {
    if(RST)                          // RST == 1이면(리셋이면)
        LED <= 1'b0;                 // LED = 0(끄고)
    else if (enable)                 // RST == 0이면
        LED <= ~LED;                 // 뒤집어라
end                                  // }
endmodule

위의 코드에 주석을 작성한 버전입니다.

 

그 다음으로는 Simlation code를 작성하여 Testbench를 진행합니다.


Testbench

`timescale 1ns / 1ps

//////////////////////////////////////////////////////////////////////////////////


module my_1sec_tb();
parameter   CLK_PED = 10.0;

reg reset, clk;                 //Testbench signals
wire    dout;


my_1sec #( .clk_freq(10))       //uut 인스턴스화(Instantiate)
 uut(
    .RST    (reset),
    .CLK    (clk),
    .LED    (dout)
    );
initial begin                   // reset simulation을 위한 initial block
    reset = 1'b1;               // Assert reset(0에서 1로 변화)
    #(CLK_PED + 10);
    reset = 1'b0;               // Deassert reset(1에서 0으로 변화)
end

initial clk = 1'b0;             // clk 0으로 초기화
always #(CLK_PED/2) clk = ~clk; // Toggle clk half peroid 마다 반전

endmodule

위의 파형이 Test로 출력되는 것을 확인 할 수 있습니다. 정상적으로 출력된것을 확인한 후, 이제 H/W로 넘어가서 Device에 Program을 진행 하면 됩니다. 실제 H/W는 1초마다 작동하게 구성하였지만 Testbench에서는 10/125,000,000마다로 설정했습니다. Testbench에서 CLK_PED를 125_000_000으로 설정했다면 비교적 매우 많은 양의 Pulse를 봐야합니다.

Default로 설정되어있는 값을 편하게 보려면, 원하는 Object에 우클릭 > Radix > Unsigned Decimal로 설정하면

 

위의 사진처럼 나오는 모습을 확인 할 수 있습니다.

 

<좌, Default>, <우, Unsigned Decimal> 확대 비교