赞
踩
状态机就是一种能够描述具有逻辑顺序和时序顺序事件的方法。
状态机有两大类:Mealy型和Moore型。
Moore型状态机的输出只与当前状态有关,而Mealy型状态机的输出不仅取决于当前状态,还受到输入的直接控制,并且可能与状态无关。
当使用Verilog来描述一个简单状态机的设计时,应将状态寄存器的控制器的控制和状态机状态里的组合逻辑分开。
当前状态、下一状态、当前输出值都写在一个always块中
当前状态、下一状态、当前输出值写在两个always块中
- 注意:这样三种组合方式,及有三种方式写这两个always块。
当前状态、下一状态、当前输出值分别写在各自的always块中,这样需要3个always块。
设计一个简单的数字电路用于电子的报纸售卖机的投币器。
- module vend(
- input [1:0] coin,
- input clock,
- input reset,
- output newspaper
- );
-
- //声明有限状态机的内部状态
- wire [1:0] NEXT_STATE;
- reg [1:0] PRES_STATE;
-
- //状态编码
- parameter s0 = 2'b00;
- parameter s5 = 2'b01;
- parameter s10 = 2'b10;
- parameter s15 = 2'b11;
-
- //用同步复位、时钟正跳变沿触发的状态触发器
- always@(posedge clock)
- begin
- if(reset == 1'b1)
- PRES_STATE <= s0;
- else
- PRES_STATE <= NEXT_STATE;
- end
- //组合逻辑
- function [2:0] fsm; //状态变化及输出组合逻辑
- input [1:0] fsm_coin;
- input [1:0] fsm_PRES_STATE;
- reg fsm_newspaper;
- reg [1:0] fsm_NEXT_STATE;
- begin
- case(fsm_PRES_STATE)
- s0: //状态为s0
- begin
- if(fsm_coin == 2'b10)
- begin
- fsm_newspaper = 1'b0;
- fsm_NEXT_STATE = s10;
- end
- else if(fsm_coin == 2'b01)
- begin
- fsm_newspaper = 1'b0;
- fsm_NEXT_STATE = s5;
- end
- else
- begin
- fsm_newspaper = 1'b0;
- fsm_NEXT_STATE = s0;
- end
- end
- s5: //状态为s5
- begin
- if(fsm_coin == 2'b10)
- begin
- fsm_newspaper = 1'b0;
- fsm_NEXT_STATE = s15;
- end
- else if(fsm_coin == 2'b01)
- begin
- fsm_newspaper = 1'b0;
- fsm_NEXT_STATE = s10;
- end
- else
- begin
- fsm_newspaper = 1'b0;
- fsm_NEXT_STATE = s5;
- end
- end
- s10: //状态为s10
- begin
- if(fsm_coin == 2'b10)
- begin
- fsm_newspaper = 1'b0;
- fsm_NEXT_STATE = s15;
- end
- else if(fsm_coin == 2'b01)
- begin
- fsm_newspaper = 1'b0;
- fsm_NEXT_STATE = s15;
- end
- else
- begin
- fsm_newspaper = 1'b0;
- fsm_NEXT_STATE = s10;
- end
- end
- s15: //状态为s15
- begin
- fsm_newspaper = 1'b1;
- fsm_NEXT_STATE = s0;
- end
- endcase
- fsm = {fsm_newspaper,fsm_NEXT_STATE};
- end
- endfunction
- //每当硬币放入或当前状态改变时,组合逻辑动作
- assign {newspaper,NEXT_STATE} = fsm(coin,PRES_STATE);
- endmodule
- module vend_tb;
-
- reg clock;
- reg reset;
- reg [1:0] coin;
- wire newspaper;
-
- always #20 clock = ~clock;
-
- initial
- begin
- clock = 0;
- reset = 1;
- #100;
- reset = 0;
-
- @(posedge clock) coin[1:0] = 2'b00;
- @(posedge clock);
- @(posedge clock) coin[1:0] = 2'b01;
- @(posedge clock);
- @(posedge clock) coin[1:0] = 2'b10;
- @(posedge clock);
- @(posedge clock) coin[1:0] = 2'b10;
- @(posedge clock);
- @(posedge clock) coin[1:0] = 2'b10;
- @(posedge clock);
-
- @(posedge clock) coin[1:0] = 2'b00;
- @(posedge clock);
- @(posedge clock) coin[1:0] = 2'b01;
- @(posedge clock);
- @(posedge clock) coin[1:0] = 2'b01;
- @(posedge clock);
- @(posedge clock) coin[1:0] = 2'b01;
- #200 $finish;
- end
- initial begin
- $fsdbDumpfile("test.fsdb");
- $fsdbDumpvars();
- end
- vend u_vend(
- .coin(coin),
- .clock(clock),
- .reset(reset),
- .newspaper(newspaper)
- );
- endmodule
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。