]> jspc29.x-matter.uni-frankfurt.de Git - pexor.git/commitdiff
*** empty log message ***
authorhadeshyp <hadeshyp>
Mon, 6 Jun 2011 16:48:10 +0000 (16:48 +0000)
committerhadeshyp <hadeshyp>
Mon, 6 Jun 2011 16:48:10 +0000 (16:48 +0000)
design/dma_core.vhd

index a82d362c4066ec2171486ed57e0f995d386f2596..ba254a8588953f30d33598358d83557bd284846e 100644 (file)
@@ -16,6 +16,7 @@ entity dma_core is
 
     DMA_DATA_IN          : in  std_logic_vector(31 downto 0);
     DMA_LENGTH_WR_IN     : in  std_logic;
+        --23-0: Buffer size in 32 Bit words
     DMA_ADDR_WR_IN       : in  std_logic;
     DMA_CONTROL_IN       : in  std_logic_vector(31 downto 0); --0x702 write
         --0: activate
@@ -25,7 +26,7 @@ entity dma_core is
         --1: buffer full - waiting for reactivation
         --31..8: data length in 32bit words
     DMA_CONFIG_IN        : in  std_logic_vector(31 downto 0); --0x703
-        --7..0 max burst size
+        --9..0 max burst size
 
     API_RUNNING_IN       : in  std_logic;
     API_DATA_IN          : in  std_logic_vector(15 downto 0);
@@ -55,6 +56,10 @@ entity dma_core is
     RX_DWEN_IN           : in  std_logic;
     RX_DATA_IN           : in  std_logic_vector(63 downto 0);
 
+    DEBUG_FIFO_DATA_OUT  : out std_logic_vector(63 downto 0);
+    DEBUG_FIFO_EMPTY_OUT : out std_logic_vector(1 downto 0);
+    DEBUG_FIFO_READ_IN   : in  std_logic_vector(1 downto 0);
+
     STATUS_REG_OUT       : out std_logic_vector(159 downto 0);
     DEBUG_OUT            : out std_logic_vector(31 downto 0)
 
@@ -65,8 +70,8 @@ architecture dma_core_arch of dma_core is
 
   signal reset_i                 : std_logic;
 
-  signal credit_available_np     : std_logic := '0';
-  signal credit_available_p      : std_logic := '0';
+--   signal credit_available_np     : std_logic := '0';
+--   signal credit_available_p      : std_logic := '0';
 
   signal tx_wr_en                : std_logic := '0';
   signal tx_rd_en                : std_logic := '0';
@@ -89,7 +94,7 @@ architecture dma_core_arch of dma_core is
   type copy_state_t is (IDLE, RUNNING, LAST_WORD, BUFFER_FULL_WAIT, WAIT_ONE, WAIT_BUFFER);
   signal copy_state : copy_state_t;
 
-  signal copy_length             : unsigned(11 downto 0) := (others => '0');
+  signal copy_length             : unsigned(9 downto 0) := (others => '0');
   signal current_address         : unsigned(31 downto 0) := (others => '0');
   signal buf_API_READ_OUT        : std_logic := '0';
 
@@ -101,47 +106,49 @@ architecture dma_core_arch of dma_core is
   signal finished_sys            : std_logic := '0';
   signal busy                    : std_logic := '0';
 
-  signal tx_req_i                : std_logic;
-  signal tx_end_i                : std_logic;
-  signal tx_st_i                 : std_logic;
+  signal tx_req_i                : std_logic := '0';
+  signal tx_end_i                : std_logic := '0';
+  signal tx_st_i                 : std_logic := '0';
   signal send_state_bits         : std_logic_vector(3 downto 0);
   signal copy_state_bits         : std_logic_vector(1 downto 0);
 
 
   signal total_length            : unsigned(23 downto 0) := (others => '0');
-  signal current_buffer          : unsigned(23 downto 0) := (others => '0');
   signal tx_fifo_padding         : std_logic_vector(3 downto 0) := (others => '0');
   signal api_running_rising      : std_logic;
   signal api_running_falling     : std_logic;
