我希望这是在正确的地方,但是因为我认为它是语法而不是实际系统设计的问题,可能就是这样。
出于某种原因,当我将其留在流程之外时,我会忽略一条语句。我可以将同一个语句复制/粘贴到一个进程中然后突然就可以了。但是它必须等待时钟信号,这会弄乱整个事情。
architecture CU of CONTROL_UNIT is
type OPCODE_ARRAY is array(3 downto 0) of std_logic_vector(3 downto 0);
signal OPCODES : OPCODE_ARRAY;
begin
OPCODES(3) <= OPCODE_IN; --problem statement!
process(CLK)
begin
if rising_edge(CLK) then
for I in 0 to 2 loop
OPCODES(I) <= OPCODES(I + 1);
end loop;
end if;
end process;
--more code
end CU;
如果我像这样模拟它,我会遇到这种我不明白的情况:
注意OPCODE_IN是D但是OPCODES(3)仍然是U。
如果我在进程中移动语句,它会将OPCODE_IN的值移到OPCODES(3)中,但当然需要另一个时钟周期来扰乱所有内容的时间:
architecture CU of CONTROL_UNIT is
type OPCODE_ARRAY is array(3 downto 0) of std_logic_vector(3 downto 0);
signal OPCODES : OPCODE_ARRAY;
begin
process(CLK)
begin
if rising_edge(CLK) then
for I in 0 to 2 loop
OPCODES(I) <= OPCODES(I + 1);
end loop;
OPCODES(3) <= OPCODE_IN; --problem statement!
end if;
end process;
--more code
end CU;
有没有人知道为什么这样做?
答案 0 :(得分:1)
总结评论中的答案:
第一个示例中的过程将为来自OPCODES(I)的最长静态前缀(即OPCODES)的所有信号创建驱动程序。所以OPCODES(0)也会有驱动程序。但是在你的过程中没有OPCODES(0)的赋值,因此它是&#39; U&#39;
当您将OPCODES(3) <= OPCODE_IN;
放入流程时,您可以进行分配,问题就解决了。
展开循环时,分配的最长静态前缀变为OPCODES(1)
,OPCODES(2)
和OPCODES(3)
,而不是OPCODES
。所以你不再拥有OPCODES(0)
的驱动程序,问题再次得到解决。
答案 1 :(得分:1)
这是VHDL变得非常反直觉的怪癖之一。由于其他并行处理语言没有它,因此特别令人困惑。
另一种解决方案是使用generate-statement。
architecture CU of CONTROL_UNIT is
type OPCODE_ARRAY is array(3 downto 0) of std_logic_vector(3 downto 0);
signal OPCODES : OPCODE_ARRAY;
begin
OPCODES(3) <= OPCODE_IN; --problem statement!
some_label: for I in 0 to 2 generate
OPCODES(I) <= OPCODES(I + 1) when rising_edge(clk);
end generate;
--more code
end architecture;
有趣的是,在这种情况下,OPCODES(I)
突然再次成为静态表达式。非常一致,是吗? ;)