Implementing Bidirectional pins

P

Prashant

Guest
Hi,

I'm trying to implement a bidirectional bus in my code. (VHDL,
APEX20K1500E). But I'm having some trouble which brought me to ask the
question :

How do I specify the direction signal while using a bidirectional bus
? I dont find myself setting any enable signals when using the
bidirectional bus. I would appreciate it if someone could explain how
this works.

Thanks,
Prashant
 
On 27 Sep 2003 17:30:57 -0700, prashantj@usa.net (Prashant) wrote:

Hi,

I'm trying to implement a bidirectional bus in my code. (VHDL,
APEX20K1500E). But I'm having some trouble which brought me to ask the
question :

How do I specify the direction signal while using a bidirectional bus
? I dont find myself setting any enable signals when using the
bidirectional bus. I would appreciate it if someone could explain how
this works.
A bidirectional signal usually signifies read/write access to a
resource (a memory location or a control register). If this is your
application, the direction signal controls the enable signal of the
bus drivers. In other words, when you read the data travels in one
direction and when you write it travels the other direction. You set
the enable signal correspondingly. As an example assume there is a
driver which is active high for output enable from the memory to the
outside, and there is an active high read, low write signal (rd_wrb).
In this case, you'd connect the rd_wrb signal to the oe pin of the
memory and when rd_wrb is one, data is driven from the memory to the
bus and when rd_wrb is zero, memory uses the data on the bus.

Hope this helps,

Muzaffer Kal

http://www.dspia.com
ASIC/FPGA design/verification consulting specializing in DSP algorithm implementations
 
Thanks Muzzafer,

So how does this work for pins on an FPGA ? I have specified some of
the FPGA pins as bidirectional pins. I'm using the bidirectional pins
to read from a register in the code or to write from a different
register in the code.
I dont understand how to specify the direction signal for the pins. I
can do this at the signal/register level within the logic. But how are
the bidirectional IO pins controlled ?

Thanks,
Prashant

Muzaffer Kal <kal@dspia.com> wrote in message news:<edbcnv85jk9l4u2b2stv225lteknhub3le@4ax.com>...
On 27 Sep 2003 17:30:57 -0700, prashantj@usa.net (Prashant) wrote:

Hi,

I'm trying to implement a bidirectional bus in my code. (VHDL,
APEX20K1500E). But I'm having some trouble which brought me to ask the
question :

How do I specify the direction signal while using a bidirectional bus
? I dont find myself setting any enable signals when using the
bidirectional bus. I would appreciate it if someone could explain how
this works.

A bidirectional signal usually signifies read/write access to a
resource (a memory location or a control register). If this is your
application, the direction signal controls the enable signal of the
bus drivers. In other words, when you read the data travels in one
direction and when you write it travels the other direction. You set
the enable signal correspondingly. As an example assume there is a
driver which is active high for output enable from the memory to the
outside, and there is an active high read, low write signal (rd_wrb).
In this case, you'd connect the rd_wrb signal to the oe pin of the
memory and when rd_wrb is one, data is driven from the memory to the
bus and when rd_wrb is zero, memory uses the data on the bus.

Hope this helps,

Muzaffer Kal

http://www.dspia.com
ASIC/FPGA design/verification consulting specializing in DSP algorithm implementations
 
On 28 Sep 2003 11:21:57 -0700, prashantj@usa.net (Prashant) wrote:

Thanks Muzzafer,

So how does this work for pins on an FPGA ? I have specified some of
the FPGA pins as bidirectional pins. I'm using the bidirectional pins
to read from a register in the code or to write from a different
register in the code.
I dont understand how to specify the direction signal for the pins. I
can do this at the signal/register level within the logic. But how are
the bidirectional IO pins controlled ?
Suppose the following is your fpga top level:

module mydesign(rd_wrb, address, data);
input rd_wrb;
input [7:0] address;
inout [7:0] data;

and this is your register block

reg [7:0] registers [7:0];

this is how you write to the memory

always @(rd_wrb or address or data)
if (!rd_wrb)
registers[address] = data;

and this is how you read from the registers including direction
control

wire [7:0] data = rd_wrb ? registers[address] : 8'hZ;

this last line shows you control the direction signal for the pins.
You take the input rd_wrb and connect it to the active high OE port of
the data pins.
Hope this help.

Muzaffer Kal

http://www.dspia.com
ASIC/FPGA design/verification consulting specializing in DSP algorithm implementations
 
prashantj@usa.net (Prashant) wrote in message news:<ea62e09.0309271630.62d832fe@posting.google.com>...
Hi,

I'm trying to implement a bidirectional bus in my code. (VHDL,
APEX20K1500E). But I'm having some trouble which brought me to ask the
question :

How do I specify the direction signal while using a bidirectional bus
? I dont find myself setting any enable signals when using the
bidirectional bus. I would appreciate it if someone could explain how
this works.

