牛客网Verilog刷题——VL38
- 题目
- 答案
题目
设计一个自动贩售机,输入货币有三种,为0.5/1/2元,饮料价格是1.5元,要求进行找零,找零只会支付0.5元。需要注意的是,投入的货币会自动经过边沿检测并输出一个在时钟上升沿到1,在下降沿到0的脉冲信号,其中rst为低电平复位。
信号示意图如下:
波形示意图如下。
输入输出描述:
信号 | 类型 | 输入/输出 | 位宽 | 描述 |
---|---|---|---|---|
clk | wire | Intput | 1 | 系统时钟信号 |
rst_n | wire | Intput | 1 | 异步复位信号,低电平有效 |
d1 | wire | Intput | 1 | 投入0.5元 |
d2 | wire | Intput | 1 | 投入1元 |
d3 | wire | Intput | 1 | 投入2元 |
out1 | reg | Output | 1 | 输出饮料 |
out2 | reg | Output | 2 | 找零,00表示0元,01表示0.5元,10表示1元,11表示1.5元 |
答案
`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***********//
//当次投入金额
wire [2:0] d;
assign d = {d3,d2,d1};//100、010、001
//投入累计金额
localparam S0 = 7'b000_0001; //0
localparam S1 = 7'b000_0010; //0.5
localparam S2 = 7'b000_0100; //1
localparam S3 = 7'b000_1000; //1.5
localparam S4 = 7'b001_0000; //2
localparam S5 = 7'b010_0000; //2.5
localparam S6 = 7'b100_0000; //3
reg [6:0] curr_state;
reg [6:0] next_state;
always @(posedge clk or negedge rst)
if(!rst)
curr_state <= S0;
else
curr_state <= next_state;
always @(*)
case(curr_state)
S0:
if(d==3'b001)
next_state = S1;
else if(d==3'b010)
next_state = S2;
else if(d==3'b100)
next_state = S4;
else
next_state = next_state;
S1:
if(d==3'b001)
next_state = S2;
else if(d==3'b010)
next_state = S3;
else if(d==3'b100)
next_state = S5;
else
next_state = next_state;
S2:
if(d==3'b001)
next_state = S3;
else if(d==3'b010)
next_state = S4;
else if(d==3'b100)
next_state = S6;
else
next_state = next_state;
S3:
next_state = S0;
S4:
next_state = S0;
S5:
next_state = S0;
S6:
next_state = S0;
default:next_state = S0;
endcase
always @(posedge clk or negedge rst)
if(!rst)
out1 <= 1'b0;
else if((next_state==S3) || (next_state==S4) || (next_state==S5) || (next_state==S6))
out1 <= 1'b1;
else
out1 <= 1'b0;
always @(posedge clk or negedge rst)
if(!rst)
out2 <= 2'd0;
else if(next_state==S3)
out2 <= 2'd0;
else if(next_state==S4)
out2 <= 2'd1;
else if(next_state==S5)
out2 <= 2'd2;
else if(next_state==S6)
out2 <= 2'd3;
else
out2 <= 2'd0;
//*************code***********//
endmodule