UVM & RTL/Verilog HDL

[31] Verilog HDL 순차회로 설계과제 (카운터)

Return 2022. 3. 6. 21:21

★ Active-high enable 신호를 갖는 8비트 감소 계수기를 설계하고, 시뮬레이션을 통해 동작을 확인한다. Enable신호 en=1이면 계수동작을 멈추는 기능을 가지며, active-low 비동기식 리셋을 갖는다. 

// 설계과제 11.13 
module counterdown(clk,en,rst,cnt);
    input clk,en,rst;
    output reg [7:0]cnt;

    always@(posedge clk or negedge rst)begin
        if(!rst) cnt <= 100;
        else if(en) cnt <= cnt;
        else cnt = cnt-1;
    end
endmodule

▣ TESTBENCH

module tb_counterdown;
    reg clk,en,rst;
    wire [7:0] cnt;

    counterdown uo(clk,en,rst,cnt);
    always 
        #10 clk = ~clk;

    initial begin 
        clk = 1'b0;
        rst = 1'b0;
        en = 1'b1;
        #20 rst =1'b1; en = 1'b0;
        #40 en = 1'b1;
        #40 en = 1'b0;
    end
endmodule

★ Mode신호에 따라 계수기 값이 증가(mode=1) 또는 감소(mode=0)되는 8비트 증가/감소 계수기를 설계하고, 시뮬레이션을 통해 동작을 확인한다. active-low 비동기식 리셋을 갖는다. 

// 설계과제 11.14
module countermode(clk,mode,rst,cnt);
    input clk , mode, rst ;
    output reg [7:0] cnt;

    always@(posedge clk or negedge rst)begin 
        if(!rst) cnt <= 7'b0;
        else if(mode) cnt <= cnt +1;
        else cnt <= cnt -1;
    end
endmodule

▣ TESTBENCH

module tb_countermode;
    reg clk,mode,rst;
    wire [7:0] cnt;

    always
        #10 clk = ~clk;
    
    countermode u0(clk,mode,rst,cnt);

    initial begin 
        clk = 1'b0;
        rst = 1'b0;
        mode = 1'b1;
        #10 rst = 1'b1;
        #80 mode = 1'b0;
        #80 mode = 1'b1;
    end
endmodule

★ 위의 두 가지 설계과제에서 설계된 기능을 추가하여 8비트 데이터의 병렬로드(load=1)기능을 갖는 8비트 증가/감소 계수기를 설계하고, 시뮬레이션을 통해 동작을 확인한다. 

// 설계과제 11.15
module countin(clk,rst,load,din,cnt);
    input clk,rst,load;
    input [7:0] din;
    output reg [7:0] cnt;

    always@(posedge clk or negedge rst)begin
        if(!rst) cnt <= 7'b0;
        else begin
            if(load) cnt <= din;
            else cnt <= cnt + 1;
        end
    end
endmodule

▣ TESTBENCH

module tb_countin;
    reg clk,rst,load;
    reg [7:0] din;
    wire [7:0] cnt;
    integer i;

    countin u0(clk,rst,load,din,cnt);

    always 
        #10 clk = ~clk;
    
    initial begin 
        clk = 1'b0; rst = 1'b0; load = 1'b0; din = 7'b0;
        #20 rst = 1'b1;
        #80 load = 1'b1;
        #100 load = 1'b0;
    end

    always begin 
        for(i=1;i<100;i=i+1)begin
            #10 din = i;
        end
    end
endmodule

★ 1부터 100까지 세는 counter를 다음과 같이 2가지 형태로 설계하고, 테스트벤치를 이용한 시뮬레이션을 통해 동작을 확인한다. 

① 0부터 99까지 세고 멈추는 모델링 

module count100(clk,rst,cnt);
    input clk,rst;
    output reg [7:0] cnt;

    always@(posedge clk or negedge rst)begin
        if(!rst) cnt <= 0;
        else if(cnt == 99) cnt <= cnt;
        else cnt <= cnt + 1;
    end
endmodule

▣ TESTBENCH 

module tb_count100;
    reg clk, rst;
    wire [7:0] cnt;

    count100 uo(clk,rst,cnt);

    always
        #2 clk = ~clk;
    
    initial begin 
        clk = 1'b0;
        rst = 1'b0;
        #10 rst = 1'b1;
    end
endmodule

② 99까지 세고 다시 0로 가는 모델링 

module count100(clk,rst,cnt);
    input clk,rst;
    output reg [7:0] cnt;

    always@(posedge clk or negedge rst)begin
        if(!rst) cnt <= 0;
        else if(cnt == 99) cnt <= 0;
        else cnt <= cnt + 1;
    end
endmodule