Thanks,
Prashant
Hi Prashant,
Try the following piece of code (taken from the VHDL template in the
Quartus Text Editor, with a modification)

-- Quartus VHDL Template
-- Tri-State Buffer (Modified to make __tri_output_name a INOUT)
-- Replace the __variable_anme with your variable name
-- As the port direction is INOUT __tri_output_name can be used on the
right
-- hand side of an assignment.
-- The __oe_input_name should be set to drive out to 0 so that
__tri_output_name can then drive into the chip.

LIBRARY ieee;
USE ieee.std_logic_1164.all;

ENTITY __entity_name IS

PORT
(
__oe_input_name : IN STD_LOGIC;
__data_input_name : IN STD_LOGIC;
__tri_output_name : INOUT STD_LOGIC
);

END __entity_name;

ARCHITECTURE a OF __entity_name IS
BEGIN

PROCESS (__oe_input_name, __data_input_name)
BEGIN

IF __oe_input_name = '0' THEN

__tri_output_name <= 'Z';

ELSE

__tri_output_name <= __data_input_name;

END IF;

END PROCESS;
END a;

- Subroto Datta
Altera Corp.
 
prashantj@usa.net (Prashant) wrote in message news:<ea62e09.0309271630.62d832fe@posting.google.com>...
Hi,

I'm trying to implement a bidirectional bus in my code. (VHDL,
APEX20K1500E). But I'm having some trouble which brought me to ask the
question :

How do I specify the direction signal while using a bidirectional bus
? I dont find myself setting any enable signals when using the
bidirectional bus. I would appreciate it if someone could explain how
this works.

Thanks,
Prashant
Hi Prashant,
Try the following piece of code (taken from the VHDL template in the
Quartus Text Editor, with a modification)

-- Quartus VHDL Template
-- Tri-State Buffer (Modified to make __tri_output_name a INOUT)
-- Replace the __variable_anme with your variable name
-- As the port direction is INOUT __tri_output_name can be used on the
right
-- hand side of an assignment.
-- The __oe_input_name should be set to drive out to 0 so that
__tri_output_name can then drive into the chip.

LIBRARY ieee;
USE ieee.std_logic_1164.all;

ENTITY __entity_name IS

PORT
(
__oe_input_name : IN STD_LOGIC;
__data_input_name : IN STD_LOGIC;
__tri_output_name : INOUT STD_LOGIC
);

END __entity_name;

ARCHITECTURE a OF __entity_name IS
BEGIN

PROCESS (__oe_input_name, __data_input_name)
BEGIN

IF __oe_input_name = '0' THEN

__tri_output_name <= 'Z';

ELSE

__tri_output_name <= __data_input_name;

END IF;

END PROCESS;
END a;

- Subroto Datta
Altera Corp.
 
prashantj@usa.net (Prashant) wrote in message news:<ea62e09.0309271630.62d832fe@posting.google.com>...
Hi,

I'm trying to implement a bidirectional bus in my code. (VHDL,
APEX20K1500E). But I'm having some trouble which brought me to ask the
question :

How do I specify the direction signal while using a bidirectional bus
? I dont find myself setting any enable signals when using the
bidirectional bus. I would appreciate it if someone could explain how
this works.

Thanks,
Prashant

Hi prashant,
All that you should know when the paricular pin is to act as input
& when as output.The use a control signal like "oe" which i have in my
following code .

Here "sda" is my bidirectional pin.
Intenally I copy it to signal "out_sda" & use.While driving the pin
"sda" i copy "int_sda" to "sda".this control is determined by the
signal "oe".

process(oe,sda)
begin
if (oe = '1') then
out_sda <= sda;
else
out_sda <= '0';
end if;
end process;

process(oe,int_sda)
begin
if (oe = '0') then
sda <= int_sda;
else
sda <= 'Z';
end if;
end process;

However the most important thing is there must not be a open loop
between "int_sda" & "out_sda" ie.,in electrical terms there must be a
closed loop for this to work.
Bye
 
I wont say I know the perfect way.. but typically you only have a
bi-directional bus on the outside world. Inside the FPGA use an output bus
and an input bus.

Xilinx have internal tristates but they can pig out on resources (I think)
but other vendors don't so code portability will suffer if you use / rely on
them.

tristate_bus : process (enable, dat_o) is
begin
if (enable = '0') then
dat_bus <= (others => 'Z');
else -- if enable = '1'
dat_bus <= dat_o;
end if;
end process tristate_bus;

dat_i <= dat_bus;

There's a simple tri-state bus in VHDL. I just typed it in without using a
VHDL compiler or simulator. so all care no responsibility but its a good
starting place.
all you have to do is to feed the dat_i to all register inputs and the
dat_o from either the internal tristate bus OR (better) from a multiplexer
which takes all the outputs from all the registers.

Simon

