Debugging 为什么把它作为一个单独的过程会引起各种各样的奇怪
我正在学习VHDL,还有什么比在其中进行项目更好的学习方法呢。所以,我的项目现在的部分是创建一个小内存组件 这是我的全部代码: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
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'));
你可以在这里找到更多:-虽然要找到真正好的可能有点难。。。;你可以在这里找到更多:-虽然要找到真正好的可能有点难。。。;