HistogramHeight : integer := 12; -- Bin Height 2**HistogramHeight
HistogramRange : integer := 10); -- Histogram Range 2**HistogramRange
port (
- clk : in std_logic; --clock
- reset : in std_logic; --reset
- StartRun : in std_logic; --start acquiring data
- StartRd : in std_logic; --start reading the histogram
- ReadAddr : in std_logic_vector(HistogramRange - 1 downto 0); --read address
- Wr : in std_logic; --write enable
- BinSelect : in std_logic_vector(HistogramRange - 1 downto 0); --select bin to write data
- DataValid : out std_logic; --output data is valid
- BinHeight : out std_logic_vector(HistogramHeight - 1 downto 0)); --value of bin at ReadAddr
+ clk : in std_logic; --clock
+ reset : in std_logic; --reset
+ clear : in std_logic; --clear memory
+ StartRun : in std_logic; --start acquiring data
+ StartRd : in std_logic; --start reading the histogram
+ ReadAddr : in std_logic_vector(HistogramRange - 1 downto 0); --read address
+ Wr : in std_logic; --write enable
+ BinSelect : in std_logic_vector(HistogramRange - 1 downto 0); --select bin to write data
+ DataValid : out std_logic; --output data is valid
+ BinHeight : out std_logic_vector(HistogramHeight - 1 downto 0)); --value of bin at ReadAddr
end Histogram;
architecture Behavioral of Histogram is
-
+
component BlockMemory
generic (
DataWidth : integer;
Dout : out std_logic_vector(DataWidth - 1 downto 0));
end component;
- type Histo_fsm_type is (idle, WriteHisto, ReadHisto, WaitOnMem, Clear);
+ type Histo_fsm_type is (idle, WriteHisto, ReadHisto, WaitOnMem, ClearMem);
signal Histo_fsm : Histo_fsm_type := idle;
signal MemWrAddr : std_logic_vector(HistogramRange - 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
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';
- else
- Histo_fsm <= Idle;
- end if;
-
- when WriteHisto =>
- if delcounter = 1 then
- MemWrAddr <= MemRdAddr;
- 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';
+ if reset = '1' then
+ Histo_fsm <= Idle;
+ else
+ 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 clear = '1' then
+ Histo_fsm <= ClearMem;
+ Overflow <= '0';
+ elsif StartRd = '1' then
+ Histo_fsm <= WaitOnMem;
+ MemRdAddr <= ReadAddr;
+ else
+ Histo_fsm <= Idle;
+ end if;
+
+ when WriteHisto =>
+ if delcounter = 1 then
+ MemWrAddr <= MemRdAddr;
+ 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
- MemDIn <= std_logic_vector(unsigned(MemDOut) + 1);
- Overflow <= '0';
+ delcounter <= delcounter + 1; --one clk read delay of memory
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
+ when WaitOnMem =>
+ Histo_fsm <= ReadHisto;
+
+ when ReadHisto =>
+ BinHeight <= MemDOut;
+ DataValid <= '1';
Histo_fsm <= idle;
- end if;
- end case;
+
+ when ClearMem =>
+ 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 if;
end process Histogram;
entity HitbusHistogram is
generic (
- HistogramRange : integer := 8; --number of histogram bins 2**HistogramRange
- PostOscillationWaitCycles : integer := 5);--number of clock cycles to wait after hit-bus signal went low
+ HistogramRange : integer := 8; --number of histogram bins 2**HistogramRange
+ PostOscillationWaitCycles : integer := 5); --number of clock cycles to wait after hit-bus signal went low
port (
- clk : in std_logic; --clock
- hitbus : in std_logic; --hit-bus signal
- trigger : in std_logic; --external trigger e.g. from scintillator
- SLV_READ_IN : in std_logic;
+ clk : in std_logic; --clock
+ reset : in std_logic; --reset
+ hitbus : in std_logic; --hit-bus signal
+ trigger : in std_logic; --external trigger e.g. from scintillator
+ 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);
port (
clk : in std_logic;
reset : in std_logic;
+ clear : in std_logic;
StartRun : in std_logic;
StartRd : in std_logic;
ReadAddr : in std_logic_vector(HistogramRange - 1 downto 0);
Width : integer;
Delay : integer);
port (
- clk_in : in std_logic;
- write_en_in : in std_logic;
- delay_in : in std_logic_vector(Delay - 1 downto 0);
- sig_in : in std_logic_vector(Width - 1 downto 0);
- sig_out : out std_logic_vector(Width - 1 downto 0));
+ clk_in : in std_logic;
+ write_en_in : in std_logic;
+ delay_in : in std_logic_vector(Delay - 1 downto 0);
+ sig_in : in std_logic_vector(Width - 1 downto 0);
+ sig_out : out std_logic_vector(Width - 1 downto 0));
end component SignalDelay;
- signal hitbus_i : std_logic_vector(1 downto 0);
+ signal hitbus_i : std_logic_vector(1 downto 0);
signal trigger_i : std_logic_vector(1 downto 0);
--ToT Histogram
- type hithisto_fsm_type is (idle, hitbus_high, wait_for_postOscillation);
- signal hithisto_fsm : hithisto_fsm_type := idle;
- signal hitbus_counter : unsigned(HistogramRange - 1 downto 0); --duration of hitbus high
+ type hithisto_fsm_type is (idle, hitbus_high, wait_for_postOscillation);
+ signal hithisto_fsm : hithisto_fsm_type := idle;
+ signal hitbus_counter : unsigned(HistogramRange - 1 downto 0); --duration of hitbus high
signal postOscillationCounter : unsigned(HistogramRange - 1 downto 0);
- signal hitbus_HistoWrAddr : std_logic_vector(HistogramRange - 1 downto 0);
- signal hitbus_WriteBin : std_logic;
- signal hitbus_BinValue : std_logic_vector(15 downto 0);
+ 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, waitforhitbus);
- signal latency_fsm : latency_fsm_type := idle;
+ type latency_fsm_type is (idle, waitforhitbus);
+ signal latency_fsm : latency_fsm_type := idle;
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 ReadHisto : std_logic := '0';
signal reading_histo_mem : std_logic := '0'; --read in progress
signal readcounter : unsigned(HistogramRange - 1 downto 0) := (others => '0');
- signal hitbus_wait : unsigned(HistogramRange - 1 downto 0) := (others => '0');
-
+ signal hitbus_wait : unsigned(HistogramRange - 1 downto 0) := (others => '0');
+
signal hitbus_delayed : std_logic;
-
-
+
+
begin
Histogram_1 : Histogram
HistogramRange => HistogramRange)
port map (
clk => clk,
- reset => histo_ctrl(2),
+ reset => reset,
+ clear => histo_ctrl(2),
StartRun => histo_ctrl(1),
StartRd => ReadHisto,
ReadAddr => ReadAddr_i,
HistogramRange => HistogramRange)
port map (
clk => clk,
- reset => histo_ctrl(2),
+ reset => reset,
+ clear => histo_ctrl(2),
StartRun => histo_ctrl(1),
StartRd => ReadHisto,
ReadAddr => ReadAddr_i,
BinSelect => latency_HistoWrAddr,
DataValid => open,
BinHeight => latency_BinValue);
-
- SignalDelay_1: entity work.SignalDelay
+
+ SignalDelay_1 : entity work.SignalDelay
generic map (
Width => 1,
Delay => 5)
write_en_in => '1',
delay_in => std_logic_vector(to_unsigned(5, 5)),
sig_in(0) => hitbus,
- sig_out(0) => hitbus_delayed);
+ sig_out(0) => hitbus_delayed);
-- purpose: hitbus and trigger edge detect
- hitbus_edge_proc: process (clk) is
+ hitbus_edge_proc : process (clk) is
begin -- process hitbus_edge_proc
if rising_edge(clk) then
- hitbus_i <= hitbus_i(0) & hitbus_delayed;
- trigger_i <= trigger_i(0) & trigger;
+ if reset = '1' then
+ hitbus_i <= (others => '0');
+ trigger_i <= (others => '0');
+ else
+ hitbus_i <= hitbus_i(0) & not hitbus_delayed; -- invert hitbus signal
+ trigger_i <= trigger_i(0) & trigger;
+ end if;
end if;
end process hitbus_edge_proc;
-
+
-----------------------------------------------------------------------------
--Time over Threshold histogram
-----------------------------------------------------------------------------
HitBusHisto : process(clk)
begin -- process HitBusHisto
if rising_edge(clk) then
- hitbus_WriteBin <= '0';
- postOscillationCounter <= (others => '0');
- hitbus_HistoWrAddr <= (others => '0');
- case hithisto_fsm is
- when idle =>
- hitbus_counter <= (others => '0');
- hithisto_fsm <= idle;
- if hitbus_i = "01" then --rising edge on hitbus
+ if reset = '1' then
+ hithisto_fsm <= idle;
+ hitbus_WriteBin <= '0';
+ postOscillationCounter <= (others => '0');
+ hitbus_HistoWrAddr <= (others => '0');
+ else
+ hitbus_WriteBin <= '0';
+ postOscillationCounter <= (others => '0');
+ hitbus_HistoWrAddr <= (others => '0');
+ case hithisto_fsm is
+ when idle =>
+ hitbus_counter <= (others => '0');
+ hithisto_fsm <= idle;
+ if hitbus_i = "01" then --rising edge on hitbus
+ hithisto_fsm <= hitbus_high;
+ end if;
+ when hitbus_high =>
+ hitbus_counter <= hitbus_counter + 1;
hithisto_fsm <= hitbus_high;
- end if;
- when hitbus_high =>
- hitbus_counter <= hitbus_counter + 1;
- hithisto_fsm <= hitbus_high;
- if hitbus_i = "10" then --falling edge
- hithisto_fsm <= wait_for_postOscillation;
- end if;
- when wait_for_postOscillation =>
+ if hitbus_i = "10" then --falling edge
+ hithisto_fsm <= wait_for_postOscillation;
+ end if;
+ when wait_for_postOscillation =>
postOscillationCounter <= postOscillationCounter + 1;
- if(to_integer(postOscillationCounter) = PostOscillationWaitCycles) then --wait 5 clock cycles
+ if(to_integer(postOscillationCounter) = PostOscillationWaitCycles) then --wait 5 clock cycles
hitbus_WriteBin <= '1';
hitbus_HistoWrAddr <= std_logic_vector(hitbus_counter);
- hithisto_fsm <= idle;
- elsif(hitbus_i = "01") then --new rising edge, belongs to the same event
+ hithisto_fsm <= idle;
+ elsif(hitbus_i = "01") then --new rising edge, belongs to the same event
hitbus_counter <= hitbus_counter + postOscillationCounter + 1;
- hithisto_fsm <= hitbus_high;
+ hithisto_fsm <= hitbus_high;
else
- hithisto_fsm <= wait_for_postOscillation;
+ hithisto_fsm <= wait_for_postOscillation;
end if;
- end case;
+ end case;
+ end if;
end if;
end process HitBusHisto;
-----------------------------------------------------------------------------
LatencyHisto : process(clk)
begin -- process LatencyHisto
- if rising_edge(clk) then
- latency_histoWraddr <= (others => '0');
- latency_WriteBin <= '0';
- case latency_fsm is
- when idle =>
- if trigger_i = "01" then
- latency_fsm <= waitforhitbus;
+ if rising_edge(clk) then
+ if reset = '1' then
+ latency_histoWraddr <= (others => '0');
+ latency_WriteBin <= '0';
+ latency_fsm <= idle;
+ else
+ latency_histoWraddr <= (others => '0');
+ latency_WriteBin <= '0';
+ case latency_fsm is
+ when idle =>
+ if trigger_i = "01" then
+ latency_fsm <= waitforhitbus;
+ latency_counter <= latency_counter + 1;
+ else
+ latency_fsm <= idle;
+ latency_counter <= (others => '0');
+ end if;
+
+ when waitforhitbus =>
latency_counter <= latency_counter + 1;
- else
- latency_fsm <= idle;
- latency_counter <= (others => '0');
- end if;
-
- when waitforhitbus =>
- 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 = hitbus_wait then
- latency_fsm <= idle;
- else
- latency_fsm <= waitforhitbus;
- end if;
- end case;
+ if hitbus_i = "01" then
+ latency_writebin <= '1';
+ latency_histoWraddr <= std_logic_vector(latency_counter);
+ latency_fsm <= idle;
+ elsif latency_counter = hitbus_wait then
+ latency_fsm <= idle;
+ else
+ latency_fsm <= waitforhitbus;
+ end if;
+ end case;
+ end if;
end if;
end process LatencyHisto;
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_ACK_OUT <= '1';
when x"0075" =>
SLV_DATA_OUT(0) <= hitbus;
- SLV_ACK_OUT <= '1';
- when x"0076" =>
- SLV_DATA_OUT(HistogramRange - 1 downto 0) <= std_logic_vector(hitbus_wait);
- SLV_ACK_OUT <= '1';
+ SLV_ACK_OUT <= '1';
+ when x"0076" =>
+ SLV_DATA_OUT(HistogramRange - 1 downto 0) <= std_logic_vector(hitbus_wait);
+ SLV_ACK_OUT <= '1';
when others =>
SLV_UNKNOWN_ADDR_OUT <= '1';
end case;
when x"0074" =>
readcounter <= unsigned(SLV_DATA_IN(HistogramRange - 1 downto 0));
SLV_ACK_OUT <= '1';
- when x"0076" =>
- hitbus_wait <= unsigned(SLV_DATA_IN(HistogramRange - 1 downto 0));
- SLV_ACK_OUT <= '1';
+ when x"0076" =>
+ hitbus_wait <= 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;