北邮数电实验报告

数字电路与逻辑设计实验报告

一、要求要求:

设计制作一个简易计算器,实现最大输入两位十进制数字的加减乘运算。

基本要求:

1、  实现最大输入两位十进制数字的加减乘运算;八个拨码开关按两位8421bcd码输入。

2、  能够实现多次连算(无优先级,从左到右计算结果),如 12+34×56-78=2498。

3、  最大长度以数码管最大个数为限,溢出报警。

提高要求:

1、  有正负数区分。

2、  实现除法(不能整除时小数保留2位有效数字)。

3、  其它扩展功能。

二、系统设计:

设计思路:

1、  将该程序进行分模块设计。可以将程序分为:主程序、译码模块和防抖模块。其中,

主程序负责将输入的数据进行存储,对数据进行运算,将数据输出到数码上等;防抖模块负责对按键输入的数防抖;译码模块负责对输入的数据进行译码(由8421bcd码转化为十进制的编码)。

2、  分模块进行相应模块的编写。

3、  对编好的模块进行测试。

4、  编写主程序并进行调试。

总体框图:

流程图:

分块设计:(按实际操作的分块)

输入模块:由符号开关和拨码开关构成。采用序列存储的方式存储相应的输入。

输入译码模块:将输入的符号序列转化成先用状态,以便选取对应的计算方法;将输入的8421bcd码转化成相应的两位十进制数。

数码显示模块:将寄存器内的数进行输出到数码管上。显示所输入的第一个数以及最后的结果。

计算模块:调用相应的计算方式,对所输入的数进行计算。

防抖模块:在用按键输入时,所得到的信号可能 会有抖动,因此加入此抖动电路。

三、仿真波形及波形分析:

分析(波形仿真时,为了方便观察,将8421bcd码输入方式,该为了十进制的直接输入方式,并将输出,有原来的数码管显示改成了直接数字显示)

由图中可以看出,当输入12 ,按下“确定”,数字就输入到了寄存器中,输入“+”号(对应仿真中的fuhao“100000”),在输入一个数35,按下“确定”,该计算器就件寄存器中的数与第二次输入的数进行相加,得到结果47。此时该结果又被直接保存到了寄存器中,继续输入运算符“-”(对应仿真中得fuhao“010000”),输入第三个数18,按下“确定”,计算器对其做减法运算,得到结果29,该结果又在寄存器中存储着。继续后续输入相应符号,相应数字可以继续进行相应的计算,只要结果在(-99999,99999)之间,就可以一直进行计算。

四、源程序:

主程序:

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_ARITH.ALL;

USE IEEE.STD_LOGIC_SIGNED.ALL;

Entity lzjisuanqi is

port(

           

       cat: OUT STD_LOGIC_VECTOR(5 DOWNTO 0);              

       digital:OUT STD_LOGIC_VECTOR(6 DOWNTO 0);           

       clk:in std_logic;                                    

       beep:out std_logic;                                  

       num:in std_logic_vector(7 downto 0);

       fuhao:in std_logic_vector(5 downto 0)   

     );

end entity lzjisuanqi;

architecture lz of lzjisuanqi is

component transform

port(cin:in std_logic_vector(7 downto 0);

     cout: out integer range 0 to 99);

end component;

component fangdou IS                

PORT(

    clk :   IN STD_LOGIC;

    key_in: IN STD_LOGIC_VECTOR(5 DOWNTO 0);

    key_out:OUT STD_LOGIC_VECTOR(5 DOWNTO 0)   

);

end component;

type state_type is (s0,s1,s2);

signal state:state_type;

type time_type is (t1,t2,t3,t4,t5,t6);

signal time1:time_type;

signal num1:integer range 0 to 99;

signal result1:integer range -99999 to 99999;

signal result2:integer range -99999 to 99999;

signal cat0:integer range 0 to 9;

signal cat1:integer range 0 to 9;

signal cat2:integer range 0 to 9;

signal cat3:integer range 0 to 9;

signal cat4:integer range 0 to 9;

signal cnt : integer range 0 to 50000;

signal clk_tmp : std_logic;

signal ffuhao: std_logic_vector(5 downto 0);

begin

u1:transform port map(cin=>num,cout=>num1);译码 

