- DataPath : UpCounter & FndController
- Control Unit : Control Unit
upCounter.v
`timescale 1ns / 1ps
module upCounter (
input clk,
input reset,
input tick,
input run_stop, // B1
input clear, // B2
output [13:0] count
);
reg [13:0] counter_reg, counter_next;
assign count = counter_reg;
always @(posedge clk, posedge reset) begin
if (reset) begin
counter_reg <= 0;
end else begin
counter_reg <= counter_next;
end
end
always @(*) begin
counter_next = counter_reg;
if (tick && run_stop) begin
if (counter_reg == 9999) begin
counter_next = 0;
end else begin
counter_next = counter_reg + 1;
end
end else if (clear) begin
counter_next = 0;
end
end
endmodule
control_unit.v
`timescale 1ns / 1ps
module control_unit (
input clk,
input reset,
input btn_run_stop, // B1
input btn_clear, // B2
output run_stop,
output clear,
output led_stop,
output led_run,
output led_clear
);
parameter STOP = 2'd0, RUN = 2'd1, CLEAR = 2'd2;
reg [1:0] state, state_next;
reg run_stop_reg, run_stop_next, clear_reg, clear_next;
assign run_stop = run_stop_reg;
assign clear = clear_reg;
// state register
always @(posedge clk, posedge reset) begin
if (reset) begin
state <= STOP;
run_stop_reg <= 1'b0;
clear_reg <= 1'b0;
end else begin
state <= state_next;
run_stop_reg <= run_stop_next;
clear_reg <= clear_next;
end
end
// next state combinational logic
always @(*) begin
state_next = state;
case (state)
STOP: begin
if (btn_run_stop) state_next = RUN;
else if (btn_clear) state_next = CLEAR;
else state_next = STOP;
end
RUN: begin
if (btn_run_stop) state_next = STOP;
else state_next = RUN;
end
CLEAR: begin
state_next = STOP;
end
endcase
end
// output combinational logic
assign led_stop = (state == STOP) ? 1'b1 : 1'b0;
assign led_run = (state == RUN) ? 1'b1 : 1'b0;
assign led_clear = (state == CLEAR) ? 1'b1 : 1'b0;
always @(*) begin
run_stop_next = 1'b0;
clear_next = 1'b0;
case (state)
STOP: begin
run_stop_next = 1'b0;
end
RUN: begin
run_stop_next = 1'b1;
end
CLEAR: begin
clear_next = 1'b1;
end
endcase
end
endmodule
top.v
`timescale 1ns / 1ps
module top (
input clk,
input reset,
input btn_run_stop,
input btn_clear,
output [3:0] fndCom,
output [7:0] fndFont,
output led_stop,
output led_run,
output led_clear
);
wire w_clk_10hz;
wire w_run_stop, w_clear;
wire [13:0] w_digit;
clkDiv #(
.MAX_COUNT(10_000_000)
) U_ClkDiv_10hz (
.clk(clk),
.reset(reset),
.o_clk(w_clk_10hz)
);
upCounter U_upCounter (
.clk(clk),
.reset(reset),
.tick(w_clk_10hz),
.run_stop(w_run_stop), // B1
.clear(w_clear), // B2
.count(w_digit)
);
fndController U_fndController (
.clk(clk),
.reset(reset),
.digit(w_digit),
.fndFont(fndFont),
.fndCom(fndCom)
);
wire w_btn_run_stop, w_btn_clear;
button U_Btn_RunStop (
.clk(clk),
.in (btn_run_stop),
.out(w_btn_run_stop)
);
button U_Btn_Clear (
.clk(clk),
.in (btn_clear),
.out(w_btn_clear)
);
control_unit U_ControlUnit (
.clk(clk),
.reset(reset),
.btn_run_stop(w_btn_run_stop), // B1
.btn_clear(w_btn_clear), // B2
.run_stop(w_run_stop),
.clear(w_clear),
.led_stop(led_stop),
.led_run(led_run),
.led_clear(led_clear)
);
/*
ila_0 U_ILA (
.clk(clk), // input wire clk
.probe0(w_btn_run_stop), // input wire [0:0] probe0
.probe1(w_btn_clear), // input wire [0:0] probe1
.probe2(w_run_stop), // input wire [0:0] probe2
.probe3(w_clear), // input wire [0:0] probe3
.probe4(w_digit), // input wire [13:0] probe4
.probe5(fndCom) // input wire [3:0] probe5
);
*/
endmodule
button.v
`timescale 1ns / 1ps
module button (
input clk,
input in,
output out
);
localparam N = 8; // shift 횟수
reg [N-1 : 0] q_reg, q_next;
always @(posedge clk) begin
q_reg <= q_next;
end
// next state logic
always @(q_reg, in) begin
q_next = {in, q_reg[N-1:1]};
end
// output logic
assign out = ~(&q_reg[N-1:1]) & q_reg[0]; // 하강 edge
// assign out = (&q_reg[N-1:1] & ~q_reg[0]);
endmodule
fndController.v
`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
## LEDs
set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 } [get_ports { led_stop }]; #IO_L23N_T3_A02_D18_14 ,Sch=LED0
set_property -dict { PACKAGE_PIN E19 IOSTANDARD LVCMOS33 } [get_ports { led_run }]; #IO_L3N_T0_DQS_EMCCLK_14 ,Sch=LED1
set_property -dict { PACKAGE_PIN U19 IOSTANDARD LVCMOS33 } [get_ports { led_clear }]; #IO_L15P_T2_DQS_RDWR_B_14 ,Sch=LED2
##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 { btn_run_stop }]; #IO_L17N_T2_A13_D29_14 ,Sch=BTNU
#set_property -dict { PACKAGE_PIN W19 IOSTANDARD LVCMOS33 } [get_ports { fndSel[1] }]; #IO_L16N_T2_A15_D31_14 ,Sch=BTNL
#set_property -dict { PACKAGE_PIN T17 IOSTANDARD LVCMOS33 } [get_ports { fndSel[0] }]; #IO_L17P_T2_A14_D30_14 ,Sch=BTNR
set_property -dict { PACKAGE_PIN U17 IOSTANDARD LVCMOS33 } [get_ports { btn_clear }]; #IO_L18P_T2_A12_D28_14 ,Sch=BTND
video
- 0514 upCounter_FSM과 동작 시퀀스가 같다.
'[하만]세미콘 아카데미 > verilog' 카테고리의 다른 글
0517 uart_tx (0) | 2024.06.22 |
---|---|
0516 UART (0) | 2024.06.22 |
0514 upCounter_FND_FSM (0) | 2024.06.22 |
0514 upCounter_Fnd_moore_machine (0) | 2024.06.22 |
0514 assignment, FSM, button_moore_mealy (0) | 2024.06.22 |