Creating delay chain with generics

  • Follow


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
0
Reply ttobsen (14) 3/21/2012 12:46:09 PM

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.
0
Reply rgaddi1 (126) 3/21/2012 4:20:37 PM


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
0
Reply ttobsen (14) 3/21/2012 4:47:51 PM

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.
0
Reply rgaddi1 (126) 3/21/2012 5:43:24 PM

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
0
Reply enrik.berkhan (15) 3/21/2012 5:54:15 PM

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


0
Reply dk4xp1809 (5) 3/21/2012 10:09:56 PM

5 Replies
41 Views

(page loaded in 0.161 seconds)

Similiar Articles:




7/26/2012 9:23:06 AM


Reply: