集成电路技术分享

 找回密码
 我要注册

QQ登录

只需一步,快速开始

搜索
查看: 3045|回复: 1

FPGA菜鸟求助,调试程序,VHDL语言编写的出租车计费器,毕设,老师说很简单……

[复制链接]
mydouble 发表于 2010-5-21 17:07:52 | 显示全部楼层 |阅读模式
模块Taxi :
功能:该模块是程序中的重要部分,
输入端口 start,reset,pause分别为汽车启动、复位
暂停、和速度选择。
输入端口start : 当start为高电平1时,表示汽车启动。
输入端口reset: 当reset为高电平1时,表示汽车停止,路程和计费复位,显示全部为0。
输入端口sk: sk为速度选择键‘00’‘01’ ‘10’ ‘11’分别代表一个档位。  
输入端口pause: 当 pause为高电平1时表示汽车暂停,路程和计费显示不变。
当reset=0,start=0,quicken=0,pause=0时,汽车按正常车速行驶。
当reset=0,start=0,quicken=1,pause=0汽车加速行驶。
当reset=0,start=0,quicken=0,pause=1,汽车处于暂停状态。
输出端口cost,journey分别表示出租车的车费和行驶路程。
该模块中信号及变量的说明:
信号a用来表示汽车是否启动,如果已启动。则a=1,否则a=0。
变量charge 和distance分别代表进程中的车费和路程。
程序为:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
Entity Taxi is
  port(clk,start,reset,pause  : in std_logic;
       sk                     : in std_logic_vector(1 downto 0);  
       cost,journey                   : out integer range 8000 to 0);
  End Taxi;
Architecture  behav of Taxi is
signal  a,b  : std_logic;
signal  q    : std_logic_vector(6 downto 0);
Begin
    process(clk,start,reset,pause,sk)
     variable charge,distance : integer range 0 to 8000;
     variable km              : integer range 0 to 100;   
    Begin
      if(clk'event and clk='1') then
         if reset='1' then
             charge:=0;
             distance:=0;
             a<='0';
             b<='0';
          elsif start='1' then
             charge:=500;
             distance:=0;
             a<='1';
             b<='0';
         elsif(start='0'  and pause='0') then
             if a='1' then
                 if q="1111111" then
                      q<="0000000";
                 else
                       q<=q+1;
                 end if;
                                
                   if(sk="00" and q(0)='1')then
                          distance:=distance+1;
                          km:=km+1;
                   end if;
                   if(sk="01" and q(2)='1')then
                          distance:=distance+1;
                          km:=km+1;
                    end if;
                   if(sk="10" and q(4)='1')then
                          distance:=distance+1;
                          km:=km+1;
                     end if;
                   if(sk="11" and q(6)='1')then
                          distance:=distance+1;
                          km:=km+1;
                   end if;              
             end if;
         end if;
         if km=100 then
            b<='1';
            km:=0;
         else
            b<='0';
         end if;  
         if (distance<400 and a='1') then
            charge:=500;
  
         elsif(charge<2000 and b='1') then
            charge:=charge+180;
         elsif (charge>=2000 and b='1' ) then
            charge:=charge+270;
         end if;
       end if;
        cost<=charge;
        journey<=distance;
      end process;
     end behav;

模块shift:
主要功能:该模块把车费和路程转化为四位十进制数。
说明:qclk的频率要比Taxi 中的clk快得多
输入端口 qclk为时钟控制键
输入端口money 和lucheng分别为车费和路程的输入键
输出端口a1,a2,a3,a4,b1,b2,b3,b4分别为车费和路程的个位、
十位、百位、千位。
功能分析:data1,data2位进程中所设置的两个变量,分别表示车费和路程。
在时钟的上升沿变化时,进程中的功能开始执行,当data1=999时,在下一个时钟到来时,他的个位、十位、百位全部变为0,并向千位进1,当data1=99时,在下一个时钟到来后,它的个位、十位全部变为0,并向百位进1,当data1=9时,当时钟到来后,个位变为0,并向十位进1,否则按正常计算即data1在时钟到来后加1,个位、十位、百位、千位分别用四位]二进制来表示,故以上是按正常十进制的计算程序。
data2的计算方法同data1,所以就不再赘述了。
最后,把计算的得到的车费和路程的个位、十位、百位、千位的二进制数分别赋给输出端的个位、十位、百位、千位。
另外,在本模块中用了二进程的程序设计。
程序为:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
Entity  shift is
  port( qclk      : in std_logic;
        money,lucheng : in integer range 8000 to 0;
        a1,a2,a3,a4,b1,b2,b3,b4  : out std_logic_vector(3 downto 0));
