第8章 属性(attribute)与配置(configuration)


2023年12月16日发(作者:伦纳德绝杀快船)

第8章 属性(Attribute)与配置(Configuration)

在VHDL中有一些事先定义好的属性,这些属性的使用有的是程序中必要的,有的会增强程序的可读性,有的会使程序的设计更为方便,在此我们会将属性分门别类地进行说明。这里将其分为三大部分,分别是:

返回信号状态的属性

返回单一数值的属性

返回数值范围的属性

接下来所要介绍的是configuration。Configuration主要用于在一些component与entity间做连接的动作。在一个设计中,同样的一个entity可以做许多不同的architecture设计,但是一次只能有一个architecture被选做这个设计的架构,configuration就是连接被选定的architecture与entity之间的桥梁。当simulator利用configuration连接entity与architecture后,设计的架构即已确定并可供仿真了。

8-1 返回信号状态的属性

这一类的属性其返回值都是表示信号的状态,比如说信号改变的瞬间,或是信号改变之前的逻辑值。我们来看看这一类的属性有哪些。

1. s’event:返回值为一boo1ean值,当一个事件发生的瞬间其返回值为true,否则返回值为false.

2. s’active:返回值为一boolean值,当一个事件或是转换事件(transaction)发生的瞬间其返

回值为true,否则返回值为false。这里的转换事件与一般所称的事件(event)略有不同, 我们将在后面对其进行说明。

3. s’1ast_event:返回值为一时间量,表示信号转换逻辑值事件发生后至目前为止的时间

4.s’1ast value:返回值为一逻辑值,表示信号改变的事件发生前,信号s最后的逻辑值。

5.s’1ast_active:返回值为一时间量,表示信号发生转换事件后至目前为止的时间量。现在

我们分别讨论以上五种属性所代表的意义及使用方法。

8-1-1 Event属性

Event属性可以说是使用最广泛的属性了。当一个事件发生的瞬间其返回值为true,对一个信号而言,其逻辑值的改变即是事件的发生。一般而言最在乎逻辑值改变的信号就是clock了,因为flip-flop输出信号的改变都是在clock逻辑值改变的瞬间发生的(异步reset的flip-flop还会受reset信号所影响)。Event这个属性一般与clock的逻辑条件搭配使用,比如下面的例子即是一个上升沿触发的D_type flip_flop。

library ieee;

use _logic_;

entity V8_0 is

port(D : in std_logic;

Q : out std_logic;

Clk : in std_logic);

end V8_0;

architecture A_DFF of V8_0 is

begin

process(Clk)

begin

if Clk = '1' and Clk'event then

Q <= D;

end if;

end process;

end A_DFF;

8-1-2 Active属性

Active属性发生的机率比event属性来得更高,因为它是在一个事件或是转换事件发生的瞬间就会返回true。什么是转换事件呢?对一个逻辑器件的输出信号而言,当其输入信号改变时,输出信号并不会因此而改变,我们称之为转换事件。比如说一个or gate,当一个输入为逻辑’1’时,其输出端一定为逻辑’1’。这时输出端受此输入信号的影响,即使另一个输入端的信号有了改变,其输出端的逻辑状态仍不会改变。这时没有事件event的发生,但却有转换事件transaction的发生。我们来看看图8-l就会明白转换事件的意义。

然而转换事件的发生对实际的电路却没有什么影响,所以在使用上也不容易举出较实用的例子。读者们可自己体会。

8-1-3 Last_event属性

Last_event属性所要返回的数值是一个时间量,而这个时间量是自检验点起往回推,—直到信号最后改变状态的时间。Last_event属性的作用在于检验信号的设定时间是否足够。我们来看看下面的例子。

library ieee;

use _logic_;

entity V8_1 is

generic(setup_time : time := 5 ns);

port(D : in std_logic;

Q : out std_logic;

Clk : in std_logic);

begin

process(Clk)

begin

if Clk = '1' and Clk'event then

