Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

VHDL clocked one-shot Implementation Problem

1,454 views
Skip to first unread message

Celeritous

unread,
Feb 3, 1999, 3:00:00 AM2/3/99
to
Hello All,

At the risk of hoots and catcalls for a stupid VHDL question, I beg
patience please. I'm still rather new at this.

I'm trying to create a clocked one-shot generator for a Xilinx based
part we're designing. It has a gate input, clock input and output.

The objective is to produce an output pulse of 1-3 clock cycles following
an asynchronus assertion of the trigger signal. Trigger is level sensitive
and is only checked on the leading edge of the clock cycle in order
to synch the one-shot output with the clock.

My code segment for this is below, which will successfully compile, simulate
using ALDEC's VHDL simulator and synthesize under Xilinx Foundation 1.5
(please, no comments about the tools...... I know we can do better... for a
price, all donations gladly accepted!)

----------------------------------------------------------------------------
---------------
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.std_logic_arith.all;

entity oneshot is
port (
clk: in std_logic;
trig: in std_logic;
output: out std_logic
);
end oneshot;

architecture oneshot_arch of oneshot is
begin
process (clk)
variable count: integer; -- count variable
begin
-- wait for clock leading edge
if clk'event and clk = '1' then
-- if trig is not asserted keep count = 2 and output
deasserted
if trig = '0' then
count := 2;
output <= '0';
-- if trig is asserted and count hasn't reached 0 then
assert output
elsif count = 2 or count = 1 then -- have tried count > 0
with no change
output <= '1';
count := count -1;
-- if trig is still asserted, but count has reached 0 the
deassert output
elsif count = 0 then
output <= '0';
end if;
end if;
end process;
end oneshot_arch;
----------------------------------------------------------------------------
---------------

Problem:

When synthesized and mapped to a part it takes up some 29-30 CLBs. It
appears
to be synthesizing a 32 bit counter to accomplish this relatively simple
task. I have
tried all manner of synthesis and implementation options with little impact.
(Yes I
know doing it brute force in DOS without using the GUI interface would be
more
manly....)

What "obvious-to-the-casual-observer" thing am I missing?

Respondents may feel free to respond directly or humiliate me in public here
;-)

With thanks,

Allen Litton
Celeritous Technical Services
ali...@celeritous.com
http://www.celeritous.com


Andre Powell

unread,
Feb 3, 1999, 3:00:00 AM2/3/99
to
Hi Allen,
The problem is in the variable definition of count, you haven't given it
a range so therefore your compiler thinks its going to need a full
integer range (which is 32 bits !). Change it to

variable count : integer range 0 to 3;

this will force the compiler to only use two flip flops (00, 01, 10, 11)
to create the counter. Also the amount of logic should be reduced as you
only have two flip flops to cope with.
Yes I have been there and I have done that so no worries !

Best Regards

--
Andre Powell

me...@mench.com

unread,
Feb 3, 1999, 3:00:00 AM2/3/99
to

One thing you should *definitely* do is to change this declaration to

variable count: integer range 0 to 2;

This change should cut down on the number of flops required to
implement count.

> Problem:

See my suggestion. BTW, I have not tried to synthesize this with the
change, but if Foundation can't handle this change, you should
seriously consider something else....

Hope this helps,

Paul

--
Paul Menchini | me...@mench.com | "Non si vive se non il
OrCAD | www.orcad.com | tempo che si ama."
P.O. Box 71767 | 919-479-1670[v] | --Claude Adrien Helvetius
Durham, NC 27722-1767 | 919-479-1671[f] |

Jaroslaw Kaczynski

unread,
Feb 3, 1999, 3:00:00 AM2/3/99
to
Hi Allen,

You may try a little bit different approach: state machine.
I have tried the following code (generated by the State Editor
in Active-VHDL):

library IEEE;
use IEEE.std_logic_1164.all;

entity oneshot is
port (CLK: in STD_LOGIC;
trig: in STD_LOGIC;
output: out STD_LOGIC);
end;

architecture oneshot_arch of oneshot is

-- SYMBOLIC ENCODED state machine: one_shot
type one_shot_type is (Rest, Step1, Step2, Zero);
signal one_shot: one_shot_type;

begin

one_shot_machine: process (CLK)

begin

if CLK'event and CLK = '1' then
case one_shot is
when Rest =>
output<='0';
if trig='1' then
one_shot <= Step1;
output<='1';
end if;
when Step1 =>
if trig='0' then
one_shot <= Zero;
output<='0';
elsif trig='1' then
one_shot <= Step2;
output<='1';
end if;
when Step2 =>
one_shot <= Zero;
output<='0';
when Zero =>
if trig='0' then
one_shot <= Rest;
end if;
when others =>
null;
end case;
end if;
end process;

end oneshot_arch;

The size of the synthesized netlist was ten times smaller, and it
contained
three flops and a couple of gates.
Using state machine has one serious advantage: practically any
synthesizer
knows how to handle them - in case of your original code some less
sophisticated
synthesizers may be confused.

