首页 文章

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

提问于
浏览
0

我使用两个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;

然后我使用以下测试单元进行模拟 . 它将值00000001设置为内存地址000x000 . 最后,它通过设置启用信号来检索值:

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寄存器都连接到同一输出,所以无法确定哪一个是我们需要检索的实际值 . 我该如何解决这个问题?

1 回答

  • 3

    你're question isn' t 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;
    

    ...我想因为所有8位RAM寄存器都连接到同一输出,所以无法确定哪一个是我们需要检索的实际值 . 我该如何解决这个问题?

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

    这里的想法是根据提供给RAM的索引一次只选择一个 . 该示例使用 l0l1 锁存器中相同的写地址,用于选择64个8位寄存器中的1个作为输出 .

    它完全是在行为上完成的,但可以使用实例化的多路复用器(选择器)来完成:

    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;
    

    这给了:

    ram88_bench_fixed.png

    RAM回读 .

    8乘8乘8位std_logic_vector值具有由两个添加的索引选择的64个b位值之一 . 如果你要从实例化组件构造它,合成并计算所有逻辑门的位置,你会发现它与用于RAM及其扇入缓冲区的锁存器大小相同,并且比写入转向大得多逻辑 .

相关问题