微波EDA网,见证研发工程师的成长!
首页 > 研发问答 > 嵌入式设计讨论 > FPGA,CPLD和ASIC > 最近做了一个自动售货机,有几个问题请教一下。。

最近做了一个自动售货机,有几个问题请教一下。。

时间:10-02 整理:3721RD 点击:

顶层文件:
module auto_machine(clk,clk1,reset,one_rmb,half_rmb,call,half_out,out,state,sel,disply);
        input clk,clk1,reset;//clk为自动售货机的基准时钟,clk1为数码管显示扫描时钟
        input one_rmb,half_rmb; //代表1元和5角
        output reg call,half_out,out;  //提示取物,找零和输出物品
        output reg[2:0]state;          //各种投币情况
        output reg[6:0]disply;         //数码管的七段数据
        output reg sel;                //选择数码管
        
        parameter idle = 0,          //idle空闲状态
                                 half =1,           //half投入硬币总钱数为5角状态
                                 one =2,            //one投入硬币总钱数为1元状态
                                 one_half =3,       //one_half投入硬币总钱数为1.5元状态
                                 two =4;            //two投入硬币总钱数为2元状态
               
        always @(posedge clk) begin
                if(reset) begin
                        state =idle;out=0;
                        half_out=0;call=0;
                        end
                case (state)
                        idle :
                                if(half_rmb) state = half;
                                else if(one_rmb) state = one;
                        half:
                                if(half_rmb) state =one;
                                else if(one_rmb) state =one_half;
                        one:
                                if(half_rmb) state= one_half;
                                else if(one_rmb) state =two;
                        one_half:
                                if(half_rmb) state= two;
                                else if(one_rmb) begin
                                        out =1;       //售出物品
                                        call=1;        //提示取物
                                        state=idle;
                                        end
                        two:
                                if(half_rmb) begin
                                        out=1;
                                        call=1;
                                        state=idle;
                                        end
                                else if(one_rmb) begin
                                                        state =idle ;
                                                        out =1;    //售出物品
                                                        call=1;    //提示取物
                                                        half_out=1; //找零
                                                        end
                                endcase
                        end
        reg [3:0] disply0,disply1;   //总价钱的高,低2个BCD数据
        reg [4:0] sum;                //统计投币的总价钱
                        
        always @(posedge clk) begin
                if(half_rmb) sum=sum+5;   //统计投币总钱数
                else if(one_rmb) sum=sum+10;
                else sum=sum;
               
                if(sum>=30) begin          //将总钱数转换成2个BCD码
                disply0 =0;
                disply1 =3;
                end
               
                else if(sum>=20) begin
                disply0 =sum-20;
                disply1 =2;
                end
               
                else if(sum>=10) begin
                disply0 <=sum-10;
                disply1 <=1;
                end
               
                else begin
                disply0 =sum;
                disply1 =0;
                end
        end
        
        reg [3:0] d;                  //将总价钱分为2个BCD码的寄存器
        always @(posedge clk1) begin
                if(sel<1) sel =sel+1;    //扫描数码管,即选择数码管
                else sel =0;
                case (sel)               //将显示数码传给相应的数码管
                        0:d=disply1;
                        1:d=disply0;
                        default:d=4'bx;
                endcase
                end
               
        always @(d) begin         //译码
                case(d)
                        0:disply =7'b1111110;  //7E
                        1:disply =7'b0110000;  //30
                        2:disply =7'b1101101;  //6D
                        3:disply =7'b1111001;  //79
                        4:disply =7'b0110011;  //33
                        5:disply =7'b1011011;  //5B
                        6:disply =7'b1011111;  //5F
                        7:disply =7'b1110000;  //70
                        8:disply =7'b1111111;  //7F
                        9:disply =7'b1111011;  //7B
                        default:disply =7'bx;
                endcase
                end
endmodule
testbench:
`timescale 1ns/1ps
module auto_machine_tb();
        
        reg clk;//clk为自动售货机的基准时钟
        reg clk1;//clk1为数码管显示扫描时钟
        reg reset;
        reg one_rmb;//代表1元
        reg half_rmb;//代表5角
        wire call;
        wire half_out;
        wire out;
        wire [2:0]state;
        wire [6:0]disply;
        wire sel;
auto_machine i1(.clk(clk),
                                        .clk1(clk1),
                                        .reset(reset),
                                        .one_rmb(one_rmb),
                                        .half_rmb(half_rmb),
                                        .call(call),
                                        .half_out(half_out),
                                        .out(out),
                                        .state(state),
                                        .sel(sel),
                                        .disply(disply)
                                        );
initial clk =0;  //clk
always #10 clk =~clk;
initial clk1 =0;  //clk1
always #40 clk1 =~clk1;
initial begin  //reset
        reset =1;
        #100;
        reset=0;
        #400;
        reset=1;
        #100;
        reset=0;
        #275;
        reset=1;
        #100;
        reset=0;
        #300;
        reset=1;
        #100;
        reset=0;
        #400;
        $stop;
end
initial begin  //half_rmb
        half_rmb=0;
        #100;
        half_rmb=1;
        #200;
        half_rmb=0;
        #100;
        half_rmb=1;
        #100;
        half_rmb=0;
        #100;
        half_rmb=1;
        #75;
        half_rmb=0;
        #700;
        half_rmb=1;
        #200;
        half_rmb=0;
        #200;
        $stop;
end
initial begin //one_rmb
        one_rmb=0;
        #300;
        one_rmb=1;
        #100;
        one_rmb=0;
        #275;
        one_rmb=1;
        #200;
        one_rmb=0;
        #100;
        one_rmb=1;
        #300;
        one_rmb=0;
        #300;
        one_rmb=1;
        #200;
        $stop;
end

endmodule
问题:1.
波形图:


disply就是数码管显示,有红色线?但是实际中不是这样的。
2.状态视图不能出来,就是一片空白。不知原因所在,求讲解。

你说的两个问题,都是你跨时钟域产生的,而且出现modelsim中红色的送不定值,不建议送不定值,给高组值也比这个要好得多的;建议从新规划一下代码,别按照C风格来搞

我发现这是一个神奇的器件

你好,有问题和你讨论,方便的话加我qq176426425

学习了。。

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top