要求完成的主要任务:
实现计费功能,计费标准为武汉起步3元,1公里后4元,1.5公里后5元,2公里后6元,2.5公里后7元,车行3公里后跳为8元,以后为1.4元/公里,当计费达到20元后,每公里加收50%的车费,车停止每3分钟增加0.7元。
车费动态扫描显示,有一位小数。
目录
摘要 ................................................................................................................ I Abstract.................................................................................. .......................
1 绪论 ..............................................................................................................
2 设计内容及要求 ..........................................................................................
2.1设计的目的及主要任务 ...........................................................................
2.1.1设计的目的 ............................................................................................
2.1.2 设计任务及主要技术指标 ...................................................................
2.2设计思想 ..................................................................................................
3 设计原理及单元模块设计 .......................................................................
3.1 设计原理及方法 ......................................................................................
3.2 单元模块设计 ..........................................................................................
3.2.1分频/计量控制模块 ...............................................................................
3.2.2八进制计数器 ........................................................................................
3.2.3 三八译码器模块 ..................................................................................
3.2.4七段译码器模块 ...................................................................................
3.2.5停车计时模块 .......................................................................................
3.2.7计费模块 ...............................................................................................
4电路的仿真及析...........................................................................................
4.1 单元模块的仿真及分析 ........................................................................
4.1.1八进制计数器仿真 .............................................................................
4.1.2 译码显示模块 ....................................................................................
5 心得体会 ....................................................................................................
参考文献 ........................................................................................................
附录 ...............................................................................................................
摘要
本文介绍了一种采用单片FPGA芯片进行出租车计费器的设计方法,主要阐述如何使用新兴的EDA器件取代传统的电子设计方法,利用FPGA的可编程性,简洁而又多变的设计方法,缩短了研发周期,同时使出租车计费器体积更小功能更强大。本设计实现了出租车计费器所需的一些基本功能,计费包括起步价、行车里程计费、等待时间计费,同时考虑到出租行业的一些特殊性,更注重了把一些新的思路加入到设计中。主要包括采用了FPGA芯片,使用VHDL语言进行编程,使其具有了更强的移植性,更加利于产品升级。
关键词:VHDL;计费器;QuartusⅡ;FPGA
Abstract
This paper describes the use of a single chip FPGA for the design of accounting-fee machine, mainly on how to use the emerging EDA electronic devices designed to replace traditional methods, using the programmable FPGA, concise and changing the design Ways to shorten the development cycle, so that taxi accounting-fee machine in a smaller more powerful. The design and implementation of the taxi accounting-fee machine for some basic functions, including billing starting price, driving metered, the waiting time billing, taking into account the special nature of some of the taxi industry, to pay more attention to a number of new Ideas into the design. Mainly including the use of the FPGAchip, the use of VHDL programming, so as to make it a stronger transplanted, and more conducive to product upgrades.
Key words: VHDL, accounting-fee machine , Quartus Ⅱ, FPGA
1 绪论
人类社会已经进入信息化时代,信息社会的发展离不开电子产品的进步。现代电子产品在性能提高、复杂度降低的同时,价格却一直呈下降趋势,而且产品更新换代的步伐也越来越快,实现这种进步的主要原因就是生产制造技术和电子设计技术的发展。前者以微细加工技术为代表,目前已进展到深亚微米阶段,可以在几平方厘米的芯片上集成数万个晶体管;后者的核心就是EDA技术。没有EDA技术的支持,想要完成超大规模集成电路的设计制造是不可想象的,反过来,生产制造技术的不断进步又必须对EDA技术提出新要求。EDA代表了当今电子设计技术的最新发展方向,它的基本特征是:设计人员按照“自顶向下”的设计方法,对整个系统进行方案设计和功能划分,系统的关键电路用一片或几片专用集成电路(ASIC)实现,然后采用硬件描述语言(VHDL)完成系统行为级设计,最后通过综合器和适配器生成最终的目标器件[1]。
可编程逻辑器件自20世纪70年代以来,经历了PAL、GAL、CPLD、FPGA几个发展阶段,其中CPLD、FPGA属高密度可编程逻辑器件,目前集成度以高达200万门/片,它将掩膜ASIC集成度高的优点和可编程逻辑器件设计生产方便的特点结合在一起,特别适合于样品研制和小批量产品开发,使产品能以最快的速度上市,而当市场扩大时,它可以和容易地转由ASIC实现,因此开发风险也大为降低。CPLD/FPGA器件已成为现代高层次电子设计方法的实现载体。
VHDL[2]是一种全方位的硬件描述语言,包括系统行为级、寄存器传输级和逻辑门级多个设计层次,支持结构、数据流和行为3种描述形式的混合描述,因此VHDL几乎覆盖了以往各种硬件描述语言的功能,整个自顶向下或自底向上的电路设计过程都可以用VHDL来完成。另外,VHDL还有以下优点:VHDL的宽范围描述能力使它成为高层次设计的核心,将设计人员的工作重心转移到了系统功能的实现和调试上,只需要花较少的精力用于物理实现;VHDL可以用简洁明确的代码描述来进行复杂控制逻辑的设计,灵活且方便,而且也便于设计结果的交流、保存和重用;VHDL的设计不依赖于特定的器件,方便了工艺的转换。VHDL是一个标准语言,为众多的EDA场上支持,因此移植性好。
2 设计内容及要求
2.1设计的目的及主要任务
2.1.1设计的目的
(1)学会在QuartusⅡ环境中运用VHDL语言设计方法构建具有一定逻辑功能的模块,
并能运用图形设计方法完成顶层原理图的设计。
(2)掌握出租车自动计费器的主要功能与在FPGA中的实现方法。
2.1.2 设计任务及主要技术指标
(1)实现计费功能,计费标准为武汉起步3元,1公里后4元,1.5公里后5元,2公里后6元,2.5公里后7元,车行3公里后跳为8元,以后为1.4元/公里,当计费达到20元后,每公里加收50%的车费,车停止每3分钟增加0.7元。车费动态扫描显示,有一位小数。
(2)运用QuartusⅡ软件中的仿真功能对所设计的出租车自动计费器的各个模块及顶层电路的功能进行仿真分析。
(3)将所设计的整个系统写入FPGA器件中,加上需要的外围电路在实验箱上实现整个系统的硬件搭建。
2.2设计思想
本次设计首先在QuartusⅡ环境中对出租车自动计费器的各个部分利用VHDL这一硬件描述语言予以设计,生成模块。而整个设计的核心部分就在分频/计量模块,该模块完成的功能主要包括计费脉冲的产生,等待计时、计价、计程功能。随后运用QuartusⅡ中的仿真功能对其予以仿真,从仿真的结果中分析程序的正确性。待所有模块的功能正确之后,运用原理图搭建顶层电路并进行整体仿真直至达到最初的设计要求,最后再在实验箱上检验设计的正确与否。
3 设计原理及单元模块设计
3.1 设计原理及方法
根据层次化设计理论,该设计问题自顶向下[4]可分为分频模块、控制模块、计量模块、译码动态扫描显示模块,其系统框图如图所示。
图3-1 出租车自动计费器系统框图
如上图所示:由于缺乏条件,所以在设计中只能模拟出出租车计费其的功能,根据设计要求,可以在设计中控制信号来模拟路程计数的动态变化、计时整三分钟时刻的到来,车处于行驶状态还是停止状态的判断信号。当这些信号做出某些动作时,则可以触发计费的变化或路程的变化或计停止时间的变化。这些变化可以通过译码,宣示电路宣示在数码管上。
3.2 单元模块设计
3.2.1分频/计量控制模块
由于课程设计中需要用到较多的时钟信号,故分频器可调式设计方式。即分频技术的次数采用变量的形式,在用到某一频率的信号时,可调用该分频器模块,再输入与此信号频率的计数总次数即可。以下为分频器的模块原理框图
3.2.2八进制计数器
设计中用到八进制计数器的八个计数状态,来分别选中数码管要宣示的数据和相应的数码管。一下为八进制模块原理框图图
图3-2-2
3.2.3 三八译码器模块
设计中由于需要用到八位气段数码管做宣示,其控制需要用到八个状态选中一位数码管,并把相应的数据送到数码管。若这八个状态快速轮流的变化,
则可以将相应的数据静
态的宣示在数码管上。当扫描的速度远快与数据变化的速度,则可观察到数码管上数据的变化。一下为三八译码器模块原理图
图3-2-3
3.2.4七段译码器模块
通常在计数的过程中,我们都采用十进制计数,而计时间时还要用到六进制,而这些书只要用到四位二进制数就能都表示出来。当数码管宣示时,我们需要控制它的七个宣示段或者八个宣示段,故需要七位二进制数或八位二进制时来控制,故需要利用七段译码器将四位二进制的数据信息转化为七位或八位的控制信息。一下为七段译码器的模块原理框图
图
3-2-4
3.2.5停车计时模块
设计指标中要求,当出租车停止时,每满三分钟,计费器所及费用要加上0.7元,我们可以这样做,当计时满三分钟时,计数器发出一个相当于进位信号的触发信号取通知计费器控制器去计费参数去进行修正,当然出租车行驶时则计时器计时功能被屏蔽掉,这可以通过关掉计时器计时的时钟源来实现。时间要宣示出去,可以通过计数器来分别选中每一位数据并送到数码管上。一下为计时块 的原理框图
图3-3-5
3.2.6行驶记路程模块
只要出租车处于行驶中,记路程的模块就会工作,此时记录路程的数据就会随着行驶的过程慢慢的更新,进而通过对这些数据的判别,取控制计费数据的更新变化。在设计中,我是这样实现的,当计路程的脉冲到来时,路程数据就自加一,并判断是否越界,即超过了九。当超过了九,则低位数据归零,高位数据自加一,然后再逐次对路程数据的高位进行判断,其中以上脉冲是模拟0.1公里二设置的。当计脉冲记到个时,则需要修正计费数据的记录。我们在此设置一个触发脉冲取通知计费模块要修正数据了。然后计费器模块就会跟根据触发信号的来源判断,它要根据哪些数据进行变化。下图为路程计量原理框图
图3-2-6
3.2.7计费模块
计费也是本次设计的关键,因为它对计费数据的修正要根据各种判断,比如要求数据修正的触发脉冲来自于何处,到底是时间的变化要求自己修改数据,还是路程的变化。知道了是时间的变化,则还要判断当前行驶路程是否大于二十公里,然后根据相应的规则进行数据的修正。若是路程的变化,则就相当的麻烦了,首先要判断当前行驶公里是否大于二十公里,若小于二十公里,则还要判断当前行驶公里数处于何数据段,然后分支去处理。另外,还要根据各种外部信号
来处理当前的计费数据,如外部的清零信号,停止信号等信号做出相对应的处理。 下图为计费控制模块原理框图
图
3-2-7
4电路的仿真及分析
在VHDL设计流程中,设计的验证是一个重要但费时的环节。由于验证方法手段不断改进和提高,对于一个系统的设计,提倡用软件、硬件协同验证方法,加速仿真过程。有经验的设计师认为,一个设计项目的成功与否,关键是仿真,其中涉及工作的90%时间花在仿真验证上。仿真有功能仿真[5]与时序仿真之分。在逻辑综合和布线之前对VHDL模型的逻辑功能进行仿真,可以有效提高效率。以下是对本次设计的各个模块以及顶层电路进行的功能仿真及分析。
4.1 单元模块的仿真及分析
4.1.1八进制计数器仿真
图4-1-1
图4-4-1为八进制计数器的功能仿真图,其中clk为时钟脉冲输入端,Q为计数控制信号输出端,可以看出,当时钟沿上升时刻到来时,计数起的输出Q就自加一,也就是Q表示的三位二进制加一。当计数器输出端加到七时,再来一个脉冲上升沿,则计数的输出端归零,必要的时候,还可以设置一输出端,用来表示进位信号,表示当前计数器已经计满了八个数,用以提示下一级,使其作出相应的行为。本设计中并没有加入这一功能,因为本设计八进制计数器的功能主要是利用其计数的八个状态,
进而去轮流控制数码管的
位选信号和数码管的段选属兔信息。
4.1.2 译码显示模块
图4-1-2
上图为三线-八线译码器的功能仿真图,其中前三个端口为信号输入端,也就上一图所示的八进制计数器的输出端。而后八个端口即为八位二进制信号的输出端。由上图可以看出:
当Datain(2 downto 0)=”000”,则Dataouta(7 downto 0)=”01111111”
当Datain(2 downto 0)=”001”,则Dataouta(7 downto 0)=” 10111111”
当Datain(2 downto 0)=”010”,则Dataouta(7 downto 0)=”11011111”
当Datain(2 downto 0)=”011”,则Dataouta(7 downto 0)=”11101111”
当Datain(2 downto 0)=”100”,则Dataouta(7 downto 0)=”1111011”
当Datain(2 downto 0)=”101”,则Dataouta(7 downto0)=”11111011”
当Datain(2 downto 0)=”110”,则Dataouta(7 downto 0)=”11111101”
当Datain(2 downto 0)=”111”,则Dataouta(7 downto 0)=”11111110”
5 心得体会
本次课程设计,我自己感觉收获很大。我利用硬件描述语言设计设计出了出租车计费器,并基本实现了出租车计费的功能。整个设计过程使我对数字电路这门课程有了更深的了解,因为课程设计本身要求将以前所学的理论知识运用到实际的电路设计当中去,在电路的设计过程中,无形中便加深了对数字电路的了解及运用能力,对课本以及以前学过的知识有了一个更好的总结与理解;以前的数字实验只是针对某一个小的功能设计,而此次得EDA课程设计对我们的总体电路的设计的要求更严格,需要通过翻阅复习以前学过的知识确立了实验总体设计方案,然后逐步细化进行各模块的设计;当然,在课程设计中也遇到了很多的问题,以前我一直时一个模块设计到底的忠实信徒,因为我觉得那样可以减少程序的行数,毕竟可以省掉原件例化的部分。当这次我却遭遇难以解决的困难。在初次设计中我用一个模块谢了整个的系统,后来编译出了错,这让我着实犯困,排出错后,又重新构架,它使我对电路故障的排查有了很大的提高;再次,通过此次课程设计,我对设计所用到的软件有了更加深刻地了解,这对我们以后的工作和学习的帮助都很有用处。
参考文献
[1]潘松,黄继业.EDA技术与VHDL.北京:清华大学出版社,2007.1.
[2]宋嘉玉,孙丽霞.EDA实用技术.北京:人民邮电出版社,2006.12.
[3]齐洪喜,陆颖.VHDL电路设计实用技术.北京:清华大学出版社,2004.5.
[4]刘艳萍,高振斌,李志军.EDA实用技术及应用.北京:国防工业出版社,2006.1.
[5]章彬宏.EDA应用技术.北京:北京理工大学出版社,2007.7.
附录
--3进制计数器源程序
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY cnt3 IS
PORT (clk,rst:IN STD_LOGIC;
q :out STD_LOGIC);
END ENTITY;
ARCHITECTURE bhv OF cnt3 IS
BEGIN
PROCESS(clk)
VARIABLE cnter :STD_LOGIC_VECTOR (1 DOWNTO 0); BEGIN
IF (rst='1') THEN
cnter:="00";
q<='0'; ELSE
IF rising_edge(clk) THEN
if cnter="10" then cnter :="00";q<='1';
else cnter:=cnter+1;q<='0';
END IF;
END IF;
END IF;
END PROCESS;
END bhv;
--8进制计数器
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY cnt8 IS
PORT (clk :IN STD_LOGIC;
q :out STD_LOGIC_VECTOR(2 DOWNTO 0)); END ENTITY;
ARCHITECTURE bhv OF cnt8 IS
BEGIN
PROCESS(clk)
VARIABLE cnter :STD_LOGIC_VECTOR (2 DOWNTO 0);
BEGIN
IF rising_edge(clk) THEN
if cnter="111" then cnter :="000";
else cnter:=cnter+1;
END IF;
end if;
q<=cnter;
END PROCESS;
END bhv;
--10进制计数器
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY cnt10 IS
PORT(clk,rst:IN STD_LOGIC;
co :OUT STD_LOGIC;
q :buffer STD_LOGIC_VECTOR(3 DOWNTO 0)); END ENTITY;
ARCHITECTURE bhv OF cnt10 IS
SIGNAL cnter :STD_LOGIC_VECTOR (3 DOWNTO 0); BEGIN
PROCESS(clk,rst)
BEGIN
IF (rst='1') THEN
cnter<="0000";
co<='0'; ELSE
IF rising_edge(clk) THEN
IF cnter="1001" THEN cnter <="0000";co<='1';
ELSE cnter<=cnter+1;co<='0';
END IF;
END IF;
END IF;
q<=cnter;
END PROCESS;
END bhv;
--加法器但要判断是否溢出
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY cnt10_7 IS
PORT(clk,rst:IN STD_LOGIC;
co :BUFFER STD_LOGIC;
q :OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); END ENTITY;
ARCHITECTURE bhv OF cnt10_7 IS
SIGNAL cnter :STD_LOGIC_VECTOR (3 DOWNTO 0); BEGIN
PROCESS(clk,rst)
BEGIN
IF (rst='1') THEN
cnter<="0000";
co<='0'; ELSE
IF rising_edge(clk) THEN
IF cnter="1001" THEN cnter <="0000";
ELSIF cnter>2 THEN cnter<=cnter+13;co<='1';
ELSE cnter<=cnter+7;co<='0';
END IF;
END IF;
END IF;
q<=cnter;
END PROCESS;
END bhv;
--清零为三的十进制计数器
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY cnt10_d IS
PORT(clk,rst:IN STD_LOGIC;
co :OUT STD_LOGIC;
q :OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); END ENTITY;
ARCHITECTURE bhv OF cnt10_d IS
SIGNAL cnter :STD_LOGIC_VECTOR (3 DOWNTO 0); BEGIN
PROCESS(clk,rst)
BEGIN
IF (rst='1') THEN
cnter<="0011";
co<='0';
ELSE
IF rising_edge(clk) THEN
IF cnter="1001" THEN cnter <="0000";co<='1';
ELSE cnter<=cnter+1;co<='0';
END IF;
END IF;
END IF;
q<=cnter;
END PROCESS;
END bhv
--24进制计数器
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY cnt24 IS PORT (clk,rst :IN STD_LOGIC;
c1,c0 :BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0)); END ENTITY;
ARCHITECTURE bhv OF cnt24 IS
BEGIN
PROCESS(clk,rst)
VARIABLE cnter :INTEGER:=0 ;
BEGIN
IF (rst='1') THEN
c1<="0000";
c0<="0000";
ELSE
IF rising_edge(clk) THEN
IF (c0="1001" OR (c0="0011" AND c1="0010"))
THEN
c0<="0000";
IF c1="0010"
THEN
c1<="0000";
ELSE
c1<=c1+1;
END IF;
ELSE
c0<=c0+1;
END IF;
END IF;
END IF;
END PROCESS;
END bhv;
--60进制计数器
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY cnt60 IS PORT (clk,rst :IN STD_LOGIC;
co :OUT STD_LOGIC;
c1,c0 :BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0)); END ENTITY;
ARCHITECTURE bhv OF cnt60 IS
BEGIN
PROCESS(clk,rst)
VARIABLE cnter :INTEGER:=0 ;
BEGIN
IF (rst='1')
THEN
c1<="0000";
c0<="0000";
co<='0';
ELSE
IF rising_edge(clk) THEN
IF (c0="1001")
THEN
c0<="0000";
IF c1="0101"
THEN
c1<="0000";
co<='1';
ELSE
c1<=c1+1;
co<='0';
END IF;
ELSE
c0<=c0+1;
END IF;
END IF;
END IF;
END PROCESS;
END bhv;
--七段译码器
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL ;
USE IEEE.STD_LOGIC_UNSIGNED.ALL ;
ENTITY decl7s IS
PORT( data :IN STD_LOGIC_VECTOR(3 DOWNTO 0); led7s :OUT STD_LOGIC_VECTOR(6 DOWNTO 0)); END;
ARCHITECTURE one OF decl7s IS
BEGIN
PROCESS(data)
BEGIN
CASE data IS
WHEN "0000" => led7s <="1000000" ;
WHEN "0001" => led7s <="1111001" ;
WHEN "0010" => led7s <="0100100" ;
WHEN "0011" => led7s <="0110000" ; WHEN "0100" => led7s <="0011001" ; WHEN "0101" => led7s <="0010010" ;
WHEN "0110" => led7s <="0000010" ;
WHEN "0111" => led7s <="1111000" ;
WHEN "1000" => led7s <="0000000" ;
WHEN "1001" => led7s <="0010000" ; WHEN "1010" => led7s <="1110111" ;
WHEN "1011" => led7s <="1111100" ;
WHEN "1100" => led7s <="0111001" ;
WHEN "1101" => led7s <="1011110" ;
WHEN "1110" => led7s <="0000000" ;
WHEN "1111" => led7s <="0111111" ;
WHEN OTHERS => NULL;
END CASE;
END PROCESS;
END one;
--分频器
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY fp IS
GENERIC (N:integer); PORT ( clk :IN STD_LOGIC;
fpq :BUFFER STD_LOGIC);
END ENTITY;
ARCHITECTURE bhv OF fp IS
BEGIN
PROCESS(clk)
VARIABLE cnter :INTEGER:=0;
BEGIN
IF rising_edge(clk) THEN
IF cnter=N-1 then cnter :=0;fpq<=not fpq;
else cnter:=cnter+1;
END IF;
END IF;
END PROCESS;
END bhv;
--记路程模块源程序
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
ENTITY MIL IS
PORT( clk,rst,stop,D :IN STD_LOGIC;
wx :IN STD_LOGIC_VECTOR(2 DOWNTO 0); p_mil :OUT STD_LOGIC;
datain :OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); END ENTITY MIL;
ARCHITECTURE one OF MIL IS
COMPONENT fp IS GENERIC (N :integer);
PORT (clk:IN STD_LOGIC;
fpq :out STD_LOGIC);
END COMPONENT;
COMPONENT cnt10 IS PORT(clk,rst:IN STD_LOGIC;
co :OUT STD_LOGIC;
q :OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); END COMPONENT;
SIGNAL clk_mil,rst_s,clk_s,cp :STD_LOGIC;
SIGNAL ci_0,ci_1,ci_2,ci_3 :STD_LOGIC;
SIGNAL p_5 :STD_LOGIC_VECTOR(2 DOWNTO 0);
SIGNAL mil3,mil2,mil1,mil0 :STD_LOGIC_VECTOR(3 DOWNTO 0); BEGIN
u0 :cnt10 PORT MAP(clk_s,rst_s,ci_0,mil0);
u1 :cnt10 PORT MAP(ci_0,rst_s,ci_1,mil1);
u2 :cnt10 PORT MAP(ci_1,rst_s,ci_2,mil2);
u3 :cnt10 PORT MAP(ci_2,rst_s,ci_3,mil3);
clk_s<=cp and (NOT stop);
rst_s<=rst;
PROCESS(cp,rst_s)
BEGIN
IF (rst_s='1') THEN
p_5<="000";
p_mil<='0';
ELSE
IF rising_edge(cp) and stop='0' THEN IF p_5="100"
then p_5 <="000"; p_mil<='1';
else p_5 <=p_5+1; P_mil<='0';
END IF;
END IF;
END IF;
END PROCESS;
PROCESS(wx) BEGIN
CASE wx IS
WHEN "000" => datain <= mil0;
WHEN "001" => datain <= mil1;
WHEN "010" => datain <= mil2;
WHEN "011" => datain <= mil3;
WHEN OTHERS =>datain <="1110" ; END CASE;
END PROCESS;
pro3:process(clk,D)
variable JSQ:integer:=0;
begin
if rising_edge(clk) then
if D='0' then
if JSQ=3 then
JSQ:=JSQ;
Else
JSQ:=JSQ+1;
end if;
if JSQ=1 then
cp<='1';
else
cp<='0';
end if;
else
JSQ:=0;
end if;
end if;
end process;
END ARCHITECTURE;
--计时模块源程序
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
ENTITY TIM IS
PORT( clk_time,rst,stop :IN STD_LOGIC;
wx :IN STD_LOGIC_VECTOR(2 DOWNTO 0);
p_up :OUT STD_LOGIC;
datain :OUT STD_LOGIC_VECTOR(3 DOWNTO 0));
END ENTITY TIM;
ARCHITECTURE one OF TIM IS
COMPONENT cnt3 IS
PORT (clk :IN STD_LOGIC;
q :out STD_LOGIC);
END COMPONENT;
COMPONENT cnt8 IS
PORT (clk :IN STD_LOGIC;
q :OUT STD_LOGIC_VECTOR(2 DOWNTO 0));
END COMPONENT;
COMPONENT cnt24 IS
PORT (clk,rst :IN STD_LOGIC;
c1,c0 :BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0));
END COMPONENT;
COMPONENT cnt60 IS
PORT (clk,rst :IN STD_LOGIC;
co :OUT STD_LOGIC;
c1,c0 :BUFFER STD_LOGIC_VECTOR(3 DOWNTO 0));
END COMPONENT;
SIGNAL clk,clk_hur,clk_min,co_sec,co_min :STD_LOGIC;
SIGNAL sig_rst:STD_LOGIC;
SIGNAL wx_signal :STD_LOGIC_VECTOR(2 DOWNTO 0);
SIGNAL clock_hur1,clock_min1,clock_sec1,clock_hur0,clock_min0,clock_sec0 :STD_LOGIC_VECTOR(3 DOWNTO 0);
BEGIN
u_hur :cnt24 PORT MAP(clk_hur,sig_rst,clock_hur1,clock_hur0);
u_min :cnt60 PORT MAP(clk_min,sig_rst,co_min,clock_min1,clock_min0);
u_sec :cnt60 PORT MAP(clk,sig_rst,co_sec,clock_sec1,clock_sec0);
u3 :cnt3 PORT MAP(clk_min,p_up);
clk<=clk_time AND stop;
clk_min<=co_sec;
clk_hur<=co_min;
sig_rst<=rst;
wx_signal<=wx;
PROCESS(wx_signal) BEGIN
CASE wx_signal IS
WHEN "000" => datain <= clock_sec0;
WHEN "001" => datain <= clock_sec1;
WHEN "010" => datain <= "1111";
WHEN "011" => datain <= clock_min0;
WHEN "100" => datain <= clock_min1;
WHEN "101" => datain <= "1111";
WHEN "110" => datain <= clock_hur0;
WHEN "111" => datain <= clock_hur1;
WHEN OTHERS => NULL;
END CASE;
END PROCESS;
END ARCHITECTURE;
--频率发生器
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
ENTITY TAXI_FP IS
PORT( clk :IN STD_LOGIC;
clk_time,clk_mil,
clk_scan,clk_v :OUT STD_LOGIC);
END ENTITY TAXI_FP;
ARCHITECTURE one OF TAXI_FP IS
COMPONENT fp IS GENERIC (N :integer);
PORT (clk:IN STD_LOGIC;
fpq :out STD_LOGIC);
END COMPONENT;
SIGNAL clk_time1,clk_mil1:STD_LOGIC;
BEGIN
c1 :fp GENERIC MAP(N=>10000000) PORT MAP(clk,clk_time1); c2 :fp GENERIC MAP(N=>100000000) PORT MAP(clk,clk_mil1); c3 :fp GENERIC MAP(N=>20000) PORT MAP(clk,clk_scan); c4 :fp GENERIC MAP(N=>500000000) PORT MAP(clk,clk_v); clk_time<=clk_time1;
clk_mil <=clk_mil1;
END ARCHITECTURE;
-- 当前计费的大小判断
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY price_s IS
GENERIC (M:integer); PORT ( clk,rst :IN STD_LOGIC;
fpq:BUFFER STD_LOGIC);
END ENTITY;
ARCHITECTURE bhv OF price_s IS
signal cnter:INTEGER:=0;
BEGIN
PROCESS(clk)
BEGIN
IF rising_edge(clk) THEN
IF rst='1' THEN
IF cnter<(2*M) then
fpq<=not fpq;cnter<=cnter+1;
end if;
ELSE cnter<=0;fpq<='0';
END IF;
END IF;
END PROCESS;
END bhv;
--计费模块源程序
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
ENTITY PRICE IS
PORT( clk_sys,p_t,p_mil,rst,switch,stop :IN STD_LOGIC;
wx :IN STD_LOGIC_VECTOR(2 DOWNTO 0); datain :OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); END ENTITY PRICE;
ARCHITECTURE one OF PRICE IS
COMPONENT fp IS GENERIC (N :integer);
PORT (clk:IN STD_LOGIC;
fpq :out STD_LOGIC);
END COMPONENT;
COMPONENT price_s IS GENERIC (M:integer); PORT ( clk,rst :IN STD_LOGIC;
fpq :BUFFER STD_LOGIC);
END COMPONENT;
COMPONENT cnt10 IS
PORT(clk,rst:IN STD_LOGIC;
co :OUT STD_LOGIC;
q :buffer STD_LOGIC_VECTOR(3 DOWNTO 0));
END COMPONENT;
COMPONENT cnt10_d IS
PORT(clk,rst:IN STD_LOGIC;
co :OUT STD_LOGIC;
q :buffer STD_LOGIC_VECTOR(3 DOWNTO 0));
END COMPONENT;
SIGNAL clk_p,clk_d,ci_0,ci_1,ci_2,ci_3,ci_4 :STD_LOGIC;
SIGNAL s_m0,s_m1,s_m2,s_m3,s_m4,s_t0,s_t1:STD_LOGIC;
SIGNAL c_mil:STD_LOGIC_VECTOR(2 DOWNTO 0);
SIGNAL price3,price2,price1,price0:STD_LOGIC_VECTOR(3 DOWNTO 0); BEGIN
uz :cnt10 PORT MAP(clk_p,rst,ci_0);
u0 :cnt10 PORT MAP(ci_0,rst,ci_1,price0);
u1 :cnt10_d PORT MAP(ci_1,rst,ci_2,price1);
u2 :cnt10 PORT MAP(ci_2,rst,ci_3,price2);
u3 :cnt10 PORT MAP(ci_3,rst,ci_4,price3);
sm0 :price_s GENERIC MAP(M=>300) PORT MAP(clk_sys,p_mil,s_m0); sm1 :price_s GENERIC MAP(M=>100) PORT MAP(clk_sys,p_mil,s_m1); sm2 :price_s GENERIC MAP(M=>70) PORT MAP(clk_sys,p_mil,s_m2); sm3 :price_s GENERIC MAP(M=>135) PORT MAP(clk_sys,p_mil,s_m3); sm4 :price_s GENERIC MAP(M=>150) PORT MAP(clk_sys,p_mil,s_m4); st0 :price_s GENERIC MAP(M=>70) PORT MAP(clk_sys,p_t,s_t0); st1 :price_s GENERIC MAP(M=>135) PORT MAP(clk_sys,p_t,s_t1); clk_d<=clk_p;
PROCESS(clk_sys,rst,stop)
BEGIN
if(rising_edge(clk_sys)) then
if (stop='1') then
if(price2<2) then clk_p<=s_t0;
else clk_p<=s_t1;
end if;
else if(price2<2) then
case c_mil IS
when "000" => clk_p <=s_m0;
when "001" => clk_p <='0';
when "010" => clk_p <=s_m1;
when "011" => clk_p <=s_m1;
when "100" => clk_p <=s_m1;
when "101" => clk_p <=s_m1;
when "110" => clk_p <=s_m1;
when "111" => clk_p <=s_m2;
when others=> null;
end case;
else
case c_mil IS
when "000" => clk_p <=s_m0;
when "001" => clk_p <='0';
when "010" => clk_p <=s_m4;
when "011" => clk_p <=s_m4;
when "100" => clk_p <=s_m4;
when "101" => clk_p <=s_m4;
when "110" => clk_p <=s_m4;
when "111" => clk_p <=s_m3;
when others=> null;
end case;
end if;
end if;
end if;
END PROCESS;
PROCESS(p_mil,rst)
BEGIN
IF (rst='1') THEN c_mil<="000";
ELSIF(rising_edge(p_mil)) and (not(c_mil="111")) THEN c_mil<=c_mil+1; END IF;
END PROCESS;
PROCESS(wx)
BEGIN
CASE wx IS
WHEN "100" => datain <= price0;
WHEN "101" => datain <= price1;
WHEN "110" => datain <= price2;
WHEN "111" => datain <= price3;
WHEN OTHERS =>datain <="1110" ;
END CASE;
END PROCESS;
END ARCHITECTURE;
--顶层模块源程序
LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
USE IEEE.STD_LOGIC_ARITH.ALL;
第28/32页
ENTITY TAXI IS
PORT( clk,rst,stop,d :IN STD_LOGIC;
point :OUT STD_LOGIC;
segout :OUT STD_LOGIC_VECTOR(6 DOWNTO 0);
weisel :out std_logic_vector(7 downto 0));
END ENTITY TAXI;
ARCHITECTURE one OF TAXI IS
COMPONENT TAXI_FP IS PORT( clk :IN STD_LOGIC;
clk_time,clk_mil,
clk_scan,clk_v :OUT STD_LOGIC);
END COMPONENT;
COMPONENT MIL IS
PORT( clk,rst,stop,D :IN STD_LOGIC;
wx :IN STD_LOGIC_VECTOR(2 DOWNTO 0);
p_mil :OUT STD_LOGIC;
datain :OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); END COMPONENT
COMPONENT PRICE IS
PORT(clk_sys,p_t,p_mil :IN STD_LOGIC;
rst,stop:IN STD_LOGIC;
wx :IN STD_LOGIC_VECTOR(2 DOWNTO 0); datain :OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); END COMPONENT;
COMPONENT TIM IS
PORT( clk_time,rst,stop :IN STD_LOGIC;
wx :IN STD_LOGIC_VECTOR(2 DOWNTO 0);
p_up :OUT STD_LOGIC;
datain :OUT STD_LOGIC_VECTOR(3 DOWNTO 0)); END COMPONENT;
COMPONENT decl7s IS PORT(data :IN STD_LOGIC_VECTOR(3 DOWNTO 0);
led7s:OUT STD_LOGIC_VECTOR(6 DOWNTO 0));
END COMPONENT;
COMPONENT cnt8 IS
PORT (clk :IN STD_LOGIC;
q :OUT STD_LOGIC_VECTOR(2 DOWNTO 0));
END COMPONENT;
SIGNAL clk_time,clk_mil,
clk_scan,clk_v :STD_LOGIC;
SIGNAL p_mil,p_t,rst_s :STD_LOGIC;
SIGNAL datain,datain_mil,datain_time,
datain_price :STD_LOGIC_VECTOR(3 DOWNTO 0);
第29/32页
SIGNAL wx_signal :STD_LOGIC_VECTOR(2 DOWNTO 0); SIGNAL state_value :STD_LOGIC;
BEGIN
u1 :TAXI_FP PORT MAP(clk,clk_time,clk_mil,clk_scan,clk_v);
u2 :MIL PORT MAP(clk_mil,rst_s,stop,d,wx_signal,p_mil,datain_mil); u3 :PRICE PORT MAP(clk,p_t,p_mil,rst_s,stop,wx_signal,datain_price); u4 :TIM PORT MAP(clk_time,rst_s,stop,wx_signal,p_t,datain_time); u5 :decl7s PORT MAP(datain,segout);
u6 :cnt8 PORT MAP(clk_scan,wx_signal);
rst_s<= rst;
PROCESS(rst,clk,wx_signal)
BEGIN
IF rst='1' THEN
point <='1';
if wx_signal>3 then
datain<=datain_price;
else
datain<=datain_mil;
end if;
ELSIF rising_edge(clk) THEN
CASE stop IS
WHEN '0'=>
IF wx_signal>3 THEN
datain<=datain_price;
ELSE datain<=datain_mil;
END IF;
IF wx_signal="101" OR wx_signal="001" THEN
point<='0';
ELSE point<='1';
END IF;
WHEN '1'=>
datain<=datain_time;
point<='1';
END CASE;
END IF;
END PROCESS;
ABC:PROCESS(wx_signal)
begin
case wx_signal is
when "000"=>weisel<="00000001";
when "001"=>weisel<="00000010";
when "010"=>weisel<="00000100";
when "011"=>weisel<="00001000";
when "100"=>weisel<="00010000";
when "101"=>weisel<="00100000";
when "110"=>weisel<="01000000";
when "111"=>weisel<="10000000";
when others=>null;
end case;
end process;
END ARCHITECTURE;