- uart 单端发送 起始位为低电平,停止位为高电平。波特率是指将时钟分频,在分频系数上传送数字信号。
module uart_tx(
input clk ,
input rst_n ,
input [7:0] data_in ,
input data_en , //1输入 0输出
output data_out ,
output tx_done //1byte转换完为1 否则为0
);
parameter CNT_MAX = 13'd5208; //波特率9600 用始终/波特率得到计数值
//信号定义
reg [19:0] cnt ;
wire add_cnt;
wire end_cnt;//波特率
reg [3:0] cnt1 ;
wire add_cnt1 ;
wire end_cnt1 ;//发送数据
reg [9:0] data_reg;
reg tx_flag ;
reg data_bit;
reg tx_done_reg;
//波特率计数模块
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt <= 'd0;
end
else if(add_cnt)begin
if(end_cnt)begin
cnt <= 'd0;
end
else begin
cnt <= cnt + 1'b1;
end
end
else begin
cnt <= cnt;
end
end
assign add_cnt = tx_flag;
assign end_cnt = add_cnt && cnt >= CNT_MAX - 1'd1;
//数据发送计数
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt1 <= 'd0;
end
else if(add_cnt1)begin
if(end_cnt1)begin
cnt1 <= 'd0;
end
else begin
cnt1 <= cnt1 + 1'b1;
end
end
else begin
cnt1 <= cnt1;
end
end
assign add_cnt1 = end_cnt;
assign end_cnt1 = add_cnt1 && cnt1 >= 10 - 1'd1;
//tx_flag
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin
tx_flag <= 0;
end
else if (data_en)begin
tx_flag <= 1;
end
else if(end_cnt1)begin
tx_flag <= 0;
end
end
//data_reg
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin
data_reg <= 0;
end
else if (data_en)begin
data_reg <= {1'b1,data_in,1'b0};
end
end
//data_bit
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin
data_bit <= 0;
end
else if (end_cnt && tx_flag)begin
data_bit <= data_reg[cnt1];
end
end
//tx_done_reg
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin
tx_done_reg <= 0;
end
else if (end_cnt1)begin
tx_done_reg <= 1;
end
else begin
tx_done_reg <= 0;
end
end
//信号输出
assign data_out = data_bit ;
assign tx_done = tx_done_reg;
endmodule
仿真波形【可以把波特率设置为可选择,case语句】
- uart 单端接收
//并行数据转换串行数据
module uart_tx(
input clk ,
input rst_n ,
input [7:0] data_in ,
input data_en , //1输入 0输出
output data_out ,
output tx_done //1byte转换完为1 否则为0
);
parameter CNT_MAX = 13'd5208; //波特率9600
//信号定义
reg [19:0] cnt ;
wire add_cnt;
wire end_cnt;//波特率
reg [3:0] cnt1 ;
wire add_cnt1 ;
wire end_cnt1 ;//发送数据
reg [9:0] data_reg;
reg tx_flag ;
reg data_bit;
reg tx_done_reg;
//波特率计数模块
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt <= 'd0;
end
else if(add_cnt)begin
if(end_cnt)begin
cnt <= 'd0;
end
else begin
cnt <= cnt + 1'b1;
end
end
else begin
cnt <= cnt;
end
end
assign add_cnt = tx_flag;
assign end_cnt = add_cnt && cnt >= CNT_MAX - 1'd1;
//数据发送计数
always @(posedge clk or negedge rst_n)begin
if(!rst_n)begin
cnt1 <= 'd0;
end
else if(add_cnt1)begin
if(end_cnt1)begin
cnt1 <= 'd0;
end
else begin
cnt1 <= cnt1 + 1'b1;
end
end
else begin
cnt1 <= cnt1;
end
end
assign add_cnt1 = end_cnt;
assign end_cnt1 = add_cnt1 && cnt1 >= 10 - 1'd1;
//tx_flag
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin
tx_flag <= 0;
end
else if (data_en)begin
tx_flag <= 1;
end
else if(end_cnt1)begin
tx_flag <= 0;
end
end
//data_reg
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin
data_reg <= 0;
end
else if (data_en)begin
data_reg <= {1'b1,data_in,1'b0};
end
end
//data_bit
// always@(posedge clk or negedge rst_n)begin
// if(!rst_n)begin
// data_bit <= 0;
// end
// else if (tx_flag && end_cnt)begin
// data_bit <= data_reg[cnt1];
// end
// end 如果采用这种输出模式,输出会慢一拍,相当于寄存器寄存一排
//tx_done_reg
always@(posedge clk or negedge rst_n)begin
if(!rst_n)begin
tx_done_reg <= 0;
end
else if (end_cnt1)begin
tx_done_reg <= 1;
end
else begin
tx_done_reg <= 0;
end
end
//信号输出
assign data_out = end_cnt? data_reg[cnt1] : data_out;
//这种输出方式就是完全对其,组合逻辑输出完全对其
assign tx_done = tx_done_reg;
endmodule
组合逻辑时钟对的起
寄存器输出时钟对不其
一个模块一个模块仿真,然后两个模块仿真。从仿真修改,仿真没错后,使用singaltap板上调试。修改实际功能
5**. fifo测试
6. uart加上fifo然后通信
7. uart加奇偶校验**
版权声明:本文为xindongpai原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。