多个 8 位寄存器连接到同一输出 (VHDL)

multipile 8bit registers connected to the same output (VHDL)

我使用两个 3 位地址寄存器创建了一个 64 字节的 RAM,并使用两个 3to8 解码器创建了 3 位寄存器的交叉条。这是 VHDL 代码:

library ieee;
use ieee.std_logic_1164.all;

entity ram88 is
  port(a : in std_logic_vector (2 downto 0);
       s0: in std_logic;
       s1: in std_logic;
       s:  in std_logic;
       e:  in std_logic;
       io_in: in std_logic_vector (7 downto 0);
       io_out:out std_logic_vector (7 downto 0));

end ram88;

architecture behavior of ram88 is

  component reg3 is
    port( a : in std_logic_vector (2 downto 0);
          ss,e : in std_logic; --st and enable
          b : out std_logic_vector (2 downto 0));
  end component;

  component reg8 is
    port( a : in std_logic_vector (7 downto 0);
          ss,e : in std_logic; --st and enable
          b : out std_logic_vector (7 downto 0));
  end component;

  component decod8 is
    port( a : in std_logic_vector (2 downto 0);
          b : out std_logic_vector (7 downto 0));
  end component;

  signal e1 : std_logic := '1';
  signal l0, l1 : std_logic_vector (2 downto 0);
  signal ll0, ll1 : std_logic_vector (7 downto 0);
  type arr2d is array (7 downto 0, 7 downto 0) of std_logic;  
  signal andij, fin_s, fin_e : arr2d;

begin

  e1 <= '1';

  reg0: reg3 port map ( a => a, ss => s0, e => e1, b => l0);
  reg1: reg3 port map ( a => a, ss => s1, e => e1, b => l1);
  decod0: decod8 port map(a => l0, b => ll0);
  decod1: decod8 port map(a => l1, b => ll1);

  mem_blks_ii:
  for ii in 0 to 7 generate
    mem_blks_jj:
    for jj in 0 to 7 generate
      andij(ii,jj) <= ll0(ii) and ll1(jj);
      fin_s(ii,jj) <= andij(ii,jj) and s;
      fin_e(ii,jj) <= andij(ii,jj) and e;
      regij: reg8 port map(a=> io_in, ss=> fin_s(ii,jj), e => fin_e(ii,jj), b => io_out);
    end generate mem_blks_jj;
  end generate mem_blks_ii;


end behavior;

那我就用下面的测试单元来模拟一下。它在内存地址 000x000 处设置值 00000001。最后,它通过设置启用信号来检索值:

library ieee;
use ieee.std_logic_1164.all;

entity ram88_bench is

end ram88_bench;

architecture behavior of ram88_bench is

  component ram88
  port(a : in std_logic_vector (2 downto 0);
       s0: in std_logic;
       s1: in std_logic;
       s:  in std_logic;
       e:  in std_logic;
       io_in: in std_logic_vector (7 downto 0);
       io_out:out std_logic_vector (7 downto 0));
  end component;

  signal abar : std_logic_vector (2 downto 0);
  signal s0bar, s1bar, sbar, ebar:  std_logic;
  signal io_in_bar, io_out_bar: std_logic_vector (7 downto 0);

begin

  ram0: ram88 port map(a=>abar, s0=> s0bar, s1=> s1bar
                       , s=> sbar, e=> ebar
                       , io_in => io_in_bar, io_out=> io_out_bar);

  process
  begin

    -- set (0,1) for access point in memory
    abar <= "000";
    s0bar <= '1';
    s1bar <= '0';
    wait for 2 fs;
    s0bar <= '0';

    abar <= "000";
    s1bar <= '1';
    wait for 2 fs;
    s1bar <= '0';

    -- store the value ...
    ebar <= '1';
    sbar <= '1';
    io_in_bar <= "00000001";
    wait for 2 fs;
    sbar <= '0';

    ---- temporary clear the value before retrieval
    --sbar <= '0';
    --ebar <= '0';
    ---- io_in_bar <= "00000000";    
    --wait for 2 fs;

    --retrieve the value ????
    ebar <= '1';
    sbar <= '0';
    wait for 6 fs;

    wait;

  end process;

end behavior;

问题是 io_out_bar 中的值在模拟结束时被强制为未知数“0X”,而不是预期的 00000001!我不知道为什么,但我猜因为所有 8 位 RAM 寄存器都连接到相同的输出,所以无法确定哪个是我们需要检索的实际值。我该如何解决这个问题?

您的问题不是 Minimal, Complete and Verifiable example,它有助于演示解决方案。一些用于实例化的快速而肮脏的实体:

