Commit 241e4a45 authored by Tristan Gingold's avatar Tristan Gingold

p2l_dma_master: refactoring

parent 78aa3267
......@@ -147,9 +147,7 @@ architecture arch of p2l_dma_master is
signal l2p_len_cnt : unsigned(29 downto 0) := (others => '0');
signal l2p_len_header : unsigned(9 downto 0) := (others => '0');
signal l2p_64b_address : std_logic;
signal s_l2p_header : std_logic_vector(31 downto 0);
signal l2p_last_packet : std_logic;
signal l2p_lbe_header : std_logic_vector(3 downto 0);
signal pdm_arb_data : std_logic_vector(31 downto 0) := (others => '0');
......@@ -208,73 +206,59 @@ begin
is_next_item <= '0';
l2p_last_packet <= '0';
else
if (p2l_dma_current_state = P2L_IDLE) then
if (dma_ctrl_start_p2l_i = '1' or dma_ctrl_start_next_i = '1') then
-- Stores DMA info locally
l2p_address_h <= dma_ctrl_host_addr_h_i;
l2p_address_l <= dma_ctrl_host_addr_l_i;
l2p_len_cnt <= unsigned(dma_ctrl_len_i(31 downto 2)); -- dma_ctrl_len_i is in byte
if (dma_ctrl_start_next_i = '1') then
-- Catching next DMA item
is_next_item <= '1'; -- flag for data retrieve block
case p2l_dma_current_state is
when P2L_IDLE =>
if dma_ctrl_start_p2l_i = '1' or dma_ctrl_start_next_i = '1' then
-- Stores DMA info locally
l2p_address_h <= dma_ctrl_host_addr_h_i;
l2p_address_l <= dma_ctrl_host_addr_l_i;
l2p_len_cnt <= unsigned(dma_ctrl_len_i(31 downto 2)); -- dma_ctrl_len_i is in byte
if dma_ctrl_start_next_i = '1' then
-- Catching next DMA item
is_next_item <= '1'; -- flag for data retrieve block
else
-- P2L DMA transfer
is_next_item <= '0';
end if;
if dma_ctrl_host_addr_h_i = X"00000000" then
l2p_64b_address <= '0';
else
l2p_64b_address <= '1';
end if;
end if;
when P2L_HEADER =>
-- if DMA length is bigger than the max PCIe payload size,
-- we have to generate several read request
if l2p_len_cnt > c_MAX_READ_REQ_SIZE then
-- when max payload length is 1024, the header length field = 0
l2p_len_header <= c_MAX_READ_REQ_SIZE(9 downto 0);
l2p_last_packet <= '0';
else
-- P2L DMA transfer
is_next_item <= '0';
l2p_len_header <= l2p_len_cnt(9 downto 0);
l2p_last_packet <= '1';
end if;
if (dma_ctrl_host_addr_h_i = X"00000000") then
l2p_64b_address <= '0';
when P2L_ADDR_L =>
-- Subtract the number of word requested to generate a new read request if needed
if l2p_last_packet = '0' then
l2p_len_cnt <= l2p_len_cnt - c_MAX_READ_REQ_SIZE;
else
l2p_64b_address <= '1';
l2p_len_cnt <= (others => '0');
end if;
end if;
elsif (p2l_dma_current_state = P2L_HEADER) then
-- if DMA length is bigger than the max PCIe payload size,
-- we have to generate several read request
if (l2p_len_cnt > c_MAX_READ_REQ_SIZE) then
-- when max payload length is 1024, the header length field = 0
l2p_len_header <= c_MAX_READ_REQ_SIZE(9 downto 0);
l2p_last_packet <= '0';
elsif (l2p_len_cnt = c_MAX_READ_REQ_SIZE) then
-- when max payload length is 1024, the header length field = 0
l2p_len_header <= c_MAX_READ_REQ_SIZE(9 downto 0);
l2p_last_packet <= '1';
else
l2p_len_header <= l2p_len_cnt(9 downto 0);
l2p_last_packet <= '1';
end if;
elsif (p2l_dma_current_state = P2L_ADDR_L) then
-- Subtract the number of word requested to generate a new read request if needed
if (l2p_last_packet = '0') then
l2p_len_cnt <= l2p_len_cnt - c_MAX_READ_REQ_SIZE;
else
l2p_len_cnt <= (others => '0');
end if;
end if;
when P2L_ADDR_H =>
null;
when P2L_WAIT_READ_COMPLETION =>
end case;
end if;
end if;
end process p_read_req;
-- Last Byte Enable must be "0000" when length = 1
l2p_lbe_header <= "0000" when l2p_len_header = 1 else "1111";
s_l2p_header <= "000" --> Traffic Class
& '0' --> Snoop
& "000" & l2p_64b_address --> Packet type = read request (32 or 64 bits)
& l2p_lbe_header --> LBE (Last Byte Enable)
& "1111" --> FBE (First Byte Enable)
& "000" --> Reserved
& '0' --> VC (Virtual Channel)
& "01" --> CID
& std_logic_vector(l2p_len_header); --> Length (in 32-bit words)
-- 0x000 => 1024 words (4096 bytes)
-----------------------------------------------------------------------------
-- PCIe read request FSM
-----------------------------------------------------------------------------
p_read_req_fsm : process (clk_i)
begin
if rising_edge(clk_i) then
if(rst_n_i = '0') then
if rst_n_i = '0' then
p2l_dma_current_state <= P2L_IDLE;
pdm_arb_req_o <= '0';
pdm_arb_valid_o <= '0';
......@@ -294,7 +278,7 @@ begin
rx_error_t <= '0';
-- Start a read request when a P2L DMA is initated or when the DMA
-- controller asks for the next DMA info (in a chained DMA).
if (dma_ctrl_start_p2l_i = '1' or dma_ctrl_start_next_i = '1') then
if dma_ctrl_start_p2l_i = '1' or dma_ctrl_start_next_i = '1' then
-- request access to PCIe bus
pdm_arb_req_o <= '1';
-- prepare a packet, first the header
......@@ -302,15 +286,28 @@ begin
end if;
when P2L_HEADER =>
if(arb_pdm_gnt_i = '1') then
if arb_pdm_gnt_i = '1' then
-- clear access request to the arbiter
-- access is granted until dframe is cleared
pdm_arb_req_o <= '0';
-- send header
pdm_arb_data <= s_l2p_header;
pdm_arb_data(31 downto 29) <= "000"; --> Traffic Class
pdm_arb_data(28) <= '0'; --> Snoop
pdm_arb_data(27 downto 24) <= "000" & l2p_64b_address; --> Packet type = read req (32 or 64)
if l2p_len_header = 1 then
-- Last Byte Enable must be "0000" when length = 1
pdm_arb_data(23 downto 20) <= "0000"; --> LBE (Last Byte Enable)
else
pdm_arb_data(23 downto 20) <= "1111"; --> LBE (Last Byte Enable)
end if;
pdm_arb_data(19 downto 16) <= "1111"; --> FBE (First Byte Enable)
pdm_arb_data(15 downto 13) <= "111"; --> Reserved
pdm_arb_data(12) <= '0'; --> VC (Virtual Channel)
pdm_arb_data(11 downto 10) <= "01"; --> CID
pdm_arb_data(9 downto 0) <= std_logic_vector(l2p_len_header); --> Length (in 32-bit words)
pdm_arb_valid_o <= '1';
pdm_arb_dframe_o <= '1';
if(l2p_64b_address = '1') then
if l2p_64b_address = '1' then
-- if host address is 64-bit, we have to send an additionnal
-- 32-word containing highest bits of the host address
p2l_dma_current_state <= P2L_ADDR_H;
......@@ -335,13 +332,14 @@ begin
when P2L_WAIT_READ_COMPLETION =>
-- End of the read request packet
pdm_arb_valid_o <= '0';
if (dma_ctrl_abort_i = '1') then
if dma_ctrl_abort_i = '1' then
rx_error_t <= '1';
p2l_dma_current_state <= P2L_IDLE;
elsif (pd_pdm_master_cpld_i = '1' and pd_pdm_data_last_i = '1'
and p2l_data_cnt <= 1) then
and p2l_data_cnt <= 1)
then
-- last word of read completion has been received
if (l2p_last_packet = '0') then
if l2p_last_packet = '0' then
-- A new read request is needed, DMA size > max payload
p2l_dma_current_state <= P2L_HEADER;
-- As the end of packet is used to delimit arbitration phases
......@@ -349,20 +347,19 @@ begin
pdm_arb_req_o <= '1';
else
-- indicate end of DMA transfer
if (is_next_item = '1') then
if is_next_item = '1' then
next_item_valid_o <= '1';
else
dma_ctrl_done_t <= '1';
end if;
p2l_dma_current_state <= P2L_IDLE;
end if;
elsif (pd_pdm_master_cpln_i = '1') then
elsif pd_pdm_master_cpln_i = '1' then
-- should not return a read completion without data
completion_error <= '1';
p2l_dma_current_state <= P2L_IDLE;
end if;
when others =>
p2l_dma_current_state <= P2L_IDLE;
pdm_arb_req_o <= '0';
......@@ -399,7 +396,7 @@ begin
p_recv_data_cnt : process (clk_i)
begin
if rising_edge(clk_i) then
if (p2l_dma_current_state = P2L_ADDR_L) then
if p2l_dma_current_state = P2L_ADDR_L then
-- Store number of 32-bit data words to be received for the current read request
if l2p_len_header = 0 then
p2l_data_cnt <= to_unsigned(1024, p2l_data_cnt'length);
......@@ -422,8 +419,9 @@ begin
begin
if rising_edge(clk_i) then
if (p2l_dma_current_state = P2L_WAIT_READ_COMPLETION
and is_next_item = '1' and pd_pdm_data_valid_i = '1') then
-- next item data are supposed to be received in the right order !!
and is_next_item = '1' and pd_pdm_data_valid_i = '1')
then
-- next item data are supposed to be received in the right order !!
case p2l_data_cnt(2 downto 0) is
when "111" =>
next_item_carrier_addr <= pd_pdm_data_i;
......@@ -479,7 +477,8 @@ begin
dma_busy_error <= '1';
end if;
elsif (p2l_dma_current_state = P2L_WAIT_READ_COMPLETION
and is_next_item = '0' and pd_pdm_data_valid_i = '1') then
and is_next_item = '0' and pd_pdm_data_valid_i = '1')
then
-- increment target address counter
target_addr_cnt <= target_addr_cnt + 1;
-- write target address and data to the sync fifo
......
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