【问题标题】:Persisting an output in comb logic block保持梳状逻辑块中的输出
【发布时间】:2014-06-27 05:46:47
【问题描述】:

我在保留 gpo 的值时遇到问题。 我希望它只在下面代码中的点进行更改。

gpo_int <= gpo_int when n_wr = '1';
gpo <= gpo_int;
write : process(n_en, n_wr) begin
  if n_wr = '0' and n_en='0' then
    case addr(15 downto 12) is
      when x"f" => -- i/o
        case addr(11 downto 8) is
          when x"0" => -- gpo
            gpo_int <= data;
          when others =>
            gpo_int <= gpo_int;
        end case;
      when others =>
        gpo_int <=  gpo_int;
    end case;
  end if;
end process;

gpo_int 是 std_logic_vector(7 downto 0) 的信号:= x"00";

首先 gpo_int 没有正确持久化(当 n_rw 变为 '1' 时,我可以看到 gpo 更改为 x"00"。还有什么方法可以更巧妙地做到这一点(为梳状逻辑定义真值表)?

【问题讨论】:

    标签: hardware vhdl fpga


    【解决方案1】:

    您似乎在要求一个闩锁。特别是在 FPGA 中,这通常不是正确的做法(出于各种原因)。

    您不能使用时钟进程来使用触发器创建所需的持久性吗?

    process (clk)
    begin
        if rising_edge(clk) then
            if n_wr = '0' and n_en ='0' and addr(11 downto 8) = x"F0" then
               gpo_int <= data;
            end if;
         end if;
    end process;
    gpo <= gpo_int;
    

    【讨论】:

      【解决方案2】:

      每个分配信号的并发语句都有该信号的驱动程序。并发信号赋值(在本例中为条件信号赋值)是并发语句。进程是并发语句。

      所以有两个驱动:

      gpo <= gpo_int;
      

      和:

      write : process
      

      std_logic_vector 是一种已解析的数据类型。 std_logic_vector 信号gpo_int 的有效值是其所有驱动程序的解析值(您有两个显示)。对于gpo_int 的每个元素,来自两个驱动程序中的每一个的相应值用于通过使用包std_logic_1164 主体中定义的分辨率表查找两个值的交点处的值来确定gpo_int 的有效值:

      CONSTANT resolution_table : stdlogic_table := (
      --      ---------------------------------------------------------
      --      |  U    X    0    1    Z    W    L    H    -        |   |
      --      ---------------------------------------------------------
              ( 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U', 'U' ), -- | U |
              ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' ), -- | X |
              ( 'U', 'X', '0', 'X', '0', '0', '0', '0', 'X' ), -- | 0 |
              ( 'U', 'X', 'X', '1', '1', '1', '1', '1', 'X' ), -- | 1 |
              ( 'U', 'X', '0', '1', 'Z', 'W', 'L', 'H', 'X' ), -- | Z |
              ( 'U', 'X', '0', '1', 'W', 'W', 'W', 'W', 'X' ), -- | W |
              ( 'U', 'X', '0', '1', 'L', 'W', 'L', 'W', 'X' ), -- | L |
              ( 'U', 'X', '0', '1', 'H', 'W', 'W', 'H', 'X' ), -- | H |
              ( 'U', 'X', 'X', 'X', 'X', 'X', 'X', 'X', 'X' )  -- | - |
          );
      

      因此,当它们的对应元素不解析相同的值时,存储值 (gpo_int &lt;= gpo_int when n_wr = '1') 和进程中分配的值可能会导致冲突。

      例如,如果一个驱动程序的gpo_int(7)'1',而另一个驱动程序是'0',则该元素的解析值为'X'

      如果你想把gpo_int当作一个latch试试:

      gpo <= gpo_int;
      
      WRITE:
          process (n_en, n_wr, data)
              begin
              if n_wr = '0' and n_en ='0' and addr(11 downto 8) = x"F0" then
                  gpo_int <= data;
              else
                  gpo_int <= gpo_int;  -- the else clause is optional for some synthesis tools
              end if;
      
          end process;
      

      忘记gpo_int 的并发信号赋值语句。当 if 语句中的三个条件都为真时,分配给gpo_int 的流程语句保留其值 accept。

      data 列在敏感度列表中的原因是它在n_wrn_en 之后转换。

      您可以在现已废除的 IEEE Std 1076.6-2004 6.2.1.1 级别敏感存储中从带有敏感度列表的进程中找到推断锁存器的公认方法的描述,或描述支持的 VHDL 语言结构的供应商文档。

      通常,系统会通过确保其中一个转向信号(在这种情况下为n_wrn_en)在其他信号转换(例如addr 是稳定的)。是的,您可以在零时间模型中获得一个 delta 周期长的组合事件。

      【讨论】:

      • 非常感谢您的解释。我采取了简单的方法并将整个设计更改为顺序。它更简单,因为我有许多其他具有相同问题的信号(不仅仅是 gpo)。它解决了所有问题,但我仍然想学习 - 你的回答已经在我脑海中解决了。我什至可以在某个时候按照您的建议尝试实施它,以确保我得到它!
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多