我知道在进程中编写for-generate是不可能的,但是我想实现代码所呈现的功能.它基本上是一个地址解码器.任何帮助表示赞赏.
以下代码给出了语法错误:"生成附近的语法错误"
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.NUMERIC_STD.ALL;
entity address_decoder is
generic (CAM_DEPTH: integer := 8);
port (in_address: in std_logic_vector(CAM_DEPTH-1 downto 0);
out_address: out std_logic_vector(2**CAM_DEPTH-1 downto 0);
clk : in std_logic;
rst: in std_logic
);
end address_decoder;
architecture Behavioral of address_decoder is
begin
decode_process:
process(clk,rst) begin
if(clk'event and clk='1') then
if (rst = '1') then
out_address <= (others => '0');
else
NAME: for i in 0 to 10 generate
if (i = to_integer(unsigned(in_address))) then
out_address(i) <= '1';
else
out_address(i) <= '0';
end if;
end generate NAME;
end if;
end if;
end process;
end Behavioral;
Run Code Online (Sandbox Code Playgroud)
use*_*120 10
使用循环语句:
decode_process:
process(clk) -- synchronous reset, no rst in sensitivity list
begin
if clk'event and clk = '1' then
if rst = '1' then
out_address <= (others => '0');
else
for i in 0 to 10 loop
if i = to_integer(unsigned(in_address)) then
out_address(i) <= '1';
else
out_address(i) <= '0' ;
end if;
end loop;
-- name: for i in 0 to 10 generate
-- if (i = to_integer(unsigned(in_address))) then
-- out_address(i) <= '1';
-- else
-- out_address(i) <= '0';
-- end if;
-- end generate name;
end if;
end if;
end process;
Run Code Online (Sandbox Code Playgroud)
另外通知rst已从灵敏度列表中删除,它被写为同步复位.
可以合成一个循环语句,参见现在已废除的IEEE Std 1076.6-2004 8.8.9,语法,顺序语句,循环语句或您的特定综合供应商的工具文档.循环中找到的顺序语句将针对循环参数的每个值进行复制,该参数被视为常量.
那么生成迭代和循环迭代之间的区别是什么?
模拟周期甚至在顺序语句中(例如在过程中)模拟信号分配的并发性.在一个if语句与合成(展开)循环中的另一个语句之间没有依赖关系.与in_address 相比,它们将是识别器的i数量,每个提供一位.第一个分配,第二个...在这种情况下,循环语句将产生一个生成语句将使用相同的逻辑(使用条件信号赋值,尽管顺序逻辑(时钟)语义会使它看起来很尴尬).in_addressiout_addressa(0)a(1)
让我们将它与在适当位置的并发语句中使用generate语句进行比较:
architecture foo of address_decoder is
function to_std_ulogic (inp: boolean) return std_ulogic is
begin
if inp = TRUE then
return '1';
else
return '0';
end if;
end;
begin
decoder:
for i in 0 to 10 generate
out_address(i) <= to_std_ulogic(i = to_integer(unsigned(in_address)))
when clk'event and clk = '1';
end generate;
end architecture;
Run Code Online (Sandbox Code Playgroud)
to_std_ulogic为了简洁起见,在条件信号赋值语句中添加了一个带有布尔参数的函数out_address(i).
这看起来很好而且紧凑,并且可能根据使用将布尔值转换为std_ulogic的函数的能力进行合成.
但是,它扩展了详细说明:
architecture fum of address_decoder is
function to_std_ulogic (inp: boolean) return std_ulogic is
begin
if inp = TRUE then
return '1';
else
return '0';
end if;
end;
begin
decoder0:
block
constant i: integer := 0;
begin
out_address(i) <= to_std_ulogic(i = to_integer(unsigned(in_address)))
when clk'event and clk = '1';
end block;
decoder1:
block
constant i: integer := 1;
begin
out_address(i) <= to_std_ulogic(i = to_integer(unsigned(in_address)))
when clk'event and clk = '1';
end block;
decoder2:
block
constant i: integer := 2;
begin
out_address(i) <= to_std_ulogic(i = to_integer(unsigned(in_address)))
when clk'event and clk = '1';
end block;
decoder3:
block
constant i: integer := 3;
begin
out_address(i) <= to_std_ulogic(i = to_integer(unsigned(in_address)))
when clk'event and clk = '1';
end block;
decoder4:
block
constant i: integer := 4;
begin
out_address(i) <= to_std_ulogic(i = to_integer(unsigned(in_address)))
when clk'event and clk = '1';
end block;
decoder5:
block
constant i: integer := 5;
begin
out_address(i) <= to_std_ulogic(i = to_integer(unsigned(in_address)))
when clk'event and clk = '1';
end block;
decoder6:
block
constant i: integer := 6;
begin
out_address(i) <= to_std_ulogic(i = to_integer(unsigned(in_address)))
when clk'event and clk = '1';
end block;
decoder7:
block
constant i: integer := 7;
begin
out_address(i) <= to_std_ulogic(i = to_integer(unsigned(in_address)))
when clk'event and clk = '1';
end block;
decoder8:
block
constant i: integer := 8;
begin
out_address(i) <= to_std_ulogic(i = to_integer(unsigned(in_address)))
when clk'event and clk = '1';
end block;
decoder9:
block
constant i: integer := 9;
begin
out_address(i) <= to_std_ulogic(i = to_integer(unsigned(in_address)))
when clk'event and clk = '1';
end block;
decoder10:
block
constant i: integer := 10;
begin
out_address(i) <= to_std_ulogic(i = to_integer(unsigned(in_address)))
when clk'event and clk = '1';
end block;
end architecture;
Run Code Online (Sandbox Code Playgroud)
更糟糕的是,每个块语句并发条件信号赋值语句都成为表单的进程语句:
decoder10:
block
constant i: integer := 10;
begin
process
begin
if clk'event and clk = '1' then
out_address(i) <= to_std_ulogic(i = to_integer(unsigned(in_address)));
end if;
wait on clk, in_address;
end process;
Run Code Online (Sandbox Code Playgroud)
所以现在突然而不是模拟一个进程,你有11个进程,每个进程对clk和in_address都很敏感,这意味着进程变得比两个时钟边缘更活跃.
因此,循环语句和等效的generate语句不仅在精化和合成之后产生相同的硬件,因此保证循环语句在模拟中更快,这是它的预期目的.
VHDL设计规范中的所有内容都转换为块语句,过程语句和子程序(函数,过程).并发过程也被移除,而函数是表达式.
保证合成首先阐述设计.在这种情况下,generate语句和包含循环的单个进程之间的合成差异是分组.除非合成工具接受允许展平的属性(例如,DISSOLVE_HIERARCHY作为生成语句的属性),否则将单独翻译流程语句.
在单个进程情况下的循环语句中,您有机会默认在10个信号分配之间共享地址识别器逻辑,从而可能产生较少的逻辑.
因此,在合成方面几乎没有差别,但在模拟方面存在显着差异,其中实际影响取决于您的设计尺寸.