串口通信控制器的Verilog HDL实现(四) 接收模块的Verilog HDL 实现
时间:2022-04-28
本文章向大家介绍串口通信控制器的Verilog HDL实现(四) 接收模块的Verilog HDL 实现,主要内容包括其使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。
但凡涉及到双方通信的系统,接收机的复杂度往往都是高于发送机的,对于串口通信系统也如此。在接收系统中,起始状态和数据都需要依靠接收端检测得到,为了避免毛刺影响,能够得到正确的起始信号和有效数据,需要完成一个简单的最大似然判决,其方法如下:由于bclk信号的频率为9600Hz的16倍,则对于每个数据都会有16个样值,最终的采样比特值为出现次数超过8次的电平逻辑值。
整个接收模块的状态机包含3个状态:s_idle、s_sample以及s_stop,其状态转移图如图13-8所示。
s_idle状态为空闲状态,用于检测接收数据链路上的起始信号。系统复位后,接收模块就处于这一状态,一直检测rxd数据是否从1跳变为0,一个起始位代表着新的一帧数据。一旦检测到起始位,立刻进入s_sample状态,采集有效数据。在此状态下,rx_ready信号的值为1。
s_sample为数据采样状态,在此状态下,接收模块连续采样数据,并对每16个采样样值进行最大似然判决,判决得到相应的逻辑值,这一过程要重复8次,并依次完成串并转换,直到接收完8个数据比特后,直接进入s_stop状态。在这一状态下,rx_ready信号的值为0。
s_stop状态用于检测停止位,为了使得接收模块的使用范围更广,本程序在这一状态等待一定的时间后,直接跳转到s_idle状态,无论停止位是1、1.5还是2位,也不对其数值进行采样判断。这是因为没有添加校验位,根据串口的传输协议,8个有效数据后肯定是停止位,但停止位所占的时间却是要补偿的,对于不同位宽的停止位,需要修改计数器的模值。
module uart_rx(
bclk,reset,rxd,rx_ready,rx_dout
);
input bclk;
input reset;
input rxd;
output rx_ready;
output [7:0]rx_dout;
parameter [3:0]Lframe=9;
parameter [2:0]s_idle=3'b000;
parameter [2:0]s_sample=3'b010;
parameter [2:0]s_stop=3'b100;
reg rx_ready;
reg [7:0]rx_doutmp=0;
reg [2:0]state=s_idle;
reg [3:0]cnt=0;
reg [3:0]dcnt=0;
reg [3:0]num=0;
assign rx_dout=rx_doutmp;
always @(posedge bclk or posedge reset)
begin
if(reset==1'b1)
begin
state<=s_idle;
cnt<=0;
dcnt<=0;
num<=0;
rx_doutmp<=0;
rx_ready<=0;
end
else
begin
case(state)
s_idle:
begin
rx_dout<=0;
rx_ready<=1;
dcnt<=0;
if(cnt==4'b1111)
begin
cnt<=0;
if(num>7)
begin
state<=s_sample;
num<=0;
end
else
begin
state<=s_idle;
num<=0;
end
end
else
begin
cnt<=cnt+1;
if(rxd==1'b0)
begin
num<=num+1;
end
else
begin
num<=num;
end
end
end
s_sample:
begin
rx_ready<=1'b0;
if(dcnt==Lframe)
begin
state<=s_stop;
end
else
begin
if(cnt==4'b1111)
begin
dcnt<=dcnt+1;
cnt<=0;
if(num>7)
begin
num<=0;
rx_doutmp[dcnt]<=1;
end
else
begin
num<=0;
rx_doutmp[dcnt]<=0;
end
end
else
begin
cnt<=cnt+1;
if(rxd==1'b1)
begin
num<=num+1;
end
else
begin
num<=num;
end
end
end
end
s_stop:
begin
rx_ready<=1'b1;
if(cnt==4'b1111)
begin
cnt<=0;
state<=s_idle;
end
else
begin
cnt<=cnt+1;
end
end
endcase
end
end
endmodule
- 实用的前端开发小技巧汇集
- python编码问题
- 微信支付推出人脸识别智慧时尚试衣间,无感购物即将来袭
- 如何判断你买的域名有没有被K过?
- 【设计模式】Factory模式
- Windows:将cmd命令行添加到右键中方法
- 回家的低价票难抢?注意!可能是被“爬虫”吃了
- DeepMind团队回顾2017年:想象、推理取得突破
- flask-mail发送QQ邮件代码示例(亲测可行)
- 数据结构与算法C#版笔记--排序(Sort)-下
- pip --upgrade批量更新过期的python库
- 数据结构与算法C#版笔记--排序(Sort)-上
- android 模拟器安装二三事
- 2017小程序发展大事件和未来3大趋势分析
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- SAP Spartacus ProductConnector和ProductService实现
- Sorted Adjacent Differences(CodeForces - 1339B)【思维+贪心】
- Redis 发布订阅,小功能大用处,真没那么废材!
- R语言实现生物序列的降维比对
- Tomcat NIO(9)-IO线程-Overall流程和关键类
- 有限元平面四边形等差单元python编程
- 动图演示:手撸堆栈的两种实现方法!
- [Go] 实战项目在线客服GO-FLY -在gin框架使用IP识别库转换IP为城市
- leetcode1552题解【二分+贪心】
- 这三年被分布式坑惨了,曝光十大坑
- 为什么删数据也提示空间不足呢?
- 前端踩坑系列《六》——让人又爱又恨的npm包
- docker运行Tomcat后访问首页报404(详细永久解决步骤)
- vue.js如何快速入门第1篇
- 3.列表-HTML基础