M
Marty Ryba
Hi gang,
I had some interesting results over the last couple weeks that gets me
to thinking there may even be more ways to attack this problem. Picture one
signal coming in (one bit for now, but maybe more later). I want copies of
this signal at various delays from "now". I have a related question
regarding the (less used) if/generate syntax: can this not be in a process?
I tried to have a for...generate around a process with one little localized
if/generate to handle the "first buffer" case in the second approach.
Modelsim (5.8d PE) didn't like it, so I coded the first buffer separately.
The first delay line method creates one buffer, one input address, and an
array of output addresses. Each output is then read from the respective
output address, and all of them get incremented on each read/write cycle
(Clock Enable high). I noticed it synthesized fairly large, so I tried a
second way, reasoning that since the synthesis tool couldn't assume anything
about the arrangement of the addresses that it had to register the data out
the wazoo to keep all the parallel reads happy.
The second way was a lot more code. I created multiple buffers, each with
its own input and output address. I made them shorter, but still the sum of
them was larger than the first buffer. The output of the first feeds the
second, and so on. The only disadvantage is that there is now a tighter
constraint on the relative spacing of the delays, but I can live with that.
Any ideas on even cuter ways to code this up?
Here's the bit of code regarding if/generate that caused problems; it also
illustrates my second way of doing it:
gen_delay: for N = 0 to NUM_DELAYS-1 generate
delay_process: process(CLK)
begin
if rising_edge(CLK) then
....
if CE = '1' then -- valid data coming in
G1: if N = 0 generate
DBuffer(N)(InAddress(N)) <= X_IN; -- first buffer takes input
signal
end generate G1;
GN: if N /= 0 generate
DBuffer(N)(InAddress(N)) <= DBuffer(N-1)(OutAddress(N-1)); --
others take output of previous
end generate GN;
InAddress(N) <= InAddress(N) + 1;
OutAddress(N) <= OutAddress(N) + 1;
X_OUT(N) <= DBuffer(N)(OutAddress(N));
end if
end if
end process delay_process;
end generate gen_delay;
I had some interesting results over the last couple weeks that gets me
to thinking there may even be more ways to attack this problem. Picture one
signal coming in (one bit for now, but maybe more later). I want copies of
this signal at various delays from "now". I have a related question
regarding the (less used) if/generate syntax: can this not be in a process?
I tried to have a for...generate around a process with one little localized
if/generate to handle the "first buffer" case in the second approach.
Modelsim (5.8d PE) didn't like it, so I coded the first buffer separately.
The first delay line method creates one buffer, one input address, and an
array of output addresses. Each output is then read from the respective
output address, and all of them get incremented on each read/write cycle
(Clock Enable high). I noticed it synthesized fairly large, so I tried a
second way, reasoning that since the synthesis tool couldn't assume anything
about the arrangement of the addresses that it had to register the data out
the wazoo to keep all the parallel reads happy.
The second way was a lot more code. I created multiple buffers, each with
its own input and output address. I made them shorter, but still the sum of
them was larger than the first buffer. The output of the first feeds the
second, and so on. The only disadvantage is that there is now a tighter
constraint on the relative spacing of the delays, but I can live with that.
Any ideas on even cuter ways to code this up?
Here's the bit of code regarding if/generate that caused problems; it also
illustrates my second way of doing it:
gen_delay: for N = 0 to NUM_DELAYS-1 generate
delay_process: process(CLK)
begin
if rising_edge(CLK) then
....
if CE = '1' then -- valid data coming in
G1: if N = 0 generate
DBuffer(N)(InAddress(N)) <= X_IN; -- first buffer takes input
signal
end generate G1;
GN: if N /= 0 generate
DBuffer(N)(InAddress(N)) <= DBuffer(N-1)(OutAddress(N-1)); --
others take output of previous
end generate GN;
InAddress(N) <= InAddress(N) + 1;
OutAddress(N) <= OutAddress(N) + 1;
X_OUT(N) <= DBuffer(N)(OutAddress(N));
end if
end if
end process delay_process;
end generate gen_delay;