目录
一、理论部分
状态机的作用:FPGA为并行执行的,若想处理具有前后顺序的事件,则需要用到状态机。
Moore型状态机:输出只与当前状态有关,而与输入无关。
Mealy型状态机:输出与当前状态、输入均有关。
共同点是状态的跳转都只和输入有关。
二、模块框图
包含三个输入信号:系统时钟(sys_clk)、复位信号(sys_rst_n)以及投币信号(pi_money)。
一个输出信号:输出可乐(po_cola)。
三、状态转移图
(一次投币信号算作投币一元,故每三次投币信号才能输出一个可乐)
“/”左边为输入,右边为输出。
Mealy型状态机状态转移图:
Moore型状态机状态转移图:
因Mealy型状态机更节省逻辑资源,故使用Mealy型状态机完成本实验。
四、波形图
1、时钟与复位信号
2、投币信号
(随机画出)
3、状态信号
4、输出信号
五、代码部分
1、三种码型
独热码:
综合时节省组合逻辑的资源,但位宽较长。
二进制码:
位宽少,因此减少了寄存器资源的使用,但综合器综合时无法进行比较器的优化,因此使用的组合逻辑资源较多。
格雷码(相邻参数只有一个比特不同,例如00与01,01与11):
状态数较多(位宽较大)时使用,寄存器资源使用较少,组合逻辑资源使用较多,
以上三种编码均可,因FPGA中组合逻辑资源较少,相对来说寄存器资源较多,所以使用独热码较好,此实验采用独热码。
总结:
低速系统中,如果状态机状态的个数小于四个,使用二进制码;
状态个数介于4~24个,使用独热码,
状态个数大于24个,使用格雷码。
高速系统中,无论状态个数是多少,最好都使用独热码。
2、状态机的三种写法
一段式:
在一段的状态机中使用时序逻辑,即描述状态的转移,又描述状态的输出。
较难表述大型状态机。
二段式:
分两段状态机,第一段状态机中使用时序逻辑描述状态的转移;在第二段状态机中使用组合逻辑描述数据的输出。
结构和理想的理论模型完全吻合,但第二段为组合逻辑,部分情况无法准确描述。
三段式:
第一段状态机中使用时序逻辑描述状态转移;第二段状态机中采用组合逻辑判断状态转移条件,描述状态转移规律;第三段状态机中描述状态转移输出,组合逻辑与时序逻辑均可。
此实验采用新式二段式状态机,均使用时序逻辑进行描述。
第一个always块描述状态的转移,第二个always块描述输出信号。
3、Verilog代码
module simple_fsm
(
input wire sys_clk,
input wire sys_rst_n,
input wire pi_money,
output reg po_cola
);
parameter IDLE = 3'b001;
parameter ONE = 3'b010;
parameter TWO = 3'b100;
reg [2:0] state;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
state <= IDLE;
else case(state)
IDLE: if(pi_money == 1'b1)
state <= ONE;
else
state <= IDLE;
ONE: if(pi_money == 1'b1)
state <= TWO;
else
state <= ONE;
TWO: if(pi_money == 1'b1)
state <= IDLE;
else
state <= TWO;
default:state <= IDLE;
endcase
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
po_cola <= 1'b0;
else if((pi_money == 1'b1)&&(state == TWO))
po_cola <= 1'b1;
else
po_cola <= 1'b0;
endmodule
4、tb仿真代码
`timescale 1ns/1ns
module tb_simple_fsm();
reg sys_clk;
reg sys_rst_n;
reg pi_money;
wire po_cola;
initial
begin
sys_clk = 1'b1;
sys_rst_n <= 1'b0;
#20
sys_rst_n <= 1'b1;
end
always #10 sys_clk = ~sys_clk;
always@(posedge sys_clk or negedge sys_rst_n)
if(sys_rst_n == 1'b0)
pi_money <= 1'b0;
else
pi_money <= {$random} % 2;
wire [2:0] state = simple_fsm_inst.state;
initial
begin
$timeformat(-9,0,"ns",6);
$monitor("@time %t:pi_money=%b,state=%b,po_cola=%b",$time,pi_money,state,po_cola);
end
simple_fsm simple_fsm_inst
(
.sys_clk(sys_clk),
.sys_rst_n(sys_rst_n),
.pi_money(pi_money),
.po_cola(po_cola)
);
endmodule
六、结果及仿真
1、综合器综合出的状态转移图
2、仿真波形
经分析,与开始手动绘制的波形图吻合,结果正确,此处不再上传上板验证结果。