AMC13
Firmwares for the different applications of the AMC13 uTCA board made at Boston University
 All Classes Variables
SFP_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 SFP_cntr is
39  generic (N : integer := 3);
40  Port ( sysclk : in STD_LOGIC;
41  clk125 : in STD_LOGIC;
42  ipb_clk : in STD_LOGIC;
43  resetCntr : in STD_LOGIC;
44  DB_cmd : in STD_LOGIC;
45  Cntr_DATA : in STD_LOGIC_VECTOR(31 downto 0);
46  Cntr_ADDR : out STD_LOGIC_VECTOR(6 downto 0);
47  ipb_addr : in STD_LOGIC_VECTOR(15 downto 0);
48  ipb_rdata : out STD_LOGIC_VECTOR(31 downto 0));
49 end SFP_cntr;
50 architecture Behavioral of SFP_cntr is
51 signal resetCntr_SyncRegs : std_logic_vector(2 downto 0) := (others =>'0');
52 signal div : std_logic_vector(6 downto 0) := (others =>'0');
53 signal div_l : std_logic_vector(6 downto 0) := (others =>'0');
54 signal CntrRstCycle : std_logic := '0';
55 signal counter_wa : std_logic_vector(9 downto 0) := (others => '0');
56 signal counter_ra : std_logic_vector(9 downto 0) := (others => '0');
57 signal counter_DIA : std_logic_vector(31 downto 0) := (others => '0');
58 signal counter_DOA : std_logic_vector(31 downto 0) := (others => '0');
59 signal we_counter : std_logic_vector(3 downto 0) := (others => '0');
60 signal startSyncRegs : std_logic_vector(3 downto 0) := (others =>'0');
61 signal DataType : std_logic_vector(1 downto 0) := (others => '0');
62 signal DataType_q : std_logic_vector(1 downto 0) := (others => '0');
63 signal ec_div : std_logic := '0';
64 signal start : std_logic := '0';
65 signal data : std_logic_vector(31 downto 0) := (others => '0');
66 signal DB_cmd_l : std_logic := '0';
67 signal carry : std_logic := '0';
68 signal DB_en : std_logic := '0';
69 signal sr : std_logic_vector(3 downto 0) := (others => '0');
70 signal toggle : std_logic := '0';
71 signal toggle_q : std_logic := '0';
72 signal ec_rdata : std_logic := '0';
73 signal ec_wdata : std_logic := '0';
74 
75 begin
76 Cntr_ADDR <= div;
77 start <= sr(0);
78 process(sysclk, CntrRstCycle)
79 begin
80  if(CntrRstCycle = '1')then
81  data <= (others => '0');
82  startSyncRegs <= (others => '0');
83  ec_div <= '0';
84  div <= (others => '0');
85  div_l <= (others => '0');
86  DataType <= "00";
87  elsif(sysclk'event and sysclk = '1')then
88  startSyncRegs <= startSyncRegs(2 downto 0) & start;
89  if(startSyncRegs(3 downto 2) = "01")then
90  ec_div <= '1';
91  else
92  ec_div <= '0';
93  end if;
94  if(ec_div = '1')then
95  div <= div + 1;
96  div_l <= div;
97  data <= Cntr_Data;
98  if(div(6 downto 3) = "0111" and div(2 downto 1) /= "00")then
99  DataType <= "11";-- 56 bit counter
100  elsif(div(6) = '0' and div(5 downto 4) /= "11")then
101  DataType <= "00";-- register
102  elsif(div(6 downto 3) = "1010" and (div(2) = '0' or div(1 downto 0) = "00"))then
103  DataType <= "00";-- register
104  elsif(div(6 downto 4) = "111")then
105  DataType <= "00";-- register
106  else
107  DataType <= "10";-- 32 bit counter
108  end if;
109  end if;
110  end if;
111 end process;
112 i_counter : BRAM_TDP_MACRO
113  generic map (
114  BRAM_SIZE => "36Kb", -- Target BRAM, "18Kb" or "36Kb"
115  DEVICE => "7SERIES", -- Target Device: "VIRTEX5", "VIRTEX6", "7SERIES", "SPARTAN6"
116  WRITE_MODE_A => "READ_FIRST", -- "WRITE_FIRST", "READ_FIRST" or "NO_CHANGE"
117  READ_WIDTH_A => 32, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb")
118  READ_WIDTH_B => 32, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb")
119  WRITE_WIDTH_A => 32, -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb")
120  WRITE_WIDTH_B => 32) -- Valid values are 1-36 (19-36 only valid when BRAM_SIZE="36Kb")
121  port map (
122  DOA => counter_DOA, -- Output port-A data, width defined by READ_WIDTH_A parameter
123  DOB => ipb_rdata, -- Output port-B data, width defined by READ_WIDTH_B parameter
124  ADDRA => counter_wa, -- Input port-A address, width defined by Port A depth
125  ADDRB => counter_ra, -- Input port-B address, width defined by Port B depth
126  CLKA => clk125, -- 1-bit input port-A clock
127  CLKB => clk125, -- 1-bit input port-B clock
128  DIA => counter_DIA, -- Input port-A data, width defined by WRITE_WIDTH_A parameter
129  DIB => x"00000000", -- Input port-B data, width defined by WRITE_WIDTH_B parameter
130  ENA => '1', -- 1-bit input port-A enable
131  ENB => ec_rdata, -- 1-bit input port-B enable
132  REGCEA => '0', -- 1-bit input port-A output register enable
133  REGCEB => '0', -- 1-bit input port-B output register enable
134  RSTA => '0', -- 1-bit input port-A reset
135  RSTB => '0', -- 1-bit input port-B reset
136  WEA => we_counter, -- Input port-A write enable, width defined by Port A depth
137  WEB => "0000" -- Input port-B write enable, width defined by Port B depth
138  );
139 counter_ra(8 downto 0) <= '0' & ipb_addr(15) & ipb_addr(6 downto 0);
140 counter_ra(9) <= '0' when ipb_addr(14 downto 7) = LSC_addr(14 downto 7) else '1';
141 process(ipb_clk)
142 begin
143  if(ipb_clk'event and ipb_clk = '1')then
144  toggle <= not toggle;
145  end if;
146 end process;
147 process(clk125)
148 begin
149  if(clk125'event and clk125 = '1')then
150  toggle_q <= toggle;
151  ec_rdata <= toggle xor toggle_q;
152  if(DB_cmd = '1' and ec_wdata = '1')then
153  DB_cmd_l <= '1';
154  elsif(sr(0) = '1' and and_reduce(counter_wa(6 downto 0)) = '1')then
155  DB_cmd_l <= '0';
156  end if;
157  if(sr(0) = '1' and and_reduce(counter_wa(6 downto 0)) = '1')then
158  DB_en <= DB_cmd_l;
159  end if;
160  if(sr(0) = '1')then
161  DataType_q <= DataType;
162  end if;
163  if(resetCntr = '1')then
164  counter_wa <= (others => '0');
165  elsif(CntrRstCycle = '1')then
166  counter_wa(7 downto 0) <= counter_wa(7 downto 0) + 1;
167  elsif(sr(0) = '1')then
168  counter_wa(7 downto 0) <= '0' & div_l;
169  elsif(sr(3) = '1')then
170  counter_wa(7) <= '1';
171  end if;
172  if(resetCntr = '1')then
173  CntrRstCycle <= '1';
174  elsif(and_reduce(counter_wa(7 downto 0)) = '1')then
175  CntrRstCycle <= '0';
176  end if;
177  if(CntrRstCycle = '1')then
178  sr <= "0000";
179  elsif(sr(2 downto 0) = "000")then
180  sr <= "0001";
181  else
182  sr <= sr(2 downto 0) & '0';
183  end if;
184  if(CntrRstCycle = '1' or sr(2) = '1')then
185  carry <= '0';
186  elsif(sr(3) = '1' and DataType_q = "11" and counter_DIA(31) = '0' and counter_DOA(31) = '1')then
187  carry <= '1';
188  end if;
189  if(CntrRstCycle = '1')then
190  counter_DIA <= (others => '0');
191  elsif(sr(0) = '1')then
192  counter_DIA <= data;
193  elsif(sr(2) = '1')then
194  if(DataType_q = "10")then
195  if(counter_DOA(9 downto 0) > counter_DIA(9 downto 0))then
196  counter_DIA(31 downto 10) <= counter_DOA(31 downto 10) + 1;
197  else
198  counter_DIA(31 downto 10) <= counter_DOA(31 downto 10);
199  end if;
200  elsif(DataType_q = "11")then
201  if(counter_wa(0) = '1')then
202  counter_DIA(23 downto 0) <= counter_DOA(23 downto 0) + carry;
203  counter_DIA(31 downto 24) <= x"00";
204  elsif(counter_DOA(24 downto 0) > counter_DIA(24 downto 0))then
205  counter_DIA(31 downto 25) <= counter_DOA(31 downto 25) + 1;
206  else
207  counter_DIA(31 downto 25) <= counter_DOA(31 downto 25);
208  end if;
209  end if;
210  end if;
211  if(sr(2) = '1' or (sr(3) = '1' and DB_en = '1') or CntrRstCycle = '1')then
212  we_counter <= x"f";
213  else
214  we_counter <= x"0";
215  end if;
216  end if;
217 end process;
218 i_ec_wdata : SRL16E
219  generic map (
220  INIT => X"0000")
221  port map (
222  Q => ec_wdata, -- SRL data output
223  A0 => '1', -- Select[0] input
224  A1 => '0', -- Select[1] input
225  A2 => '0', -- Select[2] input
226  A3 => '0', -- Select[3] input
227  CE => '1', -- Clock enable input
228  CLK => clk125, -- Clock input
229  D => ec_rdata -- SRL data input
230  );
231 end Behavioral;
232