首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

Verilog状态机的编写学习

Verilog状态机的编写学习

时序电路的状态是一个状态变量集合,这些状态变量在任意时刻的值都包含了为确定电路的未来行为而必需考虑的所有历史信息
状态机采用VerilogHDL语言编码,建议分为三个always段完成。
三段式建模描述FSM的状态机输出时,只需指定case敏感表为次态寄存器, 然后直接在每个次态的case分支中描述该状态的输出即可,不用考虑状态转移条件。三段式描述方法虽然代码结构复杂了一些,但是换来的优势是使FSM做到了同步寄存器输出,消除了组合逻辑输出的不稳定与毛刺的隐患,而且更利于时序路径分组,一般来说在FPGA/CPLD等可编程逻辑器件上的综合与布局布线效果更佳。
示列如下:
[url=][/url]
//第一个进程,同步时序always模块,格式化描述次态寄存器迁移到现态寄存器always @ (posedge clk or negedge rst_n)  //异步复位 if(!rst_n)   current_state <= IDLE; else   current_state <= next_state;//注意,使用的是非阻塞赋值//第二个进程,组合逻辑always模块,描述状态转移条件判断always @ (current_state)   //电平触发  begin    next_state = x;  //要初始化,使得系统复位后能进入正确的状态    case(current_state)    S1: if(...)       next_state = S2;  //阻塞赋值    ...    endcaseend//第三个进程,同步时序always模块,格式化描述次态寄存器输出always @ (posedge clk or negedge rst_n)//初始化 case(next_state)S1:   out1 <= 1'b1;  //注意是非阻塞逻辑S2:   out2 <= 1'b1;default:...   //default的作用是免除综合工具综合出锁存器。endcaseend[url=][/url]


三段式并不是一定要写为3个always块,如果状态机更复杂,就不止3段了。附一个比较好的状态机范例:[url=][/url]
01 module FSM(clk,rst,in,out);02 input clk,rst;03 input [7:0] in;04 output [7:0] out;05 06 parameter [1:0] //synopsys enum code07 START = 2'd0,08 SA = 1,09 SB = 2,10 SC = 3;11 12 reg [1:0] CS,NS;13 reg [7:0] tmp_out,out;14 15 // state transfer16 always @ (posedge clk or negedge rst)17 begin18 if (!rst) CS <= #1 START;19 else      CS <= #1 NS;20 end21 22 // state transfer discipline23 always @ (in or CS)24 begin25     NS = START;26     case (CS)27        START: case (in[7:6])28                        2'b11: NS = SA;29                        2'b00: NS = SC;30                        default: NS = START;31                        endcase32        SA: if(in == 8'h3c) NS = SB;33        SB: begin34                 if (in == 8'h88) NS = SC;35                 else             NS = START;36                 end37        SC: case(1'b1) //synopsys parallel_case full_case38                 (in == 8'd0): NS = SA;39                 (8'd0 < in && in < 8'd38): NS = START;40                 (in > 8'd37): NS = SB;41                   endcase42        endcase43 end44 45 // temp out46 always @ (CS)47 begin48     tmp_out = 8'bX;49     case (CS)50        START: tmp_out = 8'h00;51        SA:   tmp_out = 8'h08;52        SB:   tmp_out = 8'h18;53        SC:   tmp_out = 8'h28;54     endcase55 end56 57 // reg out58 always @ (posedge clk or negedge rst)59 begin60     if (!rst) out <= #1 8'b0;61     else     out <= #1 tmp_out;62 end63 64 endmodule[url=][/url]
继承事业,薪火相传
返回列表