Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
15 years ago

Simulation fails when it goes into big design.

Ok guys, I have designed a small block that does some counting and put some signals to zero while its counting..


library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
--use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.NUMERIC_STD.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
ENTITY deadband  IS
PORT (
        CLKOUT: IN STD_LOGIC;
        T3PWM: IN STD_LOGIC;
        PWMB7: OUT STD_LOGIC;
        PWMB8: OUT STD_LOGIC
        );
END deadband;
ARCHITECTURE identifier OF deadband IS
signal EVBCONDB_reg : UNSIGNED (7 downto 0) := "00011000";
signal PWMB7_DB_reg : STD_LOGIC;
signal PWMB8_DB_reg : STD_LOGIC;
BEGIN
  PWMB7 <= PWMB7_DB_reg;
  PWMB8 <= PWMB8_DB_reg;
-- T3PWM Deadband
-----------------
    process(CLKOUT,EVBCONDB_reg)
    variable prev_T3PWM    : STD_LOGIC;
    variable counter_en    : STD_LOGIC;
    variable count : UNSIGNED (8 downto 0);
    variable multiplier : UNSIGNED (2 downto 0);
    begin
    
        case EVBCONDB_reg(2 downto 0) is        
            when "110" => multiplier := "101"; -- /1 divisor
            when "111" => multiplier := "101";    -- /2 divisor
            when others => multiplier := EVBCONDB_reg(2 downto 0);    -- /32 default
        end case;
        if(rising_edge(CLKOUT)) then
-- if we see a transition, start the clock and enable deadband
            if(prev_T3PWM /= T3PWM) then
                counter_en := '1';
                --count := EVBCONDB_reg(6 downto 3) * multiplier;
                count := "00000" & EVBCONDB_reg(6 downto 3);
                count := count sll TO_INTEGER(multiplier);
            end if;
                
-- if we've reached 0, stop counting and disable deadband
            if(count = "000000000") then
                counter_en := '0';
-- else decrement counter by one
            else
                count := count - 1;
            end if;
-- remember T3PWM for next time
            prev_T3PWM := T3PWM;
-- and output delayed PWM outputs
            PWMB7_DB_reg    <= T3PWM and not counter_en;
            PWMB8_DB_reg    <= not T3PWM and not counter_en;
        end if; -- if rising_edge(CLKOUT)
    end process;
        
END identifier;
When it is in its own project, the timing simulation would show that it's all good.

However, when I incorporate it into the big project, the timing simulation would fail, however the functional simulation shows that it does what its supposed to do.

Then I thought its a timing problem, but the compilation flow summary says all timing requirements have been met. So what's up?

Note: Within the failed timing simulation results, this thing doesn't stop counting and the counts are not normal, once in awhile it would jump to a number far away (not wraparound).

Thanks.

17 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Could you give a bit more details about your system? Is the input serial or parallel? If your logic is synchronized on clkout but not the input, did you include synchronization stages to avoid metastability issues?

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    Input is serial and all I care is if its changing. That's it.

    And whenever the input changes, I want to start the clock. That's it.

    How to handle the metastability problem? I don't know. Thanks for helping me out
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    What do you mean by "start the clock"?

    Have a look at this document (http://www.altera.com/literature/wp/wp-01082-quartus-ii-metastability.pdf) from Altera that explains a few things about metastability. I think you should create a false path on your input signal in your timing requirements, so that Quartus doesn't have to try to meet any setup/hold requirements you don't need, and add a two registers chain between the input and your logic. Have a look at figure 3, and imagine that "Clock 2 domain" is your logic in the FPGA, and "clock 1 domain" is the signal source outside the FPGA.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    Input is serial and all I care is if its changing. That's it.

    And whenever the input changes, I want to start the clock. That's it.

    How to handle the metastability problem? I don't know. Thanks for helping me out

    --- Quote End ---

    And whenever the input changes, I want to start the counter.

    My bad.

    The algorithm is:

    1. look for a edge change in T3PWM (0->1 or 1->0)

    2. start the counter

    3. after the count decrements to 0, stop counter.

    I'll read the document. Thanks.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I've understood the problem, however I am having trouble finding vhdl code (yes, seriously) to synthesize this synchronizer circuit, could someone please help me.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I've managed to build a synchronizer and have it verified by the RTL viewer. Now, how do I set the simulation to simulate that first flip flop to have a setup and hold time of 0 ns?

    Why am I doing that? We'll thats the advice from one the threads I read about simulating these synchronizers.
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    You can set the input as false path in Timequest. If you use synchronizers you don't need to have any specific set up and hold times.