Nios® V/II Embedded Design Suite (EDS)
Support for Embedded Development Tools, Processors (SoCs and Nios® V/II processor), Embedded Development Suites (EDSs), Boot and Configuration, Operating Systems, C and C++

I2C bus in vhdl file

Altera_Forum
Honored Contributor II
1,576 Views

hi! 

i would like to write a I2C file.vhdl (master) to communicate with several  

PCF8574 devices . 

I already wrote this library for PIC microntroller , without to use  

periperal and successfull running , just to show i know the protocol. 

I'm studing vhdl , and i never found hou to set a "pin" input and output . 

For example when my master write on bus i have to set  

the SDA pin as output , and when i'm waiting to receive i need to set it  

as input. 

How may i set this pin in vhdl file ? 

thanks for helps 

ciao  

walter
0 Kudos
6 Replies
Altera_Forum
Honored Contributor II
841 Views

In VHDL, when you declare the entity, you define a port list. In this port list is where you specify what signals are input/output/bidir to the 'function'. You can look at the simple example at the end of my post.  

 

The following is going to to be quartus specific. To get your signals to actual FPGA pins do the following: Once you complete your entity, you can create a schematic symbol for your entity by loading your VHDL in Quartus, and then going to File -> Create/Update -> Create Symbol Files for Current File. Once you do so, you'll be able to place a symbol of your VHDL entity on a schematic (double click a blank schematic and navigate to your project). and connect it's traces to Input or Output symbols. From there, you can goto Assignments -> Pin Planner and connect at will.  

 

Let me know if you need any details on any specific step. 

 

VHDL Example (P.S. This code does not perform any (useful?) function): 

-------------------------------------------------------------------------------- -- Kevin Wolfe -- This is a comment -------------------------------------------------------------------------------- -- Rev.  0 - 08/14/06 - KDW - Inception LIBRARY ieee; USE ieee.STD_LOGIC_1164.all; USE ieee.STD_LOGIC_unsigned.all; --------------------------------------------------- ENTITY RAM_MANAGER IS PORT(     clk      :    IN  STD_LOGIC;     mcu_data    :    IN  STD_LOGIC_VECTOR(7  DOWNTO 0);         addr_dec    :  OUT  STD_LOGIC);      END RAM_MANAGER; ---------------------------------------------------- ARCHITECTURE behv of RAM_MANAGER IS     CONSTANT SOME_CONSTANT_NAME      :    integer := 2;     SIGNAL    some_singal_i  : STD_LOGIC_VECOTR(8 DOWNTO 0)    := (OTHERS => &#39;0&#39;);          SIGNAL    count_i      : INTEGER range 0 to READ_PERIOD    := 26; BEGIN     -- Process to respond to read Requests     PROCESS (clk)     BEGIN  CASE (conv_integer(mcu_data)) IS      WHEN 0 =>    some_singal_i <= &#39;1&#39;;      WHEN 1 =>    some_singal_i <= &#39;0&#39;;      WHEN 2 =>    count_i    <= count_i + 1;      WHEN OTHERS      =>  END CASE;     END PROCESS;          addr_dec <= some_singal_; END behv;
0 Kudos
Altera_Forum
Honored Contributor II
841 Views

very nice . 

I already wrote some custom peripheral and included in my system as vhdl files. 

After that wrote driver device and use them in NIOS II IDE . 

But in my case how i have to set the pin , as input , as output (not good ) 

or bidirectional if exist ? 

For PIC mcu i wrote library , and was possible because i can change direction "on flight" using TRIS register .Setting 0 or 1 change the direction  

but how to do in vhdl file ? 

thanks for helps  

ciao  

walter
0 Kudos
Altera_Forum
Honored Contributor II
841 Views

two ways to do this: 

 

1. 

 

in your vhdl file 

port ( 

.. 

.. 

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 

); 

 

remark: "this is from opencores i2c master, see opencores.org

 

in Quartus graphic editor, add a "tri" component and BIDIR pin. 

 

connect sda_padoen_o --> tri.enable 

connect sda_pad_o --> tri.input 

connect tri.output to sda BIDIR IO PIN 

connect sda_pad_i to sda BIDIR IO PIN 

 

this one is preffered because you normally don&#39;t have tristate signals  

inside your fpga. IP cores are always connected together in this way. 

 

-- remark sda is open collector 

-- to write &#39;0&#39; to sda 

sda_pad_o <= &#39;0&#39;; 

sda_padoen_o <= &#39;1&#39;; 

-- to write &#39;1&#39; to sda 

sda_pad_o <= &#39;0&#39;; -- &#39;0&#39; or &#39;1&#39; doesn&#39;t matter 

sda_padoen_o <= &#39;0&#39;;  

 

 

2.  

however it should also be possible to do the following if you  

directly connect your in/output to a QUARTUS BIDIR pin 

 

in your vhdl file 

port ( 

.. 

.. 

sda_pad_io : inout std_logic; -- i2c data line in/output 

); 

 

-- in Quartus graphic editor, add a BIDIR pin. 

-- connect sda_pad_io directly to your BIDIR sda pin. 

 

signal sda_in : std_logic; 

signal sda_out : std_logic; 

 

-- read input 

sda_in <= sda_pad_io; 

-- write output 

-- sda is open collector or open drain, we never drive a &#39;1&#39; 

sda_pad_io <= &#39;0&#39; when sda_out=&#39;0&#39; else &#39;Z&#39;;
0 Kudos
Altera_Forum
Honored Contributor II
841 Views
0 Kudos
Altera_Forum
Honored Contributor II
841 Views

http://forum.niosforum.com/work2/style_emoticons/<#EMO_DIR#>/blink.gif  

 

 

--- Quote Start ---  

originally posted by pmicro@Aug 15 2006, 07:56 AM 

http://forum.niosforum.com/work2/style_emoticons/<#emo_dir#>/sad.gif  

<div align='right'><{post_snapback}> (index.php?act=findpost&pid=17621) 

--- quote end ---  

 

--- Quote End ---  

0 Kudos
Altera_Forum
Honored Contributor II
841 Views

hi 

I would like design simoulation of I2c bus with (vhdl),please help me
0 Kudos
Reply