使用 generate 语句在 VHDL 中创建 'n' 寄存器数组
Use generate statement to create 'n' array of registers in VHDL
我正在将旧的 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,但是如何使用生成器创建 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;
谢谢。
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)。 return 值将是 q 输出(并且在 AHDL 生成语句中未提及)。具有函数原型关联的名称有四种赋值。这代表四个 18 个触发器的数组。
DFFE 寄存器的函数原型显示在 Altera Hardware Description Language (AHDL) Language Reference Manual,第 3 节,原语,触发器和锁存器原语,Table 3-9 中。 MAX+PLUS II 人字拖和门锁:
其中 return 值将与 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 示例有一个过程语句。它可以在灵敏度列表中没有所有启用的情况下工作,因为它们在时钟上升沿上为 'sampled'。保留启用的权限来自 IEEE 标准 1076.6-2004(现已撤销,RTL 综合),它描述了边沿敏感时序逻辑的语法和所需的敏感度列表元素。供应商通常会提供他们将支持并保证符合 1076.6 的时序逻辑形式子集的示例。
上面的VHDL代码全部分析。
(看起来像 IC 测试仪的一部分。)
我正在将旧的 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,但是如何使用生成器创建 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;
谢谢。
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)。 return 值将是 q 输出(并且在 AHDL 生成语句中未提及)。具有函数原型关联的名称有四种赋值。这代表四个 18 个触发器的数组。
DFFE 寄存器的函数原型显示在 Altera Hardware Description Language (AHDL) Language Reference Manual,第 3 节,原语,触发器和锁存器原语,Table 3-9 中。 MAX+PLUS II 人字拖和门锁:
其中 return 值将与 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 示例有一个过程语句。它可以在灵敏度列表中没有所有启用的情况下工作,因为它们在时钟上升沿上为 'sampled'。保留启用的权限来自 IEEE 标准 1076.6-2004(现已撤销,RTL 综合),它描述了边沿敏感时序逻辑的语法和所需的敏感度列表元素。供应商通常会提供他们将支持并保证符合 1076.6 的时序逻辑形式子集的示例。
上面的VHDL代码全部分析。
(看起来像 IC 测试仪的一部分。)