题解 | #自动贩售机1#
自动贩售机1
https://www.nowcoder.com/practice/dcf59e6c51f6489093495acb1bc34dd8
写了好多遍,终于对了。关键点在于:
1. 输入都为0时,小于1.5元的状态的nxt_state应该保持不变,因为在下降沿时输入会变化,所以不能让nxt_state=cur_state;
2. cur_state大于等于1.5元时应该继续检测输入,否则钱丢进入就没了(某个解答直接将nxt_state都置为ZERO);
小技巧:
用case(1'b1)和d1/d2/d3匹配会省面积。
`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 ZERO=3'b000,HALF=3'b001,ONE=3'b011,ONEHALF=3'b010; localparam TWO=3'b110, TWOHALF=3'b111, THREE=3'b101; reg [2:0] cur_state,nxt_state; always @(posedge clk, negedge rst) begin if (rst==0) cur_state <= ZERO; else cur_state <= nxt_state; end always @(*) begin case(cur_state) ZERO: case(1'b1) d1: nxt_state = HALF; d2: nxt_state = ONE; d3: nxt_state = TWO; default: nxt_state = nxt_state; endcase HALF: case(1'b1) d1: nxt_state = ONE; d2: nxt_state = ONEHALF; d3: nxt_state = TWOHALF; default: nxt_state = nxt_state; endcase ONE: case(1'b1) d1: nxt_state = ONEHALF; d2: nxt_state = TWO; d3: nxt_state = THREE; default: nxt_state = nxt_state; endcase ONEHALF: case(1'b1) d1: nxt_state = HALF; d2: nxt_state = ONE; d3: nxt_state = TWO; default: nxt_state = ZERO; endcase TWO: case(1'b1) d1: nxt_state = HALF; d2: nxt_state = ONE; d3: nxt_state = TWO; default: nxt_state = ZERO; endcase TWOHALF: case(1'b1) d1: nxt_state = HALF; d2: nxt_state = ONE; d3: nxt_state = TWO; default: nxt_state = ZERO; endcase THREE: case(1'b1) d1: nxt_state = HALF; d2: nxt_state = ONE; d3: nxt_state = TWO; default: nxt_state = ZERO; endcase default: case(1'b1) d1: nxt_state = HALF; d2: nxt_state = ONE; d3: nxt_state = TWO; default: nxt_state = ZERO; endcase endcase end always @(*) begin case (cur_state) ONEHALF: begin out1 = 1'b1; out2 = 2'd0; end TWO: begin out1 = 1'b1; out2 = 2'd1; end TWOHALF: begin out1 = 1'b1; out2 = 2'd2; end THREE: begin out1 = 1'b1; out2 = 2'd3; end default: begin out1 = 1'b0; out2 = 2'd0; end endcase end //*************code***********// endmodule