From: Tobias Weber Date: Wed, 4 Sep 2013 09:19:51 +0000 (+0200) Subject: Histogramming of MuPix Hitbus X-Git-Url: https://jspc29.x-matter.uni-frankfurt.de/git/?a=commitdiff_plain;h=cac47e2725034a03bb0a89c651d5358d438f73fe;p=trb3.git Histogramming of MuPix Hitbus --- diff --git a/mupix/sources/BlockMemory.vhd b/mupix/sources/BlockMemory.vhd new file mode 100644 index 0000000..7d80df6 --- /dev/null +++ b/mupix/sources/BlockMemory.vhd @@ -0,0 +1,64 @@ +---------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 11:09:56 07/28/2013 +-- Design Name: +-- Module Name: BlockMemory - Behavioral +-- Project Name: +-- Target Devices: +-- Tool versions: +-- Description: +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +---------------------------------------------------------------------------------- +library IEEE; +use IEEE.STD_LOGIC_1164.all; + +-- Uncomment the following library declaration if using +-- arithmetic functions with Signed or Unsigned values +use IEEE.NUMERIC_STD.all; + +-- Uncomment the following library declaration if instantiating +-- any Xilinx primitives in this code. +--library UNISIM; +--use UNISIM.VComponents.all; + +entity BlockMemory is + generic ( + DataWidth : integer := 10; + AddressWidth : integer := 10); + port ( + clk : in std_logic; + WrEn : in std_logic; + WrAddr : in std_logic_vector(AddressWidth - 1 downto 0); + Din : in std_logic_vector(DataWidth - 1 downto 0); + ReAddr : in std_logic_vector(AddressWidth - 1 downto 0); + Dout : out std_logic_vector(DataWidth - 1 downto 0)); +end BlockMemory; + +architecture Behavioral of BlockMemory is + + type memory_type is array ((2**AddressWidth) - 1 downto 0) of std_logic_vector(DataWidth - 1 downto 0); + signal memory : memory_type; + +begin + + MemoryControll : process(clk) + begin -- process MemoryControll + if rising_edge(clk) then + Dout <= memory(to_integer(unsigned(ReAddr))); --read memory + if(WrEn = '1') then + memory(to_integer(unsigned(WrAddr))) <= Din; -- write memory + end if; + end if; + end process MemoryControll; + + +end Behavioral; + diff --git a/mupix/sources/Histogram.vhd b/mupix/sources/Histogram.vhd new file mode 100644 index 0000000..99337d4 --- /dev/null +++ b/mupix/sources/Histogram.vhd @@ -0,0 +1,147 @@ +---------------------------------------------------------------------------------- +-- Company: +-- Engineer: +-- +-- Create Date: 11:33:37 07/28/2013 +-- Design Name: +-- Module Name: Histogram - Behavioral +-- Project Name: +-- Target Devices: +-- Tool versions: +-- Description: +-- +-- Dependencies: +-- +-- Revision: +-- Revision 0.01 - File Created +-- Additional Comments: +-- +---------------------------------------------------------------------------------- +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use IEEE.NUMERIC_STD.all; + +-- Uncomment the following library declaration if instantiating +-- any Xilinx primitives in this code. +--library UNISIM; +--use UNISIM.VComponents.all; + +entity Histogram is + generic ( + HistogramHeight : integer := 12; -- Bin Height in power of two + HistogramRange : integer := 10); -- Histogram Range in power of two + port ( + clk : in std_logic; + reset : in std_logic; + StartRun : in std_logic; + StartRd : in std_logic; + ReadAddr : in std_logic_vector(HistogramRange - 1 downto 0); + Wr : in std_logic; + BinSelect : in std_logic_vector(HistogramRange - 1 downto 0); + DataValid : out std_logic; + BinHeight : out std_logic_vector(HistogramHeight - 1 downto 0)); +end Histogram; + +architecture Behavioral of Histogram is + + component BlockMemory + generic ( + DataWidth : integer; + AddressWidth : integer); + port ( + clk : in std_logic; + WrEn : in std_logic; + WrAddr : in std_logic_vector(AddressWidth - 1 downto 0); + Din : in std_logic_vector(DataWidth - 1 downto 0); + ReAddr : in std_logic_vector(AddressWidth - 1 downto 0); + Dout : out std_logic_vector(DataWidth - 1 downto 0)); + end component; + + type Histo_fsm_type is (idle, WriteHisto, ReadHisto, WaitOnMem, Clear); + signal Histo_fsm : Histo_fsm_type := idle; + + signal MemWrAddr : std_logic_vector(HistogramRange - 1 downto 0); + signal MemRdAddr : std_logic_vector(HistogramRange - 1 downto 0); + signal MemWrEn : std_logic; + signal MemDIn : std_logic_vector(HistogramHeight - 1 downto 0); + signal MemDOut : std_logic_vector(HistogramHeight - 1 downto 0); + + signal bincounter : unsigned(HistogramRange - 1 downto 0); + signal delcounter : integer range 0 to 1 := 0; + signal Overflow : std_logic := '0'; + +begin + + BlockMemory_1 : BlockMemory + generic map ( + DataWidth => HistogramHeight, + AddressWidth => HistogramRange) + port map ( + clk => clk, + WrEn => MemWrEn, + WrAddr => MemWrAddr, + Din => MemDIn, + ReAddr => MemRdAddr, + Dout => MemDOut); + + Histogram : process(clk) + begin -- process Histogram + if rising_edge(clk) then + case Histo_fsm is + when idle => + bincounter <= (others => '0'); + MemRdAddr <= (others => '0'); + MemWrAddr <= (others => '0'); + MemDIn <= (others => '0'); + MemWrEn <= '0'; + DataValid <= '0'; + if (Wr = '1' and StartRun = '1' and Overflow = '0') then + Histo_fsm <= WriteHisto; + MemRdAddr <= BinSelect; + elsif StartRd = '1' then + Histo_fsm <= WaitOnMem; + MemRdAddr <= ReadAddr; + elsif Reset = '1' then + Histo_fsm <= Clear; + Overflow <= '0'; + end if; + + when WriteHisto => + if delcounter = 1 then + MemWrAddr <= BinSelect; + MemWrEn <= '1'; + delcounter <= 0; + Histo_fsm <= idle; + if to_integer(unsigned(MemDOut)) = 2**HistogramHeight - 1 then + --Overflow detected stop writing histogram data + MemDIn <= MemDOut; + Overflow <= '1'; + else + MemDIn <= std_logic_vector(unsigned(MemDOut) + 1); + Overflow <= '0'; + end if; + else + delcounter <= delcounter + 1; --one clk read delay of memory + end if; + + when WaitOnMem => + Histo_fsm <= ReadHisto; + when ReadHisto => + BinHeight <= MemDOut; + DataValid <= '1'; + Histo_fsm <= idle; + + when Clear => + bincounter <= bincounter + 1; + MemWrAddr <= std_logic_vector(bincounter); + MemDIn <= (others => '0'); + MemWrEn <= '1'; + if to_integer(bincounter) = (2**HistogramRange - 1) then + Histo_fsm <= idle; + end if; + end case; + end if; + end process Histogram; + +end Behavioral; + diff --git a/mupix/sources/HitbusHistogram.vhd b/mupix/sources/HitbusHistogram.vhd new file mode 100644 index 0000000..6ac6b7d --- /dev/null +++ b/mupix/sources/HitbusHistogram.vhd @@ -0,0 +1,260 @@ +------------------------------------------------------------------------------- +--Histogramming of Hitbus for Time over Threshold and Latency Measurement +--Readout by TRB Slave Bus +------------------------------------------------------------------------------- +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use IEEE.NUMERIC_STD.all; + + +entity HitbusHistogram is + generic ( + HistogramRange : integer := 8); + port ( + clk : in std_logic; + hitbus : in std_logic; + Trigger : out std_logic; --Trigger to Laser/LED + SLV_READ_IN : in std_logic; + SLV_WRITE_IN : in std_logic; + SLV_DATA_OUT : out std_logic_vector(31 downto 0); + SLV_DATA_IN : in std_logic_vector(31 downto 0); + SLV_ADDR_IN : in std_logic_vector(15 downto 0); + SLV_ACK_OUT : out std_logic; + SLV_NO_MORE_DATA_OUT : out std_logic; + SLV_UNKNOWN_ADDR_OUT : out std_logic + ); +end HitbusHistogram; + +architecture Behavioral of HitbusHistogram is + + component Histogram + generic ( + HistogramHeight : integer; + HistogramRange : integer); + port ( + clk : in std_logic; + reset : in std_logic; + StartRun : in std_logic; + StartRd : in std_logic; + ReadAddr : in std_logic_vector(HistogramRange - 1 downto 0); + Wr : in std_logic; + BinSelect : in std_logic_vector(HistogramRange - 1 downto 0); + DataValid : out std_logic; + BinHeight : out std_logic_vector(HistogramHeight - 1 downto 0)); + end component; + + + signal hitbus_i : std_logic_vector(1 downto 0); + + --ToT Histogram + type hithisto_fsm_type is (idle, hitbus_high); + signal hithisto_fsm : hithisto_fsm_type := idle; + signal hitbus_counter : unsigned(HistogramRange - 1 downto 0); --duration of hitbus high + signal hitbus_HistoWrAddr : std_logic_vector(HistogramRange - 1 downto 0); + signal hitbus_WriteBin : std_logic; + signal hitbus_BinValue : std_logic_vector(15 downto 0); + + + --Latency Histogram + type latency_fsm_type is (idle, waittime, generatetrigger, waitforhitbus); + signal latency_fsm : latency_fsm_type := idle; + signal trigger_counter : unsigned(2 downto 0) := (others => '0'); + signal wait_counter : unsigned(15 downto 0) := (others => '0'); + signal latency_counter : unsigned(HistogramRange - 1 downto 0); --duration of hitbus high + signal latency_HistoWrAddr : std_logic_vector(HistogramRange - 1 downto 0); + signal latency_WriteBin : std_logic; + signal latency_BinValue : std_logic_vector(15 downto 0); + + + --Histogram Ctrl + signal histo_ctrl : std_logic_vector(31 downto 0) := (others => '0'); + signal histvalue : std_logic_vector(31 downto 0); + signal histvalue_valid : std_logic; + signal ReadAddr_i : std_logic_vector(HistogramRange - 1 downto 0); + signal ReadHisto : std_logic := '0'; + signal reading_histo_mem : std_logic := '0'; --read in progress + signal readcounter : unsigned(HistogramRange - 1 downto 0) := (others => '0'); + + + + +begin + + Histogram_1 : Histogram + generic map ( + HistogramHeight => 16, --change Max Height of Histogrambin here + HistogramRange => HistogramRange) + port map ( + clk => clk, + reset => histo_ctrl(2), + StartRun => histo_ctrl(1), + StartRd => ReadHisto, + ReadAddr => ReadAddr_i, + Wr => hitbus_WriteBin, + BinSelect => hitbus_HistoWrAddr, + DataValid => histvalue_valid, + BinHeight => hitbus_BinValue); + + Histogram_2 : Histogram + generic map ( + HistogramHeight => 16, + HistogramRange => HistogramRange) + port map ( + clk => clk, + reset => histo_ctrl(2), + StartRun => histo_ctrl(1), + StartRd => ReadHisto, + ReadAddr => ReadAddr_i, + Wr => latency_WriteBin, + BinSelect => latency_HistoWrAddr, + DataValid => open, + BinHeight => latency_BinValue); + + + ----------------------------------------------------------------------------- + --Time over Threshold histogram + ----------------------------------------------------------------------------- + + HitBusHisto : process(clk) + begin -- process HitBusHisto + if rising_edge(clk) then + hitbus_i <= hitbus_i(0) & hitbus; + case hithisto_fsm is + when idle => + --hitbus_counter <= (others => '0'); + hitbus_WriteBin <= '0'; + if hitbus_i = "01" then --rising edge + hitbus_counter <= to_unsigned(0, HistogramRange); + hithisto_fsm <= hitbus_high; + end if; + when hitbus_high => + hitbus_counter <= hitbus_counter + 1; + if hitbus_i = "10" then --falling edge + hitbus_WriteBin <= '1'; + hitbus_HistoWrAddr <= std_logic_vector(hitbus_counter); + hithisto_fsm <= idle; + end if; + end case; + end if; + end process HitBusHisto; + + ----------------------------------------------------------------------------- + --Latency Histogram + ----------------------------------------------------------------------------- + + LatencyHisto : process(clk) + begin -- process LatencyHisto + if rising_edge(clk) then + case latency_fsm is + when idle => + trigger_counter <= (others => '0'); + --latency_histoaddr <= (others => '0'); + latency_counter <= (others => '0'); + latency_WriteBin <= '0'; + if histo_ctrl(3) = '1' then + latency_fsm <= waittime; + wait_counter <= wait_counter + 1; + end if; + when waittime => + wait_counter <= wait_counter + 1; + if std_logic_vector(wait_counter) = histo_ctrl(31 downto 16) then + trigger <= '1'; + latency_fsm <= generatetrigger; + end if; + when generatetrigger => --necessary width of triggersignal in + --function generator? + trigger_counter <= trigger_counter + 1; + if trigger_counter = "111" then + latency_fsm <= waitforhitbus; + else + latency_fsm <= generatetrigger; + end if; + latency_counter <= latency_counter + 1; + wait_counter <= (others => '0'); + + when waitforhitbus => + trigger <= '0'; + latency_counter <= latency_counter + 1; + if hitbus_i = "01" then + latency_writebin <= '1'; + latency_histoWraddr <= std_logic_vector(latency_counter); + latency_fsm <= idle; + elsif latency_counter = x"FFFF" then + latency_fsm <= idle; + end if; + end case; + end if; + end process LatencyHisto; + + ----------------------------------------------------------------------------- + --TRB Slave Bus + --0x0800: Histogram Ctrl + --0x0801: Last ToT Value + --0x0802: Last Latency Value + --0x0803: Read Histograms + --0x0804: ReadCounter + ----------------------------------------------------------------------------- + SLV_BUS_HANDLER : process(clk) + begin -- process SLV_BUS_HANDLER + if rising_edge(clk) then + SLV_DATA_OUT <= (others => '0'); + SLV_ACK_OUT <= '0'; + SLV_UNKNOWN_ADDR_OUT <= '0'; + SLV_NO_MORE_DATA_OUT <= '0'; + histvalue <= latency_BinValue & hitbus_BinValue; + if reading_histo_mem = '1' then + ReadHisto <= '0'; + if histvalue_valid = '1' then + SLV_DATA_OUT <= histvalue; + SLV_ACK_OUT <= '1'; + reading_histo_mem <= '0'; + readcounter <= readcounter + 1; + else + reading_histo_mem <= '1'; + end if; + + elsif SLV_READ_IN = '1' then + case SLV_ADDR_IN is + when x"0800" => + SLV_DATA_OUT <= histo_ctrl; + SLV_ACK_OUT <= '1'; + when x"0801" => + SLV_DATA_OUT(31 downto 16) <= (others => '0'); + SLV_DATA_OUT(HistogramRange - 1 downto 0) <= std_logic_vector(hitbus_counter); + SLV_ACK_OUT <= '1'; + when x"0802" => + SLV_DATA_OUT(31 downto 16) <= (others => '0'); + SLV_DATA_OUT(HistogramRange - 1 downto 0) <= latency_histoWraddr; + SLV_ACK_OUT <= '1'; + when x"0803" => + ReadHisto <= '1'; + ReadAddr_i <= std_logic_vector(readcounter); + reading_histo_mem <= '1'; + when x"0804" => + SLV_DATA_OUT(HistogramRange - 1 downto 0) <= std_logic_vector(readcounter); + SLV_ACK_OUT <= '1'; + when others => + SLV_UNKNOWN_ADDR_OUT <= '1'; + end case; + + elsif SLV_WRITE_IN = '1' then + case SLV_ADDR_IN is + when x"0800" => + histo_ctrl <= SLV_DATA_IN; + SLV_ACK_OUT <= '1'; + when x"0804" => + readcounter <= unsigned(SLV_DATA_IN(HistogramRange - 1 downto 0)); + SLV_ACK_OUT <= '1'; + when others => + SLV_UNKNOWN_ADDR_OUT <= '1'; + end case; + + end if; + end if; + + end process SLV_BUS_HANDLER; + + + +end Behavioral; +