首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

FPGA UART verilog实现代码

FPGA UART verilog实现代码

波特率9600 、 串口部分代码
`timescale 1ns / 1ns
/////////////////
//UART
//tide.zhang
/////////////////

module uart (clk,reset,uart_enable,tx_data,load_tx_data,tx,tx_empty,rx,rx_data,rx_empty,clkbaud,rx_data_buf);
input clk;
input reset;
input uart_enable;
input [7:0] tx_data;
input load_tx_data;
output tx;
output tx_empty;
input rx;
output [7:0] rx_data;
reg [7:0] rx_data;
output rx_empty;
output [7:0] rx_data_buf;

output clkbaud;
// Internal Variables
reg [7:0] tx_data_buf;
reg tx_reg;
reg tx_empty; // 1 empty ,0 full

reg rx_reg1;
reg rx_reg2;
reg [7:0] rx_data_buf;
reg rx_empty; //1 empty
reg rx_tmp;

reg [8:0] div_reg; //count (baud rate)*8
reg clkbaud; // uart send or rec a bit clk, 8*clkbaud build a frame
reg [3:0] cnt_tx_clkbaud;
reg [3:0] cnt_rx_clkbaud;

parameter div_par = 16'hA28; //set baud rate clk,the osc 50MHz,the baud rate is 9600 byte/s
assign tx = tx_reg;
//assign rx_data = rx_data_buf;
/////////////
// bit count /----\/----\/-----\/
// \----/\----/\-----/\
////////////
always @(posedge clk or negedge reset)
begin
if(!reset)
begin
div_reg <= 0;
clkbaud <= 0;
end
else if (!uart_enable)
begin
div_reg <= 0;
clkbaud <= 0;
end
else if(div_reg == div_par-1)
begin
div_reg <= 0;
clkbaud <= ~clkbaud; //
end
else
div_reg <= div_reg + 1;
end

//////////
// tx
/////////
always @(posedge clkbaud or negedge reset)
begin
if(!reset)
begin
tx_reg <= 1;
tx_empty <= 1;
cnt_tx_clkbaud <= 0;
end
else
begin
if( load_tx_data && tx_empty) //
begin
tx_data_buf <= tx_data;
tx_empty <= 0;
tx_reg <= 0;
cnt_tx_clkbaud <= 1;
end
if(load_tx_data && !tx_empty)
begin
cnt_tx_clkbaud <= cnt_tx_clkbaud + 1;
if (cnt_tx_clkbaud==0)
tx_reg <= 0;
if (cnt_tx_clkbaud>0 && cnt_tx_clkbaud<9)
begin
tx_reg <= tx_data_buf[0];
tx_data_buf[6:0] <= tx_data_buf[7:1];
end
if (cnt_tx_clkbaud == 9)
begin
tx_reg <= 1;
tx_empty <= 1;
cnt_tx_clkbaud <= 0;
end
end
end
end

///////////
// RX
//////////
always @(posedge clkbaud or negedge reset)
begin
if(!reset)
begin
rx_reg1 <= 1;
rx_reg2 <= 1;
rx_empty <= 1;
cnt_rx_clkbaud <= 0;
rx_data_buf <= 0;
end
else
begin
rx_reg1 <= rx;
rx_reg2 <= rx_reg1;
if(cnt_rx_clkbaud == 0)
begin
if(!rx_reg1 && rx_reg2) //check out a start farme
begin
rx_empty <= 0;
rx_tmp <= 1;
//rx_data_buf[7] <= rx_reg2;
//rx_data_buf[6:0] <= rx_data_buf[7:1];
cnt_rx_clkbaud <= cnt_rx_clkbaud + 1;
end
else
begin
rx_empty <= 1;
//rx_data_buf[7] <= rx_reg2;
//rx_data_buf[6:0] <= rx_data_buf[7:1];
cnt_rx_clkbaud <= 0;
end
end

else if(rx_tmp && cnt_rx_clkbaud>0 && cnt_rx_clkbaud<9)
begin
rx_data_buf[7] <= rx_reg2;
rx_data_buf[6:0] <= rx_data_buf[7:1];
cnt_rx_clkbaud <= cnt_rx_clkbaud + 1;
end
else if(cnt_rx_clkbaud == 9)
begin
rx_data_buf[7] <= rx_reg2;
rx_data_buf[6:0] <= rx_data_buf[7:1];
rx_empty <= 1;
cnt_rx_clkbaud <= 0;
rx_tmp <= 0;
end
end
end

// rx_data <= rx_data_buf;
endmodule
记录学习中的点点滴滴,让每一天过的更加有意义!
返回列表