End shift;
Architecture behav of shift is
   Begin
     process(qclk,money)
       variable data1 :integer range 0 to 9000;
       variable d1,d2,d3,d4  : std_logic_vector(3 downto 0);
     Begin
       if(qclk'event and qclk='1') then
           if data1<money then
               if(d3=9 and d2=9 and d1=9) then
                  d1:="0000";
                  d2:="0000";   
                  d3:="0000";
                  d4:=d4+1;
                  data1:=data1+1;
               elsif(d2=9 and d1=9) then
                  d1:="0000";
                  d2:="0000";
                  d3:=d3+1;
                  data1:=data1+1;
               elsif(d1=9) then
                  d1:="0000";
                  d2:=d2+1;
                  data1:=data1+1;
               else
                  d1:=d1+1;
                  data1:=data1+1;
               end if;
           else
             a1<=d1;
             a2<=d2;
             a3<=d3;
             a4<=d4;
             data1:=0;
             d1:="0000";
             d2:="0000";
             d3:="0000";
             d4:="0000";     
           end if;
         end if;
       end process;
     process(qclk, lucheng)
       variable  data2  : integer range 0 to 9000;
       variable  y1,y2,y3,y4  : std_logic_vector(3 downto 0);
      Begin
        if(qclk'event and qclk='1') then
            if data2<lucheng then
               if(y1=9 and y2=9 and y3=9) then
                  y1:="0000";
                  y2:="0000";   
                  y3:="0000";
                  y4:=y4+1;
                  data2:=data2+1;
               elsif(y1=9 and y2=9) then
                  y1:="0000";
                  y2:="0000";
                  y3:=y3+1;
                  data2:=data2+1;
               elsif(y1=9) then
                  y1:="0000";
                  y2:=y2+1;
                  data2:=data2+1;
               else
                  y1:=y1+1;
                  data2:=data2+1;
               end if;
           else
             b1<=y1;
             b2<=y2;
             b3<=y3;
             b4<=y4;
             data2:=0;
             y1:="0000";
             y2:="0000";
             y3:="0000";
             y4:="0000";     
           end if;
        end if;
      end process;
    end behav;

Show模块:
主要功能:这是一个八选一的模块,通过此模块把车费和路程
以两位小数的形式输出。
端口说明:输入端口:Cin为地址选择控制端,由一个模八的
模块输入。
输出端口:aa1,aa2,aa3,aa4分别为车费的个位、十位、百位、
千位,bb1,bb2,bb3,bb4分别为路程的个位、十位、百位、千位。
输出端口:Dp为小数点的控制键,一次来把车费和路程以两位
小数的形式输出。 Dout输出选择的数据。
功能分析:进程中,以八选一的形式选择数据,当输出两位数据后,
在第三位数据后加一个小数点,使数据以两位小数的形式输出。
程序为:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
Entity show is
    port( Cin    :  in std_logic_vector(2 downto 0);
          aa1,aa2,aa3,aa4,bb1,bb2,bb3,bb4  : in std_logic_vector(3 downto 0);
          Dp     : out std_logic;
          Dout   : out std_logic_vector(3 downto 0));
End show;
Architecture behav of show is
    signal   sign  : std_logic_vector(2 downto 0);
  Begin
    process(Cin,aa1,aa2,aa3,aa4,bb1,bb2,bb3,bb4)
      begin
         sign<=Cin;
         case sign is
            when"111"=>Dout<=aa1;
                       Dp<='0';
            when"110"=>Dout<=aa2;
                       Dp<='0';
            when"101"=>Dout<=aa3;
                       Dp<='1';
            when"100"=>Dout<=aa4;
                       Dp<='0';
            when"011"=>Dout<=bb1;
                       Dp<='0';
            when"010"=>Dout<=bb2;
                       Dp<='0';   
            when"001"=>Dout<=bb3;
                       Dp<='1';
            when"000"=>Dout<=bb4;
                       Dp<='0';
            when others=>Dout<="0000";
          end case;
       end process;
     end behav;
m8模块     :
主要功能:此模块是一个模八的计数器,作为八选一模块中的地址输入使用。
说明:该模块中的mclk的频率应该特别快,可以和模块shift中的qclk用同一频率。
此模块比较简单,在此就不再详细介绍。
Library ieee;
Use ieee.std_logic_1164.All;
Use ieee.std_logic_unsigned.All;
Entity m8 is
  Port ( mclk      : in std_logic;
      
         qq              : out std_logic_vector(2 downto 0));
End m8;
Architecture behav of m8 is
   signal qo  : std_logic_vector(2 downto 0);
  Begin
    Process(mclk,qo)
      Begin
            
       If(mclk'EVENT And mclk='1') Then
           If qo="111" Then
              qo<="000";  
           Else
              qo<=qo+1;
           End If;
       End If;
          qq<=qo;
     End Process;
  End behav;

DX模块:   
主要功能:该模块是一个七段译码显示器,通过此
模块将选择的数据显示出来,即将车费和路程中
的原来以二进制形式的个位、十为、百位、千位转化为十进制的形式显示。
程序为:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
Entity DX is
   port( Din     : in std_logic_vector(3 downto 0);
         q       : out std_logic_vector(6 downto 0));
End DX;
Architecture behav of DX is
    Begin
     process(Din)
      begin
        case Din is
           when"0000"=>q<="0111111";  
           when"0001"=>q<="0000110";   
           when"0010"=>q<="1011011";   
           when"0011"=>q<="1001111";   
           when"0100"=>q<="1100110";   
           when"0101"=>q<="1101101";   
           when"0110"=>q<="1111101";   
           when"0111"=>q<="0100111";   
           when"1000"=>q<="1111111";   
           when"1001"=>q<="1101111";     
           when others=>q<="0111111";
         end case;
       end process;
end behav;
fpga_feixiang 发表于 2021-8-23 15:01:15 | 显示全部楼层
6666666666666666
您需要登录后才可以回帖 登录 | 我要注册

本版积分规则

关闭

站长推荐上一条 /1 下一条

QQ|小黑屋|手机版|Archiver|集成电路技术分享 ( 京ICP备20003123号-1 )

GMT+8, 2024-5-2 18:16 , Processed in 0.082858 second(s), 24 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表