可以多次使用信号代替硬编码值吗?
Can signals be used instead of hard coding values multiple times?
我是一名学习 VHDL 的学生,有一个非常基本的问题。
我了解到信号分配不会立即发生。所以以下不会按预期工作:
x <= y;
z <= not x;
所以我知道分配不是立即发生的/不会按顺序发生,但我对向实体传递信号有疑问。假设我有以下代码:
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;
我习惯于尝试避免代码重复和使用其他语言进行硬编码,因此对上述代码中的 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;
这是否会按预期工作(即与上述代码块完全相同的工作方式),或者是否会因使用使两个代码块起作用的信号而导致某种 "delay"不同?
I've read that signal assignments don't take place immediately.
这是事实,但我认为您忽略了重要的一点,那就是要知道它们何时发生。当生成信号的进程遇到等待语句或结束时,信号会更新(因为在进程末尾的进程敏感列表上有一个隐式等待)。
因此,如果将您的示例放入时钟进程中,您的示例将不会像您预期的那样工作,但在具有正确敏感度列表的组合进程中完全有效。
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;
因此,除了语法错误之外,您的最后一个示例将按您的预期运行。不过,恕我直言,有一种简洁的语法更好:
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;
我是一名学习 VHDL 的学生,有一个非常基本的问题。
我了解到信号分配不会立即发生。所以以下不会按预期工作:
x <= y;
z <= not x;
所以我知道分配不是立即发生的/不会按顺序发生,但我对向实体传递信号有疑问。假设我有以下代码:
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;
我习惯于尝试避免代码重复和使用其他语言进行硬编码,因此对上述代码中的 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;
这是否会按预期工作(即与上述代码块完全相同的工作方式),或者是否会因使用使两个代码块起作用的信号而导致某种 "delay"不同?
I've read that signal assignments don't take place immediately.
这是事实,但我认为您忽略了重要的一点,那就是要知道它们何时发生。当生成信号的进程遇到等待语句或结束时,信号会更新(因为在进程末尾的进程敏感列表上有一个隐式等待)。
因此,如果将您的示例放入时钟进程中,您的示例将不会像您预期的那样工作,但在具有正确敏感度列表的组合进程中完全有效。
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;
因此,除了语法错误之外,您的最后一个示例将按您的预期运行。不过,恕我直言,有一种简洁的语法更好:
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;