Commit 992124f9 authored by Cesar Prados's avatar Cesar Prados

pstats: reduce complexity of the counters

The port counters are now a plain register up to 64 bits.
parent b211485d
......@@ -10,8 +10,7 @@
-- Standard : VHDL
-------------------------------------------------------------------------------
-- Description:
-- Simply counters in two layers organized. L1 is the basic counter and L2,
-- counts the overflow of L1. One bit to sign overflow of L2 counter.
-- Simply counters with overflow bit
-------------------------------------------------------------------------------
-- Copyright (c) 2013 Cesar Prados c.prados@gsi.de / GSI
-------------------------------------------------------------------------------
......@@ -39,51 +38,25 @@ end port_cntr;
architecture rtl of port_cntr is
signal s_L1_cnt : unsigned(c_L1_cnt_density - 1 downto 0);
signal s_L2_cnt : unsigned(c_L2_cnt_density - 1 downto 0);
signal s_L1_ovf : std_logic;
signal s_L2_ovf : std_logic;
signal s_L1_ovf_d : std_logic;
signal s_L1_ovf_r : std_logic;
signal s_cnt_ovf : std_logic;
signal s_toggle : std_logic;
signal s_cnt : t_cnt;
signal s_ovf : std_logic;
signal s_cnt_ovf : std_logic;
signal s_toggle : std_logic;
begin
L1_CNT : process(clk_i)
CNT : process(clk_i)
begin
if rising_edge(clk_i) then
if rstn_i = '0' then
s_L1_cnt <= (others => '0');
s_L1_ovf_d <= '0';
s_cnt <= (others => '0');
else
if cnt_eo_i = '1' then
s_L1_cnt <= s_L1_cnt + 1;
s_cnt <= s_cnt + 1;
else
s_L1_cnt <= s_L1_cnt;
s_cnt <= s_cnt;
end if;
s_L1_ovf_d <= s_L1_ovf;
end if;
end if;
end process;
s_L1_ovf <= '1' when s_L1_cnt = (2**c_L1_cnt_density - 1) else '0';
s_L1_ovf_r <= (not s_L1_ovf_d) and s_L1_ovf;
L2_CNT : process(clk_i)
begin
if rising_edge(clk_i) then
if rstn_i = '0' then
s_L2_cnt <= (others => '0');
s_toggle <= '0';
s_cnt_ovf <= '0';
else
if s_L1_ovf_r = '1' then
s_L2_cnt <= s_L2_cnt + 1;
else
s_L2_cnt <= s_L2_cnt;
end if;
if s_L2_ovf = '1' and s_toggle = '0' then
if s_ovf = '1' and s_toggle = '0' then
s_cnt_ovf <= '1';
s_toggle <= '1';
end if;
......@@ -91,10 +64,8 @@ begin
end if;
end process;
s_L2_ovf <= '1' when s_L2_cnt = (2**c_L2_cnt_density - 1) else '0';
s_ovf <= '1' when s_cnt = (2**c_cnt_density - 1) else '0';
cnt_ovf_o <= s_cnt_ovf;
cnt_o.L1_cnt <= std_logic_vector(s_L1_cnt);
cnt_o.L2_cnt <= std_logic_vector(s_L2_cnt);
cnt_o <= s_cnt;
end rtl;
......@@ -11,6 +11,11 @@
-------------------------------------------------------------------------------
-- Description:
-- Slave WB interface. It rolls as many registers as stat events (max 32)
-- Regsiter 0x0 : Read -> read the overflow register for the counters
-- Write -> if bit 0 is 1 = reset the counters
-- Register 0x4 - 0xI -> the first c_events registers correspond the low 32 bits
-- of the counters, the (c_events+1) - (2*c_events) are the
-- high bits counters.
-------------------------------------------------------------------------------
-- Copyright (c) 2013 Cesar Prados c.prados@gsi.de / GSI
-------------------------------------------------------------------------------
......@@ -30,7 +35,7 @@ entity pstats_wb_slave is
port (
clk_i : in std_logic;
rstn_i : in std_logic;
reg_i : in t_cnt_events;
port_cnt_i : in t_cnt_events;
cnt_ovf_i : in std_logic_vector(c_events - 1 downto 0);
cnt_rst_o : out std_logic;
wb_slave_o : out t_wishbone_slave_out;
......@@ -45,7 +50,7 @@ begin
cnt_rst_o <= s_cnt_rst;
WB_SLAVE : process(clk_i)
variable v_cnt_adr : std_logic_vector(4 downto 0);
variable v_cnt_addr : std_logic_vector(c_events_l - 1 downto 0);
begin
if rising_edge(clk_i) then
if rstn_i = '0' then
......@@ -57,30 +62,28 @@ begin
wb_slave_o.ack <= wb_slave_i.cyc and wb_slave_i.stb;
if wb_slave_i.cyc = '1' and wb_slave_i.stb = '1' then
if wb_slave_i.adr(6 downto 2) = "00000" then
if wb_slave_i.we = '1' then
if wb_slave_i.dat(0) = '0' then
s_cnt_switch <= wb_slave_i.dat(1);
elsif wb_slave_i.dat(0) = '1' then
s_cnt_rst <= '1';
end if;
else
wb_slave_o.dat <= std_logic_vector(resize(unsigned(cnt_ovf_i), wb_slave_o.dat'length));
if wb_slave_i.adr(7 downto 2) = "000000" then
if wb_slave_i.we = '1' then -- reset counters
s_cnt_rst <= '1';
else -- read overflow register
wb_slave_o.dat <= std_logic_vector(resize(unsigned(cnt_ovf_i), wb_slave_o.dat'length));
end if;
else
for I in 1 to c_events loop
v_cnt_adr := std_logic_vector(to_unsigned(I,5));
if wb_slave_i.adr(6 downto 2) = v_cnt_adr then
if s_cnt_switch = '0' then
wb_slave_o.dat <= std_logic_vector(resize(unsigned(reg_i(I - 1).L1_cnt), wb_slave_o.dat'length));
else -- read counters
for I in 1 to c_cnt_reg loop
v_cnt_addr := std_logic_vector(to_unsigned(I,c_events_l));
if wb_slave_i.adr(7 downto 2) = v_cnt_addr then
if I <= c_events then
wb_slave_o.dat <= std_logic_vector(resize(unsigned(port_cnt_i(I - 1)(31 downto 0)),
wb_slave_o.dat'length));
else
wb_slave_o.dat <= std_logic_vector(resize(unsigned(reg_i(I - 1).L2_cnt), wb_slave_o.dat'length));
wb_slave_o.dat <= std_logic_vector(resize(unsigned(port_cnt_i(I - c_events - 1)(c_cnt_density - 1 downto 32)),
wb_slave_o.dat'length));
end if;
end if;
end loop;
end if;
else
s_cnt_rst <= '0';
s_cnt_rst <= '0';
end if;
end if;
end if;
......
......@@ -26,16 +26,12 @@ use work.wishbone_pkg.all;
package wr_pstats_pkg is
constant c_events : integer := 29;
constant c_L1_cnt_density : integer := 32; -- bits
constant c_L2_cnt_density : integer := 16; -- bits
type t_cnt is
record
L1_cnt : std_logic_vector(c_L1_cnt_density - 1 downto 0);
L2_cnt : std_logic_vector(c_L2_cnt_density - 1 downto 0);
end record;
constant c_events : integer := 29; -- max 32
constant c_cnt_reg : integer := c_events*2;
constant c_events_l : integer := 6;
constant c_cnt_density : integer := 48; -- min 33 - max 64 bits
subtype t_cnt is unsigned(c_cnt_density - 1 downto 0);
type t_cnt_events is array (c_events - 1 downto 0) of t_cnt;
component xwr_pstats
......@@ -60,7 +56,7 @@ package wr_pstats_pkg is
port (
clk_i : in std_logic;
rstn_i : in std_logic;
reg_i : in t_cnt_events;
port_cnt_i : in t_cnt_events;
cnt_ovf_i : in std_logic_vector(c_events - 1 downto 0);
cnt_rst_o : out std_logic;
wb_slave_o : out t_wishbone_slave_out;
......@@ -81,6 +77,6 @@ package wr_pstats_pkg is
device_id => x"6a0c4d4d",
version => x"00000001",
date => x"20131116",
name => "WR-PSTATS ")));
name => "WR-Pstats ")));
end wr_pstats_pkg;
......@@ -58,7 +58,7 @@ begin
port map (
clk_i => clk_i,
rstn_i => rstn_i,
reg_i => s_cnt_reg,
port_cnt_i => s_cnt_reg,
cnt_ovf_i => s_cnt_ovf,
cnt_rst_o => s_wb_rst,
wb_slave_i => wb_slave_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