]> jspc29.x-matter.uni-frankfurt.de Git - trb3.git/commitdiff
add monitoring flags and counters to circular buffer.
authorTobias Weber <toweber86@gmail.com>
Mon, 27 Nov 2017 10:36:24 +0000 (11:36 +0100)
committerTobias Weber <toweber86@gmail.com>
Mon, 27 Nov 2017 10:36:24 +0000 (11:36 +0100)
mupix/Mupix8/sources/CircularMemory.vhd
mupix/Mupix8/sources/StdTypes.vhd
mupix/Mupix8/tb/CircularMemoryTest.vhd

index c7c3012f626382813130558a1db490835570a2ff..e99ebe4127d15c4f765bfb7fda3572a90079ee25 100644 (file)
@@ -7,20 +7,26 @@ library ieee;
 use ieee.std_logic_1164.all;
 use ieee.numeric_std.all;
 
+use work.StdTypes.all;
+
 entity CircularMemory is
        generic(
                g_datawidth    : integer := 32; -- width of data words
-               g_addresswidth : integer := 10  -- width of address pointers, number of words is 2**g_addresswidth
+               g_addresswidth : integer := 10; -- width of address pointers, number of words is 2**g_addresswidth
+               g_clockspeed   : integer := 1e8 -- FPGA clock speed in Hz
        );
        port(
-               clk      : in  std_logic;       -- clock input
-               rst      : in  std_logic;       -- reset 
-               wr_en    : in  std_logic;       -- write enable
-               data_in  : in  std_logic_vector(g_datawidth - 1 downto 0); -- input word
-               rd_en    : in  std_logic;       --read enable
-               data_out : out std_logic_vector(g_datawidth - 1 downto 0); -- output word
-               empty    : out std_logic;       --empty flag
-               full     : out std_logic        --full flag
+               clk          : in  std_logic;   -- clock input
+               rst          : in  std_logic;   -- reset 
+               wr_en        : in  std_logic;   -- write enable
+               data_in      : in  std_logic_vector(g_datawidth - 1 downto 0); -- input word
+               rd_en        : in  std_logic;   --read enable
+               data_out     : out std_logic_vector(g_datawidth - 1 downto 0); -- output word
+               empty        : out std_logic;   --empty flag
+               full         : out std_logic;   --full flag
+               fillcnt      : out std_logic_vector(g_addresswidth - 1 downto 0); -- number of words in circullar buffer
+               inword_freq  : out std_logic_vector(31 downto 0); -- number of input words per second
+               outword_freq : out std_logic_vector(31 downto 0) -- number of output words per second
        );
 end entity CircularMemory;
 
@@ -41,6 +47,10 @@ architecture RTL of CircularMemory is
                );
        end component BlockMemory;
        
+       --counters for write/read frequency
+       signal ticks_counter : unsigned(f_log2(g_clockspeed) - 1 downto 0) := (others => '0');
+       signal inword_counter, outword_counter : unsigned(31 downto 0) := (others => '0');
+       
        --read and write pointers
        constant c_high_address : integer := 2**g_addresswidth;
        signal readpointer : integer range 0 to c_high_address - 1 := 0;
@@ -140,9 +150,38 @@ begin
                end if;
        end process word_counter_proc;
        
+       throughput_proc : process (clk) is
+       begin
+               if rising_edge(clk) then
+                       if rst = '1' then
+                               ticks_counter <= (others => '0');
+                               inword_counter <= (others => '0');
+                               outword_counter <= (others => '0');
+                       else
+                               if wr_en = '1' then
+                                       inword_counter <= inword_counter + 1;
+                               end if;
+                               if rd_en = '1' then
+                                       outword_counter <= outword_counter + 1;
+                               end if;
+                               if ticks_counter = g_clockspeed - 1 then
+                                       ticks_counter <= (others => '0');
+                                       inword_freq <= std_logic_vector(inword_counter);
+                                       outword_freq <= std_logic_vector(outword_counter);
+                                       inword_counter <= (others => '0');
+                                       outword_counter <= (others => '0');
+                               else
+                                       ticks_counter <= ticks_counter + 1;
+                               end if;
+                       end if;
+               end if;
+       end process throughput_proc;
+       
+       
        
        empty <= '1' after 1 ns when words_in_buffer = 0 else '0' after 1 ns;
        full  <= '1' after 1 ns when words_in_buffer = c_high_address else '0' after 1 ns;
+       fillcnt <= std_logic_vector(to_unsigned(words_in_buffer, g_addresswidth));
        data_out <= Dout_mem;
        
 end architecture RTL;
index a0a891bb94108ad67447c9d1cba975c09918f61f..35d11bc08aca414d86160eb822de393ac432b5aa 100644 (file)
@@ -12,6 +12,35 @@ package StdTypes is
        end record MupixSlowControl;
        
        constant c_mupix_slctrl_init : MupixSlowControl := ('0', '0', '0', '0');
-               
+       
+       type t_counter_array is array(integer range <>) of unsigned(31 downto 0);
+       
+       function f_log2(x : positive) return natural;
+       function counter_array_to_stdvec(x : t_counter_array) return std_logic_vector;
+       
 end package StdTypes;
 
+package body StdTypes is
+       
+function f_log2(x : positive) return natural is
+               variable i : natural;
+       begin
+               i := 0;
+               while (2**i < x) loop
+                       i := i + 1;
+               end loop;
+               return i;
+       end function;
+       
+       
+function counter_array_to_stdvec(x : t_counter_array) return std_logic_vector is
+       variable tmp : std_logic_vector(32*x'length - 1 downto 0);
+begin
+       tmp := (others => '0');
+       for i in 0 to x'length - 1 loop
+               tmp(32*(i + 1) - 1 downto 32*i) := std_logic_vector(x(i));
+       end loop;
+       return tmp;
+end function;
+
+end package body StdTypes;
index a1552a9fa27c602d606ff7b819adb7698db70ad3..2388f99cbb6fe14134ceb7d32d4d0f998c18619b 100644 (file)
@@ -20,7 +20,10 @@ architecture sim of CircularMemoryTest is
                        rd_en    : in  std_logic;
                        data_out : out std_logic_vector(g_datawidth - 1 downto 0);
                        empty    : out std_logic;
-                       full     : out std_logic
+                       full     : out std_logic;
+                       fillcnt      : out std_logic_vector(g_addresswidth - 1 downto 0);
+                       inword_freq  : out std_logic_vector(31 downto 0); 
+                       outword_freq : out std_logic_vector(31 downto 0) 
                );
        end component CircularMemory;
        
@@ -36,13 +39,17 @@ architecture sim of CircularMemoryTest is
        signal data_out : std_logic_vector(c_data_width - 1 downto 0);
        signal empty    : std_logic;
        signal full     : std_logic;
+       signal fillcnt : std_logic_vector(c_address_width - 1 downto 0);
+       signal inword_freq : std_logic_vector(31 downto 0);
+       signal outword_freq : std_logic_vector(31 downto 0);
        
 begin
        
        dut : entity work.CircularMemory
                generic map(
                        g_datawidth    => c_data_width,
-                       g_addresswidth => c_address_width
+                       g_addresswidth => c_address_width,
+                       g_clockspeed => 1e3
                )
                port map(
                        clk      => clk,
@@ -52,7 +59,10 @@ begin
                        rd_en    => rd_en,
                        data_out => data_out,
                        empty    => empty,
-                       full     => full
+                       full     => full,
+                       fillcnt => fillcnt,
+                       inword_freq => inword_freq,
+                       outword_freq => outword_freq
                );
                
                clk_gen : process is