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]);
endmodule
clock.v
`timescale 1ns / 1ps
module clock (
input clk,
input Run_Set,
input screen,
input cnt_up,
input cnt_down,
input reset,
input left_right,
input tick_msec,
input switch,
//input [7:0] rx_data,
output [6:0] digit_msec,
output [5:0] digit_sec,
output [5:0] digit_min,
output [4:0] digit_hour
);
reg [6:0] msec_reg, msec_next;
reg [5:0] sec_reg, sec_next;
reg [5:0] min_reg, min_next;
reg [4:0] hour_reg, hour_next;
//UART
// reg [7:0] rx_data_reg, rx_data_next;
// Assign outputs to registers
assign digit_msec = msec_reg;
assign digit_sec = sec_reg;
assign digit_min = min_reg;
assign digit_hour = hour_reg;
// assign rx_data = rx_data_reg;
// UART SET
integer msec, sec, min, hour;
// State register updates
always @(posedge clk or posedge reset) begin
if (reset & !switch) begin
msec_reg <= 0;
sec_reg <= 0;
min_reg <= 0;
hour_reg <= 0;
end else begin
msec_reg <= msec_next;
sec_reg <= sec_next;
min_reg <= min_next;
hour_reg <= hour_next;
end
end
// Next state logic
always @(*) begin
// Initialize next state values
msec_next = msec_reg;
sec_next = sec_reg;
min_next = min_reg;
hour_next = hour_reg;
// Run or Set mode
if (!Run_Set) begin // RUN mode
// Update counters based on ticks
if (tick_msec) begin
if (msec_reg == 99) begin
msec_next = 0;
if (sec_reg == 59) begin
sec_next = 0;
if (min_reg == 59) begin
min_next = 0;
hour_next = (hour_reg == 23) ? 0 : hour_reg + 1;
end else min_next = min_reg + 1;
end else sec_next = sec_reg + 1;
end else msec_next = msec_reg + 1;
end
// Repeat similar logic for sec, min, hour updates
end else begin // SET mode
// Handle increment and decrement of counters based on control signals
if (!switch & cnt_up) begin
if (screen) begin // Adjust seconds or milliseconds
msec_next = (left_right) ? msec_reg + 1 : msec_reg;
sec_next = (!left_right) ? sec_reg + 1 : sec_reg;
if (msec_reg == 100) begin
msec_next = 0;
end else if (sec_reg == 60) begin
sec_next = 0;
end
end else begin // Adjust minutes or hours
min_next = (left_right) ? min_reg + 1 : min_reg;
hour_next = (!left_right) ? hour_reg + 1 : hour_reg;
if (min_reg == 60) begin
min_next = 0;
end else if (hour_reg == 23) begin
hour_next = 0;
end
end
end else if (!switch & cnt_down) begin
if (screen) begin // Adjust seconds or milliseconds
msec_next = (left_right) ? msec_reg - 1 : msec_reg;
sec_next = (!left_right) ? sec_reg - 1 : sec_reg;
if (msec_reg == 0) begin
msec_next = 99;
end else if (sec_reg == 0) begin
sec_next = 59;
end
end else begin // Adjust minutes or hours
min_next = (left_right) ? min_reg - 1 : min_reg;
hour_next = (!left_right) ? hour_reg - 1 : hour_reg;
if (min_reg == 0) begin
min_next = 59;
end else if (hour_reg == 0) begin
hour_next = 23;
end
end
end
end
end
endmodule
led.v
`timescale 1ns / 1ps
module led(
input clk,
input reset,
input led_in,
output led_out
);
localparam LED_OFF = 1'b0 , LED_ON = 1'b1;
reg state, state_next;
reg led_out_reg, led_out_next;
assign led_out = led_out_reg;
always @(posedge clk, posedge reset) begin
if(reset) begin
state <= LED_OFF;
led_out_reg <= 1'b0;
end else begin
state <= state_next;
led_out_reg <= led_out_next;
end
end
always @(*) begin
case (state)
LED_OFF: begin
if(led_in) state_next = LED_ON;
else state_next = LED_OFF;
end
LED_ON: begin
if(!led_in) state_next = LED_OFF;
else state_next = LED_ON;
end
endcase
end
always @(*) begin
case (state)
LED_OFF: begin
led_out_next = 1'b0;
end
LED_ON: begin
led_out_next = 1'b1;
end
endcase
end
endmodule
counter.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 tick, // time clock ex) 100hz 0.01sec
input reset,
input en,
input switch,
output [$clog2(MAX_NUM)-1:0] counter,
input [7:0] rx_data
);
// reg [7:0] rx_data_reg, rx_data_next;
reg [$clog2(MAX_NUM)-1:0] counter_reg, counter_next;
// assign rx_data = rx_data_reg;
// state register
always @(posedge clk, posedge reset) begin
if ((reset & switch)) begin
counter_reg <= 0;
end else begin
counter_reg <= counter_next;
end
end
// next state combinational logic circuit
always @(*) begin
if ((en && tick)) begin // durl
if (counter_reg == MAX_NUM - 1) begin
counter_next = 0;
end else begin
counter_next = counter_reg + 1;
end
end else begin
counter_next = counter_reg;
end
end
// output combinational logic
assign counter = counter_reg;
endmodule
fndController.v
`timescale 1ns / 1ps
module fndController (
input clk,
input reset,
input switch,
input screen,
input [13:0] digit,
input [ 6:0] digit_msec,
input [ 5:0] digit_sec,
input [ 5:0] digit_min,
input [ 4:0] digit_hour,
output [7:0] fndFont,
output [3:0] fndCom
);
wire [3:0] w_digit_1_sclock, w_digit_10_sclock, w_digit_100_sclock, w_digit_1000_sclock;
wire [3:0] w_digit_1_mclock, w_digit_10_mclock, w_digit_100_mclock, w_digit_1000_mclock;
wire [3:0] w_digit_1_counter, w_digit_10_counter, w_digit_100_counter, w_digit_1000_counter;
wire [3:0] w_digit_sclock, w_digit_mclock, w_digit_clock, w_digit_counter, w_digit;
wire [3:0] w_digit_dp_clock, w_digit_dp_counter;
wire [2: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(5)
) 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_msec(digit_msec),
.i_digit_sec(digit_sec),
.i_digit_min(digit_min),
.i_digit_hour(digit_hour),
.i_digit(digit),
.o_digit_1_sclock(w_digit_1_sclock),
.o_digit_10_sclock(w_digit_10_sclock),
.o_digit_100_sclock(w_digit_100_sclock),
.o_digit_1000_sclock(w_digit_1000_sclock),
.o_digit_1_mclock(w_digit_1_mclock),
.o_digit_10_mclock(w_digit_10_mclock),
.o_digit_100_mclock(w_digit_100_mclock),
.o_digit_1000_mclock(w_digit_1000_mclock),
.o_digit_1_counter(w_digit_1_counter),
.o_digit_10_counter(w_digit_10_counter),
.o_digit_100_counter(w_digit_100_counter),
.o_digit_1000_counter(w_digit_1000_counter),
.o_digit_dp_clock(w_digit_dp_clock),
.o_digit_dp_counter(w_digit_dp_counter)
);
Mux_5x1 U_Mux_sclock (
.sel(w_count),
.x0 (w_digit_1_sclock),
.x1 (w_digit_10_sclock),
.x2 (w_digit_100_sclock),
.x3 (w_digit_1000_sclock),
.x4 (w_digit_dp_clock),
.y (w_digit_sclock)
);
Mux_5x1 U_Mux_mclock (
.sel(w_count),
.x0 (w_digit_1_mclock),
.x1 (w_digit_10_mclock),
.x2 (w_digit_100_mclock),
.x3 (w_digit_1000_mclock),
.x4 (w_digit_dp_clock),
.y (w_digit_mclock)
);
Mux_2x1 U_Mux_Clock (
.sel(screen),
.x0 (w_digit_mclock),
.x1 (w_digit_sclock),
.y (w_digit_clock)
);
Mux_5x1 U_Mux_counter (
.sel(w_count),
.x0 (w_digit_1_counter),
.x1 (w_digit_10_counter),
.x2 (w_digit_100_counter),
.x3 (w_digit_1000_counter),
.x4 (w_digit_dp_counter),
.y (w_digit_counter)
);
Mux_2x1 U_Mux_Mode (
.sel(switch),
.x0 (w_digit_clock),
.x1 (w_digit_counter),
.y (w_digit)
);
BCDtoSEG U_BcdToSeg (
.bcd(w_digit),
.seg(fndFont)
);
endmodule
module Decoder (
input [2: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'b1011;
endcase
end
endmodule
module digitSplitter (
input [ 6:0] i_digit_msec,
input [ 5:0] i_digit_sec,
input [ 5:0] i_digit_min,
input [ 4:0] i_digit_hour,
input [13:0] i_digit,
output [3:0] o_digit_1_sclock,
output [3:0] o_digit_10_sclock,
output [3:0] o_digit_100_sclock,
output [3:0] o_digit_1000_sclock,
output [3:0] o_digit_1_mclock,
output [3:0] o_digit_10_mclock,
output [3:0] o_digit_100_mclock,
output [3:0] o_digit_1000_mclock,
output [3:0] o_digit_1_counter,
output [3:0] o_digit_10_counter,
output [3:0] o_digit_100_counter,
output [3:0] o_digit_1000_counter,
output [3:0] o_digit_dp_clock,
output [3:0] o_digit_dp_counter
);
assign o_digit_1_sclock = i_digit_msec % 10;
assign o_digit_10_sclock = i_digit_msec / 10 % 10;
assign o_digit_100_sclock = i_digit_sec % 10;
assign o_digit_1000_sclock = i_digit_sec / 10 % 10;
assign o_digit_1_mclock = i_digit_min % 10;
assign o_digit_10_mclock = i_digit_min / 10 % 10;
assign o_digit_100_mclock = i_digit_hour % 10;
assign o_digit_1000_mclock = i_digit_hour / 10 % 10;
assign o_digit_1_counter = i_digit % 10;
assign o_digit_10_counter = i_digit / 10 % 10;
assign o_digit_100_counter = i_digit / 100 % 10;
assign o_digit_1000_counter = i_digit / 1000 % 10;
assign o_digit_dp_clock = 4'ha;
assign o_digit_dp_counter = 4'hb;
endmodule
module Mux_4x1 (
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'h7F; // a : dp
4'hb: seg = 8'hFF; // everything not display
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,
output o_min_clk
);
reg [$clog2(MAX_COUNT)-1:0] counter = 0;
assign count = counter;
reg r_tick_1 = 0;
assign o_min_clk = r_tick_1;
always @(posedge clk, posedge reset) begin
if (reset == 1'b1) begin
counter <= 0;
end else begin
if (counter == MAX_COUNT - 1) begin
counter <= 0;
r_tick_1 <= 1'b1;
end else begin
counter <= counter + 1;
r_tick_1 <= 1'b0;
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
module Mux_2x1 (
input sel,
input [3:0] x0,
input [3:0] x1,
output reg [3:0] y
);
always @(sel, x0, x1) begin
case (sel)
1'b0: y = x0;
1'b1: y = x1;
default: y = x0;
endcase
end
endmodule
module Mux_5x1 (
input [2:0] sel,
input [3:0] x0,
input [3:0] x1,
input [3:0] x2,
input [3:0] x3,
input [3:0] x4,
output reg [3:0] y
);
always @(sel, x0, x1, x2, x3, x4) begin
case (sel)
3'h0: y = x0;
3'h1: y = x1;
3'h2: y = x2;
3'h3: y = x3;
3'h4: y = x4;
default: y = x0;
endcase
end
endmodule
counter_clock_fnd.v
`timescale 1ns / 1ps
module counter_fnd(
input clk,
input reset,
input switch,
input B1,
input B2,
input B3,
input B4,
// UART
input rx,
output tx,
output [ 7:0] fndFont,
output [ 3:0] fndCom,
// output [6:0] w_digit_msecq,
// output [5:0] w_digit_secq,
// output [5:0] w_digit_minq,
// output [4:0] w_digit_hourq
output led_run,
output led_stop,
output led_clear,
output led_setting,
output led_hm,
output led_smsec,
output led_upcounter1,
output led_clock1,
output led_upcounter2,
output led_clock2,
output led_upcounter3,
output led_clock3
);
wire o_clk_10, reset_counter, en_counter;
wire B1_out, B2_out, B3_out, B4_out;
wire w_rs, w_screen, w_cnt_up, w_cnt_down, w_reset_clock, w_reset_upCounter, w_lr;
wire w_clk_ms, w_clk_s, w_clk_m, w_clk_h;
wire w_led_run, w_led_stop, w_led_setting, w_led_clear, w_led_hm, w_led_smsec;
wire [13:0] digit_counter;
wire [6:0] w_digit_msec;
wire [5:0] w_digit_sec, w_digit_min;
wire [4:0] w_digit_hour;
// UART
wire [7:0] w_rx_data;
wire w_rx_empty;
// wire w_tx;
// assign w_digit_msecq = w_digit_msec;
// assign w_digit_msecq = w_digit_sec;
// assign w_digit_msecq = w_digit_min;
// assign w_digit_msecq = w_digit_hour;
// assign tx = w_tx;
// uart_fifo U_UART_FIFO(
// .clk(clk),
// .reset(reset),
// .tx(tx),
// .tx_en(~w_rx_empty),
// .tx_data(w_rx_data),
// .tx_full(),
// .rx(rx),
// .rx_en(~w_rx_empty),
// .rx_data(w_rx_data),
// .rx_empty(w_rx_empty)
// );
uart_fifo U_UART_FIFO(
.clk(clk),
.reset(reset),
.tx(tx),
.tx_en(~w_rx_empty),
.tx_data(w_rx_data),
.tx_full(),
.rx(rx),
.rx_en(~w_rx_empty),
.rx_data(w_rx_data),
.rx_empty(w_rx_empty)
);
button U_button1(
.clk(clk),
.in(B1),
.out(B1_out)
);
button U_button2(
.clk(clk),
.in(B2),
.out(B2_out)
);
button U_button3(
.clk(clk),
.in(B3),
.out(B3_out)
);
button U_button4(
.clk(clk),
.in(B4),
.out(B4_out)
);
Control_Unit U_Control_Unit(
.clk(clk),
.reset_in(reset),
.switch(switch),
// Button
.B1(B1_out),
.B2(B2_out),
.B3(B3_out),
.B4(B4_out),
// clock_FSM
.Run_Set(w_rs),
.cnt_up(w_cnt_up),
.cnt_down(w_cnt_down),
.left_right(w_lr),
.reset_out_clock(w_reset_clock),
.screen(w_screen),
// upCounter_FSM
.en(en_counter),
.reset_out_upCounter(w_reset_upCounter),
// clkDiv_HERZ
.o_clk_10(o_clk_10),
// UART
.rx_data(w_rx_data),
// LEFT led
//output led_upcounter,
.led_run(w_led_run),
.led_stop(w_led_stop),
.led_clear(w_led_clear),
// Right led
//output led_clock,
.led_setting(w_led_setting),
.led_hm(w_led_hm),
.led_smsec(w_led_smsec)
);
led U_led_clock1(
.clk(clk),
.reset(reset),
.led_in(!switch),
.led_out(led_clock1)
);
led U_led_clock2(
.clk(clk),
.reset(reset),
.led_in(!switch),
.led_out(led_clock2)
);
led U_led_clock3(
.clk(clk),
.reset(reset),
.led_in(!switch),
.led_out(led_clock3)
);
led U_led_upcounter1(
.clk(clk),
.reset(reset),
.led_in(switch),
.led_out(led_upcounter1)
);
led U_led_upcounter2(
.clk(clk),
.reset(reset),
.led_in(switch),
.led_out(led_upcounter2)
);
led U_led_upcounter3(
.clk(clk),
.reset(reset),
.led_in(switch),
.led_out(led_upcounter3)
);
led U_led_run(
.clk(clk),
.reset(reset),
.led_in(w_led_run),
.led_out(led_run)
);
led U_led_stop(
.clk(clk),
.reset(reset),
.led_in(w_led_stop),
.led_out(led_stop)
);
led U_led_clear(
.clk(clk),
.reset(reset),
.led_in(w_led_clear),
.led_out(led_clear)
);
led U_led_HM(
.clk(clk),
.reset(reset),
.led_in(w_led_hm),
.led_out(led_hm)
);
led U_led_SMEC(
.clk(clk),
.reset(reset),
.led_in(w_led_smsec),
.led_out(led_smsec)
);
led U_led_Setting(
.clk(clk),
.reset(reset),
.led_in(w_led_setting),
.led_out(led_setting)
);
upCounter #(.MAX_NUM(10000)) U_upCounter(
.clk(clk),
.tick(o_clk_10),
.reset(w_reset_upCounter),
.switch(switch),
.en(en_counter),
.counter(digit_counter),
.rx_data(w_rx_data)
);
clock U_clock(
.clk(clk),
.switch(switch),
.Run_Set(w_rs),
.screen(w_screen),
.cnt_up(w_cnt_up),
.cnt_down(w_cnt_down),
.reset(w_reset_clock),
.left_right(w_lr),
.tick_msec(o_clk_10),
// .tick_sec(w_clk_s),
// .tick_min(w_clk_m),
// .tick_hour(w_clk_h),
.digit_msec(w_digit_msec),
.digit_sec(w_digit_sec),
.digit_min(w_digit_min),
.digit_hour(w_digit_hour)
// .rx_data(w_rx_data)
);
fndController U_fndController(
.clk(clk),
.reset(reset),
.switch(switch),
.screen(w_screen),
.digit(digit_counter),
.digit_msec(w_digit_msec),
.digit_sec(w_digit_sec),
.digit_min(w_digit_min),
.digit_hour(w_digit_hour),
.fndFont(fndFont),
.fndCom(fndCom)
);
endmodule
control_unit.v
`timescale 1ns / 1ps
module Control_Unit (
input clk,
input reset_in,
input switch,
// Button
input B1,
input B2,
input B3,
input B4,
// UART
input [7:0] rx_data,
// clock_FSM
output Run_Set,
output cnt_up,
output cnt_down,
output left_right,
output reset_out_clock,
output screen,
// upCounter_FSM
output en,
output reset_out_upCounter,
// clkDiv_HERZ
output o_clk_10,
// LEFT led
//output led_upcounter,
output led_run,
output led_stop,
output led_clear,
// Right led
//output led_clock,
output led_setting,
output led_hm,
output led_smsec
);
wire [7:0] w_rx_data;
//assign rx_data = w_rx_data;
clkDiv_HERZ #(.HERZ(100)) U_clkDiv_HERZ(
.clk(clk),
.reset(reset_in),
.o_clk(o_clk_10)
);
upCounter_FSM U_upCounter_FSM(
.clk(clk),
.reset_in(reset_in),
.switch(switch),
.B1(B1),
.B2(B2),
.reset_out(reset_out_upCounter),
.en(en),
.rx_data(rx_data),
// LEFT led
//output reg led_upcounter,
.led_run(led_run),
.led_stop(led_stop),
.led_clear(led_clear)
);
clock_FSM U_clock_FSM(
.clk(clk),
.reset_in(reset_in),
.switch(switch),
.B1(B1), // RUN & SETTING
.B2(B2), // (hour:min) & (sec & ms)
.B3(B3), // fndFont UP in Setting
.B4(B4), // fndFont DOWN in Setting
.Run_Set(Run_Set), // RUN & SETTING
.screen(screen), // (hour:min) & (sec & ms)
.cnt_up(cnt_up), // fndFont UP in Setting
.cnt_down(cnt_down), // fndFont DOWN in Setting
.reset_out(reset_out_clock), // fndFont reset
.left_right(left_right), // change left & right in Setting
.rx_data(rx_data),
// Right led
//output led_clock,
.led_setting(led_setting),
.led_hm(led_hm),
.led_smsec(led_smsec)
);
endmodule
module upCounter_FSM (
input clk,
input reset_in,
input switch,
input B1,
input B2,
// UART
input [7:0] rx_data,
output reg reset_out,
output reg en,
// LEFT led
//output reg led_upcounter,
output reg led_run,
output reg led_stop,
output reg led_clear
);
reg [1:0] counter_state, counter_next_state;
// reg [7:0] rx_data_reg, rx_data_next;
// assign rx_data = rx_data_reg;
parameter STOP = 2'b00, RUN = 2'b01, CLEAR = 2'b10;
// state register
always @(posedge clk, posedge reset_in) begin
if (reset_in & switch) begin
counter_state <= CLEAR;
end else begin
counter_state <= counter_next_state;
end
end
// next state combinational logic circuit
always @(*) begin
counter_next_state = counter_state; // 없으면 latch 생김
case (counter_state)
STOP: begin
if ((B1 & switch) || (rx_data == "run")) begin
//rx_data_reg = 5;
counter_next_state = RUN;
end else if ((B2 & switch)|| (rx_data == "clear") ) begin
counter_next_state = CLEAR;
end else counter_next_state = counter_state;
end
RUN: begin
if ((B1 & switch) || (rx_data == "stop")) begin
counter_next_state = STOP;
end else counter_next_state = counter_state;
end
CLEAR: begin
counter_next_state = STOP;
end
endcase
end
// output combinational logic
always @(*) begin
en = 1'b0;
reset_out = 1'b0;
case (counter_state)
STOP: begin
en = 1'b0;
reset_out = 1'b0;
led_run = 1'b0;
led_stop = 1'b1;
led_clear = 1'b0;
end
RUN: begin
en = 1'b1;
reset_out = 1'b0;
led_run = 1'b1;
led_stop = 1'b0;
led_clear = 1'b0;
end
CLEAR: begin
en = 1'b0;
reset_out = 1'b1;
led_run = 1'b0;
led_stop = 1'b0;
led_clear = 1'b1;
end
endcase
end
endmodule
module clock_FSM (
input clk,
input reset_in,
input switch,
input B1, // RUN & SETTING
input B2, // (hour:min) & (sec & ms)
input B3, // fndFont UP in Setting
input B4, // fndFont DOWN in Setting
// UART
input [7:0] rx_data,
output Run_Set, // RUN & SETTING
output screen, // (hour:min) & (sec & ms)
output cnt_up, // fndFont UP in Setting
output cnt_down, // fndFont DOWN in Setting
output reset_out, // fndFont reset
output left_right, // change left & right in Setting
// Right led
//output led_clock,
output reg led_setting,
output reg led_hm,
output reg led_smsec
);
reg clock_state, clock_next_state; // Run_Setting
reg screen_state, screen_next_state; // (hour:min) & (sec & ms)
reg up_state, up_next_state; // fndFont UP in Setting
reg down_state, down_next_state; // fndFont DOWN in Setting
reg reset_state, reset_next_state; // fndFont reset
reg lr_state, lr_next_state; // screen left & right
//reg rx_data_next, rx_data_reg; // UART
parameter RUN = 1'b0, SETTING = 1'b1;
parameter HOUR_MIN = 1'b0, SEC_MS = 1'b1;
parameter LEFT = 1'b0, RIGHT = 1'b1;
// output
assign Run_Set = clock_state;
assign screen = screen_state;
assign cnt_up = up_state;
assign cnt_down = down_state;
assign reset_out = reset_state;
assign left_right = lr_state;
// UART
//assign rx_data = rx_data_reg;
// state register
always @(posedge clk, posedge reset_in) begin
if (reset_in & !switch) begin
clock_state <= RUN;
screen_state <= HOUR_MIN;
up_state <= 1'b0;
down_state <= 1'b0;
reset_state <= 1'b1;
lr_state <= LEFT;
end else begin
clock_state <= clock_next_state;
screen_state <= screen_next_state;
up_state <= up_next_state;
down_state <= down_next_state;
reset_state <= 1'b0;
lr_state <= lr_next_state;
end
end
// next state combinational logic circuit
always @(*) begin
clock_next_state = clock_state;
screen_next_state = screen_state;
up_next_state = up_state;
down_next_state = down_state;
lr_next_state = lr_state;
case (clock_state)
RUN: begin
if ((B1 & !switch) || (rx_data == "t")) begin
clock_next_state = SETTING;
end
else begin
clock_next_state = clock_state;
case (screen_state)
HOUR_MIN: begin
led_hm = 1'b1;
led_smsec = 1'b0;
led_setting = 1'b0;
if ((B2 & !switch) || (rx_data == "m")) begin
screen_next_state = SEC_MS;
end
else begin
screen_next_state = screen_state;
end
end
SEC_MS: begin
led_hm = 1'b0;
led_smsec = 1'b1;
led_setting = 1'b0;
if ((B2 & !switch) || (rx_data == "h")) begin
screen_next_state = HOUR_MIN;
end
else begin
screen_next_state = screen_state;
end
end
endcase
end
end
SETTING: begin
led_setting = 1'b1;
led_hm = 1'b0;
led_smsec = 1'b0;
if ((B1 & !switch) || (rx_data == "t")) begin
clock_next_state = RUN;
end
else begin
clock_next_state = clock_state;
case (lr_state)
LEFT: begin
if ((B2&!switch) || (rx_data == "w")) begin
lr_next_state = RIGHT;
end
else begin
lr_next_state = lr_state;
end
end
RIGHT: begin
if ((B2&!switch) || (rx_data == "w")) begin
lr_next_state = LEFT;
end
else begin
lr_next_state = lr_state;
end
end
endcase
if ((B3&!switch) || (rx_data == "u")) begin
up_next_state = 1'b1;
end
else if ((B4&!switch) || (rx_data == "d")) begin
down_next_state = 1'b1;
end
else begin
up_next_state = 1'b0;
down_next_state = 1'b0;
end
end
end
endcase
end
endmodule
fifo.v
`timescale 1ns / 1ps
module fifo #(
parameter ADDR_WIDTH = 3,
DATA_WIDTH = 8
) (
input clk,
input reset,
input wr_en,
output full,
input [DATA_WIDTH - 1:0] wdata,
input rd_en,
output [DATA_WIDTH - 1:0] rdata,
output empty
);
wire [ADDR_WIDTH-1:0] w_waddr, w_raddr;
register_file #(
.ADDR_WIDTH(ADDR_WIDTH),
.DATA_WIDTH(DATA_WIDTH)
) U_RegFile (
.clk (clk),
.wr_en(wr_en & ~full),
.waddr(w_waddr),
.wdata(wdata),
.raddr(w_raddr),
.rdata(rdata)
);
fifo_control_unit #(
.ADDR_WIDTH(ADDR_WIDTH)
) U_FIFO_CU (
.clk (clk),
.reset(reset),
// write
.wr_en(wr_en),
.full (full),
.waddr(w_waddr),
// read
.rd_en(rd_en),
.empty(empty),
.raddr(w_raddr)
);
endmodule
module register_file #(
parameter ADDR_WIDTH = 3,
DATA_WIDTH = 8
) (
input clk,
input wr_en,
input [ADDR_WIDTH - 1:0] waddr,
input [DATA_WIDTH - 1:0] wdata,
input [ADDR_WIDTH - 1:0] raddr,
output [DATA_WIDTH - 1:0] rdata
);
reg [DATA_WIDTH-1:0] mem[0:2**ADDR_WIDTH-1];
always @(posedge clk) begin
if (wr_en) mem[waddr] <= wdata;
end
assign rdata = mem[raddr];
endmodule
module fifo_control_unit #(
parameter ADDR_WIDTH = 3
) (
input clk,
input reset,
// write
input wr_en,
output full,
output [ADDR_WIDTH-1:0] waddr,
// read
input rd_en,
output empty,
output [ADDR_WIDTH-1:0] raddr
);
reg [ADDR_WIDTH-1:0] wr_ptr_reg, wr_ptr_next;
reg [ADDR_WIDTH-1:0] rd_ptr_reg, rd_ptr_next;
reg full_reg, full_next, empty_reg, empty_next;
assign waddr = wr_ptr_reg;
assign raddr = rd_ptr_reg;
assign full = full_reg;
assign empty = empty_reg;
always @(posedge clk, posedge reset) begin
if (reset) begin
wr_ptr_reg <= 0;
rd_ptr_reg <= 0;
full_reg <= 1'b0;
empty_reg <= 1'b1;
end else begin
wr_ptr_reg <= wr_ptr_next;
rd_ptr_reg <= rd_ptr_next;
full_reg <= full_next;
empty_reg <= empty_next;
end
end
always @(*) begin
wr_ptr_next = wr_ptr_reg;
rd_ptr_next = rd_ptr_reg;
full_next = full_reg;
empty_next = empty_reg;
case ({
wr_en, rd_en
})
2'b01: begin // read
if (!empty_reg) begin
full_next = 1'b0;
rd_ptr_next = rd_ptr_reg + 1;
if (rd_ptr_next == wr_ptr_reg) begin
empty_next = 1'b1;
end
end
end
2'b10: begin // write
if (!full_reg) begin
empty_next = 1'b0;
wr_ptr_next = wr_ptr_reg + 1;
if (wr_ptr_next == rd_ptr_reg) begin
full_next = 1'b1;
end
end
end
2'b11: begin // write, read
if (empty_reg) begin
wr_ptr_next = wr_ptr_reg;
rd_ptr_next = rd_ptr_reg;
end else begin
wr_ptr_next = wr_ptr_reg + 1;
rd_ptr_next = rd_ptr_reg + 1;
end
end
endcase
end
endmodule
top_loop_test.v
`timescale 1ns / 1ps
module top_loop_test(
input clk,
input reset,
input rx,
output tx
);
wire w_rx_empty;
wire [7:0] w_rx_data;
uart_fifo U_UART_FIFO(
.clk(clk),
.reset(reset),
.tx(tx),
.tx_en(~w_rx_empty),
.tx_data(w_rx_data),
.tx_full(),
.rx(rx),
.rx_en(~w_rx_empty),
.rx_data(w_rx_data),
.rx_empty(w_rx_empty)
);
endmodule
uart.v
`timescale 1ns / 1ps
module uart ( // PC
input clk,
input reset,
// Transmitter
output tx,
input start,
input [7:0] tx_data,
output tx_done,
// Receiver
input rx,
output [7:0] rx_data,
output rx_done
);
wire w_br_tick;
wire [7:0] w_rx_data;
baudrate_generator U_BAUDRATE_GEN (
.clk(clk),
.reset(reset),
.br_tick(w_br_tick)
);
transmitter U_Transmitter (
.clk(clk),
.reset(reset),
.br_tick(w_br_tick),
.start(start),
.tx_data(tx_data),
.tx(tx),
.tx_done(tx_done)
);
receiver U_Receiver (
.clk(clk),
.reset(reset),
.br_tick(w_br_tick),
.rx(rx),
.rx_data(rx_data),
.rx_done(rx_done)
);
endmodule
module baudrate_generator (
input clk,
input reset,
output br_tick
);
// 16 bit sampling -> baudrate 16 times
reg [$clog2(100_000_000 / 9600 / 16)-1 : 0] counter_reg, counter_next;
reg tick_reg, tick_next;
assign br_tick = tick_reg;
always @(posedge clk, posedge reset) begin
if (reset) begin
counter_reg <= 0;
tick_reg <= 1'b0;
end else begin
counter_reg <= counter_next;
tick_reg <= tick_next;
end
end
always @(*) begin
counter_next = counter_reg;
if (counter_reg == 100_000_000 / 9600 / 16 - 1) begin
//if (counter_reg == 3) begin // for simulation
counter_next = 0;
tick_next = 1'b1;
end else begin
counter_next = counter_reg + 1;
tick_next = 1'b0;
end
end
endmodule
module transmitter (
input clk,
input reset,
input br_tick,
input start,
input [7:0] tx_data,
output tx,
output tx_done
);
localparam IDLE = 0, START = 1, DATA = 2, STOP = 3;
reg [1:0] state, state_next;
reg tx_reg, tx_next;
reg tx_done_reg, tx_done_next;
reg [7:0] data_tmp_reg, data_tmp_next;
reg [3:0] br_cnt_reg, br_cnt_next;
reg [2:0] data_bit_cnt_reg, data_bit_cnt_next;
assign tx = tx_reg;
assign tx_done = tx_done_reg;
always @(posedge clk, posedge reset) begin
if (reset) begin
state <= IDLE;
tx_reg <= 1'b0;
br_cnt_reg <= 0;
data_bit_cnt_reg <= 0;
data_tmp_reg <= 0;
//tx_done_reg <= 1'b0;
end else begin
state <= state_next;
tx_reg <= tx_next;
br_cnt_reg <= br_cnt_next;
data_bit_cnt_reg <= data_bit_cnt_next;
data_tmp_reg <= data_tmp_next;
//tx_done_reg <= tx_done_next;
end
end
always @(*) begin
state_next = state;
data_tmp_next = data_tmp_reg;
tx_next = tx_reg;
br_cnt_next = br_cnt_reg;
data_bit_cnt_next = data_bit_cnt_reg;
//tx_done_next = tx_done_reg;
case (state)
IDLE: begin
tx_done_reg = 1'b0;
tx_next = 1'b1;
if (start) begin
state_next = START;
data_tmp_next = tx_data;
br_cnt_next = 0; // baud rate 16bit sampling
data_bit_cnt_next = 0;
end
end
START: begin
tx_next = 1'b0;
if (br_tick) begin
if (br_cnt_reg == 15) begin
state_next = DATA;
br_cnt_next = 0;
end else begin
br_cnt_next = br_cnt_reg + 1;
end
end
end
DATA: begin
tx_next = data_tmp_reg[0];
if (br_tick) begin
if (br_cnt_reg == 15) begin
if (data_bit_cnt_reg == 7) begin
state_next = STOP;
br_cnt_next = 0;
end else begin
data_bit_cnt_next = data_bit_cnt_reg + 1;
data_tmp_next = {1'b0, data_tmp_reg[7:1]};
br_cnt_next = 0;
end
end else begin
br_cnt_next = br_cnt_reg + 1;
end
end
end
STOP: begin
tx_next = 1'b1;
if (br_tick) begin
if (br_cnt_reg == 15) begin
tx_done_reg = 1'b1;
state_next = IDLE;
end else begin
br_cnt_next = br_cnt_reg + 1;
end
end
end
endcase
end
endmodule
module receiver (
input clk,
input reset,
input br_tick,
input rx,
output [7:0] rx_data,
output rx_done
);
localparam IDLE = 0, START = 1, DATA = 2, STOP = 3;
reg [1:0] state, state_next;
reg [7:0] rx_data_reg, rx_data_next;
reg rx_done_reg, rx_done_next;
reg [3:0] br_cnt_reg, br_cnt_next;
reg [2:0] data_bit_cnt_reg, data_bit_cnt_next;
assign rx_data = rx_data_reg;
assign rx_done = rx_done_reg;
always @(posedge clk, posedge reset) begin
if (reset) begin
state <= IDLE;
rx_data_reg <= 0;
rx_done_reg <= 1'b0;
br_cnt_reg <= 0;
data_bit_cnt_reg <= 0;
end else begin
state <= state_next;
rx_data_reg <= rx_data_next;
rx_done_reg <= rx_done_next;
br_cnt_reg <= br_cnt_next;
data_bit_cnt_reg <= data_bit_cnt_next;
end
end
always @(*) begin
state_next = state;
br_cnt_next = br_cnt_reg;
data_bit_cnt_next = data_bit_cnt_reg;
rx_data_next = rx_data_reg;
rx_done_next = rx_done_reg;
case (state)
IDLE: begin
rx_done_next = 1'b0;
if (rx == 1'b0) begin
br_cnt_next = 0;
data_bit_cnt_next = 0;
rx_data_next = 0;
state_next = START;
end
end
START: begin
if (br_tick) begin
if (br_cnt_reg == 7) begin
br_cnt_next = 0;
state_next = DATA;
end else begin
br_cnt_next = br_cnt_reg + 1;
end
end
end
DATA: begin
if (br_tick) begin
if (br_cnt_reg == 15) begin
br_cnt_next = 0;
rx_data_next = {rx, rx_data_reg[7:1]};
if (data_bit_cnt_reg == 7) begin
state_next = STOP;
br_cnt_next = 0;
end else begin
data_bit_cnt_next = data_bit_cnt_reg + 1;
end
end else begin
br_cnt_next = br_cnt_reg + 1;
end
end
end
STOP: begin
if (br_tick) begin
if (br_cnt_reg == 15) begin
br_cnt_next = 0;
rx_done_next = 1'b1;
state_next = IDLE;
end else begin
br_cnt_next = br_cnt_reg + 1;
end
end
end
endcase
end
endmodule
uart.fifo.v
`timescale 1ns / 1ps
module uart_fifo (
input clk,
input reset,
output tx,
input tx_en,
input [7:0] tx_data,
output tx_full,
output rx,
output [7:0] rx_data,
input rx_en,
output rx_empty
);
wire w_tx_fifo_empty, w_tx_done, w_rx_done;
wire [7:0] w_tx_fifo_rdata, w_rx_data;
//assign rx_data = w_rx_data;
uart U_UART (
.clk(clk),
.reset(reset),
.tx(tx),
.start(~w_tx_fifo_empty),
.tx_data(w_tx_fifo_rdata),
.tx_done(w_tx_done),
.rx(rx),
.rx_data(w_rx_data),
.rx_done(w_rx_done)
);
fifo #(
.ADDR_WIDTH(3),
.DATA_WIDTH(8)
) U_Tx_FIFO (
.clk (clk),
.reset(reset),
.wr_en(tx_en),
.full (tx_full),
.wdata(tx_data),
.rd_en(w_tx_done),
.empty(w_tx_fifo_empty),
.rdata(w_tx_fifo_rdata)
);
fifo #(
.ADDR_WIDTH(3),
.DATA_WIDTH(8)
) U_Rx_FIFO (
.clk (clk),
.reset(reset),
.wr_en(w_rx_done),
.full (),
.wdata(w_rx_data),
.rd_en(rx_en),
.empty(rx_empty),
.rdata(rx_data)
);
endmodule
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 { switch }]; #IO_L19N_T3_A09_D25_VREF_14 ,Sch=SW0
## LEDs
set_property -dict { PACKAGE_PIN U16 IOSTANDARD LVCMOS33 } [get_ports { led_clock1 }]; #IO_L23N_T3_A02_D18_14 ,Sch=LED0
set_property -dict { PACKAGE_PIN E19 IOSTANDARD LVCMOS33 } [get_ports { led_clock2 }]; #IO_L3N_T0_DQS_EMCCLK_14 ,Sch=LED1
set_property -dict { PACKAGE_PIN U19 IOSTANDARD LVCMOS33 } [get_ports { led_clock3 }]; #IO_L15P_T2_DQS_RDWR_B_14 ,Sch=LED2
set_property -dict { PACKAGE_PIN V19 IOSTANDARD LVCMOS33 } [get_ports { led_setting }]; #IO_L15N_T2_DQS_DOUT_CSO_B_14 ,Sch=LED3
set_property -dict { PACKAGE_PIN W18 IOSTANDARD LVCMOS33 } [get_ports { led_smsec }]; #IO_L16P_T2_CSI_B_14 ,Sch=LED4
set_property -dict { PACKAGE_PIN U15 IOSTANDARD LVCMOS33 } [get_ports { led_hm }]; #IO_L23P_T3_A03_D19_14 ,Sch=LED5
#set_property -dict { PACKAGE_PIN U14 IOSTANDARD LVCMOS33 } [get_ports { led[6] }]; #IO_25_14 ,Sch=LED6
#set_property -dict { PACKAGE_PIN V14 IOSTANDARD LVCMOS33 } [get_ports { led[7] }]; #IO_L24N_T3_A00_D16_14 ,Sch=LED7
#set_property -dict { PACKAGE_PIN V13 IOSTANDARD LVCMOS33 } [get_ports { led[8] }]; #IO_L24P_T3_A01_D17_14 ,Sch=LED8
#set_property -dict { PACKAGE_PIN V3 IOSTANDARD LVCMOS33 } [get_ports { led[9] }]; #IO_L6P_T0_34 ,Sch=LED9
set_property -dict { PACKAGE_PIN W3 IOSTANDARD LVCMOS33 } [get_ports { led_stop }]; #IO_L6N_T0_VREF_34 ,Sch=LED10
set_property -dict { PACKAGE_PIN U3 IOSTANDARD LVCMOS33 } [get_ports { led_run }]; #IO_L9P_T1_DQS_34 ,Sch=LED11
set_property -dict { PACKAGE_PIN P3 IOSTANDARD LVCMOS33 } [get_ports { led_clear }]; #IO_L12N_T1_MRCC_35 ,Sch=LED12
set_property -dict { PACKAGE_PIN N3 IOSTANDARD LVCMOS33 } [get_ports { led_upcounter1 }]; #IO_L12P_T1_MRCC_35 ,Sch=LED13
set_property -dict { PACKAGE_PIN P1 IOSTANDARD LVCMOS33 } [get_ports { led_upcounter2 }]; #IO_L19N_T3_VREF_35 ,Sch=LED14
set_property -dict { PACKAGE_PIN L1 IOSTANDARD LVCMOS33 } [get_ports { led_upcounter3 }]; #IO_L6N_T0_VREF_35 ,Sch=LED15
##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 { B3 }]; #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 { B4 }]; #IO_L18P_T2_A12_D28_14 ,Sch=BTND
##USB-RS232 Interface
set_property -dict { PACKAGE_PIN B18 IOSTANDARD LVCMOS33 } [get_ports { rx }]; #IO_L19P_T3_16 ,Sch=UART_RXD_IN
set_property -dict { PACKAGE_PIN A18 IOSTANDARD LVCMOS33 } [get_ports { tx }]; #IO_L19N_T3_VREF_16 ,Sch=UART_TXD_OUT
'[하만]세미콘 아카데미 > verilog' 카테고리의 다른 글
0603 RISC-v GPI GPO 0 | 2024.07.09 |
---|---|
0530~0531 RISCV_Type 0 | 2024.07.09 |
0529 DedicatedProcessor stackSum 0 | 2024.07.09 |
0529 Dedicated Processor ALU 0 | 2024.07.09 |
0529 DedicatedProcessor RegisterFile 0 | 2024.07.09 |