【问题标题】:Use generate statement to create 'n' array of registers in VHDL使用 generate 语句在 VHDL 中创建“n”个寄存器数组
【发布时间】:2018-01-31 14:30:21
【问题描述】:

我正在将旧的 AHDL 代码转换为 VHDL,我需要使用 generate 语句创建 5 个电阻器数组。我以前从未使用过generate,在尝试了几个小时后,我仍然找不到我的问题的答案。我最初的方法是使用 18 位输入数组和 18 位输出数组,但我知道这不是这样做的方法。

这是我现在的代码:

entity setup_comp_reg is

    generic(
    NUM_ID: integer := 18
   );

  port ( 
  clk:      in std_logic;  
  D:            in std_logic_vector(17 downto 0);   
  clrn:     in std_logic;   
  ena:      in std_logic;   

  Q:            out std_logic_vector(17 downto 0)

  );
end setup_comp_reg;

architecture rtl of setup_comp_reg is

begin

DFFE: process (clk, clrn, ena) -- 18 times, using generate 
begin

    if (clrn = '0') then
        Q<= (others => '0');

    elsif (rising_edge(clk)) then

        if (ena = '1') then
            Q<= D;
        end if;

    end if;
end process;


end rtl;

所以,我已经有了 DFFE,但是如何使用 generate 来创建 5 个每个 18 位的数组呢?

AHDL 代码很容易解释,它也可能有所帮助:

for i in 17 to 0 generate                       
            rg_bit_time[i].(d, clk, clrn, ena)      = (iDATA[i], clk, not reg_reset, adBT&iWR);
            rg_sample_time[i].(d, clk, clrn, ena)   = (iDATA[i], clk, not reg_reset, adSP&iWR);
            rg_low_sync[i].(d, clk, clrn, ena)      = (iDATA[i], clk, not reg_reset, adLS&iWR);
            rg_hi_sync[i].(d, clk, clrn, ena)       = (iDATA[i], clk, not reg_reset, adHS&iWR);
    end generate;

谢谢。

【问题讨论】:

  • 你已经生成了 18 个 DFFE,没有 Generate,因为 D 和 Q 都是 18 位宽。那么你真正要问的是什么?如果你想要 18 个寄存器,每个寄存器都有 18 位,你首先必须决定如何互连它们。
  • 我需要创建没有 18 位输入和输出的 DFFE。旧的 AHDL 代码非常简单,我需要做同样的事情(如下),因为我将有 5 个 18 位寄存器的数组。这是 AHDL:对于 i 在 17 到 0 生成 rg_bit_time[i].(d, clk, clrn, ena) = (iDATA[i], clk, not reg_reset, enable[i]);结束生成;
  • 所以你想要 18 个一位寄存器。您仍然需要定义它们是如何相互连接的。如果您只需要 18 个单独的输入和 18 个单独的输出,您上面的代码就可以了,只需从上面的模块中的 std_logic_vector 中挑选一些位。 std_logic_vector 只是对单个位的抽象;这就是你在更高级别的语言中得到的。
  • 什么5个数组?哦,你编辑了评论。这就像果冻。我无法读懂你的想法,请用你想要做什么和 AHDL 等价物更新问题。如果您需要 5 个 setup_comp_reg 实例,无论是单独实例化 5 次还是在一个 for..generate 语句中实例化它都没有关系。
  • 您的困惑似乎源于 DFFE 的 AHDL 原语,该原语用函数原型描述:FUNCTION DFFE (d, clk, clrn, prn, ena) RETURNS (q) ;。为它的 q 输出挂上名称的唯一地方是在分配中(它将形式与 VHDL 中的实际相关联)。请参阅Altera Hardware Description Language (AHDL) Language Reference Manual。这些名称将与 q 个输出相关联。

标签: arrays vhdl intel-fpga flip-flop


【解决方案1】:

AHDL generate 语句表示 i 的每次迭代都有四个触发器。

AHDL 生成语句:

for i in 17 to 0 generate                       
            rg_bit_time[i].(d, clk, clrn, ena)      = (iDATA[i], clk, not reg_reset, adBT&iWR);
            rg_sample_time[i].(d, clk, clrn, ena)   = (iDATA[i], clk, not reg_reset, adSP&iWR);
            rg_low_sync[i].(d, clk, clrn, ena)      = (iDATA[i], clk, not reg_reset, adLS&iWR);
            rg_hi_sync[i].(d, clk, clrn, ena)       = (iDATA[i], clk, not reg_reset, adHS&iWR);
    end generate; 

