From 05d77f772317de5d925301aa11bb9a880656dd05 Mon Sep 17 00:00:00 2001
From: Josh Blum <josh@joshknows.com>
Date: Thu, 15 Apr 2010 11:24:24 -0700
Subject: moved usrp1 and usrp2 fpga dirs into fpga subdirectory

---
 fpga/usrp2/opencores/i2c/rtl/vhdl/CVS/Entries      |   7 +
 fpga/usrp2/opencores/i2c/rtl/vhdl/CVS/Repository   |   1 +
 fpga/usrp2/opencores/i2c/rtl/vhdl/CVS/Root         |   1 +
 fpga/usrp2/opencores/i2c/rtl/vhdl/CVS/Template     |   0
 fpga/usrp2/opencores/i2c/rtl/vhdl/I2C.VHD          | 620 +++++++++++++++++++++
 .../opencores/i2c/rtl/vhdl/i2c_master_bit_ctrl.vhd | 495 ++++++++++++++++
 .../i2c/rtl/vhdl/i2c_master_byte_ctrl.vhd          | 370 ++++++++++++
 .../opencores/i2c/rtl/vhdl/i2c_master_top.vhd      | 359 ++++++++++++
 fpga/usrp2/opencores/i2c/rtl/vhdl/readme           |  25 +
 fpga/usrp2/opencores/i2c/rtl/vhdl/tst_ds1621.vhd   | 283 ++++++++++
 10 files changed, 2161 insertions(+)
 create mode 100644 fpga/usrp2/opencores/i2c/rtl/vhdl/CVS/Entries
 create mode 100644 fpga/usrp2/opencores/i2c/rtl/vhdl/CVS/Repository
 create mode 100644 fpga/usrp2/opencores/i2c/rtl/vhdl/CVS/Root
 create mode 100644 fpga/usrp2/opencores/i2c/rtl/vhdl/CVS/Template
 create mode 100644 fpga/usrp2/opencores/i2c/rtl/vhdl/I2C.VHD
 create mode 100644 fpga/usrp2/opencores/i2c/rtl/vhdl/i2c_master_bit_ctrl.vhd
 create mode 100644 fpga/usrp2/opencores/i2c/rtl/vhdl/i2c_master_byte_ctrl.vhd
 create mode 100644 fpga/usrp2/opencores/i2c/rtl/vhdl/i2c_master_top.vhd
 create mode 100644 fpga/usrp2/opencores/i2c/rtl/vhdl/readme
 create mode 100644 fpga/usrp2/opencores/i2c/rtl/vhdl/tst_ds1621.vhd

(limited to 'fpga/usrp2/opencores/i2c/rtl/vhdl')

