Belle II KLM Scint Firmware  1
trig_chan_calc.vhd
1 --*********************************************************************************
2 -- Indiana University CEEM
3 --
4 -- Project: Belle-II
5 --
6 -- Author: Brandon Kunkler
7 --
8 -- Date: 07/14/2014
9 --
10 --*********************************************************************************
11 -- Description:
12 --
13 -- Calculates the trigger channel for the unified trigger format from the ASIC
14 -- number and channel. The number of pipeline registers must be adjusted to meet
15 -- timing.
16 -- NOTE: The C input/path has two less pipeline registers than A,B,D.
17 --
18 -- Implements this logic in a DSP48:
19 --
20 -- channel_pcs : process(tdc_clk)
21 -- begin
22 -- if (tdc_clk'event and tdc_clk = '1') then
23 -- if to_ln < 6 then
24 -- -- first axis (half)
25 -- axis_bit <= AXIS_BIT_VAL;
26 -- trg_ch <= (UNSIGNED(to_ln-1)*ASIC_NUM_CHAN)+UNSIGNED(to_ch);
27 -- else
28 -- -- second axis (half)
29 -- axis_bit <= not AXIS_BIT_VAL;
30 -- trg_ch <= (UNSIGNED(to_ln-6)*ASIC_NUM_CHAN)+UNSIGNED(to_ch);
31 -- end if;
32 -- end if;
33 -- end process;
34 --*********************************************************************************
35 library ieee;
36  use ieee.std_logic_1164.all;
37  use ieee.numeric_std.all;
38 -- synthesis translate_off
39 library unisim;
40  use unisim.vcomponents.all;
41 -- synthesis translate_on
42 
43 entity trig_chan_calc is
44 generic(
45  NUM_CHAN : integer; -- ASIC channels
46  LANEIW : integer; -- Lane in width
47  CHANIW : integer; -- Channel in width
48  CHANOW : integer; -- Channel out width
49  AXIS_VAL : std_logic);-- Axis bit default
50 port(
51  -- inputs ---------------------------------------------
52  clk : in std_logic;
53  we : in std_logic;
54  lane : in std_logic_vector(LANEIW-1 downto 0);
55  chan : in std_logic_vector(CHANIW-1 downto 0);
56  valid : out std_logic;
57  axis_bit : out std_logic;
58  trig_chan : out std_logic_vector(CHANOW-1 downto 0));
59 end trig_chan_calc;
60 
61 architecture behave of trig_chan_calc is
62 
63  component DSP48A1
64  generic(
65  A0REG : integer := 0;
66  A1REG : integer := 1;
67  B0REG : integer := 0;
68  B1REG : integer := 1;
69  CARRYINREG : integer := 1;
70  CARRYINSEL : string := "OPMODE5";
71  CARRYOUTREG : integer := 1;
72  CREG : integer := 1;
73  DREG : integer := 1;
74  MREG : integer := 1;
75  OPMODEREG : integer := 1;
76  PREG : integer := 1;
77  RSTTYPE : string := "SYNC");
78  port(
79  BCOUT : out std_logic_vector(17 downto 0);
80  CARRYOUT : out std_ulogic;
81  CARRYOUTF : out std_ulogic;
82  M : out std_logic_vector(35 downto 0);
83  P : out std_logic_vector(47 downto 0);
84  PCOUT : out std_logic_vector(47 downto 0);
85  A : in std_logic_vector(17 downto 0);
86  B : in std_logic_vector(17 downto 0);
87  C : in std_logic_vector(47 downto 0);
88  CARRYIN : in std_ulogic := 'L';
89  CEA : in std_ulogic;
90  CEB : in std_ulogic;
91  CEC : in std_ulogic;
92  CECARRYIN : in std_ulogic;
93  CED : in std_ulogic;
94  CEM : in std_ulogic;
95  CEOPMODE : in std_ulogic;
96  CEP : in std_ulogic;
97  CLK : in std_ulogic;
98  D : in std_logic_vector(17 downto 0);
99  OPMODE : in std_logic_vector(7 downto 0);
100  PCIN : in std_logic_vector(47 downto 0) := (others => 'L');
101  RSTA : in std_ulogic;
102  RSTB : in std_ulogic;
103  RSTC : in std_ulogic;
104  RSTCARRYIN : in std_ulogic;
105  RSTD : in std_ulogic;
106  RSTM : in std_ulogic;
107  RSTOPMODE : in std_ulogic;
108  RSTP : in std_ulogic);
109  end component;
110 
111 
112  constant OPMODE : std_logic_vector(7 downto 0) := "01011101";
113  constant ONE18 : std_logic_vector(17 downto 0) := "000000000000000001";
114  constant SIX18 : std_logic_vector(17 downto 0) := "000000000000000110";
115  constant ZERO48 : std_logic_vector(47 downto 0) := X"000000000000";
116  constant PIPEDLY : integer := 3;
117 
118  signal a : std_logic_vector(17 downto 0);
119  signal b : std_logic_vector(17 downto 0);
120  signal c : std_logic_vector(47 downto 0);
121  signal d : std_logic_vector(17 downto 0);
122  signal p : std_logic_vector(47 downto 0);
123 
124  signal b_d0 : std_logic_vector(17 downto 0);
125  signal lane_cval : std_logic_vector(LANEIW-1 downto 0);
126  signal valid_shift : std_logic_vector(PIPEDLY-1 downto 0);
127 
128 begin
129 
130 ------------------------------------------------------------------------------------------------
131 -- Component instantiations
132 ------------------------------------------------------------------------------------------------
133  DSP48A1_inst : DSP48A1
134  generic map(
135  A0REG => 0, -- First stage A input pipeline register (0/1)
136  A1REG => 0, -- Second stage A input pipeline register (0/1)
137  B0REG => 1, -- First stage B input pipeline register (0/1)
138  B1REG => 0, -- Second stage B input pipeline register (0/1)
139  CARRYINREG => 0, -- CARRYIN input pipeline register (0/1)
140  CARRYINSEL => "OPMODE5",-- Specify carry-in source, "CARRYIN" or "OPMODE5"
141  CARRYOUTREG => 0, -- CARRYOUT output pipeline register (0/1)
142  CREG => 1, -- C input pipeline register (0/1)
143  DREG => 1, -- D pre-adder input pipeline register (0/1)
144  MREG => 1, -- M pipeline register (0/1)
145  OPMODEREG => 0, -- Enable=1/disable=0 OPMODE input pipeline registers
146  PREG => 1, -- P output pipeline register (0/1)
147  RSTTYPE => "SYNC") -- Specify reset type, "SYNC" or "ASYNC"
148  port map (
149  -- Cascade Ports: 18-bit (each) output: Ports to cascade from one DSP48 to another
150  BCOUT => open, -- 18-bit output: B port cascade output
151  PCOUT => open, -- 48-bit output: P cascade output (if used, connect to PCIN of another DSP48A1)
152  -- Data Ports: 1-bit (each) output: Data input and output ports
153  CARRYOUT => open, -- 1-bit output: carry output (if used, connect to CARRYIN pin of another DSP48A1)
154  CARRYOUTF => open, -- 1-bit output: fabric carry output
155  M => open, -- 36-bit output: fabric multiplier data output
156  P => p, -- 48-bit output: data output
157  -- Cascade Ports: 48-bit (each) input: Ports to cascade from one DSP48 to another
158  PCIN => ZERO48, -- 48-bit input: P cascade input (if used, connect to PCOUT of another DSP48A1)
159  -- Control Input Ports: 1-bit (each) input: Clocking and operation mode
160  CLK => clk, -- 1-bit input: clock input
161  OPMODE => OPMODE, -- 8-bit input: operation mode input
162  -- Data Ports: 18-bit (each) input: Data input and output ports
163  A => a, -- 18-bit input: A data input
164  B => b, -- 18-bit input: B data input (connected to fabric or BCOUT of adjacent DSP48A1)
165  C => c, -- 48-bit input: C data input
166  CARRYIN => '0', -- 1-bit input: carry input signal (if used, connect to CARRYOUT pin of another DSP48A1)
167  D => d, -- 18-bit input: B pre-adder data input
168  -- Reset/Clock Enable Input Ports: 1-bit (each) input: Reset and enable input ports
169  CEA => '1', -- 1-bit input: active high clock enable input for A registers
170  CEB => '1', -- 1-bit input: active high clock enable input for B registers
171  CEC => '1', -- 1-bit input: active high clock enable input for C registers
172  CECARRYIN => '0', -- 1-bit input: active high clock enable input for CARRYIN registers
173  CED => '1', -- 1-bit input: active high clock enable input for D registers
174  CEM => '1', -- 1-bit input: active high clock enable input for multiplier registers
175  CEOPMODE => '1', -- 1-bit input: active high clock enable input for OPMODE registers
176  CEP => '1', -- 1-bit input: active high clock enable input for P registers
177  RSTA => '0', -- 1-bit input: reset input for A pipeline registers
178  RSTB => '0', -- 1-bit input: reset input for B pipeline registers
179  RSTC => '0', -- 1-bit input: reset input for C pipeline registers
180  RSTCARRYIN => '0', -- 1-bit input: reset input for CARRYIN pipeline registers
181  RSTD => '0', -- 1-bit input: reset input for D pipeline registers
182  RSTM => '0', -- 1-bit input: reset input for M pipeline registers
183  RSTOPMODE => '0', -- 1-bit input: reset input for OPMODE pipeline registers
184  RSTP => '0' -- 1-bit input: reset input for P pipeline registers
185  );
186 
187 ---------------------------------------------------------------------------------------------------------
188 -- Concurrent statements
189 ---------------------------------------------------------------------------------------------------------
190 
191  --------------------------------------------------------
192  -- Map signals out of the port
193  --------------------------------------------------------
194  valid <= valid_shift(0);
195  trig_chan <= p(CHANOW-1 downto 0);
196 
197  --------------------------------------------------------
198  -- Combinational logic
199  --------------------------------------------------------
200  lane_cval <= STD_LOGIC_VECTOR(TO_UNSIGNED(6,lane'length));
201  b_d0 <= ONE18 when lane < lane_cval else SIX18;
202 
203 
204  a <= STD_LOGIC_VECTOR(TO_UNSIGNED(NUM_CHAN,a'length));
205  b <= b_d0;
206  c <= STD_LOGIC_VECTOR(RESIZE(UNSIGNED(chan),c'length));
207  d <= STD_LOGIC_VECTOR(RESIZE(UNSIGNED(lane),d'length));
208 
209 
210 ---------------------------------------------------------------------------------------------------------
211 -- Asynchronous and Synchronous processes
212 ---------------------------------------------------------------------------------------------------------
213 
214 
215 -------------------------------------------------------------------------------------------
216 -- Synchronous processes
217 -------------------------------------------------------------------------------------------
218  ---------------------------------------------
219  -- Mux the axis bit to output based on lane
220  -- number.
221  ---------------------------------------------
222  mux_pcs : process(clk)
223  begin
224  if (clk'event and clk = '1') then
225  if lane < lane_cval then
226  -- first axis (half)
227  axis_bit <= AXIS_VAL;
228  else
229  -- second axis (half)
230  axis_bit <= not AXIS_VAL;
231  end if;
232  end if;
233  end process;
234 
235  ---------------------------------------------
236  -- Delay the write enable by the the number of
237  -- DSP48 pipeline registers.
238  ---------------------------------------------
239  valid_pcs : process(clk)
240  begin
241  if (clk'event and clk = '1') then
242  valid_shift <= we & valid_shift(valid_shift'length-1 downto 1);
243  end if;
244  end process;
245 
246 end behave;
247 --------------------------------------------------------------------------------------------------------
248