Thanks,

Jerry


Celeritous wrote:
>
> Hello All,
>
> At the risk of hoots and catcalls for a stupid VHDL question, I beg
> patience please. I'm still rather new at this.
>

JerryBear.vcf

Lasse Langwadt Christensen

unread,
Feb 4, 1999, 3:00:00 AM2/4/99
to

8< snip,snip

>

I put the above through Leonardo and looking at the schematic it gave 5
flops
+ some,

the below gave 3 flops, 2 OR, 2 inverters and 1 AND (and no warnings :))

library IEEE;
use IEEE.std_logic_1164.all;

entity oneshot is

port (

clk, trig, reset : in std_logic;
output : out std_logic);

end oneshot;

architecture oneshot_arch of oneshot is

signal d0,d1,d2 : std_logic;

begin -- behav
process (clk, reset)
begin -- process clk
if reset = '0' then
d0 <= '0';
d1 <= '0';
d2 <= '0';
elsif clk'event and clk = '1' then
d2 <= d1;
d1 <= d0;
d0 <= trig and not(d0 or d1 or d2);
end if;
end process;

process (d0,d1,d2)
begin -- process
output <= d0 or d1 or d2;
end process;

end oneshot_arch;

--Lasse
--___--_-_-_-____--_-_--__---_-_--__---_-_-_-__--_----
Lasse Langwadt Christensen, MSEE (to be in 1999)
Aalborg University, Department of communication tech.
Applied Signal Processing and Implementation (ASPI)
http://www.kom.auc.dk/~fuz , mailto:lang...@ieee.org

Celeritous

unread,
Feb 4, 1999, 3:00:00 AM2/4/99
to
Thanks for the help all. I will try it. The simple suggestion to confine
the range of the variable fixed the problem and reduced the implementation
to 1-2 CLBs depending on the count value. I appreciate the alternate
approaches
and insight.

Regards,

Allen Litton


Lasse Langwadt Christensen wrote in message
<36B97556...@kom.auc.dk>...

Tim Kennedy

unread,
Feb 5, 1999, 3:00:00 AM2/5/99
to
You might want to try this for a programmable one-shot, it's small:

entity OneShot is
generic (
shotLength : integer
);


port (
clk: in std_logic;
trig: in std_logic;
output: out std_logic
);

end OneShot;

architecture OneShot_rtl of OneShot is

signal shiftReg : std_logic_vector(shotLength-1 downto 0);

begin

process (clk)
begin

if (clock'event and clock = '1') then

shift <= trig & shiftReg(shotLength-1 downto 1);

end if;
end process;

output <= trigger and not shift(0);

end architecture;

The caveat is that in order for the shot to be full length, the trigger must be
high for at least as long as the shot length, or you'll get a short shot.
Likewise, it must be low for at least as long as the shot. And, of course,
the
shot length must be defined at compile time.


Tim Kennedy
<tken%nedy@ba%net.net>
Remove % for email.

In article <36b89...@news.usenetnews.org>, "Celeritous"
<sa...@celeritous.com> wrote:

>Hello All,
>
>At the risk of hoots and catcalls for a stupid VHDL question, I beg
>patience please. I'm still rather new at this.
>
>I'm trying to create a clocked one-shot generator for a Xilinx based
>part we're designing. It has a gate input, clock input and output.
>
>The objective is to produce an output pulse of 1-3 clock cycles following
>an asynchronus assertion of the trigger signal. Trigger is level sensitive
>and is only checked on the leading edge of the clock cycle in order
>to synch the one-shot output with the clock.
>
>My code segment for this is below, which will successfully compile, simulate
>using ALDEC's VHDL simulator and synthesize under Xilinx Foundation 1.5
>(please, no comments about the tools...... I know we can do better... for a
>price, all donations gladly accepted!)
>
>----------------------------------------------------------------------------
>---------------
>library IEEE;
>use IEEE.std_logic_1164.all;
>use IEEE.std_logic_arith.all;
>

>entity oneshot is
> port (

> clk: in std_logic;
> trig: in std_logic;
> output: out std_logic
> );

>end oneshot;
>
>architecture oneshot_arch of oneshot is

>begin
> process (clk)
> variable count: integer; -- count variable
> begin
> -- wait for clock leading edge

> if clk'event and clk = '1' then

> -- if trig is not asserted keep count = 2 and output
>deasserted
> if trig = '0' then
> count := 2;
> output <= '0';
> -- if trig is asserted and count hasn't reached 0 then
>assert output
> elsif count = 2 or count = 1 then -- have tried count > 0
>with no change
> output <= '1';
> count := count -1;
> -- if trig is still asserted, but count has reached 0 the
>deassert output
> elsif count = 0 then
> output <= '0';
> end if;

> end if;
> end process;
>end oneshot_arch;

Lasse Langwadt Christensen

unread,
Feb 6, 1999, 3:00:00 AM2/6/99
to
snip

just modify it so that theres only put a '1' into the register
when there's none already, and output so that is '1' as long as there's
a '1' in the register

0 new messages