名称:UART通讯模块设计Verilog代码vivado仿真(文末获取)
软件:vivado
语言:Verilog
代码功能:
具体要求如下:
1.分组进行设计实践,每组10~11人,组内人员自行分工开发任务:模块开发与testbench仿真验证。
2.技术参数要求:
用户收发数据位宽:8bit;
用户时钟:100MHz
数据发送缓存:不小于4KByte;
附加功能:串行波特率可配;是否添加校验位可配
3.通讯控制模块对外接口约定如下:
module uart_intf#
(
parameter BaudRate = 868 , //波特率:时钟/波特率,如:100Mhz,115200bps,100_000000/115200 = 868
parameter CheckMode = 0 , //奇偶校验:0-无,1-奇校验(ODD),2-偶校验(EVEN),3-高校验,4-低校验
parameter BitNum = 8 ) //数据位宽度
(
input wire [00:00] uart_refclk ,
input wire [00:00] uart_refrst ,
input wire [00:00] uart_txdata_en ,
input wire [BitNum - 1:00] uart_txdata ,
output wire [00:00] uart_rxdata_en ,
output wire [BitNum - 1:00] uart_rxdata ,
input wire [00:00] uart_rx_sig ,
output wire [00:00] uart_tx_sig );
1. 工程文件
2. 程序文件
3. 程序编译
4. RTL图
5. Testbench
6. 仿真图
整体仿真图
将发送接收回环,依次发送0x24,0x3a,0x19,接收到的也为0x24,0x3a,0x19。故发送接收正确。
波特率控制模块
FIFO模块
串口发送模块
接收串口模块
部分代码展示:
module my_uart_rx(clk,rst_n,rs232_rx,clk_bps,rx_data,rx_en); input clk;// 100MHz主时钟 input rst_n;//低电平复位信号 input rs232_rx;// RS232接收数据信号 input clk_bps;// clk_bps的高电平为接收或者发送数据位的中间采样点 output[7:0] rx_data;//接收数据寄存器,保存直至下一个数据来到 output rx_en;//接收数据有效 //---------------------------------------------------------------- reg rs232_rx0,rs232_rx1,rs232_rx2;//接收数据寄存器,滤波用 wire neg_rs232_rx;//表示数据线接收到下降沿 always @ (posedge clk or negedge rst_n) begin if(!rst_n) begin rs232_rx0 <= 1'b1; rs232_rx1 <= 1'b1; rs232_rx2 <= 1'b1; end else begin rs232_rx0 <= rs232_rx; rs232_rx1 <= rs232_rx0; rs232_rx2 <= rs232_rx1; end end assign neg_rs232_rx = rs232_rx2 & ~rs232_rx1;//接收到下降沿后neg_rs232_rx置高一个时钟周期 //---------------------------------------------------------------- reg[3:0]num;//移位次数 reg rx_int;//接收数据中断信号,接收到数据期间始终为高电平 always @ (posedge clk or negedge rst_n) begin if(!rst_n) begin rx_int <= 1'b0; end else if(neg_rs232_rx) begin rx_int <= 1'b1;//接收数据中断信号使能 end else if(num==4'd11) begin rx_int <= 1'b0;//接收数据中断信号关闭 end end //---------------------------------------------------------------- reg[7:0] rx_data_r;//接收数据寄存器,保存直至下一个数据来到 //---------------------------------------------------------------- reg[7:0]rx_temp_data;//但前接收数据寄存器 reg rx_data_shift;//数据移位标志 always @ (posedge clk or negedge rst_n) begin if(!rst_n) begin rx_data_shift <= 1'b0; rx_temp_data <= 8'd0; num <= 4'd0; rx_data_r <= 8'd0; end else if(rx_int) begin//接收数据处理 if(clk_bps) begin//读取并保存数据,接收数据为一个起始位,8bit数据,一个结束位 rx_data_shift <= 1'b1; num <= num+1'b1; if(num<=4'd8) rx_temp_data[7] <= rs232_rx;//锁存9bit(1bit起始位,8bit数据) end else if(rx_data_shift) begin//数据移位处理 rx_data_shift <= 1'b0; if(num<=4'd8) rx_temp_data <= rx_temp_data >> 1'b1;//移位8次,第1bit起始位移除,剩下8bit正好时接收数据 else if(num==4'd11) begin num <= 4'd0;//接收到STOP位后结束,num清零 rx_data_r <= rx_temp_data;//把数据锁存到数据寄存器rx_data中 end end end end reg rx_int_buf=0; always @ (posedge clk ) begin rx_int_buf<=rx_int; end assign rx_en= rx_int_buf & (~rx_int);//rx_int下降沿 assign rx_data = rx_data_r;//数据 endmodule
源代码
扫描文章末尾的公众号二维码