Commit 833551b7 authored by Tristan Gingold's avatar Tristan Gingold

p2l_dma_master: fix incorrect handling of stall signal.

And refactoring.
parent af3128bd
......@@ -171,10 +171,10 @@ architecture arch of p2l_dma_master is
signal to_wb_fifo_byte_swap : std_logic_vector(1 downto 0) := (others => '0');
-- wishbone
signal wb_write_cnt : unsigned(31 downto 0);
signal wb_ack_cnt : unsigned(31 downto 0);
signal wb_ack_cnt : unsigned(15 downto 0);
signal p2l_dma_cyc_t : std_logic;
signal p2l_dma_stb_t : std_logic;
signal p2l_dma_tfr : boolean;
signal p2l_dma_stall_d : std_logic_vector(1 downto 0) := (others => '0');
signal p2l_dma_sel_t : std_logic_vector(3 downto 0) := (others => '0');
signal p2l_dma_adr_t : std_logic_vector(31 downto 0) := (others => '0');
......@@ -575,12 +575,18 @@ begin
-- Wishbone master (write only)
------------------------------------------------------------------------------
-- fifo read
to_wb_fifo_rd <= not(to_wb_fifo_empty)
and not(wb_dma_i.stall);
-- write only
wb_dma_o.we <= '1';
p2l_dma_sel_t <= (others => '1');
-- Set when a wishbone transfer occurred.
p2l_dma_tfr <= p2l_dma_stb_t = '1' and wb_dma_i.stall = '0';
-- Read from fifo.
-- Only when the fifo is not empty
-- and either no previous data or previous data read.
-- p2l_dma_stb_t = '1' when there are previous data.
to_wb_fifo_rd <= '1' when to_wb_fifo_empty = '0' and (p2l_dma_tfr or p2l_dma_stb_t = '0') else '0';
-- Wishbone master process
p_wb_master : process (wb_dma_clk_i)
......@@ -589,27 +595,38 @@ begin
if wb_fifo_rst_n = '0' then
p2l_dma_cyc_t <= '0';
p2l_dma_stb_t <= '0';
wb_ack_cnt <= (others => '0');
else
-- data and address
if (to_wb_fifo_rd = '1') then
if to_wb_fifo_rd = '1' then
-- Data available, read them from the fifo.
p2l_dma_adr_t(31 downto 30) <= "00";
p2l_dma_adr_t(29 downto 0) <= to_wb_fifo_dout(61 downto 32);
p2l_dma_dat_t <= to_wb_fifo_dout(31 downto 0);
end if;
-- stb and sel signals management
if (to_wb_fifo_empty = '0') then
-- Data/addresses are valid when fifo was just read.
p2l_dma_stb_t <= '1';
p2l_dma_sel_t <= (others => '1');
p2l_dma_cyc_t <= '1';
else
p2l_dma_stb_t <= '0';
p2l_dma_sel_t <= (others => '0');
-- No read.
if p2l_dma_stb_t = '1' and wb_dma_i.stall = '1' then
-- Data were not read, just wait.
null;
elsif to_wb_fifo_empty = '1' then
-- No more data to produce.
p2l_dma_stb_t <= '0';
if wb_ack_cnt = 0 then
-- End of the burst
p2l_dma_cyc_t <= '0';
end if;
end if;
end if;
-- cyc signal management
if (to_wb_fifo_rd = '1') then
p2l_dma_cyc_t <= '1';
elsif (wb_ack_cnt >= wb_write_cnt and p2l_dma_stall_d(1) = '0') then
-- last ack received -> end of the transaction
p2l_dma_cyc_t <= '0';
-- Track number of expected ack.
if p2l_dma_tfr and wb_dma_i.ack = '0' then
wb_ack_cnt <= wb_ack_cnt + 1;
elsif not p2l_dma_tfr and wb_dma_i.ack = '1' then
wb_ack_cnt <= wb_ack_cnt - 1;
end if;
end if;
end if;
......@@ -621,33 +638,4 @@ begin
wb_dma_o.sel <= p2l_dma_sel_t;
wb_dma_o.adr <= p2l_dma_adr_t;
wb_dma_o.dat <= p2l_dma_dat_t;
-- Wishbone write cycle counter
p_wb_write_cnt : process (wb_dma_clk_i)
begin
if rising_edge(wb_dma_clk_i) then
if wb_fifo_rst_n = '0' then
wb_write_cnt <= (others => '0');
else
if (to_wb_fifo_rd = '1') then
wb_write_cnt <= wb_write_cnt + 1;
end if;
end if;
end if;
end process p_wb_write_cnt;
-- Wishbone ack counter
p_wb_ack_cnt : process (wb_dma_clk_i)
begin
if rising_edge(wb_dma_clk_i) then
if wb_fifo_rst_n = '0' then
wb_ack_cnt <= (others => '0');
else
if (wb_dma_i.ack = '1' and p2l_dma_cyc_t = '1') then
wb_ack_cnt <= wb_ack_cnt + 1;
end if;
end if;
end if;
end process p_wb_ack_cnt;
end architecture arch;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment