error in quadrature design

Discussion in 'VHDL' started by zes, Sep 18, 2008.

  1. zes

    zes

    Joined:
    Sep 18, 2008
    Messages:
    4
    Hello,



    I am designing a vhdl quadrature decoder. The result of the decoder should be set in a register called "slv_reg2". Because the device can turn both ways i will cast the signed value to a std_logic_vector one (so my software can directly see which way is has turned).



    The design works perfect exept if I turn de shaft clockwise first and then counter-clockwise (and vice versa). When this happens i see the following on hyperterminal: 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 8, 7, 6 -4543453453. I've already spend 2 days finding the bug, but I really can't find it. Can the clock speed be to fast ??



    Here is my vhdl source:





    signal last_quad : std_logic_vector(0 to 1);
    signal look_up : std_logic_vector(0 to 3);
    signal signed_slv_reg2 : signed(0 to 31);

    begin

    slv_reg2 <= std_logic_vector(signed_slv_reg2);
    look_up <= quadrature & last_quad;

    p0:
    process(Bus2IP_Clk)
    begin
    if(Bus2IP_Clk'EVENT and Bus2IP_Clk = '1') then -- sample @ every rising clock cycle

    last_quad <= quadrature;
    signed_slv_reg2 <= signed_slv_reg2;

    if(slv_reg0(31) = '1') then -- check for reset events in control reg
    signed_slv_reg2 <= to_signed(0,32); -- if reset then empty register
    else
    case look_up is
    -- no change
    when "0000" | "1010" | "0101" | "1111" =>
    signed_slv_reg2 <= signed_slv_reg2;
    -- error
    when "0011" | "1100" | "1001"| "0110" =>
    signed_slv_reg2 <= signed_slv_reg2;
    -- turn ClockWise
    when "0010" | "0100" | "1011" | "1101" =>
    signed_slv_reg2 <= signed_slv_reg2 + to_signed(1,32);
    -- turn Counter - ClockWise
    when "0001" | "0111" | "1000" | "1110" =>
    signed_slv_reg2 <= signed_slv_reg2 - to_signed(1,32);
    -- not necessary because all states covered
    when others => null;
    end case;
    end if;
    end if;
    end process p0;
     
    zes, Sep 18, 2008
    #1
    1. Advertisements

  2. zes

    jeppe

    Joined:
    Mar 10, 2008
    Messages:
    348
    Location:
    Denmark
    Missing signals in sensivity list

    Try this - and let me know if it solves the problem - then I explain:

    Code (Text):
        signal last_quad : std_logic_vector(0 to 1);
        signal look_up : std_logic_vector(0 to 3);
        signal signed_slv_reg2 : signed(0 to 31);
    begin
        slv_reg2 <= std_logic_vector(signed_slv_reg2);
        --look_up <= quadrature & last_quad;

    p0:
    process(Bus2IP_Clk)
    begin
        if(Bus2IP_Clk'EVENT and Bus2IP_Clk = '1') then -- sample @ every rising clock cycle
            look_up <= quadrature & look_up( 0 to 1);
            --signed_slv_reg2 <= signed_slv_reg2;

            if(slv_reg0(31) = '1') then -- check for reset events in control reg
                signed_slv_reg2 <= to_signed(0,32); -- if reset then empty register
            else
                case look_up is
                -- no change
                    when "0000" | "1010" | "0101" | "1111" =>
                        signed_slv_reg2 <= signed_slv_reg2;
                -- error
                    when "0011" | "1100" | "1001"| "0110" =>
                        signed_slv_reg2 <= signed_slv_reg2;
                -- turn ClockWise
                    when "0010" | "0100" | "1011" | "1101" =>
                        signed_slv_reg2 <= signed_slv_reg2 + to_signed(1,32);
                -- turn Counter - ClockWise
                    when "0001" | "0111" | "1000" | "1110" =>
                        signed_slv_reg2 <= signed_slv_reg2 - to_signed(1,32);
                -- not necessary because all states covered
                    when others => null;
                end case;
            end if;
        end if;
    end process p0

    end Behavioral;
    Your welcome
    Jeppe
     
    Last edited: Sep 20, 2008
    jeppe, Sep 19, 2008
    #2
    1. Advertisements

  3. zes

    zes

    Joined:
    Sep 18, 2008
    Messages:
    4
    this will never work because in your changed design you dont do anything with look_up(2 to 3). And the purpose of this register is to take the current and the last value of the quadrature and this combination determines the turn.
     
    zes, Sep 22, 2008
    #3
  4. zes

    jeppe

    Joined:
    Mar 10, 2008
    Messages:
    348
    Location:
    Denmark
    Hi Zes

    Well I dont agree - may be you should take a second look in order to understand the statement:
    look_up <= quadrature & look_up( 0 to 1);
    :)

    Please visit this page: http://www.jjmk.dk/MMMI/Exercises/05_Counters_Shreg/No5_Quadrature/index.htm - with a new modified example (below) and a simulation which verifies the usefulnes (hopefully)

    Code (Text):
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.STD_LOGIC_ARITH.ALL;
    use IEEE.STD_LOGIC_SIGNED.ALL;

    entity Test is
       port( Bus2IP_Clk: in std_logic;
              slv_reg2:   inout std_logic_vector(31 downto 0) := (others=>'0');
                slv_reg0:   in    std_logic_vector(31 downto 0);
              quadrature: in    std_logic_vector(0 to 1));
    end Test;

    architecture Behavioral of Test is
       signal errors:   std_logic_vector(7 downto 0);
        signal look_up : std_logic_vector(0 to 3);
    begin

    p0: process(Bus2IP_Clk)
    begin
        if(Bus2IP_Clk'EVENT and Bus2IP_Clk = '1') then -- sample @ every rising clock cycle    

            look_up <= quadrature & look_up( 0 to 1);   -- look below
        -- look_up(0) <= quadrature(0);
        -- look_up(1) <= quadrature(1);
        -- look_up(2) <= look_up(0);
        -- look_up(3) <= look_up(1);
       
            if(slv_reg0(31) = '1') then -- check for reset events in control reg
                slv_reg2 <= (others=>'0'); -- if reset then empty register
                errors   <= (others=>'0');
            else
                case look_up is
                -- no change
                    when "0000" | "1010" | "0101" | "1111" =>
                        null;
                -- error
                    when "0011" | "1100" | "1001"| "0110" =>
                        errors <= errors+1;  -- Just to display nunber of errors
                -- turn ClockWise
                    when "0010" | "0100" | "1011" | "1101" =>
                        slv_reg2 <= slv_reg2 + 1;
                -- turn Counter - ClockWise
                    when "0001" | "0111" | "1000" | "1110" =>
                        slv_reg2 <= slv_reg2 - 1;
                -- not necessary because all states covered
                    when others => null;
                end case;
            end if;
        end if;
    end process p0;

    end Behavioral;
     
    jeppe, Sep 22, 2008
    #4
  5. zes

    zes

    Joined:
    Sep 18, 2008
    Messages:
    4
    if just synthesized and implemented your correction and it works :)

    thank you very much !!

    I just don't understand why the design works, but didn't work when i concatenated the "look_up" outside the process, can you explain why? because in simulation(modelsim XE/PE) my design worked.

    thx !! :)
     
    zes, Sep 22, 2008
    #5
  6. zes

    jeppe

    Joined:
    Mar 10, 2008
    Messages:
    348
    Location:
    Denmark
    Your welcome
    The problem (which may be not a problem actually ;-) ) could be the fact that the process in which you use look_up will only be trigged by clk pulses.
    But this will only course some delays in the detection of changes.
    There could be some (great) problems if the synthesize tool generates unexpected f/f's and hence courses your design to behave stangely, but I'm not sure this the case here.

    No the REAL problem could be your notation signed_xx ( 0 to 31) - try to change this to signed_xx( 31 downto 0)

    Jeppe
     
    Last edited: Sep 22, 2008
    jeppe, Sep 22, 2008
    #6
  7. zes

    zes

    Joined:
    Sep 18, 2008
    Messages:
    4
    well i have been turning the shaft for some times and no hazzards occured. I still have everything set as <name>(0 to 31) . And this works perfectly, i dont see why that should be different with downto, doesnt it synthesizes/simulates the same?
     
    zes, Sep 23, 2008
    #7
  8. zes

    jeppe

    Joined:
    Mar 10, 2008
    Messages:
    348
    Location:
    Denmark
    Ok - your right - just an old habbit for me to use (31 downto 0) - the result will be the same for synthesize

    About your problem - I found it :) :


    If you draw a block diagram of the circuit from your code will you find that the quadrature signals NOT synchronized.
    The Last_quad will always hold its value thanks to the Clock driven process and hence the implementation of F/F's

    Please note that this kind of problem will seldom (read never) shows in a simulation as the generatated stimulation will
    be synchone with the clock.
     
    Last edited: Sep 23, 2008
    jeppe, Sep 23, 2008
    #8
    1. Advertisements

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. ZackS
    Replies:
    5
    Views:
    6,913
    Just an Illusion
    Jul 9, 2004
  2. SpamProof
    Replies:
    3
    Views:
    684
    SpamProof
    Dec 1, 2003
  3. dave
    Replies:
    5
    Views:
    645
    William Brogden
    Jul 17, 2004
  4. Tim Smith
    Replies:
    2
    Views:
    905
    Tim Smith
    Dec 15, 2004
  5. trint
    Replies:
    1
    Views:
    385
    trint
    Nov 21, 2006
Loading...

Share This Page