cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
4,131 Views
Registered: ‎01-13-2010

algorithm needed, please help!

Hello!

I need an algorithm for the following scenario:

Let's say I have an input called "start" that goes high for a very short period of time then goes low again. Say I have an output called "b" that goes high for one second as soon as "start" is detected to be high then goes low again.

Pretty easy to explain the scenario but I really can't think of how to code it in vhdl. Still, I tried my luck and came up with the following code:

-----------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;


entity delay is
port(b: out std_logic;
clock, start: in std_logic);
end delay;

architecture archi of delay is
constant counter: natural := 50e6;
signal enableCounter: natural range 0 to counter := 50e6; --- I am using spartan 3e which has a clock speed of 50MHz
signal tick: std_logic := '0';
begin

process (clock, start)
begin
if start = '1' then
if rising_edge(clock) then
tick <= '1';
case tick is
when '1' =>
b <= '1';
if enableCounter = 0 then
tick <= '0';
enableCounter <= counter;
else
enableCounter <= enableCounter - 1;
end if;
when '0' =>
b <= '0';
when others =>
end case;
end if;
end if;
   end process;
end archi;
-----------------------------

However, I know just by looking at the code that it's wrong as the line 'if start = '1' then' only gets evaluated for a very short time. Anyone who could perhaps improve the code or help me come up with a better algorithm?
Thanks in advance!

:)
0 Kudos
Reply
2 Replies
Teacher
Teacher
4,120 Views
Registered: ‎08-14-2007

Hi,

you have posted in the wrong group, since this is not an issue of timing analysis.

But here's some help anyway.

 

From your description I understand that you want to build some sort of monoflop.

A short trigger impulse shall cause a 1 sec impulse.

To keep it simple I explain it without a retrigger feature.

 

Your code has a big mistake:

 

process (clock, start)
  begin
if start = '1' then     <- This causes the rest of the code to be active only while the trigger is active. Big mistake!
if rising_edge(clock) then    <- This line and allthat follows possibly never ever will be active.
 
So, what's to do?
First, you have to decide, whether your trigger impulse is longer or shorter than the clock period.
In the first case you can write a simple synchronous process. like this:
 
begin
 if rising_edge(clock) then
   if triggered = '0' and start = '1' then
        triggered <= '1'; -- start detected
         Counter <= (others => '0');
   elsif triggered = '1'
      -- do some counting stuff
   elsif Counter = Maxcount then
    triggered <= '0'; --disable counter andprepare for nextstart
   end if;
end if;
end process;
 
You may fill this with the missing statements.
 
Now, if your start impulse is shorter than your clock period things become a little more tricky.
To catch the start impulse you can use an asynchronous set input of a FF:
 
begin
  if Reset = '1' then 
    Trigger_FF = '0';
  elsif start = '1' then 
    Trigger_FF <= '1'
  elsif rising_edge(Clock) then
     Trigger_FF <= Trigger_FF and not Stop;
  end if;
end process;
 
You need a second process to do the counting, and at the end of counting it has to disable the Trigger_FF by setting Stop for one clock period.
 
Have a nice synthesis
  Eilert
 
 

 

0 Kudos
Reply
4,106 Views
Registered: ‎01-13-2010

hello!

Sorry for posting on the wrong thread then. I'm working on this kinda big project now and I think I'm gonna need some help on the algo from time to time. So which thread should I be posting the next time I need help on the algo/coding? Maybe we could move this post there? :)

Anyhow, I believe my project falls on the second case (trigger pulse is shorter than clock pulse). I've tried a working program of monoflop. It worked fine when I downloaded it on S3e using the pushbutton as trigger. However when I tried integrating it on my project, it didn't.

So I made a new code and based it on the code you gave:



entity monoflop is
port(
  clock, trigger: in std_logic;
  oneSec: out std_logic
);
end monoflop;

architecture rtl of monoflop is
signal flag1 : std_logic := '0';
begin

process (clock, flag1)
variable counter1 : integer range 0 to 50e6;
begin
if rising_edge(clock) and flag1 = '1' then
counter1 := 50e6;
else
counter1 := counter1 - 1;

if counter1 = 0 then
flag1 <= '0';
else
flag1 <= '1';
end if;
end if;

end process;

process(trigger, flag1)
begin
    if trigger = '1' and flag1 = '0' then
      flag1 <= '1';
    elsif flag1 = '1' then
      oneSec <= '1';
    else
      oneSec <= '0';
    end if;
end process;

end rtl;


The code seems correct to me but I get an error message ERROR:Xst:827 line 16: Signal counter1 cannot be synthesized, bad synchronous description.
line 16 is the 'process (clock, flag1)' line. Hhmm.. What does the error mean?
0 Kudos
Reply