assert (D'last_event < setup_time)

report "setup violation"

severity error;

end if;

end process;

end V8_1;

architecture A_DFF of V8_1 is

signal Dtime : time;

begin

process(Clk)

begin

if Clk = '1' and Clk'event then

if (D'last_event < setup_time) then

Q <= 'X';

else

Q <= D;

end if;

Dtime <= D'last_event;

end if;

end process;

end A_DFF;

在这个例子中,entity的下一行是一个由generic所声明的时间量,其默认值为5 ns。在begin之后有一个process,是用来检验信号D的1ast_event时间量。若在信号Clk的上升沿之前,信号D的稳定时间量要大于generic中设定的setup_time值。若是在这个时间点上,待检验的信号其设定时间不足,就会送出一个ERROR信息显示在ModelSim的主窗口上。在architecture中也会检验信号D的setup time是否足够,若是不足时会令信号Q的输出值为unknown。图8-2即是以之前的例子所做仿真的结果,其中的dtime为信号D的last_event属性的返回值。

8-1-4 Last_value及Last_active属性

在之前就曾经讲过:last_value属性的返回值为一逻辑值,也就是说在检查点上,若检查的信号没有改变,则其返回值也不会改变。一定要等到受检查的信号改变其逻辑状态,信号的last_value属性返回值才会改变。我们延续之前的例子,只是在其中加入了信号D的last_value及1ast_active属性。

library ieee;

use _logic_;

entity V8_2 is

generic(setup_time : time := 5 ns);

port(D : in std_logic;

Q : out std_logic := '0';

Clk : in std_logic);

begin

process(Clk)

begin

if Clk = '1' and Clk'event then

assert (D'last_event < setup_time)

report "setup violation"

severity error;

end if;

end process;

end V8_2;

architecture A_DFF of V8_2 is

signal Dtime : time;

signal DValue : std_logic;

signal DATime : time;

begin

process(Clk)

variable DValueV : std_logic;

begin

if Clk = '1' and Clk'event then

if (D'last_event < setup_time) then

Q <= 'X';

else

Q <= D;

end if;

Dtime <= D'last_event;

DValue <= D'last_value;

DATime <= D'last_active;

end if;

end process;

end A_DFF;

图8-3是前一节的输入信号所仿真的结果,在第一个clock信号上升沿(25 ns)之前,输入信号D(检查信号)的逻辑值并未改变,所以信号D的last_value属性(Dvalue)返回值仍与之前的值(unknown)相同。在第二个clock信号上升沿(75 ns)前,信号D已改变其逻辑值,因此D的last_value属性变为逻辑’0’。一直到172 ns处信号D又改变其逻辑值,因此Dvalue会在175 ns处再改变其逻辑值。至于信号D的’last_active的返回值是与last_event的返回值一样的。

8-2 返回单一数值的属性

这一类属性的返回值只是一个数值而已,而返回的数值是一个type或subtype的边界值。既然是边界值,表示这一定是个向量型的数据类型。让我们看看属于这一类的属性有哪些。

s’left 返回值为type或subtype最左边的位数

s’right 返回值为type或subtype最右边的位数

s’high 返回值为type或subtype最高的位数

s’low 返回值为type或subtype最低的位数

我们先举个例子声明,假设有个向量信号为:

a_vector(7 downto 0)

则以下信号四种属性的返回值分别为:

a_vector’left 的返回值为 7

a_vector’right 的返回值为 0

a_vector’high 的返回值为 7

a_vector’low 的返回值为 0

但若是a wctor这个向量改为:

a_vector(0 to 7)

那么a_vector’high及a_vector’low两属性的返回值仍与上一个例子相同,但是a_vector’left及a_vector’high两属性的返回值可就不同了,其返回值正好相反。在上面的例子中,可以很明显地看出,’high及’low两属性的返回值只与向量范围的大小有关,’high的返回值是向量范围的最大值,’low的返回值是向量范围的最小值。而’left及’right两属性的返回值只与向量排列的方式有关,’left的返回值是向量的最左边边界值,’right的返回值是向量的最右边边界值。

这一类属性的返回值主要的用途是使程序的设计更有弹性,比如说在设计中有些向量信号的范围并不固定,有可能会从32-bit升级到64-bit。那么在设计中直接将信号范围固定成31 downto 0或63 downto 0就比较没有弹性了,这时使用generic的声明会是一个好方法。以generic声明后,设计内部的范围就不宜再使用固定的数值了,这时除了使用generic声明的数值外,使用以上介绍的属性也可以达到目的。让我们看看以下的例子。

library ieee;

use _logic_;

entity V8_3 is

generic(DRange : integer := 8);

port(D : in std_logic_vector(DRange - 1 downto 0);

Q : out std_logic_vector(DRange - 1 downto 0);

Clk : in std_logic);

end V8_3;

architecture A_DFF of V8_3 is

begin

process(Clk)

begin

if Clk = '1' and Clk'event then

for i in 0 to D'left - 1 loop

Q(i) <= D(i + 1);

end loop;

Q(Q'left) <= D(D'right);

end if;

end process;

end A_DFF;

以上的例子是将8个flip-flop的输出进行重新指定。将信号D(0)输入值经flip-flop后指定给信号Q(7),信号D(1)输入值经flip-flop后指定给信号Q(0),依此类推。要是有必要将设计改成16-bit,只要将generic值改成8,再做一次compile就可以了。读者们也可以依设计的要求而自行变化使用的方式。

8-3 返回数值范围的属性

在本节要介绍的属性其返回值是一个范围,我们先看看具有这种特性的属性有哪些。

s’range 返回值为向量信号的范围值

s’reverse_range 返回值为向量信号逆顺序的范围值

那么这种属性要用在什么地方呢?首先可以用在信号的声明上,我们先来看看下面的例子:

library ieee;

use _logic_;

use _logic_;

entity V8_4 is

generic(DRange : integer := 8);

port(D : in std_logic_vector(DRange - 1 downto 0);

Q : out std_logic_vector(DRange - 1 downto 0);

Sel : in std_logic_vector(1 downto 0);

LD : in std_logic;

Clk : in std_logic);

end V8_4;

architecture A_Counter of V8_4 is

signal DC0 : std_logic_vector(D'range);

signal DC1 : std_logic_vector(DC0'range);

signal DC2 : std_logic_vector(DC1'range);

signal DC3 : std_logic_vector(DC2'range);

begin

process(Clk)

begin

if Clk = '1' and Clk'event then

if LD = '0' then

DC0 <= D;

DC1 <= D;

DC2 <= D;

DC3 <= D;

else

DC0 <= DC0 + 1;

DC1 <= DC1 + 2;

DC2 <= DC2 + 3;

DC3 <= DC3 + 4;

end if;

end if;

end process;

with Sel select

Q <= DC0 when "00" ,

DC1 when "01" ,

DC2 when "10" ,

DC3 when others;

end A_Counter;

在上面的例子中有四个计数器,分别是DC0、DCl、DC2及DC3。在architecture的声明部分中可以看到,这四个计数器都使用到’range这个属性。DC0计数器与entity中输入信号D的范围相同,因此其使用到的是信号D的range属性。至于DCl

DC2及DC3这三个计数器其实也与输入信号D的范围相同,在这边要分别声明成DC0’range、DCl’range及DC2’range,只是要让读者了解在architecture声明部分中的信号,还是可以拿来做其他信号的range声明。但是在entity中声明的信号,就不能拿来当做其他信号的range声明。比如说在上面的例子中,输入信号D及输出信号Q的范围其实是一样的。但是就是不能将信号Q声明成以下的状态:

Q : out std_logic_vector(D’range);

Compiler会告诉你他不知道D是什么东西。

第二种用途是在loop中定义其范围,让我们将之前介绍到属性’left所举的例子拿来改写。

library ieee;

use _logic_;

entity V8_5 is

generic(DRange : integer := 8);

port(D : in std_logic_vector(DRange - 1 downto 0);

Q : out std_logic_vector(DRange - 1 downto 0);

Clk : in std_logic);

end V8_5;

architecture A_DFF of V8_5 is

begin

process(Clk)

begin

if Clk = '1' and Clk'event then

for i in D'reverse_range loop

if i = Q'left then

Q(Q'left) <= D(0);

else

Q(i) <= D(i + 1);

end if;

end loop;

end if;

end process;

end A_DFF;

在上面的例子中,我们在for loop里使用到了信号D的’reverse_range属性,其所指的就是0 to 7的范围。当i的值为7时,将信号D(0)的值指定给信号Q(7),其余状态则将信号D(i+1)的值指定给信号Q(i)。这个例子的执行结果与上面的那个例子执行结果相同,只是写法不同罢了。

8-4 Configuration

Configuration的用途有点像是个牵线的红娘,她会将一个component的架构连到entity上,比如说一个设计的本体中,可能有不止一个的架构,这时configuration便可以派上用场。当使用configuration将entity与architecture连接之后,simulator会将其compile到library中,这时用来做simulation的模型便建立了。

Configuration也可以用来将一些特殊的参数值由generic的方式传送入component内,在使用component instantiation时你可以不用将这些参数以generic map的方式传入component内,而在下面的configuration声明中再将这些参数传入。

在下面的几个小节中,我们会将上面所讲述的configuration做个介绍,并会举些例子让你了解configuration的使用。

8-4-1 Architecture Configuration

这是最简单的一种configuration声明了,简单到什么程度呢?简单到其内部可以空无一物。在使用前我们先来看看其基本架构

语法:

Configuration config_name of entity_name is

for architecture_name

end for

end config_name;

当我们声明一个configuration时,在关键字configuration之后的是configuration

name,在之后又接了entity name,这表示所声明的是这一个entity的configuration,那么这个entity要连接的architecture是哪一个呢?就是声明在下一行for之后的architecture_name。我们先来看看以下的例子。

library ieee;

use _logic_;

entity V8_6 is

port(D : in std_logic;

Q : out std_logic := '0';

Rst : in std_logic;

Clk : in std_logic);

end V8_6;

architecture ARDFF of V8_6 is

begin

process(Rst,Clk)

begin

if Rst = '0' then

Q <= '0';

elsif Clk = '1' and Clk'event then

Q <= D;

end if;

end process;

end ARDFF;

configuration CFG_DFF of V8_6 is

for ARDFF

end for;

end CFG_DFF;

也许你会觉得奇怪,明明只有一个entity和一个architecture,何必要用configuration连接呢?没错,有些simulator在这种情形下是可以不需要做configuration的声明,像ModelSim就是如此。但有些simulator就未必如此了,所以在此仍说明一下最简单的configuration声明。

接着我们要看的是一个设计中有一个entity和两个architectures的例子,这个例子和前一个差不多,惟一的差别是其中多了一个architecture。

library ieee;

use _logic_;

entity V8_7 is

port(D : in std_logic;

Q : out std_logic := '0';

Rst : in std_logic;

Clk : in std_logic);

end V8_7;

architecture ARDFF of V8_7 is

begin

process(Rst,Clk)

begin

if Rst = '0' then

Q <= '0';

elsif Clk = '1' and Clk'event then

Q <= D;

end if;

end process;

end ARDFF;

architecture SRDFF of V8_7 is

begin

process(Clk)

begin

if Clk = '1' and Clk'event then

if Rst = '0' then

Q <= '0';

else

Q <= D;

end if;

end if;

end process;

end SRDFF;

configuration CFG_DFF of V8_7 is

for ARDFF

end for;

end CFG_DFF;

这是一个D_type flip-flop的设计,两个architectures所不同的是:architecture ARDFF是一个asynchronous reset的flip-flop,而architecture

SRDPF是一个synchronous reset的flip-flop。由configuration的声明可得知,这个设计采用的是asynchronous reset的flip-flop。

8-4-2 Component Configuration

前一节所介绍的是以configuration将entity与architecture连接,在本节所要介绍的则是将小的设计以component方式使用。虽然这是在下一章才会介绍到的hierarchy

design和component instantiation,不过在这儿我们仍可做个简单的介绍,让读者能了解其使用的方式。

在这一节中我们仍以上面的例子为主再做个修改,首先来看看以component的声明方式。

library ieee;

use _logic_;

entity V8_8 is

port(D : in std_logic;

Q : out std_logic := '0';

Rst : in std_logic;

Clk : in std_logic);

end V8_8;

architecture ARDFF of V8_8 is

begin

process(Rst,Clk)

begin

if Rst = '0' then

Q <= '0';

elsif Clk = '1' and Clk'event then

Q <= D;

end if;

end process;

end ARDFF;

architecture SRDFF of V8_8 is

begin

process(Clk)

begin

if Clk = '1' and Clk'event then

if Rst = '0' then

Q <= '0';

else

Q <= D;

end if;

end if;

end process;

end SRDFF;

configuration CFG_DFF of V8_8 is

for SRDFF

end for;

end CFG_DFF;

--------------------------------------------------------------------------------------------------------

library ieee;

use _logic_;

entity V8_9 is

port(D : in std_logic;

Q : out std_logic := '0';

Rst : in std_logic;

Clk : in std_logic);

end V8_9;

architecture A_TDFF of V8_9 is

component V8_8

port(D : in std_logic;

Q : out std_logic := '0';

Rst : in std_logic;

Clk : in std_logic);

end component;

begin

UDFF : V8_8

port map(D => D ,

Q => Q ,

Rst => Rst ,

Clk => Clk );

end A_TDFF;

configuration CFG_TDFF of V8_9 is

for A_TDFF

for UDFF : V8_8 use configuration _DFF;

end for;

end for;

end CFG_TDFF;

在上面的例子中,虚线的分隔线表示可以将前半部和后半部分成两个文件,当然也是可以放在同一个文件中。在前半部中的写法与前一小节的例子几乎完全一样,所不同的只有在configuration声明中使用了同步reset的SRDFF architecture。在后半部的程序中,我们在architecture的声明部分中定义了一个component,也就是前半部程序的设计。在后半部程序的设计中,只使用了一个前半部设计的component。所以加上后半部的设计和只有前半部的设

计,其结果并没有什么差别。举这个例子的目的,只是要让读者们了解configuration也可以做configuration的的声明。在之前我们已在前半部设计中利用configuration声明了这个component为SRDFF,因此在以后的设计中沿用此configuration声明。

然而在一个设计中若有两个以上的地方会用到上面的设计,而这些设计皆使用上面的configuration,那么我们可以在前一个例子的后半部设计中加上他自己的configuration。让我们来看看以下的设计。

library ieee;

use _logic_;

entity DFF is

port(D : in std_logic;

Q : out std_logic := '0';

Rst : in std_logic;

Clk : in std_logic);

end DFF;

architecture ARDFF of DFF is

begin

process(Rst,Clk)

begin

if Rst = '0' then

Q <= '0';

elsif Clk = '1' and Clk'event then

Q <= D;

end if;

end process;

end ARDFF;

architecture SRDFF of DFF is

begin

process(Clk)

begin

if Clk = '1' and Clk'event then

if Rst = '0' then

Q <= '0';

else

Q <= D;

end if;

end if;

end process;

end SRDFF;

library ieee;

use _logic_;

entity V8_10 is

port(D1 : in std_logic;

Q1 : out std_logic := '0';

D2 : in std_logic;

Q2 : out std_logic := '0';

Rst : in std_logic;

Clk : in std_logic);

end V8_10;

architecture A_TDFF of V8_10 is

component DFF

port(D : in std_logic;

Q : out std_logic := '0';

Rst : in std_logic;

Clk : in std_logic);

end component;

begin

UDFF1 : DFF

port map(D => D1 ,

Q => Q1 ,

Rst => Rst ,

Clk => Clk );

UDFF2 : DFF

port map(D => D2 ,

Q => Q2 ,

Rst => Rst ,

Clk => Clk );

end A_TDFF;

--configuration CFG_TDFF of TDFF is

-- for A_TDFF

-- for all : DFF use configuration _DFF;

-- end for;

-- end for;

--end CFG_TDFF;

configuration CFG_TDFF of V8_10 is

for A_TDFF

for UDFF1 : DFF use entity (SRDFF);

end for;

for UDFF2 : DFF use entity (ARDFF);

end for;

end for;

end CFG_TDFF;

在这个例子中我们对所有的DFF做了一个configuration声明,只要是实体名

称(instance name)为DFF,其architecture一律与CFG_DFF所声明的一致。而在设计的前半部已声明了CFG-DFF,它是将entity DFF与architecture SRDFF进行连接,因此我们在设计后半部所使用的仍是先前的architecture SRDFF。

不过若是设计中出现两个以上的components,他们使用与前面设计相同的entity,但是却使用不同的architecture,这时就不能使用先前的configuration声明,而要使用entity声明。之后的例子使用的程序与前一个例子大部分相同,只有在configuration声明处不同,让我们看看其configuration要怎么声明。

configuration CFG_TDFF of TDFF is

for A_TDFF

for UDFF1 : DFF use entity (SRDFF);

end for;

for UDFF2 : DFF use entity (ARDFF);

end for;

end for;

end CFG_TDFF;

在这个configuration中,我们对component的连接方式由configuration改变成entity。在entity声明完后,其后方有一个括号,括号内的是所要连接的architecture。在本例中名称为UDFF1的flip-flop是一个synchronous reset

D_type flip-flop,而名称为UDFF2的flip-flop是一个asynchronous reset

D-type flip-flop。这种声明方式的好处在于:每一个实体的声明都可以完全独立,而不必迁就之前configuration所做的声明。

8-4-3 Generic Configuration

Generic的主要用途是将一些参数由generic map传送到设计内部,这一点我们已经提过了。在此我们可以先对generic的用途做个较详细的声明,它具有以下的特性:

1. Generic声明的位置一般是置于entity内,port声明的上方。

2. Generic内部声明的参数,其数据类型并没有限制,但是要注意的是compiler是否能接受各种类型的参数。像Synopsys的Design Compiler其仅能接受数据类型为integer的参数。

3. Generic所声明的参数可以有默认值,而在内部设计中,若使用到的参数与默认值相同,则在做component instantiation时可以不需要generic map,若是使用到的参数与默认值不同,则在做component instantiation时就可以使用generic map将参数传入设计中。

4. Generic声明的参数在entity中就能使用。

不过在此要介绍的并不是generic的使用,而是如何在configuration中传递generic声明的参数。有些component在原始设计时使用许多外部输入的参数,藉以增加弹性以方便改变其设计的内容。比如Xilinx公司的core Generator,设计者可以用它产生许多不同的RAM,像是signal port或是dual port, address bus 及data bus的bit数,是不是要有控制信号we(write enable)、en(enable)及rst(reset),控制信号是high active或是low active等,以下的例子是其提供的library中,single

port RAM 的entity声明。

ENTITY C_MEM_SP_BLOCK_V1_0 IS

GENERIC (

C_ADDRESS_WIDTH : integer := 12;

C_CLK_POLARITY : integer := 1;

C_DEFAULT_DATA : string := “0”;

C_DEPTH : integer := 4096;

C_EN_POLARITY : integer := 1;

C_GENERATE_MIF : integer := 0;

C_HAS_DI : integer := 1;

C_HAS_DO : integer := 1;

C_HAS_EN : integer := 1;

C_HAS_RST : integer := 1;

C_HAS_WE : integer := 1;

C_MEM_INIT_FILE : string := “”;

C_MEM_INIT_RADIX : integer := 2;

C_PIPE_STAGES : integer := 0;

C_READ_MIF : integer := 1;

C_RST_POLARITY : integer := 1;

C_WE_POLARITY : integer := 1;

C_WIDTH : integer := 1

);

PORT (addr : IN STD_LOGIC_VECTOR ( C_ADDRESS_WIDTH -1 DOWNTO 0 );

di : IN STD_LOGIC_VECTOR ( C_WIDTH -1 DOWNTO 0) := (OTHERS

=> ‘0’ );

clk : IN STD_LOGIC;

we : IN STD_LOGIC := ‘0’ ;

en : IN STD_LOGIC := ‘1’;

rst : IN STD_LOGIC := ‘0’ ;

do : OUT STD_LOGIC_VECTOR ( C_WIDTH -1 DOWNTO 0 ) );

END C_MEM_SP_BLOCK_V1_0;

当你要使用SRAM的simulation model时,只要在configuration声明中设

定不同的参数值,即可得到你所想要的RAM。比如我们要建立一个data bus宽度为8-bit,数据存储深度为256(address bus为8-bit)的signal port RAM,其中包含we、en及rst三组控制信号,并且都是high active。我们就要建立一个如下的文档:

library ieee;

use _logic_;

use _logic_;

-- synopsys translate_off

Library XilinxCoreLib;

-- synopsys translate_on

entity V8_11 is

port(addr : IN std_logic_VECTOR(7 downto 0);

clk : IN std_logic;

di : IN std_logic_VECTOR(7 downto 0);

we : IN std_logic;

en : IN std_logic;

rst : IN std_logic;

do : OUT std_logic_VECTOR(7 downto 0));

end V8_11;

architecture A_RAMTest of V8_11 is

component ram256

port(addr : IN std_logic_VECTOR(7 downto 0);

clk : IN std_logic;

di : IN std_logic_VECTOR(7 downto 0);

we : IN std_logic;

en : IN std_logic;

rst : IN std_logic;

do : OUT std_logic_VECTOR(7 downto 0));

end component;

begin

Uram256 : ram256

port map(addr => addr ,

clk => clk ,

di => di ,

we => we ,

en => en ,

rst => rst ,

do => do );

end A_RAMTest;

configuration CFG_RAMTest of V8_11 is

for A_RAMTest

-- synopsys translate_off

for all : ram256

XilinxCoreLib.C_MEM_SP_BLOCK_V1_0(behavioral)

generic map(

c_has_en => 1,

c_rst_polarity => 1,

c_clk_polarity => 1,

c_width => 8,

c_has_do => 1,

c_has_di => 1,

c_en_polarity => 1,

c_has_we => 1,

c_has_rst => 1,

c_address_width => 8,

c_read_mif => 0,

c_depth => 256,

c_pipe_stages => 0,

c_mem_init_radix => 16,

c_default_data => "0",

c_mem_init_file => "",

c_we_polarity => 1,

c_generate_mif => 1);

end for;

use entity

-- synopsys translate_on

end for;

end CFG_RAMTest;

在CFG_RAMTest中我们设定了许多参数,比如设计中要有控制信号en(参数c_has_en=>1),en为high active(c_en_po1arity=>1),address bus的宽度为8-bit(c_address_width=>8)等。在architecture内只要用component

instantiation的方式将IO信号map到component上即可,而不需要以generic map的方式将参数传入设计中。

也许读者看到这个generic会很担心,因为在这个generic中有18个参数,是否要先了解所有参数的定义,再一一设定这些参数值呢。不用害怕,因为这个generic map的数值是Xilinx Core Generator自动产生的,而Core Generator 的使用在第10章中将有完整的介绍。在之前我们曾经说过,当generic的设定值与原先的默认值不同时,设计会以generic map或configuration中设定的值为依据,而原先的设计也可以不用再compile一次,以增加设计的弹性。

8-5 小结

在本章中介绍了三类信号的属性,读者们在了解其用途后,除了可以提高程序设计的弹性外,不论是在实际硬件的设计上,或是在simulation model的设计上,都能带来很大的方便性。其实在VHDL中还有许多不同的属性,但是使用的机率并不高,由于篇幅有限,这里就不介绍了。

除了介绍属性之外,我们还提到configuration。在一开始介绍的是一个entity对一个architecture的configuration连接,不过对一些simulator而言,这样的连接动作是多余的,因此许多设计者根本没有用过configuration。不过在一个以上的architecture出现时,就必须借助configuration的连接了。除此之外configuration还可以做generic参数的传递,这使得一些IP的使用变得更为方便了,所以configuration还是有学习的必要。

读完这一章后,相信读者已经对attribute及configuration的使用已经有了基本的了解。不过除了属性’event以外,本章所介绍到的内容可能在简单的设计中并不会用到。读者在看完这一章后先留下印象,在以后要用到该内容时再回来复习吧!

问题

1. 按照TTL 74373及74374的真值表,各设计一个8-bit的flip-flop,并注意’event属性的使用。

74373真值表

Output Control

L

L

L

H

Enable

H

H

L

X

Input

H

L

X

X

Output

H

L

Qo

Z

74374真值表

Output Control

L

L

L

H

Enable

?

?

L

X

Input

H

L

X

X

Output

H

L

Qo

Z

2.试设计一multiplexer,其输入有三组信号,分别是Ain、Bin及Sel。输出信号一组为Dout。当信号Sel为逻辑’0’时,输入信号Ain的值送到Dout,否则将Bin的值送到Dout。假设目前未确定信号Ain、Bin及Dout的bit数,较有可能是8-bit。请以generic声明代替固定的bit数。


本文发布于:2024-09-23 11:11:32,感谢您对本站的认可!

本文链接:https://www.17tex.com/fanyi/6096.html

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。

标签:信号   设计   属性   使用   声明   改变
留言与评论(共有 0 条评论)
   
验证码:
Copyright ©2019-2024 Comsenz Inc.Powered by © 易纺专利技术学习网 豫ICP备2022007602号 豫公网安备41160202000603 站长QQ:729038198 关于我们 投诉建议