이번시간에는 회로들을 연결해서 FPGA의 FND로 Timeclock을 만들어보겠습니다.
두가지를 진행하였습니다. 첫번째는 milisec, sec만 출력하기, 두번째는 스위치를 작동하여 milisec or sec를 출력하거나 min과 hour을 출력하여 보여줍니다.


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

두번쨰로 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
결과는 다음과같습니다.
'나의 전자 공부방 > FPGA' 카테고리의 다른 글
| vivado, FPGA로 Stopwatch 만들기 (0) | 2023.05.15 |
|---|---|
| vivado, FPGA로 LED right hift, LED left shift하기 (0) | 2023.05.15 |
| Vivado, FPGA로 upcounter 만들기 (0) | 2023.05.09 |
| vivado의 create block design을 사용해서 apb 만들기 (0) | 2023.04.19 |