一段、两段及三段式状态机的写法——售货机的verilog实现
文章目录
- 1、 状态机的Verilog分类、写法、编码方式
- 状态机的分类
- 状态机的写法
- 状态机编码方式
- 2、根据状态转移图写状态机
- 3、售货机的状态机设计
1、 状态机的Verilog分类、写法、编码方式
状态机:简单说是通过不同的状态迁移来完成一些特定的顺序逻辑。
状态机的分类
(1)Moore型:状态机的输出仅和当前状态有关。
(2)Mealy型:状态机的输出不仅与当前的状态有关,还取决于当前的输入条件。
.
当两者实现同一种功能的时候,Moore型状态机需要比Mealy型状态机多定义一个状态,且输出也比米利型延后一个时钟周期。这里之所以多一个状态,是因为Moore型的输出只取决于当前状态,因此需要有一个中间状态来产生一个输出。
用代码来区别两种状态机:
// Moore型
assign out = state == B ;//表示,输出只和状态B有关,当状态为B的时候,不管输入是多少,都输出1。
// Mealy型
assign out = ((state == B) && (in == 1)) ; //表示输出和状态以及输入有关,当状态为B且输入等于1的时候输出1.
用状态图来区别两种状态机:
比如用用两种方式,来实现同一功能的状态机。
Mealy型如下:
Moore型如下:(多一个状态)
状态机的写法
状态机一般包括三种写法:一段式、两段式和三段式。
(1)一段式:整个状态机写到一个always块里面,在该块中既描述状态寄存器,又描述状态转移和输出;
(2)二段式:用两个always块来描述状态机,一个always块采用同步时序描述状态转移;另一个块采用组合逻辑判断状态转移条件和状态输出;
(3)三段式:使用三个always块,一个always块采用同步时序描述状态转移,一个always采用组合逻辑判断状态转移条件,描述状态转移规律,另一个always块描述状态输出(可以用组合电路输出,也可以时序电路输出)。
状态机编码方式
独热码、格雷码。
独热码永远只有一位为1,缺点:用独热码后会有多余的状态;优点:可减少组合逻辑资源的消耗,比如在描述输出的时候,当采用组合逻辑进行比较的时候,可以只用其中的一位。assign state = S1[0] ;
格雷码相邻两个数只有一位不同;优点:状态少,而且可以避免毛刺出现;缺点:消耗组合逻辑资源多。assign state = S1;
注意:写case语句时,需要要加上default的情况,不然的话,会生成锁存器(跟电平有关),但在时序逻辑中,不加default生成的不是锁存器,是触发器。其中default分支可以用默认项表示,也可以用确定向来表示,以确保能最初状态。
2、根据状态转移图写状态机
小例子:
假如有三个状态,IDLE,S1,S2,在IDLE状态的时候,若en=1,则进入到S1状态,否则保持原状态不变。在S1状态的时候,若en=1,则进入到S2状态,否则保持原状态不变。在S2状态的时候,若en=1,则进入到IDLE状态,同时输出vld=1,否则保持原状态不变。
module state(clk,rst_n,en,vld);input clk,rst_n;input en;output reg vld;reg [2:0] state;localparam IDLE= 3'b001; //parameter声明全局常量,可用在整个工程中,localparam仅在当前module中有效localparam S1= 3'b010;localparam S2= 3'b100;reg [2:0] state_n;reg [2:0] state_c;always @ (posedge clk or negedge rst_n)beginif(!rst_n)state_c <= IDLE;else state_c <= state_n; endalways @(*) begincase(state_c)IDLE:beginif(en) state_n = S1;elsestate_n = IDLE; endS1:beginif(en) state_n = S2;elsestate_n = S1; endS2:beginif(en) state_n = IDLE;elsestate_n = S2; endendcaseendalways @(posedge clk or negedge rst_n)beginif(!rst_n)vld <= 0;else if (state_c == S2 && en==1)vld<=1;elsevld <= 0; end
endmodule
testbench
`timescale 1ns/1ps //时间精度
`define Clock 20 //时间周期
module state_tb;reg clk,rst_n;reg en;wire vld;
state state1(.clk(clk),.rst_n(rst_n),.en(en),.vld(vld) );//-- 状态机名称查看器localparam S0 = 4'b0001 ;
localparam S1 = 4'b0010 ;
localparam S2 = 4'b0100 ;
//2字符16位 这里是用ASICC表示,其中的S0就是IDLE
reg [15:0] state_name ;always@(*)begincase(state1.state_c)S0: state_name = "S0";S1: state_name = "S1";S2: state_name = "S2";default:state_name = "S0";endcase
end initial clk = 0;
always #(`Clock/2) clk= ~clk;initial beginrst_n=0; #(`Clock*3);rst_n=1;
end initial beginen=0;#(`Clock);en=1;#(`Clock);en=0;#(`Clock);en=0;#(`Clock*2); en=1;#(`Clock*2);en=1;#(`Clock*2);en=0;#(`Clock*2);en=1;#(`Clock*2);en=1;#(`Clock*2);en=1;#(`Clock*2);en=0;#(`Clock*2);en=1;#(`Clock*2);en=1;#(`Clock*2);en=0;#(`Clock*2);en=0;#(`Clock*2);en=1;#(`Clock*2); en=0;#(`Clock*2);en=1;#(`Clock*2);en=0;#(`Clock*50);$stop;
end
endmodule
3、售货机的状态机设计
举例子:设计一个关于售货机的状态机,要求只能投入一元和两元钱,脉动饮料的价格是四元,若超出则找零,否则不找,当达到四元时,给出脉动饮料,否则不给。
IDLE:初始状态,未投币或者已取出饮料。S0 :投币一元的状态。S1:投币两元的状态。S2:投币3元的状态。S3:投币4元的状态。(对应输出饮料)S4:投币5元的状态。(对应找零)
三段式的写法进行verilog编写:
module Sys_Rst(input clk,input rst_n,input [1:0] data,output flag_0, //找零output flag_1 //出饮料);parameter IDLE = 0,S0 = 1,S1 = 2,S2 = 3,S3 = 4,S4 = 5;reg [3:0] cur_state,next_state;//第一段
always @(posedge clk or negedge rst_n)if(rst_n == 1'b0)cur_state <= IDLE;elsecur_state <= next_state;//第二段
always @(*)case(cur_state)IDLE : beginif(data == 2'b01 )next_state <= S0;else if(data == 2'b10) next_state <= S1;else next_state <= IDLE;endS0 : beginif(data == 2'b01 )next_state <= S1;else if(data == 2'b10) next_state <= S2;else next_state <= S0;endS1 : beginif(data == 2'b01 )next_state <= S2;else if(data == 2'b10) next_state <= S3;else next_state <= S1;endS2 : beginif(data == 2'b01 )next_state <= S3;else if(data == 2'b10) next_state <= S4;else next_state <= S2;endS3 : next_state <= IDLE; S4 : next_state <= IDLE;default: next_state <= IDLE;endcase//输出
assign flag_0 = (cur_state == S4)? 1'b1: 1'b0; //找零
assign flag_1 = (cur_state == S3)? 1'b1: 1'b0; //出饮料
endmodule
testbench编写:
`timescale 1ns/1nsmodule Sys_Rst_tb;reg clk;reg rst_n;reg[1:0] d; //序列输入 wire flag_0 ; wire flag_1 ; Sys_Rst u1 (.clk(clk),.rst_n(rst_n),.data(d), //序列输入.flag_0(flag_0),.flag_1(flag_1));parameter IDLE = 0,S0 = 1,S1 = 2,S2 = 3,S3 = 4,S4 = 5;//4字符16位
reg [31:0] state_name ;always@(*)begincase(u1.cur_state)IDLE: state_name = "IDLE";S0: state_name = "S0";S1: state_name = "S1";S2: state_name = "S2";S3: state_name = "S3";S4: state_name = "S4"; default: state_name = "IDLE";endcase
end//
initial clk = 0;always #1 clk = ~clk;
//
initial beginrst_n = 0;#1;rst_n = 1;
end
//
initial begind = 2'b01; //1元#2;d = 2'b10; //2元#2;d = 2'b01; //1元 #2;d = 2'b01; //1元#2;d = 2'b01; //1元#2;d = 2'b01; //1元#2;d = 2'b10; //2元 #2;d = 2'b01; //1元#3;d= 2'b10; //2元#20;$stop;endendmodule
波形如下:
其中S3表示投入共四元,因此出饮料,因此flag_1拉高。
S3表示投入超过了四元,因此找零,因此flag_0拉高。
售货机如果有错误请指正~
一段、两段及三段式状态机的写法——售货机的verilog实现相关推荐
- 三段式状态机_Verilog实战篇(5)——FIFO amp; 状态机
今天的暑期培训课依旧是由邸志雄老师主讲:FIFO基本原理及状态机的编写和应用. 下面先说一下FIFO: 一.FIFO 常见参数主要有: 1. FIFO的宽度:即 FIFO 一次读写操作的数 ...
- 一段式、两段式以及三段式状态机(FSM)设计实例
一段式.二段式以及三段式状态机(FSM)设计实例 状态机(FSM)分类 状态转移的三种编码方式 一段式.两段式状态机(FSM)区别 vivado与modelsim联调显示状态机 设计实例 状态转移图 ...
- 三段式状态机_FPGA笔试题——序列检测(FSM状态机)
FSM有限状态机,是FPGA和数字IC相关岗位必须要掌握的知识点,在笔试和面试中都非常常见. (1)了解状态机:什么是摩尔型状态机,什么是米利型状态机,两者的区别是什么?一段式.二段式.三段式状态机的 ...
- fpga时序逻辑(三段式状态机模板、rom实现、边沿检测)
目录 VL21 根据状态转移表实现时序电路 VL22 根据状态转移图实现时序电路 VL23 ROM的简单实现 VL24 边沿检测 VL21 根据状态转移表实现时序电路 题目分析: 1.使用三段式状态机 ...
- DSP嵌入式C语言状态机,三段式状态机描述及模版
三段式状态机描述及模版 [复制链接] 本帖最后由 Aguilera 于 2018-11-10 20:23 编辑 时序电路的状态是一个状态变量集合,这些状态变量在任意时刻的值都包含了为确定电路的未来行为 ...
- 小梅哥三段式状态机按键消抖改写
小梅哥三段式状态机按键消抖改写 小梅哥资料中按键消抖部分是用一段式.二段式状态机写的.我用三段式状态机改写了一下,仿真和板载测试通过. 代码记录如下: module key_filter1(input ...
- 三段式状态机-FSM
三段式代码多,但是有时钟同步,延时少,组合逻辑跟时序逻辑分开并行出错少. (1)同步状态转移 (2)当前状态判断接下来的状态 (3)动作输出 如果程序复杂可以不止三个always .always ...
- 重迭式三段式状态机序列检测器-检测10110110
重迭式三段式状态机序列检测器-检测10110110 要求:序列检测器 clk input clock input rst_n input asynchronous reset, low active ...
- 基于verilog的三段式状态机
三段式状态机的优势:三段式描述方法与一段式和两段式状态机描述相比,虽然代码结构复杂了一些,但是换来的优势是使FSM(Finite State Machine)做到了同步寄存器输出,消除了组合逻辑输出的 ...
- SJA1000 CAN总线verilog写的SJA1000 CAN总线控制器。 程序使用三段式状态机,对于语句均有箱子的中文注释
SJA1000 CAN总线verilog写的SJA1000 CAN总线控制器. 程序使用三段式状态机,对于语句均有箱子的中文注释,同时还有相关的文档说明. 可直接拿来使用,同时适合新手学习规范写作代码 ...
最新文章
- 陆奇全面解读 AI 创业创新发展趋势,创业公司应该如何把握住机会?
- 【Spring】23、ApplicationContext ,ApplicationContextAware,Listener,Event 的关系解读
- 【Linux 内核 内存管理】内存管理架构 ① ( 内存管理架构组成 | 用户空间 | 内核空间 | MMU 硬件 | Linux 内核架构层次 | Linux 系统调用接口 )
- 汇编的8种寻址方式,以及2个默认段寄存器
- python爬取公众号历史文章_python爬微信公众号前10篇历史文章(6)-话说http cookies...
- abstract类中不可以有private的成员_别再说你不懂java面向对象了,阿里P7大佬一次性给你讲的明明白白
- 佛缘——宝华山隆昌寺之行
- Java的MD5加密和解密
- 聊聊 Java8 以后各个版本的新特性
- ip68级防水可以泡多久_iPhone8防水级别升级至IP68:能在1.5米深水中坚持30分钟
- 数控加工中心编程和UG编程和什么区别
- uart项目验证(一)-uart协议与uart ip的理解
- 神经网络中Batch和Epoch之间的区别是什么?
- STKMATLAB connect(四)卫星
- elasticsearch安装 及 启动异常解决
- 谭波 oracle,行动营复盘
- 怎么提醒自己每晚睡前喝牛奶
- 酷派t2co1怎么升Android5,而且双清不了怎么办Coolpad725?酷 – 手机爱问
- 解决No thread-bound request found: Are you referring to request attributes outside of an actual web.异常
- Linux 命令ps aux命令解析