我正在从root学习VHDL,除此之外一切正常。我从互联网上找到了这个。这是左移位寄存器的代码。
library ieee;
use ieee.std_logic_1164.all;
entity lsr_4 is
port(CLK, RESET, SI : in std_logic;
Q : out std_logic_vector(3 downto 0);
SO : out std_logic);
end lsr_4;
architecture sequential of lsr_4 is
signal shift : std_logic_vector(3 downto 0);
begin
process (RESET, CLK)
begin
if (RESET = '1') then
shift <= "0000";
elsif (CLK'event and (CLK = '1')) then
shift <= shift(2 downto 0) & SI;
end if;
end process;
Q <= shift;
SO <= shift(3);
end sequential;
我的问题是从底部开始的第三行。我的问题是,为什么我们需要将内部信号值传递给输出?或者换句话说,如果我写Q <= shift (2 downto 0) & SI
会出现什么问题?
答案 0 :(得分:1)
对于显示的代码,Q
实体的lsr_4
输出来自寄存器(shift
表示寄存器阶段并连接到Q
) 。如果您按照建议编写代码,SI
输入将直接(即组合地)连接到Q
输出。这也可以工作(假设您保留其余的代码),它将执行相同的操作逻辑上预期消除一个时钟周期延迟。然而,(通常)认为良好的设计实践是注册实体的输出,以便不引入长的“隐藏”组合路径,这些路径在不查看实体内部时是不可见的。它通常使设计更容易,并避免遇到计时问题。
答案 1 :(得分:1)
首先,这只是一个移位寄存器,因此不应推断出组合块(输入和输出缓冲区除外,它们与I / O相关,与电路本身无关)。
其次,通过将Q指定为“缓冲区”而不是“out”,可以完全消除称为“移位”的信号(这是必需的,因为Q将出现在表达式的两侧;“缓冲区”没有副作用推断电路)。您的代码建议如下。
注意:编译代码后,请在Netlist Viewers / Technology Map Viewer工具中查看实际实现的内容。
library ieee;
use ieee.std_logic_1164.all;
entity generic_shift_register is
generic (
N: integer := 4);
port(
CLK, RESET, SI: in std_logic;
Q: buffer std_logic_vector(N-1 downto 0);
SO: out std_logic);
end entity;
architecture sequential of generic_shift_register is
begin
process (RESET, CLK)
begin
if (RESET = '1') then
Q <= (others => '0');
elsif rising_edge(CLK) then
Q <= Q(N-2 downto 0) & SI;
end if;
end process;
SO <= Q(N-1);
end architecture;