VHDL Quadrature Decoder: Sequential/Combinatorial Logic -
i'm implementing quadrature decoder in vhdl , came 2 solutions.
in method 1, of logic placed within 1 process sensitive clock , reset. on spartan-3a, uses 4 slices, 7 ffs , 4 input luts.
code 1
architecture behavioral of quadr_decoder 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') -- 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 , clk_in = '1') -- 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 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) , (chan_b_prev xor chan_b_curr)); end if; end process; end behavioral;
method 2 splits logic separate sequential , combinatorial processes. uses 2 slices, 4 ffs , 4 input luts.
code 2
architecture behavioral of quadr_decoder 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') -- initialize internal signals chan_a_curr <= '0'; chan_a_prev <= '0'; chan_b_curr <= '0'; chan_b_prev <= '0'; elsif (clk_in'event , clk_in = '1') -- 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 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) , (chan_b_prev xor chan_b_curr)); end process; end behavioral;
when simulate code (behavioral), both results fine. can't believe both methods equally valid. shed light method should favored on other?
your code version 2 drives outputs combinatorially whereas code version 1 registers outputs:
- count_evt
- count_dir
- error_evt
this accounts 3 additional flip-flops (and since spartan 3 has 2xregisters per slice means need 2 additional slices).
while logical function performed code identical not behave same. if/when connect outputs blocks inputs result available 1 cycle earlier version 2. assuming downstream block takes these inputs , applies more logic see version 2 results in longer paths , therefore achievable frequency lower.
some guidelines state should register outputs blocks improve timing. want able chain multiple blocks combinatorially guidelines there exceptions. practice comment in declaration if outputs driven combinatorially. if you're feeling particularly keen make output register optional using generic.
Comments
Post a Comment