Hi,
I am not an FPGA expert although this is not my first design. The
problem that I am having for two days now, is that I am observing
different results when simulating a design in GHDL and in Modelsim
ALTERA starter edition.
The design includes a shift register. The significant code is:
read_sro : process(s_sample)
begin
if rising_edge(s_sample) then
if ... --irrelevant here
end if;
if ...
end if;
if sr_burst_ena = '1' then --First phase: store data in shift_reg
new_data <= sr_sro_wave & new_data(c_burst_no-1 downto 1);
elsif dec_shift_ena = '1' then --Second phase: rotate data
new_data <= new_data(0) & new_data(c_burst_no-1 downto 1);
--irrelevant, but included for completeness
max_cnt <= max_cnt + 1;
if usum > max then
max <= usum;
max_pos <= max_cnt;
end if;
end if;
end if;
end process read_sro;
the clock signal s_sample is obtained from the main 50 MHz clock with
the following process:
sr_signals : process(clk)
begin
if rising_edge(clk) then
if sr_clear = '1' or sr_burst_ena = '1' or dec_shift_ena ='1' then
s_sample <= not s_sample;
end if;
...
end if;
end process sr_signals;
I have uploaded some screenshots here:
1- ghdl+gtkwave result http://tinypic.com/r/wklimq/6
2- simulink http://tinypic.com/r/2le743t/6
It may be seen that the input signal (top signal in the GHDL result and
third from the top in SIMULINK) is zero during the first 5 s_sample
clocks, then is at one during 10 clocks and zero again for the rest of
the (up to 20) clocks.
The GHDL simulation shows up ok, with the register correctly loaded with
0000011111111110000 after the 20 clocks, however Altera's quartus gives
00000111110000011111.
Exactly the same file is being fed to to Quartus II for synthesis!! But
Alteras RTL (and gate level) simulations do not behave as intended.
Is there something with the coding style than can make Quartus infer an
absolutely different behaviour? Any help is very much appreciated!!
Pere
|
|
0
|
|
|
|
Reply
|
me1756 (19)
|
7/11/2012 11:23:51 AM |
|
On Wednesday, July 11, 2012 7:23:51 AM UTC-4, o pere o wrote:
> Hi,
>=20
> I am not an FPGA expert although this is not my first design. The=20
> problem that I am having for two days now, is that I am observing=20
> different results when simulating a design in GHDL and in Modelsim=20
> ALTERA starter edition.
>=20
> The design includes a shift register. The significant code is:
>=20
> read_sro : process(s_sample)
> begin
> if rising_edge(s_sample) then
> if ... --irrelevant here
> end if;
> if ... =09
> end if;=09
> if sr_burst_ena =3D '1' then --First phase: store data in=
shift_reg
> new_data <=3D sr_sro_wave & new_data(c_burst_no-1 downt=
o 1);
> elsif dec_shift_ena =3D '1' then --Second phase: rotate d=
ata
>=20
> new_data <=3D new_data(0) & new_data(c_burst_no-1 downt=
o 1);
>=20
> --irrelevant, but included for completeness
> max_cnt <=3D max_cnt + 1;
> if usum > max then
> max <=3D usum;
> max_pos <=3D max_cnt;
> end if;
> end if;
> end if;
> end process read_sro;
>=20
> the clock signal s_sample is obtained from the main 50 MHz clock with=20
> the following process:
>=20
> sr_signals : process(clk)
> begin
> if rising_edge(clk) then
> if sr_clear =3D '1' or sr_burst_ena =3D '1' or dec_=
shift_ena =3D'1' then
> s_sample <=3D not s_sample;
> end if;
> ...
> end if;
> end process sr_signals;
>=20
> I have uploaded some screenshots here:
>=20
> 1- ghdl+gtkwave result http://tinypic.com/r/wklimq/6
> 2- simulink http://tinypic.com/r/2le743t/6
>=20
> It may be seen that the input signal (top signal in the GHDL result and=
=20
> third from the top in SIMULINK) is zero during the first 5 s_sample=20
> clocks, then is at one during 10 clocks and zero again for the rest of=20
> the (up to 20) clocks.
>=20
> The GHDL simulation shows up ok, with the register correctly loaded with=
=20
> 0000011111111110000 after the 20 clocks, however Altera's quartus giv=
es=20
> 00000111110000011111.
>=20
> Exactly the same file is being fed to to Quartus II for synthesis!! But=
=20
> Alteras RTL (and gate level) simulations do not behave as intended.
>=20
> Is there something with the coding style than can make Quartus infer an=
=20
> absolutely different behaviour? Any help is very much appreciated!!
>=20
> Pere
By generating an internal clock signal you're not following synchronous des=
ign practice. In an FPGA design that spells trouble. What you need to do =
to make it synchronous is:
- Change the 'sr_signals' process that currently generates 's_sample'. Wha=
t you'll want is for 's_sample' to be a one clock cycle pulse at the approp=
riate time. Modify your if statement to accomplish this.
- Modify the 'read_src' process to use the free running clock and 's_sample=
' like this
read_sro : process(clk)=20
begin=20
if rising_edge(clk) then
if (s_sample =3D '1') then
-- Put all of the code you have that was previously within
-- the "if rising_edge(s_sample) then" statement here
end if;
end if;
end process read_src;
The reason that generated clocks are bad news in an FPGA is that you have e=
ssentially zero control over signal skew. A signal generated in one clock =
domain can, depending on the routing, make it over into the other clock dom=
ain even before the generated clock gets there, or perhaps after. In your =
case, you really have no way to say what skew there is between 'clk' and 's=
_sample'. The signals 'sr_burst_ena' and 'dec_shift_ena' are used in both =
of your processes and yet each can only be valid in one clock domain (your =
posted code does not show those signal assignments so it is not clear in wh=
ich domain they have been generated, but I suspect it is in 'clk').
Kevin Jennings
|
|
0
|
|
|
|
Reply
|
kkjennings (124)
|
7/11/2012 12:02:10 PM
|
|
On 07/11/2012 02:02 PM, KJ wrote:
> On Wednesday, July 11, 2012 7:23:51 AM UTC-4, o pere o wrote:
>> Hi,
>>
>> I am not an FPGA expert although this is not my first design. The
>> problem that I am having for two days now, is that I am observing
>> different results when simulating a design in GHDL and in Modelsim
>> ALTERA starter edition.
>>
>> The design includes a shift register. The significant code is:
>>
>> read_sro : process(s_sample)
>> begin
>> if rising_edge(s_sample) then
>> if ... --irrelevant here
>> end if;
>> if ...
>> end if;
>> if sr_burst_ena ='1' then --First phase: store data in shift_reg
>> new_data<= sr_sro_wave& new_data(c_burst_no-1 downto 1);
>> elsif dec_shift_ena ='1' then --Second phase: rotate data
>>
>> new_data<= new_data(0)& new_data(c_burst_no-1 downto 1);
>>
>> --irrelevant, but included for completeness
>> max_cnt<= max_cnt + 1;
>> if usum> max then
>> max<= usum;
>> max_pos<= max_cnt;
>> end if;
>> end if;
>> end if;
>> end process read_sro;
>>
>> the clock signal s_sample is obtained from the main 50 MHz clock with
>> the following process:
>>
>> sr_signals : process(clk)
>> begin
>> if rising_edge(clk) then
>> if sr_clear ='1' or sr_burst_ena ='1' or dec_shift_ena ='1' then
>> s_sample<= not s_sample;
>> end if;
>> ...
>> end if;
>> end process sr_signals;
>>
>> I have uploaded some screenshots here:
>>
>> 1- ghdl+gtkwave result http://tinypic.com/r/wklimq/6
>> 2- simulink http://tinypic.com/r/2le743t/6
>>
>> It may be seen that the input signal (top signal in the GHDL result and
>> third from the top in SIMULINK) is zero during the first 5 s_sample
>> clocks, then is at one during 10 clocks and zero again for the rest of
>> the (up to 20) clocks.
>>
>> The GHDL simulation shows up ok, with the register correctly loaded with
>> 0000011111111110000 after the 20 clocks, however Altera's quartus gives
>> 00000111110000011111.
>>
>> Exactly the same file is being fed to to Quartus II for synthesis!! But
>> Alteras RTL (and gate level) simulations do not behave as intended.
>>
>> Is there something with the coding style than can make Quartus infer an
>> absolutely different behaviour? Any help is very much appreciated!!
>>
>> Pere
>
> By generating an internal clock signal you're not following synchronous design practice. In an FPGA design that spells trouble. What you need to do to make it synchronous is:
>
> - Change the 'sr_signals' process that currently generates 's_sample'. What you'll want is for 's_sample' to be a one clock cycle pulse at the appropriate time. Modify your if statement to accomplish this.
> - Modify the 'read_src' process to use the free running clock and 's_sample' like this
>
> read_sro : process(clk)
> begin
> if rising_edge(clk) then
> if (s_sample = '1') then
> -- Put all of the code you have that was previously within
> -- the "if rising_edge(s_sample) then" statement here
> end if;
> end if;
> end process read_src;
>
> The reason that generated clocks are bad news in an FPGA is that you have essentially zero control over signal skew. A signal generated in one clock domain can, depending on the routing, make it over into the other clock domain even before the generated clock gets there, or perhaps after. In your case, you really have no way to say what skew there is between 'clk' and 's_sample'. The signals 'sr_burst_ena' and 'dec_shift_ena' are used in both of your processes and yet each can only be valid in one clock domain (your posted code does not show those signal assignments so it is not clear in which domain they have been generated, but I suspect it is in 'clk').
>
> Kevin Jennings
>
Kevin
Thanks for your input!
I know that this does not result in a synchronous design, and I was
already thinking of rewriting it with clock enables, as you suggested.
However, this was done because, in this case, there is no signal
generated in the "clk" domain that is read by "s_sample". Actually
"s_sample" is only used to read some signals from the outside world and
the shift register more or less tries to correlate what is read in the
present cycle with the previous ones.
Is it correct to say that, in this case, "it doesn't matter"?
Now, completely agreeing with your observation, I am still puzzled by
the fact that the even the RTL simulation (which I assume does not take
any delays into account) is not working properly. If you have a look at
the simulation results, this is absolutely not a shift register!
It seems that Altera's synthesis tool infers something quite
different... but why??
Pere
|
|
0
|
|
|
|
Reply
|
me1756 (19)
|
7/11/2012 4:48:49 PM
|
|
o pere o <me@somewhere.net> wrote:
> I am not an FPGA expert although this is not my first design. The
> problem that I am having for two days now, is that I am observing
> different results when simulating a design in GHDL and in Modelsim
> ALTERA starter edition.
(snip)
> the clock signal s_sample is obtained from the main 50 MHz
> clock with the following process:
> sr_signals : process(clk)
> begin
> if rising_edge(clk) then
> if sr_clear = '1' or sr_burst_ena = '1' or dec_shift_ena ='1' then
> s_sample <= not s_sample;
> end if;
> ...
> end if;
> end process sr_signals;
You don't show where dec_shift_ena comes from.
(snip)
> The GHDL simulation shows up ok, with the register correctly loaded with
> 0000011111111110000 after the 20 clocks, however Altera's quartus gives
> 00000111110000011111.
> Exactly the same file is being fed to to Quartus II for synthesis!! But
> Alteras RTL (and gate level) simulations do not behave as intended.
> Is there something with the coding style than can make Quartus infer an
> absolutely different behaviour? Any help is very much appreciated!!
There are designs where the HDL code can simulate differently from
the usual synthesis. In that case, one could expect differences
from different simulators.
Unless you are doing post-route simulation, there are no delays
in use, but some signals are known to come after others.
The output of a FF will change after, never at the same time, as
the input.
You can't make any assumption, though, on the outputs of two FFs
with the same clock input. In simulation, one may be considered
before or after the other. In actual logic, with actual wire
delays, the result can be a race condition, where the result
is uncertain.
I didn't see in the logic where that happened, but maybe in
the part that wasn't shown. Especially dec_shift_ena.
-- glen
|
|
0
|
|
|
|
Reply
|
gah (12261)
|
7/11/2012 6:53:49 PM
|
|
On Jul 11, 12:48 pm, o pere o <m...@somewhere.net> wrote:
> On 07/11/2012 02:02 PM, KJ wrote:
>
>
>
>
>
>
>
> > On Wednesday, July 11, 2012 7:23:51 AM UTC-4, o pere o wrote:
> >> Hi,
>
> >> I am not an FPGA expert although this is not my first design. The
> >> problem that I am having for two days now, is that I am observing
> >> different results when simulating a design in GHDL and in Modelsim
> >> ALTERA starter edition.
>
> >> The design includes a shift register. The significant code is:
>
> >> read_sro : process(s_sample)
> >> begin
> >> if rising_edge(s_sample) then
> >> if ... --irrelevant here
> >> end if;
> >> if ...
> >> end if;
> >> if sr_burst_ena =3D'1' then --First phase: store data=
in shift_reg
> >> new_data<=3D sr_sro_wave& new_data(c_burst_no-1 dow=
nto 1);
> >> elsif dec_shift_ena =3D'1' then --Second phase: rotat=
e data
>
> >> new_data<=3D new_data(0)& new_data(c_burst_no-1 dow=
nto 1);
>
> >> --irrelevant, but included for completeness
> >> max_cnt<=3D max_cnt + 1;
> >> if usum> max then
> >> max<=3D usum;
> >> max_pos<=3D max_cnt;
> >> end if;
> >> end if;
> >> end if;
> >> end process read_sro;
>
> >> the clock signal s_sample is obtained from the main 50 MHz clock with
> >> the following process:
>
> >> sr_signals : process(clk)
> >> begin
> >> if rising_edge(clk) then
> >> if sr_clear =3D'1' or sr_burst_ena =3D'1' or de=
c_shift_ena =3D'1' then
> >> s_sample<=3D not s_sample;
> >> end if;
> >> ...
> >> end if;
> >> end process sr_signals;
>
> >> I have uploaded some screenshots here:
>
> >> 1- ghdl+gtkwave resulthttp://tinypic.com/r/wklimq/6
> >> 2- simulinkhttp://tinypic.com/r/2le743t/6
>
> >> It may be seen that the input signal (top signal in the GHDL result an=
d
> >> third from the top in SIMULINK) is zero during the first 5 s_sample
> >> clocks, then is at one during 10 clocks and zero again for the rest of
> >> the (up to 20) clocks.
>
> >> The GHDL simulation shows up ok, with the register correctly loaded wi=
th
> >> 0000011111111110000 after the 20 clocks, however Altera's quartus =
gives
> >> 00000111110000011111.
>
> >> Exactly the same file is being fed to to Quartus II for synthesis!! Bu=
t
> >> Alteras RTL (and gate level) simulations do not behave as intended.
>
> >> Is there something with the coding style than can make Quartus infer a=
n
> >> absolutely different behaviour? Any help is very much appreciated!!
>
> >> Pere
>
> > By generating an internal clock signal you're not following synchronous=
design practice. In an FPGA design that spells trouble. What you need to=
do to make it synchronous is:
>
> > - Change the 'sr_signals' process that currently generates 's_sample'. =
What you'll want is for 's_sample' to be a one clock cycle pulse at the ap=
propriate time. Modify your if statement to accomplish this.
> > - Modify the 'read_src' process to use the free running clock and 's_sa=
mple' like this
>
> > read_sro : process(clk)
> > begin
> > if rising_edge(clk) then
> > if (s_sample =3D '1') then
> > -- Put all of the code you have that was previously within
> > -- the "if rising_edge(s_sample) then" statement here
> > end if;
> > end if;
> > end process read_src;
>
> > The reason that generated clocks are bad news in an FPGA is that you ha=
ve essentially zero control over signal skew. A signal generated in one cl=
ock domain can, depending on the routing, make it over into the other clock=
domain even before the generated clock gets there, or perhaps after. In y=
our case, you really have no way to say what skew there is between 'clk' an=
d 's_sample'. The signals 'sr_burst_ena' and 'dec_shift_ena' are used in b=
oth of your processes and yet each can only be valid in one clock domain (y=
our posted code does not show those signal assignments so it is not clear i=
n which domain they have been generated, but I suspect it is in 'clk').
>
> > Kevin Jennings
>
> Kevin
>
> Thanks for your input!
>
> I know that this does not result in a synchronous design, and I was
> already thinking of rewriting it with clock enables, as you suggested.
>
> However, this was done because, in this case, there is no signal
> generated in the "clk" domain that is read by "s_sample". Actually
> "s_sample" is only used to read some signals from the outside world and
> the shift register more or less tries to correlate what is read in the
> present cycle with the previous ones.
>
> Is it correct to say that, in this case, "it doesn't matter"?
>
> Now, completely agreeing with your observation, I am still puzzled by
> the fact that the even the RTL simulation (which I assume does not take
> any delays into account) is not working properly. If you have a look at
> the simulation results, this is absolutely not a shift register!
>
> It seems that Altera's synthesis tool infers something quite
> different... but why??
>
> Pere
Your design is synchronous, but you have more than one clock, so you
need to be sure of the timing of signals that cross the clock
domains. For example, the signals sr_clear, sr_burst_ena and
dec_shift_ena seem to be used in both the clk and the s_sample clock
domains without being synchonized. I guess that might be ok if you
can make sure the delays in the s_sample clock don't result in one of
these signals changing on the edge of either clock.
If the simulation is not what you want, then there is likely something
wrong with the code. But remember that while the simulation does not
account for logic delays, there are delta delays that mean signals
clocked by clk will have already changed by the time the remaining
code sees the change in s_sample.
Rick
|
|
0
|
|
|
|
Reply
|
gnuarm (2644)
|
7/11/2012 8:13:33 PM
|
|
On 07/11/2012 08:53 PM, glen herrmannsfeldt wrote:
> o pere o<me@somewhere.net> wrote:
>
>> I am not an FPGA expert although this is not my first design. The
>> problem that I am having for two days now, is that I am observing
>> different results when simulating a design in GHDL and in Modelsim
>> ALTERA starter edition.
>
> (snip)
>
>> the clock signal s_sample is obtained from the main 50 MHz
>> clock with the following process:
>
>> sr_signals : process(clk)
>> begin
>> if rising_edge(clk) then
>> if sr_clear = '1' or sr_burst_ena = '1' or dec_shift_ena ='1' then
>> s_sample<= not s_sample;
>> end if;
>> ...
>> end if;
>> end process sr_signals;
>
> You don't show where dec_shift_ena comes from.
Sorry for the omission!
dec_shift_ena is generated as follows. First, I have a counter the is
reset periodically:
clock_counter: process(clk) --counter counting over the symbol length
begin
if rising_edge(clk) then
if tc_symbol = '1' then
clk_count <= 0;
else
clk_count <= clk_count + 1;
end if;
end if;
end process clock_counter;
tc_symbol <= '1' when clk_count=c_ticks_per_symbol-1 else '0';
From this counter, I also generate some time markers, such as
dec_shift_ena_pre <= '1' when (clk_count >= ...) and (...)
else '0';
which are resynchronized in
process(clk)
begin
if rising_edge(clk) then
...
dec_shift_ena <= dec_shift_ena_pre;
end if;
end process;
> (snip)
>
>> The GHDL simulation shows up ok, with the register correctly loaded with
>> 0000011111111110000 after the 20 clocks, however Altera's quartus gives
>> 00000111110000011111.
>
>> Exactly the same file is being fed to to Quartus II for synthesis!! But
>> Alteras RTL (and gate level) simulations do not behave as intended.
>
>> Is there something with the coding style than can make Quartus infer an
>> absolutely different behaviour? Any help is very much appreciated!!
>
> There are designs where the HDL code can simulate differently from
> the usual synthesis. In that case, one could expect differences
> from different simulators.
>
> Unless you are doing post-route simulation, there are no delays
> in use, but some signals are known to come after others.
>
> The output of a FF will change after, never at the same time, as
> the input.
>
> You can't make any assumption, though, on the outputs of two FFs
> with the same clock input. In simulation, one may be considered
> before or after the other. In actual logic, with actual wire
> delays, the result can be a race condition, where the result
> is uncertain.
>
> I didn't see in the logic where that happened, but maybe in
> the part that wasn't shown. Especially dec_shift_ena.
>
> -- glen
>
I get the same results with RTL and with post-route simulation (except
for minor delays, as expected). I guess Altera's synthesis tool is doing
something strange at exactly the half of the shif register new_data: The
top half shifts correctly, but the bottom half looks as if it was
inverted. I can't figure out how a timing issue could have this outcome,
but I am probably missing something obvious -and hopefully someone can
point this out :) !!
Pere
|
|
0
|
|
|
|
Reply
|
me1756 (19)
|
7/12/2012 7:23:12 AM
|
|
On 07/11/2012 10:13 PM, rickman wrote:
> On Jul 11, 12:48 pm, o pere o<m...@somewhere.net> wrote:
>> On 07/11/2012 02:02 PM, KJ wrote:
>>
>>
>>
>>
>>
>>
>>
>>> On Wednesday, July 11, 2012 7:23:51 AM UTC-4, o pere o wrote:
>>>> Hi,
>>
>>>> I am not an FPGA expert although this is not my first design. The
>>>> problem that I am having for two days now, is that I am observing
>>>> different results when simulating a design in GHDL and in Modelsim
>>>> ALTERA starter edition.
>>
>>>> The design includes a shift register. The significant code is:
>>
>>>> read_sro : process(s_sample)
>>>> begin
>>>> if rising_edge(s_sample) then
>>>> if ... --irrelevant here
>>>> end if;
>>>> if ...
>>>> end if;
>>>> if sr_burst_ena ='1' then --First phase: store data in shift_reg
>>>> new_data<= sr_sro_wave& new_data(c_burst_no-1 downto 1);
>>>> elsif dec_shift_ena ='1' then --Second phase: rotate data
>>
>>>> new_data<= new_data(0)& new_data(c_burst_no-1 downto 1);
>>
>>>> --irrelevant, but included for completeness
>>>> max_cnt<= max_cnt + 1;
>>>> if usum> max then
>>>> max<= usum;
>>>> max_pos<= max_cnt;
>>>> end if;
>>>> end if;
>>>> end if;
>>>> end process read_sro;
>>
>>>> the clock signal s_sample is obtained from the main 50 MHz clock with
>>>> the following process:
>>
>>>> sr_signals : process(clk)
>>>> begin
>>>> if rising_edge(clk) then
>>>> if sr_clear ='1' or sr_burst_ena ='1' or dec_shift_ena ='1' then
>>>> s_sample<= not s_sample;
>>>> end if;
>>>> ...
>>>> end if;
>>>> end process sr_signals;
>>
>>>> I have uploaded some screenshots here:
>>
>>>> 1- ghdl+gtkwave resulthttp://tinypic.com/r/wklimq/6
>>>> 2- simulinkhttp://tinypic.com/r/2le743t/6
>>
>>>> It may be seen that the input signal (top signal in the GHDL result and
>>>> third from the top in SIMULINK) is zero during the first 5 s_sample
>>>> clocks, then is at one during 10 clocks and zero again for the rest of
>>>> the (up to 20) clocks.
>>
>>>> The GHDL simulation shows up ok, with the register correctly loaded with
>>>> 0000011111111110000 after the 20 clocks, however Altera's quartus gives
>>>> 00000111110000011111.
>>
>>>> Exactly the same file is being fed to to Quartus II for synthesis!! But
>>>> Alteras RTL (and gate level) simulations do not behave as intended.
>>
>>>> Is there something with the coding style than can make Quartus infer an
>>>> absolutely different behaviour? Any help is very much appreciated!!
>>
>>>> Pere
>>
>>> By generating an internal clock signal you're not following synchronous design practice. In an FPGA design that spells trouble. What you need to do to make it synchronous is:
>>
>>> - Change the 'sr_signals' process that currently generates 's_sample'. What you'll want is for 's_sample' to be a one clock cycle pulse at the appropriate time. Modify your if statement to accomplish this.
>>> - Modify the 'read_src' process to use the free running clock and 's_sample' like this
>>
>>> read_sro : process(clk)
>>> begin
>>> if rising_edge(clk) then
>>> if (s_sample = '1') then
>>> -- Put all of the code you have that was previously within
>>> -- the "if rising_edge(s_sample) then" statement here
>>> end if;
>>> end if;
>>> end process read_src;
>>
>>> The reason that generated clocks are bad news in an FPGA is that you have essentially zero control over signal skew. A signal generated in one clock domain can, depending on the routing, make it over into the other clock domain even before the generated clock gets there, or perhaps after. In your case, you really have no way to say what skew there is between 'clk' and 's_sample'. The signals 'sr_burst_ena' and 'dec_shift_ena' are used in both of your processes and yet each can only be valid in one clock domain (your posted code does not show those signal assignments so it is not clear in which domain they have been generated, but I suspect it is in 'clk').
>>
>>> Kevin Jennings
>>
>> Kevin
>>
>> Thanks for your input!
>>
>> I know that this does not result in a synchronous design, and I was
>> already thinking of rewriting it with clock enables, as you suggested.
>>
>> However, this was done because, in this case, there is no signal
>> generated in the "clk" domain that is read by "s_sample". Actually
>> "s_sample" is only used to read some signals from the outside world and
>> the shift register more or less tries to correlate what is read in the
>> present cycle with the previous ones.
>>
>> Is it correct to say that, in this case, "it doesn't matter"?
>>
>> Now, completely agreeing with your observation, I am still puzzled by
>> the fact that the even the RTL simulation (which I assume does not take
>> any delays into account) is not working properly. If you have a look at
>> the simulation results, this is absolutely not a shift register!
>>
>> It seems that Altera's synthesis tool infers something quite
>> different... but why??
>>
>> Pere
>
> Your design is synchronous, but you have more than one clock, so you
> need to be sure of the timing of signals that cross the clock
> domains. For example, the signals sr_clear, sr_burst_ena and
> dec_shift_ena seem to be used in both the clk and the s_sample clock
> domains without being synchonized. I guess that might be ok if you
> can make sure the delays in the s_sample clock don't result in one of
> these signals changing on the edge of either clock.
>
> If the simulation is not what you want, then there is likely something
> wrong with the code. But remember that while the simulation does not
> account for logic delays, there are delta delays that mean signals
> clocked by clk will have already changed by the time the remaining
> code sees the change in s_sample.
>
> Rick
Hi, Rick
the signals you are mentioning are being updated in the same
process(clk) that creates s_sample. They are only read in the
process(s_sample) as shown. However, there are no timing issues with
this showing up in the post-route simulation (in hindsight, perhaps I
was too lucky with this).
Otoh, the main point is that one simulation does what I want (and
corresponds with the intended behaviour: the GHDL result) but the other
one does not! GHDL simulates the semantics of VHDL, and Simulink
simulates what Quartus' synthesis has inferred -which does not seem to
be the same!
Pere
Pere
|
|
0
|
|
|
|
Reply
|
me1756 (19)
|
7/12/2012 7:35:07 AM
|
|
o pere o <me@somewhere.net> wrote:
(snip, I wrote)
>> You don't show where dec_shift_ena comes from.
> Sorry for the omission!
> dec_shift_ena is generated as follows.
> First, I have a counter the is reset periodically:
> clock_counter: process(clk) --counter counting over the symbol length
> begin
> if rising_edge(clk) then
> if tc_symbol = '1' then
> clk_count <= 0;
> else
> clk_count <= clk_count + 1;
> end if;
> end if;
> end process clock_counter;
> tc_symbol <= '1' when clk_count=c_ticks_per_symbol-1 else '0';
> From this counter, I also generate some time markers, such as
> dec_shift_ena_pre <= '1' when (clk_count >= ...) and (...)
> else '0';
> which are resynchronized in
I read verilog much better, but this sounds suspicious.
Why does it need resynchronizing?
> process(clk)
> begin
> if rising_edge(clk) then
> ...
> dec_shift_ena <= dec_shift_ena_pre;
> end if;
> end process;
-- glen
|
|
0
|
|
|
|
Reply
|
gah (12261)
|
7/12/2012 12:55:52 PM
|
|
On 07/12/2012 02:55 PM, glen herrmannsfeldt wrote:
> o pere o<me@somewhere.net> wrote:
>
> (snip, I wrote)
>>> You don't show where dec_shift_ena comes from.
>
>> Sorry for the omission!
>
>> dec_shift_ena is generated as follows.
>> First, I have a counter the is reset periodically:
>
>> clock_counter: process(clk) --counter counting over the symbol length
>> begin
>> if rising_edge(clk) then
>> if tc_symbol = '1' then
>> clk_count<= 0;
>> else
>> clk_count<= clk_count + 1;
>> end if;
>> end if;
>> end process clock_counter;
>> tc_symbol<= '1' when clk_count=c_ticks_per_symbol-1 else '0';
>
>> From this counter, I also generate some time markers, such as
>
>> dec_shift_ena_pre<= '1' when (clk_count>= ...) and (...)
>> else '0';
>
>> which are resynchronized in
>
> I read verilog much better, but this sounds suspicious.
> Why does it need resynchronizing?
Being a combinational assignment, it is subject to glitches. The
instants where they happen seemed to upset the post-route simulation,
with complaints of hold time to short (iirc). BTW, the timing analyser
did not complain at all. Making them a registered signal (and
pre-compensating the one-cycle delay) cleared glitches and moved the
transitions so that simulation goes ok.
Pere
>
>> process(clk)
>> begin
>> if rising_edge(clk) then
>> ...
>> dec_shift_ena<= dec_shift_ena_pre;
>> end if;
>> end process;
>
> -- glen
|
|
0
|
|
|
|
Reply
|
me1756 (19)
|
7/12/2012 2:42:16 PM
|
|
On Jul 12, 3:35=A0am, o pere o <m...@somewhere.net> wrote:
> On 07/11/2012 10:13 PM, rickman wrote:
>
>
>
>
>
>
>
>
>
> > On Jul 11, 12:48 pm, o pere o<m...@somewhere.net> =A0wrote:
> >> On 07/11/2012 02:02 PM, KJ wrote:
>
> >>> On Wednesday, July 11, 2012 7:23:51 AM UTC-4, o pere o wrote:
> >>>> Hi,
>
> >>>> I am not an FPGA expert although this is not my first design. The
> >>>> problem that I am having for two days now, is that I am observing
> >>>> different results when simulating a design in GHDL and in Modelsim
> >>>> ALTERA starter edition.
>
> >>>> The design includes a shift register. The significant code is:
>
> >>>> =A0 =A0 =A0read_sro : process(s_sample)
> >>>> =A0 =A0 =A0begin
> >>>> =A0 =A0 =A0 =A0if rising_edge(s_sample) then
> >>>> =A0 =A0 =A0 =A0 =A0if ... --irrelevant here
> >>>> =A0 =A0 =A0 =A0 =A0end if;
> >>>> =A0 =A0 =A0 =A0 =A0if ...
> >>>> =A0 =A0 =A0 =A0 =A0end if;
> >>>> =A0 =A0 =A0 =A0 =A0if sr_burst_ena =3D'1' then =A0--First ph=
ase: store data in shift_reg
> >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0new_data<=3D sr_sro_wave& new_data=
(c_burst_no-1 downto 1);
> >>>> =A0 =A0 =A0 =A0 =A0 elsif dec_shift_ena =3D'1' then --Second=
phase: rotate data
>
> >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0new_data<=3D new_data(0)& new_data=
(c_burst_no-1 downto 1);
>
> >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0--irrelevant, but included for completene=
ss
> >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0max_cnt<=3D max_cnt + 1;
> >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0if usum> max then
> >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 max<=3D usum;
> >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 max_pos<=3D max_cnt;
> >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0end if;
> >>>> =A0 =A0 =A0 =A0 =A0 end if;
> >>>> =A0 =A0 =A0 =A0end if;
> >>>> =A0 =A0 =A0end process read_sro;
>
> >>>> the clock signal s_sample is obtained from the main 50 MHz clock wit=
h
> >>>> the following process:
>
> >>>> sr_signals : process(clk)
> >>>> begin
> >>>> =A0 =A0 =A0 if rising_edge(clk) then
> >>>> =A0 =A0 =A0 =A0 if sr_clear =3D'1' or sr_burst_ena =3D'1=
' or dec_shift_ena =3D'1' then
> >>>> =A0 =A0 =A0 =A0 =A0 =A0 =A0s_sample<=3D not s_sample;
> >>>> =A0 =A0 =A0 =A0 end if;
> >>>> =A0 =A0 =A0 ...
> >>>> =A0 =A0 =A0 end if;
> >>>> end process sr_signals;
>
> >>>> I have uploaded some screenshots here:
>
> >>>> 1- ghdl+gtkwave resulthttp://tinypic.com/r/wklimq/6
> >>>> 2- simulinkhttp://tinypic.com/r/2le743t/6
>
> >>>> It may be seen that the input signal (top signal in the GHDL result =
and
> >>>> third from the top in SIMULINK) is zero during the first 5 s_sample
> >>>> clocks, then is at one during 10 clocks and zero again for the rest =
of
> >>>> the (up to 20) clocks.
>
> >>>> The GHDL simulation shows up ok, with the register correctly loaded =
with
> >>>> 0000011111111110000 after the 20 clocks, however Altera's quartu=
s gives
> >>>> 00000111110000011111.
>
> >>>> Exactly the same file is being fed to to Quartus II for synthesis!! =
But
> >>>> Alteras RTL (and gate level) simulations do not behave as intended.
>
> >>>> Is there something with the coding style than can make Quartus infer=
an
> >>>> absolutely different behaviour? Any help is very much appreciated!!
>
> >>>> Pere
>
> >>> By generating an internal clock signal you're not following synchrono=
us design practice. =A0In an FPGA design that spells trouble. =A0What you n=
eed to do to make it synchronous is:
>
> >>> - Change the 'sr_signals' process that currently generates 's_sample'=
.. =A0What you'll want is for 's_sample' to be a one clock cycle pulse at th=
e appropriate time. =A0Modify your if statement to accomplish this.
> >>> - Modify the 'read_src' process to use the free running clock and 's_=
sample' like this
>
> >>> read_sro : process(clk)
> >>> begin
> >>> =A0 =A0 =A0 if rising_edge(clk) then
> >>> =A0 =A0 =A0 =A0 =A0if (s_sample =3D '1') then
> >>> =A0 =A0 =A0 =A0 =A0 =A0 -- Put all of the code you have that was prev=
iously within
> >>> =A0 =A0 =A0 =A0 =A0 =A0 -- the "if rising_edge(s_sample) then" statem=
ent here
> >>> =A0 =A0 =A0 =A0 =A0end if;
> >>> =A0 =A0 =A0 end if;
> >>> end process read_src;
>
> >>> The reason that generated clocks are bad news in an FPGA is that you =
have essentially zero control over signal skew. =A0A signal generated in on=
e clock domain can, depending on the routing, make it over into the other c=
lock domain even before the generated clock gets there, or perhaps after. =
=A0In your case, you really have no way to say what skew there is between '=
clk' and 's_sample'. =A0The signals 'sr_burst_ena' and 'dec_shift_ena' are =
used in both of your processes and yet each can only be valid in one clock =
domain (your posted code does not show those signal assignments so it is no=
t clear in which domain they have been generated, but I suspect it is in 'c=
lk').
>
> >>> Kevin Jennings
>
> >> Kevin
>
> >> Thanks for your input!
>
> >> I know that this does not result in a synchronous design, and I was
> >> already thinking of rewriting it with clock enables, as you suggested.
>
> >> However, this was done because, in this case, there is no signal
> >> generated in the "clk" domain that is read by "s_sample". Actually
> >> "s_sample" is only used to read some signals from the outside world an=
d
> >> the shift register more or less tries to correlate what is read in the
> >> present cycle with the previous ones.
>
> >> Is it correct to say that, in this case, "it doesn't matter"?
>
> >> Now, completely agreeing with your observation, I am still puzzled by
> >> the fact that the even the RTL simulation (which I assume does not tak=
e
> >> any delays into account) is not working properly. If you have a look a=
t
> >> the simulation results, this is absolutely not a shift register!
>
> >> It seems that Altera's synthesis tool infers something quite
> >> different... but why??
>
> >> Pere
>
> > Your design is synchronous, but you have more than one clock, so you
> > need to be sure of the timing of signals that cross the clock
> > domains. =A0For example, the signals sr_clear, sr_burst_ena and
> > dec_shift_ena seem to be used in both the clk and the s_sample clock
> > domains without being synchonized. =A0I guess that might be ok if you
> > can make sure the delays in the s_sample clock don't result in one of
> > these signals changing on the edge of either clock.
>
> > If the simulation is not what you want, then there is likely something
> > wrong with the code. =A0But remember that while the simulation does not
> > account for logic delays, there are delta delays that mean signals
> > clocked by clk will have already changed by the time the remaining
> > code sees the change in s_sample.
>
> > Rick
>
> Hi, Rick
>
> the signals you are mentioning are being updated in the same
> process(clk) that creates s_sample. They are only read in the
> process(s_sample) as shown. However, there are no timing issues with
> this showing up in the post-route simulation (in hindsight, perhaps I
> was too lucky with this).
>
> Otoh, the main point is that one simulation does what I want (and
> corresponds with the intended behaviour: the GHDL result) but the other
> one does not! GHDL simulates the semantics of VHDL, and Simulink
> simulates what Quartus' synthesis has inferred -which does not seem to
> be the same!
>
> Pere
>
> Pere
I don't know why you are expecting to see your problems or solutions
in any simulation. A post route simulation uses typical timings and
can't be expected to be 100% realistic, even a chip can't be expected
to be the same as another chip. That is why they use synchronous
concepts, meet the cycle timing and all other timing issues are
handled by the chip qualification and the design tools.
If the signal is generated in the clk domain and s_sample is generated
in the clk domain, you can't predict which delay will be longer and
you have a race condition between all the signals and the s_sample
clock. One thing that would help is to generate the signals on one
edge of clk and generate s_sample on the other edge of clk. Then you
know the timing on a course level and can constrain the timing of
paths from the clk to the s_sample clock domain... or just use an
enable instead of generating a new clock.
If you don't believe the timing is a problem, draw a timing diagram
showing *all* delays. You will see the routing delay of s_sample can
be giving you trouble.
Rick
|
|
0
|
|
|
|
Reply
|
gnuarm (2644)
|
7/12/2012 4:45:49 PM
|
|
On Jul 12, 10:42=A0am, o pere o <m...@somewhere.net> wrote:
> On 07/12/2012 02:55 PM, glen herrmannsfeldt wrote:
>
>
> > o pere o<m...@somewhere.net> =A0wrote:
>
> > (snip, I wrote)
> >>> You don't show where dec_shift_ena comes from.
>
> >> Sorry for the omission!
>
> >> dec_shift_ena is generated as follows.
> >> First, I have a counter the is reset periodically:
>
> >> clock_counter: process(clk) --counter counting over the symbol length
> >> =A0 =A0begin
> >> =A0 =A0 =A0if rising_edge(clk) then
> >> =A0 =A0 =A0 =A0 if tc_symbol =3D '1' then
> >> =A0 =A0 =A0 =A0 =A0 =A0clk_count<=3D 0;
> >> =A0 =A0 =A0 =A0 else
> >> =A0 =A0 =A0 =A0 =A0 =A0clk_count<=3D clk_count + 1;
> >> =A0 =A0 =A0 =A0 end if;
> >> =A0 =A0 =A0end if;
> >> =A0 =A0end process clock_counter;
> >> =A0 =A0tc_symbol<=3D '1' when clk_count=3Dc_ticks_per_symbol-1 else '0=
';
>
> >> =A0From this counter, I also generate some time markers, such as
>
> >> =A0 =A0dec_shift_ena_pre<=3D '1' when (clk_count>=3D ...) and (...)
> >> =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 =A0 else '0';
>
> >> which are resynchronized in
>
> > I read verilog much better, but this sounds suspicious.
> > Why does it need resynchronizing?
>
> Being a combinational assignment, it is subject to glitches. The
> instants where they happen seemed to upset the post-route simulation,
> with complaints of hold time to short (iirc). BTW, the timing analyser
> did not complain at all. Making them a registered signal (and
> pre-compensating the one-cycle delay) cleared glitches and moved the
> transitions so that simulation goes ok.
>
> Pere
>
>
> >> =A0 process(clk)
> >> =A0 =A0begin
> >> =A0 =A0 =A0 if rising_edge(clk) then
> >> =A0 =A0 =A0 =A0 =A0...
> >> =A0 =A0 =A0 =A0 =A0dec_shift_ena<=3D dec_shift_ena_pre;
> >> =A0 =A0 =A0 end if;
> >> =A0 =A0end process;
>
> > -- glen
There is a problem. dec_shift_ena was transitioning in the setup/hold
time window of s_sample because the logic/routing delays of the two
paths were too close to equal. The signal needs to be synced, but not
to the clk domain, to the s_sample domain! Better to change the
timing altogether by generating s_sample on the opposite edge of
clk... or like I said above, use an enable rather than a new clock.
Rick
|
|
0
|
|
|
|
Reply
|
gnuarm (2644)
|
7/12/2012 4:51:18 PM
|
|
On Thursday, July 12, 2012 12:51:18 PM UTC-4, rickman wrote:
>
> There is a problem. dec_shift_ena was transitioning in the setup/hold
> time window of s_sample because the logic/routing delays of the two
> paths were too close to equal. The signal needs to be synced, but not
> to the clk domain, to the s_sample domain! Better to change the
> timing altogether by generating s_sample on the opposite edge of
> clk... or like I said above, use an enable rather than a new clock.
>
> Rick
I pointed out exactly these points (use a clock enable and that he was using two signals in two different clock domains) in the very first reply to his post...maybe it will click this time.
KJ
|
|
0
|
|
|
|
Reply
|
kkjennings (124)
|
7/12/2012 7:32:41 PM
|
|
On 07/11/2012 01:23 PM, o pere o wrote:
> Hi,
>
> I am not an FPGA expert although this is not my first design. The
> problem that I am having for two days now, is that I am observing
> different results when simulating a design in GHDL and in Modelsim
> ALTERA starter edition.
>
> The design includes a shift register. The significant code is:
>
> read_sro : process(s_sample)
> begin
> if rising_edge(s_sample) then
> if ... --irrelevant here
> end if;
> if ...
> end if;
> if sr_burst_ena = '1' then --First phase: store data in shift_reg
> new_data <= sr_sro_wave & new_data(c_burst_no-1 downto 1);
> elsif dec_shift_ena = '1' then --Second phase: rotate data
>
> new_data <= new_data(0) & new_data(c_burst_no-1 downto 1);
>
> --irrelevant, but included for completeness
> max_cnt <= max_cnt + 1;
> if usum > max then
> max <= usum;
> max_pos <= max_cnt;
> end if;
> end if;
> end if;
> end process read_sro;
>
> the clock signal s_sample is obtained from the main 50 MHz clock with
> the following process:
>
> sr_signals : process(clk)
> begin
> if rising_edge(clk) then
> if sr_clear = '1' or sr_burst_ena = '1' or dec_shift_ena ='1' then
> s_sample <= not s_sample;
> end if;
> ...
> end if;
> end process sr_signals;
>
> I have uploaded some screenshots here:
>
> 1- ghdl+gtkwave result http://tinypic.com/r/wklimq/6
> 2- simulink http://tinypic.com/r/2le743t/6
>
> It may be seen that the input signal (top signal in the GHDL result and
> third from the top in SIMULINK) is zero during the first 5 s_sample
> clocks, then is at one during 10 clocks and zero again for the rest of
> the (up to 20) clocks.
>
> The GHDL simulation shows up ok, with the register correctly loaded with
> 0000011111111110000 after the 20 clocks, however Altera's quartus gives
> 00000111110000011111.
>
> Exactly the same file is being fed to to Quartus II for synthesis!! But
> Alteras RTL (and gate level) simulations do not behave as intended.
>
> Is there something with the coding style than can make Quartus infer an
> absolutely different behaviour? Any help is very much appreciated!!
>
> Pere
>
Thanks to everybody for your inputs. Making the whole design work on
only one clock (with suitable enables) solves the issue. This is really
not a surprise.
However, I still have some questions on this. If I built my design from,
lets say, discrete components, I might have problems with setup and hold
times at the shift register (SR) input, but I would NEVER EVER get the
results that showed up in the simulation:
The SR was initially cleared. The serial input to the SR is zero at the
first clock but, surprisingly, a one appears at the 9th (!!) SR output
after the first edge of the clock. Can anybody find a plausible
explanation for this?
The second question is, is there a way to tell Quartus that it should
synthesize something that resembles the physical circuit? I did tell
Quartus that s_sample was a clock (and told the frequency), however this
was obviously not sufficient. Any thoughts?
Pere
|
|
0
|
|
|
|
Reply
|
me1756 (19)
|
7/13/2012 3:20:27 PM
|
|
On Jul 13, 11:20=A0am, o pere o <m...@somewhere.net> wrote:
> On 07/11/2012 01:23 PM, o pere o wrote:
>
>
>
>
>
>
>
>
>
> > Hi,
>
> > I am not an FPGA expert although this is not my first design. The
> > problem that I am having for two days now, is that I am observing
> > different results when simulating a design in GHDL and in Modelsim
> > ALTERA starter edition.
>
> > The design includes a shift register. The significant code is:
>
> > read_sro : process(s_sample)
> > begin
> > if rising_edge(s_sample) then
> > if ... --irrelevant here
> > end if;
> > if ...
> > end if;
> > if sr_burst_ena =3D '1' then --First phase: store data in shift_reg
> > new_data <=3D sr_sro_wave & new_data(c_burst_no-1 downto 1);
> > elsif dec_shift_ena =3D '1' then --Second phase: rotate data
>
> > new_data <=3D new_data(0) & new_data(c_burst_no-1 downto 1);
>
> > --irrelevant, but included for completeness
> > max_cnt <=3D max_cnt + 1;
> > if usum > max then
> > max <=3D usum;
> > max_pos <=3D max_cnt;
> > end if;
> > end if;
> > end if;
> > end process read_sro;
>
> > the clock signal s_sample is obtained from the main 50 MHz clock with
> > the following process:
>
> > sr_signals : process(clk)
> > begin
> > if rising_edge(clk) then
> > if sr_clear =3D '1' or sr_burst_ena =3D '1' or dec_shift_ena =3D'1' the=
n
> > s_sample <=3D not s_sample;
> > end if;
> > ...
> > end if;
> > end process sr_signals;
>
> > I have uploaded some screenshots here:
>
> > 1- ghdl+gtkwave resulthttp://tinypic.com/r/wklimq/6
> > 2- simulinkhttp://tinypic.com/r/2le743t/6
>
> > It may be seen that the input signal (top signal in the GHDL result and
> > third from the top in SIMULINK) is zero during the first 5 s_sample
> > clocks, then is at one during 10 clocks and zero again for the rest of
> > the (up to 20) clocks.
>
> > The GHDL simulation shows up ok, with the register correctly loaded wit=
h
> > 0000011111111110000 after the 20 clocks, however Altera's quartus gives
> > 00000111110000011111.
>
> > Exactly the same file is being fed to to Quartus II for synthesis!! But
> > Alteras RTL (and gate level) simulations do not behave as intended.
>
> > Is there something with the coding style than can make Quartus infer an
> > absolutely different behaviour? Any help is very much appreciated!!
>
> > Pere
>
> Thanks to everybody for your inputs. Making the whole design work on
> only one clock (with suitable enables) solves the issue. This is really
> not a surprise.
>
> However, I still have some questions on this. If I built my design from,
> lets say, discrete components, I might have problems with setup and hold
> times at the shift register (SR) input, but I would NEVER EVER get the
> results that showed up in the simulation:
>
> The SR was initially cleared. The serial input to the SR is zero at the
> first clock but, surprisingly, a one appears at the 9th (!!) SR output
> after the first edge of the clock. Can anybody find a plausible
> explanation for this?
>
> The second question is, is there a way to tell Quartus that it should
> synthesize something that resembles the physical circuit? I did tell
> Quartus that s_sample was a clock (and told the frequency), however this
> was obviously not sufficient. Any thoughts?
>
> Pere
I can't answer question one, but the answer is in the code and the
simulation. If necessary you will need to step through the code that
assigns a value to the SR, but the answer will be there. The real
point is that it doesn't matter really. The simulation told you
something was wrong and you found the problem. Is it important to
understand how the error was generated?
The second question is easy. You don't tell the tool what the
"physical circuit" is really. The tool tells you! Telling Quartus
that your clock is a clock shouldn't be needed as it can figure that
out because the signal is clocking FFs. There was no problem with the
tool. The problem was exactly as KJ described in his first post, once
you create a clock from logic, you can't control the skew between the
two clocks and so lose control over setup and hold times. The tool
also looses control over this as it depends on things the tool can't
control or even know about, the exact detailed timing of the chip.
In summary, generating clocks is bad ju-ju. Don't cross the beams.
Rick
|
|
0
|
|
|
|
Reply
|
gnuarm (2644)
|
7/13/2012 3:37:33 PM
|
|
On 07/13/2012 05:37 PM, rickman wrote:
> On Jul 13, 11:20 am, o pere o<m...@somewhere.net> wrote:
>> On 07/11/2012 01:23 PM, o pere o wrote:
>>
>>
>>
>>
>>
>>
>>
>>
>>
>>> Hi,
>>
>>> I am not an FPGA expert although this is not my first design. The
>>> problem that I am having for two days now, is that I am observing
>>> different results when simulating a design in GHDL and in Modelsim
>>> ALTERA starter edition.
>>
>>> The design includes a shift register. The significant code is:
>>
>>> read_sro : process(s_sample)
>>> begin
>>> if rising_edge(s_sample) then
>>> if ... --irrelevant here
>>> end if;
>>> if ...
>>> end if;
>>> if sr_burst_ena = '1' then --First phase: store data in shift_reg
>>> new_data<= sr_sro_wave& new_data(c_burst_no-1 downto 1);
>>> elsif dec_shift_ena = '1' then --Second phase: rotate data
>>
>>> new_data<= new_data(0)& new_data(c_burst_no-1 downto 1);
>>
>>> --irrelevant, but included for completeness
>>> max_cnt<= max_cnt + 1;
>>> if usum> max then
>>> max<= usum;
>>> max_pos<= max_cnt;
>>> end if;
>>> end if;
>>> end if;
>>> end process read_sro;
>>
>>> the clock signal s_sample is obtained from the main 50 MHz clock with
>>> the following process:
>>
>>> sr_signals : process(clk)
>>> begin
>>> if rising_edge(clk) then
>>> if sr_clear = '1' or sr_burst_ena = '1' or dec_shift_ena ='1' then
>>> s_sample<= not s_sample;
>>> end if;
>>> ...
>>> end if;
>>> end process sr_signals;
>>
>>> I have uploaded some screenshots here:
>>
>>> 1- ghdl+gtkwave resulthttp://tinypic.com/r/wklimq/6
>>> 2- simulinkhttp://tinypic.com/r/2le743t/6
>>
>>> It may be seen that the input signal (top signal in the GHDL result and
>>> third from the top in SIMULINK) is zero during the first 5 s_sample
>>> clocks, then is at one during 10 clocks and zero again for the rest of
>>> the (up to 20) clocks.
>>
>>> The GHDL simulation shows up ok, with the register correctly loaded with
>>> 0000011111111110000 after the 20 clocks, however Altera's quartus gives
>>> 00000111110000011111.
>>
>>> Exactly the same file is being fed to to Quartus II for synthesis!! But
>>> Alteras RTL (and gate level) simulations do not behave as intended.
>>
>>> Is there something with the coding style than can make Quartus infer an
>>> absolutely different behaviour? Any help is very much appreciated!!
>>
>>> Pere
>>
>> Thanks to everybody for your inputs. Making the whole design work on
>> only one clock (with suitable enables) solves the issue. This is really
>> not a surprise.
>>
>> However, I still have some questions on this. If I built my design from,
>> lets say, discrete components, I might have problems with setup and hold
>> times at the shift register (SR) input, but I would NEVER EVER get the
>> results that showed up in the simulation:
>>
>> The SR was initially cleared. The serial input to the SR is zero at the
>> first clock but, surprisingly, a one appears at the 9th (!!) SR output
>> after the first edge of the clock. Can anybody find a plausible
>> explanation for this?
>>
>> The second question is, is there a way to tell Quartus that it should
>> synthesize something that resembles the physical circuit? I did tell
>> Quartus that s_sample was a clock (and told the frequency), however this
>> was obviously not sufficient. Any thoughts?
>>
>> Pere
>
> I can't answer question one, but the answer is in the code and the
> simulation. If necessary you will need to step through the code that
> assigns a value to the SR, but the answer will be there. The real
> point is that it doesn't matter really. The simulation told you
> something was wrong and you found the problem. Is it important to
> understand how the error was generated?
Well, I am now just curious to know what happened to cause this
behavior. Most of us learn much more from errors than from blindly
following the rules. And I already looked at the code (actually I posted
the lines that update de SR) and I also looked at the synthesized
circuit. Nothing special there!
> The second question is easy. You don't tell the tool what the
> "physical circuit" is really. The tool tells you! Telling Quartus
> that your clock is a clock shouldn't be needed as it can figure that
> out because the signal is clocking FFs. There was no problem with the
> tool. The problem was exactly as KJ described in his first post, once
> you create a clock from logic, you can't control the skew between the
> two clocks and so lose control over setup and hold times. The tool
> also looses control over this as it depends on things the tool can't
> control or even know about, the exact detailed timing of the chip.
I can follow this reasoning. However, the result of this should be a
setup or hold time violation signaled by the simulator, shouldn't it?
But the simulator did NOT show any of them. Instead, a completely bogus
behavior was observed. Nothing special was reported except the result
being completely wrong.
> In summary, generating clocks is bad ju-ju. Don't cross the beams.
Ok. I will highlight this dogma once more ;)
> Rick
Thank you for your time!
Pere
|
|
0
|
|
|
|
Reply
|
me1756 (19)
|
7/13/2012 4:02:40 PM
|
|
On Friday, July 13, 2012 11:20:27 AM UTC-4, o pere o wrote:
> However, I still have some questions on this. If I built my design from,=
=20
> lets say, discrete components, I might have problems with setup and hold=
=20
> times at the shift register (SR) input, but I would NEVER EVER get the=20
> results that showed up in the simulation:
>=20
Yes you could. If you built a circuit with exactly the timing delays that =
were the result of simulation and did so with the same type of components u=
sed in the FPGA implementation (i.e. LUTs and FFs). It's probably not very=
likely that anyone could actually physically build such an accurate model =
out of discrete parts, but the point is that the simulator is not lying to =
you. It simulated a model that was provided to it.
> The SR was initially cleared. The serial input to the SR is zero at the=
=20
> first clock but, surprisingly, a one appears at the 9th (!!) SR output=20
> after the first edge of the clock. Can anybody find a plausible=20
> explanation for this?
>=20
Timing violation. In this case, it was most likely that a setup time requi=
rement was violated. The cause of this violation was due to the skew betwe=
en the two clock domains and the signals that crossed from one to the other=
..
Since you have the detailed model, you would have to track that one down an=
d since you are rightly interested in getting to the bottom of this you sho=
uld do so. The method I would suggest you follow is to use the original RT=
L that works as you expect as the 'golden' model and compare the simulation=
results to that of the 'failing' model. One way to do this is to
- Create a testbench that instantiates both models
- Connect all inputs to both models
- Run the simulation up until the outputs of the two models diverge
- Look at the input to the logic that creates the failing output and determ=
ine if why the output is wrong (which is generally because the input is wro=
ng...which means you iterate on this step until you finally come across the=
root cause signal that started the cascade of bad)
> The second question is, is there a way to tell Quartus that it should=20
> synthesize something that resembles the physical circuit? I did tell=20
> Quartus that s_sample was a clock (and told the frequency), however this=
=20
> was obviously not sufficient. Any thoughts?
>=20
Unless you describe your logic in the form of lookup tables and flip flops,=
Quartus will never be able to "synthesize something that resembles the phy=
sical circuit". Your source code describes a logic function description. =
Synthesis takes that description as input and produces a bitstream that can=
be loaded into a device that will then implement that function. If you cr=
eate timing problems that's a design issue (i.e. you described a function t=
hat has a design flaw). In many cases, such design issues are beyond the s=
cope of the tool.
Kevin Jennings
|
|
0
|
|
|
|
Reply
|
kkjennings (124)
|
7/13/2012 4:41:32 PM
|
|
On Friday, July 13, 2012 12:02:40 PM UTC-4, o pere o wrote:
> I can follow this reasoning. However, the result of this should be a=20
> setup or hold time violation signaled by the simulator, shouldn't it?=
=20
> But the simulator did NOT show any of them. Instead, a completely bogus=
=20
> behavior was observed. Nothing special was reported except the result=20
> being completely wrong.
>=20
Simulators don't necessarily catch timing violations. That is the job for =
a static timing analysis tool. However, even STA doesn't catch problems wh=
en the constraints are not properly defined. In this case, did you tell Qu=
artus to ignore clock domain crossings when performing timing analysis? If=
I recall correctly, Quartus defaults to this setting and you have to actua=
lly tell it to perform the cross clock domain timing analysis.
In short, there are a lot more requirements that need to be defined correct=
ly in order for static timing analysis to be correctly performed (and no go=
od way to validate that you have really got those requirement correctly spe=
cified). But when you do specify all the requirements correctly, the timin=
g analysis tool will catch and report the problems. A simulator might get =
lucky and catch something, but it will miss far more errors because it is n=
ot equipped to simulate function in a manner equivalent to how you perform =
static timing analysis.
Kevin Jennings
|
|
0
|
|
|
|
Reply
|
kkjennings (124)
|
7/13/2012 4:47:31 PM
|
|
o pere o <me@somewhere.net> wrote:
(snip)
> Well, I am now just curious to know what happened to cause this
> behavior. Most of us learn much more from errors than from blindly
> following the rules. And I already looked at the code (actually I
> posted the lines that update de SR) and I also looked at the
> synthesized circuit. Nothing special there!
If you wrote it in verilog, I might be able to figure it out.
My only guess is that there is a glitch on the generated clock.
That is, it clocks twice when you think it clocks only once.
Simulated clocks can have infinitesimal delay and still clock the FF.
Real gates won't be able to do that, at least not infinitesimally.
With enough delay, you can get a real glitch that can clock
a real FF. Another reason for synchronous logic.
The old favorite from asynchronous logic days was generating
a counter reset from the output of a ripple counter. In some
cases, the reset pulse is too short to reset all the FFs, though
that depends on the logic being especially fast and the FFs slow.
Usually it won't glitch, but I am not sure it isn't possible.
(That is, when the reset is also used to clock the next FF.)
(Use a 74L74 FF and 74S00 to generate the (not) reset.
Except that I forget which FFs have an active low reset.)
-- glen
|
|
0
|
|
|
|
Reply
|
gah (12261)
|
7/13/2012 6:42:54 PM
|
|
KJ <kkjennings@sbcglobal.net> wrote:
(snip)
> Simulators don't necessarily catch timing violations.
> That is the job for a static timing analysis tool.
> However, even STA doesn't catch problems when the constraints
> are not properly defined.
What does it do in the case of internally generated clocks.
> In this case, did you tell Quartus to ignore clock domain
> crossings when performing timing analysis?
If you have multiple clock inputs to the logic, then I might
see what it would do for static timing. If you generate a
clock internally, then it isn't so obvious.
> If I recall correctly, Quartus defaults to this setting
> and you have to actually tell it to perform the cross
> clock domain timing analysis.
-- glen
|
|
0
|
|
|
|
Reply
|
gah (12261)
|
7/13/2012 6:46:11 PM
|
|
o pere o wrote:
>
> However, I still have some questions on this. If I built my design from,
> lets say, discrete components, I might have problems with setup and hold
> times at the shift register (SR) input, but I would NEVER EVER get the
> results that showed up in the simulation:
>
> The SR was initially cleared. The serial input to the SR is zero at the
> first clock but, surprisingly, a one appears at the 9th (!!) SR output
> after the first edge of the clock. Can anybody find a plausible
> explanation for this?
>
In FPGA hardware, easily! Xilinx guarantees their LUTs to be glitch-free
by themselves, but as has been pointed out here before, when multiple
LUTs are strung together with routing delays between them, all bets are
off. Can't say about glitch behavior on Altera, but I suspect similar
things. Then, the tools pack logic into the LUTs as they fit best,
without any attention to making sure glitches can't propagate.
Now, why this behavior showed up in simulation is not clear.
But, again, if you do things that are really wrong in the HDL,
it is possible the simulator just fouls up.
> The second question is, is there a way to tell Quartus that it should
> synthesize something that resembles the physical circuit? I did tell
> Quartus that s_sample was a clock (and told the frequency), however this
> was obviously not sufficient. Any thoughts?
To some extent, but it reveals you are trying to do something that
is bending the tools and FPGA in a way they were not designed for,
and will usually lead to trouble. Some people do special things
in very special cases such as all-silicon ring oscillators where they
are using special knowledge of the internal workings to do what the
tools can't handle, but they then have to test the results carefully.
It is far better to describe in the HDL the behavior you want and
let the tools fit that onto the chip's internal architecture.
Jon
|
|
0
|
|
|
|
Reply
|
jmelson1 (65)
|
7/13/2012 7:11:20 PM
|
|
Jon Elson <jmelson@wustl.edu> wrote:
(snip)
>> However, I still have some questions on this. If I built my design from,
>> lets say, discrete components, I might have problems with setup and hold
>> times at the shift register (SR) input, but I would NEVER EVER get the
>> results that showed up in the simulation:
I am not so sure about that.
(snip)
> In FPGA hardware, easily! Xilinx guarantees their LUTs to be glitch-free
> by themselves, but as has been pointed out here before, when multiple
> LUTs are strung together with routing delays between them, all bets are
> off. Can't say about glitch behavior on Altera, but I suspect similar
> things. Then, the tools pack logic into the LUTs as they fit best,
> without any attention to making sure glitches can't propagate.
If they want to work like gates, then they shouldn't glitch in the
case where individual gates won't glitch. I suppose if you use
only synchronous design techniques then maybe there are no cases
where it matters. As far as I know, FPGAs don't require that.
> Now, why this behavior showed up in simulation is not clear.
> But, again, if you do things that are really wrong in the HDL,
> it is possible the simulator just fouls up.
Without seeing it in verilog, I don't see it either.
Reasonably likely it would be too fast for an actual FF, which
I think means it violates setup and/or hold.
-- glen
|
|
0
|
|
|
|
Reply
|
gah (12261)
|
7/13/2012 8:05:12 PM
|
|
|
20 Replies
51 Views
(page loaded in 0.272 seconds)
|