Commit be8d8346 authored by Dimitris Lampridis's avatar Dimitris Lampridis

Merge branch 'bugfix/kontron-dma-crash' into proposed_master

parents c3776541 72e138ad
...@@ -34,7 +34,12 @@ use work.genram_pkg.all; ...@@ -34,7 +34,12 @@ use work.genram_pkg.all;
entity l2p_dma_master is entity l2p_dma_master is
generic ( generic (
g_FIFO_SIZE : positive := 128; -- It is important to set this threshold such that the FIFO has room to store
-- all pending read requests from the pipelined wishbone interface in case
-- the Gennum decides to stall and the FIFO starts filling up. The default
-- value is correct if the WB slave is the Spartan-6 DDR controller.
g_FIFO_FULL_THRES : positive := 64;
g_FIFO_SIZE : positive := 256;
g_BYTE_SWAP : boolean := FALSE); g_BYTE_SWAP : boolean := FALSE);
port ( port (
-- GN4124 core clk and reset -- GN4124 core clk and reset
...@@ -96,7 +101,7 @@ architecture arch of l2p_dma_master is ...@@ -96,7 +101,7 @@ architecture arch of l2p_dma_master is
L2P_NEXT, L2P_ERROR); L2P_NEXT, L2P_ERROR);
signal l2p_dma_current_state : l2p_dma_state_type := L2P_IDLE; signal l2p_dma_current_state : l2p_dma_state_type := L2P_IDLE;
type wb_dma_state_type is (WB_IDLE, WB_SETUP, WB_DATA1,WB_DATA2, WB_HOLD); type wb_dma_state_type is (WB_IDLE, WB_SETUP, WB_DATA, WB_WAIT_ACK);
signal wb_dma_current_state : wb_dma_state_type := WB_IDLE; signal wb_dma_current_state : wb_dma_state_type := WB_IDLE;
signal dma_target_addr : unsigned(29 downto 0) := (others => '0'); signal dma_target_addr : unsigned(29 downto 0) := (others => '0');
...@@ -112,7 +117,6 @@ architecture arch of l2p_dma_master is ...@@ -112,7 +117,6 @@ architecture arch of l2p_dma_master is
signal l2p_fsm_valid : std_logic := '0'; signal l2p_fsm_valid : std_logic := '0';
signal l2p_fsm_dframe : std_logic := '0'; signal l2p_fsm_dframe : std_logic := '0';
signal l2p_fsm_hold : std_logic := '0';
signal l2p_fsm_data : std_logic_vector(31 downto 0) := (others => '0'); signal l2p_fsm_data : std_logic_vector(31 downto 0) := (others => '0');
signal l2p_fsm_dma_param_wr : std_logic := '0'; signal l2p_fsm_dma_param_wr : std_logic := '0';
...@@ -165,7 +169,6 @@ begin ...@@ -165,7 +169,6 @@ begin
ldm_arb_req_o <= '0'; ldm_arb_req_o <= '0';
l2p_fsm_valid <= '0'; l2p_fsm_valid <= '0';
l2p_fsm_dframe <= '0'; l2p_fsm_dframe <= '0';
l2p_fsm_hold <= '0';
dma_ctrl_done_o <= '0'; dma_ctrl_done_o <= '0';
dma_ctrl_error_o <= '0'; dma_ctrl_error_o <= '0';
wb_dma_fsm_en <= '0'; wb_dma_fsm_en <= '0';
...@@ -195,7 +198,6 @@ begin ...@@ -195,7 +198,6 @@ begin
when L2P_IDLE => when L2P_IDLE =>
wb_dma_fsm_en <= '0'; wb_dma_fsm_en <= '0';
fsm_fifo_rst_n <= '0'; fsm_fifo_rst_n <= '0';
l2p_fsm_hold <= '0';
dma_last_packet <= '0'; dma_last_packet <= '0';
if dma_ctrl_start_l2p_i = '1' then if dma_ctrl_start_l2p_i = '1' then
dma_target_addr <= unsigned(dma_ctrl_target_addr_i(31 downto 2)); dma_target_addr <= unsigned(dma_ctrl_target_addr_i(31 downto 2));
...@@ -303,8 +305,8 @@ begin ...@@ -303,8 +305,8 @@ begin
-- Detect end of transfer -- Detect end of transfer
if dma_packet_len = 1 then if dma_packet_len = 1 then
l2p_fsm_dframe <= '0'; l2p_fsm_dframe <= '0';
if dma_last_packet = '0' then
data_fifo_rd <= '0'; data_fifo_rd <= '0';
if dma_last_packet = '0' then
l2p_dma_current_state <= L2P_NEXT; l2p_dma_current_state <= L2P_NEXT;
else else
dma_total_len <= (others => '0'); dma_total_len <= (others => '0');
...@@ -408,67 +410,68 @@ begin ...@@ -408,67 +410,68 @@ begin
case wb_dma_current_state is case wb_dma_current_state is
when WB_IDLE => when WB_IDLE =>
-- Start when the new DMA parameters (address, size) have been received
if dma_param_wr = '1' then if dma_param_wr = '1' then
wb_dma_addr := unsigned(dma_param_sync(59 downto 30));
wb_dma_cnt_stb := unsigned(dma_param_sync(29 downto 0));
wb_dma_cnt_ack := unsigned(dma_param_sync(29 downto 0));
wb_dma_current_state <= WB_SETUP; wb_dma_current_state <= WB_SETUP;
end if; end if;
when WB_SETUP => when WB_SETUP =>
wb_dma_addr := unsigned(dma_param_sync(59 downto 30)); -- Start/maintain the WB cycle
wb_dma_cnt_stb := unsigned(dma_param_sync(29 downto 0)); wb_dma_cyc <= '1';
wb_dma_cnt_ack := unsigned(dma_param_sync(29 downto 0)); -- Always keep track of pending ACKs
if wb_dma_i.ack = '1' then
wb_dma_cnt_ack := wb_dma_cnt_ack - 1;
end if;
-- If there is space in the FIFO, send the first/next read request
if data_fifo_full = '0' then if data_fifo_full = '0' then
wb_dma_current_state <= WB_DATA1; wb_dma_o.adr <= "00" & std_logic_vector(wb_dma_addr);
wb_dma_stb <= '1';
wb_dma_current_state <= WB_DATA;
end if; end if;
when WB_DATA1 => when WB_DATA =>
-- Maintain the WB cycle
wb_dma_cyc <= '1'; wb_dma_cyc <= '1';
-- Always keep track of pending ACKs
if wb_dma_i.ack = '1' then if wb_dma_i.ack = '1' then
wb_dma_cnt_ack := wb_dma_cnt_ack - 1; wb_dma_cnt_ack := wb_dma_cnt_ack - 1;
end if; end if;
if data_fifo_full = '1' then -- If the slave was not stalling on the previous cycle,
wb_dma_stb <= '0'; -- update address and counters
wb_dma_current_state <= WB_HOLD;
else
if wb_dma_i.stall = '0' then if wb_dma_i.stall = '0' then
wb_dma_o.adr <= "00" & std_logic_vector(wb_dma_addr);
wb_dma_addr := wb_dma_addr + 1; wb_dma_addr := wb_dma_addr + 1;
wb_dma_cnt_stb := wb_dma_cnt_stb - 1;
-- If all read requests have been issued, move to next state
if wb_dma_cnt_stb = 0 then if wb_dma_cnt_stb = 0 then
wb_dma_stb <= '0'; wb_dma_stb <= '0';
wb_dma_current_state <= WB_DATA2; wb_dma_current_state <= WB_WAIT_ACK;
-- If there is no room in the FIFO, drop strobe and wait
elsif data_fifo_full = '1' then
wb_dma_stb <= '0';
wb_dma_current_state <= WB_SETUP;
-- Otherwise send the next request
else else
wb_dma_cnt_stb := wb_dma_cnt_stb - 1; wb_dma_o.adr <= "00" & std_logic_vector(wb_dma_addr);
wb_dma_stb <= '1'; wb_dma_stb <= '1';
end if; end if;
end if; end if;
end if;
when WB_DATA2 => when WB_WAIT_ACK =>
-- Maintain the WB cycle
wb_dma_cyc <= '1'; wb_dma_cyc <= '1';
-- Always keep track of pending ACKs
if wb_dma_i.ack = '1' then if wb_dma_i.ack = '1' then
wb_dma_cnt_ack := wb_dma_cnt_ack - 1; wb_dma_cnt_ack := wb_dma_cnt_ack - 1;
end if; end if;
if data_fifo_full = '1' then -- If all ACKs have been received, we are done
wb_dma_stb <= '0'; if wb_dma_cnt_ack = 0 then
wb_dma_current_state <= WB_HOLD;
elsif wb_dma_cnt_ack = 0 then
wb_dma_cyc <= '0'; wb_dma_cyc <= '0';
wb_dma_current_state <= WB_IDLE; wb_dma_current_state <= WB_IDLE;
end if; end if;
when WB_HOLD =>
wb_dma_cyc <= '1';
wb_dma_stb <= '0';
if wb_dma_i.ack = '1' then
wb_dma_cnt_ack := wb_dma_cnt_ack - 1;
end if;
if data_fifo_full = '0' then
if wb_dma_cnt_stb = 0 then
wb_dma_current_state <= WB_DATA2;
else
wb_dma_current_state <= WB_DATA1;
end if;
end if;
when others => when others =>
wb_dma_current_state <= WB_IDLE; wb_dma_current_state <= WB_IDLE;
...@@ -527,7 +530,7 @@ begin ...@@ -527,7 +530,7 @@ begin
g_SHOW_AHEAD => TRUE, g_SHOW_AHEAD => TRUE,
g_WITH_WR_FULL => FALSE, g_WITH_WR_FULL => FALSE,
g_WITH_WR_ALMOST_FULL => TRUE, g_WITH_WR_ALMOST_FULL => TRUE,
g_ALMOST_FULL_THRESHOLD => g_FIFO_SIZE/2 - c_SYNC_FIFO_FULL_DELAY) g_ALMOST_FULL_THRESHOLD => g_FIFO_FULL_THRES - c_SYNC_FIFO_FULL_DELAY)
port map ( port map (
-- write port -- write port
rst_wr_n_i => data_fifo_rst_wr_n, rst_wr_n_i => data_fifo_rst_wr_n,
......
...@@ -48,7 +48,8 @@ entity gn4124_core is ...@@ -48,7 +48,8 @@ entity gn4124_core is
g_WBM_FROM_WB_FIFO_SIZE : positive := 128; g_WBM_FROM_WB_FIFO_SIZE : positive := 128;
g_WBM_FROM_WB_FIFO_FULL_THRES : positive := 110; g_WBM_FROM_WB_FIFO_FULL_THRES : positive := 110;
g_P2L_FIFO_SIZE : positive := 64; g_P2L_FIFO_SIZE : positive := 64;
g_L2P_FIFO_SIZE : positive := 128; g_L2P_FIFO_SIZE : positive := 256;
g_L2P_FIFO_FULL_THRES : positive := 64;
-- Wishbone ACK timeout (in wishbone clock cycles) -- Wishbone ACK timeout (in wishbone clock cycles)
g_ACK_TIMEOUT : positive := 100); g_ACK_TIMEOUT : positive := 100);
port ( port (
...@@ -569,6 +570,7 @@ begin ...@@ -569,6 +570,7 @@ begin
----------------------------------------------------------------------------- -----------------------------------------------------------------------------
cmp_l2p_dma_master : entity work.l2p_dma_master cmp_l2p_dma_master : entity work.l2p_dma_master
generic map ( generic map (
g_FIFO_FULL_THRES => g_L2P_FIFO_FULL_THRES,
g_FIFO_SIZE => g_L2P_FIFO_SIZE, g_FIFO_SIZE => g_L2P_FIFO_SIZE,
g_BYTE_SWAP => TRUE) g_BYTE_SWAP => TRUE)
port map ( port map (
......
...@@ -61,7 +61,8 @@ package gn4124_core_pkg is ...@@ -61,7 +61,8 @@ package gn4124_core_pkg is
g_WBM_FROM_WB_FIFO_SIZE : positive := 128; g_WBM_FROM_WB_FIFO_SIZE : positive := 128;
g_WBM_FROM_WB_FIFO_FULL_THRES : positive := 110; g_WBM_FROM_WB_FIFO_FULL_THRES : positive := 110;
g_P2L_FIFO_SIZE : positive := 64; g_P2L_FIFO_SIZE : positive := 64;
g_L2P_FIFO_SIZE : positive := 128; g_L2P_FIFO_SIZE : positive := 256;
g_L2P_FIFO_FULL_THRES : positive := 64;
g_WB_MASTER_MODE : t_wishbone_interface_mode := PIPELINED; g_WB_MASTER_MODE : t_wishbone_interface_mode := PIPELINED;
g_WB_MASTER_GRANULARITY : t_wishbone_address_granularity := BYTE; g_WB_MASTER_GRANULARITY : t_wishbone_address_granularity := BYTE;
g_WB_DMA_CFG_MODE : t_wishbone_interface_mode := PIPELINED; g_WB_DMA_CFG_MODE : t_wishbone_interface_mode := PIPELINED;
...@@ -118,7 +119,8 @@ package gn4124_core_pkg is ...@@ -118,7 +119,8 @@ package gn4124_core_pkg is
g_WBM_FROM_WB_FIFO_SIZE : positive := 128; g_WBM_FROM_WB_FIFO_SIZE : positive := 128;
g_WBM_FROM_WB_FIFO_FULL_THRES : positive := 110; g_WBM_FROM_WB_FIFO_FULL_THRES : positive := 110;
g_P2L_FIFO_SIZE : positive := 64; g_P2L_FIFO_SIZE : positive := 64;
g_L2P_FIFO_SIZE : positive := 128; g_L2P_FIFO_SIZE : positive := 256;
g_L2P_FIFO_FULL_THRES : positive := 64;
g_ACK_TIMEOUT : positive := 100); g_ACK_TIMEOUT : positive := 100);
port ( port (
--------------------------------------------------------- ---------------------------------------------------------
......
...@@ -41,7 +41,8 @@ entity xwb_gn4124_core is ...@@ -41,7 +41,8 @@ entity xwb_gn4124_core is
g_WBM_FROM_WB_FIFO_SIZE : positive := 128; g_WBM_FROM_WB_FIFO_SIZE : positive := 128;
g_WBM_FROM_WB_FIFO_FULL_THRES : positive := 110; g_WBM_FROM_WB_FIFO_FULL_THRES : positive := 110;
g_P2L_FIFO_SIZE : positive := 64; g_P2L_FIFO_SIZE : positive := 64;
g_L2P_FIFO_SIZE : positive := 128; g_L2P_FIFO_SIZE : positive := 256;
g_L2P_FIFO_FULL_THRES : positive := 64;
-- WB config for three WB interfaces -- WB config for three WB interfaces
g_WB_MASTER_MODE : t_wishbone_interface_mode := PIPELINED; g_WB_MASTER_MODE : t_wishbone_interface_mode := PIPELINED;
g_WB_MASTER_GRANULARITY : t_wishbone_address_granularity := BYTE; g_WB_MASTER_GRANULARITY : t_wishbone_address_granularity := BYTE;
...@@ -193,6 +194,7 @@ begin ...@@ -193,6 +194,7 @@ begin
g_WBM_FROM_WB_FIFO_FULL_THRES => g_WBM_FROM_WB_FIFO_FULL_THRES, g_WBM_FROM_WB_FIFO_FULL_THRES => g_WBM_FROM_WB_FIFO_FULL_THRES,
g_P2L_FIFO_SIZE => g_P2L_FIFO_SIZE, g_P2L_FIFO_SIZE => g_P2L_FIFO_SIZE,
g_L2P_FIFO_SIZE => g_L2P_FIFO_SIZE, g_L2P_FIFO_SIZE => g_L2P_FIFO_SIZE,
g_L2P_FIFO_FULL_THRES => g_L2P_FIFO_FULL_THRES,
g_ACK_TIMEOUT => g_ACK_TIMEOUT) g_ACK_TIMEOUT => g_ACK_TIMEOUT)
port map ( port map (
rst_n_a_i => rst_n_a_i, rst_n_a_i => rst_n_a_i,
......
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