here's another .. works well you will note the input multiplexer (case
ADD_I) and the tri-state ('Z').
DAT_IO is the tri-state data bus on a HC11. This is actually part of a HC11
interface but is also generic.

Read_Registers : process(RST_I, E_I, RD_I, nCICCS_I, ADD_I,
SPI_SR, LOSS, SPI_BUSY, TxBUSY, RxBUSY, DCDo, DCDi, LEDS, DeviceReset)
is
begin
if (RST_I = '1') or (E_I = '0') or (RD_I = '0') or (nCICCS_I = '1')
then
DAT_IO <= (others => 'Z');
else
case ADD_I is
when IDr => -- Altera Revision
DAT_IO <= conv_std_logic_vector(CARD_ID, 8);

when STATUSr => -- Status bits
DAT_IO(7 downto 6) <= LOSS & SPI_BUSY;
DAT_IO(4 downto 0) <= '0' & TxBUSY & RxBUSY & DCDo & DCDi;
DAT_IO(5) <= '0';

when LED_STATUSr =>
DAT_IO <= not LEDS; -- Feed back the leds

when SPIr =>
DAT_IO <= SPI_SR; -- SPI register

when others => -- CIC 006/9
DAT_IO <= DeviceReset & conv_std_logic_vector(CIC_NO, 7);
end case;
end if;
end process Read_Registers;

CH34_Latch : process(RST_I, E_I) is
begin
if RST_I = '1' then
MODE2 <= O"7";
RE_ROUTE(2) <= '0';
MODE3 <= O"7";
RE_ROUTE(3) <= '0';
elsif falling_edge(E_I) then
if (WrCs = '1') and (ADD_I = CH34r) then
MODE2 <= DAT_IO(2 downto 0);
RE_ROUTE(2) <= DAT_IO(3);
MODE3 <= DAT_IO(6 downto 4);
RE_ROUTE(3) <= DAT_IO(7);
end if;
end if;
end process CH34_Latch;


I hope those give you some Ideas.

"Prashant" <prashantj@usa.net> wrote in message
news:ea62e09.0309281021.641cbbd9@posting.google.com...
Thanks Muzzafer,

So how does this work for pins on an FPGA ? I have specified some of
the FPGA pins as bidirectional pins. I'm using the bidirectional pins
to read from a register in the code or to write from a different
register in the code.
I dont understand how to specify the direction signal for the pins. I
can do this at the signal/register level within the logic. But how are
the bidirectional IO pins controlled ?

Thanks,
Prashant

Muzaffer Kal <kal@dspia.com> wrote in message
news:<edbcnv85jk9l4u2b2stv225lteknhub3le@4ax.com>...
On 27 Sep 2003 17:30:57 -0700, prashantj@usa.net (Prashant) wrote:

Hi,

I'm trying to implement a bidirectional bus in my code. (VHDL,
APEX20K1500E). But I'm having some trouble which brought me to ask the
question :

How do I specify the direction signal while using a bidirectional bus
? I dont find myself setting any enable signals when using the
bidirectional bus. I would appreciate it if someone could explain how
this works.

A bidirectional signal usually signifies read/write access to a
resource (a memory location or a control register). If this is your
application, the direction signal controls the enable signal of the
bus drivers. In other words, when you read the data travels in one
direction and when you write it travels the other direction. You set
the enable signal correspondingly. As an example assume there is a
driver which is active high for output enable from the memory to the
outside, and there is an active high read, low write signal (rd_wrb).
In this case, you'd connect the rd_wrb signal to the oe pin of the
memory and when rd_wrb is one, data is driven from the memory to the
bus and when rd_wrb is zero, memory uses the data on the bus.

Hope this helps,

Muzaffer Kal

http://www.dspia.com
ASIC/FPGA design/verification consulting specializing in DSP algorithm
implementations
 
Hi,

I've also got a little problem with implemeting a bidirectional port on a Spartan2.

When I use the following code:

process (ClkInt, ClkDir)
begin
if ClkDir = '0' then
SIGT <= 'Z';
ClkRxTX <= SIGT;
else
SIGT <= ClkInt;
ClkRxTX <= ClkInt;
end if;
end process ClkSwitch ;

My SIGT port becomes an output. only when I remove the lines SIGT <= ClkInt; and SIGT <= 'Z'; the SIGT port becomes an input. I just can't seem to get the port to become an inout (or Bidir).
My synthesis tool (leonardo spectrum) reports that the port is an inout. But after running the Xilinx map tool the port is already an ouput. I don't see anything in the reports about these ports.

One strange thing: When I make three testports on my toplevel, and create a process like the one above, there's no problem. The port is bidir as it should be. Anybody got any ideas on what this problem might be ??

Note: The sigt port is combined into a std_logic_vector with 7 other SIGT signales. The signals are declared as inout in the whole design.
 

Welcome to EDABoard.com

Sponsor

Back
Top