u2:fangdou port map(clk=>clk,key_in=>fuhao,key_out=>ffuhao);

                                                           防抖

    process(clk)                                            

    begin

        if (clk'event and clk='1') then

            if cnt=49999 then

                cnt<=0;

                clk_tmp<= not clk_tmp;                

            else

                cnt<=cnt+1;

            end if;

        end if;

    end process;

p1:process(clk_tmp)

   

     variable result:integer range -9999999 to 9999999; 缓存

     variable fuhao1:integer range 0 to 6:=0;

    begin

     if (clk_tmp'event and clk_tmp='1') then

         case state is

         when s0=>result:=num1;

              state<=s1;

            when s1=>

                  if(ffuhao="000010")then                

                  fuhao1:=0;state<=s1;

                 

                  elsif(ffuhao="000001")then                   

                  result:=num1;fuhao1:=0;state<=s0;beep<='0';

                 

                  elsif(ffuhao="001000")then             

               fuhao1=3

                  fuhao1:=3;

                  state<=s2;

                 

                  elsif(ffuhao="010000")then            

                  fuhao1:=2;

                  state<=s2;

                 

                  elsif(ffuhao="100000")then              

                  fuhao1=1

                  fuhao1:=1;

                  state<=s2;

                  else state<=s1;

                  end if;

                 

                  

         when s2=>if(fuhao1=0)then                      

                     result:=result;state<=s1;

                    

                    elsif(fuhao1=1)then                  

                     result:=result+num1;

                      if(result>99999 or result<-99999)then

                        result:=num1;beep<='1';state<=s0;

                       else beep<='0';state<=s1;

                      end if;

                 

                     elsif(fuhao1=2)then                  

                      result:=result-num1;

                       if(result>99999 or result<-99999)then

                        result:=num1;beep<='1';state<=s0;

                         else beep<='0';state<=s1;                

                      end if;

                     

                      elsif(fuhao1=3)then             

                      result:=result*num1;

                       if(result>99999 or result<-99999)then

                        result:=num1;beep<='1';state<=s0;

                         else beep<='0';state<=s1; 

                        end if;

                    end if;

                            

           end case;

    result2<=result;

 if(result2<0)then result1<=abs(result2);             

      else result1<=result;

      end if;

   if(result1>=90000)then cat4<=9;                           

   elsif(result1>=80000 and result1<90000)then cat4<=8;

   elsif(result1>=70000 and result1<80000)then cat4<=7;

   elsif(result1>=60000 and result1<70000)then cat4<=6;

   elsif(result1>=50000 and result1<60000)then cat4<=5;      

   elsif(result1>=40000 and result1<50000)then cat4<=4;          

   elsif(result1>=30000 and result1<40000)then cat4<=3;

   elsif(result1>=20000 and result1<30000)then cat4<=2;

   elsif(result1>=10000 and result1<20000)then cat4<=1;

   elsif(result1<10000)then cat4<=0;

   end if;

   if((result1-cat4*10000)>=9000 and (result1-cat4*10000)<10000)then cat3<=9;    

   elsif((result1-cat4*10000)>=8000 and (result1-cat4*10000)<9000)then cat3<=8;

   elsif((result1-cat4*10000)>=7000 and (result1-cat4*10000)<8000)then cat3<=7;

   elsif((result1-cat4*10000)>=6000 and (result1-cat4*10000)<7000)then cat3<=6;

   elsif((result1-cat4*10000)>=5000 and (result1-cat4*10000)<6000)then cat3<=5;

   elsif((result1-cat4*10000)>=4000 and (result1-cat4*10000)<5000)then cat3<=4;

   elsif((result1-cat4*10000)>=3000 and (result1-cat4*10000)<4000)then cat3<=3;

   elsif((result1-cat4*10000)>=2000 and (result1-cat4*10000)<3000)then cat3<=2;

   elsif((result1-cat4*10000)>=1000 and (result1-cat4*10000)<2000)then cat3<=1;

   elsif((result1-cat4*10000)<1000)then cat3<=0;

   end if;

   if((result1-cat4*10000-cat3*1000)>=900and (result-cat4*10000-cat3*1000)<1000)then cat2<=9;

   elsif((result1-cat4*10000-cat3*1000)>=800and (result1-cat4*10000-cat3*1000)<900)then cat2<=8;

   elsif((result1-cat4*10000-cat3*1000)>=700and (result1-cat4*10000-cat3*1000)<800)then cat2<=7;

   elsif((result1-cat4*10000-cat3*1000)>=600and (result1-cat4*10000-cat3*1000)<700)then cat2<=6;

   elsif((result1-cat4*10000-cat3*1000)>=500and (result1-cat4*10000-cat3*1000)<600)then cat2<=5;              

   elsif((result1-cat4*10000-cat3*1000)>=400and (result1-cat4*10000-cat3*1000)<500)then cat2<=4;

   elsif((result1-cat4*10000-cat3*1000)>=300and (result1-cat4*10000-cat3*1000)<400)then cat2<=3;

   elsif((result1-cat4*10000-cat3*1000)>=200and (result1-cat4*10000-cat3*1000)<300)then cat2<=2;

   elsif((result1-cat4*10000-cat3*1000)>=100and (result1-cat4*10000-cat3*1000)<200)then cat2<=1;

   elsif((result1-cat4*10000-cat3*1000)<100) then cat2<=0;

   end if;

   if((result1-cat4*10000-cat3*1000-cat2*100)>=90and (result1-cat4*10000-cat3*1000-cat2*100)<100)then cat1<=9;

   elsif((result1-cat4*10000-cat3*1000-cat2*100)>=80and (result1-cat4*10000-cat3*1000-cat2*100)<90)then cat1<=8;

   elsif((result1-cat4*10000-cat3*1000-cat2*100)>=70and (result1-cat4*10000-cat3*1000-cat2*100)<80)then cat1<=7;

   elsif((result1-cat4*10000-cat3*1000-cat2*100)>=60and (result1-cat4*10000-cat3*1000-cat2*100)<70)then cat1<=6;       

   elsif((result1-cat4*10000-cat3*1000-cat2*100)>=50and (result1-cat4*10000-cat3*1000-cat2*100)<60)then cat1<=5;

   elsif((result1-cat4*10000-cat3*1000-cat2*100)>=40and (result1-cat4*10000-cat3*1000-cat2*100)<50)then cat1<=4;

   elsif((result1-cat4*10000-cat3*1000-cat2*100)>=30and (result1-cat4*10000-cat3*1000-cat2*100)<40)then cat1<=3;

   elsif((result1-cat4*10000-cat3*1000-cat2*100)>=20and (result1-cat4*10000-cat3*1000-cat2*100)<30)then cat1<=2;

   elsif((result1-cat4*10000-cat3*1000-cat2*100)>=10and (result1-cat4*10000-cat3*1000-cat2*100)<20)then cat1<=1;

   elsif((result1-cat4*10000-cat3*1000-cat2*100)<10)then cat1<=0;

   end if;

  

   cat0<=result1-cat4*10000-cat3*1000-cat2*100-cat1*10;

  

     

                                                  

      if(result>=0)then 以下为数码管显示相应数字

     

            CASE time1 IS

             

              WHEN t1 =>

              cat <= "101111";

              CASE cat4 IS

              WHEN  0=> digital <= "1111110";

              WHEN  1=> digital <= "0110000";

              WHEN  2=> digital <= "1101101";

              WHEN  3=> digital <= "1111001";

              WHEN  4=> digital <= "0110011";

              WHEN  5=> digital <= "1011011";

              WHEN  6=> digital <= "1011111";

              WHEN  7=> digital <= "1110000";

              WHEN  8=> digital <= "1111111";

              WHEN  9=> digital <= "1111011";

              END CASE;

              time1 <= t2;

     

              WHEN t2 =>

              cat <= "110111";

              CASE cat3 IS

              WHEN  0=> digital <= "1111110";

              WHEN  1=> digital <= "0110000";

              WHEN  2=> digital <= "1101101";

              WHEN  3=> digital <= "1111001";

              WHEN  4=> digital <= "0110011";

              WHEN  5=> digital <= "1011011";

              WHEN  6=> digital <= "1011111";

              WHEN  7=> digital <= "1110000";

              WHEN  8=> digital <= "1111111";

              WHEN  9=> digital <= "1111011";

              end case;

              time1 <= t3;

             

              WHEN t3 =>

              cat <= "111011";

              CASE cat2 IS

              WHEN  0=> digital <= "1111110";

              WHEN  1=> digital <= "0110000";

              WHEN  2=> digital <= "1101101";

              WHEN  3=> digital <= "1111001";

              WHEN  4=> digital <= "0110011";

              WHEN  5=> digital <= "1011011";

              WHEN  6=> digital <= "1011111";

              WHEN  7=> digital <= "1110000";

              WHEN  8=> digital <= "1111111";

              WHEN  9=> digital <= "1111011";

              END CASE;

              time1 <= t4;

             

              WHEN t4 =>

              cat <= "111101";

              CASE cat1 IS

              WHEN  0=> digital <= "1111110";

              WHEN  1=> digital <= "0110000";

              WHEN  2=> digital <= "1101101";

              WHEN  3=> digital <= "1111001";

              WHEN  4=> digital <= "0110011";

              WHEN  5=> digital <= "1011011";

              WHEN  6=> digital <= "1011111";

              WHEN  7=> digital <= "1110000";

              WHEN  8=> digital <= "1111111";

              WHEN  9=> digital <= "1111011";

              END CASE;

              time1 <= t5;

             

              WHEN t5 =>

              cat <= "111110";

              CASE cat0 IS

              WHEN  0=> digital <= "1111110";

              WHEN  1=> digital <= "0110000";

              WHEN  2=> digital <= "1101101";

              WHEN  3=> digital <= "1111001";

              WHEN  4=> digital <= "0110011";

              WHEN  5=> digital <= "1011011";

              WHEN  6=> digital <= "1011111";

              WHEN  7=> digital <= "1110000";

              WHEN  8=> digital <= "1111111";

              WHEN  9=> digital <= "1111011";

              END CASE;

              time1 <= t1;

             

              WHEN OTHERS => time1 <= t1;

            END CASE;

           

            elsif(result<0)then

          CASE time1 IS

             

             

              WHEN t1 =>

              cat <= "101111";

              CASE cat4 IS

              WHEN  0=> digital <= "1111110";

              WHEN  1=> digital <= "0110000";

              WHEN  2=> digital <= "1101101";

              WHEN  3=> digital <= "1111001";

              WHEN  4=> digital <= "0110011";

              WHEN  5=> digital <= "1011011";

              WHEN  6=> digital <= "1011111";

              WHEN  7=> digital <= "1110000";

              WHEN  8=> digital <= "1111111";

              WHEN  9=> digital <= "1111011";

              END CASE;

              time1 <= t2;

     

              WHEN t2 =>

              cat <= "110111";

              CASE cat3 IS

              WHEN  0=> digital <= "1111110";

              WHEN  1=> digital <= "0110000";

              WHEN  2=> digital <= "1101101";

              WHEN  3=> digital <= "1111001";

              WHEN  4=> digital <= "0110011";

              WHEN  5=> digital <= "1011011";

              WHEN  6=> digital <= "1011111";

              WHEN  7=> digital <= "1110000";

              WHEN  8=> digital <= "1111111";

              WHEN  9=> digital <= "1111011";

              end case;

              time1 <= t3;

             

              WHEN t3 =>

              cat <= "111011";

              CASE cat2 IS

              WHEN  0=> digital <= "1111110";

              WHEN  1=> digital <= "0110000";

              WHEN  2=> digital <= "1101101";

              WHEN  3=> digital <= "1111001";

              WHEN  4=> digital <= "0110011";

              WHEN  5=> digital <= "1011011";

              WHEN  6=> digital <= "1011111";

              WHEN  7=> digital <= "1110000";

              WHEN  8=> digital <= "1111111";

              WHEN  9=> digital <= "1111011";

              END CASE;

              time1 <= t4;

             

              WHEN t4 =>

              cat <= "111101";

              CASE cat1 IS

              WHEN  0=> digital <= "1111110";

              WHEN  1=> digital <= "0110000";

              WHEN  2=> digital <= "1101101";

              WHEN  3=> digital <= "1111001";

              WHEN  4=> digital <= "0110011";

              WHEN  5=> digital <= "1011011";

              WHEN  6=> digital <= "1011111";

              WHEN  7=> digital <= "1110000";

              WHEN  8=> digital <= "1111111";

              WHEN  9=> digital <= "1111011";

              END CASE;

              time1 <= t5;

             

              WHEN t5 =>

              cat <= "111110";

              CASE cat0 IS

              WHEN  0=> digital <= "1111110";

              WHEN  1=> digital <= "0110000";

              WHEN  2=> digital <= "1101101";

              WHEN  3=> digital <= "1111001";

              WHEN  4=> digital <= "0110011";

              WHEN  5=> digital <= "1011011";

              WHEN  6=> digital <= "1011111";

              WHEN  7=> digital <= "1110000";

              WHEN  8=> digital <= "1111111";

              WHEN  9=> digital <= "1111011";

              END CASE;

              time1 <= t6;

             

              when t6=>

              cat<="011111";digital<="0000001";

              time1<=t1;

             

             

              WHEN OTHERS => time1 <= t1;

            END CASE;

            end if;

        end if;

            end process;

      end lz;

防抖模块:

LIBRARY IEEE;

USE IEEE.STD_LOGIC_1164.ALL;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

USE IEEE.STD_LOGIC_ARITH.ALL;

ENTITY fangdou IS

PORT(

    clk :   IN STD_LOGIC;

    key_in: IN STD_LOGIC_VECTOR(5 DOWNTO 0);

    key_out:OUT STD_LOGIC_VECTOR(5 DOWNTO 0)   

);

END fangdou;

ARCHITECTURE behave OF fangdou IS

SIGNAL clk_tmp : STD_LOGIC;

SIGNAL cnt : integer range 0 to 199999;

signal tmp1,tmp2: STD_LOGIC_VECTOR(5 DOWNTO 0);

BEGIN

process(clk)

begin

if (clk'event and clk='1') then

    if cnt=199999 then

    cnt<=0;

    clk_tmp<= not clk_tmp;

    else

    cnt<=cnt+1;

    end if;

    end if;

    end process;

   

PROCESS(clk_tmp)

BEGIN

    IF (clk_tmp'EVENT AND clk_tmp='0') THEN                

        tmp2<=tmp1;

        tmp1<=key_in;  

    END If;

   

END PROCESS;

key_out(0)<=clk_tmp and tmp1(0) and (not tmp2(0));

key_out(1)<=clk_tmp and tmp1(1) and (not tmp2(1));

key_out(2)<=clk_tmp and tmp1(2) and (not tmp2(2));

key_out(3)<=clk_tmp and tmp1(3) and (not tmp2(3));

key_out(4)<=clk_tmp and tmp1(4) and (not tmp2(4));

key_out(5)<=clk_tmp and tmp1(5) and (not tmp2(5));

END behave;

译码模块:

library ieee;

USE IEEE.STD_LOGIC_UNSIGNED.ALL;

use ieee.std_logic_1164.all;

entity transform is

port(cin:in std_logic_vector(7 downto 0);

     cout: out integer range 0 to 99

     );

end entity transform;

architecture behave of transform is

signal h1: integer range 0 to 10;

signal l1: integer range 0 to 10;

begin

m1:process(cin)

begin

case cin(7 downto 4) is

when "0000"=>

h1<=0;

when "0001"=>

h1<=1;

when "0010"=>

h1<=2;

when "0011"=>

h1<=3;

when "0100"=>

h1<=4;

when "0101"=>

h1<=5;

when "0110"=>

h1<=6;

when "0111"=>

h1<=7;

when "1000"=>

h1<=8;

when "1001"=>

h1<=9;

when others=>

h1<=10;

end case;

end process m1;

m2:process(cin)

begin

case cin(3 downto 0) is

when "0000"=>

l1<=0;

when "0001"=>

l1<=1;

when "0010"=>

l1<=2;

when "0011"=>

l1<=3;

when "0100"=>

l1<=4;

when "0101"=>

l1<=5;

when "0110"=>

l1<=6;

when "0111"=>

l1<=7;

when "1000"=>

l1<=8;

when "1001"=>

l1<=9;

when others=>

l1<=10;

end case;

end process m2;

cout<=h1*10+l1;

end behave;

五、功能说明:

     实验的基本要求已经实现。即能实现基本的加减乘,不含除法的复合四则运算(从左到右的运算,无运算优先级)。能做到溢出报警。结果有正负的输出。具体例子:

  99×99=9801    而 99×99×99—报警

  12+21×31-40=983   20-51×8=-248

六、元件器件清单及资源利用情况:

    该实验所需:带quarters的计算机一台,数字电路与逻辑设计实验板一个。资源利用情况:所需逻辑单元为81%。

七、故障及问题分析:

1、 下载后,按键没有反应。   检验相应管脚是否设置正确,检查管脚是否失效。

2、 数码管显示乱码。  检查相应的输出译码部分是否正确,相应管脚设置是否正确。

3、蜂鸣器不响,一开始我直接检查代码,检查了好久都没发现错误,后来换了个实验板,重新下载后就好了。

4、仿真结果出不来,可能是由于end time设置得不对,把end time修改。

八、总结及结论:

   当选完试验后,所遇到的第一个问题就是设计思路的问题。刚开始时,对着题目,感觉有些无从下手,毫无头绪。于是找相应的书籍,在网络上查询相关资料。最后终于有了一点点思路。顺着这思路,对相应模块进行了相应设计,在自己认为可以之后,于是开始了相应代码的编写。在编写过程中,有遇到了对vhdl语法有些遗忘的问题,于是,又回过头去复习相应的语法规则。不过即便如此,在编写时还是出现了很多错误。一编译,出现了好多错误,于是一个一个去找,发现自己错得最多的还是if的相关用法。

     这次实验收获最多的还是对于数字电路的设计方式。之前所接触最多的还是理论的上的东西。虽然上个学期也做个数字电路的实验,但那个时候,我们所做的都是较为简单的数字电路的实现。而这个学期,我们所做的这个实验综合性很高。从实验的设计到实验完成,所要经历的东西相对于之前的要多太多。通过这次实验,我深刻意识到,数字电路的设计最困难以及最重要的还是实验的设计,而不是代码的编写。只要设计思路对了,将所需的模块都设计好了,代码的编写相对于设计还是容易得多的。

相关推荐