-  signal api_starts              : std_logic;
   signal last_api_running        : std_logic;
   signal buf_TX_DATA_OUT         : std_logic_vector(63 downto 0) := (others => '0');
   signal buffer_full_strobe      : std_logic;
   signal buffer_full             : std_logic;
 
-  signal current_burst_length    : unsigned(11 downto 0);
+  signal current_burst_length    : unsigned(9 downto 0) := (others => '0');
   signal buffer_space_available  : std_logic;
-  signal buffer_space_end        : unsigned(31 downto 0);
-  signal buffer_space_afull      : unsigned(31 downto 0);
-  
-  signal credits_sys             : std_logic_vector(12 downto 0);
-  
+  signal buffer_length           : unsigned(23 downto 0) := (others => '0');
+  signal credits_sys             : std_logic_vector(12 downto 0) := (others => '0');
+
   signal rden_dma_fifo            : std_logic := '0';
   signal reset_dma_fifo           : std_logic := '0';
   signal empty_addr_fifo          : std_logic := '0';
   signal empty_length_fifo        : std_logic := '0';
-  signal next_dma_length_i        : std_logic_vector(31 downto 0);
-  signal next_dma_start_address_i : std_logic_vector(31 downto 0);
-  signal dma_length_i             : std_logic_vector(31 downto 0);
-  signal dma_start_address_i      : std_logic_vector(31 downto 0);
+  signal next_dma_length_i        : std_logic_vector(31 downto 0) := (others => '0');
+  signal next_dma_start_address_i : std_logic_vector(31 downto 0) := (others => '0');
+  signal dma_length_i             : std_logic_vector(31 downto 0) := (others => '0');
+  signal dma_start_address_i      : std_logic_vector(31 downto 0) := (others => '0');
   signal new_buffer_available     : std_logic := '0';
-  signal dma_fifo_state           : std_logic_vector(3 downto 0);
+  signal dma_fifo_state           : std_logic_vector(3 downto 0) := (others => '0');
 
   type dma_state_t is (INACTIVE, ACTIVE, WAIT_1, WAIT_2, WAIT_3, ENABLE, WORKING, DMA_RESET);
   signal current_dma_state : dma_state_t;
-  
+
   signal  dummy : std_logic_vector(2 downto 0);
-  
+
+  signal df_write_en        : std_logic;
+  signal df_read_en         : std_logic_vector(1 downto 0);
+  signal df_full            : std_logic;
+  signal df_full_q          : std_logic;
+  signal next_df_write_en   : std_logic;
+
 begin
 
 
@@ -185,7 +192,7 @@ API_READ_OUT <= buf_API_READ_OUT;
       if rising_edge(CLK_IN) then
         rden_dma_fifo             <= '0';
         reset_dma_fifo            <= '0';
-        new_buffer_available      <= '0';        
+        new_buffer_available      <= '0';
         case current_dma_state is
           when INACTIVE =>
             DMA_STATUS_OUT(1)     <= '0';
@@ -229,7 +236,7 @@ API_READ_OUT <= buf_API_READ_OUT;
             DMA_STATUS_OUT(1)     <= '1';
             current_dma_state     <= INACTIVE;
         end case;
-        
+
         if RESET_IN = '1' then
           current_dma_state <= INACTIVE;
         end if;
@@ -239,14 +246,14 @@ API_READ_OUT <= buf_API_READ_OUT;
         end if;
       end if;
     end process;
-    
+
 
   process(CLK_IN)
     begin
       if rising_edge(CLK_IN) then
         dma_length_i <= next_dma_length_i;
         dma_start_address_i <= next_dma_start_address_i;
-        
+
       end if;
     end process;
 
@@ -256,34 +263,41 @@ API_READ_OUT <= buf_API_READ_OUT;
 -- Burst Length & Buffer Space calculation
 -----------------------------------------------------------------------
 PROC_BUFFER_SPACE : process(CLK_IN)
+  variable credit_sys_u    : unsigned(23 downto 0);
+  variable max_burst_u     : unsigned(23 downto 0);
+  variable current_burst_u : unsigned(23 downto 0);
+  variable space_left_u    : unsigned(23 downto 0);
+  begin
+    credit_sys_u    := "000000000" & unsigned(credits_sys(12 downto 0)) & "00";
+    max_burst_u     := "00000000000000" & unsigned(DMA_CONFIG_IN(9 downto 0));
+    space_left_u    := unsigned(dma_length_i(23 downto 0)) - buffer_length;
+    current_burst_u := max_burst_u;
 
-  begin  
-    buffer_space_end   <= unsigned(dma_start_address_i) + unsigned(dma_length_i(28 downto 0)) * to_unsigned(4,3);
-    buffer_space_afull <= buffer_space_end - (unsigned(DMA_CONFIG_IN(11 downto 0)) * to_unsigned(4,20));
-    
-    --Enough space for full burst
-    if rising_edge(CLK_IN)  then 
+    if rising_edge(CLK_IN)  then
       if (copy_state = IDLE or copy_state = LAST_WORD or copy_state = BUFFER_FULL_WAIT or copy_state = WAIT_BUFFER) then
         if busy = '0' then
           buffer_space_available    <= '1';
-          current_burst_length      <= unsigned(DMA_CONFIG_IN(11 downto 0));          
-        elsif current_address < buffer_space_afull then
-          if unsigned(DMA_CONFIG_IN(11 downto 0)) < unsigned(credits_sys(11 downto 0)) then
-            current_burst_length    <= unsigned(DMA_CONFIG_IN(11 downto 0));            
-          else
-            current_burst_length    <= unsigned(credits_sys(11 downto 0));
-          end if;
-          buffer_space_available  <= '1';
-        elsif current_address < buffer_space_end then
-          if buffer_space_end(13 downto 2) - current_address(13 downto 2) < unsigned(credits_sys(11 downto 0)) then
-            current_burst_length    <= buffer_space_end(13 downto 2) - current_address(13 downto 2);
-          else
-            current_burst_length    <= unsigned(credits_sys(11 downto 0)); 
+          current_burst_u           := max_burst_u;
+        elsif unsigned(dma_length_i(23 downto 0)) > buffer_length then --space available
+          buffer_space_available    <= '1';
+          if credit_sys_u < max_burst_u then                           --less credits than max burst
+            if space_left_u >= credit_sys_u then                       --more space than credits
+              current_burst_u       := credit_sys_u;
+            else                                                       --less space than credits
+              current_burst_u       := space_left_u;
+            end if;
+          else                                                         --more credits than max burst
+            if space_left_u >= max_burst_u then                        --more space than credits
+              current_burst_u       := max_burst_u;
+            else                                                       --less space than credits
+              current_burst_u       := space_left_u;
+            end if;
           end if;
-          buffer_space_available  <= '1';
-        else
-          buffer_space_available  <= '0';
+        else                                                           -- no space
+          buffer_space_available    <= '0';
+          current_burst_u           := (others => '0');
         end if;
+        current_burst_length <= current_burst_u(9 downto 0);
       end if;
     end if;
   end process;
@@ -309,9 +323,10 @@ PROC_COPY_DATA : process(CLK_IN)
         tx_length_wr_en    <= '0';
         copy_state         <= IDLE;
         buf_API_READ_OUT   <= '0';
-        copy_length        <= (others => '0'); --length counter while copying
+        copy_length        <= (others => '0'); --length counter while copying for current burst
         buffer_full_strobe <= '0';
-        total_length       <= (others => '0');
+        buffer_length      <= (others => '0'); --length of data written to current buffer
+        total_length       <= (others => '0'); --total length of transfer
       else
         tx_wr_en           <= '0';
         tx_length_wr_en    <= '0';
@@ -323,21 +338,23 @@ PROC_COPY_DATA : process(CLK_IN)
             copy_state_bits <= "00";
             if new_buffer_available = '1' then
               current_address            <= unsigned(dma_start_address_i);
+              buffer_length              <= (others => '0');
             end if;
-            if busy = '1' and (API_RUNNING_IN = '1' or API_DATAREADY_IN = '1') and tx_almost_full = '0' then --DMA enable and API running
+            if busy = '1' and (API_RUNNING_IN = '1' or API_DATAREADY_IN = '1') and tx_almost_full = '0' and tx_length_almost_full = '0' then
+
               if buffer_space_available = '1' then --Enough space in buffer for one burst
