//uart 2017.10.7 发送接收到的数据
//波特率9600 一个停止位 无奇偶校验
//DE2板子
/*
rx GPIO_K25 0 left -----tx
tx GPIO_K26 1 right -----rx
GND 右边第6 或者倒数第6
*/
//复位不成功 ????? 复位按键有问题 靠右按即可复位
//特别注意 如果一个条件中同时给一个寄存器赋不同的值 结果不确定
//以下是错误代码例子 tx_num
//同时赋值 这里加一 下面赋值0
/*
tx_num<=tx_num+1'b1;
case(tx_num)
0:tx<=1'b0;
1:tx<=tx_data[0];
2:tx<=tx_data[1];
3:tx<=tx_data[2];
4:tx<=tx_data[3];
5:tx<=tx_data[4];
6:tx<=tx_data[5];
7:tx<=tx_data[6];
8:tx<=tx_data[7];
9:begin tx<=1'b1; tx_num<=4'b0; end
*/
//一些小的算法问题 画个时序图 标出各个点寄存器的值
//对照程序看是否正确 特别是需要判断且改变状态的点
//以下是代码
//----------------------代码------------------
module uart(
clk, //50Mhz
rst_n, //reset
rx, //input
tx, //ouptut
sw //测试是否收到数据
);
input clk,rst_n;
input rx;
output reg tx;
//测试是否收到数据
output wire [7:0] sw;
//-----------------检测是否有数据来--------
//边沿检测
wire rx_start;
reg rx1;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n) rx1<=1'b0;
else rx1<=rx;
end
assign rx_start = ~rx & rx1;
//-------------------波特率控制------------
wire bps_start;
reg bps_start_rx,bps_start_tx;
reg [3:0] rx_num,tx_num; // 2^4-1=15
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
bps_start_rx<=1'b0;
bps_start_tx<=1'b0;
end
else if(rx_start) bps_start_rx<=1'b1;
//接收完数据后 开始发送数据
else if(rx_num==10)
begin
bps_start_rx<=1'b0;
bps_start_tx<=1'b1;
end
//发送完数据后 无需产生波特率
else if(tx_num==10)
bps_start_tx<=1'b0;
end
assign bps_start = bps_start_rx|bps_start_tx;
//------------------产生波特率--------------
//9600
parameter bps_cnt=5208; //50Mhz / 9600 = 5208.3......
parameter bps_cnt_half=2604;
reg [12:0] cnt;
always@(posedge clk or negedge rst_n)
begin
if(!rst_n) cnt<=13'b0;
else if(cnt==bps_cnt) cnt<=13'b0;
else if(bps_start) cnt<=cnt+1'b1;
else cnt<=13'b0;
end
//--------------------------------------------
reg [7:0] rx_data,tx_data;
//测试是否收到数据
assign sw=rx_data;
//---------------------接收数据--------------
//receive
always@(posedge clk or negedge rst_n)
begin
if(!rst_n)
begin
rx_num<=4'b0;
rx_data<=8'b0;
end
else if(cnt==bps_cnt_half)
begin
if(bps_start_rx)
begin
rx_num<=rx_num+1'b1;
case(rx_num)
1:rx_data[0]<=rx;
2:rx_data[1]<=rx;
3:rx_data[2]<=rx;
4:rx_data[3]<=rx;
5:rx_data[4]<=rx;
6:rx_data[5]<=rx;
7:rx_data[6]<=rx;
8:rx_data[7]<=rx;
9:tx_data<=rx_data;
endcase
end
end
else if(rx_num==10) rx_num<=4'b0;
end
//---------------------发送数据--------------
//transport
always@(posedge clk or negedge rst_n)
begin
if(!rst_n) tx_num<=4'b0;
else if(cnt==bps_cnt_half)
begin
if(bps_start_tx)
begin
tx_num<=tx_num+1'b1;
case(tx_num)
0:tx<=1'b0;
1:tx<=tx_data[0];
2:tx<=tx_data[1];
3:tx<=tx_data[2];
4:tx<=tx_data[3];
5:tx<=tx_data[4];
6:tx<=tx_data[5];
7:tx<=tx_data[6];
8:tx<=tx_data[7];
9:tx<=1'b1;
endcase
end
else tx<=1'b1;
end
else if(tx_num==10) tx_num<=4'b0;
end
endmodule