目录
1.实验目的
1.使用状态机的方法实现按键消抖;
2.简易售货机
货物(唯一)价值5元
货币(0.5 ,1.0 ,2.0)
显示模块(投入货币总值,并显示找零)
LED(表示状态)
设置确认付款按钮,(我这里只有四个按键,所以不设复位,但还是要写代码,
Key1: 确认付款按键
Key2:货币0.5信号
Key3:货币1.0信号
Key4:货币2.0信号
)
1.满足货物价值,出货开关打开,并显示找零,led流水,蜂鸣器播放音乐(两只老虎);
2.不满足货物价值,退钱,led灯高速闪烁,蜂鸣器鸣叫(我这里播放 《我没有钱,我不要脸》)
2.需求分析
这里要求我们的是一个简易的售货机,自动默认已经选好商品,且价值也唯一(这些有需要可以自己加),相当于我们只需要直接投入货币,然后计算投入总值,再与商品价值作比较,如果投入金额大于等于商品价值,出货成功,并有一系列器件反映(目的处有),如果小于商品价值,退钱,并且嘲讽他穷。
3.状态转移图
4.结构框图
5.代码片段
5.1 seller_ctrl模块(中心控制)
这个模块实现的就是实现投币,判断投币值是否大于等于商品价值,并实现计算找零,最后将是否成功购买的信号传递到其他模块,将其作为其他元器件反映的输入信号,其他的反应可随自己意添加和修改。
module seller_ctrl (
input clk ,
input rst_n ,
input key1 , //确认付款
input key2 , //投币0.5
input key3 , //投币1
input key4 , //投币2
output reg [2:0] flag_sell ,//是否成功支付,需要传递到led,蜂鸣器模块
output reg [7:0] num_money ,//投入货币的总额,需要传递到数码管模块。最高6.5,即显示65
output reg [7:0] surplus_money //应该找零的余额,也传递到数码管。
);
parameter MAX_money = 6'd50 ; //商品总价值5元
parameter IDLE = 4'b0001; //空闲状态
parameter BUY = 4'b0010;// 货币投入
parameter JUD = 4'b0100;//判断投入货币总值
parameter RES = 4'b1000;//判断结果
parameter NUM_5s = 28'd25000_0000; //5s计数;
reg [27:0] cnt_5s;
reg [3:0] cstate; //现态
reg [3:0] nstate; //次态
//100ms计时器,当判断投入货币总值状态过了100ms后进入判断结果状态,再过100ms进入判断结果状态。
always @(posedge clk or negedge rst_n) begin
if(!rst_n)begin
cnt_5s <= 28'd0;
end
else if(cnt_5s == NUM_5s - 1'd1)begin
cnt_5s <= 28'd0;
end
else begin
cnt_5s <= cnt_5s + 1'd1;
end
end
//状态转移
always @(posedge clk or negedge rst_n) begin
if(!rst_n)begin
cstate <= IDLE;
end
else begin
cstate <= nstate;
end
end
//状态转移判断
always @(*) begin
if(!rst_n)begin
nstate <= IDLE;
end
else begin
case (cstate)
IDLE: begin
if(key1)begin
nstate = BUY;
end
else begin
nstate = IDLE;
end
end
BUY : begin
if(key1)begin
nstate = JUD;
end
else begin
nstate = BUY;
end
end
JUD : begin
if(cnt_5s == (NUM_5s / 5) - 1'd1)begin //一秒后进入状态四,
nstate = RES;
end
else begin
nstate = JUD;
end
end
RES : begin
if(cnt_5s == NUM_5s - 1'd1)begin // 5s后进入状态一,元器件反映的时间就在这状态
nstate = IDLE;
end
else begin
nstate = RES;
end
end
default: nstate = IDLE;
endcase
end
end
//对每个状态下的值进行分支并且将输出赋值
always @(posedge clk or negedge rst_n) begin
if(!rst_n)begin
flag_sell <= 3'b001 ;
num_money <= 8'd0 ;
surplus_money <= 8'd0 ;
end
else begin
case (cstate)
IDLE:begin
flag_sell <= 3'b001 ;
num_money <= 8'd0 ;
surplus_money <= 8'd0 ;
end
BUY: begin
if(key2)begin //按下按键2,投入总额增加0.5
num_money <= num_money + 8'd5;
end
else if(key3)begin //按下按键3,投入总额增加1
num_money <= num_money + 8'd10;
end
else if(key4)begin //按下按键4,投入增加2
num_money <= num_money + 8'd20;
end
else begin
num_money <= num_money;
end
end
JUD:begin
if(num_money >= MAX_money)begin //当投入总额大于总价值时,找零。
surplus_money <= num_money - MAX_money;
end
else begin //当投入总额小于总价值时,退还投入的钱。
surplus_money <= num_money;
end
end
RES:begin
if(num_money >= MAX_money)begin //当投入总额大于总价值时,购买成功。
flag_sell <= 3'b010;
end
else begin //当投入总额小于总价值时,购买失败。
flag_sell <= 3'b100;
end
end
default: ;
endcase
end
end
endmodule
5.2 led_ctrl(led控制模块)
这个模块是根据seller_ctrl模块传过来的是否成功购买的参数,来判断led应该显示什么状态
module led_ctrl(
input clk,
input rst_n,
input [2:0]flag_sell,
output reg[3:0] led
);
reg [25:0] cnt; // 振动次数寄存器
parameter MAX_NUM = 26'd250_0000; //50ms
reg flag ;// 闪烁信号
always @(posedge clk or negedge rst_n) begin
if(!rst_n)begin
cnt <= 26'd0;
flag <= 1'b0;
end
else if(cnt == MAX_NUM -1'd1)begin
cnt <= 26'd0;
flag <= ~flag;
end
else begin
cnt <= cnt +1'd1;
flag <= flag;
end
end
always @(posedge clk or negedge rst_n) begin
if(!rst_n)begin
led <= 4'b0001;
end
else if(cnt == MAX_NUM -1'd1 && flag_sell==3'b010)begin
led <= {led[2:0],led[3]};
end
else if(flag_sell == 3'b100)begin
case (flag)
1'b0: led <= 4'b0000;
1'b1: led <= 4'b1111;
default: ;
endcase
end
else begin
led <= led;
end
end
endmodule
5.3 beep_ctrl模块(蜂鸣器控制模块)
这个也是随自己心意设计,我设计当成功购买,蜂鸣器播放《两只老虎》5s,失败后,播放5s
《我没有钱,我不要脸》。
module beep_ctrl (
input clk,
input rst_n,
input [2:0] flag_sell, // 消抖的按键信号,控制系统暂停播放。
output reg pwm_o
);
parameter CLK_FRE = 5000_0000;
parameter
L_DO = CLK_FRE / 262,
L_RE = CLK_FRE / 294,
L_MI = CLK_FRE / 330,
L_FA = CLK_FRE / 349,
L_SO = CLK_FRE / 392,
L_LA = CLK_FRE / 440,
L_SI = CLK_FRE / 494,
M_DO = CLK_FRE / 523,
M_RE = CLK_FRE / 587,
M_MI = CLK_FRE / 659,
M_FA = CLK_FRE / 698,
M_SO = CLK_FRE / 784,
M_LA = CLK_FRE / 880,
M_SI = CLK_FRE / 998,
H_DO = CLK_FRE / 1047,
H_RE = CLK_FRE / 1175,
H_MI = CLK_FRE / 1319,
H_FA = CLK_FRE / 1397,
H_SO = CLK_FRE / 1568,
H_LA = CLK_FRE / 1760,
H_SI = CLK_FRE / 1967;
reg [17:0] cnt_charac; //单个音符的计数器,单个音符振动次数
wire add_charac;// 开始音符计数使能信号
wire end_charac;//结束音符计数使能信号
reg [17:0] max_charac;
reg [9:0] cnt_200; //单个音符持续时间,
wire add_200; //开始250ms计时信号
wire end_200; //结束250ms计时信号,
reg [7:0] cnt_num; //音谱里的音符数
wire add_num; //音谱计数使能信号
wire end_num; //音谱结束信号
reg [17:0] max_num;
parameter MAX_250ms = 24'd1500_0000 ; //音符持续时间,250ms
parameter MAX_NUM = 8'd49; //乐谱中音符数。
//单个音符计周期模块
always @(posedge clk or negedge rst_n) begin
if(!rst_n)begin
cnt_charac <= 18'd0;
end
else if(add_charac)begin
if(end_charac)begin
cnt_charac <= 18'd0;
end
else begin
cnt_charac <= cnt_charac + 1'd1;
end
end
else begin
cnt_charac <= cnt_charac;
end
end
assign add_charac = flag_sell == 3'b010 || flag_sell == 3'b100;
assign end_charac = add_charac && cnt_charac >= max_charac - 18'd1;
//音符计数模块,选择每个音符持续200个周期
always @(posedge clk or negedge rst_n) begin
if(!rst_n)begin
cnt_200 <= 10'd0;
end
else if(add_200)begin
if(end_200)begin
cnt_200 <= 10'd0;
end
else begin
cnt_200 <= cnt_200 + 1'd1;
end
end
else begin
cnt_200 <= cnt_200;
end
end
assign add_200 = end_charac;
assign end_200 = add_200 && cnt_200 == 200 - 1'd1;
//音符选择模块
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
cnt_num <= 8'd0;
end
else if (add_num)begin
if(end_num)begin
cnt_num <= 8'd0;
end
else begin
cnt_num <= cnt_num + 8'd1;
end
end
else begin
cnt_num <= cnt_num;
end
end
assign add_num = end_200;
assign end_num = add_num && cnt_num ==MAX_NUM - 1'd1;
always @(*) begin
case (flag_sell)
3'b010: begin
case(cnt_num)
8'd0 : max_charac = M_DO; //两
8'd1 : max_charac = M_RE;//只
8'd2 : max_charac = M_MI;//老
8'd3 : max_charac = M_DO;//虎
8'd4 : max_charac = M_DO;//两
8'd5 : max_charac = M_RE;//只
8'd6 : max_charac = M_MI;//老
8'd7 : max_charac = M_DO;//虎
8'd8 : max_charac = M_MI;//跑
8'd9 : max_charac = M_FA;//得
8'd10 : max_charac = M_SO;//快
8'd11 : max_charac = M_SO;//快
8'd12 : max_charac = M_MI;//跑
8'd13 : max_charac = M_FA;//得
8'd14 : max_charac = M_SO;//快
8'd15 : max_charac = M_SO;//快
8'd16 : max_charac = 1;
8'd17 : max_charac = M_SO;//一
8'd18 : max_charac = M_LA;//只
8'd19 : max_charac = M_SO;//没
8'd20 : max_charac = M_FA;//有
8'd21 : max_charac = M_MI;//眼
8'd22 : max_charac = M_MI;//
8'd23 : max_charac = M_DO;//睛
8'd24 : max_charac = M_DO;//
8'd25 : max_charac = M_SO;//一
8'd26 : max_charac = M_LA;//只
8'd27 : max_charac = M_SO;//没
8'd28 : max_charac = M_FA;//有
8'd29 : max_charac = M_MI;//尾
8'd30 : max_charac = M_MI;//
8'd31 : max_charac = M_DO;//巴
8'd32 : max_charac = M_DO;//
8'd33 : max_charac = M_RE;//真
8'd34 : max_charac = M_RE;//
8'd35 : max_charac = L_SO;//奇
8'd36 : max_charac = L_SO;//
8'd37 : max_charac = M_DO;//怪
8'd38 : max_charac = M_DO;//
8'd39 : max_charac = 1;
8'd40 : max_charac = 1;
8'd41 : max_charac = M_RE;//真
8'd42 : max_charac = M_RE;//
8'd43 : max_charac = L_SO;//奇
8'd44 : max_charac = L_SO;//
8'd45 : max_charac = M_DO;//怪
8'd46 : max_charac = M_DO;//
8'd47 : max_charac = 1;
8'd48 : max_charac = 1;
default: max_charac = 1;
endcase
end
3'b100:begin
case (cnt_num)
8'd0 : max_charac = L_MI;
8'd1 : max_charac = M_DO;
8'd2 : max_charac = L_SO;
8'd3 : max_charac = L_LA;
8'd4 : max_charac = M_LA;
8'd5 : max_charac = 1;
8'd6 : max_charac = 1;
8'd7 : max_charac = 1;
8'd8 : max_charac = 1;
8'd9 : max_charac = L_SO;
8'd10 : max_charac = M_DO;
8'd11 : max_charac = M_DO;
8'd12 : max_charac = L_MI;
8'd13 : max_charac = M_DO;
8'd14 : max_charac = L_SO;
8'd15 : max_charac = L_LA;
8'd16 : max_charac =M_LA;
8'd17 : max_charac = 1;
8'd18 : max_charac = 1;
8'd19 : max_charac = 1;
8'd20 : max_charac = 1;
8'd21 : max_charac = L_SO;
8'd22 : max_charac = M_DO;
8'd23 : max_charac = L_MI;
8'd24 : max_charac = M_DO;
8'd25 : max_charac = L_SO;
8'd26 : max_charac = L_LA;
8'd27 : max_charac = M_LA;
8'd28 : max_charac = 1;
8'd29 : max_charac = 1;
8'd30 : max_charac = 1;
8'd31 : max_charac = 1;
8'd32 : max_charac = L_SO;
8'd33 : max_charac = M_DO;
8'd34 : max_charac = L_MI;
8'd35 : max_charac = M_DO;
8'd36 : max_charac = L_SO;
8'd37 : max_charac = L_LA;
8'd38 : max_charac = M_LA;
8'd39 : max_charac = 1;
8'd40 : max_charac = 1;
8'd41 : max_charac = 1;
8'd42 : max_charac = 1;
8'd43 : max_charac = L_SO;
8'd44 : max_charac = M_DO;
8'd45 : max_charac = L_MI;
8'd46 : max_charac = M_DO;
8'd47 : max_charac = L_SO;
8'd48 : max_charac = L_LA;
default: ;
endcase
end
default: ;
endcase
end
//设置占空比可调
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
pwm_o <= 1'b1;//复位,静音
end
else if (cnt_charac < (max_charac >> 2 )&& (flag_sell == 3'b010 || flag_sell == 3'b100)) begin//占空比设置为25%
pwm_o <= 1'b0;
end
else begin
pwm_o <= 1'b1;
end
end
endmodule
5.4 seg_ctrl模块(数码管控制模块)
数码管显示模块,左边两位显示投币金额,右边两位显示找零金额
module seg_ctrl (
input clk ,
input rst_n,
input wire [7:0] num_money , //投入总金额,放在sel[1:0]
input wire [7:0] surplus_money , //找零金额,放在sel[5:4]
output reg[7:0] seg ,
output reg[5:0] sel
);
parameter MIN_NUM = 20'd15_0000; //3ms计数器
reg [19:0] cnt_3ms; //3ms计数器,用于位选信号切换计时
reg [3:0]flag; //位选信号状态设置。
wire [3:0] num_money_low ;
wire [3:0] num_money_high ;
wire [3:0] surplus_money_low ;
wire [3:0] surplus_money_high ;
assign num_money_high = num_money / 10;
assign num_money_low = num_money % 10;
assign surplus_money_high = surplus_money / 10;
assign surplus_money_low = surplus_money % 10;
//3ms计时模块,计满位选信号取反
always @(posedge clk or negedge rst_n) begin
if(!rst_n)begin
cnt_3ms <= 20'd0;
flag <= 4'd0;
end
else if(cnt_3ms == MIN_NUM - 1'd1 && flag <=5)begin
cnt_3ms <= 20'd0;
flag <= flag + 1'd1;
end
else if(cnt_3ms == MIN_NUM - 1'd1)begin
cnt_3ms <= 20'd0;
flag <= 4'd0;
end
else begin
cnt_3ms <= cnt_3ms + 1'd1;
flag <= flag;
end
end
always @(*) begin //位选信号设置
case (flag)
4'd0: sel = 6'b011_111;
4'd1: sel = 6'b101_111;
4'd2: sel = 6'b111_111;
4'd3: sel = 6'b111_111;
4'd4: sel = 6'b111_101;
4'd5: sel = 6'b111_110;
default: sel = 6'b111_111;
endcase
end
reg [3:0] number; //寄存数字。
always @(*) begin //对每个数码管进行赋值。
case (flag)
4'd0:number = surplus_money_low;
4'd1:number = surplus_money_high;
4'd4:number = num_money_low;
4'd5:number = num_money_high;
default: ;
endcase
end
always @(*) begin
if(sel == 6'b101_111 ||sel == 6'b111_110)begin
case(number)//匹配16进制数
4'h0: seg = 8'b0100_0000;//匹配到后参考共阳极真值表
4'h1: seg = 8'b0111_1001;
4'h2: seg = 8'b0010_0100;
4'h3: seg = 8'b0011_0000;
4'h4: seg = 8'b0001_1001;
4'h5: seg = 8'b0001_0010;
4'h6: seg = 8'b0000_0010;
4'h7: seg = 8'b0111_1000;
4'h8: seg = 8'b0000_0000;
4'h9: seg = 8'b0001_0000;
default : seg = 8'b1100_0000;
endcase
end
else begin
case(number)//匹配16进制数
4'h0: seg = 8'b1100_0000;//匹配到后参考共阳极真值表
4'h1: seg = 8'b1111_1001;
4'h2: seg = 8'b1010_0100;
4'h3: seg = 8'b1011_0000;
4'h4: seg = 8'b1001_1001;
4'h5: seg = 8'b1001_0010;
4'h6: seg = 8'b1000_0010;
4'h7: seg = 8'b1111_1000;
4'h8: seg = 8'b1000_0000;
4'h9: seg = 8'b1001_0000;
default : seg = 8'b1100_0000;
endcase
end
end
endmodule
5.5 key_filter模块
这里使用的是状态机的按键消抖模块,并且是一个一个消抖,也可以用多个按键同时消抖
//通过状态机实现消抖
module key_filter(
input clk,
input rst_n,
input key_in,
output reg key_out
);
//三段式状态机描述按键消抖。
//状态参数使用独热码进行定义
parameter state1 = 4'b0001, //空闲状态
state2 = 4'b0010,// 按下抖动状态
state3 = 4'b0100, //保持按下状态
state4 = 4'b1000; // 按键松开抖动状态
parameter MAX_NUM = 20'd100_0000; //20ms
reg [19:0] cnt;//20位的20ms计数器
reg [3:0] cstate, nstate; //当前状态和下一状态。
wire add_cnt;
wire end_cnt;
always @(posedge clk or negedge rst_n) begin // 20ms计时模块
if(!rst_n)begin
cnt <= 20'd0;
end
else if(add_cnt)begin
if(end_cnt)begin
cnt <= cnt;
end
else begin
cnt <= cnt +1'd1;
end
end
else begin
cnt <= 20'd0;
end
end
assign add_cnt = (cstate == state2 && !key_in ) || (cstate == state4 && key_in);
assign end_cnt = (cnt == MAX_NUM -1'd1 && add_cnt);
always @(posedge clk or negedge rst_n) begin //第一段,时序逻辑,状态空间切换
if(!rst_n) begin
cstate <= state1;
end
else begin
cstate <= nstate;
end
end
always @(*) begin //第二段,组合逻辑描述状态转移
case (cstate)
state1:begin
if(!key_in)begin //空闲状态时,当按下按键,进入按下抖动状态。
nstate <= state2;
end
else begin
nstate <= state1;
end
end
state2:begin
if(end_cnt)begin //按下抖动状态下,计满20ms后,进入状态三,稳定状态
nstate <= state3;
end
else if(key_in) begin
nstate <= state1;
end
else begin
nstate <= state2;
end
end
state3:begin //稳定状态下,检测到按键高电平,即松开按键,进入按键松开抖动状态。
if(key_in)begin
nstate <= state4;
end
else begin
nstate <= state3;
end
end
state4:begin
if(end_cnt)begin //松开抖动状态下,当计时满了20ms后,进入空闲状态。
nstate <= state1;
end
else begin
nstate <= state4;
end
end
default: nstate <= state1; //其他状态下,回到空闲状态
endcase
end
always @(*) begin //第三段,组合逻辑描述输出。
if(!rst_n)begin
key_out = 1'b0;
end
else begin
case (cstate) // 对当前状态的输出进行赋值。
state2:begin
if(end_cnt)begin
key_out = 1'b1;
end
else begin
key_out = 1'b0;
end
end
default: key_out = 1'b0;
endcase
end
end
endmodule
5.6 top_seller(顶层文件)
module top_seller (
input clk ,
input rst_n ,
input key1 ,
input key2 ,
input key3 ,
input key4 ,
output wire[5:0] sel ,
output wire[7:0] seg ,
output wire[3:0] led ,
output wire beep
);
wire add_key1;
wire add_key2;
wire add_key3;
wire add_key4;
wire [2:0] flag_sell ;
wire [7:0] num_money ;
wire [7:0] surplus_money ;
beep_ctrl u_beep_ctrl(
.clk (clk ) ,
.rst_n (rst_n ) ,
.flag_sell(flag_sell) , // 消抖的按键信号,控制系统暂停播放。
.pwm_o (beep)
);
seg_ctrl u_seg_ctrl(
.clk (clk ) ,
.rst_n (rst_n ) ,
.num_money (num_money ) , //投入总金额,放在sel[1:0]
.surplus_money (surplus_money) , //找零金额,放在sel[5:4]
.seg (seg ) ,
.sel (sel)
);
led_ctrl u_led_ctrl(
.clk (clk ) ,
.rst_n (rst_n ) ,
.flag_sell(flag_sell) ,
.led(led)
);
seller_ctrl u_seller_ctrl(
.clk (clk ) ,
.rst_n(rst_n) ,
.key1 (add_key1) , //确认付款
.key2 (add_key2) , //投币0.5
.key3 (add_key3) , //投币1
.key4 (add_key4) , //投币2
.flag_sell (flag_sell ) ,//是否成功支付,需要传递到led,蜂鸣器模块
.num_money (num_money ) ,//投入货币的总额,需要传递到数码管模块。最高6.5,即显示65
.surplus_money(surplus_money) //应该找零的余额,也传递到数码管。
);
key_filter u1_key_filter(
.clk (clk ) ,
.rst_n (rst_n ) ,
.key_in (key1 ) ,
.key_out(add_key1)
);
key_filter u2_key_filter(
.clk (clk ) ,
.rst_n (rst_n ) ,
.key_in (key2 ) ,
.key_out(add_key2)
);
key_filter u3_key_filter(
.clk (clk ) ,
.rst_n (rst_n ) ,
.key_in (key3 ) ,
.key_out(add_key3)
);
key_filter u4_key_filter(
.clk (clk ) ,
.rst_n (rst_n ) ,
.key_in (key4 ) ,
.key_out(add_key4)
);
endmodule
6. 仿真文件书写
6.1 仿真代码
`timescale 1ns/1ps
module tb_seller();
reg clk;
reg rst_n;
reg key1;
reg key2;
reg key3;
reg key4;
wire[5:0] sel ;
wire[7:0] seg ;
wire[3:0] led ;
wire beep;
defparam u_top_seller.u1_key_filter.MAX_NUM = 20'd10; //按键消抖时间20ms
defparam u_top_seller.u2_key_filter.MAX_NUM = 20'd10; //按键消抖时间20ms
defparam u_top_seller.u3_key_filter.MAX_NUM = 20'd10; //按键消抖时间20ms
defparam u_top_seller.u4_key_filter.MAX_NUM = 20'd10; //按键消抖时间20ms
defparam u_top_seller.u_seller_ctrl.NUM_5s = 20'd250;
defparam u_top_seller.u_led_ctrl.MAX_NUM = 20'd50;
defparam u_top_seller.u_seg_ctrl.MIN_NUM = 20'd15;
always #10 clk = ~clk ;
initial begin
clk = 1'b0;
rst_n = 1'b0;
key1 = 1'b1;
key2 = 1'b1;
key3 = 1'b1;
key4 = 1'b1;
#100 rst_n = 1'b1;
#100 key1 = 1'b0; //选择投币
#8000 key1 = 1'b1;
#100 key2 = 1'b0;
#8000 key2 = 1'b1; // 0.5
#8000 key3 = 1'b0;
#8000 key3 = 1'b1; // 1
#8000 key4 = 1'b0;
#8000 key4 = 1'b1; //2
#8000 key4 = 1'b0;
#8000 key4 = 1'b1; //2
#8000 key4 = 1'b0;
#8000 key4 = 1'b1; //2
#8000 key1 = 1'b0; //确认付款
#8000 key1 = 1'b1;
end
top_seller u_top_seller(
/*input */.clk (clk ) ,
/*input */.rst_n(rst_n) ,
/*input */.key1 (key1 ) ,
/*input */.key2 (key2 ) ,
/*input */.key3 (key3 ) ,
/*input */.key4 (key4 ) ,
/*output wire[5:0] */. sel ( sel ) ,
/*output wire[7:0] */. seg ( seg ) ,
/*output wire[3:0] */. led ( led ) ,
/*output */.beep(beep)
);
endmodule
6.2仿真效果实现
7.0上板验证
自动售货机