Asignación continua aparentemente no funciona
Estoy trabajando en un filtro FIR, específicamente la línea de retardo.x_delayed
Se inicializa a todos los ceros.
type slv32_array is array(natural range <>) of std_logic_vector(31 downto 0);
...
signal x_delayed : slv32_array(0 to NTAPS-1) := (others => (others => '0'));
Esto no funciona:
x_delayed(0) <= x; -- Continuous assignment
DELAYS : process(samp_clk)
begin
if rising_edge(samp_clk) then
for i in 1 to NTAPS-1 loop
x_delayed(i) <= x_delayed(i-1);
end loop;
end if; -- rising_edge(samp_clk)
end process;
Pero esto hace:
DELAYS : process(samp_clk)
begin
if rising_edge(samp_clk) then
x_delayed(0) <= x; -- Registering input
for i in 1 to NTAPS-1 loop
x_delayed(i) <= x_delayed(i-1);
end loop;
end if; -- rising_edge(samp_clk)
end process;
El problema con esta "solución" es que el primer elemento enx_delayed
se retrasa por una muestra, que deberíano ser. (El resto del código esperax_delayed(0)
ser elcorriente muestra).
Estoy usando Xilinx ISE 13.2, simulando con ISim, pero esto también se confirmó simulando con ModelSim.
¿Lo que da?
Editar:
El problema era esencialmente ese, aunquex_delayed(0)
no parecía ser conducido dentro de laprocess
, era.
Después de implementarLa idea de Brian Drummond funciona perfectamente
x_delayed(0) <= x;
-- Synchronous delay cycles.
DELAYS : process(samp_clk)
begin
-- Disable the clocked driver, allowing the continuous driver above to function correctly.
-- https://stackoverflow.com/questions/18247955/#comment26779546_18248941
x_delayed(0) <= (others => 'Z');
if rising_edge(samp_clk) then
for i in 1 to NTAPS-1 loop
x_delayed(i) <= x_delayed(i-1);
end loop;
end if; -- rising_edge(samp_clk)
end process;
Edición 2:
Yo toméSugerencia de OllieB para deshacerse de lafor
lazo. Tuve que cambiarlo, ya que mix_delayed
es indexado desde(0 to NTAPS-1)
, pero terminamos con este pequeño y bonito proceso:
x_delayed(0) <= x;
DELAYS : process(samp_clk)
begin
x_delayed(0) <= (others => 'Z');
if rising_edge(samp_clk) then
x_delayed(1 to x_delayed'high) <= x_delayed(0 to x_delayed'high-1);
end if; -- rising_edge(samp_clk)
end process;
Edición 3:
SiguiendoLa siguiente sugerencia de OllieB, resulta que elx_delayed(0) <= (others => 'Z')
Fue innecesario, siguiendo su anterior cambio. Los siguientes trabajos funcionan bien:
x_delayed(0) <= x;
DELAYS : process(samp_clk)
begin
if rising_edge(samp_clk) then
x_delayed(1 to x_delayed'high) <= x_delayed(0 to x_delayed'high-1);
end if;
end process;