有限状态机
1.米利型:输出和当前状态和输入有关
2.摩尔型:输出只与输入有关
编码方式:
1.2进制编码:二进制编码状态,当跳转导致多个bit位改变时会有毛刺
2.格雷码:状态跳转时,只有一个位变化,毛刺少一些
3.one hot:n个状态就选n个bit位编码,:0001,0010,0100,1000
代码方式:
两段式:输出方程+激励方程,状态转移方程
//(两段式)
//第一个进程,同步时序always模块,格式化描述次态寄存器迁移到现态寄存器
always @(posedge clk or negedge rst_n);
if (!rst_n) current_state<=IDLE;
else current_state<=next_state;//使用非阻塞赋值
//第二个进程,组合逻辑always模块,描述状态转移条件判断
always @(current_state);//电平触发
case(current_state)
S1:if(..)
next_state <=S2;
out1<=1'b1;
...
endcase
end
三段式:输出方程,激励方程,状态转移方程
//第一个进程,同步时序always模块,格式化描述次态寄存器迁移到现态寄存器
always @(posedge clk or negedge rst_n);
if (!rst_n) current_state<=IDLE;
else current_state<=next_state;//使用非阻塞赋值
//第二个进程,组合逻辑always模块,描述状态转移条件判断
always @(current_state);//电平触发
case(current_state)
S1:if(..)
next_state =S2;//阻塞赋值
...
endcase
end
//第三个进程,同步时序always模块,格式化描述次态寄存器输出
always @(posedge clk or negedge ret_n);//电平触发
case(current_state)
S1:
out<=1'b1;//非阻塞赋值
S2:
out<=1'b1;
default:..//避免综合工具综合出锁存器
...
endcase
end
一、设计4位顺序脉冲发生器
功能描述:
有4路输出W0, W1, W2, W3,每路输出上高电平脉冲依次出现,在1000,0100,0010,0001之间循环。
状态转移图:
代码实现:
module datagen_4(OUT,clk);
input clk;
output [3:0]OUT;
reg [3:0]OUT;
reg [1:0]current_state, next_state;
always@(current_state)
case(current_state)
2'b00:
begin
OUT<=4'b1000;
next_state<=2'b01;
end
2'b01:
begin
OUT<=4'b0100;
next_state<=2'b10;
end
2'b10:
begin
OUT<=4'b0010;
next_state<=2'b11;
end
2'b11:
begin
OUT<=4'b0001;
next_state<=2'b00;
end
endcase
always@(posedge clk)
current_state<=next_state;
endmodule
仿真波形:
二、设计一个自动售货机,饮料8角,硬币有1角,2角,5角,一元,不考虑投币为大面额(如:不会投了5角之后投1元,要么直接投1元,要么投5角不够再投1,2,5角)
状态转移图:
S0表示没有投币,角标表示投币总和,如S1表示投了1角,M表示输入,角标表示硬币面额
代码实现:
data_out=1时饮料送出,data_return1=1表示找回1角钱,data_return2=1表示找回2角钱
仿真波形:
三、“11010”序列检测器
功能描述:当输入端出现序列11010时,输出为1,否则为0。当出现指定的序列后,重新开始检测。
状态转移图:
代码实现:
module checkerlist(clk,OUT,rst_n,data_in);
parameter IDLE=3'd000,A=3'b001,B=3'b010,C=3'b011,D=3'b100,E=3'b101;
input data_in,clk,rst_n;
output OUT;
reg [2:0]current_state,next_state;
wire OUT;//assign语句不能赋值reg类型
assign OUT=(current_state==E?1:0);
initial current_state<=3'b000;
always@(posedge clk or negedge rst_n)
if (!rst_n) current_state=IDLE;
else
case(current_state)
IDLE:
if (data_in) next_state=A;
else next_state=IDLE;
A:
if (data_in) next_state=B;
else next_state=IDLE;
B:
if (!data_in) next_state=C;
else next_state=B;
C:
if (data_in) next_state=D;
else next_state=IDLE;
D:
if (!data_in) next_state=E;
else next_state=B;
E:
if (data_in) next_state=A;
else next_state=IDLE;
default:next_state=IDLE;
endcase
always@(posedge clk)
current_state<=next_state;
endmodule
Verilog测试程序设计
一、全加器
(1)设计代码
module adder(A,B,CI,SO,CO);
input A,B,CI;
output SO,CO;
assign {CO,SO}=A+B+CI;
endmodule
(2)测试代码
module adder_tb;
wire SO,CO;
reg A,B,CI;
adder U1(A,B,CI,SO,CO);
initial
begin
A=0;B=0;CI=0;
#20 A=0;B=0;CI=1;
#20 A=0;B=1;CI=0;
#20 A=0;B=1;CI=1;
#20 A=1;B=0;CI=0;
#20 A=1;B=0;CI=1;
#20 A=1;B=1;CI=0;
#20 A=1;B=1;CI=1;
#200 $finish;
end
endmodule
仿真波形:vivado2017