---                 current_address + unsigned(DMA_CONFIG_IN(7 downto 0)) * to_unsigned(4,32)
---                     < unsigned(DMA_START_ADDR_IN) + unsigned(DMA_LENGTH_IN) * to_unsigned(4,32) then
-                tx_data_in( 7 downto  0) <= std_logic_vector(current_address(31 downto 24));
-                tx_data_in(15 downto  8) <= std_logic_vector(current_address(23 downto 16));
-                tx_data_in(23 downto 16) <= std_logic_vector(current_address(15 downto 8));
-                tx_data_in(31 downto 24) <= std_logic_vector(current_address( 7 downto 0));
-                tx_data_in(35 downto 32) <= x"0";
-                buf_API_READ_OUT         <= '1';
-                copy_length              <= (0 => '1', others => '0');
-                copy_state               <= RUNNING;
-                tx_wr_en                 <= '1';
-                tx_fifo_padding          <= x"8";
+                if current_burst_length /= 0 then
+                  tx_data_in( 7 downto  0) <= std_logic_vector(current_address(31 downto 24));
+                  tx_data_in(15 downto  8) <= std_logic_vector(current_address(23 downto 16));
+                  tx_data_in(23 downto 16) <= std_logic_vector(current_address(15 downto 8));
+                  tx_data_in(31 downto 24) <= std_logic_vector(current_address( 7 downto 0));
+                  tx_data_in(35 downto 32) <= x"0";
+                  buf_API_READ_OUT         <= '1';
+                  copy_length              <= (0 => '1', others => '0');
+                  copy_state               <= RUNNING;
+                  tx_wr_en                 <= '1';
+                  tx_fifo_padding          <= x"8";
+                end if;
               else
                 buffer_full_strobe       <= '1';
                 copy_state               <= BUFFER_FULL_WAIT;
@@ -347,11 +364,12 @@ PROC_COPY_DATA : process(CLK_IN)
           when RUNNING =>
             copy_state_bits <= "01";
             if API_DATAREADY_IN = '1' then
-              tx_data_in             <= x"0" & "00000001000000"
+              tx_data_in             <= x"0" & "000000" & API_RUNNING_IN & "1000000"
                                         & API_PACKET_NUM_IN(2) & API_PACKET_NUM_IN(0) & API_DATA_IN(15 downto 0);
               tx_wr_en               <= '1';
-              copy_length            <= copy_length + to_unsigned(1,7);
+              copy_length            <= copy_length + to_unsigned(1,10);
               total_length           <= total_length + to_unsigned(1,1);
+              buffer_length          <= buffer_length + to_unsigned(1,1);
               current_address        <= current_address + to_unsigned(4,32);
 --               if copy_length = unsigned(DMA_CONFIG_IN(6 downto 0)) - to_unsigned(1,1) then
 --                 buf_API_READ_OUT     <= '0';
@@ -383,9 +401,10 @@ PROC_COPY_DATA : process(CLK_IN)
             copy_state_bits          <= "11";
             if new_buffer_available = '1' then
               copy_state             <= WAIT_BUFFER;
-              current_address        <= unsigned(dma_start_address_i);              
+              buffer_length          <= (others => '0');
+              current_address        <= unsigned(dma_start_address_i);
             end if;
-            
+
           when WAIT_BUFFER =>
             copy_state               <= IDLE;
         end case;
@@ -398,7 +417,7 @@ PROC_COPY_DATA : process(CLK_IN)
     end if;
   end process;
 
-  tx_length_data_in <= last_words & "000" & std_logic_vector(copy_length-to_unsigned(1,12));
+  tx_length_data_in <= last_words & "00000" & std_logic_vector(copy_length(9 downto 0)-to_unsigned(1,10));
 
 
 
@@ -478,11 +497,13 @@ PROC_DMA_SEND : process(CLK_125_IN)
 
           when SEND_CREDIT_WAIT =>
             send_state_bits <= x"1";
-            if tx_length_data_out(11 downto 0) = "0000000" then --no data
+            if tx_length_data_out(9 downto 0) = "0000000000" then --no data
               finished     <= tx_length_data_out(15);
               send_state   <= SEND_IDLE;
