状态关系还是 非常清晰的。
*************************
三段式
/*以下为三段式状态机*/
//状态转移
always @ (posedge ClkIn or negedge Resetb)
。。。。。
//状态转移条件判断
always @ (cState or Resetb or RxdIner or Cnt16 or Cnt8)
。。。。。
//各个状态的时序控制
always @ (posedge ClkIn or negedge Resetb)
。。。。。
*************************
//状态转移
always @ (posedge ClkIn or negedge Resetb)
if(!Resetb)
cState<=Idle;
else
cState<=nState;
复习一下, cState = current State ;
nState = next State
**************************
//状态转移条件判断
always @ (cState or Resetb or RxdIner or Cnt16 or Cnt8)
if(!Resetb)
nState=Idle;
else
case(cState)
Idle:
Idle转移条件判断;
RevStartBit:
RevStartBit转移条件判断;
RevDataBit:
RevDataBit转移条件判断;
RevStopBit:
RevStopBit转移条件判断;
RevDone:
RevDone转移条件判断;
default:nState=4'bx;
endcase
状态转移条件判断,明显比较复杂,同时也是本节的重点,因为
采样 规则要在这里体现。
例如
2、标准C51 当连续8次采集到RXD线上为低电平时,检测电路便认定RXD线上有了“开始位”,例程一致;
就是
RevStartBit转移条件判断; 要实现的。
- RevStartBit:
- begin
- if(Cnt16<8)//只要有输入为高,立即跳到Idle状态,连续8次采集低电平则认为开始位
- begin
- if(RxdIner==1'b0)
- nState=RevStartBit;
- else
- nState=Idle;
- end
- else
- nState=RevDataBit;//
- end
复制代码
Cnt16 16倍于 接收时钟,当 前8次都采集 低电平,则后面8次采样不需要判断,直接 nState=RevDataBit;
例如,
3、例程 是 每次 第 8 个脉冲时进行RXD采样,采取 “只取中间一个值” 的原则来确定接收的数据,与C51 “三中取二”的原则不一致。
- RevDataBit:
- begin
- if(Cnt8==4'd8&&Cnt16==4'd15)//采完8个bits后停止
- nState=RevStopBit;
- else
- nState=RevDataBit;
- end
复制代码
其他几个状态转移条件判断 类似理解。
********************************
//各个状态的时序控制
always @ (posedge ClkIn or negedge Resetb)
if(!Resetb)
begin
Cnt16<=4'b0;
Cnt8<=3'b0;
RxReady<=1'b0;
end
else
case(nState)
Idle:
Idle 时序控制;
RevStartBit:
RevStartBit 时序控制;
RevDataBit:
RevDataBit 时序控制;
RevStopBit:
RevStopBit 时序控制;
RevDone:
RevDone 时序控制;
endcase
通过 RevDataBit 时序控制 来辅助理解,
3、例程 是 每次 第 8 个脉冲时进行RXD采样,采取 “只取中间一个值” 的原则来确定接收的数据,与C51 “三中取二”的原则不一致。
- RevDataBit:
- begin
- Cnt16<=Cnt16+1'b1;
- if(Cnt16==7)//在中间采样
- begin
- RxDataBuf[Cnt8]<=RxdIner;
- Cnt8<=Cnt8+1'b1;
- end
复制代码
可以看出 当 Cnt16 ==7 时,进行采样,此时 缓冲 RxDataBuf[Cnt8]<=RxdIner;
这里 RxdIner 其实 就是 Rxd,只不过这个例程 加了一个 D触发器,去除数据线上的干扰,
**********************
//D触发器,去除数据线上的干扰
always @ (posedge ClkIn or negedge Resetb)
if(!Resetb)
RxdIner<=1'b1;
else
RxdIner<=Rxd;
*********************
其他时序控制 也用类似方法理解。
这样 接收 模块 就有了 整体理解。