Forum Discussion
Altera_Forum
Honored Contributor
21 years agoIntegrate the Opencores's I2C ip into SOPC
Hello:
I gathered 2 messages about how to integrate Opencores's I2C IP into SOPC. And I just have got it work by following these instructions below. But one note is that you can not just include the header file "oc_i2c_master.h" directly. Please refer to Altera's application note "AN333" to wirte your own header file. ================================================= you can easily connect the I2C Wishbone core to the NIOS processor 1. Within SOPC builder, generate interface to user logic. 2. Select bus interface type: avalon register slave. 3. Add "i2c_master_top.v" design file. 4. Read port list from file. 5. Connect the signals as follow: wb_adr_i <=> address wb_dat_i <=> writedata wb_dat_o <=> readdata wb_we_i <=> write wb_stb_i <=> chipselect wb_cyc_i <=> chipselect wb_inta_o <=> irq wb_clk_i <=> clk wb_ack_o <=> waitrequest_n wb_rst_i <=> always0 arst_i <=> reset_n scl_pad_i <=> export scl_pad_o <=> export scl_padoen_o <=> export sda_pad_i <=> export sda_pad_o <=> export sda_padoen_o <=> export 6. Under timing tab, leave the setup, wait and hold settings at 0 cycles. You can now access the I2C core via included "oc_i2c_master.h". ======================================================== Original message is written by "Guido Kuhlmann" from the Opencores forum. reference from: (http://www.opencores.org/forums.cgi/cores/2004/04/000609) ======================================================== If you have integrated the I2C IP from Opencores into your system correctly there are only some more steps to bring it to work. 1. Insert -> Symbol ... 2. 2x primitives -> buffer -> tri 3. 2x primitives -> logic -> not 4. 2x primitives -> pin -> bidir 5. connect "scl_padoen_o" and "sda_padoen_o" to the input of the "not"-logics 6. connect "scl_pad_o" and "sda_pad_o" to the input of the "tri"-buffers 7. connect the output of the "not"-logics to the corresponding output-enables of the "tri"-buffers 8. name the output of the "tri"-buffers "i2c_scl" and "i2c_sda" 9. connect "i2c_scl" and "i2c_sda" to the corresponding inputs of the I2C IP 10. connect "i2c_scl" and "i2c_sda" to "bidir"-pins That's it! ======================================================== Original message is written by "niosIIuser" from the Nios forum. reference from : (here (http://www.niosforum.com/forum/index.php?act=st&f=2&t=590&hl=opencore)) ========================================================16 Replies
- Altera_Forum
Honored Contributor
I have done the process as the trout writes, and generated a symbol named I2cCore. The I2cCore occupys 32 8-bit address. But in the 32 addresses, I find that I can only write 4 of them, why? I am confused that which are the registers? Is there anything I omitted? By the way, in the nios2 core, I have integrated cup, onchip_memory, timer, pio, epcs_controller, jtag and I2cCore. Does anyone can help me?
- Altera_Forum
Honored Contributor
Hi:
I have designed a IPcore which is belown: library ieee; use ieee.std_logic_1164.all; entity ad574 is port(D :IN STD_LOGIC_VECTOR(15 DOWNTO 0); address: in std_logic_vector(1 downto 0); CLK ,STATUS,read: IN STD_LOGIC;--״̬»úʱÖÓCLK£¬AD574״̬ÐźÅSTATUS byteenable: in std_logic_vector(3 downto 0); chipselect: in std_logic; CE,CS,A0,RC,K12X8: OUT STD_LOGIC; --AD574¿ØÖÆÐźŠQ : out STD_LOGIC_VECTOR(31 DOWNTO 0)); end ad574; architecture behav of ad574 is type state is (st0, st1, st2, st3,st4); signal current_state,next_state :state:=st0; signal data_reg_select: std_logic; signal control_reg_select: std_logic; SIGNAL data_reg : STD_LOGIC_VECTOR(31 DOWNTO 0); SIGNAL lock: STD_LOGIC; begin K12X8 <= '1'; process(address,chipselect) begin data_reg_select<='0'; control_reg_select<='0'; if chipselect='1' then case address is when "00" => data_reg_select<='1'; when "01" => control_reg_select<='1'; when others => null; end case; end if; end process; process(current_state,status) --»ù±¾ÈÎÎñÉè¼Æ(״̬ÄÚÐźű仯) begin case current_state is when st0 =>CE<='0';CS<='1'; A0<='1';RC<='1';LOCK<='0';next_state <= st1; when st1 =>CE<='1';CS<='0'; A0<='0';RC<='0';LOCK<='0'; next_state <= st2; when st2 =>CE<='1';CS<='0'; A0<='0';RC<='0';LOCK<='0'; IF (STATUS='1') THEN next_state <= st2; ELSE next_state <= st3; END IF ; when st3 =>CE<='1';CS<='0'; A0<='0';RC<='1';LOCK<='0'; next_state <= st4; when st4 =>CE<='1';CS<='0'; A0<='0';RC<='1';LOCK<='1'; next_state <= st0; when others =>CE<='0';CS<='1'; A0<='1';RC<='1';LOCK<='0';next_state <= st0; end case; end process; PROCESS (clk,control_reg_select,chipselect) --¿ØÖƼĴæÆ÷¿ØÖÆ×ª»»¹ý³Ì BEGIN IF ( clk'EVENT AND clk='1') THEN if (control_reg_select and chipselect)='1' then current_state <= next_state; end if; END IF; END PROCESS ; process(lock) --Êý¾Ý¿ØÖƼĴæÆ÷²Ù×÷ BEGIN IF LOCK='1' AND LOCK'EVENT THEN if byteenable(0)='1' then data_reg(7 downto 0)<=d(7 downto 0);end if;data_reg<=d; if byteenable(1)='1' then data_reg(15 downto 8)<=d(15 downto 8);end if; if byteenable(2)='1' then data_reg(23 downto 16)<="00000000";end if; if byteenable(3)='1' then data_reg(31 downto 24)<="00000000";end if; END IF; END PROCESS ; process(read,clk,data_reg_select,chipselect) --NIOS×ÜÏßͨѶ begin if clk'event and clk='1' then if (read and data_reg_select and chipselect)='1' then Q <=data_reg; else Q<=(others=>'Z'); end if; end if ; end process; END behav; now I integerate the IP to sopc , and the base address of the IP is :0x02000008 and the end address is 0x0200000f , the generation of the system is successful . but when I built the software about the system above on the NiosII IDE , but there is error and display that the range of the IP ---ad16bit is out of the range of the address , what is it? while I change the "Q : out STD_LOGIC_VECTOR(31 DOWNTO 0));" to " Q : out STD_LOGIC_VECTOR(15 DOWNTO 0)); " the error is disappeared. why? and how can I write the drivers of the IP core ? who can help me? - Altera_Forum
Honored Contributor
--- Quote Start --- originally posted by tek66tim@Jun 2 2005, 04:08 PM hi,i looked for the an 333 and it's no longer available, does anyone have a modified oc_i2c_master.h file or some hints on how to modify the .h file to work with sopc builder?
thanks --- Quote End --- There is a new document present on Altera web site who describe how to create a NIOS II / SOPC Builder component: Quartus II Development Software Handbook v5.0 Volume 4: SOPC Builder. It is available here (http://www.altera.com/literature/hb/qts/qts_qii5v4.pdf) or go to quartus literature page (http://www.altera.com/literature/lit-qts.jsp). I add opencores I2C master component to SOPC Builder, but to do that I have created an additionnal VHDL file because SOPC Builder seems to have problem with the STD_LOGIC GENERIC parameters.
Now I am working on I2C software driver, the basic functions are working. I can read and write I2C devices, now I have to clean up my code.-------------------------------------------- -- Description VHDL d'une interface I2C maître -- FM 28/06/2005 -------------------------------------------- -- Déclaration des bibliothèques library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_arith.all; -------------------------------------------- -- Déclaration de l'entité entity oc_i2c_master_top is port( -- Signaux du bus Avalon address: in unsigned(2 downto 0); readdata: out std_logic_vector(7 downto 0); writedata: in std_logic_vector(7 downto 0); write: in std_logic; chipselect: in std_logic; clk: in std_logic; -- Entrée horloge reset_n: in std_logic; -- Entrée de RESET (actif à l'état bas) irq: out std_logic; waitrequest_n: out std_logic; -- Sortie I2C scl: inout std_logic; -- i2c clock line output sda: inout std_logic -- i2c data line output ); end oc_i2c_master_top; -------------------------------------------- -- Déclaration de l'architecture comportementale "algorithmique" de l'entité architecture bhv of oc_i2c_master_top is component i2c_master_top is generic( ARST_LVL : std_logic -- asynchronous reset level ); port ( -- wishbone signals wb_clk_i : in std_logic; -- master clock input wb_rst_i : in std_logic; -- synchronous active high reset arst_i : in std_logic; -- 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 component; signal scl_pad_i : std_logic; signal scl_pad_o : std_logic; signal scl_padoen_o : std_logic; signal sda_pad_i : std_logic; signal sda_pad_o : std_logic; signal sda_padoen_o : std_logic; begin i2c_top : i2c_master_top generic map ( ARST_LVL => '0') port map ( wb_adr_i => address, wb_dat_i => writedata, wb_dat_o => readdata, wb_we_i => write, wb_stb_i => chipselect, wb_cyc_i => chipselect, wb_inta_o => irq, wb_clk_i => clk, wb_ack_o => waitrequest_n, wb_rst_i => '0', arst_i => reset_n, scl_pad_i => scl_pad_i, scl_pad_o => scl_pad_o, scl_padoen_o => scl_padoen_o, sda_pad_i => sda_pad_i, sda_pad_o => sda_pad_o, sda_padoen_o => sda_padoen_o ); scl <= scl_pad_o when (scl_padoen_o = '0') else 'Z'; sda <= sda_pad_o when (sda_padoen_o = '0') else 'Z'; scl_pad_i <= scl; sda_pad_i <= sda; end architecture bhv; - Altera_Forum
Honored Contributor
Hi,
I looked for the AN 333 and it's no longer available, does anyone have a modified oc_i2c_master.h file or some hints on how to modify the .h file to work with SOPC builder? Thanks - Altera_Forum
Honored Contributor
The I2C slave model of OC is not synthesizable, but the master seems to work.
- Altera_Forum
Honored Contributor
Thank U!!
I will try .....