`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2023/07/09 20:32:42
// Design Name:
// Module Name: uart_drive
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module uart_drive#(
parameter P_SYSTEM_CLK = 50_000_000 ,
parameter P_UART_DATA_WIDTH = 8 ,
parameter P_UART_BUAD_CLK = 9600 ,
parameter P_UART_STOP_WIDTH = 1 ,
parameter P_UART_CHECK = 0
)
(
input i_sys_clk ,
input i_sys_rst ,
input i_uart_rx ,
output o_uart_tx ,
input [P_UART_DATA_WIDTH-1:0] i_uart_tx_data ,
input i_uart_tx_vaild ,
output o_uart_tx_ready ,
output [P_UART_DATA_WIDTH-1:0] o_uart_rx_data ,
output o_uart_rx_vaild ,
output o_buad_clk ,
output o_buad_clk_rst
);
localparam P_DIV = P_SYSTEM_CLK/P_UART_BUAD_CLK ;
wire w_buad_clk ;
wire w_buad_clk_rst ;
wire w_uart_rx_vaild ;
wire w_rx_clk ;
reg r_rx_rst ;
reg r_uart_rx_vaild ;
reg o_uart_rx_vaild
reg [2:0] r_rx_overvalue ;
reg [2:0] r_rx_overvalue_1d ;
reg r_rx_overlock ;
assign o_buad_clk =w_buad_clk;
assign o_buad_clk_rst= w_buad_clk_rst;
clk_div#(
.P_CLK_DIV (P_DIV )
)
clk_div_u0
(
.i_sys_clk (i_sys_clk ) ,
.i_sys_rst (i_sys_rst ) ,
.o_clk_div (w_buad_clk )
);
clk_div#(
.P_CLK_DIV (P_DIV )
)
clk_div_u1
(
.i_sys_clk (i_sys_clk ) ,
.i_sys_rst (r_rx_rst ) ,
.o_clk_div (w_rx_clk )
);
rst_gen#(
.P_RST_CYCLE ( 4 )
)
rst_gen_u0
(
.i_sys_clk (w_buad_clk ) ,
.o_sys_rst (w_buad_clk_rst )
);
uart_tx#(
.P_UART_DATA_WIDTH (P_UART_DATA_WIDTH ) ,
.P_UART_STOP_WIDTH (P_UART_STOP_WIDTH ) ,
.P_UART_CHECK (P_UART_CHECK )
)
uart_tx_u0
(
.i_uart_tx_data (i_uart_tx_data ) ,
.i_clk (w_buad_clk ) ,
.i_rst (w_buad_clk_rst ) ,
.i_uart_tx_vaild (i_uart_tx_vaild ) ,
.o_uart_tx_ready (o_uart_tx_ready ) ,
.o_uart_tx (o_uart_tx )
);
uart_rx#(
.P_UART_DATA_WIDTH (P_UART_DATA_WIDTH ) ,
.P_UART_STOP_WIDTH (P_UART_STOP_WIDTH ) ,
.P_UART_CHECK (P_UART_CHECK )
)
uart_rx_u0
(
.i_uart_rx (i_uart_rx) ,
.i_clk (w_rx_clk) ,
.i_rst (w_buad_clk_rst) ,
.o_uart_rx_data (o_uart_rx_data) ,
.o_uart_rx_vaild (w_uart_rx_vaild)
);
always@(posedge i_sys_clk or posedge i_sys_rst)
begin
if(i_sys_rst)
r_rx_overvalue<=3'b111;
else if(!r_rx_overlock)
r_rx_overvalue<={r_rx_overvalue[1:0],i_uart_rx};
else
r_rx_overvalue<=3'b111;
end
always@(posedge i_sys_clk or posedge i_sys_rst)
begin
if(i_sys_rst)
r_rx_overvalue_1d<=3'b111;
else
r_rx_overvalue_1d<= r_rx_overvalue;
end
always@(posedge i_sys_clk or posedge i_sys_rst)
begin
if(i_sys_rst)
r_rx_overlock<='d0;
else if(!r_uart_rx_vaild && w_uart_rx_vaild)
r_rx_overlock<='d0;
else if(!(r_rx_overvalue_1d==3'b000)&&r_rx_overvalue==3'b000)
r_rx_overlock<='d1;
else
r_rx_overlock<=r_rx_overlock;
end
always@(posedge i_sys_clk or posedge i_sys_rst)
begin
if(i_sys_rst)
r_uart_rx_vaild<='d0;
else
r_uart_rx_vaild<=w_uart_rx_vaild;
end
always@(posedge i_sys_clk or posedge i_sys_rst)
begin
if(i_sys_rst)
r_rx_rst<='d1;
else if(!r_uart_rx_vaild && w_uart_rx_vaild)
r_rx_rst<='d1;
else if(!(r_rx_overvalue_1d==3'b000)&&r_rx_overvalue==3'b000)
r_rx_rst<='d0;
else
r_rx_rst<=r_rx_rst;
end
endmodule
`timescale 1ns / 1ps
//
// Company:
// Engineer:
//
// Create Date: 2023/07/09 20:32:42
// Design Name:
// Module Name: uart_tx
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//
module uart_tx#(
parameter P_UART_DATA_WIDTH = 8 ,
parameter P_UART_STOP_WIDTH = 1 ,
parameter P_UART_CHECK = 1
)
(
input [P_UART_DATA_WIDTH-1:0] i_uart_tx_data ,
input i_clk ,
input i_rst ,
input i_uart_tx_vaild ,
output o_uart_tx_ready ,
output o_uart_tx
);
reg r_uart_tx ;
reg r_uart_tx_ready ;
reg [P_UART_DATA_WIDTH-1:0] r_uart_tx_data ;
reg [15:0] r_cnt ;
reg r_uart_check ;
wire w_tx_active ;
assign w_tx_active = i_uart_tx_vaild && r_uart_tx_ready ; //握手信号,激活发送
assign o_uart_tx_ready = r_uart_tx_data ;
assign o_uart_tx = r_uart_tx ;
//数据寄存
always@(posedge i_clk or posedge i_rst)
begin
if(i_rst)
r_uart_tx_data<='d0;
else if(w_tx_active)
r_uart_tx_data<=i_uart_tx_data;
else if(!r_uart_tx_ready)
r_uart_tx_data>>1;
else
r_uart_tx_data<=r_uart_tx_data;
end
//计数器
always@(posedge i_clk or posedge i_rst)
begin
if(i_rst)
r_cnt<='d0;
else if((r_cnt==1+P_UART_DATA_WIDTH+1+P_UART_STOP_WIDTH-1)&&P_UART_CHECK>0)
r_cnt<='d0;
else if((r_cnt==1+P_UART_DATA_WIDTH+P_UART_STOP_WIDTH-1)&&P_UART_CHECK=0)
r_cnt<='d0;
else if(!r_uart_tx_ready)
r_cnt<=r_cnt+'d1;
else
r_cnt<=r_cnt ;
end
//准备信号
always@(posedge i_clk or posedge i_rst)
begin
if(i_rst)
r_uart_tx_ready<=1;
else if((r_cnt==1+P_UART_DATA_WIDTH+1+P_UART_STOP_WIDTH-2)&&P_UART_CHECK>0)
r_uart_tx_ready<=1;
else if((r_cnt==1+P_UART_DATA_WIDTH+P_UART_STOP_WIDTH-2)&&P_UART_CHECK=0)
r_uart_tx_ready<=1;
else if(w_tx_active)
r_uart_tx_ready<=0;
else
r_uart_tx_ready<=r_uart_tx_ready;
end
//奇偶校验
always@(posedge i_clk or posedge i_rst)
begin
if(i_rst)
r_uart_check<=0;
else if(!r_uart_tx_ready)
r_uart_check<=r_uart_check^r_uart_tx_data[0];
else
r_uart_check<=r_uart_check;
end
//数据发送
always@(posedge i_clk or posedge i_rst)
begin
if(i_rst)
r_uart_tx<=1;
else if(w_tx_active)
r_uart_tx<='d0;
else if(!r_uart_tx_ready&&r_cnt<8)
r_uart_tx<=r_uart_tx_data[0];
else if(r_cnt==8&&P_UART_CHECK==0)
r_uart_tx<=1;
else if(r_cnt==8&&P_UART_CHECK==1)
r_uart_tx<=~r_uart_check;
else if(r_cnt==8&&P_UART_CHECK==2)
r_uart_tx<=r_uart_check;
else if(r_cnt>8)
r_uart_tx<=1;
else
r_uart_tx<=1;
end
endmodule