第五章 VHDL设计进阶
1,数据对象有三类,变量,常量,信号
2,常量定义:
constant 常数名:数据类型 :=表达式
constant fat: STD_LOGIC_VECTOR :="1011"
STD_LOGIC_VECTOR标准位矢类型
INTEGER整数类型
常数在程序包,设计实体,具有全局化特征,如果常数在设计实体的某一结构体中,则只能用于此结构体中
3,变量
变量是一个局部量,只能在进程和子程序中使用。变量的赋值,是一中理想化的输入,不存在任何延时行为
定义 variable 变量名 : 数据类型 :=初始化
variable a: integer range 0 to 15;变量a定义为常数,取值范围0——15
variable d: std_logic :='1' 变量d定义为标准逻辑位类型
变量的赋值语句:=‘表达式’
variable x,y : integer range 15 dowmto 0;取值范围为0——15
variable a,b : std_logic_vector( 7 dowmto 0);表示有8位
x:= 11;
y:=2 + x;
a:=b;
a(0 to 5):=b(2 to 7);
4,信号
信号具有记忆和延时 行为
signal 信号名: 数据类型 :=初始化
与变量相比,信号的硬件特征更为明显,它具有全局性特征
信号和实体的端口概念是一致的,对于端口来说只是输出端口不能输入数据,输入端口不能被赋值。信号可看成实体内部的端口。
信号的使用和定义范围是 实体,结构体和程序包。在进程和子程序的顺序语句中不允许定义信号
赋值:
目标信号名 <= 表达式
信号的赋值可以在进程中,也可以在结构体的并行语句中,在进程中信号可以被多次赋值,但是有效的是最后一个,并行语句中信号不允许被多次赋值
signal a,b,c,y,z: integer;
.....
process(a,b,c)
begin
y<=a+b;
z<=c-b;
y<=b;
end process;
5.进程中信号赋值和变量赋值
变量和信号相当于逻辑电路系统中的连线和连线上的信号值;常量相当于恒电平;
信号可以设置传输延迟量,而变量则不能,变量只能作为局部的信息载体,信号可以作为信息传输和界面间的通信。
信号用作为电路中的信号连线,变量用于进程中局部数据存储单元。
使用变量赋值的d触发器
architcture bhv of dff3 is ;结构体
begin
process(clk)
variable qq : std_logic;
begin
if clk'event and clk='1'
then qq: =d1;
end if;
q1<=qq;
end process;
end;
使用信号赋值的d触发器
architctrue bhv of dff3 is
signal qq : std_logic;
begin
process(clk)
begin
if clk'event and clk ='1';
then qq<=d1;
end if;
end process;
q1<=qq;
end;
变量的赋值只能放在进程中,信号中同一语句放在进程内外都可以、
再看下面两个程序:
使用信号赋值:
library ieee;
use ieee.std_logic_1164.all;
entity dff3 is
port( clk,d1: in std_logic;
q1: out std_logic);
end;
architcture bhv of dff3 is
signal a,b : logic;
begin
process(clk)
begin
if clk'event and clk='1'
then
a<=d1;
b<=a;
q1<=b;
end if;
end process;
end;
使用变量赋值:
library ieee;
use ieee.std_logic_1164.all;
entity dff3 is
port(clk,d1 : in std_logic ;
q1: out std_logic);
end;
architecture bhv of dff3 is
begin
process(clk)
variable a,b :std_logic;
begin
if clk'event and clk='1'
then
a:=d1;
b:=a;
q1<=b;
end if ;
end process;
end;
这两个例子,不同: 使用信号的是三个d触发器的连接,使用变量的是仍然一个触发器。
一个进程的赋值特点,所有赋值语句(变量和信号)都必须在一个&延时内完成,即,一个进程的
运行时间固定为一个&延时。执行赋值和完成赋值是两个不同的概念。
6,信号被多次赋值时候,只有最后一个才有效。。。
看一个使用变量的4选1多路选择器。
library ieee;
use ieee.std_logic_1164.all;
entity mux4 is
port( i0,i1,i2,i3,a,b: in std_logic;
q: out std_logic);
end mux4;
architecture body_mux4 of mux4 is
begin
process(i0,i1,i2,i3,a,b)
variable muxval : integer range 7 downto 0;
begin
muxval :=0;
if(a='1') then muxval :=muxval+1; end if;
if(b='1') then muxval :=muxval+2; end if;
case muxval is
when 0 => q<=i0;
when 1 => q<=i1;
when 2 => q<=i2;
when 3 => q<=i3;
when other =>null;
end case;
end process;
end body_mux4;
7,VHDL设计实例及语法内涵
含有同步并行预置功能的8位移位寄存器设计
电路的工作原理: 当clk上升沿到来时,进程被启动,如果这时候预置使能load为高电平,则将输入端口的8位二进制数
并行置入移位寄存器中,作为串行右移输出的初始值,如果预置使能load为低电平,则执行:
reg8(6 downto 0)<= reg8(7 downto 1);
串行移空的最高位始终由最初并行预置数的最高位填补。
library ieee;
use ieee.std_logic1164.all;
entity shft is
port(clk,load:in std_logic;
din : in std_logic_vector(7 downto 0);
dout : out std_logic_vector(7 downto 0);
qb: out std_logic);
end shft;
architecture behav of shft is
signal reg8 : std_logic_vector(7 downto 0);
begin
process(clk,load)
begin
if clk'event and clk='1' then
if load='1' then reg8<=din;
else reg8(6 downto 0)<= reg8(7 downto 1);
end if;
end if;
end process;
qb<=reg8(0);
dout=reg8;
end behav;
8,移位可控的8位移位寄存器设计
library ieee;
use ieee.std_logic_1164.all;
entity shft is
port( clk,co : in std_logic; co是进位输入
md : in std_logic_vector(2 downto 0);
d: in std_logic_vector(7 downto 0);
qb: out std_logic_vector(7 downto 0);
cn: out std_logic); cn是进位输出
end entity;
architecture behav of shft is
signal reg : std_logic_vector(7 downto 0);
signal cy: std_logic;
begin
process(clk,md,co)
begin
if clk'event and clk='1' then
case md is
when "001" => reg(0)<=c0;
reg( 7 downto 1)<= reg(6 downto 0); cy<=reg(7); 带进位循环左移
when "010" => reg(0)<=reg(7); 自循环左移
reg(7 downto 1)<= reg(6 downto 0);
when "011"=> reg(7)<=reg(0); 自循环右移
reg(6 downto 0)<=reg(7 downto 1);
when "100"=> reg(7)<=c0;
reg(6 downto 0)<=reg(7 downto 1);cy<=reg(0); 带进位循环右移
when "101"=>reg(7 downto 0)<= d( 7 downto 0);加载待移数
when others => reg<=reg; cy<=cy;
end case;
end if;
end process;
qb(7 downto 0)<=reg(7 downto 0); cn<=cy; 移位后输出
end behav;
9,JK触发器的设计
library ieee;
use ieee.std_logic_1164.all;
entity jkffl is
port(j,k: in std_logic;
clk: in std_logic;
q,qn: out std_logic);
endtity jkffl ;
architecture bhv of jkffl is
signal q1:std_logic;
begin
process(clk)
begin
if clk'event and clk='1' then
if j='1' and k='0' then q1<='0';
elsif j='0' and k='1' then q1='1';
elsif j='1' and k='1' then q1<=not q1;
else q1<=q1;
end if;
end if;
end process;
q<=q1;
qn<=not q1;
end architecture;
10,4位十进制计数器的设计
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity couter1 is
port(enb: in std_logic;
clr: in std_logic;
clk: in std_logic;
cout: out std_logic;
q: out std_logic_vector(15 downto 0));
end entity couter1;
architecture bhv of couter1 is
signal q1,q2,q3,q4: std_logic_vector(3 downto 0);
begin
process(clk,enb,clr)
begin
if clr='1' then q1<="0000";q2<="0000";q3<="0000";q4<="0000";
elsif clk'event and clk='1' then
if enb='1' then
if q1<"1001" then q1<=q1+1; cout<='0';
elsif q2<"1001" then q1<="0000";q2<=q2+1;
elsif q3<"1001" then q1<="0000";q2<="0000";q3<=q3+1;
elsif q4<"1001" then q1<="0000";q2<="0000";q3<="0000";q4<=q4+1;
else q1<="0000";q2<="0000";q3<="0000";q4<="0000"; cout<='1';
end if;
end if;
end if;
end process;
q<=q4&q3&q2&q1;
11,位矢中‘1’数码个数的统计电路设计
注意:这里是只能使用变量不能使用使用信号
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
entity cntc is
port( din: in std_logic_vector(7 downto 0;
cnth: out std_logic_vector(3 downto 0);
end entity cntc;
architecture bhv of cntc is
begin
process(din)
variable q: std_logic_vector(3 downto 0);
begin
q="0000";
for(n in 0 to 7) loop ;;;;;;;n是loop 的循环变量
if ( din(n)='1') then q:=q+1;
end loop;
cnth<=q;
end process;
end;
这里注意的是loop循环的使用
12,三态门的设计
如果用std_logic数据类型的'z'对一个变量赋值,就会引入一个三态门
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
。。。。。。。。。。。。。。。。。。。。。。。。。。。。。
13,顺序语句归纳
在一个结构体中,允许放置任意多个进程语句结构,而每一个进程的内部是由一系列顺序语句构成的,
在进程中的顺序语句并不意味着硬件的实现也顺序
下面详细了解一下process进程语句
一个结构体中可以包含多个进程process,但是所有被激活的的进程都是并行运行的
process结构由三部分组成:进程说明,顺序描述,敏感参数表