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
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
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] |
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.
>
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
Regards,
Allen Litton
Lasse Langwadt Christensen wrote in message
<36B97556...@kom.auc.dk>...
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;
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