名称:基于UART串口的32K数据发送和接收设计Verilog代码VIVADO仿真(文末获取)
软件:VIVADO
语言:Verilog
代码功能:
基于UART串口的32K数据发送和接收
1、编写代码,实现UART串口发送和接收
2、待发送数据通过8位并行接口输入,输入后换成在FIFO中
2、发送模块收到发送使能信号后开始发送FIFO内缓存的数据,发送完成后输出完毕信号
3、接收模块接收数据也缓存在FIFO,接收满32k数据后产生接收中断
4、仿真时为更快仿真出结果,可以将32K数据改为10个数据
1. 工程文件
2. 程序文件
2.1发送模块
2.2接收模块
3. 程序编译
4. 程序仿真
Testbench
1.发送模块仿真
为便于快速观察结果,将32k(32768)的数据量修改为10,即发送模块收到发送使能信号后开始发送数据,发送10个字节后输出完毕信号。
发送模块使用:先通过tfifo_wr_en和tfifo_wr_data信号将待发送的数据写入fifo中,写完后启动send_en信号(一个时钟周期高电平),将启动串口发送,所有数据发送完成后,send_over信号拉高。具体仿真图如下:
将待发送数据写入fifo
启动发送send_en=1
发送完成send_over信号拉高
2.接收模块仿真
为便于快速观察结果,将32k(32768)的数据量修改为10,即接收满10字节数据后产生接收中断。
接收模块使用:rx接收的数据存于FIFO中,rfifo_wr_en为FIFO写信号,rfifo_wr_data为FIFO写数据。数据接收满32768字节后(仿真时改为10),产生接收中断信号
receive_interrupt,receive_interrupt为高电平表示接收中断。要处理接收到的数据只需要通过FIFO的读接口rfifo_rd_en、rfifo_rd_data读取数据即可。具体仿真图如下:
串行rx接收转换为并行rfifo_wr_data
receive_interrupt拉高表示接收中断
部分代码展示:
//接收模块接收数据缓存在fifo,接收满32k数据后产生接收中断 module rs422_rx_module(clk,rst_p,rs422_rx,rfifo_rd_en,rfifo_rd_data,receive_interrupt); input clk;//50M input rst_p;//高电平复位 input rs422_rx; input rfifo_rd_en;//FIFO读使能 output[7:0] rfifo_rd_data;// FIFO读数据 output receive_interrupt;//接收满32K字节中断信号,高电平有效 reg receive_interrupt; wire [15:0] rfifo_data_count; wire rfifo_rd_en; wire [7:0] rfifo_rd_data; wire full; wire empty; wire[15:0] bps_cnt; wire[15:0] bps_cnt_mid; assign bps_cnt=16'd5208;//50000000/9600=5208 assign bps_cnt_mid=16'd2604; reg rx_mid; reg rx_en; reg[15:0] cnt; reg[3:0] num; always @(posedge clk) if(rfifo_data_count==16'd10)//仿真时为更快仿真出结果,将32768改为10,实际使用时改为32k,即32768 receive_interrupt<=1;//接收模块接收数据缓存在fifo,接收满32k数据后产生接收中断 else receive_interrupt<=0; always @(posedge clk or posedge rst_p) if(rst_p) rx_mid<=1'b0; else if(rx_en) if(cnt==bps_cnt_mid) rx_mid<=1'b1; else rx_mid<=1'b0; else rx_mid<=1'b0; reg rx_r0,rx_r1; always @(posedge clk or posedge rst_p) //rs422_rx下降沿检测 if(rst_p) begin rx_r0<=1'b1; rx_r1<=1'b1; end else begin rx_r0<=rs422_rx; rx_r1<=rx_r0; end wire rx_req; assign rx_req = ~rx_r0 & rx_r1; wire rx_done; assign rx_done = (cnt==bps_cnt_mid && num==4'd10); //停止位1位num==4'd10 always @(posedge clk or posedge rst_p) if(rst_p) rx_en<=1'b0; else if(rx_req) rx_en<=1'b1; else if(rx_done) rx_en<=1'b0; else rx_en<=rx_en; always @(posedge clk or posedge rst_p) if(rst_p) cnt<=16'd0; else if(rx_done) cnt<=16'd0; else if(rx_en) if(cnt==bps_cnt) cnt<=16'd0; else cnt<=cnt+16'b1; else cnt<=16'd0; always @(posedge clk or posedge rst_p) if(rst_p) num<=4'd0; else if(rx_done) num<=4'd0; else if(rx_en) if(cnt==bps_cnt) num<=num+1'b1; else num<=num; else num<=4'd0; reg[7:0] rx_data; reg rx_verify_bit; always @(posedge clk or posedge rst_p) if(rst_p) begin rx_data<=8'd0; rx_verify_bit<=1'b0; end else if(rx_en) if(rx_mid) case(num) 4'd1 : rx_data[0]<=rs422_rx; 4'd2 : rx_data[1]<=rs422_rx; 4'd3 : rx_data[2]<=rs422_rx; 4'd4 : rx_data[3]<=rs422_rx; 4'd5 : rx_data[4]<=rs422_rx; 4'd6 : rx_data[5]<=rs422_rx; 4'd7 : rx_data[6]<=rs422_rx; 4'd8 : rx_data[7]<=rs422_rx; 4'd9 : rx_verify_bit<=rs422_rx;
源代码
点击下方的公众号卡片获取