EDA, 自动售货机设计报告,含VHDL源码,多层设计,放的报告

EDA技术应用》学生项目报告

二、项目目的

1. 项目原理

        通过VHDL多层文本设计,实现自动售货机控制系统的设计,通过仿真来模拟售货机内部进行选择商品、投入货币、计算金额,数码管显示等等售货机日常应用功能。

2. 项目意义

        本次自动售货机控制系统的设计主要是为了锻炼VHDL文本编写能力,VHDL项目的实践。而自动售货机系统也具有很好的设计理念融入,涵盖了许多VHDL设计的核心方法和知识点。项目也具有较高的实用性,可以很好的提高购物的便利性,自动售货机可以部署在人流量大的地区,提供24小时不间断服务,增加消费者购物的欲望和随时需求。降低人力成本:自动化销售减少了对店员的依赖,降低了长期的运营成本。数据收集与分析:现代自动售货机可收集销售数据,帮助商家分析消费行为,优化商品结构和补货策略。

三、项目内容 

1. EDA设计流程

  1. 首先是需求分析,确定售货机的功能需求,如支持的商品类型、支付方式,显示内容,等待规则等。
  2. 系统文本架构设计:确定好功能模块划分,确定好底层和顶层设计内容。
  3. VHDL文本设计编写:使用Quartus编写VHDL文本,编写多层设计。

2. VHDL设计文本

        顶层文本:

LIBRARY IEEE; ---- ieee标准库声明(电子工程协会标准)

USE IEEE.STD_LOGIC_1164.all; -- 使用ieee.std_logic_1164库(标准逻辑库)的所有数据包

USE IEEE.STD_LOGIC_UNSIGNED.ALL; -- 使用ieee.std_logic_unsigned库的所有数据包,引入重载运算符

USE IEEE.STD_LOGIC_ARITH.ALL;  --  引入新的类型,像是unsigned类型等等

ENTITY mall IS

   PORT(clk20:IN STD_LOGIC;                           --时钟

        rst2:IN STD_LOGIC;                            --复位键

        coin2:IN STD_LOGIC_VECTOR(1 DOWNTO 0);     --投币

        pp:IN STD_LOGIC_VECTOR(3 DOWNTO 0);       --选择商品

        l12:OUT STD_LOGIC_VECTOR(6 DOWNTO 0) ;    --显示商品价格

        l22:OUT STD_LOGIC_VECTOR(6 DOWNTO 0);   --显示需要补交的钱数

        l32:OUT STD_LOGIC_VECTOR(6 DOWNTO 0);    --显示找零钱数

        suc2:OUT STD_LOGIC;                         --交易成功信号

          pd: out std_logic_vector(3 downto 0);

        showout2:OUT STD_LOGIC);                     --找零成功信号

END mall;

ARCHITECTURE jie OF mall IS

  

COMPONENT fp IS                                --分频模块端口信息

        PORT(CLK20:IN STD_LOGIC;

                 co:OUT STD_LOGIC);

END COMPONENT  fp;

   COMPONENT  xianshi  IS                           --显示模块端口信息

          PORT(price: IN STD_LOGIC_VECTOR(3 DOWNTO 0);

                     need: IN STD_LOGIC_VECTOR(3 DOWNTO 0);

                     mout: IN STD_LOGIC_VECTOR(3 DOWNTO 0);

                     l1: OUT STD_LOGIC_VECTOR(6 DOWNTO 0);

                     l2: OUT STD_LOGIC_VECTOR(6 DOWNTO 0);

                     l3: OUT STD_LOGIC_VECTOR(6 DOWNTO 0));

   END COMPONENT xianshi;

 

