Search code examples
vhdlmodelsimquartusregister-transfer-level

Why does the output signals post-synthesis not work as usual?


I had written a small VHD file for simulating the behavior of a quadrature decoder, enclosed below. Simulating the design with a generic testbench works as expected. But after generating a synthesizable design with Quartus, I run into one of two problems (while playing with using unsigned, for example)
1. The position and direction signal are always at a constant 0 value throughout the post-synthesis simulation.
2. The position value seems to jump 10 values every 3-4 clock cycles, which I attribute to some jitter in data.
Does anyone have any recommendations to solve this issue? Is this mainly a timing problem or is there a major flaw in my design?

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.NUMERIC_STD.ALL;

entity quad_decoder is
  port(rst   : in  std_logic;
       clk   : in  std_logic;
       a    : in  std_logic;
       b    : in  std_logic;
       direction : out std_logic;
       position : out std_logic_vector(8 DOWNTO 0));
end quad_decoder;


architecture behavioral of quad_decoder is
begin
    process(clk)
        variable counter : integer range 0 to 360 := 0;
        variable chanA,chanB : std_logic;
        variable int_direction : std_logic; 
            begin
                if (rst = '0') then 
                    int_direction := '0';
                    counter := 0;
                elsif (rising_edge(clk)) then                   
                    chanA := a;
                    chanB := b;
                    if (chanA = '1') and (chanB = '0') then
                        if (counter = 360) then
                            counter := 0;
                        else
                            counter:= counter + 1;
                        end if;
                        int_direction := '1';
                    elsif (chanA = '0') and (chanB = '1') then
                        if (counter = 0) then 
                            counter := 360; 
                        else 
                            counter := counter-1;
                        end if;
                        int_direction := '0';
                    else
                        counter := counter;
                        int_direction := int_direction;
                    end if;
                    position <= std_logic_vector(to_unsigned(counter,9));
                    direction <= int_direction;
                end if;
    end process;
end behavioral;

The expected pre-synthesis snap is here.

I've linked an example snap of the post-synthesis simulation here. As seen, no change to position nor direction in multiple clock cycles.


Solution

  • If anyone is inquisitive, doing assignments right at the clock edge as well as turning the reset signal high proved to introduce all kinds of timing issues, which passed the multi-corner timing analysis test, but failed other tests in Quartus that I had failed to notice.

    I can go into more details if my answer is vague.