名称:UART串口发送模块可接收模块设计Verilog代码VIVADO仿真
软件:VIVADO
语言:Verilog
代码功能:
1、发送模块收到发送使能信号后开始发送数据,发送完成后输出完毕信号。数据发送使用FIFO接口
2、接收模块接收数据缓存在fifo,接收满32k数据后产生接收中断(FIFO满)
FPGA代码Verilog/VHDL代码资源下载:www.hdlcode.com
演示视频:
设计文档:
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)
点击链接获取代码文件:http://www.hdlcode.com/index.php?m=home&c=View&a=index&aid=1103