tdc.vhd 8.31 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14
-------------------------------------------------------------------------------
-- TDC Core / CERN
-------------------------------------------------------------------------------
--
-- unit name: tdc
--
-- author: Sebastien Bourdeauducq, sebastien@milkymist.org
--
-- description: Top level module
--
-- references: http://www.ohwr.org/projects/tdc-core
--
-------------------------------------------------------------------------------
-- last changes:
15
-- 2011-11-05 SB Added extra histogram bits support
16 17 18
-- 2011-08-17 SB Created file
-------------------------------------------------------------------------------

19 20 21 22 23 24 25 26 27 28
-- Copyright (C) 2011 CERN
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU Lesser General Public License as published by
-- the Free Software Foundation, version 3 of the License.
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU General Public License for more details.
-- You should have received a copy of the GNU Lesser General Public License
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
29

30 31 32 33
-- DESCRIPTION:
-- Top level module of the TDC core, contains all logic except the optional
-- host interface.

34 35 36 37 38 39
library ieee;
use ieee.std_logic_1164.all;

library work;
use work.tdc_package.all;

40
entity tdc is
41 42
    generic(
        -- Number of channels.
43
        g_CHANNEL_COUNT  : positive := 1;
44
        -- Number of CARRY4 elements per channel.
45
        g_CARRY4_COUNT   : positive := 124;
46
        -- Number of raw output bits.
47
        g_RAW_COUNT      : positive := 9;
48
        -- Number of fractional part bits.
49
        g_FP_COUNT       : positive := 13;
50 51
        -- Number of extra histogram bits.
        g_EXHIS_COUNT    : positive := 4;
52
        -- Number of coarse counter bits.
53
        g_COARSE_COUNT   : positive := 25;
54
        -- Length of each ring oscillator.
55
        g_RO_LENGTH      : positive := 31;
56
        -- Frequency counter width.
57
        g_FCOUNTER_WIDTH : positive := 13;
58
        -- Frequency counter timer width.
59
        g_FTIMER_WIDTH   : positive := 14
60 61
    );
    port(
62 63 64
        clk_i        : in std_logic;
        reset_i      : in std_logic;
        ready_o      : out std_logic;
65 66
        
        -- Coarse counter control.
67 68
        cc_rst_i     : in std_logic;
        cc_cy_o      : out std_logic;
69 70
        
        -- Per-channel deskew inputs.
71
        deskew_i     : in std_logic_vector(g_CHANNEL_COUNT*(g_COARSE_COUNT+g_FP_COUNT)-1 downto 0);
72 73
        
        -- Per-channel signal inputs.
74 75
        signal_i     : in std_logic_vector(g_CHANNEL_COUNT-1 downto 0);
        calib_i      : in std_logic_vector(g_CHANNEL_COUNT-1 downto 0);
76 77
        
         -- Per-channel detection outputs.
78 79 80 81
        detect_o     : out std_logic_vector(g_CHANNEL_COUNT-1 downto 0);
        polarity_o   : out std_logic_vector(g_CHANNEL_COUNT-1 downto 0);
        raw_o        : out std_logic_vector(g_CHANNEL_COUNT*g_RAW_COUNT-1 downto 0);
        fp_o         : out std_logic_vector(g_CHANNEL_COUNT*(g_COARSE_COUNT+g_FP_COUNT)-1 downto 0);
82 83
        
        -- Debug interface.
84
        freeze_req_i : in std_logic;
Sebastien Bourdeauducq's avatar
Sebastien Bourdeauducq committed
85 86 87 88 89 90 91
        freeze_ack_o : out std_logic;
        cs_next_i    : in std_logic;
        cs_last_o    : out std_logic;
        calib_sel_i  : in std_logic;
        lut_a_i      : in std_logic_vector(g_RAW_COUNT-1 downto 0);
        lut_d_o      : out std_logic_vector(g_FP_COUNT-1 downto 0);
        his_a_i      : in std_logic_vector(g_RAW_COUNT-1 downto 0);
92
        his_d_o      : out std_logic_vector(g_FP_COUNT+g_EXHIS_COUNT-1 downto 0);
Sebastien Bourdeauducq's avatar
Sebastien Bourdeauducq committed
93 94 95 96
        oc_start_i   : in std_logic;
        oc_ready_o   : out std_logic;
        oc_freq_o    : out std_logic_vector(g_FCOUNTER_WIDTH-1 downto 0);
        oc_sfreq_o   : out std_logic_vector(g_FCOUNTER_WIDTH-1 downto 0)
97 98 99 100
    );
end entity;

architecture rtl of tdc is
Sebastien Bourdeauducq's avatar
Sebastien Bourdeauducq committed
101 102 103 104 105
signal cs_next     : std_logic;
signal cs_next_c   : std_logic;
signal cs_last     : std_logic;
signal calib_sel   : std_logic;
signal calib_sel_c : std_logic;
106

Sebastien Bourdeauducq's avatar
Sebastien Bourdeauducq committed
107 108 109 110 111
signal lut_a       : std_logic_vector(g_RAW_COUNT-1 downto 0);
signal lut_a_c     : std_logic_vector(g_RAW_COUNT-1 downto 0);
signal lut_we      : std_logic;
signal lut_d_w     : std_logic_vector(g_FP_COUNT-1 downto 0);
signal lut_d_r     : std_logic_vector(g_FP_COUNT-1 downto 0);
112

Sebastien Bourdeauducq's avatar
Sebastien Bourdeauducq committed
113 114 115 116 117
signal c_detect    : std_logic;
signal c_raw       : std_logic_vector(g_RAW_COUNT-1 downto 0);
signal his_a       : std_logic_vector(g_RAW_COUNT-1 downto 0);
signal his_a_c     : std_logic_vector(g_RAW_COUNT-1 downto 0);
signal his_we      : std_logic;
118 119
signal his_d_w     : std_logic_vector(g_FP_COUNT+g_EXHIS_COUNT-1 downto 0);
signal his_d_r     : std_logic_vector(g_FP_COUNT+g_EXHIS_COUNT-1 downto 0);
120

