From 5c41e3e7048a1ab41ced0c1a6ad1d3c088eb42a5 Mon Sep 17 00:00:00 2001 From: Tobias Weber Date: Mon, 27 Nov 2017 11:36:24 +0100 Subject: [PATCH] add monitoring flags and counters to circular buffer. --- mupix/Mupix8/sources/CircularMemory.vhd | 57 +++++++++++++++++++++---- mupix/Mupix8/sources/StdTypes.vhd | 31 +++++++++++++- mupix/Mupix8/tb/CircularMemoryTest.vhd | 16 +++++-- 3 files changed, 91 insertions(+), 13 deletions(-) diff --git a/mupix/Mupix8/sources/CircularMemory.vhd b/mupix/Mupix8/sources/CircularMemory.vhd index c7c3012..e99ebe4 100644 --- a/mupix/Mupix8/sources/CircularMemory.vhd +++ b/mupix/Mupix8/sources/CircularMemory.vhd @@ -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; diff --git a/mupix/Mupix8/sources/StdTypes.vhd b/mupix/Mupix8/sources/StdTypes.vhd index a0a891b..35d11bc 100644 --- a/mupix/Mupix8/sources/StdTypes.vhd +++ b/mupix/Mupix8/sources/StdTypes.vhd @@ -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; diff --git a/mupix/Mupix8/tb/CircularMemoryTest.vhd b/mupix/Mupix8/tb/CircularMemoryTest.vhd index a1552a9..2388f99 100644 --- a/mupix/Mupix8/tb/CircularMemoryTest.vhd +++ b/mupix/Mupix8/tb/CircularMemoryTest.vhd @@ -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 -- 2.43.0