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]