题解 | #自动贩售机1#
自动贩售机1
https://www.nowcoder.com/practice/dcf59e6c51f6489093495acb1bc34dd8
`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 ); //*************code***********// //这里的状态值设计的是全部的状态,有点多余了,其实可以只有三个状态的,然后输出的全被归到一类里 localparam IDEL_st = 7'b000_0001; localparam ZeroFive_st = 7'b000_0010; localparam One_st = 7'b000_0100; localparam OneFive_st = 7'b000_1000; localparam Two_st = 7'b001_0000; localparam TwoFive_st = 7'b010_0000; localparam Thre_st = 7'b100_0000; reg [6:0] cur_state; reg [6:0] nex_state; reg d1_reg; reg d2_reg; reg d3_reg; always@(posedge clk or negedge rst) //由题目可知输入的信号是一个检测后的边沿信号的脉冲,所以其不能被有效地采集到,故需要进行一个打一拍的操作,这样就会产生一个延时,那后面的状态机就需要进行相应的选取nex begin if(!rst) begin d1_reg <= 1'b0; d2_reg <= 1'b0; d3_reg <= 1'b0; end else begin d1_reg <= d1; d2_reg <= d2; d3_reg <= d3; end end always@(posedge clk or negedge rst) begin if(!rst) cur_state <= IDEL_st; else cur_state <= nex_state; end always@(*) begin if(!rst) nex_state = IDEL_st; else begin nex_state = IDEL_st; case(cur_state) IDEL_st : begin case({d3_reg , d2_reg , d1_reg}) 3'b000 : nex_state = IDEL_st; 3'b001 : nex_state = ZeroFive_st; 3'b010 : nex_state = One_st; 3'b100 : nex_state = Two_st; default : nex_state = IDEL_st; endcase end ZeroFive_st : begin case({d3_reg , d2_reg , d1_reg}) 3'b000 : nex_state = ZeroFive_st; 3'b001 : nex_state = One_st; 3'b010 : nex_state = OneFive_st; 3'b100 : nex_state = TwoFive_st; default : nex_state = IDEL_st; endcase end One_st : begin case({d3_reg , d2_reg , d1_reg}) 3'b000 : nex_state = One_st; 3'b001 : nex_state = OneFive_st; 3'b010 : nex_state = Two_st; 3'b100 : nex_state = Thre_st; default : nex_state = IDEL_st; endcase end OneFive_st : begin case({d3_reg , d2_reg , d1_reg}) 3'b000 : nex_state = IDEL_st; //这里和下面的都是这样,因为直接把东西和钱都输出了,所以不操作就是回原点,以及投入都是从原点开始计算 3'b001 : nex_state = ZeroFive_st; 3'b010 : nex_state = One_st; 3'b100 : nex_state = Two_st; default : nex_state = IDEL_st; endcase end Two_st : begin case({d3_reg , d2_reg , d1_reg}) 3'b000 : nex_state = IDEL_st; 3'b001 : nex_state = ZeroFive_st; 3'b010 : nex_state = One_st; 3'b100 : nex_state = Two_st; default : nex_state = IDEL_st; endcase end TwoFive_st : begin case({d3_reg , d2_reg , d1_reg}) 3'b000 : nex_state = IDEL_st; 3'b001 : nex_state = ZeroFive_st; 3'b010 : nex_state = One_st; 3'b100 : nex_state = Two_st; default : nex_state = IDEL_st; endcase end Thre_st : begin case({d3_reg , d2_reg , d1_reg}) 3'b000 : nex_state = IDEL_st; 3'b001 : nex_state = ZeroFive_st; 3'b010 : nex_state = One_st; 3'b100 : nex_state = Two_st; default : nex_state = IDEL_st; endcase end default : nex_state = IDEL_st; endcase end end always@(posedge clk or negedge rst) begin if(!rst) begin out1 <= 1'b0; out2 <= 2'b0; end else begin case(nex_state) //由于上面的输入进行了打一拍延时,那么这里也就需要进行当前,因为延时已经存在了 IDEL_st : begin out1 <= 1'b0; out2 <= 2'b0; end ZeroFive_st : begin out1 <= 1'b0; out2 <= 2'b0; end One_st : begin out1 <= 1'b0; out2 <= 2'b0; end OneFive_st : begin out1 <= 1'b1; out2 <= 2'b0; end Two_st : begin out1 <= 1'b1; out2 <= 2'd1; end TwoFive_st : begin out1 <= 1'b1; out2 <= 2'd2; end Thre_st : begin out1 <= 1'b1; out2 <= 2'd3; end default : begin out1 <= 1'b0; out2 <= 2'b0; end endcase end end //*************code***********// endmodule