library ieee;
use ieee.std_logic_1164.all;

entity reg3 is
    port (
        a:      in  std_logic_vector (2 downto 0);
        ss,e:   in  std_logic;
        b:      out std_logic_vector (2 downto 0)
    );
end entity;

architecture foo of reg3 is
begin
    b <= a when ss = '1' and e = '1';
end architecture;

library ieee;
use ieee.std_logic_1164.all;

entity decod8 is
    port (
        a:      in  std_logic_vector (2 downto 0);
        b:      out std_logic_vector (7 downto 0)
    );
end entity;

architecture foo of decod8 is
    use ieee.numeric_std.all;
begin
    process (a)
        variable idx:   natural range 0 to 7;
    begin
        idx := to_integer(unsigned(a));
        b <= (others => '0');
        b(idx) <= '1';
    end process;
end architecture;

library ieee;
use ieee.std_logic_1164.all;

entity reg8 is
    port (
        a:      in  std_logic_vector (7 downto 0);
        ss,e:   in  std_logic;
        b:      out std_logic_vector (7 downto 0)
    );
end entity;

architecture foo of reg8 is
begin
    b <= a when ss = '1' and e = '1';
end architecture;    

... I guess since all 8bit RAM registers are connected to the same output, it can't be determined which one is the real value we need to retrieve. How can I resolve this issue?

你猜对了,所有64 8位寄存器驱动io_out.

这里的想法是根据提供给 RAM 的索引一次 select 一个。该示例使用来自 l0l1 锁存器的相同写入地址,用于 select 64 个 8 位寄存器中的 1 个用于输出。

这里纯粹是在行为上完成的,但可以使用实例化的多路复用器(select或)来完成:

architecture behavior of ram88 is

  component reg3 is
    port( a : in std_logic_vector (2 downto 0);
          ss,e : in std_logic; --st and enable
          b : out std_logic_vector (2 downto 0));
  end component;

  component reg8 is
    port( a : in std_logic_vector (7 downto 0);
          ss,e : in std_logic; --st and enable
          b : out std_logic_vector (7 downto 0));
  end component;

  component decod8 is
    port( a : in std_logic_vector (2 downto 0);
          b : out std_logic_vector (7 downto 0));
  end component;

  signal e1 : std_logic := '1';
  signal l0, l1 : std_logic_vector (2 downto 0);
  signal ll0, ll1 : std_logic_vector (7 downto 0);
  type arr2d is array (7 downto 0, 7 downto 0) of std_logic;  
  signal andij, fin_s, fin_e : arr2d;
  type mux is array (7 downto 0, 7 downto 0) of    -- ADDED
              std_logic_vector (7 downto 0);
  signal mux88: mux;                               -- ADDED
  signal idxii, idxjj:  natural range 0 to 7;      -- ADDED
  use ieee.numeric_std.all;                        -- ADDED

begin

  e1 <= '1';

  idxii <= to_integer(unsigned(l0));              -- ADDED
  idxjj <= to_integer(unsigned(l1));              -- ADDED

  reg0: reg3 port map ( a => a, ss => s0, e => e1, b => l0);
  reg1: reg3 port map ( a => a, ss => s1, e => e1, b => l1);
  decod0: decod8 port map(a => l0, b => ll0);
  decod1: decod8 port map(a => l1, b => ll1);

  mem_blks_ii:
  for ii in 0 to 7 generate
    mem_blks_jj:
    for jj in 0 to 7 generate
      andij(ii,jj) <= ll0(ii) and ll1(jj);
      fin_s(ii,jj) <= andij(ii,jj) and s;
      fin_e(ii,jj) <= andij(ii,jj) and e;
    -- regij: reg8 port map(a=> io_in, ss=> fin_s(ii,jj), e => fin_e(ii,jj), b => io_out);   -- CHANGED 
    regij: reg8 port map(a=> io_in, ss=> fin_s(ii,jj), e => fin_e(ii,jj), b => mux88(ii,jj));        -- CHANGED 
    end generate mem_blks_jj;
  end generate mem_blks_ii;

  io_out <= mux88(idxii, idxjj);    -- ADDED READBACK MUX

end behavior;

这给出了:

RAM 回读。

8 x 8 x 8 位 std_logic_vector 值具有 64 个 b 位值之一 select 由两个添加的索引编辑。如果您要从实例化的组件构建它,综合并计算所有逻辑门的位置,您会发现它与用于 RAM 的锁存器及其扇入缓冲区的大小大致相同,并且比写转向大很多逻辑。