Synchronization

Discussion in 'VHDL' started by john, Apr 2, 2009.

  1. john

    john Guest

    Hello,

    Clock (clk1x) is a 100MHz clock and the VHDL program is using it to
    read the SDRAM. I need to load the SDRAM with the data and then send
    it to the Digital to Analog converter. The DAC works with 1MHz clock,
    49 bits of data and a Tag signal which tells the DAC that a new 49 bit
    data is available. I tried to divide the 100MHz clock to 1MHz and send
    the data to the clock. But I am unable to see the DAC working. I
    hooked up the logic analyzer and looked at the signals. The Tag who
    should repeats itself after every 49 bits is not stable at all. it
    repeats multiple times during the data stream and resets the DAC. My
    code is given below. I am having clock synchronization problems.
    Please advice. John

    library IEEE;
    use IEEE.std_logic_1164.all;
    use IEEE.numeric_std.all;
    use IEEE.std_logic_arith.all;
    use IEEE.std_logic_unsigned.all;

    package mem is

    component memTest
    generic(
    PIPE_EN : boolean := false; -- enable pipelined
    operations
    DATA_WIDTH : natural := 16; -- memory data width
    ADDR_WIDTH : natural := 23; -- memory address width
    BEG_TEST_1 : natural := 16#00_0000#; -- beginning test
    range address
    BEG_TEST_2 : natural := 16#00_0002#;
    BEG_TEST_3 : natural := 16#00_0004#;
    BEG_TEST_4 : natural := 16#00_0006#;
    BEG_TEST_5 : natural := 16#00_0008#;
    BEG_TEST_6 : natural := 16#00_0009#;
    END_TEST_1 : natural := 16#3F_FFFF#;
    END_TEST_2 : natural := 16#3F_FFFF#;
    END_TEST_3 : natural := 16#3F_FFFF#;
    END_TEST_4 : natural := 16#3F_FFFF#;
    END_TEST_5 : natural := 16#3F_FFFF#;
    END_TEST_6 : natural := 16#7F_FFFF# -- ending test range
    address
    );

    port(
    clk : in std_logic; -- master clock input
    rst : in std_logic; -- reset
    doAgain : in std_logic; -- re-do memory test
    begun : in std_logic; -- memory operation begun
    indicator
    done : in std_logic; -- memory operation done
    indicator
    dIn : in std_logic_vector(DATA_WIDTH-1 downto 0); --
    data from memory
    rdPending: in std_logic; -- read operations in progress
    indicator
    rd : out std_logic; -- memory read control
    signal
    wr : out std_logic; -- memory write control
    signal
    addr : out std_logic_vector(ADDR_WIDTH-1 downto 0); --
    address to memory
    dOut : out std_logic_vector(DATA_WIDTH-1 downto 0); --
    data to memory
    progress : out std_logic_vector(1 downto 0); -- memory test
    progress indicator
    err : out std_logic; -- memory error flag
    Logic_port: out std_logic_vector(DATA_WIDTH-1 downto 0);
    Trigger : out std_logic;
    -- lock_in : in std_logic;
    clk1x : in std_logic;
    clk_out : out std_logic;
    ser_out : out std_logic;
    done_1 : out std_logic;
    done_2 : out std_logic;
    done_3 : out std_logic;

    -- Signals for Six more Phil's Chips --

    ser_out_1 : out std_logic;
    sclk_1 : out std_logic;
    Dclk_1 : out std_logic;
    Tag_1 : out std_logic;

    ser_out_2 : out std_logic;
    sclk_2 : out std_logic;
    Dclk_2 : out std_logic;
    Tag_2 : out std_logic;


    ser_out_3 : out std_logic;
    sclk_3 : out std_logic;
    Dclk_3 : out std_logic;
    Tag_3 : out std_logic;


    ser_out_4 : out std_logic;
    sclk_4 : out std_logic;
    Dclk_4 : out std_logic;
    Tag_4 : out std_logic;

    ser_out_5 : out std_logic;
    sclk_5 : out std_logic;
    Dclk_5 : out std_logic;
    Tag_5 : out std_logic

    );
    end component;
    end package mem;

    library IEEE;
    use IEEE.std_logic_1164.all;
    use IEEE.std_logic_unsigned.all;
    use IEEE.numeric_std.all;
    use WORK.common.all;
    use WORK.rand.all;

    entity memTest is
    generic(
    PIPE_EN : boolean := false; -- enable pipelined
    operations
    DATA_WIDTH : natural := 16; -- memory data width
    ADDR_WIDTH : natural := 23; -- memory address width
    BEG_TEST_1 : natural := 16#00_0000#; -- beginning test
    range address
    BEG_TEST_2 : natural := 16#00_0002#;
    BEG_TEST_3 : natural := 16#00_0004#;
    BEG_TEST_4 : natural := 16#00_0006#;
    BEG_TEST_5 : natural := 16#00_0008#;
    BEG_TEST_6 : natural := 16#00_0009#;
    END_TEST_1 : natural := 16#3F_FFFF#;
    END_TEST_2 : natural := 16#3F_FFFF#;
    END_TEST_3 : natural := 16#3F_FFFF#;
    END_TEST_4 : natural := 16#3F_FFFF#;
    END_TEST_5 : natural := 16#3F_FFFF#;
    END_TEST_6 : natural := 16#7F_FFFF# -- ending test range
    address
    );
    port(

    clk : in std_logic; -- master clock input
    rst : in std_logic; -- reset
    doAgain : in std_logic; -- re-do memory test
    begun : in std_logic; -- memory operation begun
    indicator
    done : in std_logic; -- memory operation done
    indicator
    dIn : in std_logic_vector(DATA_WIDTH-1 downto 0); --
    data from memory
    rdPending : in std_logic; -- read operations in progress
    indicator
    rd : out std_logic; -- memory read control
    signal
    wr : out std_logic; -- memory write control
    signal
    addr : out std_logic_vector(ADDR_WIDTH-1 downto 0); --
    address to memory
    dOut : out std_logic_vector(DATA_WIDTH-1 downto 0); --
    data to memory
    progress : out std_logic_vector(1 downto 0); -- memory test
    progress indicator
    err : out std_logic; -- memory error flag
    Logic_port : out std_logic_vector(DATA_WIDTH-1 downto 0);
    Trigger : out std_logic;
    clk1x : in std_logic;
    clk_out : out std_logic;
    ser_out : out std_logic;
    done_1 : out std_logic;
    done_2 : out std_logic;
    done_3 : out std_logic;

    -- Signals for Six more Phil's Chip --

    ser_out_1 : out std_logic;
    sclk_1 : out std_logic;
    Dclk_1 : out std_logic;
    Tag_1 : out std_logic;

    ser_out_2 : out std_logic;
    sclk_2 : out std_logic;
    Dclk_2 : out std_logic;
    Tag_2 : out std_logic;


    ser_out_3 : out std_logic;
    sclk_3 : out std_logic;
    Dclk_3 : out std_logic;
    Tag_3 : out std_logic;


    ser_out_4 : out std_logic;
    sclk_4 : out std_logic;
    Dclk_4 : out std_logic;
    Tag_4 : out std_logic;

    ser_out_5 : out std_logic;
    sclk_5 : out std_logic;
    Dclk_5 : out std_logic;
    Tag_5 : out std_logic
    );
    end memTest;

    architecture arch of memTest is

    type matrix is array ( 47 downto 0) of bit;
    --states of the memory tester state machine
    type testState is (
    INIT,
    Ser_buff_LOAD_1,
    Ser_buff_LOAD_2,
    Ser_buff_LOAD_3,
    Ser_buff_LOAD_4,
    EMPTY_PIPE,
    STOP,
    ser_out_state,
    extra_state,
    First_byte,
    Second_byte,
    Third_byte,
    Reset_state,
    Tag_state,
    extra_Tag_state
    );

    signal state_r, state_x : testState; -- state register and next state
    --registers
    signal addr_r, addr_x : unsigned(addr'range);
    signal err_r,err_x :std_logic;

    --Internal signals
    signal ld : std_logic;
    signal cke: std_logic;
    signal rand :std_logic_vector (dOut'range);
    signal seed :std_logic_vector (dIn'range);
    signal ser_buff : std_logic_vector (47 downto 0);
    signal p2s_counter : unsigned (5 downto 0);
    signal count_begin :std_logic;
    signal count_load : std_logic;
    signal d1,d2,d3 : std_logic; -- Signals to load the data buffers
    signal Reset_counter : std_logic;
    signal p2s: std_logic_vector (5 downto 0);
    signal co : std_logic_vector (5 downto 0);
    signal xser_out : std_logic;
    signal Tag : std_logic;
    signal clk_divider : std_logic_vector ( 10 downto 0);
    signal clk_a, a,b,c,clk_b : std_logic;
    signal Tag_fall,dummy_clk,clk_out_1, Tag2, t2, Tag3,
    t3,D_2clk,Q_2clk : std_logic;
    signal D,Q,d_1 : std_logic;
    signal slow_clk : std_logic;
    signal count : std_logic_vector ( 6 downto 0);
    signal Tag_sig : std_logic;
    signal ser_out_sig_1: std_logic;
    signal ser_out_sig_2: std_logic;
    signal clk_delay : std_logic;
    signal Tag_out_2, Tag_out_1,Tag_out_0 : std_logic;
    signal Reset_counter_0,
    Reset_counter_1,final_reset,clk_synch,synch_reset,synch_reset_2 :
    std_logic;
    signal Reset_synch_0,Reset_synch_1,Reset_synch_2,Reset_synch_3 :
    std_logic;

    ---Second State Machine --
    Type Pulse_state is ( seek, find);
    Signal status : PULSE_STATE;
    Signal Pulse_out : std_logic;
    Signal Pulse_out_1 : std_logic;
    Signal Pulse_out_2 : std_logic;

    Begin
    seed <= (others => '1');-- random number seed is 111...111
    u0 : randGen
    generic map(
    DATA_WIDTH => seed'length
    )
    port map(
    clk => clk, -- input clock
    cke => cke, -- clock-enable to control when
    new random num is computed
    ld => ld, -- load seed control signal
    seed => seed, -- random number seed
    rand => rand -- random number output from
    generator
    );
    ------------------------------------------------------------------------------------
    addr <= std_logic_vector(addr_r); -- linear memory addressing
    clk_b <= clk_divider(6);
    done_1 <= synch_reset ;-- Tag
    done_3 <= clk_synch when synch_reset ='0' else '0'; -- DCLK
    clk_out <= clk_divider(5); -- SCLK

    -----------------------------------------------------------------------------------
    -- memory test controller state machine operations

    combinatorial : process(err_r, addr_r, dIn, rand, begun, done,
    rdPending, doAgain )

    begin

    -- default operations (do nothing unless explicitly stated in the
    following case statement)
    rd <= NO; -- no memory write
    wr <= NO; -- no memory read
    ld <= NO; -- don't load the random
    number generator
    cke <= NO; -- don't generate a new random
    number
    addr_x <= addr_r; -- next address is the same as
    current address
    err_x <= err_r; -- error flag is unchanged
    state_x <= state_r; -- no change in memory tester
    state

    -- **** compute the next state and operations ****
    case state_r is

    ------------------------------------------------------
    -- initialize the memory test controller
    ------------------------------------------------------
    when INIT =>

    ld <= YES; -- load random number seed
    cke <= YES; -- enable clocking of rand num
    gen so seed gets loaded
    addr_x <= TO_UNSIGNED(BEG_TEST_1, addr_x'length); -- load
    starting mem address
    err_x <= NO; -- clear memory error flag
    state_x <= Ser_buff_LOAD_1; -- next go to LOAD state and write
    pattern to memory
    progress <= "00"; -- indicate the current controller
    state
    Reset_counter <= '1';
    count_begin <= '0';

    when Ser_buff_LOAD_1 => -- re-run the generator and
    compare it to memory contents

    Reset_counter <= '1';

    if PIPE_EN then
    rd <= YES;
    if begun = YES then
    addr_x <= addr_r + 1; -- increment address to check next
    memory location
    end if;

    if addr_r = END_TEST_1 then
    state_x <= EMPTY_PIPE;
    end if;

    if done = YES then
    cke <= YES;
    end if;
    else

    if done = NO then -- current read operation is not
    complete
    rd <= YES; -- keep read signal active since
    memory read is not done
    count_begin <='0';

    else
    rd <= NO;
    d1 <='1'; -- Loaded first set of buffer
    d2 <='0';
    d3 <='0';
    count_begin <='0';
    state_x <= Ser_buff_LOAD_2;

    if addr_r= END_TEST_1 then
    state_x <= STOP; -- go to STOP state once entire
    range has been checked
    end if;
    addr_x <= addr_r + 1; -- increment address to check next
    memory location
    cke <= YES;
    End if;
    End if;
    ------------------------------------
    When Ser_buff_LOAD_2 =>
    Reset_counter <='1';

    if PIPE_EN then
    rd <= YES;
    if begun = YES then
    addr_x <= addr_r + 1; -- increment address to check next
    memory location
    end if;

    if addr_r = END_TEST_1 then
    state_x <= EMPTY_PIPE;
    end if;

    if done = YES then
    cke <= YES;
    end if;

    else

    if done = NO then -- current read operation is not
    complete
    rd <= YES; -- keep read signal active since
    memory read is not done
    count_begin <='0';

    else
    rd <= NO;
    d1 <='0';
    d2 <='1'; -- Loaded Second set of buffer
    d3 <='0';
    count_begin <='0';
    state_x <= Ser_buff_LOAD_3;

    if addr_r= END_TEST_1 then
    state_x <= STOP; -- go to STOP state once entire
    range has been checked
    end if;
    addr_x <= addr_r + 1; -- increment address to check next
    memory location
    cke <= YES;
    End if;
    End if;
    ---------------------------------------------
    When Ser_buff_LOAD_3 =>

    if PIPE_EN then
    rd <= YES;

    if begun = YES then
    addr_x <= addr_r + 1; -- increment address to check next
    memory location
    end if;

    if addr_r = END_TEST_1 then
    state_x <= EMPTY_PIPE;
    end if;

    if done = YES then
    cke <= YES;
    end if;

    else

    if done = NO then -- current read operation is not
    complete
    rd <= YES; -- keep read signal active since
    memory read is not done
    count_begin <='0';

    else
    rd <= NO;
    d1 <='0';
    d2 <='0';
    d3 <='1'; -- Loaded Third set of buffer
    count_begin <='0';
    state_x <= Reset_state;

    if addr_r= END_TEST_1 then
    state_x <= STOP; -- go to STOP state once entire
    range has been checked
    end if;
    addr_x <= addr_r + 1; -- increment address to check next
    memory location
    cke <= YES;
    End if;
    End if;
    ----------------------------------------------
    when Reset_state =>

    progress <= "10"; -- indicate the current
    controller state
    d1<='0';
    d2<='0';
    d3<='0';
    Reset_counter <='1';
    rd<=NO;
    count_begin<='0';

    state_x<= Tag_state;

    --------------------------------------------
    when Tag_state => -- Is this an extra state

    d1 <= '0';
    d2 <= '0';
    d3 <= '0';
    Reset_counter <='0';
    rd<=NO;
    count_begin <= '0';
    state_x <= ser_out_state;
    ----------------------------------------
    when ser_out_state =>

    Reset_counter <='0';

    if ( p2s_counter /= "110001") then
    rd <= NO;
    count_begin <= '1';
    Reset_counter <='0';
    state_x <= ser_out_state;

    else

    state_x <= Ser_buff_LOAD_1;

    end if;
    ---------------------------------------
    When EMPTY_PIPE =>
    Reset_counter <='1';
    if done = YES then
    cke <= YES;
    end if;

    if rdPending = NO then
    state_x <= STOP;
    end if;
    ------------------------------------
    When others =>

    if doAgain = YES then
    Reset_counter <='1';
    ld <= YES;
    cke <= YES;
    addr_x <= TO_UNSIGNED (BEG_TEST_1, addr_x'length);
    count_begin <='0';
    state_x <= INIT;
    end if;
    end case;

    end process;

    ------------------------------------
    -- clk1x is the main clock generated by xess's program
    update: process (clk1x)
    begin
    if clk1x'event and clk1x = '1' then
    if rst = YES then -- main reset from xess's program
    state_r <= INIT;
    else
    addr_r <= addr_x;
    state_r <= state_x;
    end if;
    end if;
    end process;
    ------------------------------------
    -- Filling the Buffers with memory data
    trig: process ( clk1x)
    begin
    if clk1x'event and clk1x = '1' then
    if ( done = YES ) then
    if ( d1 = '1') then
    ser_buff ( 15 downto 0) <= dIn ( 15 downto 0);
    --ser_buff ( 15 downto 0) <= "1010101010101010";
    a <='1';
    b <='0';
    c <= '0';

    elsif ( d2 = '1' ) then
    ser_buff ( 31 downto 16 ) <= dIn ( 15 downto 0);
    --ser_buff ( 31 downto 16 ) <= "1010101010101010";
    a <= '0';
    b <= '1';
    c <= '0';

    elsif ( d3 = '1') then
    ser_buff ( 47 downto 32 ) <= dIn ( 15 downto 0);
    --ser_buff ( 47 downto 32 ) <= "1010101010101010";
    a <= '0';
    b <= '0';
    c <= '0';

    else
    a <='0';
    b <='0';
    c <='0';
    end if;
    end if;
    end if;
    end process;

    --------------------------------------
    -- Synchronizing the Reset counter of the state machine..
    Reset_synch: process ( clk1x,rst)
    Begin

    if (rst= '1') then
    clk_synch <= '0';
    elsif rising_edge (clk1x) then
    clk_synch <= clk_b;
    end if;
    end process;
    -------------------------------------

    serial_count : process (synch_reset , clk_synch)
    begin
    if ( synch_reset = '1') Then
    p2s_counter <= ( others =>'0');
    elsif falling_edge (clk_synch) then
    p2s_counter <= p2s_counter + 1;
    --ser_out<=ser_buff ( to_integer ( p2s_counter ) );
    else
    end if;
    end process;
    ------------------------------------
    -- Synchronizing the state machine "Reset counter" with the DCLK--
    process(clk_synch, Reset_counter)
    begin
    If (Reset_counter = '1') Then
    synch_reset_2 <='1';
    elsif rising_edge (clk_synch) then
    synch_reset_2 <= Reset_counter;
    end if;
    end process;
    ------------------------------------
    process(clk_synch, synch_reset_2)
    begin
    If ( synch_reset_2 = '1') Then
    synch_reset <='1';
    elsif rising_edge (clk_synch) then
    synch_reset <= synch_reset_2;
    end if;
    end process;
    -----------------------------------
    div : process ( rst,clk1x)
    begin
    If ( rst = '1') Then
    clk_divider <= "00000000000";
    elsIf rising_edge (clk1x) then
    clk_divider <= clk_divider + 1;
    end if;
    end process;
    ---------------------------------
    End arch;
    john, Apr 2, 2009
    #1
    1. Advertising

  2. john

    JohnDuq

    Joined:
    Dec 9, 2008
    Messages:
    88
    I don't see any division by 100; I see a division by 32 (clk_out; that never gets used by the way) and a division by 64 (clk_b). How are you getting div by 100?

    John
    JohnDuq, Apr 2, 2009
    #2
    1. Advertising

  3. john

    JohnDuq

    Joined:
    Dec 9, 2008
    Messages:
    88
    Why are you running your state machine running combinatorial instead of synchronous? That could be another cause of unexpected timing. Sync to your 100 MHz clock (clk1).

    Side note - If you you spaces instead of tabs when you write, your code is much easier to read on this site. I learned that recently!
    JohnDuq, Apr 2, 2009
    #3
  4. john

    Symon Guest

    Hi John,
    Use a simulator.
    HTH., Syms.
    Symon, Apr 3, 2009
    #4
  5. john wrote:

    > Clock (clk1x) is a 100MHz clock and the VHDL program is using it to
    > read the SDRAM. I need to load the SDRAM with the data and then send
    > it to the Digital to Analog converter. The DAC works with 1MHz clock,
    > 49 bits of data and a Tag signal which tells the DAC that a new 49 bit
    > data is available. I tried to divide the 100MHz clock to 1MHz and send
    > the data to the clock. But I am unable to see the DAC working.


    A 100MHz process running on the fpga ought
    to be fast enough to handshake synchronously
    with a 1 MHz dac.

    -- Mike Treseler
    Mike Treseler, Apr 3, 2009
    #5
  6. john

    JohnDuq

    Joined:
    Dec 9, 2008
    Messages:
    88
    Does the DAQ have its own 1 MHz clock, so there are two clocks and the signal is passing from one clock (100 MHz sync'd) to the other (1 MHz DAQ)? That can have metastability issues you will need to address. Or is there only one master clock (clk1) in the system?
    JohnDuq, Apr 3, 2009
    #6
  7. john

    Andy Peters Guest

    On Apr 2, 10:06 am, john <> wrote:
    > Hello,
    >
    > Clock (clk1x) is a 100MHz clock and the VHDL program is using it to
    > read the SDRAM. I need to load the SDRAM with the data and then send
    > it to the Digital to Analog converter. The DAC works with 1MHz clock,
    > 49 bits of data and a Tag signal which tells the DAC that a new 49 bit
    > data is available. I tried to divide the 100MHz clock to 1MHz and send
    > the data to the clock.  But I am unable to see the DAC working. I
    > hooked up the logic analyzer and looked at the signals. The Tag who
    > should repeats itself after every 49 bits is not stable at all. it
    > repeats multiple times during the data stream and resets the DAC. My
    > code is given below. I am having clock synchronization problems.
    > Please advice. John


    Wow, more two-process state machine lossage.

    And you've declared both numeric_std and std_logic_arith.

    -a
    Andy Peters, Apr 6, 2009
    #7
  8. john

    Aiken Guest

    Did you check the DAC data sheet the SETUP and HOLD time for the DAC
    you may need to Hold/Set your data to the DAC at rising/falling edge
    in the DAC clock.

    On Apr 6, 2:09 pm, Andy Peters <> wrote:
    > On Apr 2, 10:06 am, john <> wrote:
    >
    > > Hello,

    >
    > > Clock (clk1x) is a 100MHz clock and the VHDL program is using it to
    > > read the SDRAM. I need to load the SDRAM with the data and then send
    > > it to the Digital to Analog converter. The DAC works with 1MHz clock,
    > > 49 bits of data and a Tag signal which tells the DAC that a new 49 bit
    > > data is available. I tried to divide the 100MHz clock to 1MHz and send
    > > the data to the clock.  But I am unable to see the DAC working. I
    > > hooked up the logic analyzer and looked at the signals. The Tag who
    > > should repeats itself after every 49 bits is not stable at all. it
    > > repeats multiple times during the data stream and resets the DAC. My
    > > code is given below. I am having clock synchronization problems.
    > > Please advice. John

    >
    > Wow, more two-process state machine lossage.
    >
    > And you've declared both numeric_std and std_logic_arith.
    >
    > -a
    Aiken, Apr 13, 2009
    #8
    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. arcvonz

    System Time synchronization

    arcvonz, Aug 23, 2004, in forum: ASP .Net
    Replies:
    2
    Views:
    480
    Sam Santiago
    Aug 23, 2004
  2. John

    Flip Flop Synchronization

    John, Jan 3, 2004, in forum: VHDL
    Replies:
    3
    Views:
    9,684
    valentin tihomirov
    Jan 5, 2004
  3. Simon
    Replies:
    1
    Views:
    621
    tbx135
    Jan 9, 2004
  4. prav

    regarding synchronization

    prav, Feb 18, 2004, in forum: VHDL
    Replies:
    5
    Views:
    1,294
    Jos De Laender
    Feb 21, 2004
  5. deep
    Replies:
    0
    Views:
    468
Loading...

Share This Page