-            elsif (TX_CA_PH_IN(8) = '1' or (unsigned(TX_CA_PH_IN(7 downto 0)) > to_unsigned(1,8)))
-              and ((TX_CA_PD_IN(12 downto 8) /= "00000") or (unsigned(TX_CA_PD_IN(11 downto 0)) >= unsigned(tx_length_data_out(11 downto 0))))
+            elsif (TX_CA_PH_IN(8) = '1' or (unsigned(TX_CA_PH_IN(7 downto 0)) >= to_unsigned(1,8)))
+              and ((TX_CA_PD_IN(12 downto 8) /= "00000")
+                   or (unsigned(TX_CA_PD_IN(7 downto 0)) > unsigned(tx_length_data_out(9 downto 2)))
+                   or (unsigned(TX_CA_PD_IN(7 downto 0)) = unsigned(tx_length_data_out(9 downto 2)) and tx_length_data_out(1 downto 0) = "00"))
                 then
               tx_st_i        <= '0';
               tx_end_i       <= '0';
@@ -503,7 +524,7 @@ PROC_DMA_SEND : process(CLK_125_IN)
                               x"FF";     --Byte Enables
               tx_rd_en     <= '1'; --
               tx_req_i     <= '1';
-              tx_length    <= unsigned(tx_length_data_out(11 downto 0));
+              tx_length    <= "00" & unsigned(tx_length_data_out(9 downto 0));
               send_state   <= SEND_START;
             end if;
 
@@ -512,10 +533,10 @@ PROC_DMA_SEND : process(CLK_125_IN)
             if TX_RDY_IN = '1' then
               if TX_VAL_IN = '1' then
                 tx_st_i    <= '1';
-                if tx_length > to_unsigned(1,3) then
+                if tx_length > to_unsigned(1,12) then
                   tx_rd_en   <= '1';
                 end if;
-                tx_length  <= tx_length - to_unsigned(1,1);
+                tx_length  <= tx_length - to_unsigned(1,12);
                 send_state <= SEND_DATA; --SEND_FIRST;
                 tx_req_i <= '0';
               end if;