AHDL 使用函数原型来表示基元(此处为 DFFE)。返回值将是 q 输出(在 AHDL 生成语句中未提及)。具有函数原型关联的名称有四个赋值。这代表了 18 个触发器的四个数组。

DFFE 寄存器的函数原型显示在Altera Hardware Description Language (AHDL) Language Reference Manual,第 3 节,基元、触发器和锁存基元,表 3-9 中。 MAX+PLUS II 人字拖和闩锁:

返回值将与 AHDL 生成语句中的赋值语句中的名称(例如 rg_bit_time[i])相关联。

在 VHDL 中,我们通过将实际值与包含输出的 DFFE 实体的形式相关联来做到这一点。

具有所有输出和输入端口的行为表示如下所示:

library ieee;                   -- ADDED context clause
use ieee.std_logic_1164.all;

entity setup_comp_reg is

    generic (
        NUM_ID: integer := 18
    );

    port ( 
        clk:            in  std_logic;  
        D:              in  std_logic_vector(NUM_ID - 1 downto 0);   
        clrn:           in  std_logic;   
        ena:            in  std_logic;   
        -- Q:        out std_logic_vector(17 downto 0)
        WR:             in  std_logic;  -- ADDED
        adBT:           in  std_logic;  -- ADDED
        adSP:           in  std_logic;  -- ADDED
        adLS:           in  std_logic;  -- ADDED
        adHS:           in  std_logic;  -- ADDED
        rg_bit_time:    out std_logic_vector(NUM_ID - 1 downto 0); -- ADDED
        rg_sample_time: out std_logic_vector(NUM_ID - 1 downto 0); -- ADDED
        rg_low_sync:    out std_logic_vector(NUM_ID - 1 downto 0); -- ADDED
        rg_hi_sync:     out std_logic_vector(NUM_ID - 1 downto 0)  -- ADDED
    );
end entity setup_comp_reg;

architecture rtl of setup_comp_reg is
    -- For no -2008 dependency, ADD these:
    signal adBTWR:      std_logic;
    signal adSPWR:      std_logic;
    signal adLSWR:      std_logic;
    signal adHSWR:      std_logic;
begin
-- Write ENABLE conditions:

    adBTWR <= adBT and WR;
    adSPWR <= adSP and WR;
    adLSWR <= adLS and WR;
    adHSWR <= adHS and WR;

SETUP_REGS:
    for i in NUM_ID - 1 downto 0 generate
BIT_TIME:
        process (clk, clrn)  -- enables not needed in sensitivity list
        begin
            if clrn = '0' then
                rg_bit_time(i)  <= '0';
            elsif rising_edge (clk) then
                if adBTWR = '1' then
                    rg_bit_time(i) <= D(i);
                end if;
            end if;
        end process;
SAMPLE_TIME:
        process (clk, clrn)
        begin
            if clrn = '0' then
                rg_sample_time(i)  <= '0';
            elsif rising_edge (clk) then
                if adSPWR = '1' then
                    rg_sample_time(i) <= D(i);
                end if;
            end if;
        end process;
LOW_SYNC:
        process (clk, clrn)
        begin
            if clrn = '0' then
                rg_low_sync(i)  <= '0';
            elsif rising_edge (clk) then
                if adLSWR = '1' then
                    rg_low_sync(i) <= D(i);
                end if;
            end if;
        end process;
HI_SYNC:
        process (clk, clrn)
        begin
            if clrn = '0' then
                rg_hi_sync(i)  <= '0';
            elsif rising_edge (clk) then
                if adHSWR = '1' then
                    rg_hi_sync(i) <= D(i);
                end if;
            end if;
        end process;
    end generate;

end architecture rtl;

您可以关联来自实体 (DFFE) 的各个触发器,但不需要 VHDL 寄存器传输逻辑 (RTL) 表示。在 AHDL 中,您别无选择,命名元素将是与设备引脚相关联的触发器。

您还可以简化上述描述,以这种方式编写以显示 AHDL 生成语句的天意(没有单独的触发器)。

使用带有实例化触发器的生成语句将详细说明用于实例化的 i 个嵌套块语句,外部用于端口映射,内部包含一个或多个为四个名称中的每一个名称实现触发器的进程。上面没有实例化(保存一个块语句嵌套级别)。