COMPONENT shouhuoji IS                          --主控状态机模块端口信息

          PORT( clk: IN STD_LOGIC;

                             rst: IN STD_LOGIC;

                             coIN: IN STD_LOGIC_VECTOR(1 DOWNTO 0);

                             p: IN STD_LOGIC_VECTOR(3 DOWNTO 0);

                             price: OUT STD_LOGIC_VECTOR(3 DOWNTO 0);

                             need: OUT STD_LOGIC_VECTOR(3 DOWNTO 0);

                             mout: OUT STD_LOGIC_VECTOR(3 DOWNTO 0);

                             suc: OUT STD_LOGIC;

                             showout:OUT STD_LOGIC;

                             pt: OUT STD_LOGIC_VECTOR(3 DOWNTO 0));

END COMPONENT shouhuoji;

SIGNAL co1:STD_LOGIC;

SIGNAL need1:STD_LOGIC_VECTOR(3 DOWNTO 0);

SIGNAL price1:STD_LOGIC_VECTOR(3 DOWNTO 0);

SIGNAL mout1:STD_LOGIC_VECTOR(3 DOWNTO 0);

BEGIN

        U1:fp PORT MAP (clk20,co=>co1);                        --各模块间的映射连接

        U2:shouhuoji PORT MAP(co1, rst2, coin2, pp, price1, need1, mout1, suc2, showout2, pd);

        U3:xianshi PORT MAP(price1, need1, mout1, l12, l22, l32);

 END jie;

底层u1,进行延时:

LIBRARY IEEE; ---- ieee标准库声明(电子工程协会标准)

USE IEEE.STD_LOGIC_1164.all; -- 使用ieee.std_logic_1164库(标准逻辑库)的所有数据包

USE IEEE.STD_LOGIC_UNSIGNED.ALL; -- 使用ieee.std_logic_unsigned库的所有数据包,引入重载运算符

USE IEEE.STD_LOGIC_ARITH.ALL;  --  引入新的类型,像是unsigned类型等等

ENTITY  fp  IS

PORT(CLK20:IN STD_LOGIC;

        co:OUT STD_LOGIC);

END fp;

ARCHITECTURE  a  OF  fp  IS

SIGNAL q:STD_LOGIC_VECTOR(24 DOWNTO 0);

BEGIN

   PROCESS(CLK20)

        BEGIN

         IF CLK20' EVENT AND CLK20='1' THEN

         -- IF q="1001100010010110011111111" THEN    -- 这里是延时的10秒在仿真里看不出来

                       IF q="0000000000000000000000011" THEN

             q<="0000000000000000000000000";co<='1'; ELSE

             q<=q+1;co<='0';

              END IF;

      END IF;

       END PROCESS;

END a;

底层u2进行售货机内部运算,传输数据:

LIBRARY IEEE; ---- ieee标准库声明(电子工程协会标准)

USE IEEE.STD_LOGIC_1164.all; -- 使用ieee.std_logic_1164库(标准逻辑库)的所有数据包

USE IEEE.STD_LOGIC_UNSIGNED.ALL; -- 使用ieee.std_logic_unsigned库的所有数据包,引入重载运算符

USE IEEE.STD_LOGIC_ARITH.ALL;  --  引入新的类型,像是unsigned类型等等

ENTITY shouhuoji IS

     PORT( clk:IN STD_LOGIC;                             --时钟

                  rst:IN STD_LOGIC;                              --复位信号

                  coin:IN STD_LOGIC_VECTOR(1 DOWNTO 0);      --投币

                  p:IN STD_LOGIC_VECTOR(3 DOWNTO 0);         --选择商品

                  price:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);     --商品价格

                 need:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);      --需要补交的钱数

                 mout:OUT STD_LOGIC_VECTOR(3 DOWNTO 0);     --显示找零钱数

                 suc:OUT STD_LOGIC;                             --交易成功信号

                 showout:OUT STD_LOGIC;

                               pt:OUT STD_LOGIC_VECTOR(3 DOWNTO 0));              --找零成功信号

END shouhuoji;

