前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >串口通信控制器的Verilog HDL实现(三) 发送模块的Verilog HDL 实现

串口通信控制器的Verilog HDL实现(三) 发送模块的Verilog HDL 实现

作者头像
瓜大三哥
发布2018-02-24 17:31:40
1.4K0
发布2018-02-24 17:31:40
举报
文章被收录于专栏:瓜大三哥

由于波特率发生器产生的时钟信号bclk的频率为9600Hz的16倍,因此在发送器中,每16个bclk周期发送一个有效比特,发送数据格式严格按照图13-3所示的串口数据帧来完:首先是起始位(发送端口txd从逻辑1转化为逻辑0,并持续1/9600s),其次是8个有效数据比特(低位在前,高位在后),最后是一位停止位(没有添加校验位)。

整个发送模块的状态机包含5个状态:s_idle、s_start、s_wait、s_shift以及s_stop,其状态转移图如图13-6所示。

其中,s_idle为空闲状态,当复位信号有效或者发送任务已完成时,发送模块就处于s_idle状态,等待下一个发送指令(tx_cmd)的到来。在s_idle中,发送完成指示tx_ready为高电平,表明随时可以接收外部的发送指令。tx_cmd信号高有效,且持续时间为一个bclk信号的周期,其由顶层模块根据外部按键响应同步整形得到。当tx_cmd有效时,发送模块的下一状态为s_start。

s_start为发送模块的起始状态,拉低tx_ready信号,表明发送模块正处于工作中,并拉低发送比特线txd,给出起始位,然后跳转到s_wait状态。需要注意的是,s_start状态仅持续一个bclk周期,完成相关信号值的改变后,无条件进入s_wait状态。

s_wait为发送模块的等待状态,保持所有信号值不变。当发送模块处于这一状态时,等待计满16个bclk后,判断8个有效数据比特是否发送完毕,如果发送完毕跳转到s_stop,结束有效数据的发送;否则,跳转到s_shift状态,发送下一个有效比特。

s_shift为数据移位状态,发送模块在这一状态将下一个要发送的数据移动到发送端口上,然后直接跳转到s_wait状态。

s_stop状态完成停止位的发送,当有效数据发送完成后,发送模块进入该状态,发送一个停止位,发送完成后自动进入s_idle状态,并且将tx_ready信号拉高。在实际设计中,如果读者需要实现1.5位或者2位停止码,直接修改计数器的数值即可。

代码语言:js
复制
module uart_tx(
bclk,reset,tx_din,tx_cmd,tx_ready,txd
    );
 input bclk;
 input reset;
 input [7:0]tx_din;
 input tx_cmd;
 output tx_ready;
 output txd;
 reg tx_ready;
 parameter Lframe=8;
 parameter [2:0]s_idle=3'b000;
 parameter [2:0]s_start=3'b001;
 parameter [2:0]s_wait=3'b010;
 parameter [2:0]s_shift=3'b011;
 parameter [2:0]s_stop=3'b100;
 reg [2:0]state=s_idle;
 reg [3:0]cnt=0;
 reg [3:0]dcnt=0;
 reg txdt;
 assign txd=txdt;
 always @(posedge bclk or posedge reset)
 begin
if(reset)
begin
state<=s_idle;
cnt<=0;
tx_ready<=0;
txdt<=1'b1;
end
else
begin
case(state)
s_idle:
begin
tx_ready<=1;
cnt<=0;
txdt<=1'b1;
if(tx_cmd==1'b1)
state<=s_start;
else
state<=s_idle;
end
s_start:
begin
tx_ready<=1'b0;
txdt<=1'b0;//the start bit
state<=s_wait;
end
s_wait:
begin
tx_ready<=1'b0;
if(cnt>=4'b1110)
begin
cnt<=0;
if(dcnt==Lframe)
begin
state<=s_stop;
txdt<=1'b1;
dcnt<=0;
end
else
begin
state<=s_shift;
txdt<=txdt;
end
end
else
begin
state<=s_shift;
cnt<=cnt+1;
end
end
s_shift:
begin
tx_ready<=1'b0;
txdt<=tx_din[dcnt];
dcnt<=dcnt+1;
state<=s_wait;
end
s_stop:
begin
txdt<=1'b1;
if(cnt>4'b1110)
begin
tx_ready<=1'b1;
cnt<=0;
state<=s_idle;
end
else
begin
state<=s_stop;
cnt<=cnt+1;
end
end
endcase
end
 end
endmodule
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2016-07-05,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 瓜大三哥 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档