diff --git a/fpga/usrp2/opencores/i2c/rtl/vhdl/CVS/Entries b/fpga/usrp2/opencores/i2c/rtl/vhdl/CVS/Entries
new file mode 100644
index 000000000..2a33278f7
--- /dev/null
+++ b/fpga/usrp2/opencores/i2c/rtl/vhdl/CVS/Entries
@@ -0,0 +1,7 @@
+/I2C.VHD/1.1/Mon Sep 24 12:21:51 2001//
+/i2c_master_bit_ctrl.vhd/1.14/Wed Oct 11 12:10:13 2006//
+/i2c_master_byte_ctrl.vhd/1.5/Wed Feb 18 11:41:48 2004//
+/i2c_master_top.vhd/1.7/Sun Mar 14 10:17:03 2004//
+/readme/1.2/Sat Nov 30 22:25:47 2002//
+/tst_ds1621.vhd/1.1/Mon Sep 24 12:21:51 2001//
+D
diff --git a/fpga/usrp2/opencores/i2c/rtl/vhdl/CVS/Repository b/fpga/usrp2/opencores/i2c/rtl/vhdl/CVS/Repository
new file mode 100644
index 000000000..c210ff4e3
--- /dev/null
+++ b/fpga/usrp2/opencores/i2c/rtl/vhdl/CVS/Repository
@@ -0,0 +1 @@
+i2c/rtl/vhdl
diff --git a/fpga/usrp2/opencores/i2c/rtl/vhdl/CVS/Root b/fpga/usrp2/opencores/i2c/rtl/vhdl/CVS/Root
new file mode 100644
index 000000000..44b2aa23b
--- /dev/null
+++ b/fpga/usrp2/opencores/i2c/rtl/vhdl/CVS/Root
@@ -0,0 +1 @@
+:pserver:anonymous@cvs.opencores.org:/cvsroot/anonymous
diff --git a/fpga/usrp2/opencores/i2c/rtl/vhdl/CVS/Template b/fpga/usrp2/opencores/i2c/rtl/vhdl/CVS/Template
new file mode 100644
index 000000000..e69de29bb
diff --git a/fpga/usrp2/opencores/i2c/rtl/vhdl/I2C.VHD b/fpga/usrp2/opencores/i2c/rtl/vhdl/I2C.VHD
new file mode 100644
index 000000000..64d1eb656
--- /dev/null
+++ b/fpga/usrp2/opencores/i2c/rtl/vhdl/I2C.VHD
@@ -0,0 +1,620 @@
+--
+-- Simple I2C controller
+--
+-- 1) No multimaster
+-- 2) No slave mode
+-- 3) No fifo's
+--
+-- notes:
+-- Every command is acknowledged. Do not set a new command before previous is acknowledged.
+-- Dout is available 1 clock cycle later as cmd_ack
+--
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_arith.all;
+
+package I2C is
+	component simple_i2c is
+	port (
+		clk : in std_logic;
+		ena : in std_logic;
+		nReset : in std_logic;
+
+		clk_cnt : in unsigned(7 downto 0);	-- 4x SCL 
+
+		-- input signals
+		start,
+		stop,
+		read,
+		write,
+		ack_in : std_logic;
+		Din : in std_logic_vector(7 downto 0);
+
+		-- output signals
+		cmd_ack : out std_logic;
+		ack_out : out std_logic;
+		Dout : out std_logic_vector(7 downto 0);
+
+		-- i2c signals
+		SCL : inout std_logic;
+		SDA : inout std_logic
+	);
+	end component simple_i2c;
+end package I2C;
+
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_arith.all;
+
+entity simple_i2c is
+	port (
+		clk : in std_logic;
+		ena : in std_logic;
+		nReset : in std_logic;
+
+		clk_cnt : in unsigned(7 downto 0);	-- 4x SCL 
+
+		-- input signals
+		start,
+		stop,
+		read,
+		write,
+		ack_in : std_logic;
+		Din : in std_logic_vector(7 downto 0);
+
+		-- output signals
+		cmd_ack : out std_logic;
+		ack_out : out std_logic;
+		Dout : out std_logic_vector(7 downto 0);
+
+		-- i2c signals
+		SCL : inout std_logic;
+		SDA : inout std_logic
+	);
+end entity simple_i2c;
+
+architecture structural of simple_i2c is
+	component i2c_core is
+	port (
+		clk : in std_logic;
+		nReset : in std_logic;
+
+		clk_cnt : in unsigned(7 downto 0);
+
+		cmd : in std_logic_vector(2 downto 0);
+		cmd_ack : out std_logic;
+		busy : out std_logic;
+
+		Din : in std_logic;
+		Dout : out std_logic;
+
+		SCL : inout std_logic;
+		SDA : inout std_logic
+	);
+	end component i2c_core;
+
+	-- commands for i2c_core
+	constant CMD_NOP	: std_logic_vector(2 downto 0) := "000";
+	constant CMD_START	: std_logic_vector(2 downto 0) := "010";
+	constant CMD_STOP	: std_logic_vector(2 downto 0) := "011";
+	constant CMD_READ	: std_logic_vector(2 downto 0) := "100";
+	constant CMD_WRITE	: std_logic_vector(2 downto 0) := "101";
+
+	-- signals for i2c_core
+	signal core_cmd : std_logic_vector(2 downto 0);
+	signal core_ack, core_busy, core_txd, core_rxd : std_logic;
+
+	-- signals for shift register
+	signal sr : std_logic_vector(7 downto 0); -- 8bit shift register
+	signal shift, ld : std_logic;
+
+	-- signals for state machine
+	signal go, host_ack : std_logic;
+begin
+	-- hookup i2c core
+	u1: i2c_core port map (clk, nReset, clk_cnt, core_cmd, core_ack, core_busy, core_txd, core_rxd, SCL, SDA);
+
+	-- generate host-command-acknowledge
+	cmd_ack <= host_ack;
+	
+	-- generate go-signal
+	go <= (read or write) and not host_ack;
+
+	-- assign Dout output to shift-register
+	Dout <= sr;
+
+	-- assign ack_out output to core_rxd (contains last received bit)
+	ack_out <= core_rxd;
+
+	-- generate shift register
+	shift_register: process(clk)
+	begin
+		if (clk'event and clk = '1') then
+			if (ld = '1') then
+				sr <= din;
+			elsif (shift = '1') then
+				sr <= (sr(6 downto 0) & core_rxd);
+			end if;
+		end if;
+	end process shift_register;
+
+	--
+	-- state machine
+	--
+	statemachine : block
+		type states is (st_idle, st_start, st_read, st_write, st_ack, st_stop);
+		signal state : states;
+		signal dcnt : unsigned(2 downto 0);
+	begin
+		--
+		-- command interpreter, translate complex commands into simpler I2C commands
+		--
+		nxt_state_decoder: process(clk, nReset, state)
+			variable nxt_state : states;
+			variable idcnt : unsigned(2 downto 0);
+			variable ihost_ack : std_logic;
+			variable icore_cmd : std_logic_vector(2 downto 0);
+			variable icore_txd : std_logic;
+			variable ishift, iload : std_logic;
+		begin
+			-- 8 databits (1byte) of data to shift-in/out
+			idcnt := dcnt;
+
+			-- no acknowledge (until command complete)
+			ihost_ack := '0';
+
+			icore_txd := core_txd;
+
+			-- keep current command to i2c_core
+			icore_cmd := core_cmd;
+
+			-- no shifting or loading of shift-register
+			ishift := '0';
+			iload := '0';
+
+			-- keep current state;
+			nxt_state := state;
+			case state is
+				when st_idle =>
+					if (go = '1') then
+						if (start = '1') then
+							nxt_state := st_start;	
+							icore_cmd := CMD_START;
+						elsif (read = '1') then
+							nxt_state := st_read;
+							icore_cmd := CMD_READ;
+							idcnt := "111";
+						else
+							nxt_state := st_write;
+							icore_cmd := CMD_WRITE;
+							idcnt := "111";
+							iload := '1';
+						end if;
+					end if;
+
+				when st_start =>
+					if (core_ack = '1') then
+						if (read = '1') then
+							nxt_state := st_read;
+							icore_cmd := CMD_READ;
+							idcnt := "111";
+						else
+							nxt_state := st_write;
+							icore_cmd := CMD_WRITE;
+							idcnt := "111";
+							iload := '1';
+						end if;
+					end if;
+
+				when st_write =>
+					if (core_ack = '1') then
+						idcnt := dcnt -1;	-- count down Data_counter
+						icore_txd := sr(7);
+						if (dcnt = 0) then
+							nxt_state := st_ack;
+							icore_cmd := CMD_READ;
+						else
+							ishift := '1';
+--							icore_txd := sr(7);
+						end if;
+					end if;			
+
+				when st_read =>
+					if (core_ack = '1') then
+						idcnt := dcnt -1;	-- count down Data_counter
+						ishift := '1';
+						if (dcnt = 0) then
+							nxt_state := st_ack;
+							icore_cmd := CMD_WRITE;
+							icore_txd := ack_in;
+						end if;
+					end if;			
+
+				when st_ack =>
+					if (core_ack = '1') then
+						-- generate command acknowledge signal
+						ihost_ack := '1';
+
+						-- Perform an additional shift, needed for 'read' (store last received bit in shift register)
+						ishift := '1';
+
+						-- check for stop; Should a STOP command be generated ?
+						if (stop = '1') then
+							nxt_state := st_stop;
+							icore_cmd := CMD_STOP;
+						else
+							nxt_state := st_idle;
+							icore_cmd := CMD_NOP;
+						end if;
+					end if;
+
+				when st_stop =>
+					if (core_ack = '1') then
+						nxt_state := st_idle;
+						icore_cmd := CMD_NOP;
+					end if;
+
+				when others => -- illegal states
+					nxt_state := st_idle;
+					icore_cmd := CMD_NOP;
+			end case;
+
+			-- generate registers
+			if (nReset = '0') then
+				core_cmd <= CMD_NOP;
+				core_txd <= '0';
+				
+				shift <= '0';
+				ld <= '0';
+
+				dcnt <= "111";
+				host_ack <= '0';
+
+				state <= st_idle;
+			elsif (clk'event and clk = '1') then
+				if (ena = '1') then
+					state <= nxt_state;
+
+					dcnt <= idcnt;
+					shift <= ishift;
+					ld <= iload;
+
+					core_cmd <= icore_cmd;
+					core_txd <= icore_txd;
+
+					host_ack <= ihost_ack;
+				end if;
+			end if;
+		end process nxt_state_decoder;
+
+	end block statemachine;
+
+end architecture structural;
+
+
+--
+--
+-- I2C Core
+--
+-- Translate simple commands into SCL/SDA transitions
+-- Each command has 5 states, A/B/C/D/idle
+--
+-- start:	SCL	~~~~~~~~~~\____
+--	SDA	~~~~~~~~\______
+--		 x | A | B | C | D | i
+--
+-- repstart	SCL	____/~~~~\___
+--	SDA	__/~~~\______
+--		 x | A | B | C | D | i
+--
+-- stop	SCL	____/~~~~~~~~
+--	SDA	==\____/~~~~~
+--		 x | A | B | C | D | i
+--
+--- write	SCL	____/~~~~\____
+--	SDA	==X=========X=
+--		 x | A | B | C | D | i
+--
+--- read	SCL	____/~~~~\____
+--	SDA	XXXX=====XXXX
+--		 x | A | B | C | D | i
+--
+
+-- Timing:		Normal mode	Fast mode
+-----------------------------------------------------------------
+-- Fscl		100KHz		400KHz
+-- Th_scl		4.0us		0.6us	High period of SCL
+-- Tl_scl		4.7us		1.3us	Low period of SCL
+-- Tsu:sta		4.7us		0.6us	setup time for a repeated start condition
+-- Tsu:sto		4.0us		0.6us	setup time for a stop conditon
+-- Tbuf		4.7us		1.3us	Bus free time between a stop and start condition
+--
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_arith.all;
+
+entity i2c_core is
+	port (
+		clk : in std_logic;
+		nReset : in std_logic;
+
+		clk_cnt : in unsigned(7 downto 0);
+
+		cmd : in std_logic_vector(2 downto 0);
+		cmd_ack : out std_logic;
+		busy : out std_logic;
+
+		Din : in std_logic;
+		Dout : out std_logic;
+
+		SCL : inout std_logic;
+		SDA : inout std_logic
+	);
+end entity i2c_core;
+
+architecture structural of i2c_core is
+	constant CMD_NOP	: std_logic_vector(2 downto 0) := "000";
+	constant CMD_START	: std_logic_vector(2 downto 0) := "010";
+	constant CMD_STOP	: std_logic_vector(2 downto 0) := "011";
+	constant CMD_READ	: std_logic_vector(2 downto 0) := "100";
+	constant CMD_WRITE	: std_logic_vector(2 downto 0) := "101";
+
+	type cmds is (idle, start_a, start_b, start_c, start_d, stop_a, stop_b, stop_c, rd_a, rd_b, rd_c, rd_d, wr_a, wr_b, wr_c, wr_d);
+	signal state : cmds;
+	signal SDAo, SCLo : std_logic;
+	signal txd : std_logic;
+	signal clk_en, slave_wait :std_logic;
+	signal cnt : unsigned(7 downto 0) := clk_cnt;
+begin
+	-- whenever the slave is not ready it can delay the cycle by pulling SCL low
+	slave_wait <= '1' when ((SCLo = '1') and (SCL = '0')) else '0';
+
+	-- generate clk enable signal
+	gen_clken: process(clk, nReset)
+	begin
+		if (nReset = '0') then
+			cnt <= (others => '0');
+			clk_en <= '1'; --'0';
+		elsif (clk'event and clk = '1') then
+			if (cnt = 0) then
+				clk_en <= '1';
+				cnt <= clk_cnt;
+			else
+				if (slave_wait = '0') then
+					cnt <= cnt -1;
+				end if;
+				clk_en <= '0';
+			end if;
+		end if;
+	end process gen_clken;
+
+	-- generate statemachine
+	nxt_state_decoder : process (clk, nReset, state, cmd, SDA)
+		variable nxt_state : cmds;
+		variable icmd_ack, ibusy, store_sda : std_logic;
+		variable itxd : std_logic;
+	begin
+
+		nxt_state := state;
+
+		icmd_ack := '0'; -- default no acknowledge
+		ibusy := '1'; -- default busy
+
+		store_sda := '0';
+
+		itxd := txd;
+
+		case (state) is
+			-- idle
+			when idle =>
+				case cmd is
+					when CMD_START =>
+						nxt_state := start_a;
+						icmd_ack := '1'; -- command completed
+
+					when CMD_STOP =>
+						nxt_state := stop_a;
+						icmd_ack := '1'; -- command completed
+
+					when CMD_WRITE =>
+						nxt_state := wr_a;
+						icmd_ack := '1'; -- command completed
+						itxd := Din;
+
+					when CMD_READ =>
+						nxt_state := rd_a;
+						icmd_ack := '1'; -- command completed
+
+					when others =>
+						nxt_state := idle;
+-- don't acknowledge NOP command						icmd_ack := '1'; -- command completed
+						ibusy := '0';
+				end case;
+
+			-- start
+			when start_a =>
+				nxt_state := start_b;
+
+			when start_b =>
+				nxt_state := start_c;
+
+			when start_c =>
+				nxt_state := start_d;
+
+			when start_d =>
+				nxt_state := idle;
+				ibusy := '0'; -- not busy when idle
+
+
+			-- stop
+			when stop_a =>
+				nxt_state := stop_b;
+
+			when stop_b =>
+				nxt_state := stop_c;
+
+			when stop_c =>
+--				nxt_state := stop_d;
+
+--			when stop_d =>
+				nxt_state := idle;
+				ibusy := '0'; -- not busy when idle
+
+			-- read
+			when rd_a =>
+				nxt_state := rd_b;
+
+			when rd_b =>
+				nxt_state := rd_c;
+
+			when rd_c =>
+				nxt_state := rd_d;
+				store_sda := '1';
+
+			when rd_d =>
+				nxt_state := idle;
+				ibusy := '0'; -- not busy when idle
+
+			-- write
+			when wr_a =>
+				nxt_state := wr_b;
+
+			when wr_b =>
+				nxt_state := wr_c;
+
+			when wr_c =>
+				nxt_state := wr_d;
+
+			when wr_d =>
+				nxt_state := idle;
+				ibusy := '0'; -- not busy when idle
+
+		end case;
+
+		-- generate regs
+		if (nReset = '0') then
+			state <= idle;
+			cmd_ack <= '0';
+			busy <= '0';
+			txd <= '0';
+			Dout <= '0';
+		elsif (clk'event and clk = '1') then
+			if (clk_en = '1') then
+				state <= nxt_state;
+				busy <= ibusy;
+
+				txd <= itxd;
+				if (store_sda = '1') then
+					Dout <= SDA;
+				end if;
+			end if;
+
+			cmd_ack <= icmd_ack and clk_en;
+		end if;
+	end process nxt_state_decoder;
+
+	--
+	-- convert states to SCL and SDA signals
+	--
+	output_decoder: process (clk, nReset, state)
+		variable iscl, isda : std_logic;
+	begin
+		case (state) is
+			when idle =>
+				iscl := SCLo; -- keep SCL in same state
+				isda := SDA; -- keep SDA in same state
+
+			-- start
+			when start_a =>
+				iscl := SCLo; -- keep SCL in same state (for repeated start)
+				isda := '1'; -- set SDA high
+
+			when start_b =>
+				iscl := '1';	-- set SCL high
+				isda := '1'; -- keep SDA high
+
+			when start_c =>
+				iscl := '1';	-- keep SCL high
+				isda := '0'; -- sel SDA low
+
+			when start_d =>
+				iscl := '0'; -- set SCL low
+				isda := '0'; -- keep SDA low
+
+			-- stop
+			when stop_a =>
+				iscl := '0'; -- keep SCL disabled
+				isda := '0'; -- set SDA low
+
+			when stop_b =>
+				iscl := '1'; -- set SCL high
+				isda := '0'; -- keep SDA low
+
+			when stop_c =>
+				iscl := '1'; -- keep SCL high
+				isda := '1'; -- set SDA high
+
+			-- write
+			when wr_a =>
+				iscl := '0';	-- keep SCL low
+--				isda := txd; -- set SDA
+				isda := Din;
+
+			when wr_b =>
+				iscl := '1';	-- set SCL high
+--				isda := txd; -- set SDA
+				isda := Din;
+
+			when wr_c =>
+				iscl := '1';	-- keep SCL high
+--				isda := txd; -- set SDA
+				isda := Din;
+
+			when wr_d =>
+				iscl := '0'; -- set SCL low
+--				isda := txd; -- set SDA
+				isda := Din;
+
+			-- read
+			when rd_a =>
+				iscl := '0'; -- keep SCL low
+				isda := '1'; -- tri-state SDA
+
+			when rd_b =>
+				iscl := '1'; -- set SCL high
+				isda := '1'; -- tri-state SDA
+
+			when rd_c =>
+				iscl := '1'; -- keep SCL high
+				isda := '1'; -- tri-state SDA
+
+			when rd_d =>
+				iscl := '0'; -- set SCL low
+				isda := '1'; -- tri-state SDA
+		end case;
+
+		-- generate registers
+		if (nReset = '0') then
+			SCLo <= '1';
+			SDAo <= '1';
+		elsif (clk'event and clk = '1') then
+			if (clk_en = '1') then
+				SCLo <= iscl;
+				SDAo <= isda;
+			end if;
+		end if;
+	end process output_decoder;
+
+	SCL <= '0' when (SCLo = '0') else 'Z'; -- since SCL is externally pulled-up convert a '1' to a 'Z'(tri-state)
+	SDA <= '0' when (SDAo = '0') else 'Z'; -- since SDA is externally pulled-up convert a '1' to a 'Z'(tri-state)
+--	SCL <= SCLo;
+--	SDA <= SDAo;
+
+end architecture structural;
+
+
+
+
diff --git a/fpga/usrp2/opencores/i2c/rtl/vhdl/i2c_master_bit_ctrl.vhd b/fpga/usrp2/opencores/i2c/rtl/vhdl/i2c_master_bit_ctrl.vhd
new file mode 100644
index 000000000..1b8eb96d2
--- /dev/null
+++ b/fpga/usrp2/opencores/i2c/rtl/vhdl/i2c_master_bit_ctrl.vhd
@@ -0,0 +1,495 @@
+---------------------------------------------------------------------
+----                                                             ----
+----  WISHBONE revB2 I2C Master Core; bit-controller             ----
+----                                                             ----
+----                                                             ----
+----  Author: Richard Herveille                                  ----
+----          richard@asics.ws                                   ----
+----          www.asics.ws                                       ----
+----                                                             ----
+----  Downloaded from: http://www.opencores.org/projects/i2c/    ----
+----                                                             ----
+---------------------------------------------------------------------
+----                                                             ----
+---- Copyright (C) 2000 Richard Herveille                        ----
+----                    richard@asics.ws                         ----
+----                                                             ----
+---- This source file may be used and distributed without        ----
+---- restriction provided that this copyright statement is not   ----
+---- removed from the file and that any derivative work contains ----
+---- the original copyright notice and the associated disclaimer.----
+----                                                             ----
+----     THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY     ----
+---- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   ----
+---- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   ----
+---- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      ----
+---- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         ----
+---- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    ----
+---- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   ----
+---- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        ----
+---- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  ----
+---- LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  ----
+---- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  ----
+---- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         ----
+---- POSSIBILITY OF SUCH DAMAGE.                                 ----
+----                                                             ----
+---------------------------------------------------------------------
+
+--  CVS Log
+--
+--  $Id: i2c_master_bit_ctrl.vhd,v 1.14 2006/10/11 12:10:13 rherveille Exp $
+--
+--  $Date: 2006/10/11 12:10:13 $
+--  $Revision: 1.14 $
+--  $Author: rherveille $
+--  $Locker:  $
+--  $State: Exp $
+--
+-- Change History:
+--               $Log: i2c_master_bit_ctrl.vhd,v $
+--               Revision 1.14  2006/10/11 12:10:13  rherveille
+--               Added missing semicolons ';' on endif
+--
+--               Revision 1.13  2006/10/06 10:48:24  rherveille
+--               fixed short scl high pulse after clock stretch
+--
+--               Revision 1.12  2004/05/07 11:53:31  rherveille
+--               Fixed previous fix :) Made a variable vs signal mistake.
+--
+--               Revision 1.11  2004/05/07 11:04:00  rherveille
+--               Fixed a bug where the core would signal an arbitration lost (AL bit set), when another master controls the bus and the other master generates a STOP bit.
+--
+--               Revision 1.10  2004/02/27 07:49:43  rherveille
+--               Fixed a bug in the arbitration-lost signal generation. VHDL version only.
+--
+--               Revision 1.9  2003/08/12 14:48:37  rherveille
+--               Forgot an 'end if' :-/
+--
+--               Revision 1.8  2003/08/09 07:01:13  rherveille
+--               Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line.
+--               Fixed a potential bug in the byte controller's host-acknowledge generation.
+--
+--               Revision 1.7  2003/02/05 00:06:02  rherveille
+--               Fixed a bug where the core would trigger an erroneous 'arbitration lost' interrupt after being reset, when the reset pulse width < 3 clk cycles.
+--
+--               Revision 1.6  2003/02/01 02:03:06  rherveille
+--               Fixed a few 'arbitration lost' bugs. VHDL version only.
+--
+--               Revision 1.5  2002/12/26 16:05:47  rherveille
+--               Core is now a Multimaster I2C controller.
+--
+--               Revision 1.4  2002/11/30 22:24:37  rherveille
+--               Cleaned up code
+--
+--               Revision 1.3  2002/10/30 18:09:53  rherveille
+--               Fixed some reported minor start/stop generation timing issuess.
+--
+--               Revision 1.2  2002/06/15 07:37:04  rherveille
+--               Fixed a small timing bug in the bit controller.\nAdded verilog simulation environment.
+--
+--               Revision 1.1  2001/11/05 12:02:33  rherveille
+--               Split i2c_master_core.vhd into separate files for each entity; same layout as verilog version.
+--               Code updated, is now up-to-date to doc. rev.0.4.
+--               Added headers.
+--
+
+
+--
+-------------------------------------
+-- Bit controller section
+------------------------------------
+--
+-- Translate simple commands into SCL/SDA transitions
+-- Each command has 5 states, A/B/C/D/idle
+--
+-- start:    SCL  ~~~~~~~~~~~~~~\____
+--	     SDA  XX/~~~~~~~\______
+--	          x | A | B | C | D | i
+--
+-- repstart  SCL  ______/~~~~~~~\___
+--	     SDA  __/~~~~~~~\______
+--	          x | A | B | C | D | i
+--
+-- stop      SCL  _______/~~~~~~~~~~~
+--	     SDA  ==\___________/~~~~~
+--	          x | A | B | C | D | i
+--
+--- write    SCL  ______/~~~~~~~\____
+--	     SDA  XXX===============XX
+--	          x | A | B | C | D | i
+--
+--- read     SCL  ______/~~~~~~~\____
+--	     SDA  XXXXXXX=XXXXXXXXXXX
+--	          x | A | B | C | D | i
+--
+
+-- Timing:      Normal mode     Fast mode
+-----------------------------------------------------------------
+-- Fscl         100KHz          400KHz
+-- Th_scl       4.0us           0.6us   High period of SCL
+-- Tl_scl       4.7us           1.3us   Low period of SCL
+-- Tsu:sta      4.7us           0.6us   setup time for a repeated start condition
+-- Tsu:sto      4.0us           0.6us   setup time for a stop conditon
+-- Tbuf         4.7us           1.3us   Bus free time between a stop and start condition
+--
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_arith.all;
+
+entity i2c_master_bit_ctrl is
+	port (
+		clk    : in std_logic;
+		rst    : in std_logic;
+		nReset : in std_logic;
+		ena    : in std_logic;				-- core enable signal
+
+		clk_cnt : in unsigned(15 downto 0);		-- clock prescale value
+
+		cmd     : in std_logic_vector(3 downto 0);
+		cmd_ack : out std_logic; -- command completed
+		busy    : out std_logic; -- i2c bus busy
+		al      : out std_logic; -- arbitration lost
+
+		din  : in std_logic;
+		dout : out std_logic;
+
+		-- i2c lines
+		scl_i   : in std_logic;  -- i2c clock line input
+		scl_o   : out std_logic; -- i2c clock line output
+		scl_oen : out std_logic; -- i2c clock line output enable, active low
+		sda_i   : in std_logic;  -- i2c data line input
+		sda_o   : out std_logic; -- i2c data line output
+		sda_oen : out std_logic  -- i2c data line output enable, active low
+	);
+end entity i2c_master_bit_ctrl;
+
+architecture structural of i2c_master_bit_ctrl is
+	constant I2C_CMD_NOP    : std_logic_vector(3 downto 0) := "0000";
+	constant I2C_CMD_START  : std_logic_vector(3 downto 0) := "0001";
+	constant I2C_CMD_STOP   : std_logic_vector(3 downto 0) := "0010";
+	constant I2C_CMD_READ   : std_logic_vector(3 downto 0) := "0100";
+	constant I2C_CMD_WRITE  : std_logic_vector(3 downto 0) := "1000";
+
+	type states is (idle, start_a, start_b, start_c, start_d, start_e,
+	                stop_a, stop_b, stop_c, stop_d, rd_a, rd_b, rd_c, rd_d, wr_a, wr_b, wr_c, wr_d);
+	signal c_state : states;
+
+	signal iscl_oen, isda_oen : std_logic;          -- internal I2C lines
+	signal sda_chk            : std_logic;          -- check SDA status (multi-master arbitration)
+	signal dscl_oen           : std_logic;          -- delayed scl_oen signals
+	signal sSCL, sSDA         : std_logic;          -- synchronized SCL and SDA inputs
+	signal clk_en, slave_wait : std_logic;          -- clock generation signals
+	signal ial                : std_logic;          -- internal arbitration lost signal
+--	signal cnt : unsigned(15 downto 0) := clk_cnt;  -- clock divider counter (simulation)
+	signal cnt : unsigned(15 downto 0);             -- clock divider counter (synthesis)
+
+begin
+	-- whenever the slave is not ready it can delay the cycle by pulling SCL low
+	-- delay scl_oen
+	process (clk)
+	begin
+	    if (clk'event and clk = '1') then
+	      dscl_oen <= iscl_oen;
+	    end if;
+	end process;
+	slave_wait <= dscl_oen and not sSCL;
+
+	-- generate clk enable signal
+	gen_clken: process(clk, nReset)
+	begin
+	    if (nReset = '0') then
+	      cnt    <= (others => '0');
+	      clk_en <= '1';
+	    elsif (clk'event and clk = '1') then
+	      if (rst = '1') then
+	        cnt    <= (others => '0');
+	        clk_en <= '1';
+	      elsif ( (cnt = 0) or (ena = '0') ) then
+	        cnt    <= clk_cnt;
+	        clk_en <= '1';
+	      elsif (slave_wait = '1') then
+	        cnt    <= cnt;
+	        clk_en <= '0';
+	      else
+	        cnt    <= cnt -1;
+	        clk_en <= '0';
+	      end if;
+	    end if;
+	end process gen_clken;
+
+
+	-- generate bus status controller
+	bus_status_ctrl: block
+	  signal dSCL, dSDA          : std_logic;  -- delayes sSCL and sSDA
+	  signal sta_condition       : std_logic;  -- start detected
+	  signal sto_condition       : std_logic;  -- stop detected
+	  signal cmd_stop            : std_logic;  -- STOP command
+	  signal ibusy               : std_logic;  -- internal busy signal
+	begin
+	    -- synchronize SCL and SDA inputs
+	    synch_scl_sda: process(clk, nReset)
+	    begin
+	        if (nReset = '0') then
+	          sSCL <= '1';
+	          sSDA <= '1';
+
+	          dSCL <= '1';
+	          dSDA <= '1';
+	        elsif (clk'event and clk = '1') then
+	          if (rst = '1') then
+	            sSCL <= '1';
+	            sSDA <= '1';
+
+	            dSCL <= '1';
+	            dSDA <= '1';
+	          else
+	            sSCL <= scl_i;
+	            sSDA <= sda_i;
+
+	            dSCL <= sSCL;
+	            dSDA <= sSDA;
+	          end if;
+	        end if;
+	    end process synch_SCL_SDA;
+
+	    -- detect start condition => detect falling edge on SDA while SCL is high
+	    -- detect stop condition  => detect rising edge on SDA while SCL is high
+	    detect_sta_sto: process(clk, nReset)
+	    begin
+	        if (nReset = '0') then
+	          sta_condition <= '0';
+	          sto_condition <= '0';
+	        elsif (clk'event and clk = '1') then
+	          if (rst = '1') then
+	            sta_condition <= '0';
+	            sto_condition <= '0';
+	          else
+	            sta_condition <= (not sSDA and dSDA) and sSCL;
+	            sto_condition <= (sSDA and not dSDA) and sSCL;
+	          end if;
+	        end if;
+	    end process detect_sta_sto;
+
+	    -- generate i2c-bus busy signal
+	    gen_busy: process(clk, nReset)
+	    begin
+	        if (nReset = '0') then
+	          ibusy <= '0';
+	        elsif (clk'event and clk = '1') then
+	          if (rst = '1') then
+	            ibusy <= '0';
+	          else
+	            ibusy <= (sta_condition or ibusy) and not sto_condition;
+	          end if;
+	        end if;
+	    end process gen_busy;
+	    busy <= ibusy;
+
+
+	    -- generate arbitration lost signal
+	    -- aribitration lost when:
+	    -- 1) master drives SDA high, but the i2c bus is low
+	    -- 2) stop detected while not requested (detect during 'idle' state)
+	    gen_al: process(clk, nReset)
+	    begin
+	      if (nReset = '0') then
+	        cmd_stop  <= '0';
+	        ial       <= '0';
+	      elsif (clk'event and clk = '1') then
+	        if (rst = '1') then
+	          cmd_stop  <= '0';
+	          ial       <= '0';
+	        else
+	          if (clk_en = '1') then
+	            if (cmd = I2C_CMD_STOP) then
+	              cmd_stop <= '1';
+	            else
+	              cmd_stop <= '0';
+	            end if;
+	          end if;
+
+	          if (c_state = idle) then
+	            ial <= (sda_chk and not sSDA and isda_oen);
+	          else
+	            ial <= (sda_chk and not sSDA and isda_oen) or (sto_condition and not cmd_stop);
+	          end if;
+
+	        end if;
+	      end if;
+	    end process gen_al;
+	    al <= ial;
+
+	    -- generate dout signal, store dout on rising edge of SCL
+	    gen_dout: process(clk)
+	    begin
+	      if (clk'event and clk = '1') then
+	        if (sSCL = '1' and dSCL = '0') then
+	          dout <= sSDA;
+	        end if;
+	      end if;
+	    end process gen_dout;
+	end block bus_status_ctrl;
+
+
+	-- generate statemachine
+	nxt_state_decoder : process (clk, nReset, c_state, cmd)
+	begin
+	    if (nReset = '0') then
+	      c_state  <= idle;
+	      cmd_ack  <= '0';
+	      iscl_oen <= '1';
+	      isda_oen <= '1';
+	      sda_chk  <= '0';
+	    elsif (clk'event and clk = '1') then
+	      if (rst = '1' or ial = '1') then
+	        c_state  <= idle;
+	        cmd_ack  <= '0';
+	        iscl_oen <= '1';
+	        isda_oen <= '1';
+	        sda_chk  <= '0';
+	      else
+	        cmd_ack <= '0'; -- default no acknowledge
+
+	        if (clk_en = '1') then
+	          case (c_state) is
+	             -- idle
+	             when idle =>
+	                case cmd is
+	                  when I2C_CMD_START => c_state <= start_a;
+	                  when I2C_CMD_STOP  => c_state <= stop_a;
+	                  when I2C_CMD_WRITE => c_state <= wr_a;
+	                  when I2C_CMD_READ  => c_state <= rd_a;
+	                  when others        => c_state <= idle; -- NOP command
+	                end case;
+
+	                iscl_oen <= iscl_oen; -- keep SCL in same state
+	                isda_oen <= isda_oen; -- keep SDA in same state
+	                sda_chk  <= '0';      -- don't check SDA
+
+	             -- start
+	             when start_a =>
+	                c_state  <= start_b;
+	                iscl_oen <= iscl_oen; -- keep SCL in same state (for repeated start)
+	                isda_oen <= '1';      -- set SDA high
+	                sda_chk  <= '0';      -- don't check SDA
+
+	             when start_b =>
+	                c_state  <= start_c;
+	                iscl_oen <= '1'; -- set SCL high
+	                isda_oen <= '1'; -- keep SDA high
+	                sda_chk  <= '0'; -- don't check SDA
+
+	             when start_c =>
+	                c_state  <= start_d;
+	                iscl_oen <= '1'; -- keep SCL high
+	                isda_oen <= '0'; -- set SDA low
+	                sda_chk  <= '0'; -- don't check SDA
+
+	             when start_d =>
+	                c_state  <= start_e;
+	                iscl_oen <= '1'; -- keep SCL high
+	                isda_oen <= '0'; -- keep SDA low
+	                sda_chk  <= '0'; -- don't check SDA
+
+	             when start_e =>
+	                c_state  <= idle;
+	                cmd_ack  <= '1'; -- command completed
+	                iscl_oen <= '0'; -- set SCL low
+	                isda_oen <= '0'; -- keep SDA low
+	                sda_chk  <= '0'; -- don't check SDA
+
+	             -- stop
+	             when stop_a =>
+	                c_state  <= stop_b;
+	                iscl_oen <= '0'; -- keep SCL low
+	                isda_oen <= '0'; -- set SDA low
+	                sda_chk  <= '0'; -- don't check SDA
+
+	             when stop_b =>
+	                c_state  <= stop_c;
+	                iscl_oen <= '1'; -- set SCL high
+	                isda_oen <= '0'; -- keep SDA low
+	                sda_chk  <= '0'; -- don't check SDA
+
+	             when stop_c =>
+	                c_state  <= stop_d;
+	                iscl_oen <= '1'; -- keep SCL high
+	                isda_oen <= '0'; -- keep SDA low
+	                sda_chk  <= '0'; -- don't check SDA
+
+	             when stop_d =>
+	                c_state  <= idle;
+	                cmd_ack  <= '1'; -- command completed
+	                iscl_oen <= '1'; -- keep SCL high
+	                isda_oen <= '1'; -- set SDA high
+	                sda_chk  <= '0'; -- don't check SDA
+
+	             -- read
+	             when rd_a =>
+	                c_state  <= rd_b;
+	                iscl_oen <= '0'; -- keep SCL low
+	                isda_oen <= '1'; -- tri-state SDA
+	                sda_chk  <= '0'; -- don't check SDA
+
+	             when rd_b =>
+	                c_state  <= rd_c;
+	                iscl_oen <= '1'; -- set SCL high
+	                isda_oen <= '1'; -- tri-state SDA
+	                sda_chk  <= '0'; -- don't check SDA
+
+	             when rd_c =>
+	                c_state  <= rd_d;
+	                iscl_oen <= '1'; -- keep SCL high
+	                isda_oen <= '1'; -- tri-state SDA
+	                sda_chk  <= '0'; -- don't check SDA
+
+	             when rd_d =>
+	                c_state  <= idle;
+	                cmd_ack  <= '1'; -- command completed
+	                iscl_oen <= '0'; -- set SCL low
+	                isda_oen <= '1'; -- tri-state SDA
+	                sda_chk  <= '0'; -- don't check SDA
+
+	             -- write
+	             when wr_a =>
+	                c_state  <= wr_b;
+	                iscl_oen <= '0'; -- keep SCL low
+	                isda_oen <= din; -- set SDA
+	                sda_chk  <= '0'; -- don't check SDA (SCL low)
+
+	             when wr_b =>
+	                c_state  <= wr_c;
+	                iscl_oen <= '1'; -- set SCL high
+	                isda_oen <= din; -- keep SDA
+	                sda_chk  <= '1'; -- check SDA
+
+	             when wr_c =>
+	                c_state  <= wr_d;
+	                iscl_oen <= '1'; -- keep SCL high
+	                isda_oen <= din; -- keep SDA
+	                sda_chk  <= '1'; -- check SDA
+
+	             when wr_d =>
+	                c_state  <= idle;
+	                cmd_ack  <= '1'; -- command completed
+	                iscl_oen <= '0'; -- set SCL low
+	                isda_oen <= din; -- keep SDA
+	                sda_chk  <= '0'; -- don't check SDA (SCL low)
+
+	             when others =>
+
+	          end case;
+	        end if;
+	      end if;
+	    end if;
+	end process nxt_state_decoder;
+
+
+	-- assign outputs
+	scl_o   <= '0';
+	scl_oen <= iscl_oen;
+	sda_o   <= '0';
+	sda_oen <= isda_oen;
+end architecture structural;
+
diff --git a/fpga/usrp2/opencores/i2c/rtl/vhdl/i2c_master_byte_ctrl.vhd b/fpga/usrp2/opencores/i2c/rtl/vhdl/i2c_master_byte_ctrl.vhd
new file mode 100644
index 000000000..bdb2a881e
--- /dev/null
+++ b/fpga/usrp2/opencores/i2c/rtl/vhdl/i2c_master_byte_ctrl.vhd
@@ -0,0 +1,370 @@
+---------------------------------------------------------------------
+----                                                             ----
+----  WISHBONE revB2 compl. I2C Master Core; byte-controller     ----
+----                                                             ----
+----                                                             ----
+----  Author: Richard Herveille                                  ----
+----          richard@asics.ws                                   ----
+----          www.asics.ws                                       ----
+----                                                             ----
+----  Downloaded from: http://www.opencores.org/projects/i2c/    ----
+----                                                             ----
+---------------------------------------------------------------------
+----                                                             ----
+---- Copyright (C) 2000 Richard Herveille                        ----
+----                    richard@asics.ws                         ----
+----                                                             ----
+---- This source file may be used and distributed without        ----
+---- restriction provided that this copyright statement is not   ----
+---- removed from the file and that any derivative work contains ----
+---- the original copyright notice and the associated disclaimer.----
+----                                                             ----
+----     THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY     ----
+---- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   ----
+---- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   ----
+---- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      ----
+---- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         ----
+---- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    ----
+---- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   ----
+---- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        ----
+---- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  ----
+---- LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  ----
+---- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  ----
+---- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         ----
+---- POSSIBILITY OF SUCH DAMAGE.                                 ----
+----                                                             ----
+---------------------------------------------------------------------
+
+--  CVS Log
+--
+--  $Id: i2c_master_byte_ctrl.vhd,v 1.5 2004/02/18 11:41:48 rherveille Exp $
+--
+--  $Date: 2004/02/18 11:41:48 $
+--  $Revision: 1.5 $
+--  $Author: rherveille $
+--  $Locker:  $
+--  $State: Exp $
+--
+-- Change History:
+--               $Log: i2c_master_byte_ctrl.vhd,v $
+--               Revision 1.5  2004/02/18 11:41:48  rherveille
+--               Fixed a potential bug in the statemachine. During a 'stop' 2 cmd_ack signals were generated. Possibly canceling a new start command.
+--
+--               Revision 1.4  2003/08/09 07:01:13  rherveille
+--               Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line.
+--               Fixed a potential bug in the byte controller's host-acknowledge generation.
+--
+--               Revision 1.3  2002/12/26 16:05:47  rherveille
+--               Core is now a Multimaster I2C controller.
+--
+--               Revision 1.2  2002/11/30 22:24:37  rherveille
+--               Cleaned up code
+--
+--               Revision 1.1  2001/11/05 12:02:33  rherveille
+--               Split i2c_master_core.vhd into separate files for each entity; same layout as verilog version.
+--               Code updated, is now up-to-date to doc. rev.0.4.
+--               Added headers.
+--
+
+
+
+
+--
+------------------------------------------
+-- Byte controller section
+------------------------------------------
+--
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_arith.all;
+
+entity i2c_master_byte_ctrl is
+	port (
+		clk    : in std_logic;
+		rst    : in std_logic; -- synchronous active high reset (WISHBONE compatible)
+		nReset : in std_logic;	-- asynchornous active low reset (FPGA compatible)
+		ena    : in std_logic; -- core enable signal
+
+		clk_cnt : in unsigned(15 downto 0);	-- 4x SCL
+
+		-- input signals
+		start,
+		stop,
+		read,
+		write,
+		ack_in : std_logic;
+		din    : in std_logic_vector(7 downto 0);
+
+		-- output signals
+		cmd_ack  : out std_logic; -- command done
+		ack_out  : out std_logic;
+		i2c_busy : out std_logic; -- arbitration lost
+		i2c_al   : out std_logic; -- i2c bus busy
+		dout     : out std_logic_vector(7 downto 0);
+
+		-- i2c lines
+		scl_i   : in std_logic;  -- i2c clock line input
+		scl_o   : out std_logic; -- i2c clock line output
+		scl_oen : out std_logic; -- i2c clock line output enable, active low
+		sda_i   : in std_logic;  -- i2c data line input
+		sda_o   : out std_logic; -- i2c data line output
+		sda_oen : out std_logic  -- i2c data line output enable, active low
+	);
+end entity i2c_master_byte_ctrl;
+
+architecture structural of i2c_master_byte_ctrl is
+	component i2c_master_bit_ctrl is
+	port (
+		clk    : in std_logic;
+		rst    : in std_logic;
+		nReset : in std_logic;
+		ena    : in std_logic;				-- core enable signal
+
+		clk_cnt : in unsigned(15 downto 0);		-- clock prescale value
+
+		cmd     : in std_logic_vector(3 downto 0);
+		cmd_ack : out std_logic; -- command done
+		busy    : out std_logic; -- i2c bus busy
+		al      : out std_logic; -- arbitration lost
+
+		din  : in std_logic;
+		dout : out std_logic;
+
+		-- i2c lines
+		scl_i   : in std_logic;  -- i2c clock line input
+		scl_o   : out std_logic; -- i2c clock line output
+		scl_oen : out std_logic; -- i2c clock line output enable, active low
+		sda_i   : in std_logic;  -- i2c data line input
+		sda_o   : out std_logic; -- i2c data line output
+		sda_oen : out std_logic  -- i2c data line output enable, active low
+	);
+	end component i2c_master_bit_ctrl;
+
+	-- commands for bit_controller block
+	constant I2C_CMD_NOP  	: std_logic_vector(3 downto 0) := "0000";
+	constant I2C_CMD_START	: std_logic_vector(3 downto 0) := "0001";
+	constant I2C_CMD_STOP	 : std_logic_vector(3 downto 0) := "0010";
+	constant I2C_CMD_READ	 : std_logic_vector(3 downto 0) := "0100";
+	constant I2C_CMD_WRITE	: std_logic_vector(3 downto 0) := "1000";
+
+	-- signals for bit_controller
+	signal core_cmd : std_logic_vector(3 downto 0);
+	signal core_ack, core_txd, core_rxd : std_logic;
+	signal al : std_logic;
+
+	-- signals for shift register
+	signal sr : std_logic_vector(7 downto 0); -- 8bit shift register
+	signal shift, ld : std_logic;
+
+	-- signals for state machine
+	signal go, host_ack : std_logic;
+	signal dcnt : unsigned(2 downto 0); -- data counter
+	signal cnt_done : std_logic;
+
+begin
+	-- hookup bit_controller
+	bit_ctrl: i2c_master_bit_ctrl port map(
+		clk     => clk,
+		rst     => rst,
+		nReset  => nReset,
+		ena     => ena,
+		clk_cnt => clk_cnt,
+		cmd     => core_cmd,
+		cmd_ack => core_ack,
+		busy    => i2c_busy,
+		al      => al,
+		din     => core_txd,
+		dout    => core_rxd,
+		scl_i   => scl_i,
+		scl_o   => scl_o,
+		scl_oen => scl_oen,
+		sda_i   => sda_i,
+		sda_o   => sda_o,
+		sda_oen => sda_oen
+	);
+	i2c_al <= al;
+
+	-- generate host-command-acknowledge
+	cmd_ack <= host_ack;
+
+	-- generate go-signal
+	go <= (read or write or stop) and not host_ack;
+
+	-- assign Dout output to shift-register
+	dout <= sr;
+
+	-- generate shift register
+	shift_register: process(clk, nReset)
+	begin
+	    if (nReset = '0') then
+	      sr <= (others => '0');
+	    elsif (clk'event and clk = '1') then
+	      if (rst = '1') then
+	        sr <= (others => '0');
+	      elsif (ld = '1') then
+	        sr <= din;
+	      elsif (shift = '1') then
+	        sr <= (sr(6 downto 0) & core_rxd);
+	      end if;
+	    end if;
+	end process shift_register;
+
+	-- generate data-counter
+	data_cnt: process(clk, nReset)
+	begin
+	    if (nReset = '0') then
+	      dcnt <= (others => '0');
+	    elsif (clk'event and clk = '1') then
+	      if (rst = '1') then
+	        dcnt <= (others => '0');
+	      elsif (ld = '1') then
+	        dcnt <= (others => '1');  -- load counter with 7
+	      elsif (shift = '1') then
+	        dcnt <= dcnt -1;
+	      end if;
+	    end if;
+	end process data_cnt;
+
+	cnt_done <= '1' when (dcnt = 0) else '0';
+
+	--
+	-- state machine
+	--
+	statemachine : block
+	    type states is (st_idle, st_start, st_read, st_write, st_ack, st_stop);
+	    signal c_state : states;
+	begin
+	    --
+	    -- command interpreter, translate complex commands into simpler I2C commands
+	    --
+	    nxt_state_decoder: process(clk, nReset)
+	    begin
+	        if (nReset = '0') then
+	          core_cmd <= I2C_CMD_NOP;
+	          core_txd <= '0';
+	          shift    <= '0';
+	          ld       <= '0';
+	          host_ack <= '0';
+	          c_state  <= st_idle;
+	          ack_out  <= '0';
+	        elsif (clk'event and clk = '1') then
+	          if (rst = '1' or al = '1') then
+	            core_cmd <= I2C_CMD_NOP;
+	            core_txd <= '0';
+	            shift    <= '0';
+	            ld       <= '0';
+	            host_ack <= '0';
+	            c_state  <= st_idle;
+	            ack_out  <= '0';
+	          else
+	            -- initialy reset all signal
+	            core_txd <= sr(7);
+	            shift    <= '0';
+	            ld       <= '0';
+	            host_ack <= '0';
+
+	            case c_state is
+	              when st_idle =>
+	                 if (go = '1') then
+	                   if (start = '1') then
+	                     c_state  <= st_start;
+	                     core_cmd <= I2C_CMD_START;
+	                   elsif (read = '1') then
+	                     c_state  <= st_read;
+	                     core_cmd <= I2C_CMD_READ;
+	                   elsif (write = '1') then
+	                     c_state  <= st_write;
+	                     core_cmd <= I2C_CMD_WRITE;
+	                   else -- stop
+	                     c_state  <= st_stop;
+	                     core_cmd <= I2C_CMD_STOP;
+	                   end if;
+
+	                   ld <= '1';
+	                 end if;
+
+	              when st_start =>
+	                 if (core_ack = '1') then
+	                   if (read = '1') then
+	                     c_state  <= st_read;
+	                     core_cmd <= I2C_CMD_READ;
+	                   else
+	                     c_state  <= st_write;
+	                     core_cmd <= I2C_CMD_WRITE;
+	                   end if;
+
+	                   ld <= '1';
+	                 end if;
+
+	              when st_write =>
+	                 if (core_ack = '1') then
+	                   if (cnt_done = '1') then
+	                     c_state  <= st_ack;
+	                     core_cmd <= I2C_CMD_READ;
+	                   else
+	                     c_state  <= st_write;       -- stay in same state
+	                     core_cmd <= I2C_CMD_WRITE;  -- write next bit
+	                     shift    <= '1';
+	                   end if;
+	                 end if;
+
+	              when st_read =>
+	                 if (core_ack = '1') then
+	                   if (cnt_done = '1') then
+	                     c_state  <= st_ack;
+	                     core_cmd <= I2C_CMD_WRITE;
+	                   else
+	                     c_state  <= st_read;      -- stay in same state
+	                     core_cmd <= I2C_CMD_READ; -- read next bit
+	                   end if;
+
+	                   shift    <= '1';
+	                   core_txd <= ack_in;
+	                 end if;
+
+	              when st_ack =>
+	                 if (core_ack = '1') then
+	                   -- check for stop; Should a STOP command be generated ?
+	                   if (stop = '1') then
+	                     c_state  <= st_stop;
+	                     core_cmd <= I2C_CMD_STOP;
+	                   else
+	                     c_state  <= st_idle;
+	                     core_cmd <= I2C_CMD_NOP;
+
+	                     -- generate command acknowledge signal
+	                     host_ack <= '1';
+	                   end if;
+
+	                   -- assign ack_out output to core_rxd (contains last received bit)
+	                   ack_out  <= core_rxd;
+
+	                   core_txd <= '1';
+	                 else
+	                   core_txd <= ack_in;
+	                 end if;
+
+	              when st_stop =>
+	                 if (core_ack = '1') then
+	                   c_state  <= st_idle;
+	                   core_cmd <= I2C_CMD_NOP;
+
+	                   -- generate command acknowledge signal
+	                   host_ack <= '1';
+	                 end if;
+
+	              when others => -- illegal states
+	                 c_state  <= st_idle;
+	                 core_cmd <= I2C_CMD_NOP;
+	                 report ("Byte controller entered illegal state.");
+
+	            end case;
+
+	          end if;
+	        end if;
+	    end process nxt_state_decoder;
+
+	end block statemachine;
+
+end architecture structural;
+
diff --git a/fpga/usrp2/opencores/i2c/rtl/vhdl/i2c_master_top.vhd b/fpga/usrp2/opencores/i2c/rtl/vhdl/i2c_master_top.vhd
new file mode 100644
index 000000000..a2557120f
--- /dev/null
+++ b/fpga/usrp2/opencores/i2c/rtl/vhdl/i2c_master_top.vhd
@@ -0,0 +1,359 @@
+---------------------------------------------------------------------
+----                                                             ----
+----  WISHBONE revB2 compl. I2C Master Core; top level           ----
+----                                                             ----
+----                                                             ----
+----  Author: Richard Herveille                                  ----
+----          richard@asics.ws                                   ----
+----          www.asics.ws                                       ----
+----                                                             ----
+----  Downloaded from: http://www.opencores.org/projects/i2c/    ----
+----                                                             ----
+---------------------------------------------------------------------
+----                                                             ----
+---- Copyright (C) 2000 Richard Herveille                        ----
+----                    richard@asics.ws                         ----
+----                                                             ----
+---- This source file may be used and distributed without        ----
+---- restriction provided that this copyright statement is not   ----
+---- removed from the file and that any derivative work contains ----
+---- the original copyright notice and the associated disclaimer.----
+----                                                             ----
+----     THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY     ----
+---- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   ----
+---- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   ----
+---- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      ----
+---- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         ----
+---- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    ----
+---- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   ----
+---- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        ----
+---- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  ----
+---- LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  ----
+---- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  ----
+---- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         ----
+---- POSSIBILITY OF SUCH DAMAGE.                                 ----
+----                                                             ----
+---------------------------------------------------------------------
+
+--  CVS Log
+--
+--  $Id: i2c_master_top.vhd,v 1.7 2004/03/14 10:17:03 rherveille Exp $
+--
+--  $Date: 2004/03/14 10:17:03 $
+--  $Revision: 1.7 $
+--  $Author: rherveille $
+--  $Locker:  $
+--  $State: Exp $
+--
+-- Change History:
+--               $Log: i2c_master_top.vhd,v $
+--               Revision 1.7  2004/03/14 10:17:03  rherveille
+--               Fixed simulation issue when writing to CR register
+--
+--               Revision 1.6  2003/08/09 07:01:13  rherveille
+--               Fixed a bug in the Arbitration Lost generation caused by delay on the (external) sda line.
+--               Fixed a potential bug in the byte controller's host-acknowledge generation.
+--
+--               Revision 1.5  2003/02/01 02:03:06  rherveille
+--               Fixed a few 'arbitration lost' bugs. VHDL version only.
+--
+--               Revision 1.4  2002/12/26 16:05:47  rherveille
+--               Core is now a Multimaster I2C controller.
+--
+--               Revision 1.3  2002/11/30 22:24:37  rherveille
+--               Cleaned up code
+--
+--               Revision 1.2  2001/11/10 10:52:44  rherveille
+--               Changed PRER reset value from 0x0000 to 0xffff, conform specs.
+--
+
+
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_arith.all;
+
+entity i2c_master_top is
+	generic(
+		ARST_LVL : std_logic := '0'                   -- asynchronous reset level
+	);
+	port (
+		-- wishbone signals
+		wb_clk_i  : in  std_logic;                    -- master clock input
+		wb_rst_i  : in  std_logic := '0';             -- synchronous active high reset
+		arst_i    : in  std_logic := not ARST_LVL;    -- asynchronous reset
+		wb_adr_i  : in  unsigned(2 downto 0);         -- lower address bits
+		wb_dat_i  : in  std_logic_vector(7 downto 0); -- Databus input
+		wb_dat_o  : out std_logic_vector(7 downto 0); -- Databus output
+		wb_we_i   : in  std_logic;	              -- Write enable input
+		wb_stb_i  : in  std_logic;                    -- Strobe signals / core select signal
+		wb_cyc_i  : in  std_logic;	              -- Valid bus cycle input
+		wb_ack_o  : out std_logic;                    -- Bus cycle acknowledge output
+		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
+	);
+end entity i2c_master_top;
+
+architecture structural of i2c_master_top is
+	component i2c_master_byte_ctrl is
+	port (
+		clk    : in std_logic;
+		rst    : in std_logic; -- synchronous active high reset (WISHBONE compatible)
+		nReset : in std_logic;	-- asynchornous active low reset (FPGA compatible)
+		ena    : in std_logic; -- core enable signal
+
+		clk_cnt : in unsigned(15 downto 0);	-- 4x SCL
+
+		-- input signals
+		start,
+		stop,
+		read,
+		write,
+		ack_in : std_logic;
+		din    : in std_logic_vector(7 downto 0);
+
+		-- output signals
+		cmd_ack  : out std_logic;
+		ack_out  : out std_logic;
+		i2c_busy : out std_logic;
+		i2c_al   : out std_logic;
+		dout     : out std_logic_vector(7 downto 0);
+
+		-- i2c lines
+		scl_i   : in std_logic;  -- i2c clock line input
+		scl_o   : out std_logic; -- i2c clock line output
+		scl_oen : out std_logic; -- i2c clock line output enable, active low
+		sda_i   : in std_logic;  -- i2c data line input
+		sda_o   : out std_logic; -- i2c data line output
+		sda_oen : out std_logic  -- i2c data line output enable, active low
+	);
+	end component i2c_master_byte_ctrl;
+
+	-- registers
+	signal prer : unsigned(15 downto 0);             -- clock prescale register
+	signal ctr  : std_logic_vector(7 downto 0);      -- control register
+	signal txr  : std_logic_vector(7 downto 0);      -- transmit register
+	signal rxr  : std_logic_vector(7 downto 0);      -- receive register
+	signal cr   : std_logic_vector(7 downto 0);      -- command register
+	signal sr   : std_logic_vector(7 downto 0);      -- status register
+
+	-- internal reset signal
+	signal rst_i : std_logic;
+
+	-- wishbone write access
+	signal wb_wacc : std_logic;
+
+	-- internal acknowledge signal
+	signal iack_o : std_logic;
+
+	-- done signal: command completed, clear command register
+	signal done : std_logic;
+
+	-- command register signals
+	signal sta, sto, rd, wr, ack, iack : std_logic;
+
+	signal core_en : std_logic;                      -- core enable signal
+	signal ien     : std_logic;                      -- interrupt enable signal
+
+	-- status register signals
+	signal irxack, rxack : std_logic;                -- received aknowledge from slave
+	signal tip           : std_logic;                -- transfer in progress
+	signal irq_flag      : std_logic;                -- interrupt pending flag
+	signal i2c_busy      : std_logic;                -- i2c bus busy (start signal detected)
+	signal i2c_al, al    : std_logic;                -- arbitration lost
+
+begin
+	-- generate internal reset signal
+	rst_i <= arst_i xor ARST_LVL;
+
+	-- generate acknowledge output signal
+	gen_ack_o : process(wb_clk_i)
+	begin
+	    if (wb_clk_i'event and wb_clk_i = '1') then
+	      iack_o <= wb_cyc_i and wb_stb_i and not iack_o;         -- because timing is always honored
+	    end if;
+	end process gen_ack_o;
+	wb_ack_o <= iack_o;
+	
+	
+	-- generate wishbone write access signal
+	wb_wacc <= wb_cyc_i and wb_stb_i and wb_we_i;
+
+	-- assign wb_dat_o
+	assign_dato : process(wb_clk_i)
+	begin
+	    if (wb_clk_i'event and wb_clk_i = '1') then
+	      case wb_adr_i is
+	        when "000"  => wb_dat_o <= std_logic_vector(prer( 7 downto 0));
+	        when "001"  => wb_dat_o <= std_logic_vector(prer(15 downto 8));
+	        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
+
+	        -- 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 others => wb_dat_o <= (others => 'X');	-- for simulation only
+	      end case;
+	    end if;
+	end process assign_dato;
+
+
+	-- generate registers (CR, SR see below)
+	gen_regs: process(rst_i, wb_clk_i)
+	begin
+	    if (rst_i = '0') then
+	      prer <= (others => '1');
+	      ctr  <= (others => '0');
+	      txr  <= (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');
+	      elsif (wb_wacc = '1') then
+	        case wb_adr_i is
+	           when "000" => prer( 7 downto 0) <= unsigned(wb_dat_i);
+	           when "001" => prer(15 downto 8) <= unsigned(wb_dat_i);
+	           when "010" => ctr               <= wb_dat_i;
+	           when "011" => txr               <= wb_dat_i;
+	           when "100" => null; --write to CR, avoid executing the others clause
+
+	           -- illegal cases, for simulation only
+	           when others =>
+	              report ("Illegal write address, setting all registers to unknown.");
+	              prer <= (others => 'X');
+	              ctr  <= (others => 'X');
+	              txr  <= (others => 'X');
+	        end case;
+	      end if;
+	    end if;
+	end process gen_regs;
+
+
+	-- generate command register
+	gen_cr: process(rst_i, wb_clk_i)
+	begin
+	    if (rst_i = '0') then
+	        cr <= (others => '0');
+	    elsif (wb_clk_i'event and wb_clk_i = '1') then
+	        if (wb_rst_i = '1') then
+	            cr <= (others => '0');
+	        elsif (wb_wacc = '1') then
+	            if ( (core_en = '1') and (wb_adr_i = 4) ) then
+	                -- only take new commands when i2c core enabled
+	                -- pending commands are finished
+	                cr <= wb_dat_i;
+	            end if;
+	        else
+	            if (done = '1' or i2c_al = '1') then
+	                cr(7 downto 4) <= (others => '0'); -- clear command bits when command done or arbitration lost
+	            end if;
+
+	            cr(2 downto 1) <= (others => '0');   -- reserved bits, always '0'
+	            cr(0) <= '0';                        -- clear IRQ_ACK bit
+	        end if;
+	    end if;
+	end process gen_cr;
+
+	-- decode command register
+	sta  <= cr(7);
+	sto  <= cr(6);
+	rd   <= cr(5);
+	wr   <= cr(4);
+	ack  <= cr(3);
+	iack <= cr(0);
+
+	-- decode control register
+	core_en <= ctr(7);
+	ien     <= ctr(6);
+
+	-- hookup byte controller block
+	byte_ctrl: i2c_master_byte_ctrl port map (
+		clk      => wb_clk_i,
+		rst      => wb_rst_i,
+		nReset   => rst_i,
+		ena      => core_en,
+		clk_cnt  => prer,
+		start    => sta,
+		stop     => sto,
+		read     => rd,
+		write    => wr,
+		ack_in   => ack,
+		i2c_busy => i2c_busy,
+		i2c_al   => i2c_al,
+		din      => txr,
+		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
+	);
+
+
+	-- status register block + interrupt request signal
+	st_irq_block : block
+	begin
+	    -- generate status register bits
+	    gen_sr_bits: process (wb_clk_i, rst_i)
+	    begin
+	        if (rst_i = '0') then
+	          al       <= '0';
+	          rxack    <= '0';
+	          tip      <= '0';
+	          irq_flag <= '0';
+	        elsif (wb_clk_i'event and wb_clk_i = '1') then
+	          if (wb_rst_i = '1') then
+	            al       <= '0';
+	            rxack    <= '0';
+	            tip      <= '0';
+	            irq_flag <= '0';
+	          else
+	            al       <= i2c_al or (al and not sta);
+	            rxack    <= irxack;
+	            tip      <= (rd or wr);
+
+	            -- interrupt request flag is always generated
+	            irq_flag <= (done or i2c_al or irq_flag) and not iack;
+	          end if;
+	        end if;
+	    end process gen_sr_bits;
+
+	    -- generate interrupt request signals
+	    gen_irq: process (wb_clk_i, rst_i)
+	    begin
+	        if (rst_i = '0') then
+	          wb_inta_o <= '0';
+	        elsif (wb_clk_i'event and wb_clk_i = '1') then
+	          if (wb_rst_i = '1') then
+	            wb_inta_o <= '0';
+	          else
+	            -- interrupt signal is only generated when IEN (interrupt enable bit) is set
+	            wb_inta_o <= irq_flag and ien;
+	          end if;
+	        end if;
+	    end process gen_irq;
+
+	    -- assign status register bits
+	    sr(7)          <= rxack;
+	    sr(6)          <= i2c_busy;
+	    sr(5)          <= al;
+	    sr(4 downto 2) <= (others => '0'); -- reserved
+	    sr(1)          <= tip;
+	    sr(0)          <= irq_flag;
+	end block;
+
+end architecture structural;
diff --git a/fpga/usrp2/opencores/i2c/rtl/vhdl/readme b/fpga/usrp2/opencores/i2c/rtl/vhdl/readme
new file mode 100644
index 000000000..0d049f736
--- /dev/null
+++ b/fpga/usrp2/opencores/i2c/rtl/vhdl/readme
@@ -0,0 +1,25 @@
+
+
+-- This code is provided for free and may be used and   --
+-- distributed without restriction provided that the    --
+-- copyright statement is not removed from the file and --
+-- that any derivative work contains the original       --
+-- copyright notice and the associated disclaimer.      --
+
+--   Comments and suggestions are always welcome        --
+
+The i2c_master core consists of three files:
+
+- i2c_master_top        -- top level
+- i2c_master_byte_ctrl  -- byte controller
+- i2c_master_bit_ctrl   -- bit controller
+
+VHDL needs to be compiled in order. The files are listed 
+above in descending order.
+
+I2C.VHD and tst_ds1621.vhd are not supported anymore.
+They remain mostly for historical purposes, altough they
+might prove usefull.
+
+Richard Herveille
+rherveille@opencores.org
diff --git a/fpga/usrp2/opencores/i2c/rtl/vhdl/tst_ds1621.vhd b/fpga/usrp2/opencores/i2c/rtl/vhdl/tst_ds1621.vhd
new file mode 100644
index 000000000..ccf50460c
--- /dev/null
+++ b/fpga/usrp2/opencores/i2c/rtl/vhdl/tst_ds1621.vhd
@@ -0,0 +1,283 @@
+--
+--
+-- State machine for reading data from Dallas 1621
+--
+-- Testsystem for i2c controller
+--
+--
+library ieee;
+use ieee.std_logic_1164.all;
+use ieee.std_logic_arith.all;
+
+use work.i2c.all;
+
+entity DS1621_interface is
+	port (
+		clk : in std_logic;
+		nReset : in std_logic;
+
+		Dout : out std_logic_vector(7 downto 0);	-- data read from ds1621
+
+		error : out std_logic; -- no correct ack received
+
+		SCL : inout std_logic;
+		SDA : inout std_logic
+	);
+end entity DS1621_interface;
+
+architecture structural of DS1621_interface is
+	constant SLAVE_ADDR : std_logic_vector(6 downto 0) := "1001000";
+	constant CLK_CNT : unsigned(7 downto 0) := conv_unsigned(20, 8);
+
+	signal cmd_ack : std_logic;
+	signal D : std_logic_vector(7 downto 0);
+	signal lack, store_dout : std_logic;
+
+	signal start, read, write, ack, stop : std_logic;
+	signal i2c_dout : std_logic_vector(7 downto 0);
+
+begin
+	-- hookup I2C controller
+	u1: simple_i2c port map (clk => clk, ena => '1', clk_cnt => clk_cnt, nReset => nReset,
+			read => read, write => write, start => start, stop => stop, ack_in => ack, cmd_ack => cmd_ack, 
+			Din => D, Dout => i2c_dout, ack_out => lack, SCL => SCL, SDA => SDA);
+
+	init_statemachine : block
+		type states is (i1, i2, i3, i4, i5, t1, t2, t3, t4, t5);
+		signal state : states;
+	begin
+		nxt_state_decoder: process(clk, nReset, state)
+			variable nxt_state : states;
+			variable iD : std_logic_vector(7 downto 0);
+			variable ierr : std_logic;
+			variable istart, iread, iwrite, iack, istop : std_logic;
+			variable istore_dout : std_logic;
+		begin
+			nxt_state := state;
+			ierr := '0';
+			istore_dout := '0';
+
+			istart := start;
+			iread := read;
+			iwrite := write;
+			iack := ack;
+			istop := stop;
+			iD := D;
+
+			case (state) is
+				-- init DS1621
+				-- 1) send start condition
+				-- 2) send slave address + write
+				-- 3) check ack
+				-- 4) send "access config" command (0xAC)
+				-- 5) check ack
+				-- 6) send config register data (0x00)
+				-- 7) check ack
+				-- 8) send stop condition
+				-- 9) send start condition
+				-- 10) send slave address + write
+				-- 11) check ack
+				-- 12) send "start conversion" command (0xEE)
+				-- 13) check ack
+				-- 14) send stop condition
+
+				when i1 =>	-- send start condition, sent slave address + write
+					nxt_state := i2;
+					istart := '1';
+					iread := '0';
+					iwrite := '1';
+					iack := '0';
+					istop := '0';
+					iD := (slave_addr & '0'); -- write to slave (R/W = '0')
+
+				when i2 =>	-- send "access config" command
+					if (cmd_ack = '1') then
+						nxt_state := i3;
+						-- check aknowledge bit
+						if (lack = '1') then
+							ierr := '1'; -- no acknowledge received from last command, expected ACK
+						end if;
+
+						istart := '0';
+						iread := '0';
+						iwrite := '1';
+						iack := '0';
+						istop := '0';
+						iD := x"AC";
+					end if;
+
+				when i3 =>	-- send config register data, sent stop condition
+					if (cmd_ack = '1') then
+						nxt_state := i4;
+						-- check aknowledge bit
+						if (lack = '1') then
+							ierr := '1'; -- no acknowledge received from last command, expected ACK
+						end if;
+
+						istart := '0';
+						iread := '0';
+						iwrite := '1';
+						iack := '0';
+						istop := '1';
+						iD := x"00";
+					end if;
+
+				when i4 =>	-- send start condition, sent slave address + write
+					if (cmd_ack = '1') then
+						nxt_state := i5;
+	
+						istart := '1';
+						iread := '0';
+						iwrite := '1';
+						iack := '0';
+						istop := '0';
+						iD := (slave_addr & '0'); -- write to slave (R/W = '0')
+					end if;
+
+				when i5 =>	-- send "start conversion" command + stop condition
+					if (cmd_ack = '1') then
+						nxt_state := t1;
+						-- check aknowledge bit
+						if (lack = '1') then
+							ierr := '1'; -- no acknowledge received from last command, expected ACK
+						end if;
+
+						istart := '0';
+						iread := '0';
+						iwrite := '1';
+						iack := '0';
+						istop := '1';
+						iD := x"EE";
+					end if;
+				-- read temperature
+				-- 1) sent start condition
+				-- 2) sent slave address + write
+				-- 3) check ack
+				-- 4) sent "read temperature" command (0xAA)
+				-- 5) check ack
+				-- 6) sent start condition
+				-- 7) sent slave address + read
+				-- 8) check ack
+				-- 9) read msb
+				-- 10) send ack
+				-- 11) read lsb
+				-- 12) send nack
+				-- 13) send stop condition
+
+				when t1 =>	-- send start condition, sent slave address + write
+					if (cmd_ack = '1') then
+						nxt_state := t2;
+						-- check aknowledge bit
+						if (lack = '1') then
+							ierr := '1'; -- no acknowledge received from last command, expected ACK
+						end if;
+
+						istart := '1';
+						iread := '0';
+						iwrite := '1';
+						iack := '0';
+						istop := '0';
+						iD := (slave_addr & '0'); -- write to slave (R/W = '0')
+					end if;
+
+				when t2 =>	-- send read temperature command
+					if (cmd_ack = '1') then
+						nxt_state := t3;
+						-- check aknowledge bit
+						if (lack = '1') then
+							ierr := '1'; -- no acknowledge received from last command, expected ACK
+						end if;
+
+						istart := '0';
+						iread := '0';
+						iwrite := '1';
+						iack := '0';
+						istop := '0';
+						iD := x"AA";
+					end if;
+
+				when t3 =>	-- send (repeated) start condition, send slave address + read
+					if (cmd_ack = '1') then
+						nxt_state := t4;
+						-- check aknowledge bit
+						if (lack = '1') then
+							ierr := '1'; -- no acknowledge received, expected ACK
+						end if;
+
+						istart := '1';
+						iread := '0';
+						iwrite := '1';
+						iack := '0';
+						istop := '0';
+						iD := (slave_addr & '1'); -- read from slave (R/W = '1')
+					end if;
+
+				when t4 =>	-- read MSB (hi-byte), send acknowledge
+					if (cmd_ack = '1') then
+						nxt_state := t5;
+						-- check aknowledge bit
+						if (lack = '1') then
+							ierr := '1'; -- no acknowledge received from last command, expected ACK
+						end if;
+
+						istart := '0';
+						iread := '1';
+						iwrite := '0';
+						iack := '0'; --ACK
+						istop := '0';
+					end if;
+
+				when t5 =>	-- read LSB (lo-byte), send acknowledge, sent stop
+					if (cmd_ack = '1') then
+						nxt_state := t1;
+
+						istart := '0';
+						iread := '1';
+						iwrite := '0';
+						iack := '1'; --NACK
+						istop := '1';
+
+						istore_dout := '1';
+					end if;
+			end case;
+
+			-- genregs
+			if (nReset = '0') then
+				state <= i1;
+				error <= '0';
+				store_dout <= '0';
+
+				start <= '0';
+				read <= '0';
+				write <= '0';
+				ack <= '0';
+				stop <= '0';
+				D <= (others => '0');
+			elsif (clk'event and clk = '1') then
+				state <= nxt_state;
+				error <= ierr;
+				store_dout <= istore_dout;
+
+				start <= istart;
+				read <= iread;
+				write <= iwrite;
+				ack <= iack;
+				stop <= istop;
+				D <= iD;
+			end if;
+		end process nxt_state_decoder;
+	end block init_statemachine;
+
+	-- store temp
+	gen_dout : process(clk)
+	begin
+		if (clk'event and clk = '1') then
+			if (store_dout = '1') then
+				Dout <= i2c_dout;
+			end if;
+		end if;
+	end process gen_dout;
+
+end architecture structural;
+
+
-- 
cgit v1.2.3