gpt4 book ai didi

debugging - 为什么将其作为一个单独的过程会导致各种怪异

转载 作者:行者123 更新时间:2023-12-04 18:22:31 25 4
gpt4 key购买 nike

我正在学习 VHDL,还有什么比在其中拥有一个项目更好的学习方式。所以,我现在项目的一部分是创建一个小的内存组件。

这是我的完整代码:

entity memory is
port(
Address: in std_logic_vector(15 downto 0); --memory address
Write: in std_logic; --write or read
UseTopBits: in std_logic; --if 1, top 8 bits of data is ignored and not written to memory
Clock: in std_logic;
DataIn: in std_logic_vector(15 downto 0);
DataOut: out std_logic_vector(15 downto 0);
Reset: in std_logic
);
end memory;

architecture Behavioral of memory is
constant SIZE : integer := 4096;
type memorytype is array(0 to (size-1)) of std_logic_vector(7 downto 0);
signal mem: memorytype;

begin
resetmem: process(Clock, Reset) --this process is the troublemaker
begin
if(Reset ='1' and rising_edge(Clock)) then
mem <= (others => "00000000");
end if;

end process;
writemem: process(Reset,Write, Address, UseTopBits, Clock)
variable addr: integer;
begin
addr := conv_integer(Address);
if(addr>size-1) then
addr:=0;
end if;
if(Write='1' and Reset='0') then
if(rising_edge(clock)) then
mem(conv_integer(addr)) <= DataIn(7 downto 0);
if(UseTopBits='1') then
mem(conv_integer(addr)+1) <= DataIn(15 downto 8);
end if;
end if;
end if;
end process;
readmem: process(Reset,Address,Write,Clock)
variable addr: integer;
begin
addr := conv_integer(Address);
if(addr>size-1) then
addr:=0;
end if;
if(Reset='1') then
DataOut <= (others => '0');
elsif(Write='0') then
DataOut <= mem(conv_integer(addr)+1) & mem(conv_integer(addr));
else
DataOut <= (others => '0');
end if;
end process;
end Behavioral;

在添加重置过程之前,根据我的测试台,我的代码运行良好。现在添加它后,我在 DataOut 上得到了各种奇怪的东西.看似随机的位将具有 X 的逻辑状态而不是 01这会导致我所有的测试台都失败(应该如此)

我通过将代码放入 writemem 来修复它过程如下:
begin
--where resetmem process was
writemem: process(Reset,Write, Address, UseTopBits, Clock)
variable addr: integer;
begin
addr := conv_integer(Address);
if(addr>size-1) then
addr:=0;
end if;
if(Reset ='1' and rising_edge(Clock)) then --code is now here
mem <= (others => "00000000");
elsif(Write='1' and Reset='0') then
if(rising_edge(clock)) then
mem(conv_integer(addr)) <= DataIn(7 downto 0);
if(UseTopBits='1') then
mem(conv_integer(addr)+1) <= DataIn(15 downto 8);
end if;
end if;
end if;
end process;

所以这个问题现在已经解决了,但我不明白为什么将 resetmem 作为一个单独的进程会导致所有这些奇怪的问题。任何人都可以阐明这是如何发生的吗?

最佳答案

VHDL 在信号上有这个“驱动程序”的概念。

每个写入信号(或总线的一部分)的进程都会创建一个驱动程序。当多个驱动程序连接到一个信号时,会调用一个“解析函数”来决定结果值应该是什么。碰巧(对于第一个近似值)std_logic 的分辨率函数(因此对于 std_logic_vector s 位)当具有相反值的驱动程序( 10 )被驱动到信号上时会产生 Xs。还有一个值叫做 Z它被视为可以被其他值覆盖的非驱动值。 (还有 WLH ,但我们暂时将它们放在一边,U 用于未初始化)

这个过程:

resetmem: process(Clock, Reset) --this process is the troublemaker 
begin
if(Reset ='1' and rising_edge(Clock)) then
mem <= (others => "00000000");
end if;
end process;

说(转述)

if (reset and clock) then drive zeros to mem




如果条件为假,它没有说明要做什么,因此它继续驱动零(在其余时间)。当您的其他流程驱动值(value)时,它们会发生冲突并产生 X s

出于模拟目的,您可以这样做
else
mem <= (others => 'Z');

这将使其“驱动”另一个过程可以覆盖的高阻抗。

但是我认为您要做的是将 RAM 初始化为全零。 FPGA RAM 不能通过信号重置为特定值,但可以在配置时加载值。模拟器对配置过程一无所知,您的模拟被认为是在配置完成后发生的。

因此,模拟这种行为的一种方法是在声明信号时对其进行初始化:
signal mem: memorytype := (others => (others => '0'));

关于debugging - 为什么将其作为一个单独的过程会导致各种怪异,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10376504/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com