Nat*_*ate 1 fpga vhdl modelsim quartus
我是一名学习VHDL的学生,并且有一个非常基本的问题.
我已经读过,信号分配不会立即发生.所以以下内容不会按预期工作:
x <= y;
z <= not x;
Run Code Online (Sandbox Code Playgroud)
所以我理解分配不是立即/不按顺序发生,但我有一个关于将信号传递给实体的问题.假设我有以下代码:
architecture struct of mips is
begin
controller: entity work.controller port map(opD => instrD(31 downto 26),
functD => instrD(5 downto 0));
datapath: entity work.dataPath port map(opD => instrD(31 downto 26),
functD => instrD(5 downto 0));
end;
Run Code Online (Sandbox Code Playgroud)
我习惯于尝试避免代码重复和其他语言的硬编码,因此上面代码中的硬编码opD和functD值很困扰我.
我想知道的是,如果我可以将这些值分配给内部信号,如下所示:
architecture struct of mips is
signal opD: STD_LOGIC;
signal functD: STD_LOGIC;
begin
signal opD <= instrD(31 downto 26);
signal functD <= instrD(5 downto 0);
controller: entity work.controller port map(opD => opD,
functD => functD);
datapath: entity work.dataPath port map(opD => opD,
functD => functD);
end;
Run Code Online (Sandbox Code Playgroud)
这是否会按预期工作(即工作与上面的代码块完全相同),或者是否会因使用信号导致两个代码块功能不同而导致某种"延迟"?
我已经读过,信号分配不会立即发生.
这是事实,但我认为你错过了一个重要的观点,即知道它们何时发生.当生成它们的进程遇到wait语句或结束时(由于在进程结束时对进程敏感性列表存在隐式等待),信号会更新.
因此,如果您将它放在一个时钟进程中,那么您的示例将无法像您期望的那样工作,但在具有正确灵敏度列表的组合过程中完全有效.
architecture rtl of example is
signal y_r : std_logic;
signal z_r : std_logic;
signal y : std_logic;
signal z : std_logic;
begin
y <= x; -- immediately updated when x changes
z <= not y; -- immediately updated when y changes, equivalent to z <= not x
process(clk)
begin
if rising_edge(clk) then
y_r <= x; -- y is updated when the clock rise, once this process finishes
z_r <= not y_r; -- y still have the value it had when the process started executing
end if;
end process;
end architecture rtl;
Run Code Online (Sandbox Code Playgroud)
因此,除了语法错误之外,您的最后一个示例将按预期工作.有一个简洁的语法,更好的恕我直言,但:
architecture struct of mips is
alias opD is instrD(31 downto 26);
alias functD is instrD(5 downto 0);
begin
controller: entity work.controller port map(opD => opD,
functD => functD
datapath: entity work.dataPath port map(opD => opD,
functD => functD;
end;
Run Code Online (Sandbox Code Playgroud)