Ciągłe zadanie najwyraźniej nie działa

Pracuję nad filtrem FIR, szczególnie linią opóźnienia.x_delayed jest inicjowany na wszystkie zera.

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'));

To nie działa:

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;

Ale to robi:

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;

Problem z tym „rozwiązaniem” polega na tym, że pierwszy element tox_delayed jest opóźniony o jedną próbkę, którą powiniennie być. (Reszta kodu oczekujex_delayed(0) byćobecny próba).

Używam Xilinx ISE 13.2, symulując z ISim, ale potwierdzono to również symulując za pomocą ModelSim.

Co daje?

Edytować:

Problem polegał zasadniczo na tym, chociażx_delayed(0) nie wyglądało na to, że był w środkuprocess, to było.

Po wdrożeniuPomysł Briana Drummonda działa doskonale:

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;

Edytuj 2:

wziąłemSugestia OllieB za pozbycie sięfor pętla. Musiałem to zmienić, ponieważ mójx_delayed jest indeksowany z(0 to NTAPS-1), ale kończymy na tym ładnie wyglądającym małym procesie:

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;

Edytuj 3:

NastępującyNastępna sugestia OllieB, okazuje sięx_delayed(0) <= (others => 'Z') było niepotrzebne po jego poprzedniej zmianie. Poniższe działa dobrze:

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;

questionAnswers(4)

yourAnswerToTheQuestion