Creating delay chain with generics

T

Tobias Baumann

Guest
Hi

I try to implement a synthesizable delay chain. Here a working example:

library ieee;
use ieee.std_logic_1164.all;

entity delay_gate is

generic (
ACTIVE_EDGE : std_logic := '1';
MAX_DELAY_GATE_CYCLES : integer := 7
);

port (
clk_in : in std_logic;

data_in : in std_logic_vector(9 downto 0);
num_delays_in : in integer range 0 to MAX_DELAY_GATE_CYCLES;
data_q : out std_logic_vector(9 downto 0)

);

end entity delay_gate;

architecture RTL of delay_gate is

type delay_gate_data_type is array (0 to MAX_DELAY_GATE_CYCLES) of
std_logic_vector(9 downto 0);

signal delay_data : delay_gate_data_type := (others => (others =>
'0'));

begin

-- first element has no delay
delay_data(0) <= data_in;

delay_proc: process(clk_in)
begin
if (clk_in'event and clk_in = ACTIVE_EDGE) then

delay_data(1) <= delay_data(0);
delay_data(2) <= delay_data(1);
delay_data(3) <= delay_data(2);
delay_data(4) <= delay_data(3);
delay_data(5) <= delay_data(4);
delay_data(6) <= delay_data(5);
delay_data(7) <= delay_data(6);

end if;
end process;

with num_delays_in select
data_q <= delay_data(0) when 0,
delay_data(1) when 1,
delay_data(2) when 2,
delay_data(3) when 3,
delay_data(4) when 4,
delay_data(5) when 5,
delay_data(6) when 6,
delay_data(7) when 7,
delay_data(0) when others;

end architecture RTL;

The problem is that I want to have a real generic entity so that I
haven't to change delay_proc and the with...select statement by hand.

Can someone help me finding the correct VHDL syntax? I tried using a
for...loop, but the simulation results aren't good (data_q is undefined).

Thanks a lot for any help.

Tobias
 
On Wed, 21 Mar 2012 13:46:09 +0100
Tobias Baumann <ttobsen@hotmail.com> wrote:

Hi

I try to implement a synthesizable delay chain. Here a working example:

library ieee;
use ieee.std_logic_1164.all;

entity delay_gate is

generic (
ACTIVE_EDGE : std_logic := '1';
MAX_DELAY_GATE_CYCLES : integer := 7
);

port (
clk_in : in std_logic;

data_in : in std_logic_vector(9 downto 0);
num_delays_in : in integer range 0 to MAX_DELAY_GATE_CYCLES;
data_q : out std_logic_vector(9 downto 0)

);

end entity delay_gate;

architecture RTL of delay_gate is

type delay_gate_data_type is array (0 to MAX_DELAY_GATE_CYCLES) of
std_logic_vector(9 downto 0);

signal delay_data : delay_gate_data_type := (others => (others =
'0'));

begin

-- first element has no delay
delay_data(0) <= data_in;

delay_proc: process(clk_in)
begin
if (clk_in'event and clk_in = ACTIVE_EDGE) then

delay_data(1) <= delay_data(0);
delay_data(2) <= delay_data(1);
delay_data(3) <= delay_data(2);
delay_data(4) <= delay_data(3);
delay_data(5) <= delay_data(4);
delay_data(6) <= delay_data(5);
delay_data(7) <= delay_data(6);

end if;
end process;

with num_delays_in select
data_q <= delay_data(0) when 0,
delay_data(1) when 1,
delay_data(2) when 2,
delay_data(3) when 3,
delay_data(4) when 4,
delay_data(5) when 5,
delay_data(6) when 6,
delay_data(7) when 7,
delay_data(0) when others;

end architecture RTL;

The problem is that I want to have a real generic entity so that I
haven't to change delay_proc and the with...select statement by hand.

Can someone help me finding the correct VHDL syntax? I tried using a
for...loop, but the simulation results aren't good (data_q is undefined).

Thanks a lot for any help.

Tobias
Delay chains are tricky nastiness that in practice no one sensible
should ever use. So when I've use them, I generally find
that I need to directly instantiate some kind of low-level primitive of
the specific target device. Then I'll lay some vendor-specific
placement constraints over top, in order to get something that a) won't
synthesize out and b) holds anything even resembling a constant timing
between builds.