ARCHITECTURE  H  OF  shouhuoji  IS

    TYPE state_type IS(a,b,c,d,g);           --枚举数据类型定义状态机共a、b、c、d、g五种状态

    SIGNAL current_state:state_type:=a;     --定义初始状态为a

    SIGNAL q: integer range 0 to 100;        --投币过程中10秒计时的计数器

    SIGNAL paidtemp: STD_LOGIC_VECTOR(3 DOWNTO 0);  --已付的钱数

    SIGNAL needtemp: STD_LOGIC_VECTOR(3 DOWNTO 0);  --投币后与单价的差价

    SIGNAL backmoney: STD_LOGIC_VECTOR(3 DOWNTO 0); --需要找零的钱数

    SIGNAL pricetemp: STD_LOGIC_VECTOR(3 DOWNTO 0); --商品的单价

 begin

 PROCESS(clk)

        BEGIN

              

               IF rst='0' THEN

                      current_state<=b;

               ELSIF clk' EVENT AND clk='1' THEN

                      pt<="1111";

                      CASE current_state IS

                             WHEN a=>         

                                    paidtemp<="0000";

                                    backmoney<="0000";

                                    pricetemp<="0000";

                                    q<=0;

                                    mout<="0000";

                                    need<="0000";

                                    price<="0000";

                                    suc<='0';

                                    showout<='0';

                             IF p="0001" THEN                                         

                                    pricetemp<=pricetemp+2;

                                    needtemp<=pricetemp;

                                    current_state<=b;

                             ELSIF p="0010" THEN

                                    pricetemp<=pricetemp+3;

                                    needtemp<=pricetemp;

                                    current_state<=b;

                             ELSIF p="0100" THEN

                                    pricetemp<=pricetemp+4;needtemp<=pricetemp;

                                    current_state<=b;

                             ELSIF p="1000" THEN pricetemp<=pricetemp+6;needtemp<=pricetemp;

                                    current_state<=b;

                             ELSE

                                    current_state<=a;

                             END IF;  

                             price<=pricetemp;

                             pt<=pricetemp;

                             WHEN b=>     

                                    q<=q+1;                                 -- 10秒开始计时

                                    CASE coin IS 

                                           WHEN "10"=> paidtemp<=paidtemp+1;       --投入1元则已付钱数加1

                                           WHEN "01"=> paidtemp<=paidtemp+5;        --投入5元则已付钱数加5

                                           WHEN others=> paidtemp<=paidtemp;          --其余情况已付钱数不变

                                    END CASE;  

                     

                                    IF paidtemp>=pricetemp  THEN

                                           needtemp<="0000";

                                           backmoney<=paidtemp-pricetemp;

                                           current_state<=d;

                                    END IF;

              

                                    IF paidtemp<pricetemp  THEN

                                           needtemp<=pricetemp-paidtemp;backmoney<="0000";

                                          

                                           IF q=10 THEN

                                                  IF paidtemp="0000" THEN

                                                         current_state<=a;         --到了延时的10秒,如果已付钱数为0就回到a状态

                                                  ELSE

                                                         q<=0;

                                                         current_state<=c;--已付钱数不为零则重新开始计时,进入状态c

                                           END IF;

                     

                                           ELSE

                                                  current_state<=b;    --不到10秒,继续停留在状态b  

                                           END IF;

                                    END IF;  

                              price<=pricetemp;

                              need<=needtemp;

                              pt<=pricetemp;

                              

                      WHEN c=>

                             q<=q+1;                                   --10秒开始计时

                             CASE coin IS

                                    WHEN "10"=> paidtemp<=paidtemp+1;           --投币1元则已付加1

                                    WHEN "01"=> paidtemp<=paidtemp+5;           --投币5元则已付加5

                                    WHEN others=> paidtemp<=paidtemp;            --其余情况已付不变

                             END CASE;

                             IF paidtemp>=pricetemp THEN              --接下来判断与b状态类似

                                     needtemp<="0000";backmoney<=paidtemp-pricetemp;current_state<=d;

                             END IF;  --当已付钱数大于单价,则还需要钱数为0,找零钱数等于已付钱数减去单价,进入状态d

                      WHEN d=>

                             suc<='1';                      --交易成功指示灯亮

                             price<=pricetemp;              --显示单价

                             pt<=pricetemp;

                             need<=needtemp;               --显示需补交的钱

                             IF backmoney>"0000" THEN

                                    mout<=backmoney;showout<='1'; --如果已付大于单价即找零不为0,显示找零同时,找零指示灯亮

                             ELSE

                                    mout<="0000";showout<='0';   --已付小于单价即找零为0并显示,找零指示灯不亮

                             END IF;  

                             current_state<=a;               --返回到状态a

                     

                      WHEN g=>

                             suc<='0';price<=pricetemp;need<=needtemp;  --交易成功指示灯不亮,同时显示单价和还需多少钱

                             IF backmoney>"0000" THEN 

                               mout<=backmoney;

                               showout<='1';--如果找零大于0(即投币了但小于单价),退钱并且找零指示灯亮

                             ELSE  mout<="0000";showout<='0';        --如果为0(未投币),找零指示灯不亮

                             END IF;  

                             current_state<=a;            --回到状态a

                      end case;

        END IF;

       

END process;

END H;

                       

底层u3制作显示数码馆段选数据:

LIBRARY IEEE; ---- ieee标准库声明(电子工程协会标准)

USE IEEE.STD_LOGIC_1164.all; -- 使用ieee.std_logic_1164库(标准逻辑库)的所有数据包

USE IEEE.STD_LOGIC_UNSIGNED.ALL; -- 使用ieee.std_logic_unsigned库的所有数据包,引入重载运算符

USE IEEE.STD_LOGIC_ARITH.ALL;  --  引入新的类型,像是unsigned类型等等

entity xianshi is

PORT(price: IN STD_LOGIC_VECTOR(3 DOWNTO 0);

          need: IN STD_LOGIC_VECTOR(3 DOWNTO 0);

          mout: IN STD_LOGIC_VECTOR(3 DOWNTO 0);

          l1: OUT STD_LOGIC_VECTOR(6 DOWNTO 0);

          l2: OUT STD_LOGIC_VECTOR(6 DOWNTO 0);

          l3: OUT STD_LOGIC_VECTOR(6 DOWNTO 0));

end xianshi;

architecture tt of xianshi is

begin

        PROCESS(price,need,mout)

                BEGIN

                      CASE price IS

                             WHEN "0000"=>l1<="0111111";

                             WHEN "0001"=>l1<="0000110";

                             WHEN "0010"=>l1<="1011011";

                             WHEN "0011"=>l1<="1001111";

                             WHEN "0100"=>l1<="1100110";

                             WHEN "0101"=>l1<="1101101";

                             WHEN "0110"=>l1<="1111101";

                             WHEN "0111"=>l1<="0000111";

                             WHEN "1000"=>l1<="1111111";

                             WHEN "1001"=>l1<="1101111";

                             WHEN "1010"=>l1<="1110111";

                             WHEN OTHERS=>l1<=null;

                      END CASE;

                     

                      CASE need IS

                             WHEN "0000"=>l2<="0111111";

                             WHEN "0001"=>l2<="0000110";

                             WHEN "0010"=>l2<="1011011";

                             WHEN "0011"=>l2<="1001111";

                             WHEN "0100"=>l2<="1100110";

                             WHEN "0101"=>l2<="1101101";

                             WHEN "0110"=>l2<="1111101";

                             WHEN "0111"=>l2<="0000111";

                             WHEN "1000"=>l2<="1111111";

                             WHEN "1001"=>l2<="1101111";

                             WHEN "1010"=>l2<="1110111";

                             WHEN OTHERS=>l2<=null;

                      end case;

                      CASE mout IS

                             WHEN "0000"=>l3<="0111111";

                             WHEN "0001"=>l3<="0000110";

                             WHEN "0010"=>l3<="1011011";

                             WHEN "0011"=>l3<="1001111";

                             WHEN "0100"=>l3<="1100110";

                             WHEN "0101"=>l3<="1101101";

                             WHEN "0110"=>l3<="1111101";

                             WHEN "0111"=>l3<="0000111";

                             WHEN "1000"=>l3<="1111111";

                             WHEN "1001"=>l3<="1101111";

                             WHEN "1010"=>l3<="1110111";

                             WHEN OTHERS=>l3<=null;

                      end caSE;

        end process;

