vhdl是不会运行的!它不同于C、C++等语言,它用于描述一个硬件结构,描述完之后,所生成的硬件就已经成型了,所以这个问题相当于你在问“硬件是怎样运行的?”一样,记住,vhdl是硬件“描述”语言!
拿到一些芯片,上面写着74lvth245a、tms320f2812pgf、74hc08、rtl8201bl、ds1302、ref198等等。这些编码是如何规定的?有什么规律?能否看到这些编码大概知道它是个什么性能的电路?我们在protel里元件库中如何快速找到自己想要的芯片?
你说的这些芯片都是很常用的单片机及其外围芯片,如果你有相关经验很容易知道,比如第一个是个逻辑芯片,74是数字逻辑芯片的一个族,区别于54系列,后面那个lv表示低电压low-vol,可能工作在33v的电压下,第二个是ti出的dsp(数字信号处理器),tms320是ti起的名字,在公司的系列产品中有自己的意义,f表示用的是flash存储,2812是其代码,还有2407,5402等等,后面是封装参数。后面那几个芯片有基本逻辑和时钟芯片等,这里不再赘述,你上网查这些芯片的pdf全有,不过大多是英文的。
回答你后面的问题:这些编码有的是行业里的规定,比如74ls,74hc,54基本的芯片,也有是公司自己起的名字,比如tms320f2812等,要说规律很简单,你有过设计经验,用过一些片子就知道的差不多了,要速成可以去看嵌入式硬件设计的书。
protel里找自己的芯片可不容易,你在搜索器件里找一下就可以了,事实上,用protel的老手,全部是用自己画的器件,以免在具体设计时出现这样或那样的偏差。
别学protel了,学那个altiumDesigner吧,他们公司新出的最新版,容易上手功能强大。
课程设计内容与要求
1,用开关按键表示脉冲,每个脉冲代表100米,10个脉冲1公里,每公里14元,能同步显示里程和费用;
2,低于2公里5元计费,高于2公里总费用=起步费用+(里程-2公里)里程单价+
等候时间等后单价;
3,等候时间大于2分钟,按每分钟13元计费;
4,可以设定起步价和里程单价。
一、设计原理与技术方法:
包括:电路工作原理分析与原理图、元器件选择与参数计算、电路调试方法与结果说明;
软件设计说明书与流程图、软件源程序代码、软件调试方法与运行结果说明。
根据设计要求,系统的输入信号clk,计价开始信号start,等待信号stop,里程脉冲信号fin。系统的输出信号有:总费用数C0—c3,行驶距离k0—k1,等待时间m0—m1等。系统有两个脉冲输入信号clk_750k,fin,其中clk_750k将根据设计要求分频成14hz,15hz和1hz分别作为公里计费和超时计费的脉冲。两个控制输入开关start,stop;控制过程为:start作为计费开始的开关,当start为高电平时,系统开始根据输入的情况计费。当有乘客上车并开始行驶时,fin脉冲到来,进行行驶计费,此时的stop需要置为0;如需停车等待,就把stop变为高电平,
并去除fin输入脉冲,进行等待计费;当乘客下车且不等待时,直接将start置为0,系统停止工作;价格开始归为起步价50元。
整个设计由分频模块,计量模块,计费模块,控制模块和显示模块五个部分组成。
其中计量模块是整个系统实现里程计数和时间计数的重要部分;控制模块是实现不同计费方式的选择部分,根据所设计的使能端选择是根据里程计费还是根据等待时间计费,同时设计通过分频模块产生不同频率的脉冲信号来实现系统的计费。计量模块采用1hz的驱动信号,计费模块采用14hz,13hz的驱动信号;计量模块每计数一次,计量模块就实现14次或者13次计数,即为实现计时的13元/min,计程时的14元/km的收费。组成框图如下所示:
1百进制模块:
实现百米脉冲的驱动信号,元件框图如图3所示:
图3 百进制模块框图
源程序如下:
library ieee;
use ieeestd_logic_1164all;
use ieeestd_logic_unsignedall;
entity baijinzhi is
port(start,clk2: in std_logic; --秒脉冲
a: out std_logic_vector(3 downto 0));
end baijinzhi;
architecture rt1 of baijinzhi is
signal count_1:std_logic_vector(3 downto 0);
begin
a<=count_1;
process(start,clk2)
begin
if(start='0')then
count_1<="0000";
elsif(clk2'event and clk2='1')then
if(count_1="0111")then
count_1<="0000";
else
count_1<=count_1+'1';
end if;
end if;
end process;
end rt1
2计费模块
; 实现里程和等候时间的计费并输出到显示,元件框图4如下:
图4 计费模块框图
源程序如下:
Library IEEE;
use IEEEstd_logic_1164all;
use IEEEstd_logic_arithall;
use IEEEstd_logic_unsignedall;
entity jifei is
port(clk2:in std_logic; --计费驱动信号
start:in std_logic; --计费开始信号
c0,c1,c2,c3:buffer std_logic_vector(3 downto 0));
end jifei;
architecture rt1 of jifei is
begin
process(clk2,start)
begin
if start='0'then c3<="0000";c2<="0000";c1<="0101";c0<="0000"; --起步价5元
elsif clk2'event and clk2='1'then
if c0="1001" then c0<="0000";
if c1="1001" then c1<="0000";
if c2="1001" then c2<="0000";
if c3="1001" then c3<="0000";
else c3<=c3+1;
end if;
else c2<=c2+1;
end if;
else c1<=c1+1;
end if;
else c0<=c0+1;
end if;
end if;
end process;
end rt1;
3公里模块
实现历程的计数和输出计费脉冲,元件框图5如下:
图5 公里模块框图
源程序如下:
library ieee;
use ieeestd_logic_1164all;
use ieeestd_logic_unsignedall;
entity gongli is
port(clk1,start: in std_logic; --百米脉冲
k1,k2,k3,k4: out std_logic_vector(3 downto 0); --里程显示
temp2 : out std_logic);
end gongli;
architecture rt1 of gongli is
signal count_1: std_logic_vector(3 downto 0);
signal count_2: std_logic_vector(3 downto 0);
signal count_3: std_logic_vector(3 downto 0);
signal count_4: std_logic_vector(3 downto 0);
begin
k1<=count_1;
k2<=count_2;
k3<=count_3;
k4<=count_4;
process(start,clk1)
begin
if(start='0')then
count_1<="0000";
count_2<="0000";
count_3<="0000";
count_4<="0000"; ---公里清零
elsif(clk1'event and clk1='1')then
if(count_1="1001")then --公里计数器
count_1<="0000";count_2<=count_2+1;temp2<='1';
if(count_2="1001")then
count_2<="0000";count_3<=count_3+'1';
if(count_3="1001")then
count_3<="0000";count_4<=count_4+'1';
end if;
end if;
else
count_1<=count_1+'1';temp2<='0';
end if;
end if;
end process;
end rt1;
4输出模块
实现所有数据的输出,元件框图6如下:
图6 输出模块框图
源程序如下:
library ieee;
use ieeestd_logic_1164all;
use ieeestd_logic_unsignedall;
entity shuchu is
port(y: in std_logic_vector(3 downto 0);
e: out std_logic_vector(6 downto 0));
end shuchu;
architecture rt1of shuchu is
begin
process
begin
case y is
when"0000"=>e<="0111111";
when"0001"=>e<="0000110";
when"0010"=>e<="1011011";
when"0011"=>e<="1001111";
when"0100"=>e<="1100110";
when"0101"=>e<="1101101";
when"0110"=>e<="1111101";
when"0111"=>e<="0000111";
when"1000"=>e<="1111111";
when"1001"=>e<="1100111";
when others=>e<="0000000";
end case;
end process;
end rt1;
5显示模块
实现所有数据的显示,元件框图7如下:
图7 显示模块框图
源程序如下:
library ieee;
use ieeestd_logic_1164all;
use ieeestd_logic_unsignedall;
entity xianshi is
port(start: in std_logic;
a:in std_logic_vector(3 downto 0); --选择信号
c1,c2,c3,c4,out1,out2,out3,out4:in std_logic_vector(3 downto 0); --里程显示,时间显示输入
y:out std_logic_vector(3 downto 0)); --里程显示,时间显示输出
end xianshi;
architecture rt1 of xianshi is
begin
process
begin
if(start='0')then
y<="0000";
else case a is
when "0000"=> y<=c1 ;
when "0001"=> y<=c2 ;
when "0010"=> y<=c3 ;
when "0011"=> y<=c4 ;
when "0100"=> y<=out1 ;
when "0101"=> y<=out2;
when "0110"=> y<=out3 ;
when "0111"=> y<=out4;
when others =>y<= "0000";
end case;
end if;
end process;
end rt1;
6dian模块
图8 dian模块框图
源程序如下:
library ieee;
use ieeestd_logic_1164all;
use ieeestd_logic_unsignedall;
entity dian is
port(a: in std_logic_vector(3 downto 0);
e: out std_logic);
end dian;
architecture rt1 of dian is
begin
process
begin
case a is
when "0001"=>e<='1';
when "0101"=>e<='1';
when others=>e<='0';
end case;
end process;
end rt1;
三、中各个模块设计分析
系统总体顶层框图如下:
系统总体顶层框图
程序最终功能实现波形仿真
1 分频模块
由于实验箱上没有14hz和13hz的整数倍时钟信号,因此采用频率较大的750khz进行分频,以近似得到14hz,13hz和1hz的时钟频率。通过以上三种不同频率的脉冲信号实行出租车行驶,等待两种情况下的不同计费。模块元件如下:
分频模块框图
源程序如下:
Library IEEE;
use IEEEstd_logic_1164all;
use IEEEstd_logic_arithall;
use IEEEstd_logic_unsignedall;
entity fenpin is
port(clk_750k:in std_logic; --系统时钟
clk_14:buffer std_logic; --14分频
clk_13:buffer std_logic; --13分频
clk_1 : buffer std_logic); --1分频
end fenpin ;
architecture rt1 of fenpin is
signal q_14:integer range 0 to 53570; --定义中间信号量
signal q_13:integer range 0 to 57691;
signal q_1:integer range 0 to 749999;
begin
process(clk_750k)
begin
If(clk_750k' event and clk_750k='1')then
If q_14=53570 then q_14<=0;clk_14<=not clk_14;
else q_14<=q_14+1;
end if; --得14hz频率信号
If q_13=57691 then q_13<=0;clk_13<=not clk_13;
else q_13<=q_13+1;
end if; --得13hz频率信号
If q_1=749999 then q_1<=0;clk_1<=not clk_1;
else q_1<=q_1+1;
end if; --得1hz频率信号
end if;
end process;
end rt1;
2 计量模块
计量模块主要完成计时和计程功能。
计时部分:计算乘客的等待累积时间,当等待时间大于2min时,本模块中en1使能信号变为1;当clk1每来一个上升沿,计时器就自增1,计时器的量程为59min,满量程后自动归零。
计程部分:计算乘客所行驶的公里数,当行驶里程大于2km时,本模块中en0使能信号变为1;当clk每来一个上升沿,计程器就自增1,计程器的量程为99km,满量程后自动归零。
元件框图为:
计量模块框图
计量模块仿真波形为:
源程序如下:
library ieee;
use ieeestd_logic_1164all;
use ieeestd_logic_arithall;
use ieeestd_logic_unsignedall;
entity jiliang is
port(start:in std_logic; --计费开始信号
fin:in std_logic; --里程脉冲信号
stop:in std_logic; --行驶中途等待信号
clk1:in std_logic; --驱动脉冲
en1,en0:buffer std_logic; --计费单价使能信号
k1,k0:buffer std_logic_vector(3 downto 0); --行驶公里计数
m1,m0:buffer std_logic_vector(3 downto 0)); --等待时间计数
end jiliang;
architecture rt2 of jiliang is
signal w:integer range 0 to 59; --计时范围0~59
begin
process(clk1)
begin
if(clk1'event and clk1='1')then
if start='0' then
w<=0;en1<='0';en0<='0';m1<="0000";
m0<="0000";k1<="0000";k0<="0000";
elsif stop='1' then --计时开始信号
if w=59 then
w<=0;
else w<=w+1;
end if;
if m0="1001" then
m0<="0000";
if m1="0101" then
m1<="0000";
else m1<=m1+1;
end if;
else m0<=m0+1;
end if;
if stop='1' then en0<='0';
if m1&m0>"00000001" then en1<='1'; --若等待时间大于2min则en1置1
else en1<='0';
end if;
end if;
elsif fin='1' then --里程计数开始
if k0="1001" then k0<="0000";
if k1="1001" then k1<="0000"; --计程范围0~99
else k1<=k1+1;
end if;
else k0<=k0+1;
end if;
if stop='0' then
en1<='0';
if k1&k0>"00000001" then
en0<='1'; --若行使里程大于2km,则en0置1
else en0<='0';
end if;
end if;
end if;
end if;
end process;
end rt2;
3 控制模块
本模块主要是通过计量模块产生的两个不同的输入使能信号en0,en1,对每个分频模块输出的14hz,13hz的脉冲进行选择输出的过程;本模块实现了双脉冲的二选一;最终目的为了计费模块中对行驶过程中不同的时段进行计价。
模块元件如下:
控制模块框图
控制模块仿真波形为:
源程序如下:
Library IEEE;
use IEEEstd_logic_1164all;
use IEEEstd_logic_arithall;
use IEEEstd_logic_unsignedall;
entity kongzhi is
port(en0,en1:in std_logic; --使能选择信号
clk_in1:in std_logic; --14分频输入信号
clk_in2:in std_logic; --13分频输入信号
clk_out:out std_logic); --输出信号
end kongzhi;
architecture rt3 of kongzhi is
begin
process(en0,en1)
begin
if en0='1' then --实现二选一功能
clk_out<=clk_in1;
elsif en1='1' then
clk_out<=clk_in2;
end if;
end process;
end rt3;
4计费模块
当计费信号start一直处于高电平即计费状态时,本模块根据控制模块选择出的信号从而对不同的单价时段进行计费。即行程在2km内,而且等待累计时间小于2min则为起步价5元;2km外以每公里14元计费,等待累积时间超过2min则按每分钟13元计费。c0,c1,c2,c3分别表示费用的显示。
模块元件为:
计费模块框图
计费模块仿真波形为:
源程序如下:
Library IEEE;
use IEEEstd_logic_1164all;
use IEEEstd_logic_arithall;
use IEEEstd_logic_unsignedall;
entity jifei is
port(clk2:in std_logic; --计费驱动信号
start:in std_logic; --计费开始信号
c0,c1,c2,c3:buffer std_logic_vector(3 downto 0));
end jifei;
architecture rt4 of jifei is
begin
process(clk2,start)
begin
if start='0'then c3<="0000";c2<="0000";c1<="0101";c0<="0000"; --起步价5元
elsif clk2'event and clk2='1'then
if c0="1001" then c0<="0000";
if c1="1001" then c1<="0000";
if c2="1001" then c2<="0000";
if c3="1001" then c3<="0000"; --计价范围0~9999
else c3<=c3+1;
end if;
else c2<=c2+1;
end if;
else c1<=c1+1;
end if;
else c0<=c0+1;
end if;
end if;
end process;
end rt4;
5显示模块
显示模块完成计价,计时和计程数据显示。计费数据送入显示模块进行译码,最后送至以百元,十元,元,角为单位对应的数码管上显示。计时数据送入显示模块进行译码,最后送至以分为单位对应的数码管上显示。计程数据送入显示模块进行译码,最后送至以km为单位的数码管上显示。
模块元件为:
显示模块框图
源程序如下:
library ieee;
use ieeestd_logic_1164all;
use ieeestd_logic_unsignedall; --定义库包
entity xianshi is --定义实体
port(
clk_scan:in std_logic; --扫描时钟信号端口设置
c3,c2,c1,c0:in std_logic_vector(3 downto 0); --总费用输入端口
k0,k1:in std_logic_vector(3 downto 0); --里程输入端口
m0,m1:in std_logic_vector(3 downto 0); --等待时间输入端口
sel:out std_logic_vector(2 downto 0); --控制数码管位选信号的扫描信号输出端口
led:out std_logic_vector(6 downto 0); --数码管的控制端口
led_dp:out std_logic --数码管的小数点输出端口
);
end xianshi;
architecture rt5 of xianshi is
signal duan:std_logic_vector(6 downto 0); --数码显示管中间变量
signal shuju:std_logic_vector(3 downto 0); --选择输入端的中间变量
signal cnt:std_logic_vector(2 downto 0); --控制数码管的中间变量
signal xiaodian:std_logic; --小数点的中间变量
begin
process(clk_scan) --开始进程
begin
if clk_scan'event and clk_scan='1' then
cnt<=cnt+1; --每有一个扫描信号上升沿实现加1扫描
end if;
end process; --结束进程
process(cnt) --开始进程(选择扫描显示数码管)
begin
case cnt is --扫描时给每个数码管赋值
when "000"=>shuju<=c0;
when "001"=>shuju<=c1;
when "010"=>shuju<=c2;
when "011"=>shuju<=c3;
when "100"=>shuju<=k0;
when "101"=>shuju<=k1;
when "110"=>shuju<=m0;
when "111"=>shuju<=m1;
when others=> null;
end case;
if (cnt="001" or cnt="110")
then xiaodian<='1'; --在里程和总费用的个位处显示小数点
else xiaodian<='0';
end if;
end process; --结束进程
process(shuju) --开始进程(译码显示)
begin
case shuju is
when "0000"=>duan<="0111111"; --0
when "0001"=>duan<="0000110"; --1
when "0010"=>duan<="1011011"; --2
when "0011"=>duan<="1001111"; --3
when "0100"=>duan<="1100110"; --4
when "0101"=>duan<="1101101"; --5
when "0110"=>duan<="1111101"; --6
when "0111"=>duan<="0000111"; --7
when "1000"=>duan<="1111111"; --8
when "1001"=>duan<="1101111"; --9
when others=>null;
end case;
end process;
sel<=cnt;
led<=duan;
led_dp<=xiaodian;
end rt5;
二、课程设计工作记录:
包括:设计步骤与时间安排、调试步骤与时间安排、课题完成结果说明
2课题完成结果说明:
此计费器能实现起步价是5元;实现实验要求的1公里计费一次单价,行驶公里大于2km时每公里按14元计费并能显示里程和总共的费用。当行驶了6公里,等待了4分钟时,费用显示为158元。与计算公式总费用=起步费用+(里程-2公里)里程单价+等候时间等后单价;即158=5+(6-2)14+413。实验结果与理论结果完全一致,实验设计成功。
你说的置位就是有一个set输入(q=1),清零应该可以用复位键reset吧(q=0)。
library
ieee;
use
ieeestd_logic_1164all;
entity
sync_rsdff
is
port(d,clk
:
in
std_logic;
set
:
in
std_logic;
reset:
in
std_logic;
q,qb
:
out
std_logic);
end
sync_rsdff;
architecture
rtl_arc
of
sync_rsdff
is
process(clk)
begin
if
(clk'event
and
clk='1')
then
if(set='0'
and
reset='1')
then
q<='1';
qb<='0';
elsif
(set='1'
and
reset='0')
then
q<='0';
qb<='1';
else
q<=d;
qb<=not
d;
end
if;
end
process;
end
rtl_arc;
以上是同步置位/复位的d触发器。
我也在忙我自己的论文啊。
VHDL不允许在一个进程中检测多个信号的边沿,只能检测某一个信号的边沿。if clk'event and clk='1'then if PUSH_IN'EVENT AND PUSH_IN='0' THEN 这种描述方式VHDL不认可。
type array_type is (39 downto 0) of std_logic_vector(15 downto 0);
signal array : array_type;
这是定义40个16bit的数。
如果你的40个数是又是5行8列的,可以这么写
type array_1type is (4 downto 0) of std_logic_vector(15 downto 0);
type array_2type is (7 downto 0) of array_1type;
signal array: array_2type;
IFO 是先入先出存储器的缩写,FIFO 控制器在数字系统中被大量使用,可以作为数据缓存
使用。时钟同步的FIFO 控制器接口如下图所示,主要接口信号定义如下:
RST_N:异步复位信号,当RST_N 为低电平时,FULL 输出‘0’,EMPTY 信号输出‘1’
电平,FIFO 指针指向0,FIFO 被清空;
CLK:时钟信号,输出信号与CLK 信号同步;
DATAIN:数据输入信号,8 位总线;
RD:读有效信号,高电平有效,当RD 位高时,在时钟信号CLK 的上升沿,DATAOUT 输
出一个8 位的有效数据;
WR:写有效信号,当WR 为高电平时,在CLK 的上升沿,从DATAIN 信号向存储器写入
一个8 位的有效数据;
DATAOUT:数据输出信号,8 位总线,在CLK 的上升沿,当RD 为高电平时,从FIFO 中
输出一个8 位的数据;
FULL:存储器写满标志信号,高电平时表示存储器中的数据已经写满;
EMPTY:存储器读空标志信号,高电平时表示存储器中的数据已经被读空了。
要求:用Verilog 写一个8x16 的FIFO,完成先入先出的功能,并且在FIFO读空时输出EMPTY
有效信号,读指针RP 不再移动;FIFO 写满时输出FULL 有效信号,并且即使WR 有效也
不再向存储单元中写入数据(写指针WP 不再移动)。
存储单元使用一个二维数组来建模。注意存储单元的地址在读或者写到最高地址时要能回到
最低值。
写出合适的testbench 来测试所写的Verilog 代码,检验其正确性。
module fifo_mem(data,clk,rstN,wrN,rdN,empty,full);
inout [7:0] data;
input clk,rstN,wrN,rdN;
output empty,full;
reg [4:0] _cntr,rd_cntr;
wire [3:0] add;
ram16X8 ram(data(data),addr(addr),wrN(wrN),oe(wrN));
always @(posedge clk or negedge rstN)
if(!rstN) wr_cntr<=0;
else if (!wrN) wr_cntr<=wr_cntr+1;
always @ (posedge clk or negedge rstN)
if(!rstN) rd_cntr<=0;
else if(!rdN) rd_cntr<=rd_cntr+1;
assign addr=wrNrd_cntr [3:0]: wr_cntr [3:0];
assign empty=(wr_cntr [3:0] == rd_cntr [3:0])&&!(wr_cntr[4]^rd_cntr[4]);
assign full=(wr_cntr [3:0] ==rd_cntr [3:0])&&(wr_cntr[4]^rd_cntr[4]);
endmodule
以上就是关于vhdl 程序是如何运行的全部的内容,包括:vhdl 程序是如何运行的、集成电路芯片的编码是怎样规定的、EDA课程设计,用VHDL编程做出租车计费器等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)