Spartan6 学习笔记(四)——UART

---恢复内容开始---

最近尽一个星期都在研究UART的实现,主要是把以前的检起来,进度有点慢,不过结果还算满意。

用的方式是16个采样周期一计算,如果0的个数大于9就认为是0,小于7就认为是1,开始位检查值是11。这个方式有点啰嗦,是从清华徐文波的书上看的方法,稍加修改

经过反复的验证调试,基本能实用了。下面要了解的是三段式的状态机。

三段式代码多,但是有时钟同步,延时少,组合逻辑跟时序逻辑分开并行出错少。

(1)同步状态转移 (2)当前状态判断接下来的状态 (3)动作输出

如果程序复杂可以不止三个always   。always 后常接case  case必须有default,对于FPGA常用 状态数较少,独热码编码 ,或者格雷码

//独热码编码

parameter NO_KEY_PRESSED = 6'b000_001; // 没有按键按下 
parameter SCAN_row0 = 6'b000_010; // 扫描第0行 
parameter SCAN_row1 = 6'b000_100; // 扫描第1行
parameter SCAN_row2 = 6'b001_000; // 扫描第2行 
parameter SCAN_row3 = 6'b010_000; // 扫描第3行 
parameter KEY_PRESSED = 6'b100_000; // 有按键按下

reg [5:0] current_state, next_state; // 现态、次态

(1)第一个always模块,格式化描述次态寄存器迁移到现态寄存器

always @ (posedge key_clk, negedge rst_n) //异步复位
if (!rst_n)
current_state <= NO_KEY_PRESSED;//初始化按键没按下 //默认状态
else
current_state <= next_state;    //注意,使用的是非阻塞赋值

(2)第二个进程,组合逻辑always模块,描述状态转移条件判断用current_state

always @ (current_state) //电平触发      或者always @ *

begin

next_state = x; //要初始化,使得系统复位后能进入正确的状态

case(current_state)

S1: if(...)

next_state = S2;     //阻塞赋值

...

endcase

end

 

(3)第三个进程,同步时序always模块,描述次态寄存器输出

always @ (posedge clk or negedge rst_n)

...//初始化

case(next_state)  //注意是下一个状态

S1:

out1 <= 1'b1; //注意是非阻塞逻辑

S2:

out2 <= 1'b1;

default:... //default的作用是免除综合工具综合出锁存器。

endcase

end

 

三段式并不是一定要写为3个always块,如果状态机更复杂,就不止3段了。

1. 三段always模块中,第一个和第三个always模块是同步时序always模块,用非阻塞赋值( <= );第二个always模块是组合逻辑always模块,用阻塞赋值( = )。

2. 第二部分为组合逻辑always模块,为了抑制warning信息,对于always的敏感列表建议采用always@(*)的方式。

3. 第二部分,组合逻辑always模块,里面判断条件一定要包含所有情况!可以用else保证包含完全。

4. 第二部分,组合逻辑电平要维持超过一个clock,仿真时注意。

5. 需要注意:第二部分case中的条件应该为当前态(current_state)。

6. 第三部分case中的条件应该为次态(next_state)。

7. 编码原则,binary和gray-code适用于触发器资源较少,组合电路资源丰富的情况(CPLD),对于FPGA,适用one-hot code。这样不但充分利用FPGA丰富的触发器资源,还因为只需比较一个bit,速度快,组合电路简单。

http://blog.sina.com.cn/s/blog_4df28f050101ilqo.html两种状态机

摩尔状态机和米粒状态机的区别

图1描述了一个经典状态机的示意图。其中,x(t)为当前输入;z(t)为当前输出;状态寄存器(也就是一组触发器)输出s(t)为现态;组合逻辑电路输出s(t+1)则为次态。
摩尔状态机和米粒状态机的区别
                1 米粒状态机 
 
通常会把图1中的组合逻辑电路模块分成C1和C2两个部分,如图2所示。组合逻辑模块C1有两个输入端,分别为当前输入x(t)和现态s(t), 其输出为次态s(t+1)。组合逻辑模块C2也将当前输入x(t)和现态s(t)作为其两个输入端,输出为z(t)。像这样输出z(t)取决于当前输入 x(t)和现态s(t)两个信号的状态机,我们称之为米里状态机(Mealy State Machine)。
如果输出z(t)仅取决于现态s(t),如图3所示,我们称这种状态机为摩尔状态机(Moore State Machine)。
摩尔状态机和米粒状态机的区别
           2 米粒状态机
摩尔状态机和米粒状态机的区别
            3 摩尔状态机
 
Moore型与Mealy型两种状态机的不同点在于,Moore型状态机的输出信号是直接由状态寄存器译码得到,而Mealy型状态机则是以现时的输入信号结合即将变成次态的现态,编码成输出信号。

---恢复内容结束---

猜你喜欢

转载自www.cnblogs.com/ManRenFei/p/9110242.html