自动售货机
if朴素方法
一种思路是用寄存器cnt记录已有的最小单位货币量,这里就是0.5
当d1时,cnt+1;d2时,cnt+2;d3时,cnt+4;
`timescale 1ns/1ns
module seller1(input wire clk ,input wire rst ,input wire d1 ,input wire d2 ,input wire d3 ,output reg out1,output reg [1:0]out2
);
reg[2:0]cnt;
always@(posedge clk,negedge rst)beginif(!rst)begincnt<=0;out1<=0;out2<=0;endelse beginif(d1)cnt<=cnt+1;else if(d2)cnt<=cnt+2;else if(d3)cnt<=cnt+4;else if(cnt>=3)beginout1<=1;out2<=cnt-3;cnt<=0;//记得复位为0,表示一个过程的结束endelse beginout1<=0;out2<=0;end//这里需要注意一定需要这一步,不然在不复位时,将保持一直输出1的状态end
end
endmodule
这里注意,d1,d2,d3都是以脉冲的形式,即只会接受一个时间步里,检测也都是
`timescale 1ns/1nsmodule seller1(input wire clk ,input wire rst ,input wire d1 ,input wire d2 ,input wire d3 ,output reg out1,output reg [1:0]out2
);parameter S0 = 'd0, S1 = 'd1, S2 = 'd2, S3 = 'd3 , S4 = 'd4, S5 = 'd5 , S6 = 'd6;reg [2:0] current_state;reg [2:0] next_state;wire [2:0] input_state;//将输入组合起来assign input_state = {d1,d2,d3};always@(posedge clk or negedge rst)beginif(rst == 1'b0)begincurrent_state <= S0;endelse begincurrent_state <= next_state;endend always@(*)begincase(current_state)S0:begincase(input_state)3'b100:next_state = S1 ;3'b010:next_state = S2 ;3'b001:next_state = S4 ;default:next_state = next_state;endcase endS1:begincase(input_state)3'b100:next_state = S2 ;3'b010:next_state = S3 ;3'b001:next_state = S5 ;default:next_state = next_state; endcaseendS2:begincase(input_state)3'b100:next_state = S3 ;3'b010:next_state = S4 ;3'b001:next_state = S6 ;default:next_state = next_state;endcase enddefault:beginnext_state = S0;endendcaseendalways@(posedge clk or negedge rst)beginif(rst == 1'b0)beginout1 <= 1'b0;out2 <= 2'b0;endelse begincase(next_state)S3: begin out1 <= 1'b1;out2 <= 2'b0; end S4: begin out1 <= 1'b1;out2 <= 2'b1; end S5: begin out1 <= 1'b1;out2 <= 2'b10; end S6: begin out1 <= 1'b1;out2 <= 2'b11; end default: begin out1 <= 1'b0;out2 <= 2'b0; end endcase endendendmodule
状态机方法
采用MOORE状态机,即输出只与状态有关,而与当前输入信号无关
状态机的方式可以支持一次投入多枚硬币
MOORE三段
第一段:信号声明,状态定义,状态转换
第二段:由现态,依据输入信号确定次态
这里可以看出,如果一次投入多个硬币,可以进行转移与判断,只需在case里增添判断即可
第三段:依据次态确定输出信号
自动售货机(支持多物品售卖)
sel为0时买一块五,即第四个状态,s3;为1时买两块五,为第六个状态,s5
状态机
`timescale 1ns/1nsmodule seller2(input wire clk ,input wire rst ,input wire d1 ,input wire d2 ,input wire sel ,output reg out1,output reg out2,output reg out3
);
//*************code***********//parameter S0=0, S0_5=1, S1=2, S1_5=3, S2=4, S2_5=5, S3=6;reg[2:0] state, nstate;always@(posedge clk or negedge rst) beginif(~rst)state <= 0;elsestate <= nstate;endalways@(*) begincase(state)S0 : nstate = d1? S0_5:d2? S1:nstate;S0_5 : nstate = d1? S1:d2? S1_5:nstate;S1 : nstate = d1? S1_5:d2? S2:nstate;S1_5 : nstate = ~sel? S0:d1? S2:d2? S2_5:nstate;S2 : nstate = ~sel? S0:d1? S2_5:d2? S3:nstate;default: nstate = S0;endcaseendalways@(*) beginif(~rst) begin{out1, out2, out3} = 3'b000;endelse begincase(state)S0, S0_5, S1: {out1, out2, out3} = 0;S1_5 : {out1, out2, out3} = ~sel? 3'b100: 3'b000;S2 : {out1, out2, out3} = ~sel? 3'b101: 3'b000;S2_5 : {out1, out2, out3} = ~sel? 3'b101: 3'b010;S3 : {out1, out2, out3} = ~sel? 3'b101: 3'b011;default : {out1, out2, out3} = 3'b000;endcaseendend
//*************code***********//
endmodule
上面为mealy型状态机,即输出取决于现态与输入信号
`timescale 1ns/1nsmodule seller2(input wire clk ,input wire rst ,input wire d1 ,input wire d2 ,input wire sel ,output reg out1,output reg out2,output reg out3
);parameter S0 = 'd0, S1 = 'd1, S2 = 'd2, S3 = 'd3 , S4 = 'd4, S5 = 'd5, S6 = 'd6;reg [2:0] current_state;reg [2:0] next_state;wire [1:0] input_state;assign input_state = {d1,d2};always@(posedge clk or negedge rst)beginif(rst == 1'b0)begincurrent_state <= S0;endelse begincurrent_state <= next_state;endend always@(*)beginif (!sel) begincase(current_state)S0:begincase(input_state)2'b10 :next_state = S1 ;2'b01 :next_state = S2 ;default:next_state = next_state;endcase endS1:begincase(input_state)2'b10 :next_state = S2 ;2'b01 :next_state = S3 ;default:next_state = next_state;endcase endS2:begincase(input_state)2'b10 :next_state = S3 ;2'b01 :next_state = S4 ;default:next_state = next_state;endcase enddefault: next_state = S0; endcaseendelse begincase(current_state)S0:begincase(input_state)2'b10 :next_state = S1 ;2'b01 :next_state = S2 ;default:next_state = next_state;endcase endS1:begincase(input_state)2'b10 :next_state = S2 ;2'b01 :next_state = S3 ;default:next_state = next_state;endcase endS2:begincase(input_state)2'b10 :next_state = S3 ;2'b01 :next_state = S4 ;default:next_state = next_state;endcase endS3:begincase(input_state)2'b10 :next_state = S4 ;2'b01 :next_state = S5 ;default:next_state = next_state;endcase endS4:begincase(input_state)2'b10 :next_state = S5 ;2'b01 :next_state = S6 ;default:next_state = next_state;endcase enddefault: next_state = S0; endcaseendendalways@(posedge clk or negedge rst)beginif(rst == 1'b0)beginout1 <= 1'b0;out2 <= 1'b0;out3 <= 1'b0;endelse beginif(!sel)begincase (next_state)S3: begin out1 <= 1'b1;out2 <= 1'b0;out3 <= 1'b0;end S4: begin out1 <= 1'b1;out2 <= 1'b0;out3 <= 1'b1;end default:begin out1 <= 1'b0;out2 <= 1'b0;out3 <= 1'b0;end endcaseendelse begincase (next_state) S5: begin out1 <= 1'b0;out2 <= 1'b1;out3 <= 1'b0;end S6: begin out1 <= 1'b0;out2 <= 1'b1;out3 <= 1'b1;end default:begin out1 <= 1'b0;out2 <= 1'b0;out3 <= 1'b0;end endcase endendendendmodule
上面为标准的MOORE状态机代码,即输出只与次态有关
在状态转换中,一定要记得写
即相当于 后面的复位,不然没办法复位