AMC13
Firmwares for the different applications of the AMC13 uTCA board made at Boston University
 All Classes Files Variables
AMC_cntr.vhd
1 ----------------------------------------------------------------------------------
2 -- Company:
3 -- Engineer:
4 --
5 -- Create Date: 15:54:09 02/16/2016
6 -- Design Name:
7 -- Module Name: TTC_cntr - Behavioral
8 -- Project Name:
9 -- Target Devices:
10 -- Tool versions:
11 -- Description:
12 --
13 -- Dependencies:
14 --
15 -- Revision:
16 -- Revision 0.01 - File Created
17 -- Additional Comments:
18 --
19 ----------------------------------------------------------------------------------
20 library IEEE;
21 use IEEE.STD_LOGIC_1164.ALL;
22 use IEEE.STD_LOGIC_ARITH.ALL;
23 use IEEE.STD_LOGIC_UNSIGNED.ALL;
24 use IEEE.std_logic_misc.all;
25 use work.amc13_pack.all;
26 
27 -- Uncomment the following library declaration if using
28 -- arithmetic functions with Signed or Unsigned values
29 --use IEEE.NUMERIC_STD.ALL;
30 
31 -- Uncomment the following library declaration if instantiating
32 -- any Xilinx primitives in this code.
33 library UNISIM;
34 use UNISIM.VComponents.all;
35 Library UNIMACRO;
36 use UNIMACRO.vcomponents.all;
37 
38 entity AMC_cntr is
39  Port ( UsrClk : in STD_LOGIC;
40  clk125 : in STD_LOGIC;
41  sysclk : in STD_LOGIC;
42  ipb_clk : in STD_LOGIC;
43  resetCntr : in STD_LOGIC;
44  DB_cmd : in STD_LOGIC;
45  AMC_if_data : in STD_LOGIC_VECTOR(15 downto 0);
46  Cntr_DATA : in array12x16;
47  Cntr_ADDR : out STD_LOGIC_VECTOR(11 downto 0);
48  ipb_addr : in STD_LOGIC_VECTOR(15 downto 0);
49  ipb_rdata : out STD_LOGIC_VECTOR(31 downto 0));
50 end AMC_cntr;
51 architecture Behavioral of AMC_cntr is
52 signal resetCntr_SyncRegs : std_logic_vector(2 downto 0) := (others =>'0');
53 signal div : std_logic_vector(11 downto 0) := (others =>'0');
54 signal div_l : std_logic_vector(10 downto 0) := (others =>'0');
55 signal div_l2 : std_logic_vector(10 downto 0) := (others =>'0');
56 signal CntrRstCycle : std_logic := '0';
57 signal counter_wa : std_logic_vector(10 downto 0) := (others => '0');
58 signal counter_ra : std_logic_vector(10 downto 0) := (others => '0');
59 signal counter_DIA : std_logic_vector(31 downto 0) := (others => '0');
60 signal counter_DOA : std_logic_vector(31 downto 0) := (others => '0');
61 signal counter_DOB : std_logic_vector(31 downto 0) := (others => '0');
62 signal we_counter : std_logic_vector(1 downto 0) := (others => '0');
63 signal buffer_DOB : std_logic_vector(31 downto 0) := (others => '0');
64 signal buffer_RSTB : std_logic := '0';
65 signal we_buffer : std_logic_vector(1 downto 0) := (others => '0');
66 signal startSyncRegs : std_logic_vector(3 downto 0) := (others =>'0');
67 signal DataType : std_logic_vector(1 downto 0) := (others => '0');
68 signal DataType_l : std_logic_vector(1 downto 0) := (others => '0');
69 signal DataType_l2 : std_logic_vector(1 downto 0) := (others => '0');
70 signal DataType_q : std_logic_vector(1 downto 0) := (others => '0');
71 signal tmp : std_logic_vector(31 downto 0) := (others => '0');
72 signal ec_div : std_logic_vector(1 downto 0) := (others => '0');
73 --signal sample_data : std_logic := '0';
74 signal start : std_logic := '0';
75 --signal start_edge : std_logic := '0';
76 --signal rst_ec_div : std_logic := '0';
77 signal data : std_logic_vector(31 downto 0) := (others => '0');
78 signal DB_cmd_l : std_logic := '0';
79 signal carry_m : std_logic := '0';
80 signal DB_en : std_logic := '0';
81 signal carry_h : std_logic := '0';
82 signal sr : std_logic_vector(4 downto 0) := (others => '0');
83 signal toggle : std_logic := '0';
84 signal toggle_q : std_logic := '0';
85 signal ec_rdata : std_logic := '0';
86 signal ec_wdata : std_logic := '0';
87 
88 begin
89 Cntr_ADDR <= div;
90 process(UsrClk, Cntr_Data, CntrRstCycle)
91 variable CntrDataOR : std_logic_vector(15 downto 0);
92 begin
93  CntrDataOR := AMC_if_data;
94  for i in 0 to 11 loop
95  CntrDataOR := CntrDataOR or Cntr_Data(i);
96  end loop;
97  if(CntrRstCycle = '1')then
98  data <= (others => '0');
99  tmp <= (others => '0');
100  elsif(UsrClk'event and UsrClk = '1')then
101  if(ec_div(0) = '1')then
102  data <= tmp;
103  tmp(15 downto 0) <= CntrDataOR;
104  end if;
105  if(ec_div(1) = '1')then
106  if(DataType = "11")then
107  tmp(31 downto 16) <= (others => '0');
108  else
109  tmp(31 downto 16) <= CntrDataOR;
110  end if;
111  end if;
112  end if;
113 end process;
114 --i_sample_data : SRL16E
115 -- port map (
116 -- Q => sample_data, -- SRL data output
117 -- A0 => '1', -- Select[0] input
118 -- A1 => '0', -- Select[1] input
119 -- A2 => '0', -- Select[2] input
120 -- A3 => '0', -- Select[3] input
121 -- CE => '1', -- Clock enable input
122 -- CLK => UsrClk, -- Clock input
123 -- D => ec_div -- SRL data input
124 -- );
125 i_ec_div1 : SRL16E
126  port map (
127  Q => ec_div(1), -- SRL data output
128  A0 => '0', -- Select[0] input
129  A1 => '0', -- Select[1] input
130  A2 => '1', -- Select[2] input
131  A3 => '0', -- Select[3] input
132  CE => '1', -- Clock enable input
133  CLK => UsrClk, -- Clock input
134  D => ec_div(0) -- SRL data input
135  );
136 start <= sr(0);
137 process(UsrClk, CntrRstCycle)
138 begin
139  if(CntrRstCycle = '1')then
140  startSyncRegs <= (others => '0');
141  ec_div(0) <= '0';
142  div <= (others => '0');
143  div_l <= (others => '0');
144  div_l2 <= (others => '0');
145  DataType <= "10";
146  elsif(UsrClk'event and UsrClk = '1')then
147  startSyncRegs <= startSyncRegs(2 downto 0) & start;
148 -- if(startSyncRegs(3 downto 2) = "01")then
149 -- start_edge <= '1';
150 -- else
151 -- start_edge <= '0';
152 -- end if;
153 -- rst_ec_div <= start_edge;
154  if(startSyncRegs(3 downto 2) = "01")then
155  ec_div(0) <= '1';
156  else
157  ec_div(0) <= '0';
158  end if;
159  if(ec_div /= "00")then
160  div <= div + 1 + DataType(1);
161  end if;
162  if(div(11 downto 3) = "110000101" or div(11 downto 5) = "1100010")then
163  DataType <= "00";-- 32 bit counter
164  elsif(div(11 downto 6) = "111000" or div(11 downto 9) = "110")then
165  DataType <= "01";-- register
166  elsif(div(11 downto 10) /= "11" and div(7 downto 5) = "010")then
167  DataType <= "11";-- register of daq_link
168  else
169  DataType <= "10";-- 48 bit counter
170  end if;
171  if(ec_div(0) = '1')then
172  div_l <= div(11 downto 1);
173  div_l2 <= div_l;
174  DataType_l <= DataType;
175  DataType_l2 <= DataType_l;
176  end if;
177  end if;
178 end process;
179 g_counter: for i in 0 to 1 generate
180  i_counter : BRAM_TDP_MACRO
181  generic map (
182  BRAM_SIZE => "36Kb", -- Target BRAM, "18Kb" or "36Kb"
183  DEVICE => "7SERIES", -- Target Device: "VIRTEX5", "VIRTEX6", "7SERIES", "SPARTAN6"
184  WRITE_MODE_A => "READ_FIRST", -- "WRITE_FIRST", "READ_FIRST" or "NO_CHANGE"
185  READ_WIDTH_A => 16, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb")
186  READ_WIDTH_B => 16, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb")
187  WRITE_WIDTH_A => 16, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb")
188  WRITE_WIDTH_B => 16) -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb")
189  port map (
190  DOA => counter_DOA(i*16+15 downto i*16), -- Output port-A data, width defined by READ_WIDTH_A parameter
191  DOB => counter_DOB(i*16+15 downto i*16), -- Output port-B data, width defined by READ_WIDTH_B parameter
192  ADDRA => counter_wa, -- Input port-A address, width defined by Port A depth
193  ADDRB => ipb_addr(10 downto 0), -- Input port-B address, width defined by Port B depth
194  CLKA => clk125, -- 1-bit input port-A clock
195  CLKB => clk125, -- 1-bit input port-B clock
196  DIA => counter_DIA(i*16+15 downto i*16), -- Input port-A data, width defined by WRITE_WIDTH_A parameter
197  DIB => x"0000", -- Input port-B data, width defined by WRITE_WIDTH_B parameter
198  ENA => '1', -- 1-bit input port-A enable
199  ENB => ec_rdata, -- 1-bit input port-B enable
200  REGCEA => '0', -- 1-bit input port-A output register enable
201  REGCEB => '0', -- 1-bit input port-B output register enable
202  RSTA => '0', -- 1-bit input port-A reset
203  RSTB => ipb_addr(15), -- 1-bit input port-B reset
204  WEA => we_counter, -- Input port-A write enable, width defined by Port A depth
205  WEB => "00" -- Input port-B write enable, width defined by Port B depth
206  );
207  i_buffer : BRAM_TDP_MACRO
208  generic map (
209  BRAM_SIZE => "36Kb", -- Target BRAM, "18Kb" or "36Kb"
210  DEVICE => "7SERIES", -- Target Device: "VIRTEX5", "VIRTEX6", "7SERIES", "SPARTAN6"
211  WRITE_MODE_A => "READ_FIRST", -- "WRITE_FIRST", "READ_FIRST" or "NO_CHANGE"
212  READ_WIDTH_A => 16, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb")
213  READ_WIDTH_B => 16, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb")
214  WRITE_WIDTH_A => 16, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb")
215  WRITE_WIDTH_B => 16) -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb")
216  port map (
217  DOA => open, -- Output port-A data, width defined by READ_WIDTH_A parameter
218  DOB => buffer_DOB(i*16+15 downto i*16), -- Output port-B data, width defined by READ_WIDTH_B parameter
219  ADDRA => counter_wa, -- Input port-A address, width defined by Port A depth
220  ADDRB => ipb_addr(10 downto 0), -- Input port-B address, width defined by Port B depth
221  CLKA => clk125, -- 1-bit input port-A clock
222  CLKB => clk125, -- 1-bit input port-B clock
223  DIA => counter_DIA(i*16+15 downto i*16), -- Input port-A data, width defined by WRITE_WIDTH_A parameter
224  DIB => x"0000", -- Input port-B data, width defined by WRITE_WIDTH_B parameter
225  ENA => '1', -- 1-bit input port-A enable
226  ENB => ec_rdata, -- 1-bit input port-B enable
227  REGCEA => '0', -- 1-bit input port-A output register enable
228  REGCEB => '0', -- 1-bit input port-B output register enable
229  RSTA => '0', -- 1-bit input port-A reset
230  RSTB => buffer_RSTB, -- 1-bit input port-B reset
231  WEA => we_buffer, -- Input port-A write enable, width defined by Port A depth
232  WEB => "00" -- Input port-B write enable, width defined by Port B depth
233  );
234 end generate;
235 buffer_RSTB <= not ipb_addr(15);
236 we_counter(1) <= we_counter(0);
237 we_buffer(1) <= we_buffer(0);
238 ipb_rdata <= counter_DOB or buffer_DOB;
239 process(ipb_clk)
240 begin
241  if(ipb_clk'event and ipb_clk = '1')then
242  toggle <= not toggle;
243  end if;
244 end process;
245 process(clk125)
246 begin
247  if(clk125'event and clk125 = '1')then
248  toggle_q <= toggle;
249  ec_rdata <= toggle xor toggle_q;
250  if(DB_cmd = '1' and ec_wdata = '1')then
251  DB_cmd_l <= '1';
252  elsif(sr(0) = '1' and and_reduce(counter_wa) = '1')then
253  DB_cmd_l <= '0';
254  end if;
255  if(sr(0) = '1' and and_reduce(counter_wa) = '1')then
256  DB_en <= DB_cmd_l;
257  end if;
258  if(sr(0) = '1')then
259  DataType_q <= DataType_l2;
260  end if;
261  if(resetCntr = '1')then
262  counter_wa <= (others => '0');
263  elsif(CntrRstCycle = '1')then
264  counter_wa <= counter_wa + 1;
265  elsif(sr(0) = '1')then
266  counter_wa <= div_l2;
267  elsif(DataType_q(1) = '1')then
268  counter_wa(0) <= (sr(2) or sr(4)) and not sr(3);
269  end if;
270  if(resetCntr = '1')then
271  CntrRstCycle <= '1';
272  elsif(and_reduce(counter_wa) = '1')then
273  CntrRstCycle <= '0';
274  end if;
275  if(CntrRstCycle = '1')then
276  sr <= "00000";
277  elsif(sr(3 downto 0) = x"0")then
278  sr <= "00001";
279  else
280  sr <= sr(3 downto 0) & '0';
281  end if;
282  if(sr(2) = '1')then
283  if(DataType_q(0) = '0' and counter_DOA(15 downto 0) > counter_DIA(15 downto 0))then
284  carry_m <= '1';
285  else
286  carry_m <= '0';
287  end if;
288  end if;
289  if(sr(3) = '1')then
290  if(carry_m = '1' and counter_DOA(31 downto 16) = x"ffff")then
291  carry_h <= '1';
292  else
293  carry_h <= '0';
294  end if;
295  end if;
296  if(CntrRstCycle = '1')then
297  counter_DIA <= (others => '0');
298  elsif(sr(0) = '1')then
299  counter_DIA <= data;
300  elsif(sr(3) = '1' and DataType_q(0) = '0')then
301  counter_DIA(31 downto 16) <= counter_DOA(31 downto 16) + carry_m;
302  elsif(sr(4) = '1')then
303  counter_DIA <= x"0000" & (counter_DOA(15 downto 0) + carry_h);
304  end if;
305  we_counter(0) <= sr(3) or (sr(4) and DataType_q(1) and not DataType_q(0)) or CntrRstCycle;
306  we_buffer(0) <= (DB_en and(sr(3) or (sr(4) and DataType_q(1) and not DataType_q(0)))) or CntrRstCycle;
307  end if;
308 end process;
309 i_ec_wdata : SRL16E
310  generic map (
311  INIT => X"0000")
312  port map (
313  Q => ec_wdata, -- SRL data output
314  A0 => '1', -- Select[0] input
315  A1 => '0', -- Select[1] input
316  A2 => '0', -- Select[2] input
317  A3 => '0', -- Select[3] input
318  CE => '1', -- Clock enable input
319  CLK => clk125, -- Clock input
320  D => ec_rdata -- SRL data input
321  );
322 end Behavioral;
323