题解 | #自动贩售机1#
自动贩售机1
https://www.nowcoder.com/practice/dcf59e6c51f6489093495acb1bc34dd8
这题有两种方案,1、无锁存器,需要使用下降沿触发。2、有锁存器,正常上升沿触发。
1、无锁存器:
//方案一:无锁存器方案 `timescale 1ns/1ns module seller1( input wire clk , input wire rst , input wire d1 , //0.5 input wire d2 , //1 input wire d3 , //2 output reg out1, output reg [1:0]out2 ); reg [2:0] state, next_state; wire [2:0] d = {d3,d2,d1}; //0.5的倍数bit always @(*) begin case(state) 0: begin case (d) 0:next_state = 0; 1:next_state = 1; 2:next_state = 2; 4:next_state = 4; default: next_state = 0; endcase end //未投币 1: begin case (d) 0:next_state = 1; 1:next_state = 2; 2:next_state = 3; 4:next_state = 5; default: next_state = 0; endcase end //投币未投够 2: begin case (d) 0:next_state = 2; 1:next_state = 3; 2:next_state = 4; 4:next_state = 6; default: next_state = 0; endcase end //找零 default: next_state = 0; endcase end always @(negedge clk,negedge rst) begin if(!rst) begin state <= 0; end else begin state <= next_state; end end //由于组合逻辑未使用锁存器结构,所以需要使用negedge触发 always @(posedge clk,negedge rst) begin if (!rst) begin out1 <= 0; out2 <= 0; end else begin case(state) 3: begin out1 = 1; out2 = 0; end 4: begin out1 = 1; out2 = 1; end 5: begin out1 = 1; out2 = 2; end 6: begin out1 = 1; out2 = 3; end default: begin out1 = 0; out2 = 0; end endcase end end endmodule
2、有锁存器:
// 方案二:有锁存器方案 `timescale 1ns/1ns module seller1( input wire clk , input wire rst , input wire d1 , //0.5 input wire d2 , //1 input wire d3 , //2 output reg out1, output reg [1:0]out2 ); reg [2:0] state, next_state; wire [2:0] d = {d3,d2,d1}; //0.5的倍数bit // 组合逻辑中使用锁存结构检测脉冲 always @(*) begin case(state) 0: begin case (d) 1:next_state = 1; 2:next_state = 2; 4:next_state = 4; default: next_state = next_state; endcase end //未投币 1: begin case (d) 1:next_state = 2; 2:next_state = 3; 4:next_state = 5; default: next_state = next_state; endcase end //投币未投够 2: begin case (d) 1:next_state = 3; 2:next_state = 4; 4:next_state = 6; default: next_state = next_state; endcase end //找零 default: next_state = 0; endcase end always @(posedge clk,negedge rst) begin if(!rst) begin state <= 0; end else begin state <= next_state; end end //由于组合逻辑使用锁存器结构,所以可以使用posedge触发 always @(*) begin if (!rst) begin out1 = 0; out2 = 0; end else begin case(state) 3: begin out1 = 1; out2 = 0; end 4: begin out1 = 1; out2 = 1; end 5: begin out1 = 1; out2 = 2; end 6: begin out1 = 1; out2 = 3; end default: begin out1 = 0; out2 = 0; end endcase end end endmodule
不带锁存的仿真,下降沿进行状态转移:
可以看到state在下降沿时刻将next_state采样。
带锁存的仿真:
可以看到next_state在d脉冲触发后将次态锁存,用于状态转移。
此题学习到锁存器的用法之一。