for-generate内部进程vhdl

pre*_*a B 2 vhdl

我知道在进程中编写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个信号分配之间共享地址识别器逻辑,从而可能产生较少的逻辑.

因此,在合成方面几乎没有差别,但在模拟方面存在显着差异,其中实际影响取决于您的设计尺寸.