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