Simulation and realworld problem in design - what is wrong?

P

Preben Holm

Guest
Hi,

(question first asked in comp.arch.fpga, but think it probably suits
this group better since this more a VHDL question than FPGA in general
question)

I wonder why this results in undefined values (further comments in
bottom of post):

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

-- Uncomment the following lines to use the declarations that are
-- provided for instantiating Xilinx primitive components.
--library UNISIM;
--use UNISIM.VComponents.all;

entity trigger_level is
Port ( clk : in std_logic;
prescale : in std_logic;
din : in std_logic_vector(7 downto 0);
level : in std_logic_vector(7 downto 0);
rf : in std_logic;
hold : in std_logic;
trig : out std_logic);
end trigger_level;

architecture Behavioral of trigger_level is
type samples_buffer is array(9 downto 0) of
std_logic_vector(7 downto 0);

signal samples : samples_buffer;
begin

process(clk)
begin
if rising_edge(clk) and prescale = '1' and hold = '0' then
-- no reset circuit (not needed) for reducing the number of
slices to 1 instead of 5
for i in 9 downto 1 loop
samples(i) <= samples(i-1);
end loop;
samples(0) <= din;
end if;
end process;


process(clk)
begin
if rising_edge(clk) then
if (rf = '1') then --- falling edge
if (samples(0) < level and samples(9) > level) then
trig <= '1';
else
trig <= '0';
end if;
elsif (rf = '0') then --- rising edge
if (samples(0) > level and samples(9) < level) then
trig <= '1';
else
trig <= '0';
end if;
else
trig <= '0';
end if;
end if;
end process;

end Behavioral;
----------------------------------


The design should be a trigger for an oscilloscope, and I think I have
an error in my design here! The trouble is that I get triggers where I
shouldn't! (or my presampler probably doesn't work, but I think this
simulation told me where the error was!)

The simulation "error" is viewable on my website:
http://www.interrupt.dk/sim.jpg

The trigger is a level/edge trigger that should activate on rising and
falling edges!



And like always: Thanks for helping

Preben Holm
 
i guess the problem comes as u have declared ur array as a signal.
Problem - why? Signal or variable - what's the difference in this case?
I often use signals because they give me less logic (in the tests I've
made)!

Now there are two processes, both sensitive to clock edges. And in
1st you r manipulating the array and at the same time in the second u r
using it to check some condition. This may result in simulation
mismatch.
But in the circuit could this give me any trouble? Is it just simulation
trouble?

I am not very sure but just try to declare both the tasks in
one process and declare ur array as a variable.
I'll try that?


Also one question . Why hav u used if .. elsif and else... as there
is only one parameter rf on which ur condition depends then u cud hav
used just if... else..... Have u used it bcoz it is declared as
std_logic and that u want to care for all the other levels? just
explain...
I've learned (read somewhere) that I should never use "bit" - rather use
"std_logic"! That's why!
 
Well the signal is already synchronized in the whole application.

Therefore I ran a simulation on the module itself with a generated pulse
with the "wizard".

All async. inputs are put into one or more flipflops to cure metastability.


Thanks for answering!
 
Preben Holm wrote:

The simulation "error" is viewable on my website:
http://www.interrupt.dk/sim.jpg
Looks like two processes are driving
the testbench signal /trigger_level_tb/trig.
The testbench should only be reading this
signal. Only the DUT instance port map should
drive it.

-- Mike Treseler
 
hi...
i guess the problem comes as u have declared ur array as a signal.
Now there are two processes, both sensitive to clock edges. And in
1st you r manipulating the array and at the same time in the second u r
using it to check some condition. This may result in simulation
mismatch. I am not very sure but just try to declare both the tasks in
one process and declare ur array as a variable.
Also one question . Why hav u used if .. elsif and else... as there
is only one parameter rf on which ur condition depends then u cud hav
used just if... else..... Have u used it bcoz it is declared as
std_logic and that u want to care for all the other levels? just
explain...
 
Your simulator is indicating a setup error for the flip-flop trig, and
trig depends on samples which is synchronous and rf which is probably
asynchronous. Samples also depends on both prescale and hold which are
presumably asynchronous with respect to clk. Any of the signals rf,
prescale or hold will cause real world problems with your design. They
should each be synchronized with clk by using a synchronizer. The
synchronizer many designers use is simply 2 D flip-flops A and B with
A's D input connected to the signal to be synchronized, B's D input
connected to A's output, their clock inputs connected to your system
clock (clk). You use the synchronizer's output instead of the
unsynchronized signal on the input of A. This may or may not cure your
simulation problem (because it is not a perfect solution), but you
should find that the real world circuit now performs properly.

Best regards,

Charles
 
Some changes maybe: IF-ELSIF-ELSE and additional ELSEs are
not needed. Makes the code more readable.

process(clk)
begin
if rising_edge(clk) then

trig <= '0';

if (rf = '1') then --- falling edge
if (samples(0) < level and samples(9) > level) then
trig <= '1';
end if;

else --- rising edge
if (samples(0) > level and samples(9) < level) then
trig <= '1';
end if;
end if;

end if;
end process;
 

Welcome to EDABoard.com

Sponsor

Back
Top