@@ -571,7 +592,8 @@ THE_finished_strobe_SYNC : pulse_sync
 --sync credits to sys clock
 THE_Credit_FIFO : fifo_16x512_dualclock
     port map (
-      Data        => "000" & TX_CA_PD_IN(12 downto 0),
+      Data(15 downto 13)=> "000",
+      Data(12 downto 0) => TX_CA_PD_IN(12 downto 0),
       WrClock     => CLK_125_IN,
       RdClock     => CLK_IN,
       WrEn        => '1',
@@ -627,6 +649,68 @@ PROC_STATUS_OUT : process(CLK_IN)
     end if;
   end process;
 
+-----------------------------------------------------------------------
+-- RX Path
+-----------------------------------------------------------------------
+THE_DEBUG_FIFO_1 : fifo_dc_32x1024
+    port map(
+      Data        => buf_TX_DATA_OUT(31 downto 0),
+      WrClock     => CLK_125_IN,
+      RdClock     => CLK_IN,
+      WrEn        => df_write_en,
+      RdEn        => df_read_en(0),
+      Reset       => RESET_IN,
+      RPReset     => RESET_IN,
+      Q           => DEBUG_FIFO_DATA_OUT(31 downto 0),
+      Empty       => DEBUG_FIFO_EMPTY_OUT(0),
+      Full        => open,
+      AlmostEmpty => open,
+      AlmostFull  => df_full
+      );
+THE_DEBUG_FIFO_2 : fifo_dc_32x1024
+    port map(
+      Data        => buf_TX_DATA_OUT(63 downto 32),
+      WrClock     => CLK_125_IN,
+      RdClock     => CLK_IN,
+      WrEn        => df_write_en,
+      RdEn        => df_read_en(1),
+      Reset       => RESET_IN,
+      RPReset     => RESET_IN,
+      Q           => DEBUG_FIFO_DATA_OUT(63 downto 32),
+      Empty       => DEBUG_FIFO_EMPTY_OUT(1),
+      Full        => open,
+      AlmostEmpty => open,
+      AlmostFull  => open
+      );
+
+process(CLK_125_IN)
+  begin
+    if rising_edge(CLK_125_IN) then
+      if tx_st_i = '1' then
+        next_df_write_en <= '1';
+      elsif tx_end_i = '1' or send_state = SEND_IDLE then
+        next_df_write_en <= '0';
+      end if;
+    end if;
+  end process;
+
+df_write_en <= next_df_write_en or tx_st_i;
+df_read_en(0) <= df_full_q or DEBUG_FIFO_READ_IN(0);
+df_read_en(1) <= df_full_q or DEBUG_FIFO_READ_IN(1);
+
+THE_DF_FIFO_SYNC : signal_sync
+  generic map(
+    WIDTH => 1,     --
+    DEPTH => 2
+    )
+  port map(
+    RESET    => RESET_IN,
+    CLK0     => CLK_IN,
+    CLK1     => CLK_IN,
+    D_IN(0)  => df_full,
+    D_OUT(0) => df_full_q
+    );
+
 
 -----------------------------------------------------------------------
 -- RX Path
@@ -650,16 +734,16 @@ STATUS_REG_OUT(12)           <= tx_empty;
 STATUS_REG_OUT(13)           <= tx_length_empty;
 STATUS_REG_OUT(14)           <= tx_almost_full;
 STATUS_REG_OUT(15)           <= tx_end_i;
-STATUS_REG_OUT(27 downto 16) <= std_logic_vector(copy_length);
-STATUS_REG_OUT(28)           <= buffer_full;
-STATUS_REG_OUT(31 downto 29) <= (others => '0');
+STATUS_REG_OUT(25 downto 16) <= std_logic_vector(copy_length);
+STATUS_REG_OUT(26)           <= buffer_full;
+STATUS_REG_OUT(31 downto 27) <= (others => '0');
 
 STATUS_REG_OUT(40 downto 32) <= TX_CA_PH_IN;
 STATUS_REG_OUT(53 downto 41) <= credits_sys(12 downto 0); --TX_CA_PD_IN;
 STATUS_REG_OUT(62 downto 54) <= TX_CA_NPH_IN;
 STATUS_REG_OUT(63)           <= '0';
 
-STATUS_REG_OUT(95 downto 64) <= std_logic_vector(current_burst_length) &  x"0"  & tx_length_data_out;
+STATUS_REG_OUT(95 downto 64) <= "00" & std_logic_vector(current_burst_length) &  x"0"  & tx_length_data_out;
 
 STATUS_REG_OUT(127 downto 96)<= std_logic_vector(current_address);
 
@@ -703,8 +787,8 @@ process(CLK_IN)
       DEBUG_OUT(11 downto 10)<= dma_fifo_state(1 downto 0);
       DEBUG_OUT(13 downto 12) <= copy_state_bits;
       DEBUG_OUT(15 downto 14) <= send_state_bits(1 downto 0);
-      DEBUG_OUT(23 downto 16) <= credits_sys(7 downto 0);
-      DEBUG_OUT(31 downto 24) <= tx_length(7 downto 0);
+      DEBUG_OUT(28 downto 16) <= credits_sys(12 downto 0);
+      DEBUG_OUT(31 downto 29) <= "000";
     end if;
   end process;
 
@@ -793,3 +877,22 @@ end architecture;
 --             else
 --               tx_end_i   <= '0';
 --             end if;
+
+
+--         elsif current_address < buffer_space_afull then
+--           if unsigned(DMA_CONFIG_IN(11 downto 0)) < unsigned(credits_sys(11 downto 0)) then
+--             current_burst_length    <= unsigned(DMA_CONFIG_IN(11 downto 0));
+--           else
+--             current_burst_length    <= unsigned(credits_sys(11 downto 0));
+--           end if;
+--           buffer_space_available  <= '1';
+--         elsif current_address < buffer_space_end then
+--           if buffer_space_end(13 downto 2) - current_address(13 downto 2) < unsigned(credits_sys(11 downto 0)) then
+--             current_burst_length    <= buffer_space_end(13 downto 2) - current_address(13 downto 2);
+--           else
+--             current_burst_length    <= unsigned(credits_sys(11 downto 0));
+--           end if;
+--           buffer_space_available  <= '1';
+--         else
+--           buffer_space_available  <= '0';
+--         end if;