使用循环语句而不是生成语句的描述将消除单个触发器的所有过程,并且可以通过对数组对象的目标使用赋值来进一步折叠:

architecture rtl1 of setup_comp_reg is
    -- For no -2008 dependency, ADD these:
    signal adBTWR:      std_logic;
    signal adSPWR:      std_logic;
    signal adLSWR:      std_logic;
    signal adHSWR:      std_logic;
begin
-- Write ENABLE conditions:

    adBTWR <= adBT and WR;
    adSPWR <= adSP and WR;
    adLSWR <= adLS and WR;
    adHSWR <= adHS and WR;

-- SETUP_REGS:
BIT_TIME:
        process (clk, clrn)  -- enables not needed in sensitivity list
        begin
            if clrn = '0' then
                rg_bit_time  <= (others => '0');
            elsif rising_edge (clk) then
                if adBTWR = '1' then
                    rg_bit_time <= D;
                end if;
            end if;
        end process;
SAMPLE_TIME:
        process (clk, clrn)
        begin
            if clrn = '0' then
                rg_sample_time  <= (others => '0');
            elsif rising_edge (clk) then
                if adSPWR = '1' then
                    rg_sample_time <= D;
                end if;
            end if;
        end process;
LOW_SYNC:
        process (clk, clrn)
        begin
            if clrn = '0' then
                rg_low_sync  <= (others => '0');
            elsif rising_edge (clk) then
                if adLSWR = '1' then
                    rg_low_sync <= D;
                end if;
            end if;
        end process;
HI_SYNC:
        process (clk, clrn)
        begin
            if clrn = '0' then
                rg_hi_sync  <= (others => '0');
            elsif rising_edge (clk) then
                if adHSWR = '1' then
                    rg_hi_sync <= D;
                end if;
            end if;
        end process;
end architecture rtl1;

这是四个过程语句。

精明的准备者会注意到可以通过对命名寄存器输出使用单独的启用来进一步压缩代码:

architecture rtl2 of setup_comp_reg is
    signal adBTWR:      std_logic;
    signal adSPWR:      std_logic;
    signal adLSWR:      std_logic;
    signal adHSWR:      std_logic;
begin
-- Write ENABLE conditions:
    adBTWR <= adBT and WR;
    adSPWR <= adSP and WR;
    adLSWR <= adLS and WR;
    adHSWR <= adHS and WR;

BT_SP_LS_HS:
        process (clk, clrn)  -- enables not needed in sensitivity list
        begin
            if clrn = '0' then
                rg_bit_time  <= (others => '0');
                rg_sample_time  <= (others => '0');
                rg_low_sync  <= (others => '0');
                rg_hi_sync  <= (others => '0');
            elsif rising_edge (clk) then
                if adBTWR = '1' then
                    rg_bit_time <= D;
                end if;
                if adSPWR = '1' then
                    rg_sample_time <= D;
                end if;
                if adLSWR = '1' then
                    rg_low_sync <= D;
                end if;
                if adHSWR = '1' then
                    rg_hi_sync <= D;
                end if;
            end if;
        end process;
end architecture rtl2;

过程语句是 VHDL 中的模拟单元。挂起和恢复的执行开销越少。 rtl2 示例有一个流程语句。它可以在灵敏度列表中没有所有启用的情况下工作,因为它们是在时钟上升沿“采样”的。保留使能的权限来自 IEEE Std 1076.6-2004(现已撤销,RTL Synthesis),该标准描述了边缘敏感时序逻辑的语法和所需的敏感度列表元素。供应商通常会提供他们将支持并保证符合 1076.6 的顺序逻辑形式子集的示例。

首先分析VHDL代码。

(看起来像是 IC 测试仪的一部分。)

【讨论】:

  • 好的,这回答了我的问题。还有一件事,使用 generate 语句不如使用 rtl2 架构?我应该选择rtl2,对吗?感谢您的帮助。
  • Actel 的 generate 语句支持自下而上的设计(带有寄存器原语),这在通过 RTL 综合支持隐含寄存器的 VHDL 中不需要。缺乏 RTL 综合是 AHDL 的一个限制。所有三种架构都会生成等效的网表。最后,当将更多系统设计移植到相同的更高密度现代设备或执行系统仿真时,rtl2 更适合仿真。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-01-09
  • 1970-01-01
相关资源
最近更新 更多