Why doesn't this work in an XC9572XL?

Discussion in 'VHDL' started by JohnDuq, Jan 23, 2009.

  1. JohnDuq

    JohnDuq

    Joined:
    Dec 9, 2008
    Messages:
    88
    I have a fairly simple program here, that is supposed to run on a XC2-XL evaluation board. In the past it simulated properly, but I haven't rerun a simulation in a while.

    It takes the 1.8 MHz clock and divides it by 2^20 for a 2 Hz clock. It then cycles a pattern through four outputs on the part. I see the reset pattern happen, but nothing else. What am I missing?


    Thanks in advance,

    John

    ====================================
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.STD_LOGIC_ARITH.ALL;
    use IEEE.STD_LOGIC_UNSIGNED.ALL;

    ---- Uncomment the following library declaration if instantiating
    ---- any Xilinx primitives in this code.
    library UNISIM;
    use UNISIM.VComponents.all;

    entity GDC_top is
    Port ( EncA_I : in STD_LOGIC;
    EncB_I : in STD_LOGIC;
    Reset_I : in STD_LOGIC;
    GoLimA_I : in STD_LOGIC;
    GoLimB_I : in STD_LOGIC;
    Stop_I : in STD_LOGIC;
    SetPos_I : in STD_LOGIC;
    GoPos_I : in STD_LOGIC;
    Scale_I : in STD_LOGIC;
    LimAHit_I : in STD_LOGIC;
    LimBHit_I : in STD_LOGIC;
    Clk1p8_I : in STD_LOGIC;
    Step_O : out STD_LOGIC;
    Dir_O : out STD_LOGIC;
    Scale0_O : out STD_LOGIC; -- active low
    Scale1_O : out STD_LOGIC; -- active low
    Scale2_O : out STD_LOGIC; -- active low
    Scale3_O : out STD_LOGIC; -- active low
    LimA_O : out STD_LOGIC;
    LimB_O : out STD_LOGIC;
    PosSet_O : out STD_LOGIC);
    end GDC_top;


    architecture Behavioral of GDC_top is

    signal clk_scaler : unsigned(20 downto 0); -- Divides the clock and provides various divisors
    signal clk : std_logic; -- Internal clock derived from oscillators
    signal clk_180 : std_logic; -- clock with 180 degree shift
    signal Scale_state : unsigned(1 downto 0); -- Scale_I state
    signal Reset : std_logic; -- buffered reset
    signal Scale_size : unsigned(7 downto 0); -- eight bit scale multipler (255 max)

    begin

    -- CLOCK PRESCALER, the fast synchronous timing block
    process (Clk1p8_I, Reset_I, clk_scaler)
    begin
    if (Reset_I = '1') then
    clk_scaler <= (others => '0');
    elsif (Clk1p8_I'event) and (Clk1p8_I = '1')
    then
    clk_scaler <= clk_scaler + 1; -- Divides clock and provides various divisors
    end if;

    clk <= clk_scaler(20); -- change this to (20) when ready to implement in CPLD; (0) for sim
    clk_180 <= not(clk_scaler(20)); -- change this to (20) when ready to implement in CPLD; (0) for sim
    Reset <= not(Reset_I); -- this needs an inversion 1-23-09 JRD

    end process; -- CLOCK prescaler


    process(clk_180, Reset)
    -- the other big slow synchronous clock that is 180 out of sync

    variable old_state : unsigned(1 downto 0); -- previous state

    begin
    if (Reset = '1')
    then
    Scale0_O <= '1';
    Scale1_O <= '0';
    Scale2_O <= '1';
    Scale3_O <= '1';
    Scale_size <= "00000100"; -- one is the default scale
    elsif (clk_180'event) and (clk_180 = '1')
    then

    -- Scaler output
    case Scale_state is
    when "00" =>
    Scale0_O <= '0';
    Scale1_O <= '1';
    Scale2_O <= '1';
    Scale3_O <= '1';
    Scale_size <= "00000010"; -- one *2
    when "01" =>
    Scale0_O <= '1';
    Scale1_O <= '0';
    Scale2_O <= '1';
    Scale3_O <= '1';
    Scale_size <= "00000100"; -- two *2
    when "10" =>
    Scale0_O <= '1';
    Scale1_O <= '1';
    Scale2_O <= '0';
    Scale3_O <= '1';
    Scale_size <= "00000110"; -- three *2
    when others => -- aka "11"
    Scale0_O <= '1';
    Scale1_O <= '1';
    Scale2_O <= '1';
    Scale3_O <= '0';
    Scale_size <= "00001000"; -- four *2
    end case;
    end if;

    end process; -- process(clk_180)


    process(clk, Reset) -- one big slow synchronous timing block

    variable previous_step : std_logic; -- previous step for change detector
    variable previous_scale : std_logic; -- previous scale for change detection


    begin
    if (Reset = '1') then
    Scale_state <= (others => '0');
    LimA_O <= '0';
    LimB_O <= '0';
    PosSet_O <= '0';
    Dir_O <= '0';
    elsif (clk'event) and (clk = '1')
    then
    Scale_state <= Scale_state + 1; -- increment scale state
    end if; -- risingedge(clk)
    end process;


    end Behavioral;


    ====================================
     
    JohnDuq, Jan 23, 2009
    #1
    1. Advertising

  2. JohnDuq

    JohnDuq

    Joined:
    Dec 9, 2008
    Messages:
    88
    Hmm, and I just tried to simulate it and it doesn't work there anymore either...
    Is there something wrong with my clocking technique? I'm using the old school technique of having signals change on one edge of the clock (rising edge of CLK) and then latching them on the other edge (rising edge of CLK_180). Here my dual clocking rate is thus half of CLK.

    This used to work fine in ABEL, does it still work in VHDL?

    John
     
    JohnDuq, Jan 23, 2009
    #2
    1. Advertising

  3. JohnDuq

    JohnDuq

    Joined:
    Dec 9, 2008
    Messages:
    88
    Okay, it looks like I figured out what's going on. Here is my lesson's learned list from this project:

    1. When I moved from simulation to real hardware I found the reset signal was inverted, so I then inverted it in some but not all of my logic (doh!). In 'C' I would set a constant like RESET_LEVEL = '1' and then use that in my logic later (if apple = RESET_LEVEL, if banana = not(RESET_LEVEL)) so then I would only have to make one change to accommodate hardware changes.

    Is there a way to define constants in VHDL?


    2. When designing synchronous logic, don't define variables, only define signals. Variables and signals will change on the same clock edge; variables will NOT change value at the end of the process as some of the VHDL tutorials on the web indicate. If you have a signal referencing a variable (or vice versa) in the same process you will get timing violations. Processes in synchronous logic are not serial; each statement will run in parallel WITHIN the process.
     
    JohnDuq, Feb 6, 2009
    #3
  4. JohnDuq

    joris

    Joined:
    Jan 29, 2009
    Messages:
    152
    I haven't looked into your code in detail, but I'll try and reply on the things I know,
    Yea you declare them like this:
    Code:
    constant x : std_logic_vector(3 downto 0) := X"1001"; -- 9
    (ofcourse any type can be declared like that.)

    It seems you have been confusing signal semantics and variable semantics. As far as I know, it works like this:

    • Variables are updated right at the point where an assignment occurs
    • Assigning a variable to a signal works as expected
    • A signal assignments in a process is special: it is only applied after the process has completed. During the process, referring to the signal returns the original value
    • Assigning a signal to a variable works as expected (that is, the original value should be assigned?)

    In case I made a mistake in any of those, please tell!
     
    joris, Feb 6, 2009
    #4
  5. JohnDuq

    JohnDuq

    Joined:
    Dec 9, 2008
    Messages:
    88
    hi Joris,

    Thanks for the info on constants. That works great.

    I had thought the variables were causing timing violations; I later realized I hadn't defined my main clock rate properly. I didn't realize this until after I had converted all the variables to signals, so I'll have to revisit this.

    In a CPLD the process runs off a single clock, so I believe everything in a process latches at the same time, whether it is a variable or a signal. This makes the actual performance not match the simulation which is not good. ISE could get around this by adding another set of registers that get updated after the rest (or variables are combinatorial and not registered?). I'll investigate this later.

    John
     
    JohnDuq, Feb 25, 2009
    #5
    1. Advertising

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. David Prowak

    Why oh why doesn't my data view work?

    David Prowak, Jan 30, 2004, in forum: ASP .Net
    Replies:
    1
    Views:
    745
    Alvin Bruney [MVP]
    Jan 30, 2004
  2. Mr. SweatyFinger

    why why why why why

    Mr. SweatyFinger, Nov 28, 2006, in forum: ASP .Net
    Replies:
    4
    Views:
    922
    Mark Rae
    Dec 21, 2006
  3. Mr. SweatyFinger
    Replies:
    2
    Views:
    2,074
    Smokey Grindel
    Dec 2, 2006
  4. Sara
    Replies:
    6
    Views:
    275
    John W. Krahn
    Apr 12, 2004
  5. PerlFAQ Server
    Replies:
    0
    Views:
    269
    PerlFAQ Server
    Apr 26, 2011
Loading...

Share This Page