VL61. 自动售卖机
描述
请设计状态机电路,实现自动售卖机功能,A饮料5元钱,B饮料10元钱,售卖机可接收投币5元钱和10元钱,每次投币只可买一种饮料,考虑找零的情况。
电路的接口如下图所示。sel信号会先于din信号有效,且在购买一种饮料时值不变。
输入描述
input clk ,输出描述
output reg [1:0] drinks_out,Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-06
`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=0; parameter s1=1; reg [1:0] c_state,n_state; wire [2:0] a; assign a={sel,din}; always @(posedge clk or negedge rst_n) begin if(!rst_n) c_state<=idle; else c_state<=n_state; end always @(*) begin case(c_state) idle:begin case(a) 3'b101:n_state=s1; default:n_state=idle; endcase end s1:begin case(din) 2'b00:n_state=s1; default:n_state=idle; endcase end default:n_state=idle; endcase end always @(posedge clk or negedge rst_n) begin if(!rst_n) begin drinks_out<=0; change_out<=0; end else if(!sel) begin drinks_out<=(c_state==idle&din!=0); change_out<=(c_state==idle&din==2); end else begin change_out<=(c_state==s1&din==2); if(c_state==s1&din!=0) drinks_out<=2; else if(c_state==idle&&din==2) drinks_out<=2; else drinks_out<=0; end end endmodule
Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-06
`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 ); reg [2:0]state,next_state; parameter IDLE = 3'd0;//0元 parameter FIVE = 3'd1;//5元 always@(*)begin case(state) IDLE:if(din == 2'b0)begin next_state = IDLE; end else if(din == 2'b01)begin if(sel == 0)begin next_state = IDLE; end else begin next_state = FIVE; end end else if(din == 2'b10)begin next_state = IDLE; end else begin next_state = IDLE; end FIVE:if(din == 2'b0)begin next_state = FIVE; end else if(din == 2'b01)begin next_state = IDLE; end else if(din == 2'b10)begin next_state = IDLE; end else begin next_state = FIVE; end default:next_state = IDLE; endcase end always@(posedge clk or negedge rst_n)begin if(!rst_n)begin state <= IDLE; end else state <= next_state; end always@(posedge clk or negedge rst_n)begin if(!rst_n)begin drinks_out <= 2'b0; end else begin case(next_state) IDLE:if( (din == 2'b01 || din == 2'b10) && sel == 1'b0)begin drinks_out <= 2'b01; end else if((din == 2'b10 || din == 2'b01) && sel == 1) begin drinks_out <= 2'b10; end else drinks_out <= 2'b00; FIVE: drinks_out <= 2'b00; endcase end end always@(posedge clk or negedge rst_n)begin if(!rst_n)begin change_out <= 1'b0; end else begin case(next_state) IDLE:if(din == 2'b10 && sel == 0|| state == FIVE && din == 2'b10)begin change_out <= 1'b1; end else change_out <= 1'b0; FIVE:change_out <= 1'b0; endcase end end endmodule
Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-06
`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 = 3'd0, S0_D0= 3'd1, S0_D1= 3'd2, S0_D2= 3'd3, S1_D0= 3'd4, S1_D1= 3'd5, S1_D2= 3'd6, S1_D3= 3'd7; reg [2:0] state , next_state ; always@(posedge clk or negedge rst_n) if(!rst_n) state <= IDLE; else state <= next_state; always@(*) case(state) IDLE,S0_D0,S0_D1,S0_D2,S1_D0,S1_D2,S1_D3: case({sel,din}) 3'b000 : next_state = S0_D0; 3'b001 : next_state = S0_D1; 3'b010 : next_state = S0_D2; 3'b100 : next_state = S1_D0; 3'b101 : next_state = S1_D1; 3'b110 : next_state = S1_D2; default : next_state = IDLE; endcase S1_D1 : if(din == 2'd0) next_state = S1_D1; else if(din == 2'd1) next_state = S1_D2; else if(din == 2'd2) next_state = S1_D3; else next_state = IDLE; default: next_state = IDLE; endcase always@(*) case(state) S0_D1: begin drinks_out <= 2'd1; change_out <= 1'b0; end S0_D2: begin drinks_out <= 2'd1; change_out <= 1'b1; end S1_D2: begin drinks_out <= 2'd2; change_out <= 1'b0; end S1_D3 : begin drinks_out <= 2'd2; change_out <= 1'b1; end default: begin drinks_out <= 2'b0; change_out <= 1'b0; end endcase endmodule
Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-06
`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 S0 = 1'b0; parameter S1 = 1'b1; reg cstate, nstate; always@(posedge clk or negedge rst_n) begin if(!rst_n) begin cstate <= 1'b0; end else begin cstate <= nstate; end end always@(*) begin case(cstate) S0: begin nstate = (sel&(din=='d1))?S1:S0; end S1: begin nstate = (din=='d0)?S1:S0; end default: begin nstate = S0; end endcase end always@(posedge clk or negedge rst_n) begin if(!rst_n) begin drinks_out <= 2'd0; end else if((!sel) & (cstate==S0) & (din!='d0)) begin drinks_out <= 2'd1; end else if(sel & (((cstate==S0) & (din=='d2)) | ((cstate==S1) & (din!='d0)))) begin drinks_out <= 2'd2; end else begin drinks_out <= 2'd0; end end always@(posedge clk or negedge rst_n) begin if(!rst_n) begin change_out <= 1'b0; end else if(((!sel) & (cstate==S0) & (din=='d2)) | (sel & (cstate==S1) & (din=='d2))) begin change_out <= 1'b1; end else begin change_out <= 1'b0; end end endmodule
Verilog 解法, 执行用时: 0ms, 内存消耗: 0KB, 提交时间: 2022-08-06
`timescale 1ns/1ns module sale(input clk, input rst_n, input sel, input [1:0] din, output reg [1:0] drinks_out, output reg change_out); parameter idle = 3'b000; parameter s05 = 3'b001; parameter s10 = 3'b010; parameter s15 = 3'b100; reg [2:0] cs,ns; always@(posedge clk or negedge rst_n) cs <= ~rst_n?idle:ns; always@(*) begin ns = idle; case(cs) idle: ns = din == 0?idle:din == 1?s05:din == 2?s10:idle; s05: ns = sel?(din == 0?s05:din == 1?s10:din == 2?s15:idle):(din == 0?idle:din == 1?s05:din == 2?s10:idle); s10: ns = din == 0?idle:din == 1?s05:din == 2?s10:idle; s15: ns = din == 0?idle:din == 1?s05:din == 2?s10:idle; default: ns = idle; endcase end always@(posedge clk or negedge rst_n) begin if (!rst_n) drinks_out <= 0; else drinks_out <= sel?((ns == s10 || ns == s15)?2:0):((ns == s05 || ns == s10 | cs == s15)?1:0); end always@(posedge clk or negedge rst_n) begin if (!rst_n) change_out <= 0; else change_out <= sel?((ns == s15)?1:0):((ns == s10 || ns == s15)?1:0); end endmodule