Avoiding "Bad Synchronous Description" Error when Synthesizi

T

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;
 
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" <Tak@somwhere.net> wrote in message
news:_EdVd.9027$MY6.1221@newsread1.news.pas.earthlink.net...
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
 
<james_pannozzi@cisgi.com> schreef in bericht
news:1109782534.193265.25960@f14g2000cwb.googlegroups.com...
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
 

Welcome to EDABoard.com

Sponsor

Back
Top