代码之家  ›  专栏  ›  技术社区  ›  Cactus

为什么数组更新会损坏元素值?

  •  3
  • Cactus  · 技术社区  · 6 年前

    下面的独立VHDL文件是从CLaSH的输出简化而来的,这应该可以解释它有点奇怪的结构。

    s.tup2_sel1(0) 在循环中 s.tup2_sel0 "01" . 然而,我在VHDL模拟器中看到的是 OUTPUT (因此, s、 tup2\u sel1(0) )变为unknoqn(其值为 "XXXXXXXX" )在数组更新之后。为什么数组元素会损坏?

    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.NUMERIC_STD.ALL;
    use work.all;
    
    entity CHIP8 is
      port(-- clock
           CLK    : in std_logic;
           -- asynchronous reset: active high
           RESET  : in std_logic;
           OUTPUT : out unsigned(7 downto 0));
    
      type array_of_unsigned_8 is array (integer range <>) of unsigned(7 downto 0);
    
      type tup2 is record
        tup2_sel0 : std_logic_vector(1 downto 0);
        tup2_sel1 : array_of_unsigned_8(0 to 1);
      end record;
    
    end;
    
    architecture structural of CHIP8 is
      signal y1 : array_of_unsigned_8(0 to 1);
      signal s  : tup2;
      signal s1 : tup2;
      signal y  : array_of_unsigned_8(0 to 1);
      signal x  : unsigned(7 downto 0);
    begin
      y <= s.tup2_sel1;
      x <= y(0);
    
      process(y)
        variable ivec : array_of_unsigned_8(0 to 1);
      begin
        ivec := y;
        ivec(0) := x + 1;
        y1 <= ivec;
      end process;
    
      with s.tup2_sel0 select
        s1 <= (tup2_sel0 => "01", tup2_sel1 => y) when "00",
              (tup2_sel0 => "10", tup2_sel1 => y1) when "01",
              (tup2_sel0 => "10", tup2_sel1 => y) when others;
    
      process(CLK,RESET)
      begin
        if RESET = '1' then
          s <= (tup2_sel0 => "00", tup2_sel1 => array_of_unsigned_8'(0 to 1 => to_unsigned(0,8)));
        elsif rising_edge(CLK) then
          s <= s1;
        end if;
      end process;
    
      OUTPUT <= x;
    end;
    

    RESET 信号:

    LIBRARY ieee;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.NUMERIC_STD.ALL;
    use work.all;
    
    ENTITY TB IS
    END TB;
    
    ARCHITECTURE behavior OF TB IS  
      signal CLK : std_logic := '0';
      signal RESET : std_logic := '0';
      signal OUTPUT : unsigned(7 downto 0);
    
      constant CLK_period : time := 10 ns; 
    BEGIN
      uut: entity work.CHIP8 PORT MAP (
        CLK => CLK,
        RESET => RESET,
        OUTPUT => OUTPUT);
    
      CLK_proc :process
      begin
        CLK <= '0';
        wait for CLK_period/2;
        CLK <= '1';
        wait for CLK_period/2;
      end process;
    
      RESET_proc: process
      begin
        RESET <= '1';     
        wait for CLK_period * 2;
        RESET <= '0';
        wait;
      end process;
    END;
    
    1 回复  |  直到 6 年前
        1
  •  3
  •   Paebbels    6 年前

    信号 x process(y) . 这可能是有意的,但99%的情况下这是个错误。

    因为它是生成的代码,所以我无法判断编写代码发射器的人是否是像我这样聪明的VHDL程序员,他们知道敏感度列表是一种语法糖,或者他们只是错过了向敏感度列表添加更多信号的机会。。。

    敏感度列表是如何翻译的?

    process(y, x)
    begin
      -- some code
    end process;
    

    翻译为:

    process
    begin
      -- some code
      wait on y, x;
    end process;
    

    y 事件,但不是“x”事件。一些VHDL专家可能会用它来优化进程唤醒,其他人则称之为棘手的代码行。


    X 当信号包含元值时,可以生成值,如 U , - , W + 1 已使用。

    我没有看到的任何初始化值 tup2_sel1 ,重置条件除外。