Study/Digital System Design and Lab[Verilog]

#4-1 "IF", "Case" Statement - Counter

얼죽아여뜨샤 2023. 10. 15. 18:02

*4bit Counter design

`timescale 1ns/1ns

module Counter4(Reset, Ck, Mode, Din, Out);

input Reset, Ck;
input [1:0]Mode;
input [3:0]Din;
output [3:0]Out;
wire [3:0]Out;

parameter LOAD = 2'b01, C_UP = 2'b10, C_DOWN = 2'b11;

reg [3:0]Register;

always@(posedge Ck) //synchronous
begin
	if(Reset)
    	Register <= 4'b0000;
    else
    	case(Mode)
        	LOAD : Register <= Din;	//b'01		
            C_UP : Register <= Register + 1; //Up counting //b'10
            C_DOWN : Register <= Register - 1; //Down counting //b'11
            default : Register <= Register; //b'00
        endcase
end

assign Out = Register;

endmodule

 

*4bit Counter Test bench design

`timescale 1ns/1ns

module Counter4_Tb;

parameter tlimit = 400;
parameter ckPeriod = 7;

reg Reset = 1'b1, Ck = 1'b0;
reg [1:0]Mode = 2'b00;
reg [3:0]Din = 4'b0000;
wire [3:0]Out;

Counter4 U1 (Reset, Ck, Mode, Din, Out);

//initial block은 test bench에는 사용해도 된다. 합성에 안들어가서
initial #tlimit $stop;
initial #10 Reset = 1'b0;
always #ckPeriod Ck = ~Ck;

always@(negedge Ck)
begin
	Mode = $random; Din = $random; //$기호는 verilog에서 기본으로 사용하는 함수사용
end

integer result;

always@(posedge Ck)
begin
	if(Reset) 
    begin
    	result = $fopen("result.txt");
        $fwrite(result, "time = %d, Mode = %d, Din = %d, ", $time, Mode, Din); //fwrite는 줄 바꾸지 않는 명령어
        #2;
        $display(result, "Out = %d", Out); //fdisplay는 다음 명령은 줄을 바꾸는 명령어
    end
end

endmodule

 

*Simulation result 

 

*Simulation result - Waveform

 

*4bit Counter - 3bit Mode

`timescale 1ns/1ns

module Register4(Reset, Ck, Mode, Din, R_In, L_In, Out); 
input Reset, Ck, R_In, L_In; //L, R는 shift시 채워지는 1bit신호
input [3:0]Mode;
input [3:0]Din;
output [3:0]Out;

wire [3:0]Out
reg [3:0]Register

parameter STAY = 3'b000, LOAD = 3'b001, UP = 3'b010, DOWN = 3'b011, R_SHIFT = 3'b100, L_SHIFT = 3'b101, COM = 3'b110, SWAP = 3'b111;

always@(posedge Ck)
begin
	if(Reset)
    Register <= 4'b0000;
    else
    	case(Mode)
        STAY : Register <= Register;
        LOAD : Register <= Din;
        UP : Register <= Register + 1;
        DOWN : Register <= Register - 1;
        R_SHIFT : Register <= {R_In, Register[3:1]};
        L_SHIFT : Register <= {Register[2:0], L_In};
        COM : Register <= ~Register;
        SWAP : Register <= {Register[1:0], Register[3:2]};
        //default : Rdgister <= Register;
        
        endcase
end

assign Out = Register;

endmodule

 

 *4bit Counter - 3bit Mode Tb

`timescale 1ns/1ns

module Counter4_Tb;

parameter tlimit = 400;
parameter ckPeriod = 7;

reg Reset = 1'b1, Ck = 1'b0, R_In = 1'b0, L_In = 1'b0;
reg [2:0]Mode = 3'b000;
reg [3:0]Din = 4'b0000;
wire [3:0]Out;

Register4 U1(Reset, Ck, Mode, Din, R_In, L_In, Out);

//initial block은 test bench에는 사용해도 된다. 합성에 안들어가서
initial #tlimit $stop;
initial #10 Reset = 1'b0;
always #ckPeriod Ck = ~Ck;

always@(negedge Ck)
begin
	Mode = $random; Din = $random; //$기호는 verilog에서 기본으로 사용하는 함수사용
    R_In = $random; L_In = &random;
end

integer result;

always@(posedge Ck)
begin
	if(Reset) 
    begin
    	result = $fopen("result.txt");
        $fwrite(result, "time = %d, Mode = %d, Din = %d, R_In = %d, L_In = %d, ", $time, Mode, Din, R_In, L_In); //fwrite는 줄 바꾸지 않는 명령어
        #2;
        $display(result, "Out = %d", Out); //fdisplay는 다음 명령은 줄을 바꾸는 명령어
    end
end

endmodule

 

*Simulation result 

 

*Simulation result - Waveform