end tt;

       

3. VHDL仿真以及时序分析

       

因为实际效果延时时间到达10秒,而在仿真中最大时间是10ns这也导致一开始一直没有现象改变,后来再次进入深度理解,才知道不是文本设计问题而只是单纯的显示问题,通过调整代码中的一些配置,成功做到了仿真效果。以下是仿真的结果

                                    

80ns处,成功取得商品价格信息

       116.21ns时,投入了一定的硬币后,发现需要找补的价格l22逐渐从需找补整个价格“1100110”到现在的“0111111”也就是数码管的4到了现在的0,成功补齐了要付的货币,suc2置为高电平,输出表明交易成功。甚至还可以发现在l32这里,也有了数字,说明在延时时间内,多投了钱, 现在成功进行了“0000110”的找零也就是1的找零,最后也有showout2的高电平,输出表明找零成功。

最后再让我们确定一下投入的货币数,因为我们设置的延时为“0011”三次时钟上升沿,在到来三次开始进行投币计数,记三次后结束时刚好投入为5,5-4=1,正好对应找零数,设计完成。

因为实际效果延时时间到达10秒,而在仿真中最大时间是10ns这也导致一开始一直没有现象改变,后来再次进入深度理解,才知道不是文本设计问题而只是单纯的显示问题,通过调整代码中的一些配置,成功做到了仿真效果。以下是仿真的结果

                                    

80ns处,成功取得商品价格信息

       116.21ns时,投入了一定的硬币后,发现需要找补的价格l22逐渐从需找补整个价格“1100110”到现在的“0111111”也就是数码管的4到了现在的0,成功补齐了要付的货币,suc2置为高电平,输出表明交易成功。甚至还可以发现在l32这里,也有了数字,说明在延时时间内,多投了钱, 现在成功进行了“0000110”的找零也就是1的找零,最后也有showout2的高电平,输出表明找零成功。

        最后再让我们确定一下投入的货币数,因为我们设置的延时为“0011”三次时钟上升沿,在到来三次开始进行投币计数,记三次后结束时刚好投入为5,5-4=1,正好对应找零数,设计完成。

  • 15
    点赞
  • 17
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
自动售货机VHDL设计EDA课程设计是基于VHDL(Very High-Speed Integrated Circuit Hardware Description Language)语言和EDA(Electronic Design Automation)工具进行的。该设计旨在实现一个能够自动进行商品销售的自动售货机。 首先,我将根据设计需求和功能要求,使用VHDL语言编写自动售货机的硬件描述代码。该代码将包括自动售货机的控制逻辑、状态机、输入输出接口等。 接下来,我将使用EDA工具对编写的VHDL代码进行仿真和验证。通过仿真,我可以模拟自动售货机的运行过程,测试控制逻辑的正确性和性能。如果出现错误或不符合要求的情况,我将修改代码并再次进行仿真,直到达到预期效果。 在完成仿真验证后,我将使用EDA工具进行自动售货机的综合。综合是将VHDL代码转换为可用于FPGA或ASIC等硬件平台的逻辑门级的电路描述。综合的过程中,我会关注电路的时序约束、资利用率和功耗等因素。 接着,我将进行布局布线,即将综合后的逻辑电路映射到实际的硬件平台上。在布局布线过程中,我会考虑电路的物理约束、时序优化和信号完整性等问题,以确保设计的可靠性和稳定性。 最后,我将使用EDA工具进行静态时序分析和时序约束的验证。通过时序分析,我可以评估自动售货机的性能指标,如最大可达频率和潜在的时序冲突。同时,我还将验证时序约束是否满足设计要求。 总结来说,自动售货机VHDL设计EDA课程设计包括硬件描述代码的编写、仿真验证、综合、布局布线和时序分析等步骤。通过这样的设计流程,能够实现一个功能强大、性能优良的自动售货机系统。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值