一个好用的Verilog串口UART程序
2013-03-12
标签:

出自http://www.asic-world.com/,测试过了很好用。

==========================================================================

//-----------------------------------------------------
// Design Name : uart 
// File Name: uart.v
// Function: Simple UART
// Coder: Deepak Kumar Tala
//-----------------------------------------------------
module uart (
reset,
txclk,
ld_tx_data,
tx_data,
tx_enable,
tx_out,
tx_empty,
rxclk,
uld_rx_data,
rx_data,
rx_enable,
rx_in,
rx_empty
);
// Port declarations
inputreset;
inputtxclk;
inputld_tx_data;
input [7:0] tx_data;
inputtx_enable;
outputtx_out;
outputtx_empty;
inputrxclk;
inputuld_rx_data;
output [7:0] rx_data;
inputrx_enable;
inputrx_in;
outputrx_empty;
// Internal Variables 
reg [7:0]tx_reg;
regtx_empty;
regtx_over_run;
reg [3:0]tx_cnt;
regtx_out;
reg [7:0]rx_reg;
reg [7:0]rx_data;
reg [3:0]rx_sample_cnt ;
reg [3:0]rx_cnt; 
regrx_frame_err;
regrx_over_run;
regrx_empty;
regrx_d1;
regrx_d2;
regrx_busy;
// UART RX Logic
always @ (posedge rxclk or posedge reset)
if (reset) begin
rx_reg<= 0; 
rx_data<= 0;
rx_sample_cnt <= 0;
rx_cnt<= 0;
rx_frame_err <= 0;
rx_over_run<= 0;
rx_empty<= 1;
rx_d1<= 1;
rx_d2<= 1;
rx_busy<= 0;
end else begin
// Synchronize the asynch signal
rx_d1 <= rx_in;
rx_d2 <= rx_d1;
// Uload the rx data
if (uld_rx_data) begin
rx_data <= rx_reg;
rx_empty <= 1;
end
// Receive data only when rx is enabled
if (rx_enable) begin
// Check if just received start of frame
if (!rx_busy && !rx_d2) begin
rx_busy<= 1;
rx_sample_cnt <= 1;
rx_cnt<= 0;
end
// Start of frame detected, Proceed with rest of data
if (rx_busy) begin
rx_sample_cnt <= rx_sample_cnt + 1;
// Logic to sample at middle of data
if (rx_sample_cnt == 7) begin
if ((rx_d2 == 1) && (rx_cnt == 0)) begin
rx_busy <= 0;
end else begin
rx_cnt <= rx_cnt + 1; 
// Start storing the rx data
if (rx_cnt > 0 && rx_cnt < 9) begin
rx_reg[rx_cnt - 1] <= rx_d2;
end
if (rx_cnt == 9) begin
rx_busy <= 0;
// Check if End of frame received correctly
if (rx_d2 == 0) begin
rx_frame_err <= 1;
end else begin
rx_empty<= 0;
rx_frame_err <= 0;
// Check if last rx data was not unloaded,
rx_over_run <= (rx_empty) ? 0 : 1;
end
end
end
end 
end 
end
if (!rx_enable) begin
rx_busy <= 0;
end
end
// UART TX Logic
always @ (posedge txclk or posedge reset)
if (reset) begin
tx_reg<= 0;
tx_empty<= 1;
tx_over_run<= 0;
tx_out<= 1;
tx_cnt<= 0;
end else begin
if (ld_tx_data) begin
if (!tx_empty) begin
tx_over_run <= 0;
end else begin
tx_reg<= tx_data;
tx_empty <= 0;
end
end
if (tx_enable && !tx_empty) begin
tx_cnt <= tx_cnt + 1;
if (tx_cnt == 0) begin
tx_out <= 0;
end
if (tx_cnt > 0 && tx_cnt < 9) begin
tx_out <= tx_reg[tx_cnt -1];
end
if (tx_cnt == 9) begin
tx_out <= 1;
tx_cnt <= 0;
tx_empty <= 1;
end
end
if (!tx_enable) begin
tx_cnt <= 0;
end
end
endmodule


可能会用到的工具/仪表
相关文章
推荐文章
热门文章
章节目录
本站简介 | 意见建议 | 免责声明 | 版权声明 | 联系我们
CopyRight@2024-2039 嵌入式资源网
蜀ICP备2021025729号