본문 바로가기
나의 전자 공부방/FPGA

vivado, FPGA를 이용해서 시계(TimeClock)만들기

by 나만의생각 2023. 5. 10.

이번시간에는 회로들을 연결해서 FPGA의 FND로 Timeclock을 만들어보겠습니다.

 

두가지를 진행하였습니다. 첫번째는 milisec, sec만 출력하기, 두번째는 스위치를 작동하여 milisec or sec를 출력하거나 min과 hour을 출력하여 보여줍니다.

 

Time Clock Schematic
testbench

클럭 2개와 inclk가 1일때 fndData가 1110에 들어가는것을 볼수있습니다. 이를통해 잘 검증되었다고 알수 있습니다.

 

TimeClock Schematic(2)

두번쨰로 4x1의 Mux를 하나 추가해서 clockdiver와 counter에 연결한모습입니다. 이를통하여 min hour을 출력할 것인지 milisec sec를 출력할것인지 결정을합니다.

 

 

연결방법

 

`timescale 1ns/1ps

//--------

module clk_1Mhz(in_clk, in_reset, out_clk);

input in_clk, in_reset;
output out_clk;

reg out_clk = 0;
reg [31:0] count = 0;

always@(posedge in_clk or posedge in_reset) begin
    if(in_reset) begin
		out_clk <= 0;
       count <= 0;
    end
    else begin
        if(count == 500_000-1)begin
       out_clk <= ~out_clk;
       count<=0;
        end
        else begin
            count <= count +1;
        end
    end
end
endmodule
//----------------------------------------------

 

module clk_1khz(in_clk, in_reset, out_clk);

input in_clk, in_reset;
output out_clk;

reg out_clk = 0;
reg [31:0] count = 0;

always@(posedge in_clk or posedge in_reset) begin
    if(in_reset) begin
		out_clk <= 0;
       count <= 0;
    end
    else begin
        if(count == 500)begin
       out_clk <= ~out_clk;
       count<=0;
        end
        else begin
            count <= count +1;
        end
    end
end
endmodule
// -------------------counter------------------
module counter(in_clk, in_reset, out_value);

input in_clk, in_reset;
output [3:0] out_value;

reg[3:0] out_value =0;

always@(posedge in_clk or posedge in_reset) begin


if(in_reset) begin
   out_value <=0;
end

else if (in_clk) begin
   out_value <= out_value+1;
   if(out_value == 9)
   out_value<= 0;
end
end

endmodule

 

module fnd_decoder(in_data,out_fndFont);
input [3:0]in_data;
output [7:0] out_fndFont;

reg[7:0] out_fndFont;
always@(*)begin

//out_fndFont = 8'hff;
   case (in_data)
            default : out_fndFont = 8'hc0;//
            1 : out_fndFont = 8'hf9;
            2 : out_fndFont = 8'ha4;
            3 : out_fndFont = 8'hb0;
            4 : out_fndFont = 8'h99;
            5 : out_fndFont = 8'h92;
            6 : out_fndFont = 8'h82;
            7 : out_fndFont = 8'hf8;
            8 : out_fndFont = 8'h80;
            9 : out_fndFont = 8'h90;
            
   endcase
end
endmodule
module dec_2x4(in_sel, out_sel);
input [1:0] in_sel;
output [3:0] out_sel;

reg[3:0] out_sel;

always@(*) begin
    case(in_sel)
        2'd0: out_sel = 4'b1110;
		2'd1: out_sel = 4'b1101;
		2'd2: out_sel = 4'b1011;
		2'd3: out_sel = 4'b0111;
        
 
    endcase
    end
endmodule
module mux_4x1(in_sel,in_a, in_b, in_c, in_d,out_y);
    input [1:0] in_sel;
    input [3:0] in_a, in_b, in_c, in_d;
    output [3:0] out_y;
    

    reg [3:0] reg_y;

    assign out_y = reg_y;

    always @(in_sel) begin
        reg_y = 0;
        case (in_sel)
        2'd0 : reg_y = in_a;
        2'd1 : reg_y = in_b;
        2'd2 : reg_y = in_c;
        2'd3 : reg_y = in_d;
        endcase
    end
endmodule

module mux_2x1(
	input in_sel,
    input [3:0] in_a, in_b,
    output [3:0] out_y
    );

    reg [3:0] reg_y;

    assign out_y = reg_y;

    always @(in_sel) begin
        reg_y = 0;
        case (in_sel)
        2'd0 : reg_y = in_a;
        2'd1 : reg_y = in_b;
        endcase
    end
endmodule
module time_counter(in_clk, in_reset, out_sec, out_ms, out_min, out_hour);

input in_clk, in_reset;
output [6:0] out_sec, out_ms, out_min, out_hour;

reg[6:0] reg_sec, reg_ms, reg_min,reg_hour;


assign out_sec = reg_sec;
assign out_ms = reg_ms;
assign out_min= reg_min;
assign out_hour = reg_hour;

always @(posedge in_clk or posedge in_reset)begin
    if(in_reset)begin
    reg_ms<=0;
    reg_sec<=0;
	reg_min<=0;
	reg_hour<=0;
    end
   else begin
     if(reg_ms==100)begin
        reg_ms<=0;
             if(reg_sec==59)begin
                reg_sec<=0;
				if(reg_min == 59)begin
				reg_min <=0;
					if(reg_hour == 23)begin
					reg_hour<=0;
					end
					else begin
					reg_hour<=reg_hour+1;
					end
				end
				else begin
				reg_min<=reg_min+1;
				end	
             end
             else begin 
            reg_sec <= reg_sec+1;
             end
      end       
      else begin
          reg_ms <= reg_ms+1;
       end
    end
end   

endmodule

 

 

module digit_divider(in_sec, in_ms,in_min,in_hour, out_ms_1, out_ms_10, out_sec_1, out_sec_10 ,out_min_1, out_min_10, out_hour_1, out_hour_10);
	
	input [6:0] in_sec, in_ms,in_min,in_hour;
    output [3:0] out_ms_1, out_ms_10, out_sec_1, out_sec_10;
    output [3:0] out_min_1, out_min_10, out_hour_1, out_hour_10;

    assign  out_ms_1    = in_ms %10;
    assign out_ms_10   = in_ms  /10 % 10;
    assign out_sec_1  = in_sec 	%10;
    assign  out_sec_10 = in_sec  /10 % 10;
    
     assign  out_min_1    = in_min %10;
    assign out_min_10   = in_min  /10 % 10;
    assign out_hour_1  = in_hour 	%10;
    assign  out_hour_10 = in_hour  /10 % 10;

endmodule
module top_upcounter(in_clk, in_reset,in_sw_sel, out_fndData, out_sel);

input in_clk, in_reset,in_sw_sel;
output [7:0] out_fndData;
output [3:0] out_sel;

wire [1:0]w_2bit_value;
wire w_1Mhz, w_1khz;
//wire [3:0] in_sel;
wire [3:0] w_sec_10,w_sec_1,w_ms_10,w_ms_1,w_ms_data,w_min_data,select_data;
wire [3:0] w_min_10, w_min_1, w_hour_10, w_hour_1;
wire[6:0]w_sec,w_ms,w_min,w_hour;

 always @(w_1Mhz) begin

    out_fndData = inst_fnd_decoder.out_fndFont;
  end
clk_1Mhz inst_clk_1Mhz(.in_clk(in_clk), .in_reset(in_reset), .out_clk(w_1Mhz));
//counter inst_4bit_counter(.in_clk(oclk_to_iclk), .in_reset(in_reset), .out_value(ovalue_to_idata));
fnd_decoder inst_fnd_decoder(.in_data(select_data), .out_fndFont(out_fndData));
time_counter inst_time_counter(.in_clk(w_1Mhz), .in_reset(in_reset), .out_sec(w_sec), .out_ms(w_ms) ,.out_min(w_min), .out_hour(w_hour));

digit_divider inst_digit_divider(.in_sec(w_sec), .in_ms(w_ms), .in_min(w_min), .in_hour(w_hour), 
                                    .out_ms_1(w_ms_1), .out_ms_10(w_ms_10), .out_sec_1(w_sec_1), .out_sec_10(w_sec_10),
									.out_min_1(w_min_1), .out_min_10(w_min_10), .out_hour_1(w_hour_1), .out_hour_10(w_hour_10));
mux_4x1 inst_mux_4x1mssec(.in_a(w_ms_1), .in_b(w_ms_10), .in_c(w_sec_1), .in_d(w_sec_10),.in_sel(w_2bit_value),.out_y(w_ms_data));
mux_4x1 inst_mux_4x1minhour(.in_a(w_min_1), .in_b(w_min_10), .in_c(w_hour_1), .in_d(w_hour_10),.in_sel(w_2bit_value),
							.out_y(w_min_data));

clk_1khz inst_clk_1khz(.in_clk(in_clk), .in_reset(in_reset), .out_clk(w_1khz));

 //mux_2x1(.in_a, .in_b, .in_sel(in_sel),.out_y);
counter inst_2bit_counter(.in_clk(w_1khz), .in_reset(in_reset), .out_value(w_2bit_value));
dec_2x4 inst_dec_2x4(.in_sel(w_2bit_value), .out_sel(out_sel));

mux_2x1 inst_mux_2x_1(.in_sel(in_sw_sel),.in_a(w_ms_data), .in_b(w_min_data),.out_y(select_data));

endmodule

 

결과는 다음과같습니다.