Commit 2a23d551 authored by Dimitris Lampridis's avatar Dimitris Lampridis

hdl: wip, do not use this commit

parent 73cb5a89
......@@ -76,13 +76,24 @@ end l2p_dma_master;
architecture arch of l2p_dma_master is
-- Used to tweak the almost full flag threshold of the SYNC FIFO
-- in
-- in order to help with timing by giving an advanced warning
-- that we can then pipeline through an equal number of registers.
constant c_SYNC_FIFO_FULL_DELAY : natural := 3;
type l2p_dma_state_type is (L2P_IDLE, L2P_SETUP, L2P_WAIT,
L2P_HEADER, L2P_HOLD, L2P_ADDR_H,
L2P_ADDR_L, L2P_DATA, L2P_NEXT,
L2P_ERROR);
-- Even though the actual limit is 4KiB, the GN4124 really hates it
-- if we try to send more than 256 Bytes (64 Words) within a single packet.
-- During tests, we've seen that the GN4124 chip might freeze when such
-- a request arrives, with the probability of a freeze increasing with
-- the size of the packet.
-- The overhead of the extra transaction is minimal so we keep here the
-- limit that was there in previous versions of this code (128 Bytes,
-- or 32 Words).
constant c_L2P_MAX_PAYLOAD : integer := 32;
type l2p_dma_state_type is (L2P_IDLE, L2P_WB_SETUP, L2P_SETUP,
L2P_WAIT, L2P_HEADER, L2P_HOLD,
L2P_ADDR_H, L2P_ADDR_L, L2P_DATA,
L2P_NEXT, L2P_ERROR);
signal l2p_dma_current_state : l2p_dma_state_type := L2P_IDLE;
type wb_dma_state_type is (WB_IDLE, WB_SETUP, WB_DATA, WB_HOLD);
......@@ -90,7 +101,7 @@ architecture arch of l2p_dma_master is
signal dma_target_addr : unsigned(29 downto 0) := (others => '0');
signal dma_total_len : unsigned(29 downto 0) := (others => '0');
signal dma_packet_len : unsigned(10 downto 0) := (others => '0');
signal dma_packet_len : unsigned(5 downto 0) := (others => '0');
signal dma_host_addr : unsigned(63 downto 0) := (others => '0');
signal dma_byte_swap : std_logic_vector(1 downto 0) := (others => '0');
......@@ -106,7 +117,7 @@ architecture arch of l2p_dma_master is
signal l2p_fsm_dma_param_wr : std_logic := '0';
signal l2p_fsm_dma_param_busy : std_logic := '0';
signal dma_param_sync : std_logic_vector(40 downto 0) := (others => '0');
signal dma_param_sync : std_logic_vector(59 downto 0) := (others => '0');
signal dma_param_wr : std_logic := '0';
signal l2p_timeout_cnt : unsigned(12 downto 0) := (others => '0');
......@@ -116,8 +127,8 @@ architecture arch of l2p_dma_master is
signal wb_dma_stb : std_logic := '0';
signal wb_dma_addr : unsigned(29 downto 0) := (others => '0');
signal wb_dma_addr_d : unsigned(29 downto 0) := (others => '0');
signal wb_dma_cnt_stb : unsigned(10 downto 0) := (others => '0');
signal wb_dma_cnt_ack : unsigned(10 downto 0) := (others => '0');
signal wb_dma_cnt_stb : unsigned(29 downto 0) := (others => '0');
signal wb_dma_cnt_ack : unsigned(29 downto 0) := (others => '0');
signal wb_dma_fsm_en : std_logic := '0';
signal wb_dma_fsm_en_sync : std_logic := '0';
......@@ -185,26 +196,31 @@ begin
dma_host_addr_l <= unsigned(dma_ctrl_host_addr_l_i);
dma_total_len <= unsigned(dma_ctrl_len_i(31 downto 2));
dma_byte_swap <= dma_ctrl_byte_swap_i;
l2p_dma_current_state <= L2P_WB_SETUP;
end if;
when L2P_WB_SETUP =>
l2p_fsm_dma_param_wr <= '1';
if l2p_fsm_dma_param_busy = '1' then
l2p_dma_current_state <= L2P_SETUP;
end if;
when L2P_SETUP =>
-- Calculate DMA packet length for next tranfer. A transfer can be
-- up to 1024 words, limited by the "length" field in the L2P header.
if dma_total_len > 1024 then
dma_packet_len <= to_unsigned(1024, dma_packet_len'length);
-- We limit it artificially to c_L2P_MAX_PAYLOAD (see note in
-- constant declaration).
if dma_total_len > c_L2P_MAX_PAYLOAD then
dma_packet_len <= to_unsigned(c_L2P_MAX_PAYLOAD, dma_packet_len'length);
dma_last_packet <= '0';
elsif dma_total_len = 1024 then
dma_packet_len <= to_unsigned(1024, dma_packet_len'length);
elsif dma_total_len = c_L2P_MAX_PAYLOAD then
dma_packet_len <= to_unsigned(c_L2P_MAX_PAYLOAD, dma_packet_len'length);
dma_last_packet <= '1';
else
dma_packet_len <= dma_total_len(10 downto 0);
dma_packet_len <= dma_total_len(5 downto 0);
dma_last_packet <= '1';
end if;
l2p_fsm_dma_param_wr <= '1';
if l2p_fsm_dma_param_busy = '1' then
l2p_dma_current_state <= L2P_WAIT;
end if;
when L2P_WAIT =>
-- Send request to DMA arbiter
......@@ -237,7 +253,7 @@ begin
-- FBE (First Byte Enable)
l2p_fsm_data(19 downto 16) <= "1111";
-- Length field (in 32 bit words). When zero it means 1024 words.
l2p_fsm_data(9 downto 0) <= std_logic_vector(dma_packet_len(9 downto 0));
l2p_fsm_data(9 downto 0) <= "0000" & std_logic_vector(dma_packet_len);
if (l2p_64b_address = '1') then
l2p_dma_current_state <= L2P_ADDR_H;
else
......@@ -302,9 +318,9 @@ begin
when L2P_NEXT =>
if data_fifo_empty = '1' then
dma_total_len <= dma_total_len - 1024;
dma_target_addr <= dma_target_addr + 1024;
dma_host_addr <= dma_host_addr + 4096;
dma_total_len <= dma_total_len - c_L2P_MAX_PAYLOAD;
dma_target_addr <= dma_target_addr + c_L2P_MAX_PAYLOAD;
dma_host_addr <= dma_host_addr + 4*c_L2P_MAX_PAYLOAD;
l2p_dma_current_state <= L2P_SETUP;
end if;
......@@ -332,15 +348,15 @@ begin
-------------------------------------------------
gen_sync_word_dma_param : if g_DMA_USE_PCI_CLK = FALSE generate
signal dma_param_to_sync : std_logic_vector(40 downto 0);
signal dma_param_to_sync : std_logic_vector(59 downto 0);
begin
dma_param_to_sync(40 downto 11) <= std_logic_vector(dma_target_addr);
dma_param_to_sync(10 downto 0) <= std_logic_vector(dma_packet_len);
dma_param_to_sync(59 downto 30) <= std_logic_vector(dma_target_addr);
dma_param_to_sync(29 downto 0) <= std_logic_vector(dma_total_len);
cmp_sync_dma_param : entity work.gc_sync_word_wr
generic map (
g_AUTO_WR => false,
g_WIDTH => 41)
g_AUTO_WR => FALSE,
g_WIDTH => 60)
port map (
clk_in_i => clk_i,
rst_in_n_i => '1',
......@@ -362,44 +378,14 @@ begin
end generate gen_sync_word_dma_param;
gen_no_sync_word_dma_param: if g_DMA_USE_PCI_CLK = TRUE generate
dma_param_sync(40 downto 11) <= std_logic_vector(dma_target_addr);
dma_param_sync(10 downto 0) <= std_logic_vector(dma_packet_len);
gen_no_sync_word_dma_param : if g_DMA_USE_PCI_CLK = TRUE generate
dma_param_sync(59 downto 30) <= std_logic_vector(dma_target_addr);
dma_param_sync(29 downto 0) <= std_logic_vector(dma_total_len);
l2p_fsm_dma_param_busy <= l2p_fsm_dma_param_wr;
dma_param_wr <= l2p_fsm_dma_param_wr;
wb_dma_fsm_en_sync <= wb_dma_fsm_en;
end generate gen_no_sync_word_dma_param;
-- p_wb_master : process (wb_dma_clk_i) is
-- begin
-- if rising_edge(wb_dma_clk_i) then
-- if wb_dma_rst_n_i = '0' then
-- wb_dma_stb <= '0';
-- else
-- -- Handle strobe and address generation.
-- wb_dma_stb <= '0';
-- if wb_xfer_en_sync = '1' then
-- if wb_dma_cnt > 1 and data_fifo_full = '0' or
-- wb_dma_stb <= '1';
-- if wb_dma_i.stall = '0' and wb_dma_stb = '1' then
-- wb_dma_addr <= wb_dma_addr + 1;
-- wb_dma_cnt <= wb_dma_cnt - 1;
-- end if;
-- end if;
-- elsif dma_param_wr = '1' then
-- wb_dma_addr <= unsigned(dma_param_sync(40 downto 11));
-- wb_dma_cnt <= unsigned(dma_param_sync(10 downto 0));
-- end if;
-- -- Write received data to FIFO.
-- -- No need to check FIFO full, it was done earlier
-- -- when we decided to strobe.
-- data_fifo_din <= wb_dma_i.dat;
-- data_fifo_wr <= wb_dma_i.ack;
-- end if;
-- end if;
-- end process p_wb_master;
-- P2P communication, no need to drop WB cycle.
wb_dma_o.cyc <= '1';
wb_dma_o.stb <= wb_dma_stb;
......@@ -436,9 +422,9 @@ begin
end if;
when WB_SETUP =>
wb_dma_addr <= unsigned(dma_param_sync(40 downto 11));
wb_dma_cnt_stb <= unsigned(dma_param_sync(10 downto 0));
wb_dma_cnt_ack <= unsigned(dma_param_sync(10 downto 0));
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));
if data_fifo_full = '0' then
wb_dma_current_state <= WB_DATA;
end if;
......
......@@ -179,7 +179,7 @@ module main;
initial begin
automatic int ntest = 1;
const int tests = 9;
const int tests = 8;
uint32_t addr, val, expected;
......@@ -211,38 +211,6 @@ module main;
$write("PASS\n");
/* -----\/----- EXCLUDED -----\/-----
$write("Test %0d/%0d: 128B read over DMA, abort after first read: ",
ntest++, tests);
if (dma_irq != 1'b0)
$fatal(1, "dma irq should be 0");
acc.write('h14, 'h80); // count
acc.write('h00, 'h01); // start
// Check values read from memory
@(posedge i_gn4124.l2p_valid); // skip header
repeat(2) @(posedge i_gn4124.l2p_clk_p);
expected = 32'h8000001f;
val = i_gn4124.l2p_data;
@(posedge i_gn4124.l2p_clk_n);
val |= i_gn4124.l2p_data << 16;
val_check("DMA read-back", 'h20, val, expected);
repeat(2) @(posedge clk_125m);
// Test abort feature
acc.write('h00, 'h02);
reg_check('h04, 'h03);
acc.write('h00, 'h00);
repeat(2) @(posedge clk_125m);
$write("PASS\n");
-----/\----- EXCLUDED -----/\----- */
$write("Test %0d/%0d: 2x128B chained reads over DMA: ",
ntest++, tests);
......@@ -347,26 +315,26 @@ module main;
#1us;
end
$write("Test %0d/%0d: 8KB read over DMA with 32bit host address overflow: ",
$write("Test %0d/%0d: 256B read over DMA with 32bit host address overflow: ",
ntest++, tests);
acc.write('h14, 'h2000); // count
acc.write('h14, 'h100); // count
acc.write('h20, 'h00); // attrib
acc.write('h0c, 'hfffff000); // hstartL
acc.write('h0c, 'hffffff80); // hstartL
acc.write('h10, 'h00000000); // hstartH
acc.write('h00, 'h01); // start
// Transfer will be split internally by L2P DMA master in two requests, the first
// one with a 32-bit adress starting at ffff_f000 and the next one with a 64-bit
// one with a 32-bit adress starting at ffff_ff80 and the next one with a 64-bit
// address starting at 1_0000_0000
@(posedge DUT.cmp_wrapped_gn4124.ldm_arb_dframe);
@(posedge DUT.cmp_wrapped_gn4124.sys_clk);
val_check("Host address overflow header", 1, DUT.cmp_wrapped_gn4124.ldm_arb_data, 'h02ff0000);
val_check("Host address overflow header", 1, DUT.cmp_wrapped_gn4124.ldm_arb_data, 'h02ff0020);
@(posedge DUT.cmp_wrapped_gn4124.sys_clk);
val_check("Host address overflow address", 1, DUT.cmp_wrapped_gn4124.ldm_arb_data, 'hfffff000);
val_check("Host address overflow address", 1, DUT.cmp_wrapped_gn4124.ldm_arb_data, 'hffffff80);
@(posedge DUT.cmp_wrapped_gn4124.ldm_arb_dframe);
@(posedge DUT.cmp_wrapped_gn4124.sys_clk);
val_check("Host address overflow header", 2, DUT.cmp_wrapped_gn4124.ldm_arb_data, 'h03ff0000);
val_check("Host address overflow header", 2, DUT.cmp_wrapped_gn4124.ldm_arb_data, 'h03ff0020);
@(posedge DUT.cmp_wrapped_gn4124.sys_clk);
val_check("Host address overflow address high", 2, DUT.cmp_wrapped_gn4124.ldm_arb_data, 1);
@(posedge DUT.cmp_wrapped_gn4124.sys_clk);
......
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