题解 | #自动贩售机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脉冲触发后将次态锁存,用于状态转移。
此题学习到锁存器的用法之一。