Wednesday, June 1, 2011

Can you guess why multicycle constraints are problematic?

As I have been suffering with synthesis tools that don't analyze clock domains during synthesis, I realized a new aspect to this problem. Have you ever designed a module that uses a multicycle path? Well it can cause you real headaches if you're not careful. Imagine this code:


entity demo_module is
port (
clk : in std_logic;
rstn : in std_logic;

sel : in std_logic;
inputa : in std_logic_vector(7 downto 0);
inputb : in std_logic_vector(7 downto 0);
output : out std_logic_vector(7 downto 0)
);
end entity;

architecture rtl of demo_module is
signal sel_input : std_logic_vector(7 downto 0);
signal input_d : std_logic_vector(7 downto 0);
begin
process(sel, inputa, inputb)
begin
if(sel = '0') then
sel_input <= inputa;
else
sel_input <= inputb;
end if;
end process;

process(clk, rstn)
begin
if(rstn = '0') then
input_d <= (others => '0');
output <= (others => '0');
elsif(clk'event and clk = '1') then
input_d <= sel_input;
output <= sel_input xor input_d;
end if;
end process;
end rtl;

I'm doing nothing complex here. Using sel to select which of the inputs I'm gonna sample and then output the xor of.

Now let's say that it takes 2 cycles to change inputa or inputb, and I make sure that sel only switches every other cycle. This should be valid. Here's where the problem with synthesis tools come in to play. Synthesis tools can use any method they choose for implementing the sel mux. They do not have to use an actual mux. This could be done using a combination of gates / complex gates. What this means is that even when sel is stable on inputa, a change on inputb can cause a glitch (and vice versa). This is unimportant when inputa and inputb are guaranteed to change within a clock, but this is of vital importance when you want to use a multicycle constraint. The fact that inputa and inputb take more than one cycle to change means that at the clock edge when sel doesn't change (and sel is STABLE), inputa / inputb can be changing and thereby cause a glitch on the output of the muxing process (when done without a mux). This will then create an incorrect read of input_d (the sampled value).

Beware!

No comments:

Post a Comment