学习Verilog的五个阶段
00:心中无电路,代码无电路
01:心中有电路,代码无电路
10:心中有电路,代码有电路
11:心中无电路,代码有电路
00:心中无电路,代码无电路
经过多少次将写好的电路推到重构,经过多少次否定之否定的哲学沉思。终于明白一切数字逻辑不都可以归一化为一个有限状态机吗?00—01—10—11—00这不也是一个状态循环么!
万物基于状态机
我们知道所有的数字电路都可以抽象为组合逻辑+时序逻辑,任何时序逻辑都可以通过有限状态机描述,即使是组合逻辑也可以描述成单个状态的状态机。
上图:
是不是看着很眼熟,变换一下
任何算法计算或逻辑过程都可以简化为一坨组合逻辑云,然后再加一个D触发器打拍输出。常见的三段式状态机,第二段组合逻辑状态转移,再加时序逻辑保存当前状态,所以任何的数字逻辑在理论上都可以描述为状态机,万物基于状态机。
当然,要是写一个计数器都准备写成状态机那就,,就是徒增功耗而已。
三段式状态机
//第一段
always @(posedge clk or negedge rst_n)begin
if(!rst_n)
pre_state[2:0] <= IDLE;
else
pre_state[2:0] <= next_state;
end
//第二段
always @(*)begin
next_state[2:0] = pre_state;
case(pre_state)
IDLE:begin
if(init_end)
next_state = ARBIT;
end
ARBIT:begin
if(ref_en)
next_state = A_REF;
else if(wr_en)
next_state = WRITE;
else if(rd_en)
next_state = READ;
end
A_REF:begin
if(ref_end)
next_state = ARBIT;
end
WRITE:begin
if(wr_end)
next_state = ARBIT;
end
READ:begin
if(rd_end)
next_state = ARBIT;
end
default: next_state = IDLE;
endcase
end
//第三段
//组合逻辑或时序逻辑赋值用pre_state做条件
要用到状态机直接默认上三段式状态机,前人总结的经验以及业界公认。
小Tips,在写状态机时,将第二段需要保持状态循环的状态写法,写成这样的写法,可以省去很多else的分支。
仲裁状态机
在SDRAM控制器的设计中有一种设计方法,是仲裁状态机的设计,在SDRAM初始化操作进行完成后,进入上图所示的ARBIT仲裁状态,当SDRAM需要进行自刷新或读写操作,产生一个req请求信号,如果状态机正在处于仲裁状态,也就是当前无其他操作,就产生一个en使能信号进入对应的状态进行操作,操作完成后产生一个done信号回到仲裁状态。
当状态机正在处于读或写状态时,如果自刷新请求也同时到来,状态机在READ/WRITE状态,则刷新请求一直存在,当进行完一个burstlength的读或写操作,也就是一个突发长度的操作后回到ARBIT状态(仲裁状态),这时才会产生ref_en(自刷新使能)。读写也是同样的逻辑,这也是仲裁状态机设计的关键。
主从状态机
上面的状态机其实就是SDRAM设计的主控制状态机,进入到读写或自刷新操作状态,里面也是使用的状态机描述,也就运用到了主从状态机的设计,画个图意思一下。
这里主要体现的是主从状态机的串行化,即在从状态机跳转时,主状态机会一直在该状态等待。
还有一种设计方法主从状态机并行化,在主状态机启动从状态机后,继续完成主机的状态,然后另一个某个状态中等待从机的操作结束标志,这样的状态机设计会复杂,但是可以提高整个系统的速度。本文只提一下不展开讨论。
状态机大法好
在一个数字芯片设计中,可能包含了成百上千个有限状态机。对于控制流的设计基本上都是首选状态机,每个状态最理想的设计就是,start信号和over信号都是pulse,脉冲信号来控制这个状态的跳入跳出。状态划分越多,代表你这个状态干的事情越少,跳转条件就越简单。
有一点,如果整体设计有很长的一段是流水线操作,用状态机描述反而有些别扭,因为整个流水线中操作很多而且是同时操作,状态名不好起,也不好打断,所以应该直接定义为一个状态,然后控制流水线的启动和结束就行了。
状态机确保命名有确定的含义,一个状态做一件特定功能的事情,所谓代码即注释
状态机加看门狗定时器。在设计状态机时为了防止状态机卡死在某个状态死循环,可以加个看门狗定时器,玩过单片机或DSP的朋友肯定很熟悉,看门狗定时器(Watch Dog Timer,WDT),其实就是一个计数器,在初始状态给计数器赋值一个很大的值,当状态机或程序开始运行后,计数器开始倒计数,如果状态机或程序运行正常,每隔一段时间发出指令或给计数器重新load一个大初始值,重新开始倒计数,如果计数到0就认为状态机或程序卡死,需要强制整个系统复位。
load初始值整个操作被戏称为“喂狗”,一段时间没有喂狗,看门狗就会叫。
最后
感谢阅读到最后,关于有限状态机你还有哪些要告诉我的,请在留言区留言。你点起来真好看。
References
《通信IC设计》——李庆华
如何才能看到verilog,就知道综合出来的电路呢?www.zhihu.com