Regarding your design, you can't really do what you want with a clocked
process. A clocked process implies "Figure this all out ahead of time,
and put flops that latch the result of it all on this clock edge.",
which is the antithesis of what you want.

To be a bit of a jerk for a moment, you don't seem to have a
particularly strong grasp of VHDL or FPGA design. That's no crime, we
all cut our teeth sometime, but anything involving asynchronous delay
lines tends to be pretty touchy, advanced stuff that serious FPGA
jocks with lots of experience will go to great lengths to avoid. If you
can explain a bit more about your problem, there's a very good chance
that there's a better solution. Or worse, that there isn't, but
the one you're trying won't work either.

--
Rob Gaddi, Highland Technology -- www.highlandtechnology.com
Email address domain is currently out of order. See above to fix.
 
Thanks for your answer.

The problem I try to solve:

I have some data, which will be generated synchronously with my clock.
In some cases I need the data with an latency for a well known number of
clock cycles. So I need an entity where I can set the number of clock
cycles to delay my data. Maybe "delay chain" isn't the right keyword but
"register pipelining". And I think register pipelining can be well done
in FPGA using VHDL.

Maybe you can give me a hint how to build up such an entity.

Tobias
 
On Wed, 21 Mar 2012 17:47:51 +0100
Tobias Baumann <ttobsen@hotmail.com> wrote:

Thanks for your answer.

The problem I try to solve:

I have some data, which will be generated synchronously with my clock.
In some cases I need the data with an latency for a well known number of
clock cycles. So I need an entity where I can set the number of clock
cycles to delay my data. Maybe "delay chain" isn't the right keyword but
"register pipelining". And I think register pipelining can be well done
in FPGA using VHDL.

Maybe you can give me a hint how to build up such an entity.

Tobias
That's a much easier problem than I thought you had. In that case,
basically what you need is to take advantage of the fact that arrays
can be indexed and sliced. Try something like this:

....
type delay_gate_data_type is array (1 to MAX_DELAY_GATE_CYCLES) of
std_logic_vector(9 downto 0);

signal delay_data : delay_gate_data_type := (others => (others =>
'0'));

begin

delay_proc: process(clk_in)
begin
if (clk_in'event and clk_in = ACTIVE_EDGE) then
delay_data <= data_in & delay_data(1 to MAX_DELAY_GATE_CYCLES-1);
end if;
end process;

data_q <= data_in when (num_delays_in = 0)
else delay_data(num_delays_in);
....

--
Rob Gaddi, Highland Technology -- www.highlandtechnology.com
Email address domain is currently out of order. See above to fix.
 
Tobias Baumann <ttobsen@hotmail.com> wrote:
Can someone help me finding the correct VHDL syntax? I tried using a
for...loop, but the simulation results aren't good (data_q is undefined).
the following should work, not even generate is needed here:

-- 8< --
architecture RTL of delay_gate is

type delay_gate_data_type is array (0 to MAX_DELAY_GATE_CYCLES)
of std_logic_vector(9 downto 0);
signal delay_data : delay_gate_data_type := (others => (others => '0'));

begin

-- first element has no delay
delay_data(0) <= data_in;

delay_proc: process(clk_in)
begin
if clk_in'event and clk_in = ACTIVE_EDGE then
delay_data(1 to MAX_DELAY_GATE_CYCLES) <=
delay_data(0 to MAX_DELAY_GATE_CYCLES-1);
end if;
end process;

data_q <= delay_data(num_delays_in);

end architecture RTL;
-- >8 --

Looks good in ModelSim and in Quartus II (11.1), using the expected number of
FFs and some additional LEs for the output mux.

Enrik
 
On 03/21/2012 05:47 PM, Tobias Baumann wrote:

I have some data, which will be generated synchronously with my clock.
In some cases I need the data with an latency for a well known number of
clock cycles. So I need an entity where I can set the number of clock
cycles to delay my data. Maybe "delay chain" isn't the right keyword but
"register pipelining". And I think register pipelining can be well done
in FPGA using VHDL.

Maybe you can give me a hint how to build up such an entity.
take a look at my sine & cosine module on

< http://opencores.org/project,sincos >

it contains a programmable pipeline register entity that does exactly
that.

regards, Gerhard
 

Welcome to EDABoard.com

Sponsor

Back
Top