1.问题描述:
将下面的状态转移图用Verilog HDL描述。在图中,状态机的输入只与状态的跳转有关,与状态机的输出无关,因此该状态机为摩尔型状态机。下面为三段式描述方式。
2.问题分析:
状态机分为moore型和mealy型,moore型状态机的输出只和此时的状态有关,而mealy型的输出不仅和状态有关,还和此时的输入有关。本题描述的状态机是一个典型的moore机。
状态机的关键之一是对状态的编码,常用的状态机编码方式有:顺序(sequential)编码,一位热码(one-hot),格雷码(gray),以及约翰逊编码(johnson)方式。在这里的状态数是4个,采用顺序编码即可,即采用一个二位二进制数对状态机进行编码。
状态机的另一个关键是编写风格,可以采用三个always进行描述,分现态、状态转换、输出逻辑三个模块;也可以采用两个always模块,分现、次态转换、输出逻辑两个模块;也可以卸载一个always语句中。有图可知,此状态机一共有四个状态,用顺序编码表示为:00,01,10,11。而后用case来进行状态检测,用if语句来进行操作判断。
3. 程序内容
.v文件:
`timescale 1ns / 1ps
module moore(clr,clk,out,step);
input clr,clk,step; //状态机是一个时序电路,因此一定有clk存在
//clr是复位信号,检测到clr置高时,对信号进行复位
output reg [2:0]out; //后面需要在always语句中对out进行赋值
reg [1:0] state;
parameter ST0=2'b00,ST1=2'b01,
ST2=2'b10,ST3=2'b11;
always @(posedge clk or posedge clr)
begin
if(clr==1)
state<=ST0;
else
case(state)
ST0:begin
if(step==1) state<=ST1;
else if(step==0) state<=ST0;
out=3'b001;
end
ST1:begin
state<=ST2;
out=3'b010;
end
ST2:begin
if(step==0) state<=ST0;
else if(step==1) state<=ST3;
out=3'b100;
end
ST3:begin
if(step==0) state<=ST3;
else if(step==1) state<=ST0;
out=3'b111;
end
default: state<=0;
endcase
end
endmodule
tb文件:
`timescale 1ns / 1ps
module tb();
reg clr, step;
wire [2:0]out;
reg clk;
always #1 clk=~clk;//生成最小单位频率的时钟
moore my_moore(.clr(clr),.clk(clk),.out(out),.step(step));
initial begin
clr=1;
clk=1'b0;
step=0;//初始复位信号;
#2 clr=0;//二单位时间后,结束复位,开始工作
#2 step=0;
#2 step=1;
#2 step=0;
#2 step=1;
#2 step=0;
#2 step=1;//完成了一个大圈的循环
#2 step=0;
#2 step=1;
#2 step=1;
#2 step=0;//完成了一个小圈的循环
#2 step=1;
#2 step=1;
#2 clr=1; //检测复位是否正常
end
//测试中的闲置时间至少要是一倍时钟周期!否则可能时钟上升沿检测不到信号变化。
endmodule
4. 实验结果
开始的一个时间单位内,没有对state进行赋值,因此out为x,而后,根据测试信号,先进行了一次状态圈的大循环,1—2—4—7,在进行一次小循环1—2—4—1,最后,复位信号置高后,输出维持为2。测试和预期功能完全一致。