1 ----------------------------------------------------------------------------------
5 -- Create Date: 15:
01:
01 07/27/2011
7 -- Module Name: I2C - Behavioral
16 -- Revision 0.
01 -
File Created
17 -- Additional Comments:
19 ----------------------------------------------------------------------------------
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;
27 -- Uncomment the following library declaration if using
28 -- arithmetic functions with or values
29 --use IEEE.NUMERIC_STD.ALL;
31 -- Uncomment the following library declaration if instantiating
32 -- any Xilinx primitives in this code.
34 use UNISIM.VComponents.
all;
36 use UNIMACRO.vcomponents.
all;
39 Port ( clk : in ;
-- DRPclk 50MHz
43 addr: in (31 downto 0);
44 rdata : out (31 downto 0);
48 SFP_ABS : in (3 downto 0);
49 SFP_LOS : in (2 downto 0);
50 SFP_SCL : out (3 downto 0);
51 SFP_SDA : inout (3 downto 0));
54 architecture Behavioral
of I2C is
55 signal clk_div : (7 downto 0) := (others => '0');
56 signal SFP_ABSq : (7 downto 0) := (others =>'0');
57 signal SFP : (1 downto 0) := (others =>'0');
58 signal SFP_DATA : (3 downto 0) := (others =>'0');
59 signal we_SFP : := '0';
60 signal set_we_SFP : := '0';
61 type state is (Idle,Debouce,S,D,A,W,P);
62 signal SM : state := Idle;
63 signal t_SDA : (3 downto 0) := (others => '1');
64 signal Si5338Cntr : (7 downto 0) := (others => '1');
65 signal t_CLK_SDA : := '1';
66 signal t_CLK_SDA_q : := '1';
67 signal Si5338Done : := '0';
68 signal ce_CLK_rdy : := '0';
72 signal SFPROM_data : := '0';
73 signal SCL_phase : (1 downto 0) := (others => '0');
74 signal SM_cntr : (10 downto 0) := (others => '0');
75 signal Debouce_cntr : (17 downto 0) := (others => '0');
76 signal SFP_ADDR : (9 downto 0) := (others => '0');
77 signal we_rdata : := '0';
78 --type RAM16384X1 is array(0 to 16383)
of ;
79 --signal I2C_buf : RAM16384X1 := (others => '0');
80 signal rdata_ra : (8 downto 0) := (others =>'1');
81 signal rdata_wa : (13 downto 0) := (others =>'1');
82 signal DIBDI : (0 downto 0) := (others =>'0');
83 signal resetSyncRegs : (2 downto 0) := (others => '0');
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';
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
102 ce_CLK_rdy <= '1' when clk_div(7) = '1' and SCL_phase = "11" else '0';
106 resetSyncRegs <= (others => '1');
107 elsif(clk'event and clk = '1')then
108 resetSyncRegs <= resetSyncRegs(1 downto 0) & '0';
113 if(clk'event and clk = '1')then
114 if(resetSyncRegs(2) = '1' or clk_div(7) = '1')then -- 400 KHz
117 clk_div <= clk_div + 1;
119 if(resetSyncRegs(2) = '1')then
121 elsif(clk_div(7) = '1')then
122 SCL_phase <= SCL_phase + 1;
124 if(resetSyncRegs(2) = '1')then
125 SFP_ABSq <= (others => '1');
128 elsif(clk_div(7) = '1' and SCL_phase = "11")then
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
137 Debouce_cntr <= (others => '0');
139 SFP_ABSq <= SFP_ABSq(3 downto 0) & SFP_ABS;
140 Debouce_cntr <= Debouce_cntr + 1;
141 if(Debouce_cntr(17) = '1')then
146 t_SDA <= SFP_ABSq(7 downto 4);
148 if(SM_cntr(2 downto 0) = "111")then
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);
157 ACK <= not SM_cntr(10);
159 if(SM_cntr(10 downto 9) = "10" or (SM_cntr(10 downto 9) = "11" and SM_cntr(4 downto 3) = "11"))then
164 if(ACK = '1' and SM_cntr(10 downto 9) /= "10")then
165 t_SDA <= SFP_ABSq(7 downto 4);
170 if(SM_cntr(10 downto 9) = "10")then
177 t_SDA <= SFP_ABSq(7 downto 4);
178 when others => SM <= Idle;
181 t_CLK_SDA_q <= t_CLK_SDA;
182 if(resetSyncRegs(2) = '1')then
184 elsif(clk_div(7) = '1' and SCL_phase(1) = '1' and Si5338Cntr = x"72")then
187 if(resetSyncRegs(2) = '1' or Si5338Done = '1')then
189 elsif(clk_div(7) = '1' and SCL_phase(0) = '1')then
190 if(SCL_phase(1) = '0')then
192 elsif(Si5338Cntr /= x"e2" and Si5338Cntr /= x"8f")then
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;
203 rdata_wa(12 downto 0) <= '0' & not SFP & SFP_ADDR;
205 DIBDI(0) <= SFP_DATA(3);
208 SFP_DATA <= SFP_SDA and not SFP_ABSq(7 downto 4);
210 SFP(1) <= SFP(1) xor SFP(0);
211 SFP(0) <= not SFP(0);
212 SFP_DATA <= SFP_DATA(2 downto 0) & '0';
214 if(SFPROM_data = '1' and SCL_phase = "01" and clk_div(7) = '1')then
219 if(set_we_SFP = '1')then
221 elsif(SFP = "11")then
224 if(clk_div(7) = '1')then
225 if(SM = S or SM = Idle or SM = Debouce or SCL_phase(1) = '0')then
228 SFP_SCL <= SFP_ABSq(7 downto 4);
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
241 i_I2C_buf : BRAM_SDP_MACRO
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
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
268 -- if(clk'event and clk = '1')then
269 -- if(we_rdata = '1')then
270 -- I2C_buf(conv_integer(rdata_wa)) <= DIBDI(0);
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)));
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';
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]
296 i_Si5338ROM : ROM256X1
298 -- INIT => X"b83cd08dc156a041201008040205b83cd0080000000000000000000000000000")
299 INIT => X"ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff"
)
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]