分配记录 VHDL

Assigning Records VHDL

大家好。

最近我尝试在新项目中改进代码并发现了一些有趣的解码器。 它有两个过程:第一个是所有数据形成,第二个是所有总线通过控制信号触发输入输出寄存器。但是有些电线需要在一段时间内重新设置(在第二个过程中)。

所以我决定编写此代码以正确重新设置一些信号([cm_regA/cm_regB] 是具有不同类型数据的记录):

----------------------------------------
LOAD_DATA_PROCESS: process(clk_i)
begin
  if rising_edge(clk_i) then
    if (reset_reg) then
      cm_regB.reg_1 <= '0';
      cm_regB.reg_2 <= '0';
      cm_regB.reg_3 <= '0';
      cm_regB.reg_4 <= '0';
    else
      if (load_reg) then
        cm_regB <= cm_regA;
      else null;
      end if;
    end if;
  end if;
end process;
----------------------------------------

但是这个结构在 reg_5...reg_10 之间合成了很多多路复用器,所以下一个代码给我很好的合成结构和很快的速度:

----------------------------------------
LOAD_DATA_PROCESS: process(clk_i)
begin
  if rising_edge(clk_i) then
    if (reset_reg) then
      cm_regB.reg_1 <= '0';
      cm_regB.reg_2 <= '0';
      cm_regB.reg_3 <= '0';
      cm_regB.reg_4 <= '0';
    else
      if (load_reg) then
        cm_regB.reg_1 <= cm_regA.reg_1;
        cm_regB.reg_2 <= cm_regA.reg_2;
        cm_regB.reg_3 <= cm_regA.reg_3;
        cm_regB.reg_4 <= cm_regA.reg_4;
      else null;
      end if;
    end if;

    if (load_reg) then
      cm_regB.reg_5  <= cm_regA.reg_5;
      cm_regB.reg_6  <= cm_regA.reg_6;
      cm_regB.reg_7  <= cm_regA.reg_7;
      cm_regB.reg_8  <= cm_regA.reg_8;
      cm_regB.reg_9  <= cm_regA.reg_9;
      cm_regB.reg_10  <= cm_regA.reg_10;
    else null;
    end if;

  end if;
end process;
----------------------------------------

接下来的问题是:

  1. 如何使这个结构更紧凑(如第一个示例)?
  2. 或者如何使总线 [cm_regA/cm_regB] 中的任何更改在第二个示例中可见(以防更改第一个进程而忘记将此更改添加到 LOAD_DATA_PROCESS)?

P.S。 cm_regA 和 cm_regB 的类型在包中声明。这是:

----------------------------------------
type cm_t is record
    reg_1   : STD_LOGIC;
    reg_2   : STD_LOGIC;
    reg_3   : STD_LOGIC;   
    reg_4   : STD_LOGIC;
    reg_5   : STD_LOGIC;
    reg_6   : BOOLEAN;
    reg_7   : STD_LOGIC;
    reg_8   : STD_LOGIC;
    reg_9   : STD_LOGIC_VECTOR(CONST_1-1 downto 0);
    reg_10  : STD_LOGIC_VECTOR(CONST_2-1 downto 0);
end record cm_t;
----------------------------------------

对于您的第一个代码,您确实在 reset 中添加了对 reg_5reg_10 的依赖。这是因为 if-else 语句。这是您为这些寄存器编写的有效代码。

if not(reset_reg) and load_reg then
    cm_regB.reg_5 <= cm_regA.reg_5;
    [...]
    cm_regB.reg_10 <= cm_regA.reg_10;
end if;

因此,您应该将重置块与其他作业分开。您可以通过以下事实实现这一点:对于信号 只有进程中的最后一个分配 将应用于下一个增量循环。所以像这样:

LOAD_DATA_PROCESS: process(clk_i)
begin
    if rising_edge(clk_i) then
        if load_reg then
            cm_regB <= cm_regA;
        end if;
        if reset_reg then
            cm_regB.reg_1 <= '0';
            cm_regB.reg_2 <= '0';
            cm_regB.reg_3 <= '0';
            cm_regB.reg_4 <= '0';
        end if;
    end if;
end process;