diff --git a/modules/wishbone/wb_i2c_master/i2c_master_top.vhd b/modules/wishbone/wb_i2c_master/i2c_master_top.vhd index 9e4609a93b0e0c917b0292b4a42fb59c54b22c76..80efd2dab322175b22c2ba530a5fdf9ec45f3cf3 100644 --- a/modules/wishbone/wb_i2c_master/i2c_master_top.vhd +++ b/modules/wishbone/wb_i2c_master/i2c_master_top.vhd @@ -65,7 +65,11 @@ -- Revision 1.2 2001/11/10 10:52:44 rherveille -- Changed PRER reset value from 0x0000 to 0xffff, conform specs. -- - +--------------------------------------------------------------------- +-- +-- Modified to support multiple i2c interfaces, G.Daniluk, CERN 2013 +-- +--------------------------------------------------------------------- library ieee; use ieee.std_logic_1164.all; @@ -74,7 +78,8 @@ use ieee.numeric_std.all; entity i2c_master_top is generic( - ARST_LVL : std_logic := '0' -- asynchronous reset level + ARST_LVL : std_logic := '0'; -- asynchronous reset level + g_num_interfaces : integer := 1 ); port ( -- wishbone signals @@ -91,12 +96,12 @@ entity i2c_master_top is wb_inta_o : out std_logic; -- interrupt request output signal -- i2c lines - scl_pad_i : in std_logic; -- i2c clock line input - scl_pad_o : out std_logic; -- i2c clock line output - scl_padoen_o : out std_logic; -- i2c clock line output enable, active low - sda_pad_i : in std_logic; -- i2c data line input - sda_pad_o : out std_logic; -- i2c data line output - sda_padoen_o : out std_logic -- i2c data line output enable, active low + scl_pad_i : in std_logic_vector(g_num_interfaces-1 downto 0); -- i2c clock line input + scl_pad_o : out std_logic_vector(g_num_interfaces-1 downto 0); -- i2c clock line output + scl_padoen_o : out std_logic_vector(g_num_interfaces-1 downto 0); -- i2c clock line output enable, active low + sda_pad_i : in std_logic_vector(g_num_interfaces-1 downto 0); -- i2c data line input + sda_pad_o : out std_logic_vector(g_num_interfaces-1 downto 0); -- i2c data line output + sda_padoen_o : out std_logic_vector(g_num_interfaces-1 downto 0) -- i2c data line output enable, active low ); end entity i2c_master_top; @@ -168,6 +173,11 @@ architecture structural of i2c_master_top is signal i2c_busy : std_logic; -- i2c bus busy (start signal detected) signal i2c_al, al : std_logic; -- arbitration lost + signal scl_in, scl_out, scl_oen : std_logic; + signal sda_in, sda_out, sda_oen : std_logic; + signal if_num : std_logic_vector(3 downto 0); + signal if_busy : std_logic; + begin -- generate internal reset signal rst_i <= not wb_rst_i; --arst_i xor ARST_LVL; @@ -194,13 +204,13 @@ begin when "010" => wb_dat_o <= ctr; when "011" => wb_dat_o <= rxr; -- write is transmit register TxR when "100" => wb_dat_o <= sr; -- write is command register CR + when "101" => wb_dat_o <= if_busy & "000" & if_num; -- Debugging registers: -- These registers are not documented. -- Functionality could change in future releases - when "101" => wb_dat_o <= txr; - when "110" => wb_dat_o <= cr; - when "111" => wb_dat_o <= (others => '0'); + when "110" => wb_dat_o <= txr; + when "111" => wb_dat_o <= cr; when others => wb_dat_o <= (others => 'X'); -- for simulation only end case; end if; @@ -214,11 +224,15 @@ begin prer <= (others => '1'); ctr <= (others => '0'); txr <= (others => '0'); + if_busy <= '0'; + if_num <= (others => '0'); elsif (wb_clk_i'event and wb_clk_i = '1') then if (wb_rst_i = '1') then prer <= (others => '1'); ctr <= (others => '0'); txr <= (others => '0'); + if_busy <= '0'; + if_num <= (others => '0'); elsif (wb_wacc = '1') then case wb_adr_i is when "000" => prer( 7 downto 0) <= unsigned(wb_dat_i); @@ -226,6 +240,10 @@ begin when "010" => ctr <= wb_dat_i; when "011" => txr <= wb_dat_i; when "100" => null; --write to CR, avoid executing the others clause + when "101" => if_busy <= wb_dat_i(7); + if(if_busy='0') then --change i/f number only if previous was released + if_num <= wb_dat_i(3 downto 0); + end if; -- illegal cases, for simulation only when others => @@ -295,14 +313,24 @@ begin cmd_ack => done, ack_out => irxack, dout => rxr, - scl_i => scl_pad_i, - scl_o => scl_pad_o, - scl_oen => scl_padoen_o, - sda_i => sda_pad_i, - sda_o => sda_pad_o, - sda_oen => sda_padoen_o + scl_i => scl_in, + scl_o => scl_out, + scl_oen => scl_oen, + sda_i => sda_in, + sda_o => sda_out, + sda_oen => sda_oen ); + --Multiplexing i2c lines depending on if_num + scl_in <= scl_pad_i(to_integer(unsigned(if_num))); + sda_in <= sda_pad_i(to_integer(unsigned(if_num))); + GEN_I2C_OUT: for i in 0 to g_num_interfaces-1 generate + scl_pad_o(i) <= scl_out when i = to_integer(unsigned(if_num)) else '1'; + scl_padoen_o(i) <= scl_oen when i = to_integer(unsigned(if_num)) else '1'; + sda_pad_o(i) <= sda_out when i = to_integer(unsigned(if_num)) else '1'; + sda_padoen_o(i) <= sda_oen when i = to_integer(unsigned(if_num)) else '1'; + end generate; + -- status register block + interrupt request signal st_irq_block : block diff --git a/modules/wishbone/wb_i2c_master/wb_i2c_master.vhd b/modules/wishbone/wb_i2c_master/wb_i2c_master.vhd index 6dca5a4406056aa21f681a05d1a875238bc167d4..f32f2c9a6ea94307c0d50f48e76bbf9886b4ed2c 100644 --- a/modules/wishbone/wb_i2c_master/wb_i2c_master.vhd +++ b/modules/wishbone/wb_i2c_master/wb_i2c_master.vhd @@ -5,7 +5,7 @@ -- Author : Tomasz Wlostowski -- Company : CERN BE-Co-HT -- Created : 2010-05-18 --- Last update: 2011-10-05 +-- Last update: 2013-09-09 -- Platform : FPGA-generic -- Standard : VHDL'87 ------------------------------------------------------------------------------- @@ -23,6 +23,7 @@ -- Date Version Author Description -- 2010-05-18 1.0 twlostow Created -- 2010-10-04 1.1 twlostow Added WB slave adapter +-- 2013-09-09 1.2 greg.d Multiplexing multiple i2c interfaces ------------------------------------------------------------------------------- library ieee; @@ -33,8 +34,8 @@ use work.wishbone_pkg.all; entity wb_i2c_master is generic ( g_interface_mode : t_wishbone_interface_mode := CLASSIC; - g_address_granularity : t_wishbone_address_granularity := WORD - ); + g_address_granularity : t_wishbone_address_granularity := WORD; + g_num_interfaces : integer := 1); port ( clk_sys_i : in std_logic; rst_n_i : in std_logic; @@ -50,19 +51,20 @@ entity wb_i2c_master is wb_int_o : out std_logic; wb_stall_o : out std_logic; - scl_pad_i : in std_logic; -- i2c clock line input - scl_pad_o : out std_logic; -- i2c clock line output - scl_padoen_o : out std_logic; -- i2c clock line output enable, active low - sda_pad_i : in std_logic; -- i2c data line input - sda_pad_o : out std_logic; -- i2c data line output - sda_padoen_o : out std_logic -- i2c data line output enable, active low + scl_pad_i : in std_logic_vector(g_num_interfaces-1 downto 0); -- i2c clock line input + scl_pad_o : out std_logic_vector(g_num_interfaces-1 downto 0); -- i2c clock line output + scl_padoen_o : out std_logic_vector(g_num_interfaces-1 downto 0); -- i2c clock line output enable, active low + sda_pad_i : in std_logic_vector(g_num_interfaces-1 downto 0); -- i2c data line input + sda_pad_o : out std_logic_vector(g_num_interfaces-1 downto 0); -- i2c data line output + sda_padoen_o : out std_logic_vector(g_num_interfaces-1 downto 0) -- i2c data line output enable, active low ); end wb_i2c_master; architecture rtl of wb_i2c_master is component i2c_master_top generic ( - ARST_LVL : std_logic); + ARST_LVL : std_logic; + g_num_interfaces : integer := 1); port ( wb_clk_i : in std_logic; wb_rst_i : in std_logic := '0'; @@ -75,12 +77,12 @@ architecture rtl of wb_i2c_master is wb_cyc_i : in std_logic; wb_ack_o : out std_logic; wb_inta_o : out std_logic; - scl_pad_i : in std_logic; - scl_pad_o : out std_logic; - scl_padoen_o : out std_logic; - sda_pad_i : in std_logic; - sda_pad_o : out std_logic; - sda_padoen_o : out std_logic); + scl_pad_i : in std_logic_vector(g_num_interfaces-1 downto 0); + scl_pad_o : out std_logic_vector(g_num_interfaces-1 downto 0); + scl_padoen_o : out std_logic_vector(g_num_interfaces-1 downto 0); + sda_pad_i : in std_logic_vector(g_num_interfaces-1 downto 0); + sda_pad_o : out std_logic_vector(g_num_interfaces-1 downto 0); + sda_padoen_o : out std_logic_vector(g_num_interfaces-1 downto 0)); end component; signal dat_out : std_logic_vector(7 downto 0); @@ -123,7 +125,8 @@ begin Wrapped_I2C : i2c_master_top generic map ( - ARST_LVL => '0') + ARST_LVL => '0', + g_num_interfaces => g_num_interfaces) port map ( wb_clk_i => clk_sys_i, wb_rst_i => rst, diff --git a/modules/wishbone/wb_i2c_master/xwb_i2c_master.vhd b/modules/wishbone/wb_i2c_master/xwb_i2c_master.vhd index 3d672e06c0a85de11de40ca695cfd07999dabaf5..dab5a96aeb00a23aeee66a51fbdcbc0cd2c3b7c5 100644 --- a/modules/wishbone/wb_i2c_master/xwb_i2c_master.vhd +++ b/modules/wishbone/wb_i2c_master/xwb_i2c_master.vhd @@ -6,8 +6,8 @@ use work.wishbone_pkg.all; entity xwb_i2c_master is generic( g_interface_mode : t_wishbone_interface_mode := CLASSIC; - g_address_granularity : t_wishbone_address_granularity := WORD - ); + g_address_granularity : t_wishbone_address_granularity := WORD; + g_num_interfaces : integer := 1); port ( clk_sys_i : in std_logic; rst_n_i : in std_logic; @@ -16,12 +16,12 @@ entity xwb_i2c_master is slave_o : out t_wishbone_slave_out; desc_o : out t_wishbone_device_descriptor; - scl_pad_i : in std_logic; -- i2c clock line input - scl_pad_o : out std_logic; -- i2c clock line output - scl_padoen_o : out std_logic; -- i2c clock line output enable, active low - sda_pad_i : in std_logic; -- i2c data line input - sda_pad_o : out std_logic; -- i2c data line output - sda_padoen_o : out std_logic -- i2c data line output enable, active low + scl_pad_i : in std_logic_vector(g_num_interfaces-1 downto 0); -- i2c clock line input + scl_pad_o : out std_logic_vector(g_num_interfaces-1 downto 0); -- i2c clock line output + scl_padoen_o : out std_logic_vector(g_num_interfaces-1 downto 0); -- i2c clock line output enable, active low + sda_pad_i : in std_logic_vector(g_num_interfaces-1 downto 0); -- i2c data line input + sda_pad_o : out std_logic_vector(g_num_interfaces-1 downto 0); -- i2c data line output + sda_padoen_o : out std_logic_vector(g_num_interfaces-1 downto 0) -- i2c data line output enable, active low ); end xwb_i2c_master; @@ -30,7 +30,8 @@ architecture rtl of xwb_i2c_master is component wb_i2c_master generic ( g_interface_mode : t_wishbone_interface_mode; - g_address_granularity : t_wishbone_address_granularity); + g_address_granularity : t_wishbone_address_granularity; + g_num_interfaces : integer := 1); port ( clk_sys_i : in std_logic; rst_n_i : in std_logic; @@ -44,12 +45,12 @@ architecture rtl of xwb_i2c_master is wb_ack_o : out std_logic; wb_int_o : out std_logic; wb_stall_o : out std_logic; - scl_pad_i : in std_logic; - scl_pad_o : out std_logic; - scl_padoen_o : out std_logic; - sda_pad_i : in std_logic; - sda_pad_o : out std_logic; - sda_padoen_o : out std_logic); + scl_pad_i : in std_logic_vector(g_num_interfaces-1 downto 0); + scl_pad_o : out std_logic_vector(g_num_interfaces-1 downto 0); + scl_padoen_o : out std_logic_vector(g_num_interfaces-1 downto 0); + sda_pad_i : in std_logic_vector(g_num_interfaces-1 downto 0); + sda_pad_o : out std_logic_vector(g_num_interfaces-1 downto 0); + sda_padoen_o : out std_logic_vector(g_num_interfaces-1 downto 0)); end component; begin -- rtl @@ -58,7 +59,8 @@ begin -- rtl U_Wrapped_I2C : wb_i2c_master generic map ( g_interface_mode => g_interface_mode, - g_address_granularity => g_address_granularity) + g_address_granularity => g_address_granularity, + g_num_interfaces => g_num_interfaces) port map ( clk_sys_i => clk_sys_i, rst_n_i => rst_n_i, diff --git a/modules/wishbone/wishbone_pkg.vhd b/modules/wishbone/wishbone_pkg.vhd index 64980da0f2e24a54b5cb8c70c08c2097e132213c..722bfb86a664dc2746fceaa044f1721b65df42d2 100644 --- a/modules/wishbone/wishbone_pkg.vhd +++ b/modules/wishbone/wishbone_pkg.vhd @@ -540,7 +540,8 @@ package wishbone_pkg is component wb_i2c_master generic ( g_interface_mode : t_wishbone_interface_mode := CLASSIC; - g_address_granularity : t_wishbone_address_granularity := WORD); + g_address_granularity : t_wishbone_address_granularity := WORD; + g_num_interfaces : integer := 1); port ( clk_sys_i : in std_logic; rst_n_i : in std_logic; @@ -554,30 +555,31 @@ package wishbone_pkg is wb_ack_o : out std_logic; wb_int_o : out std_logic; wb_stall_o : out std_logic; - scl_pad_i : in std_logic; - scl_pad_o : out std_logic; - scl_padoen_o : out std_logic; - sda_pad_i : in std_logic; - sda_pad_o : out std_logic; - sda_padoen_o : out std_logic); + scl_pad_i : in std_logic_vector(g_num_interfaces-1 downto 0); + scl_pad_o : out std_logic_vector(g_num_interfaces-1 downto 0); + scl_padoen_o : out std_logic_vector(g_num_interfaces-1 downto 0); + sda_pad_i : in std_logic_vector(g_num_interfaces-1 downto 0); + sda_pad_o : out std_logic_vector(g_num_interfaces-1 downto 0); + sda_padoen_o : out std_logic_vector(g_num_interfaces-1 downto 0)); end component; component xwb_i2c_master generic ( g_interface_mode : t_wishbone_interface_mode := CLASSIC; - g_address_granularity : t_wishbone_address_granularity := WORD); + g_address_granularity : t_wishbone_address_granularity := WORD; + g_num_interfaces : integer := 1); port ( clk_sys_i : in std_logic; rst_n_i : in std_logic; slave_i : in t_wishbone_slave_in; slave_o : out t_wishbone_slave_out; desc_o : out t_wishbone_device_descriptor; - scl_pad_i : in std_logic; - scl_pad_o : out std_logic; - scl_padoen_o : out std_logic; - sda_pad_i : in std_logic; - sda_pad_o : out std_logic; - sda_padoen_o : out std_logic); + scl_pad_i : in std_logic_vector(g_num_interfaces-1 downto 0); + scl_pad_o : out std_logic_vector(g_num_interfaces-1 downto 0); + scl_padoen_o : out std_logic_vector(g_num_interfaces-1 downto 0); + sda_pad_i : in std_logic_vector(g_num_interfaces-1 downto 0); + sda_pad_o : out std_logic_vector(g_num_interfaces-1 downto 0); + sda_padoen_o : out std_logic_vector(g_num_interfaces-1 downto 0)); end component; component xwb_lm32