AMC13
Firmwares for the different applications of the AMC13 uTCA board made at Boston University
 All Classes Variables
I2C.vhd
1 ----------------------------------------------------------------------------------
2 -- Company:
3 -- Engineer:
4 --
5 -- Create Date: 15:01:01 07/27/2011
6 -- Design Name:
7 -- Module Name: I2C - 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 I2C is
39  Port ( clk : in STD_LOGIC; -- DRPclk 50MHz
40  ipb_clk : in STD_LOGIC;
41  reset : in STD_LOGIC;
42 -- ns2500 : in STD_LOGIC;
43  addr: in STD_LOGIC_VECTOR(31 downto 0);
44  rdata : out STD_LOGIC_VECTOR(31 downto 0);
45  CLK_rdy : out STD_LOGIC;
46  CLK_SCL : out STD_LOGIC;
47  CLK_SDA : inout STD_LOGIC;
48  SFP_ABS : in STD_LOGIC_VECTOR(3 downto 0);
49  SFP_LOS : in STD_LOGIC_VECTOR(2 downto 0);
50  SFP_SCL : out STD_LOGIC_VECTOR(3 downto 0);
51  SFP_SDA : inout STD_LOGIC_VECTOR(3 downto 0));
52 end I2C;
53 
54 architecture Behavioral of I2C is
55 signal clk_div : std_logic_vector(7 downto 0) := (others => '0');
56 signal SFP_ABSq : std_logic_vector(7 downto 0) := (others =>'0');
57 signal SFP : std_logic_vector(1 downto 0) := (others =>'0');
58 signal SFP_DATA : std_logic_vector(3 downto 0) := (others =>'0');
59 signal we_SFP : std_logic := '0';
60 signal set_we_SFP : std_logic := '0';
61 type state is (Idle,Debouce,S,D,A,W,P);
62 signal SM : state := Idle;
63 signal t_SDA : std_logic_vector(3 downto 0) := (others => '1');
64 signal Si5338Cntr : std_logic_vector(7 downto 0) := (others => '1');
65 signal t_CLK_SDA : std_logic := '1';
66 signal t_CLK_SDA_q : std_logic := '1';
67 signal Si5338Done : std_logic := '0';
68 signal ce_CLK_rdy : std_logic := '0';
69 signal ACK : std_logic := '0';
70 signal done : std_logic := '0';
71 signal data : std_logic := '0';
72 signal SFPROM_data : std_logic := '0';
73 signal SCL_phase : std_logic_vector(1 downto 0) := (others => '0');
74 signal SM_cntr : std_logic_vector(10 downto 0) := (others => '0');
75 signal Debouce_cntr : std_logic_vector(17 downto 0) := (others => '0');
76 signal SFP_ADDR : std_logic_vector(9 downto 0) := (others => '0');
77 signal we_rdata : std_logic := '0';
78 --type RAM16384X1 is array(0 to 16383) of std_logic;
79 --signal I2C_buf : RAM16384X1 := (others => '0');
80 signal rdata_ra : std_logic_vector(8 downto 0) := (others =>'1');
81 signal rdata_wa : std_logic_vector(13 downto 0) := (others =>'1');
82 signal DIBDI : std_logic_vector(0 downto 0) := (others =>'0');
83 signal resetSyncRegs : std_logic_vector(2 downto 0) := (others => '0');
84 
85 begin
86 CLK_SDA <= '0' when t_CLK_SDA_q = '0' else 'Z';
87 SFP_SDA(3) <= '0' when t_SDA(3) = '0' else 'Z';
88 SFP_SDA(2) <= '0' when t_SDA(2) = '0' else 'Z';
89 SFP_SDA(1) <= '0' when t_SDA(1) = '0' else 'Z';
90 SFP_SDA(0) <= '0' when t_SDA(0) = '0' else 'Z';
91 i_CLK_rdy : SRLC32E
92  generic map (
93  INIT => X"00000000")
94  port map (
95  Q => CLK_rdy, -- SRL data output
96  Q31 => open, -- SRL cascade output pin
97  A => "11111", -- 5-bit shift depth select input
98  CE => ce_CLK_rdy, -- Clock enable input
99  CLK => clk, -- Clock input
100  D => Si5338Done -- SRL data input
101  );
102 ce_CLK_rdy <= '1' when clk_div(7) = '1' and SCL_phase = "11" else '0';
103 process(clk,reset)
104 begin
105  if(reset = '1')then
106  resetSyncRegs <= (others => '1');
107  elsif(clk'event and clk = '1')then
108  resetSyncRegs <= resetSyncRegs(1 downto 0) & '0';
109  end if;
110 end process;
111 process(clk)
112 begin
113  if(clk'event and clk = '1')then
114  if(resetSyncRegs(2) = '1' or clk_div(7) = '1')then -- 400 KHz
115  clk_div <= x"04";
116  else
117  clk_div <= clk_div + 1;
118  end if;
119  if(resetSyncRegs(2) = '1')then
120  SCL_phase <= "00";
121  elsif(clk_div(7) = '1')then
122  SCL_phase <= SCL_phase + 1;
123  end if;
124  if(resetSyncRegs(2) = '1')then
125  SFP_ABSq <= (others => '1');
126  SM <= Idle;
127  t_sda <= x"f";
128  elsif(clk_div(7) = '1' and SCL_phase = "11")then
129  case SM is
130  when Idle =>
131  SM_cntr <= "11111101000";
132  SFP_ABSq <= SFP_ABSq(3 downto 0) & SFP_ABS;
133  if(SFP_ABSq(7 downto 4) /= SFP_ABSq(3 downto 0))then
134  SM <= Debouce;
135  end if;
136  t_SDA <= x"f";
137  Debouce_cntr <= (others => '0');
138  when Debouce =>
139  SFP_ABSq <= SFP_ABSq(3 downto 0) & SFP_ABS;
140  Debouce_cntr <= Debouce_cntr + 1;
141  if(Debouce_cntr(17) = '1')then
142  SM <= S;
143  end if;
144  when S =>
145  SM <= D;
146  t_SDA <= SFP_ABSq(7 downto 4);
147  when D =>
148  if(SM_cntr(2 downto 0) = "111")then
149  SM <= A;
150  end if;
151  SM_cntr <= SM_cntr + 1;
152  if(SM_cntr(10 downto 9) = "11" and data = '0')then
153  t_SDA <= SFP_ABSq(7 downto 4);
154  else
155  t_SDA <= x"f";
156  end if;
157  ACK <= not SM_cntr(10);
158  when A =>
159  if(SM_cntr(10 downto 9) = "10" or (SM_cntr(10 downto 9) = "11" and SM_cntr(4 downto 3) = "11"))then
160  SM <= W;
161  else
162  Sm <= D;
163  end if;
164  if(ACK = '1' and SM_cntr(10 downto 9) /= "10")then
165  t_SDA <= SFP_ABSq(7 downto 4);
166  else
167  t_SDA <= x"f";
168  end if;
169  when W =>
170  if(SM_cntr(10 downto 9) = "10")then
171  SM <= P;
172  else
173  SM <= S;
174  end if;
175  when P =>
176  SM <= Idle;
177  t_SDA <= SFP_ABSq(7 downto 4);
178  when others => SM <= Idle;
179  end case;
180  end if;
181  t_CLK_SDA_q <= t_CLK_SDA;
182  if(resetSyncRegs(2) = '1')then
183  Si5338Done <= '0';
184  elsif(clk_div(7) = '1' and SCL_phase(1) = '1' and Si5338Cntr = x"72")then
185  Si5338Done <= '1';
186  end if;
187  if(resetSyncRegs(2) = '1' or Si5338Done = '1')then
188  CLK_SCL <= '1';
189  elsif(clk_div(7) = '1' and SCL_phase(0) = '1')then
190  if(SCL_phase(1) = '0')then
191  CLK_SCL <= '1';
192  elsif(Si5338Cntr /= x"e2" and Si5338Cntr /= x"8f")then
193  CLK_SCL <= '0';
194  end if;
195  end if;
196  if(resetSyncRegs(2) = '1' or Si5338Done = '1')then
197  Si5338Cntr <= (others => '1');
198  elsif(clk_div(7) = '1')then
199  if(SCL_phase = "00")then
200  Si5338Cntr <= Si5338Cntr - 1;
201  end if;
202  end if;
203  rdata_wa(12 downto 0) <= '0' & not SFP & SFP_ADDR;
204  we_rdata <= we_SFP;
205  DIBDI(0) <= SFP_DATA(3);
206  if(we_SFP = '0')then
207  SFP <= "00";
208  SFP_DATA <= SFP_SDA and not SFP_ABSq(7 downto 4);
209  else
210  SFP(1) <= SFP(1) xor SFP(0);
211  SFP(0) <= not SFP(0);
212  SFP_DATA <= SFP_DATA(2 downto 0) & '0';
213  end if;
214  if(SFPROM_data = '1' and SCL_phase = "01" and clk_div(7) = '1')then
215  set_we_SFP <= '1';
216  else
217  set_we_SFP <= '0';
218  end if;
219  if(set_we_SFP = '1')then
220  we_SFP <= '1';
221  elsif(SFP = "11")then
222  we_SFP <= '0';
223  end if;
224  if(clk_div(7) = '1')then
225  if(SM = S or SM = Idle or SM = Debouce or SCL_phase(1) = '0')then
226  SFP_SCL <= x"f";
227  else
228  SFP_SCL <= SFP_ABSq(7 downto 4);
229  end if;
230  if(SCL_phase = "11")then
231  SFP_ADDR <= SM_cntr(9 downto 3) & not SM_cntr(2 downto 0);
232  if(SM = D and SM_cntr(10) = '0')then
233  SFPROM_data <= '1';
234  else
235  SFPROM_data <= '0';
236  end if;
237  end if;
238  end if;
239  end if;
240 end process;
241 i_I2C_buf : BRAM_SDP_MACRO
242  generic map (
243  BRAM_SIZE => "18Kb", -- Target BRAM, "18Kb" or "36Kb"
244  DEVICE => "7SERIES", -- Target device: "VIRTEX5", "VIRTEX6", "7SERIES", "SPARTAN6"
245  WRITE_WIDTH => 1, -- Valid values are 1-72 (37-72 only valid when BRAM_SIZE="36Kb")
246  READ_WIDTH => 32, -- Valid values are 1-72 (37-72 only valid when BRAM_SIZE="36Kb")
247  DO_REG => 0, -- Optional output register (0 or 1)
248  SIM_COLLISION_CHECK => "NONE", -- Collision check enable "ALL", "WARNING_ONLY",
249  -- "GENERATE_X_ONLY" or "NONE"
250  WRITE_MODE => "WRITE_FIRST", -- Specify "READ_FIRST" for same clock or synchronous clocks
251  -- Specify "WRITE_FIRST for asynchrononous clocks on ports
252  INIT => X"000000000000000000") -- Initial values on output port
253  port map (
254  DO => rdata, -- Output read data port, width defined by READ_WIDTH parameter
255  DI => DIBDI, -- Input write data port, width defined by WRITE_WIDTH parameter
256  RDADDR => rdata_ra, -- Input read address, width defined by read port depth
257  RDCLK => ipb_clk, -- 1-bit input read clock
258  RDEN => '1', -- 1-bit input read port enable
259  REGCE => '1', -- 1-bit input read output register enable
260  RST => '0', -- 1-bit input reset
261  WE => "1", -- Input write enable, width defined by write port depth
262  WRADDR => rdata_wa, -- Input write address, width defined by write port depth
263  WRCLK => clk, -- 1-bit input write clock
264  WREN => we_rdata -- 1-bit input write port enable
265  );
266 --process(clk)
267 --begin
268 -- if(clk'event and clk = '1')then
269 -- if(we_rdata = '1')then
270 -- I2C_buf(conv_integer(rdata_wa)) <= DIBDI(0);
271 -- end if;
272 -- end if;
273 --end process;
274 --process(ipb_clk)
275 --begin
276 -- if(ipb_clk'event and ipb_clk = '1')then
277 -- for i in 0 to 31 loop
278 -- rdata(i) <= I2C_buf(conv_integer(rdata_ra & conv_std_logic_vector(i,5)));
279 -- end loop;
280 -- end if;
281 --end process;
282 rdata_wa(13) <= '1';
283 rdata_ra(7 downto 0) <= addr(7 downto 0);
284 rdata_ra(8) <= '1' when addr(15 downto 8) = I2C_addr(15 downto 8) else '0';
285 i_data : ROM32X1
286  generic map (
287  INIT => X"85000500")
288  port map (
289  O => data, -- ROM output
290  A0 => SM_cntr(0), -- ROM address[0]
291  A1 => SM_cntr(1), -- ROM address[1]
292  A2 => SM_cntr(2), -- ROM address[2]
293  A3 => SM_cntr(3), -- ROM address[3]
294  A4 => SM_cntr(4) -- ROM address[4]
295  );
296 i_Si5338ROM : ROM256X1
297  generic map (
298 -- INIT => X"b83cd08dc156a041201008040205b83cd0080000000000000000000000000000")
299  INIT => X"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff")
300  port map (
301  O => t_CLK_SDA, -- ROM output
302  A0 => Si5338Cntr(0), -- ROM address[0]
303  A1 => Si5338Cntr(1), -- ROM address[1]
304  A2 => Si5338Cntr(2), -- ROM address[2]
305  A3 => Si5338Cntr(3), -- ROM address[3]
306  A4 => Si5338Cntr(4), -- ROM address[4]
307  A5 => Si5338Cntr(5), -- ROM address[5]
308  A6 => Si5338Cntr(6), -- ROM address[6]
309  A7 => Si5338Cntr(7) -- ROM address[7]
310  );
311 
312 
313 end Behavioral;
314