---------------------------------------------------------------------------------- -- Company: -- Engineer: -- -- Create Date: 04/22/2020 03:22:13 PM -- Design Name: -- Module Name: I2C_if - Behavioral -- Project Name: -- Target Devices: -- Tool Versions: -- Description: -- -- Dependencies: -- -- Revision: -- Revision 0.01 - File Created -- Additional Comments: -- ---------------------------------------------------------------------------------- library IEEE; use IEEE.STD_LOGIC_1164.ALL; library work; use work.ngFEC_pack.all; -- Uncomment the following library declaration if using -- arithmetic functions with Signed or Unsigned values use IEEE.NUMERIC_STD.ALL; -- Uncomment the following library declaration if instantiating -- any Xilinx leaf cells in this code. library UNISIM; use UNISIM.VComponents.all; entity I2C_if is GENERIC ( WAIT_STATES : INTEGER := 10); Port ( ipb_clk : in STD_LOGIC; ipb_reset : in STD_LOGIC; local_reset : in std_logic_vector(8 downto 0); prescale : in std_logic_vector(31 downto 0); Si_SDA : inout std_logic; Si_SCL : inout std_logic; FF_TX_SDA : inout std_logic_vector(3 downto 0); FF_TX_SCL : inout std_logic_vector(3 downto 0); FF_RX_SDA : inout std_logic_vector(3 downto 0); FF_RX_SCL : inout std_logic_vector(3 downto 0); ipb_mosi : in ipb_wbus; ipb_miso : out ipb_rbus); end I2C_if; architecture Behavioral of I2C_if is Component Module_RAM port( clk : in STD_LOGIC; --Port A a_addr : in STD_LOGIC_VECTOR (BRAM_WORD_SIZE downto 0); a_din : in STD_LOGIC_VECTOR (31 downto 0); a_wr : in STD_LOGIC_VECTOR (0 downto 0); a_dout : out STD_LOGIC_VECTOR (31 downto 0); --Port B b_addr : in STD_LOGIC_VECTOR (BRAM_WORD_SIZE downto 0); b_din : in STD_LOGIC_VECTOR (31 downto 0); b_wr : in STD_LOGIC_VECTOR (0 downto 0); b_dout : out STD_LOGIC_VECTOR (31 downto 0) ); end Component; component buffer_server_com generic ( partition : in STD_LOGIC_VECTOR); port( ipb_clk_i : in std_logic; ipb_reset_i : in std_logic; local_reset_i : in std_logic; ram_mosi : in ipb_wbus; ram_miso : out ipb_rbus; server_addr_o : out STD_LOGIC_VECTOR (BRAM_WORD_SIZE downto 0); server_din_o : out STD_LOGIC_VECTOR (31 downto 0); server_wr_o : out STD_LOGIC_VECTOR (0 downto 0); server_dout : in STD_LOGIC_VECTOR (31 downto 0); input_size : out STD_LOGIC_VECTOR (31 downto 0); output_size : in STD_LOGIC_VECTOR (31 downto 0); control_reg : out STD_LOGIC_VECTOR (31 downto 0); status_reg : in STD_LOGIC_VECTOR (31 downto 0); ngccm_state_o : out state ); end component; component buffer_ngccm_com port( ipb_clk_i : in std_logic; ipb_reset_i : in std_logic; ngccm_addr : out STD_LOGIC_VECTOR (BRAM_WORD_SIZE downto 0); ngccm_din : out STD_LOGIC_VECTOR (31 downto 0); ngccm_wr : out STD_LOGIC_VECTOR (0 downto 0); ngccm_dout : in STD_LOGIC_VECTOR (31 downto 0); input_size : in STD_LOGIC_VECTOR (31 downto 0); output_size : out STD_LOGIC_VECTOR (31 downto 0); status_reg : out STD_LOGIC_VECTOR (31 downto 0); ngccm_state : in state; ngccm_miso : in ipb_rbus; ngccm_mosi : out ipb_wbus; partition : in STD_LOGIC_VECTOR (4 downto 0) ); end component; COMPONENT LocalI2CBridge PORT ( reset_local : IN STD_LOGIC; clk_local : IN STD_LOGIC; strobe_local : IN STD_LOGIC; write_local : IN STD_LOGIC; addr_local : IN STD_LOGIC_VECTOR(3 DOWNTO 0); DataIn_local : IN STD_LOGIC_VECTOR(31 DOWNTO 0); DataOut_local : OUT STD_LOGIC_VECTOR(31 DOWNTO 0); wb_ack_o : OUT STD_LOGIC; clk_en : IN STD_LOGIC; prer_scale_i : IN STD_LOGIC_VECTOR (15 downto 0); power_good : IN std_logic; sfp_rx_lost : IN STD_LOGIC; sfp_tx_fault : IN STD_LOGIC; scl_i : IN STD_LOGIC; sda_i : IN STD_LOGIC; scl_o : OUT STD_LOGIC; sda_o : OUT STD_LOGIC); END COMPONENT; signal ram_miso : ipb_out := (others=>init_ipb_rbus); signal ngccm_mosi : ipb_in := (others=>init_ipb_wbus); signal ngccm_miso : ipb_out := (others=>init_ipb_rbus); signal control_reg : ram_register ; signal input_size : ram_register ; signal output_size : ram_register ; signal ref_state : ram_register ; signal status_reg : ram_register ; signal ngccm_state : block_state; type array9X4unsigned is array(0 to 8) of unsigned(3 downto 0); signal cycle_cnt : array9x4unsigned := (others => (others => '0')); signal server : block_ram := (others => init_block_ram); signal ngCCM : block_ram := (others => init_block_ram); signal ack : std_logic_vector(8 downto 0) := (others => '0'); signal ipb_cycle : std_logic_vector(8 downto 0) := (others => '0'); signal local_strobe : std_logic_vector(8 downto 0) := (others => '0'); signal local_write : std_logic_vector(8 downto 0) := (others => '0'); type array9X4 is array(0 to 8) of std_logic_vector(3 downto 0); type array9X32 is array(0 to 8) of std_logic_vector(31 downto 0); signal toggle : std_logic_vector(8 downto 0) := (others => '0'); signal toggle_q : array9x4 := (others => (others => '0')); signal local_addr : array9x4 := (others => (others => '0')); signal local_data_in : array9x32 := (others => (others => '0')); signal local_data_out : array9x32 := (others => (others => '0')); signal i2c_sda : std_logic_vector(8 downto 0); signal i2c_scl : std_logic_vector(8 downto 0); signal i2c_scl_i : std_logic_vector(8 downto 0) := (others => '1'); signal i2c_scl_o : std_logic_vector(8 downto 0) := (others => '1'); signal i2c_sda_i : std_logic_vector(8 downto 0) := (others => '1'); signal i2c_sda_o : std_logic_vector(8 downto 0) := (others => '1'); signal prescale_cnt : unsigned(15 downto 0); signal i2c_clk_en : std_logic := '0'; begin Si_SDA <= i2c_sda(8); Si_SCL <= i2c_scl(8); FF_TX_SDA <= i2c_sda(7 downto 4); FF_RX_SDA <= i2c_sda(3 downto 0); FF_TX_SCL <= i2c_scl(7 downto 4); FF_RX_SCL <= i2c_scl(3 downto 0); process(ipb_mosi,ram_miso) variable s : std_logic_vector(4 downto 0); begin s := ipb_mosi.ipb_addr(26)&ipb_mosi.ipb_addr(19 downto 16); case s is when "00000" => ipb_miso <= ram_miso(0); when "00001" => ipb_miso <= ram_miso(1); when "00010" => ipb_miso <= ram_miso(2); when "00011" => ipb_miso <= ram_miso(3); when "00100" => ipb_miso <= ram_miso(4); when "00101" => ipb_miso <= ram_miso(5); when "00110" => ipb_miso <= ram_miso(6); when "00111" => ipb_miso <= ram_miso(7); when "01000" => ipb_miso <= ram_miso(8); when others => ipb_miso <= init_ipb_rbus; end case; end process; I2C_array : for i in 0 to 8 generate begin RAM: Module_RAM Port map( clk => ipb_clk, a_addr => server(i).ram_addr, a_din => server(i).ram_datain, a_wr => server(i).ram_wr, a_dout => server(i).ram_dataout, b_addr => ngCCM(i).ram_addr, b_din => ngCCM(i).ram_datain, b_wr => ngCCM(i).ram_wr, b_dout => ngCCM(i).ram_dataout ); buffer_server: buffer_server_com generic map( partition => part(i)) port map( ipb_clk_i => ipb_clk, ipb_reset_i => ipb_reset, local_reset_i => local_reset(i), ram_mosi => ipb_mosi, ram_miso => ram_miso(i), server_addr_o => server(i).ram_addr, server_din_o => server(i).ram_datain, server_wr_o => server(i).ram_wr, server_dout => server(i).ram_dataout, input_size => input_size(i), output_size => output_size(i), control_reg => control_reg(i), ngccm_state_o => ngccm_state(i), status_reg => status_reg(i)); buffer_ngccm:buffer_ngccm_com port map( ipb_clk_i => ipb_clk, ipb_reset_i => ipb_reset, input_size => input_size(i), output_size => output_size(i), status_reg => status_reg(i), ngccm_addr => ngccm(i).ram_addr, ngccm_din => ngccm(i).ram_datain, ngccm_wr => ngccm(i).ram_wr, ngccm_dout => ngccm(i).ram_dataout, ngccm_state => ngccm_state(i), ngccm_miso => ngccm_miso(i), ngccm_mosi => ngccm_mosi(i), partition => part(i)); process(ipb_clk) begin if(ipb_clk'event and ipb_clk = '1')then if(ack(i) = '1')then ipb_cycle(i) <= '0'; elsif(ngccm_mosi(i).ipb_strobe = '1')then ipb_cycle(i) <= '1'; end if; if(ngccm_mosi(i).ipb_strobe = '1' and ipb_cycle(i) = '0')then toggle(i) <= not toggle(i); end if; toggle_q(i) <= toggle_q(i)(2 downto 0) & toggle(i); if(ipb_cycle(i) = '0')then cycle_cnt(i) <= (others => '0'); else cycle_cnt(i) <= cycle_cnt(i) + 1; end if; if(cycle_cnt(i) = to_unsigned(WAIT_STATES,4))then ack(i) <= '1'; else ack(i) <= '0'; end if; if(cycle_cnt(i) = to_unsigned(WAIT_STATES,4))then ngccm_miso(i).ipb_rdata <= local_data_out(i); end if; if(toggle_q(i)(1) = toggle_q(i)(3))then local_strobe(i) <= '0'; else local_strobe(i) <= '1'; end if; if(toggle_q(i)(2) = toggle_q(i)(3))then local_write(i) <= '0'; else local_write(i) <= ngccm_mosi(i).ipb_write; end if; if(toggle_q(i)(1) /= toggle_q(i)(0))then local_addr(i) <= ngccm_mosi(i).ipb_addr(3 downto 0); local_data_in(i) <= ngccm_mosi(i).ipb_wdata; end if; end if; end process; LocalI2CBridge_fe : LocalI2CBridge PORT MAP ( reset_local => local_reset(i), clk_local => ipb_clk, strobe_local => local_strobe(i), write_local => local_write(i), addr_local => local_addr(i), DataIn_local => local_data_in(i), DataOut_local => local_data_out(i), wb_ack_o => open, clk_en => i2c_clk_en, prer_scale_i => prescale(15 DOWNTO 0), power_good => '0', sfp_rx_lost => '0', sfp_tx_fault => '0', scl_i => i2c_scl_i(i), sda_i => i2c_sda_i(i), scl_o => i2c_scl_o(i), sda_o => i2c_sda_o(i)); i2c_scl_inst : IOBUF port map (I => '0', O => i2c_scl_i(i), IO => i2c_scl(i), T => i2c_scl_o(i)); i2c_sda_inst : IOBUF port map (I => '0', O => i2c_sda_i(i), IO => i2c_sda(i), T => i2c_sda_o(i)); end generate I2C_array; process(ipb_clk) begin if(ipb_clk'event and ipb_clk = '1')then if (prescale_cnt = 0) then prescale_cnt <= unsigned(prescale(15 downto 0)); i2c_clk_en <= '1'; else prescale_cnt <= prescale_cnt - 1; i2c_clk_en <= '0'; end if; end if; end process; end Behavioral;