题解 | #自动售卖机#
自动售卖机
https://www.nowcoder.com/practice/487953e6d3e3434988e0dd6960b6c9f8
解法2:更简单的解法,状态机是一样的。
注意点:将两个输出合二为一、一起输出,更简单、
`timescale 1ns/1ns module sale( input clk , input rst_n , input sel ,//sel=0,5$dranks,sel=1,10&=$drinks input [1:0] din ,//din=1,input 5$,din=2,input 10$ output reg [1:0] drinks_out,//drinks_out=1,output 5$ drinks,drinks_out=2,output 10$ drinks output reg change_out ); parameter idle = 2'b01, drinkB_5 = 2'b10; reg [1:0] state, next_state; wire [2:0] comb; assign comb = {sel, din}; always @ (posedge clk, negedge rst_n) begin if(!rst_n) begin state <= idle; end else begin state <= next_state; end end always @ (*) begin case(state) idle: begin next_state = sel ? (din == 1 ? drinkB_5 : idle) : idle; end drinkB_5: begin next_state = din == 0 ? drinkB_5 : idle; end default: begin next_state = idle; end endcase end always @ (posedge clk, negedge rst_n) begin if(!rst_n) begin {drinks_out, change_out} <= 3'd0; end else begin if((state == drinkB_5)) begin if(comb == 3'b101) begin {drinks_out, change_out} <= 3'b100; end else if(comb == 3'b110) begin {drinks_out, change_out} <= 3'b101; end else begin {drinks_out, change_out} <= 3'd0; end end else begin if(comb == 3'b001) begin {drinks_out, change_out} <= 3'd010; end else if(comb == 3'b010) begin {drinks_out, change_out} <= 3'd011; end else if (comb == 3'b110) begin {drinks_out, change_out} <= 3'd100; end else begin {drinks_out, change_out} <= 3'd0; end end end end // always @ (posedge clk, negedge rst_n) begin // if(!rst_n) begin // change_out <= 1'd0; // end // else if ((sel == 1'b0 && state == idle && din == 2) || (sel && state == drinkB_5 && din == 2)) begin // change_out <= 1'd1; // end // else begin // change_out <= 1'd0; // end // end endmodule
解法一:状态机。离大谱,状态机都不会写了
注意点:只有两个状态,需要考虑清楚
parameter idle = 2'b01, drinkB_5 = 2'b10;
`timescale 1ns/1ns module sale( input clk , input rst_n , input sel ,//sel=0,5$dranks,sel=1,10&=$drinks input [1:0] din ,//din=1,input 5$,din=2,input 10$ output reg [1:0] drinks_out,//drinks_out=1,output 5$ drinks,drinks_out=2,output 10$ drinks output reg change_out ); parameter idle = 2'b01, drinkB_5 = 2'b10; reg [1:0] state, next_state; wire [2:0] comb; always @ (posedge clk, negedge rst_n) begin if(!rst_n) begin state <= idle; end else begin state <= next_state; end end always @ (*) begin case(state) idle: begin next_state = sel ? (din == 1 ? drinkB_5 : idle) : idle; end drinkB_5: begin next_state = din == 0 ? drinkB_5 : idle; end default: begin next_state = idle; end endcase end always @ (posedge clk, negedge rst_n) begin if(!rst_n) begin drinks_out <= 2'd0; end else if (!sel) begin if((state == idle && din == 1) || (state == idle && din == 2)) begin drinks_out <= 2'd1; end else begin drinks_out <= 2'd0; end end else begin if((state == idle && din == 2) || (state == drinkB_5 && din == 2) || (state == drinkB_5 && din == 1)) begin drinks_out <= 2'd2; end else begin drinks_out <= 2'd0; end end end always @ (posedge clk, negedge rst_n) begin if(!rst_n) begin change_out <= 1'd0; end else if ((sel == 1'b0 && state == idle && din == 2) || (sel && state == drinkB_5 && din == 2)) begin change_out <= 1'd1; end else begin change_out <= 1'd0; end end endmodule