是否有必要在 VHDL 中编码时将组合逻辑与顺序逻辑分开,同时针对综合?

Gau*_*ngh 7 vhdl register-transfer-level soc asic

我正在从事需要综合我的 RTL 代码专门用于 ASIC 开发的项目。鉴于这种情况,在设计我的 RTL 时将时序逻辑与差分逻辑分开有多重要?如果这很重要,那么我在设计时应该采用什么方法,好像我应该如何区分顺序逻辑和组合逻辑的设计?

Mat*_*lor 3

一般来说,我会毫不犹豫地将组合与顺序逻辑混合在一起。我有 IC 设计背景,总是将组合逻辑与顺序逻辑混为一谈。我认为,如果您不这样做并且没有充分利用逻辑合成器的功能,那么您就限制了自己太多。

例如,以下是我如何用 VHDL 设计一个简单的异步重置计数器:

  process (Clock, Reset)
  begin
    if Reset = '1' then
      Cnt <= (others => '0');
    elsif Rising_edge(Clock) then
      if Enable = '1' then
          Cnt <= Cnt + 1;
      end if;
    end if;
  end process;
Run Code Online (Sandbox Code Playgroud)

这种用 VHDL 编写计数器的风格是普遍存在的。我个人认为将代码分成两个单独的进程(一个是顺序的,另一个是组合的)没有任何优势。我刚刚教了一屋子的工程师以这种方式设计柜台。

以下是一些例外情况。如果满足以下条件,我会将组合逻辑与顺序逻辑分开:

i)我正在设计一个状态机:

我认为这是一种非常优雅的状态机编码方式,您可以将组合逻辑与顺序逻辑分开:

  Registers: process (Clock, Reset)
  begin
    if Reset = '1' then
      State <= Idle;
    elsif Rising_edge(Clock) then
      State <= NextState;
    end if;
  end process Registers;

  Combinational: process (State, Inputs)
  begin
    NextState <= State;
    Output1 <= '0';
    Output2 <= '0';
    -- etc
    case State is
      when Idle =>
        if Inputs(1) = '1' then
          NextState <= State2;
        end if;
      when State2=>
        Output1 <= '1';
        if Inputs = "00" then
          NextState <= State3;
        end if;
      -- etc
    end case;
  end process Combinational;
Run Code Online (Sandbox Code Playgroud)

像这样编码状态机的优点是组合过程看起来非常像状态图。写入时不易出错,修改时不易出错,读取时不易出错。

ii) 组合逻辑很复杂:

对于真正大的组合逻辑块,我会分开。“真正大”的确切定义是一个判断问题。

iii) 组合逻辑位于触发器的 Q 输出上:

在顺序过程中驱动的任何信号都可称为触发器。因此,如果您希望实现驱动实体*输出的组合逻辑,则该组合逻辑必须位于单独的进程中。

*通常不是一个好主意——要小心。