]> jspc29.x-matter.uni-frankfurt.de Git - trb3.git/commitdiff
Histogramming of MuPix Hitbus
authorTobias Weber <webert@kph.uni-mainz.de>
Wed, 4 Sep 2013 09:19:51 +0000 (11:19 +0200)
committerTobias Weber <webert@kph.uni-mainz.de>
Wed, 4 Sep 2013 09:19:51 +0000 (11:19 +0200)
mupix/sources/BlockMemory.vhd [new file with mode: 0644]
mupix/sources/Histogram.vhd [new file with mode: 0644]
mupix/sources/HitbusHistogram.vhd [new file with mode: 0644]

diff --git a/mupix/sources/BlockMemory.vhd b/mupix/sources/BlockMemory.vhd
new file mode 100644 (file)
index 0000000..7d80df6
--- /dev/null
@@ -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 (file)
index 0000000..99337d4
--- /dev/null
@@ -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 (file)
index 0000000..6ac6b7d
--- /dev/null
@@ -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;
+