多个 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 一个。该示例使用来自 l0
和 l1
锁存器的相同写入地址,用于 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 的锁存器及其扇入缓冲区的大小大致相同,并且比写转向大很多逻辑。
我使用两个 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 一个。该示例使用来自 l0
和 l1
锁存器的相同写入地址,用于 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 的锁存器及其扇入缓冲区的大小大致相同,并且比写转向大很多逻辑。