Sebastien Bourdeauducq's avatar
Sebastien Bourdeauducq committed
121 122 123 124 125 126
signal oc_start    : std_logic;
signal oc_start_c  : std_logic;
signal oc_ready    : std_logic;
signal oc_freq     : std_logic_vector(g_FCOUNTER_WIDTH-1 downto 0);
signal oc_store    : std_logic;
signal oc_sfreq    : std_logic_vector(g_FCOUNTER_WIDTH-1 downto 0);
127 128

signal freeze_ack : std_logic;
129
begin
130 131 132 133 134 135
    cmp_channelbank: tdc_channelbank
        generic map(
            g_CHANNEL_COUNT  => g_CHANNEL_COUNT,
            g_CARRY4_COUNT   => g_CARRY4_COUNT,
            g_RAW_COUNT      => g_RAW_COUNT,
            g_FP_COUNT       => g_FP_COUNT,
136
            g_EXHIS_COUNT    => g_EXHIS_COUNT,
137 138 139 140
            g_COARSE_COUNT   => g_COARSE_COUNT,
            g_RO_LENGTH      => g_RO_LENGTH,
            g_FCOUNTER_WIDTH => g_FCOUNTER_WIDTH,
            g_FTIMER_WIDTH   => g_FTIMER_WIDTH
141
        )
142
        port map(
143 144
            clk_i        => clk_i,
            reset_i      => reset_i,
145
             
146 147 148 149 150
            cc_rst_i     => cc_rst_i,
            cc_cy_o      => cc_cy_o,
            next_i       => cs_next,
            last_o       => cs_last,
            calib_sel_i  => calib_sel,
151
            
152
            deskew_i     => deskew_i,
153
             
154 155
            signal_i     => signal_i,
            calib_i      => calib_i,
156
             
157 158 159 160
            detect_o     => detect_o,
            polarity_o   => polarity_o,
            raw_o        => raw_o,
            fp_o         => fp_o,
161
             
162 163 164 165
            lut_a_i      => lut_a,
            lut_we_i     => lut_we,
            lut_d_i      => lut_d_w,
            lut_d_o      => lut_d_r,
166
            
167 168 169 170 171 172
            c_detect_o   => c_detect,
            c_raw_o      => c_raw,
            his_a_i      => his_a,
            his_we_i     => his_we,
            his_d_i      => his_d_w,
            his_d_o      => his_d_r,
173

174 175 176 177 178
            oc_start_i   => oc_start,
            oc_ready_o   => oc_ready,
            oc_freq_o    => oc_freq,
            oc_store_i   => oc_store,
            oc_sfreq_o   => oc_sfreq
179 180 181 182 183 184
        );
    
    cmp_controller: tdc_controller
        generic map(
            g_RAW_COUNT      => g_RAW_COUNT,
            g_FP_COUNT       => g_FP_COUNT,
185
            g_EXHIS_COUNT    => g_EXHIS_COUNT,
186
            g_FCOUNTER_WIDTH => g_FCOUNTER_WIDTH
187
        )
188 189 190 191 192
        port map(
            clk_i       => clk_i,
            reset_i     => reset_i,
            ready_o     => ready_o,
            
Sebastien Bourdeauducq's avatar
Sebastien Bourdeauducq committed
193
            next_o      => cs_next_c,
194
            last_i      => cs_last,
Sebastien Bourdeauducq's avatar
Sebastien Bourdeauducq committed
195
            calib_sel_o => calib_sel_c,
196
            
Sebastien Bourdeauducq's avatar
Sebastien Bourdeauducq committed
197
            lut_a_o     => lut_a_c,
198 199 200 201 202
            lut_we_o    => lut_we,
            lut_d_o     => lut_d_w,
            
            c_detect_i  => c_detect,
            c_raw_i     => c_raw,
Sebastien Bourdeauducq's avatar
Sebastien Bourdeauducq committed
203
            his_a_o     => his_a_c,
204 205 206 207
            his_we_o    => his_we,
            his_d_o     => his_d_w,
            his_d_i     => his_d_r,

Sebastien Bourdeauducq's avatar
Sebastien Bourdeauducq committed
208
            oc_start_o  => oc_start_c,
209 210 211
            oc_ready_i  => oc_ready,
            oc_freq_i   => oc_freq,
            oc_store_o  => oc_store,
212 213 214 215
            oc_sfreq_i  => oc_sfreq,
            
            freeze_req_i => freeze_req_i,
            freeze_ack_o => freeze_ack
216
        );
Sebastien Bourdeauducq's avatar
Sebastien Bourdeauducq committed
217 218 219 220 221 222 223 224 225 226 227 228 229 230

    -- Debug interface signals.
    cs_next <= cs_next_i when (freeze_ack = '1') else cs_next_c;
    calib_sel <= calib_sel_i when (freeze_ack = '1') else calib_sel_c;
    lut_a <= lut_a_i when (freeze_ack = '1') else lut_a_c;
    his_a <= his_a_i when (freeze_ack = '1') else his_a_c;
    oc_start <= oc_start_i when (freeze_ack = '1') else oc_start_c;
    freeze_ack_o <= freeze_ack;
    cs_last_o <= cs_last;
    lut_d_o <= lut_d_r;
    his_d_o <= his_d_r;
    oc_ready_o <= oc_ready;
    oc_freq_o <= oc_freq;
    oc_sfreq_o <= oc_sfreq;
231
end architecture;