Menu Close

VHDL预编译(常数,generic…)

在VHDL语言中没有类似C语言中的#define语句定义宏来实现字符常量(用字符代替常数)。但VHDL语言中也有类似的机制实现常量的定义和使用,一般有两种方法实现,一种为。参数、常量的定义和使用也预编译的一种,即在VHDL语言工程在真正编译前先扫描各个VHDL文件,将参数和符号常量替换成常数才进行真正的编译。使用符号常量代替常数有诸多优点:

(1)语义比直接使用常数更加清晰;

(2)容易修改和替换;

比如在一个设计多出使用了4位位宽数据或地址总线,如data( 3 downto 0)。但后续设计时如果想修改为8位总线接口,就要找到每一个相关的4位接口并逐一修改,不仅费时费力,还容易出错。但如果采用参数化设计,或利用constant声明符号常量,只要在声明处修改一处即可。

(3)利用Generic实现参数传递,可在元件声明时重新设置参数值达到最大限度重用代码的效果。

例1 利用Generic设计参数化奇偶校验码。

(1)设计实体程序

entity even_odd is
generic (
WIDTH : integer := 4
);
Port ( 
a : in  bit_vector( WIDTH-1 downto 0);
c : out bit_vector( WIDTH downto 0)


);
end even_odd;

architecture arch_even_odd of even_odd is
signal cal_odd: bit ;
begin
cal_odd <= xor a;    --reduction xor operator
c       <= cal_odd & a  ;

end arch_even_odd;

实体设计程序中利用generic声明了整形参数WIDTH,初值为4。 在构造体的行为逻辑区,利用缩减运算符(reduction operator)XOR实现了信号a(位矢量)中所有位中’1’的数量奇偶统计。如果a中’1’的数量为奇数,则表达式XOR a返回’1′,否则返回’0’。如:

cal_odd <= xor a;   –reduction xor operator

但需要注意,该语句是VHDL 2008语法格式。在Vivado中使用时需要在文件属性里指定为VHDL 2008 才能正确编译。如图1所示,

%title插图%num

图1

 语句 c <= cal_odd & a ; 采用并位操作符将,将xor a的计算结果并位到a的左边形成偶校验码。

(2)仿真程序

entity tb_odd_gen is
--  Port ( );
end tb_odd_gen;

architecture Behavioral of tb_odd_gen is
constant tb_WIDTH :integer :=8;
signal   tb_a : bit_vector (tb_WIDTH-1 downto 0);
signal   even_out: bit_vector (tb_WIDTH downto 0); 

component even_odd
generic (
WIDTH : integer
);
port (
 a : in  bit_vector(WIDTH-1 downto 0);
 c : out bit_vector(WIDTH downto 0)
 
);
end component;
begin

odd_gen: even_odd
generic map
(
WIDTH => tb_WIDTH
)
port map(

a => tb_a,
c =>even_out

);

--tb_a<= B"0000_0000", B"0000_0001" after 10 ns , B"0000_0010" after 20 ns, B"0010_0011" after 30 ns,
     --  B"0011_0111" after 40 ns, B"1000_1000" after 50 ns;

tb_a<= "00000000", "00000001" after 10 ns , "00000010" after 20 ns, "00100011" after 30 ns,
       "00110111" after 40 ns, "10001000" after 50 ns;

end Behavioral;

仿真程序中给出部分位矢量的,并没有给出全部的检查。 有两种格式可以使用,如:

tb_a<= B”0000_0000″, B”0000_0001″ after 10 ns , B”0000_0010″ after 20 ns, B”0010_0011″ after 30 ns, — B”0011_0111″ after 40 ns, B”1000_1000″ after 50 ns;

第一种格式明确指出数据的进位格式B表示二进制格式,此时可以使用”_”分割二进制数据,提高数据的可读性。

tb_a<= “00000000”, “00000001” after 10 ns , “00000010” after 20 ns, “00100011” after 30 ns, “00110111” after 40 ns, “10001000” after 50 ns;

第二种格式没有明确指出数据的进位格式,此时编译器根据赋值语句左右的类型进行匹配,但此时不可以使用”_”分割二进制数据。

利用语句constant tb_WIDTH :integer :=8; 将tb_WIDTH设为常量8,并修改设计实体的参数,实现8位参数传递。

 

(3)仿真波形

%title插图%num

图2

从图2的波形可以看出,even_out实行了偶校验结果。

Posted in FPGA, FPGA 教材教案, IC, IC 教材教案, VHDL, VHDL, Vivado, Vivado, 开发工具, 开发工具, 开发语言, 教材与教案, 数字集成电路, 文章, 编程语言

发表回复

相关链接