counter_fnd.v
`timescale 1ns / 1ps
module counter_fnd(
input clk,
input reset,
input en,
input B1,
input B2,
output [ 7:0] fndFont,
output [ 3:0] fndCom
);
wire o_clk_100;
wire [13:0] digit_counter;
clkDiv_HERZ #(.HERZ(100)) U_clkDiv_HERZ(
.clk(clk),
.reset(reset),
.o_clk(o_clk_100)
);
upCounter #(.MAX_NUM(10000)) U_upCounter(
.clk(clk),
.reset(reset),
.tick(o_clk_100),
.en(en),
.B1(B1),
.B2(B2),
.counter(digit_counter)
);
fndController U_fndController (
.clk(clk),
.reset(reset),
.digit(digit_counter),
.fndFont(fndFont),
.fndCom(fndCom)
);
endmodule
기존의 upCounter.v, clock_upCounter.v 사용
upCounter.v
`timescale 1ns / 1ps
module clkDiv_HERZ #(
parameter HERZ = 100
) (
input clk,
input reset,
output o_clk
);
reg [$clog2(100_000_000/HERZ)-1:0] counter;
reg r_clk;
assign o_clk = r_clk;
always @(posedge clk, posedge reset) begin
if (reset) begin
counter <= 0;
r_clk <= 1'b0;
end else begin
if (counter == 100_000_000 / HERZ - 1) begin
counter <= 0;
r_clk <= 1'b1;
end else begin
counter <= counter + 1;
r_clk <= 1'b0;
end
end
end
endmodule
module upCounter #(
parameter MAX_NUM = 10000
) (
input clk, // system operation clock, 100MHz
input reset,
input tick, // time clock ex) 100hz 0.01sec
input en,
input B1, // run & stop
input B2, // stop & clear
output [$clog2(MAX_NUM)-1:0] counter
);
parameter STOP = 2'b00, RUN = 2'b01, CLEAR = 2'b10;
reg [$clog2(MAX_NUM)-1:0] counter_reg, counter_next;
reg [1:0] counter_state = STOP;
// state register
always @(posedge clk, posedge reset) begin
if (reset) begin
counter_reg <= 0;
end else begin
counter_reg <= counter_next;
end
end
always @(posedge clk, posedge B1, posedge B2) begin
if (B1) begin
if (counter_state == STOP) begin
counter_state <= RUN;
end
else if (counter_state == RUN) begin
counter_state <= STOP;
end
end
else if (B2 && (counter_state == STOP)) begin
if (counter_state == STOP) begin
counter_state <= CLEAR;
end
else if (counter_state == CLEAR) begin
counter_state <= STOP;
end
end
end
// next state combinational logic circuit
always @(*) begin
if (tick && en) begin
if (counter_reg == MAX_NUM - 1) begin
counter_next = 0;
end else if (counter_state == RUN) begin
counter_next = counter_reg + 1;
end else if (counter_state == STOP) begin
counter_next = counter_reg;
end else if (counter_state == CLEAR) begin
counter_next = 0;
end
end else begin
counter_next = counter_reg;
end
end
// output combinational logic
//always @(counter_reg) begin
// counter_state = STOP;
//end
assign counter = counter_reg;
endmodule
clock_upCounter
`timescale 1ns / 1ps
module clock_upCounter(
input clk,
input reset,
input switch,
output [7:0] fndFont,
output [ 3:0] fndCom
);
wire [7:0] fndFont_clock, fndFont_upCounter;
wire [5:0] digit_sec, digit_min;
wire [13:0] digit;
clock U_clock(
.clk(clk),
.reset(reset),
.digit_sec(digit_sec),
.digit_min(digit_min)
);
UpCounter U_UpCounter(
.clk(clk),
.reset(reset),
.digit(digit)
);
fndController U_fndController(
.clk(clk),
.reset(reset),
.switch(switch),
.digit(digit),
.digit_sec(digit_sec),
.digit_min(digit_min),
.fndFont(fndFont),
.fndCom(fndCom)
);
endmodule
module clock(
input clk,
input reset,
output[5:0] digit_sec,
output[5:0] digit_min
);
wire w_clk_1s, w_clk_s;
wire [13:0] w_count_m_digit;
wire [5:0] w_clk_60m_cal;
clkDiv #(.MAX_COUNT(100_000_000)) U_ClkDiv_1s (
.clk (clk),
.reset(reset),
.o_clk(w_clk_1s)
);
counter #(.MAX_COUNT(60)) U_Counter_s (
.clk (w_clk_1s),
.reset(reset),
.count(digit_sec),
.o_min_clk(w_clk_s)
);
counter #(.MAX_COUNT(60)) U_Counter_m (
.clk (w_clk_s),
.reset(reset),
.count(digit_min)
);
endmodule
module UpCounter(
input clk,
input reset,
output[13:0] digit
);
wire w_clk_10hz;
wire [13:0] w_count_10k;
clkDiv #(.MAX_COUNT(100_000_000)) U_ClkDiv_1Hz(
.clk(clk),
.reset(reset),
.o_clk(w_clk_10hz)
);
counter #(.MAX_COUNT(10_000)) U_Counter_10k(
.clk(w_clk_10hz),
.reset(reset),
.count(digit)
);
endmodule
fndController
`timescale 1ns / 1ps
module fndController (
input clk,
input reset,
input [13:0] digit,
output [ 7:0] fndFont,
output [ 3:0] fndCom
);
wire [3:0] w_digit_1, w_digit_10, w_digit_100, w_digit_1000;
wire [3:0] w_digit;
wire [1:0] w_count;
wire w_clk_1khz;
clkDiv #(.MAX_COUNT(100_000)) U_ClkDiv(
.clk(clk),
.reset(reset),
.o_clk(w_clk_1khz)
);
counter #(.MAX_COUNT(4)) U_Counter_2bit(
.clk(w_clk_1khz),
.reset(reset),
.count(w_count)
);
Decoder U_Decoder_2x4 (
.x(w_count),
.y(fndCom)
);
digitSplitter U_DigitSplitter (
.i_digit(digit),
.o_digit_1(w_digit_1),
.o_digit_10(w_digit_10),
.o_digit_100(w_digit_100),
.o_digit_1000(w_digit_1000)
);
Mux U_Mux (
.sel(w_count),
.x0 (w_digit_1),
.x1 (w_digit_10),
.x2 (w_digit_100),
.x3 (w_digit_1000),
.y (w_digit)
);
BCDtoSEG U_BcdToSeg0 (
.bcd(w_digit),
.seg(fndFont)
);
endmodule
module Decoder (
input [1:0] x,
output reg [3:0] y
);
always @(x) begin
case (x)
2'h0: y = 4'b1110;
2'h1: y = 4'b1101;
2'h2: y = 4'b1011;
2'h3: y = 4'b0111;
default: y = 4'b1110;
endcase
end
endmodule
module digitSplitter (
input [13:0] i_digit,
output [ 3:0] o_digit_1,
output [ 3:0] o_digit_10,
output [ 3:0] o_digit_100,
output [ 3:0] o_digit_1000
);
assign o_digit_1 = i_digit % 10;
assign o_digit_10 = i_digit / 10 % 10;
assign o_digit_100 = i_digit / 100 % 10;
assign o_digit_1000 = i_digit / 1000 % 10;
endmodule
module Mux (
input [1:0] sel,
input [3:0] x0,
input [3:0] x1,
input [3:0] x2,
input [3:0] x3,
output reg [3:0] y
);
always @(sel, x0, x1, x2, x3) begin
case (sel)
2'b00: y = x0;
2'b01: y = x1;
2'b10: y = x2;
2'b11: y = x3;
default: y = x0;
endcase
end
endmodule
module BCDtoSEG (
input [3:0] bcd,
output reg [7:0] seg
);
always @(bcd) begin
case (bcd)
4'h0: seg = 8'hc0;
4'h1: seg = 8'hf9;
4'h2: seg = 8'ha4;
4'h3: seg = 8'hb0;
4'h4: seg = 8'h99;
4'h5: seg = 8'h92;
4'h6: seg = 8'h82;
4'h7: seg = 8'hf8;
4'h8: seg = 8'h80;
4'h9: seg = 8'h90;
4'ha: seg = 8'h88;
4'hb: seg = 8'h83;
4'hc: seg = 8'hc6;
4'hd: seg = 8'ha1;
4'he: seg = 8'h86;
4'hf: seg = 8'h8e;
default: seg = 8'hff;
endcase
end
endmodule
module counter #(parameter MAX_COUNT = 4)(
input clk,
input reset,
output [$clog2(MAX_COUNT)-1:0] count
);
reg [$clog2(MAX_COUNT)-1:0] counter = 0;
assign count = counter;
always @(posedge clk, posedge reset) begin // 비동�? reset
if (reset == 1'b1) begin
counter <= 0;
end
else begin
if (counter == MAX_COUNT - 1) begin
counter <= 0;
end
else begin
counter <= counter + 1;
end
end
end
endmodule
module clkDiv #(parameter MAX_COUNT = 100)(
input clk,
input reset,
output o_clk
);
reg [$clog2(MAX_COUNT)-1:0] counter = 0;
reg r_tick = 0 ;
assign o_clk = r_tick;
always @(posedge clk, posedge reset) begin
if (reset) begin
counter <= 0;
end
else begin
if (counter == (MAX_COUNT - 1)) begin
counter <= 0;
r_tick <= 1'b1;
end
else begin
counter <= counter + 1;
r_tick <= 1'b0;
end
end
end
endmodule
schematic
constraint
## Clock signal
set_property -dict { PACKAGE_PIN W5 IOSTANDARD LVCMOS33 } [get_ports { clk }]; #IO_L12P_T1_MRCC_34 ,Sch=CLK100MHZ
create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports clk]
## Switches
set_property -dict { PACKAGE_PIN V17 IOSTANDARD LVCMOS33 } [get_ports { en }]; #IO_L19N_T3_A09_D25_VREF_14 ,Sch=SW0
##7 segment display
set_property -dict { PACKAGE_PIN W7 IOSTANDARD LVCMOS33 } [get_ports { fndFont[0] }]; #IO_L13P_T2_MRCC_34 ,Sch=CA
set_property -dict { PACKAGE_PIN W6 IOSTANDARD LVCMOS33 } [get_ports { fndFont[1] }]; #IO_L13N_T2_MRCC_34 ,Sch=CB
set_property -dict { PACKAGE_PIN U8 IOSTANDARD LVCMOS33 } [get_ports { fndFont[2] }]; #IO_L14P_T2_SRCC_34 ,Sch=CC
set_property -dict { PACKAGE_PIN U8 IOSTANDARD LVCMOS33 } [get_ports { fndFont[2] }]; #IO_L14P_T2_SRCC_34 ,Sch=CC
set_property -dict { PACKAGE_PIN V8 IOSTANDARD LVCMOS33 } [get_ports { fndFont[3] }]; #IO_L14N_T2_SRCC_34 ,Sch=CD
set_property -dict { PACKAGE_PIN U5 IOSTANDARD LVCMOS33 } [get_ports { fndFont[4] }]; #IO_L16P_T2_34 ,Sch=CE
set_property -dict { PACKAGE_PIN V5 IOSTANDARD LVCMOS33 } [get_ports { fndFont[5] }]; #IO_L16N_T2_34 ,Sch=CF
set_property -dict { PACKAGE_PIN U7 IOSTANDARD LVCMOS33 } [get_ports { fndFont[6] }]; #IO_L19P_T3_34 ,Sch=CG
set_property -dict { PACKAGE_PIN V7 IOSTANDARD LVCMOS33 } [get_ports { fndFont[7] }]; #IO_L19N_T3_VREF_34 ,Sch=DP
set_property -dict { PACKAGE_PIN U2 IOSTANDARD LVCMOS33 } [get_ports { fndCom[0] }]; #IO_L9N_T1_DQS_34 ,Sch=DP
set_property -dict { PACKAGE_PIN U4 IOSTANDARD LVCMOS33 } [get_ports { fndCom[1] }]; #IO_L11P_T1_SRCC_34 ,Sch=DP
set_property -dict { PACKAGE_PIN V4 IOSTANDARD LVCMOS33 } [get_ports { fndCom[2] }]; #IO_L11N_T1_SRCC_34 ,Sch=DP
set_property -dict { PACKAGE_PIN W4 IOSTANDARD LVCMOS33 } [get_ports { fndCom[3] }]; #IO_L12N_T1_MRCC_34 ,Sch=DP
##Buttons
set_property -dict { PACKAGE_PIN U18 IOSTANDARD LVCMOS33 } [get_ports { reset }]; #IO_L18N_T2_A11_D27_14 ,Sch=BTNC
#set_property -dict { PACKAGE_PIN T18 IOSTANDARD LVCMOS33 } [get_ports { switch }]; #IO_L17N_T2_A13_D29_14 ,Sch=BTNU
set_property -dict { PACKAGE_PIN W19 IOSTANDARD LVCMOS33 } [get_ports { B2 }]; #IO_L16N_T2_A15_D31_14 ,Sch=BTNL
set_property -dict { PACKAGE_PIN T17 IOSTANDARD LVCMOS33 } [get_ports { B1 }]; #IO_L17P_T2_A14_D30_14 ,Sch=BTNR
#set_property -dict { PACKAGE_PIN U17 IOSTANDARD LVCMOS33 } [get_ports { }]; #IO_L18P_T2_A12_D28_14 ,Sch=BTND
video
- switch를 ON하여 en 신호를 줘야 동작하는 모습니다.
- 버튼의 채터링이 잡히지 않았다. 버튼을 여러 번 눌러야 동작을 인식한다.
'[하만]세미콘 아카데미 > verilog' 카테고리의 다른 글
0516 upCounter_FSM (0) | 2024.06.22 |
---|---|
0514 upCounter_FND_FSM (0) | 2024.06.22 |
0514 assignment, FSM, button_moore_mealy (0) | 2024.06.22 |
0513 clock_upCounter (0) | 2024.06.22 |
0510 clockCounter, upCounter (0) | 2024.06.22 |