uart_top.v
`timescale 1ns / 1ps
module uart_top(
input RST,
input CLK,
input RXD,
output [6:0] AN,
output CA,
output PAR_ERR,
output FRM_ERR
);
wire [7:0] rx_data;
uart_rx uart_rx_0 (
.RST (RST),
.CLK (CLK),
.RXD (RXD),
.RX_DATA (rx_data),
.RX_DATA_RDY (),
.FRM_ERR (FRM_ERR),
.PARITY_ERR (PAR_ERR)
);
display_inf disp_0 (
.RST (RST),
.CLK (CLK), // 125 Mhz
.NUM_1S (rx_data[3:0]),
.NUM_10S (rx_data[7:4]),
.CA (CA),
.AN (AN)
);
endmodule
uart_rx.v
`timescale 1ns / 1ps
module uart_rx(
input RST,
input CLK,
input RXD,
output [7:0] RX_DATA,
output RX_DATA_RDY,
output FRM_ERR,
output PARITY_ERR
);
wire baud_x16_en;
uart_baud_gen uart_baud_gen (
.RST (RST),
.CLK (CLK),
.BAUD_X16_EN (baud_x16_en)
);
uart_rx_cntl uart_rx_cntl(
.RST (RST),
.CLK (CLK),
.RXD (RXD),
.BAUD_X16_EN (baud_x16_en),
.RX_DATA (RX_DATA),
.RX_DATA_RDY (RX_DATA_RDY),
.FRM_ERR (FRM_ERR),
.PARITY_ERR (PARITY_ERR)
);
endmodule
uart_baud_gen.v
`timescale 1ns / 1ps
module uart_baud_gen(
input RST,
input CLK,
output BAUD_X16_EN
);
parameter CLK_FREQ = 125_000_000;
parameter BAUD_RATE = 9600;
localparam MAX_CNT = (CLK_FREQ)/(BAUD_RATE*16);
reg [12:0] cnt;
reg enable;
assign BAUD_X16_EN = enable;
always @(posedge CLK)
begin
if (RST) begin
cnt <= 13'd0;
enable <= 1'b0;
end else begin
if(cnt == (MAX_CNT-1)) begin
cnt <= 13'd0;
enable <= 1'b1;
end else begin
cnt <= cnt + 1;
enable <= 1'b0;
end
end
end //always
endmodule
uart_rx_cntl
`timescale 1ns / 1ps
module uart_rx_cntl(
input RST,
input CLK,
(* mark_debug = "true" *)
input RXD,
(* mark_debug = "true" *)
input BAUD_X16_EN, //over_sample_cnt_done,
output [7:0] RX_DATA,
(* mark_debug = "true" *)
output reg RX_DATA_RDY,
(* mark_debug = "true" *)
output reg FRM_ERR,
(* mark_debug = "true" *)
output PARITY_ERR
// output reg [1:0] fsm_state
);
localparam [1:0] idle = 2'b00,
start = 2'b01,
data = 2'b10,
stop = 2'b11;
(* mark_debug = "true" *)
reg [1:0] curr_state;//
reg [1:0] next_state;
(* mark_debug = "true" *)
wire over_sample_cnt_done;
(* mark_debug = "true" *)
reg [3:0] over_sample_cnt;
(* mark_debug = "true" *)
reg [3:0] bit_cnt;
(* mark_debug = "true" *)
wire bit_cnt_done;
(* mark_debug = "true" *)
reg [8:0] rx_frame;
reg rx_d;
always @(posedge CLK)
begin
if(RST)
curr_state <= idle;
else
curr_state <= next_state;
end //always
always @(curr_state, over_sample_cnt_done, bit_cnt_done, RXD)
begin
case (curr_state)
idle : begin
if(RXD == 1'b0)
next_state = start;
else
next_state = idle;
// fsm_state = 2'b00;
end
start : begin
if(over_sample_cnt_done) begin
if(RXD)
next_state = idle;
else
next_state = data;
end
else next_state = start;
// fsm_state = 2'b01;
end
data : begin
if(over_sample_cnt_done && bit_cnt_done)
next_state = stop;
else
next_state = data;
// fsm_state = 2'b10;
end
stop : begin
if(over_sample_cnt_done)
next_state = idle;
else
next_state = stop;
// fsm_state = 2'b11;
end
default : next_state = idle;
endcase
end //always
// over sample count
always @(posedge CLK)
begin
if(RST || curr_state == idle)
over_sample_cnt <= 4'd7;
else if (BAUD_X16_EN) begin
if(over_sample_cnt_done)
over_sample_cnt <= 4'd15;
else
over_sample_cnt <= over_sample_cnt - 1;
end
end
assign over_sample_cnt_done = (over_sample_cnt == 4'd0) & BAUD_X16_EN;
// bit cnt generate
always @(posedge CLK)
begin
if(RST || curr_state != data)
bit_cnt <= 4'd0;
else if(over_sample_cnt_done)
bit_cnt <= bit_cnt + 1;
end //always
assign bit_cnt_done = (over_sample_cnt_done && (bit_cnt == 4'd8));
// output data generate
assign RX_DATA = rx_frame[7:0];
always @(posedge CLK)
begin
if (RST)
rx_frame <= 9'd0;
else if (curr_state == data && over_sample_cnt_done)
rx_frame[bit_cnt] <= RXD;
end //always
//always @(posedge CLK)
// rx_d <= RXD;
always @(posedge CLK)
RX_DATA_RDY <= bit_cnt_done;
assign PARITY_ERR = RX_DATA_RDY & ( rx_frame[8] != ^RX_DATA);
always @(posedge CLK)
begin
if(RST)
FRM_ERR <= 1'b0;
else if((curr_state == stop) && over_sample_cnt_done)
if (!RXD)
FRM_ERR <= 1'b1;
else
FRM_ERR <= 1'b0;
end
endmodule
disp_inf.v
`timescale 1ns / 1ps
module display_inf(
input RST,
input CLK, // 125 Mhz
input [3:0] NUM_1S,
input [3:0] NUM_10S,
output reg CA,
output reg [6:0] AN
);
parameter CLK_FREQ = 125_000_000;
parameter CNT_MAX = CLK_FREQ / 1000_000;
reg [26:0] clk_cnt;
wire enable;
always @(posedge CLK)
begin
if(RST)
clk_cnt <= 27'd0;
else begin
if( clk_cnt == (CNT_MAX -1))
clk_cnt <= 27'd0;
else
clk_cnt <= clk_cnt + 1;
end
end
assign enable = (clk_cnt == (CNT_MAX -1));
always @(posedge CLK)
if(RST)
CA <= 1'b0;
else if (enable)
CA <= ~CA;
always @(CA, NUM_1S, NUM_10S)
begin
if (CA) begin
case (NUM_10S)
4'd0 : AN = 7'h7e;
4'd1 : AN = 7'h30;
4'd2 : AN = 7'h6d;
4'd3 : AN = 7'h79;
4'd4 : AN = 7'h33;
4'd5 : AN = 7'h5b;
4'd6 : AN = 7'h5f;
4'd7 : AN = 7'h70;
4'd8 : AN = 7'h7f;
4'd9 : AN = 7'h7b;
default : AN = 7'h00;
endcase
end else begin
case (NUM_1S)
4'd0 : AN = 8'h7e;
4'd1 : AN = 8'h30;
4'd2 : AN = 8'h6d;
4'd3 : AN = 8'h79;
4'd4 : AN = 7'h33;
4'd5 : AN = 7'h5b;
4'd6 : AN = 7'h5f;
4'd7 : AN = 7'h70;
4'd8 : AN = 7'h7f;
4'd9 : AN = 7'h7b;
default : AN = 8'h00;
endcase
end
end
endmodule
'Circuit Design > 🔥HDL' 카테고리의 다른 글
[Verilog] 10. FIFO(First In First Out) (0) | 2024.06.03 |
---|---|
[Verilog] 9. RAM(Random Access Memory) (0) | 2024.05.27 |
[Verilog] 7. 교통신호기 FSM (0) | 2024.04.29 |
[Verilog] 6.FSM Security (0) | 2024.04.29 |
[Verilog] 5. FSM Demo. (1) | 2024.04.26 |