我正在用VHDL实现正交解码器,并提出了两种解决方案。
在方法1中,所有逻辑都放在一个对时钟和复位敏感的进程中。 在Spartan-3A上,它使用四个切片,七个FF和四个输入LUT。
代码1
architecture Behavioral of quadr_decoder is
signal chan_a_curr : std_logic;
signal chan_a_prev : std_logic;
signal chan_b_curr : std_logic;
signal chan_b_prev : std_logic;
begin
process (n_reset, clk_in) begin
if (n_reset = '0') then
-- initialize internal signals
chan_a_curr <= '0';
chan_a_prev <= '0';
chan_b_curr <= '0';
chan_b_prev <= '0';
-- initialize outputs
count_evt <= '0';
count_dir <= '0';
error_evt <= '0';
elsif (clk_in'event and clk_in = '1') then
-- keep delayed inputs
chan_a_prev <= chan_a_curr;
chan_b_prev <= chan_b_curr;
-- read current inputs
chan_a_curr <= chan_a;
chan_b_curr <= chan_b;
-- detect a count event
count_evt <= ((chan_a_prev xor chan_a_curr) xor
(chan_b_prev xor chan_b_curr));
-- determine count direction
count_dir <= (chan_a_curr xor chan_b_prev xor
count_mode);
-- detect error conditions
error_evt <= ((chan_a_prev xor chan_a_curr) and
(chan_b_prev xor chan_b_curr));
end if;
end process;
end Behavioral;
方法2将逻辑分成单独的顺序和组合过程。它使用两个切片,四个FF和四个输入LUT。
代码2
architecture Behavioral of quadr_decoder is
signal chan_a_curr : std_logic;
signal chan_a_prev : std_logic;
signal chan_b_curr : std_logic;
signal chan_b_prev : std_logic;
begin
process (n_reset, clk_in) begin
if (n_reset = '0') then
-- initialize internal signals
chan_a_curr <= '0';
chan_a_prev <= '0';
chan_b_curr <= '0';
chan_b_prev <= '0';
elsif (clk_in'event and clk_in = '1') then
-- keep delayed inputs
chan_a_prev <= chan_a_curr;
chan_b_prev <= chan_b_curr;
-- read current inputs
chan_a_curr <= chan_a;
chan_b_curr <= chan_b;
end if;
end process;
process (chan_a_prev, chan_a_curr, chan_b_prev, chan_b_curr) begin
-- detect a count event
count_evt <= ((chan_a_prev xor chan_a_curr) xor
(chan_b_prev xor chan_b_curr));
-- determine count direction
count_dir <= (chan_a_curr xor chan_b_prev xor count_mode);
-- detect error conditions
error_evt <= ((chan_a_prev xor chan_a_curr) and
(chan_b_prev xor chan_b_curr));
end process;
end Behavioral;
当我模拟代码(行为)时,两个结果看起来都很好。但我无法相信这两种方法同样有效。 有人可以说明哪种方法比另一种方法更受欢迎?
答案 0 :(得分:4)
您的代码版本2组合驱动输出,而代码版本1注册输出:
这说明了另外3个触发器(因为Spartan 3每个片有2个寄存器意味着你需要2个额外的片)。
虽然代码执行的逻辑功能相同但它们的行为不同。如果/当您将输出连接到另一个块输入时,结果将在版本2的前一个周期可用。假设下游块采用这些输入并应用更多逻辑,您将看到版本2导致更长的路径,因此可实现的频率低了。
一些指导原则规定您通常应将输出注册到块以改善时序。有时您希望能够将多个块组合在一起,因此所有指南总是有一些例外。如果任何产出是组合驱动的,那么在声明中作出评论是一种好的做法。如果您感觉特别敏锐,可以使用通用的输出寄存器。