【问题标题】:VHDL Quadrature Decoder: Sequential/Combinatorial LogicVHDL 正交解码器:顺序/组合逻辑
【发布时间】:2014-05-28 11:26:40
【问题描述】:

我正在用 VHDL 实现一个正交解码器,并提出了两种解决方案。

在方法 1 中,所有逻辑都放在一个对时钟和复位敏感的进程中。 在 Spartan-3A 上,这使用了四个 slice、七个 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;

当我模拟代码(行为)时,两个结果看起来都很好。但我不敢相信这两种方法同样有效。 有人可以阐明哪种方法应该优于另一种方法吗?

【问题讨论】:

    标签: logic vhdl sequential decoder


    【解决方案1】:

    您的代码版本 2 组合驱动输出,而代码版本 1 注册输出:

    • count_evt
    • count_dir
    • error_evt

    这说明了 3 个额外的触发器(由于 Spartan 3 每个切片有 2 个寄存器意味着您需要 2 个额外的切片)。

    虽然代码执行的逻辑功能相同,但它们的行为不同。如果/当您将输出连接到另一个模块输入时,版本 2 的结果将提前 1 个周期可用。假设下游模块采用这些输入并应用更多逻辑,您将看到版本 2 导致更长的路径,因此可实现的频率更低。

    一些准则规定,您通常应该将输出注册到块中以改进时序。有时您希望能够以组合方式将多个块链接在一起,以便在所有准则中总有一些例外。如果任何输出是组合驱动的,最好在声明中进行注释。如果您感觉特别热衷,可以使用泛型将输出寄存器设为可选。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-01-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-09-05
      • 1970-01-01
      相关资源
      最近更新 更多