Debugging 为什么把它作为一个单独的过程会引起各种各样的奇怪

Debugging 为什么把它作为一个单独的过程会引起各种各样的奇怪,debugging,vhdl,Debugging,Vhdl,我正在学习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 dat

我正在学习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;

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

有两个进程同时驱动具有不同非Z值的mem,这就是导致“X”值的原因

此外,如果您计划合成代码,您可能希望查看用于推断触发器的推荐流程模板如果您使用Xilinx ISE,您可以在编辑>语言模板>VHDL>合成构造>编码示例>触发器中找到这些模板。这将帮助您获得复位/时钟启用引脚的正确优先级,以获得高效映射到FPGA硬件的设计

例如:

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;
您的代码将更加干净,并且至少在Xilinx FPGA的情况下,它还应该更好地合成底层硬件


另外,请看一下Ken Chapmans的白皮书。

您有两个进程同时使用不同的非Z值驱动mem,这就是导致“X”值的原因

此外,如果您计划合成代码,您可能希望查看用于推断触发器的推荐流程模板如果您使用Xilinx ISE,您可以在编辑>语言模板>VHDL>合成构造>编码示例>触发器中找到这些模板。这将帮助您获得复位/时钟启用引脚的正确优先级,以获得高效映射到FPGA硬件的设计

例如:

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;
您的代码将更加干净,并且至少在Xilinx FPGA的情况下,它还应该更好地合成底层硬件


另外,请看一下Ken Chapmans的白皮书。

VHDL具有信号驱动程序的概念

为总线写入信号或部分信号的每个进程都会创建一个驱动程序。当多个驱动器连接到一个信号时,将调用一个解析函数,该函数决定结果值。对于一次近似,当具有相反值1和0的驱动器被驱动到一个信号上时,std_逻辑的分辨率函数以及std_逻辑向量的分辨率函数会产生Xs。还有一个称为Z的值,它被视为非驱动值,可以被其他值覆盖。有W,L和H,但我们暂时把它们放在一边,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;
这将使它驱动一个高阻抗,而另一个过程可以覆盖它

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

因此,模拟此行为的一种方法是在声明信号时初始化该信号:

signal mem: memorytype := (others => (others => '0'));

VHDL具有信号驱动程序的概念

为总线写入信号或部分信号的每个进程都会创建一个驱动程序。当多个驱动器连接到一个信号时,将调用一个解析函数,该函数决定结果值。对于一次近似,当具有相反值1和0的驱动器被驱动到一个信号上时,std_逻辑的分辨率函数以及std_逻辑向量的分辨率函数会产生Xs。还有一个称为Z的值,它被视为非驱动值,可以被其他值覆盖。有W,L和H,但我们暂时把它们放在一边,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;
这将使它驱动一个高阻抗,而另一个过程可以覆盖它

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

因此,模拟此行为的一种方法是在声明信号时初始化该信号:

signal mem: memorytype := (others => (others => '0'));

你可以在这里找到更多:-虽然要找到真正好的可能有点难。。。;你可以在这里找到更多:-虽然要找到真正好的可能有点难。。。;