Avoiding "Bad Synchronous Description" Error when Synthesizing

Discussion in 'VHDL' started by Takuon Soho, Mar 2, 2005.

  1. Takuon Soho

    Takuon Soho Guest

    I have learned how to set up a process
    properly with clk and reset signals so that it will
    synthesize properly without getting the dreaded
    "bad synchronous description" error.

    But here I have 3 signals - a clk (of course),
    a start signal, and a MessageRcvd signal.

    I am supposed to accumulate a count
    by adding 1 to a counter
    only after getting a "Start" signal (hi).

    Whenever the "MsgRcvd" signal goes
    hi, I must output the count and clear the counter.

    Whatever I try keeps running into the "bad synchrnous"
    problem.

    Question: Should I break this into two seperate processes
    or is it doable in 1?? Can 2 processes have a common
    variable (the counter?)

    I was going to try to re-write it as a state machine

    Here is one thing I tried (clearly wrong because
    sw_linexx and send_xx are set low by
    1 clock signal and set high by another).

    Thanks for any suggestions.
    Tak (VHDL newbie, obviously).


    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.STD_LOGIC_ARITH.ALL;
    use IEEE.NUMERIC_STD.all;

    entity count12 is port (
    clk: in std_logic;
    start: in std_logic
    msgRcvd: in std_logic;
    sw_linex: out std_logic;
    send_xx: out std_logic := '0';
    bus_0_11: out std_logic_vector(11 downto 0);
    );
    end count12;

    architecture behavioral of count12 is
    begin


    process(clk,start,msgRcvd)

    subtype counter_ty is integer range 0 to 4095;
    variable my_counter : counter_ty := 0;
    variable msgFlag :integer := 0; --make it a boolean flag later

    begin

    if (rising_edge(start)) then
    msgFlag := 1;
    end if;

    if (rising_edge(clk) and msgFlag = 1) then
    sw_linex <= '0';
    send_xx <= '0';
    my_counter := my_counter + 1;
    elsif
    (rising_edge(msgRcvd)) then
    send_xx <= '1';
    sw_linex <= '1';
    msgFlag := 0;
    bus_0_11 <= conv_std_logic_vector(my_counter, 12);
    end if;

    end process;

    end behavioral;
     
    Takuon Soho, Mar 2, 2005
    #1
    1. Advertising

  2. "Takuon Soho" <> wrote in message
    news:_EdVd.9027$...
    >I have learned how to set up a process
    > properly with clk and reset signals so that it will
    > synthesize properly without getting the dreaded
    > "bad synchronous description" error.
    >
    > But here I have 3 signals - a clk (of course),
    > a start signal, and a MessageRcvd signal.
    >
    > I am supposed to accumulate a count
    > by adding 1 to a counter
    > only after getting a "Start" signal (hi).
    >
    > Whenever the "MsgRcvd" signal goes
    > hi, I must output the count and clear the counter.
    >
    > Whatever I try keeps running into the "bad synchrnous"
    > problem.
    >
    > Question: Should I break this into two seperate processes
    > or is it doable in 1?? Can 2 processes have a common
    > variable (the counter?)
    >
    > I was going to try to re-write it as a state machine
    >
    > Here is one thing I tried (clearly wrong because
    > sw_linexx and send_xx are set low by
    > 1 clock signal and set high by another).
    >
    > Thanks for any suggestions.
    > Tak (VHDL newbie, obviously).
    >
    >
    > library IEEE;
    > use IEEE.STD_LOGIC_1164.ALL;
    > use IEEE.STD_LOGIC_ARITH.ALL;
    > use IEEE.NUMERIC_STD.all;
    >
    > entity count12 is port (
    > clk: in std_logic;
    > start: in std_logic
    > msgRcvd: in std_logic;
    > sw_linex: out std_logic;
    > send_xx: out std_logic := '0';
    > bus_0_11: out std_logic_vector(11 downto 0);
    > );
    > end count12;
    >
    > architecture behavioral of count12 is
    > begin
    >
    >
    > process(clk,start,msgRcvd)
    >
    > subtype counter_ty is integer range 0 to 4095;
    > variable my_counter : counter_ty := 0;
    > variable msgFlag :integer := 0; --make it a boolean flag later
    >
    > begin
    >
    > if (rising_edge(start)) then
    > msgFlag := 1;
    > end if;
    >
    > if (rising_edge(clk) and msgFlag = 1) then
    > sw_linex <= '0';
    > send_xx <= '0';
    > my_counter := my_counter + 1;
    > elsif
    > (rising_edge(msgRcvd)) then
    > send_xx <= '1';
    > sw_linex <= '1';
    > msgFlag := 0;
    > bus_0_11 <= conv_std_logic_vector(my_counter, 12);
    > end if;
    >
    > end process;
    >
    > end behavioral;
    >
    >

    The rising_edge with different signal names (clk and msgRcvd) is not
    (mostly) supported by synthesis tools.
    The synchronous frame work you learned was probably something like:

    process(reset,clk)
    begin
    if reset='1' then
    -- here the reset stuff
    elsif rising_edge(clk) then
    -- here the synchronous logic.
    -- no rising_edge, falling_edge or 'event
    end if;
    end process;

    > Whenever the "MsgRcvd" signal goes hi

    How long is this signal at least high?
    If it is at least one clock period high you could load the signal in a
    flipflop ("MsgRcvdPrev").
    If MsgRcvdPrev='0' and MsgRcvd='1' then "increment counter"
    (Note: probably you need also 1 or 2 flipflops for synchonization?)

    In case your MsgRcvd is short high, compared to the clock period, you could
    model an SR latch. Set the latch with the MsgRcvd and reset the latch from
    your synchronous description. (You can not detect two or more short high
    pulses within one clock period).

    Egbert Molenkamp
     
    Egbert Molenkamp, Mar 2, 2005
    #2
    1. Advertising

  3. Takuon Soho

    Guest

    Thanks, I think I can take the approach of making everything
    synchrnous to the clock signal and yes the MsgRcvd is at least
    one clock signal high.

    If I make everything synchonous to the clock signal, then an I follow
    the well known reset/clk paradigm that you mentioned?

    How is it done with 3 signals instead of 2?

    Thanks
    Tak

    Egbert Molenkamp wrote:
    > "Takuon Soho" <> wrote in message
    > news:_EdVd.9027$...
    > >I have learned how to set up a process
    > > properly with clk and reset signals so that it will
    > > synthesize properly without getting the dreaded
    > > "bad synchronous description" error.
    > >
    > > But here I have 3 signals - a clk (of course),
    > > a start signal, and a MessageRcvd signal.
    > >
    > > I am supposed to accumulate a count
    > > by adding 1 to a counter
    > > only after getting a "Start" signal (hi).
    > >
    > > Whenever the "MsgRcvd" signal goes
    > > hi, I must output the count and clear the counter.
    > >
    > > Whatever I try keeps running into the "bad synchrnous"
    > > problem.
    > >
    > > Question: Should I break this into two seperate processes
    > > or is it doable in 1?? Can 2 processes have a common
    > > variable (the counter?)
    > >
    > > I was going to try to re-write it as a state machine
    > >
    > > Here is one thing I tried (clearly wrong because
    > > sw_linexx and send_xx are set low by
    > > 1 clock signal and set high by another).
    > >
    > > Thanks for any suggestions.
    > > Tak (VHDL newbie, obviously).
    > >
    > >
    > > library IEEE;
    > > use IEEE.STD_LOGIC_1164.ALL;
    > > use IEEE.STD_LOGIC_ARITH.ALL;
    > > use IEEE.NUMERIC_STD.all;
    > >
    > > entity count12 is port (
    > > clk: in std_logic;
    > > start: in std_logic
    > > msgRcvd: in std_logic;
    > > sw_linex: out std_logic;
    > > send_xx: out std_logic := '0';
    > > bus_0_11: out std_logic_vector(11 downto 0);
    > > );
    > > end count12;
    > >
    > > architecture behavioral of count12 is
    > > begin
    > >
    > >
    > > process(clk,start,msgRcvd)
    > >
    > > subtype counter_ty is integer range 0 to 4095;
    > > variable my_counter : counter_ty := 0;
    > > variable msgFlag :integer := 0; --make it a boolean flag

    later
    > >
    > > begin
    > >
    > > if (rising_edge(start)) then
    > > msgFlag := 1;
    > > end if;
    > >
    > > if (rising_edge(clk) and msgFlag = 1) then
    > > sw_linex <= '0';
    > > send_xx <= '0';
    > > my_counter := my_counter + 1;
    > > elsif
    > > (rising_edge(msgRcvd)) then
    > > send_xx <= '1';
    > > sw_linex <= '1';
    > > msgFlag := 0;
    > > bus_0_11 <= conv_std_logic_vector(my_counter, 12);
    > > end if;
    > >
    > > end process;
    > >
    > > end behavioral;
    > >
    > >

    > The rising_edge with different signal names (clk and msgRcvd) is not
    > (mostly) supported by synthesis tools.
    > The synchronous frame work you learned was probably something like:
    >
    > process(reset,clk)
    > begin
    > if reset='1' then
    > -- here the reset stuff
    > elsif rising_edge(clk) then
    > -- here the synchronous logic.
    > -- no rising_edge, falling_edge or 'event
    > end if;
    > end process;
    >
    > > Whenever the "MsgRcvd" signal goes hi

    > How long is this signal at least high?
    > If it is at least one clock period high you could load the signal in

    a
    > flipflop ("MsgRcvdPrev").
    > If MsgRcvdPrev='0' and MsgRcvd='1' then "increment counter"
    > (Note: probably you need also 1 or 2 flipflops for synchonization?)
    >
    > In case your MsgRcvd is short high, compared to the clock period, you

    could
    > model an SR latch. Set the latch with the MsgRcvd and reset the latch

    from
    > your synchronous description. (You can not detect two or more short

    high
    > pulses within one clock period).
    >
    > Egbert Molenkamp
     
    , Mar 2, 2005
    #3
  4. <> schreef in bericht
    news:...
    > Thanks, I think I can take the approach of making everything
    > synchrnous to the clock signal and yes the MsgRcvd is at least
    > one clock signal high.
    >
    > If I make everything synchonous to the clock signal, then an I follow
    > the well known reset/clk paradigm that you mentioned?
    >
    > How is it done with 3 signals instead of 2?
    >
    > Thanks
    > Tak
    >


    Something like:

    architecture ...
    signal MsgRcvdPrev : std_logic;
    begin

    process(reset,clk)
    ...
    begin
    if reset='1' then
    -- here the reset stuff
    elsif rising_edge(clk) then
    if MsgRcvdPrev='0' and MsgRcvd='1' then
    -- now you have detect the '1' (I Assumed it is long enough high)
    send_xx <= '1';
    sw_linex <= '1';
    msgFlag := 0;
    bus_0_11 <= conv_std_logic_vector(my_counter, 12);
    end if
    MsgRcvdPrev <= MsgRcvd; -- flipflop
    end if;
    end process;

    Egbert Molenkamp
     
    Egbert Molenkamp, Mar 3, 2005
    #4
  5. Takuon Soho

    Takuon Soho Guest

    Thanks, this is idea interesting.

    But, I ended up breaking counter stuff into a seperate process
    and then it synthesized fine. Did'nt use up much macrocells
    either.

    Thanks everyone.

    Tak.


    "Egbert Molenkamp" <> wrote in message
    news:d07qh2$ahh$...
    >
    > <> schreef in bericht
    > news:...
    >> Thanks, I think I can take the approach of making everything
    >> synchrnous to the clock signal and yes the MsgRcvd is at least
    >> one clock signal high.
    >>
    >> If I make everything synchonous to the clock signal, then an I follow
    >> the well known reset/clk paradigm that you mentioned?
    >>
    >> How is it done with 3 signals instead of 2?
    >>
    >> Thanks
    >> Tak
    >>

    >
    > Something like:
    >
    > architecture ...
    > signal MsgRcvdPrev : std_logic;
    > begin
    >
    > process(reset,clk)
    > ...
    > begin
    > if reset='1' then
    > -- here the reset stuff
    > elsif rising_edge(clk) then
    > if MsgRcvdPrev='0' and MsgRcvd='1' then
    > -- now you have detect the '1' (I Assumed it is long enough high)
    > send_xx <= '1';
    > sw_linex <= '1';
    > msgFlag := 0;
    > bus_0_11 <= conv_std_logic_vector(my_counter, 12);
    > end if
    > MsgRcvdPrev <= MsgRcvd; -- flipflop
    > end if;
    > end process;
    >
    > Egbert Molenkamp
    >
     
    Takuon Soho, Mar 4, 2005
    #5
  6. Logic like this is SOOO much easier if you just make everything
    synchronous.
    A synchronous process should have only the clock in the sensitivity
    list. (Actually, I prefer to WAIT on a clock edge and not have a
    sensitivity list at all; even simpler.)
    If this is going to be synthesized into real logic, you shouldn't put
    initial values on any ports or signals. You must design the logic so
    that a reset sequence gets it into a known state.

    Try something like this:

    entity count12 is port (
    clk: in std_logic;
    reset: in std_logic;
    start: in std_logic;
    msgRcvd: in std_logic;
    sw_linex: out std_logic;
    send_xx: out std_logic;
    bus_0_11: out std_logic_vector(11 downto 0)
    );
    end count12;

    architecture behavioral of count12 is
    begin

    process
    subtype counter_ty is integer range 0 to 4095;
    variable my_counter : counter_ty;
    variable counting : bit;

    begin
    wait until clk='1';
    if reset='1' then
    counting := '0';
    send_xx <= '0';
    sw_linex <= '0';
    else
    if start='1' then
    my_counter := 0;
    counting := '1';
    elsif msgRcvd='1' then
    bus_0_11 <= conv_std_logic_vector(my_counter, 12);
    counting := '0';
    elsif counting='1' then
    my_counter := my_counter + 1;
    end if;
    send_xx <= msgRcvd;
    sw_linex <= msgRcvd;
    end if;
    end process;

    end behavioral;

    You didn't say whether the start or msgRcvd inputs were synchronous to
    the clock or how wide they were. If not, then you need to add
    synchronizing latches to the above circuit. The reset signal needs to
    be synchronous to the clock also.

    In a synchronous circuit, everything happens on a clock edge. You
    shouldn't try to trigger on edges of any other signals. Think of these
    other inputs as levels that are stable during the clock period and
    change on the clock edge. If they aren't, then add synchronizing
    latches to make it so.

    Charles Bailey
     
    Charles Bailey, Mar 9, 2005
    #6
    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. fpgawizz
    Replies:
    4
    Views:
    712
    dutchgoldtony
    Mar 4, 2005
  2. Zenock
    Replies:
    7
    Views:
    9,027
    vipinlal
    Mar 10, 2010
  3. Roman Himmes
    Replies:
    8
    Views:
    13,645
    Duane Clark
    Jun 22, 2005
  4. tarzandavid
    Replies:
    1
    Views:
    888
    jeppe
    Jun 13, 2008
  5. Replies:
    15
    Views:
    871
Loading...

Share This Page