【问题标题】:multipile 8bit registers connected to the same output (VHDL)多个 8 位寄存器连接到同一输出 (VHDL)
【发布时间】:2017-02-28 20:47:36
【问题描述】:

我使用两个 3 位地址寄存器和使用两个 3to8 解码器的 3 位寄存器的交叉开关创建了一个 64 字节的 RAM。这是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 寄存器都连接到同一个输出,因此无法确定哪一个是我们需要检索的真实值。我该如何解决这个问题?

【问题讨论】:

  • 使用多路复用器选择一个。另一种方法是使用三态逻辑,但这在我所知道的任何现代 FPGA 中都无效。

标签: vhdl ram digital-logic


【解决方案1】:

您的问题不是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;

这给出了:

RAM 回读。

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

【讨论】:

  • 谢谢!非常全面的答案!
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2020-11-21
  • 1970-01-01
  • 2014-11-18
  • 2013-06-03
  • 1970-01-01
相关资源
最近更新 更多