Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > VHDL > INOUT port on entity

Reply
Thread Tools

INOUT port on entity

 
 
minkowsky
Guest
Posts: n/a
 
      02-16-2004
Hello,

I have an entity with an INOUT port. When I modify the port from inside the
entity, the inside of the entity sees the new value, but the outside doesn't
seem to feel the change in value.

Any idea why?

here is a sample of the code:

COMPONENT comms
PORT(
p_mem0 : INOUT std_logic_vector(63 downto 0);
p_mem1 : INOUT std_logic_vector(63 downto 0);
);
END COMPONENT;

and the declaration

comms4: comms PORT MAP(
p_mem0 => mem0,
p_mem1 => mem1,
);

process (mem0) -- this process seems to be never called...
variable tmp: std_logic_vector(63 downto 0):=(others=>'1')
begin
mem1<= mem0 xor tmp;
end process;

The process seems never called because if I write a new value to port
p_mem0, inside the component, then when I read both values (from inside the
communications component), I get my new value in mem0 (that's to be awaited)
and nothing in mem1 (its old value, in fact).

It's as if the component has decided the value once and for all and doesn't
accept a new value for p_mem1.

I'm at a loss, any help is welcome.


 
Reply With Quote
 
 
 
 
Eyck Jentzsch
Guest
Posts: n/a
 
      02-16-2004
minkowsky wrote:
> Hello,
>
> I have an entity with an INOUT port. When I modify the port from inside the
> entity, the inside of the entity sees the new value, but the outside doesn't
> seem to feel the change in value.
>
> Any idea why?
>
> here is a sample of the code:
>
> COMPONENT comms
> PORT(
> p_mem0 : INOUT std_logic_vector(63 downto 0);
> p_mem1 : INOUT std_logic_vector(63 downto 0);
> );
> END COMPONENT;
>
> and the declaration
>
> comms4: comms PORT MAP(
> p_mem0 => mem0,
> p_mem1 => mem1,
> );
>
> process (mem0) -- this process seems to be never called...
> variable tmp: std_logic_vector(63 downto 0):=(others=>'1')
> begin
> mem1<= mem0 xor tmp;
> end process;
>
> The process seems never called because if I write a new value to port
> p_mem0, inside the component, then when I read both values (from inside the
> communications component), I get my new value in mem0 (that's to be awaited)
> and nothing in mem1 (its old value, in fact).
>
> It's as if the component has decided the value once and for all and doesn't
> accept a new value for p_mem1.
>
> I'm at a loss, any help is welcome.
>
>

Your comms is driving a U to the outside world of both pins. This
prevents updating the internal signal. You should set mem0 to 'Z' inside
your comms architecture (you can do it with an concurrent assignment
since you signals are resolved ones)

-Eyck

 
Reply With Quote
 
 
 
 
minkowsky
Guest
Posts: n/a
 
      02-16-2004


"Eyck Jentzsch" <> wrote in message
news:...
> Your comms is driving a U to the outside world of both pins. This
> prevents updating the internal signal. You should set mem0 to 'Z' inside
> your comms architecture (you can do it with an concurrent assignment
> since you signals are resolved ones)
>
> -Eyck


Thanx for your kind answer.

I tried what you said, but it seems harder than I thought.

I wished to have a generic component that would handle IO communications and
have another component deal with the payload ( that would implement
functions dependant of the time elapsed and any of the other signals... ).

I have signals coming from outside telling me the if the outside controler
PC wants to write or read data and two bus of signals one for the address I
wish to scan/write and one for the data (p_write, p_read, p_address, and
p_data).

at some point, when the p_write signal is on, depending on the address, I
set the value of the IO port of my component to the data that was passed...
I suppose that's around where I must set all the other ports to Z at that
precise time... Or maybe more so, as soon as the p_write bit is reset.

So I tried that and get a compilation error telling me the signal cannot be
synthetized, that there is a bad synchronous description.

Since I don't want to burden you too much, do you know of any good pointers
to info on this matter (the Z stuffs and INOUT ports inside a component).

Thanks a bunch.

Mink.


 
Reply With Quote
 
Mike Treseler
Guest
Posts: n/a
 
      02-16-2004
minkowsky wrote:

> I tried what you said, but it seems harder than I thought.


A common complaint, and a good reason to use separate
input and output pins when you can.

> So I tried that and get a compilation error telling me the signal cannot be
> synthetized, that there is a bad synchronous description.


Have a look this example of a synchronous inout port
and its testbench.

http://groups.google.com/groups?q=oe_demo.vhd

-- Mike Treseler
 
Reply With Quote
 
David R Brooks
Guest
Posts: n/a
 
      02-16-2004
If all you want is to be able to alter a signal's value *from within
the block*, then see that change both inside & outside the block, the
keyword is "buffer", not "inout".
You only need "inout" if you really intend a bidirectional bus, which
will be explicitly driven to "Z" at the receiving end.

"minkowsky" <> wrote:

:Hello,
:
:I have an entity with an INOUT port. When I modify the port from inside the
:entity, the inside of the entity sees the new value, but the outside doesn't
:seem to feel the change in value.
:
:Any idea why?
:
:here is a sample of the code:
:
: COMPONENT comms
: PORT(
: p_mem0 : INOUT std_logic_vector(63 downto 0);
: p_mem1 : INOUT std_logic_vector(63 downto 0);
: );
: END COMPONENT;
:
:and the declaration
:
:comms4: comms PORT MAP(
: p_mem0 => mem0,
: p_mem1 => mem1,
: );
:
rocess (mem0) -- this process seems to be never called...
:variable tmp: std_logic_vector(63 downto 0):=(others=>'1')
:begin
: mem1<= mem0 xor tmp;
:end process;
:
:The process seems never called because if I write a new value to port
_mem0, inside the component, then when I read both values (from inside the
:communications component), I get my new value in mem0 (that's to be awaited)
:and nothing in mem1 (its old value, in fact).
:
:It's as if the component has decided the value once and for all and doesn't
:accept a new value for p_mem1.
:
:I'm at a loss, any help is welcome.
:

 
Reply With Quote
 
minkowsky
Guest
Posts: n/a
 
      02-16-2004

"David R Brooks" <> wrote in message
news:...
> If all you want is to be able to alter a signal's value *from within
> the block*, then see that change both inside & outside the block, the
> keyword is "buffer", not "inout".


I'll look into that one
thanks.

> You only need "inout" if you really intend a bidirectional bus, which
> will be explicitly driven to "Z" at the receiving end.


That might be the reason I have problems. I understand from what U say that
I should set to Z outside of my comms componnent.

I'll try that one too.

Thanks Again for the tips


 
Reply With Quote
 
minkowsky
Guest
Posts: n/a
 
      02-16-2004

"Mike Treseler" <> wrote in message
news:c0r61t$nk2$...
> minkowsky wrote:
>
> > I tried what you said, but it seems harder than I thought.

>
> A common complaint, and a good reason to use separate
> input and output pins when you can.


I keep that as a fallback position. Though I really want to understand this
INOUT thing (must be a reason it exists in the first place)

I'll also look into the Buffer thing on the way. Must be a reason behind
that one too

> > So I tried that and get a compilation error telling me the signal

cannot be
> > synthetized, that there is a bad synchronous description.

>
> Have a look this example of a synchronous inout port
> and its testbench.
>
> http://groups.google.com/groups?q=oe_demo.vhd


Gee thanks!

Mink.


 
Reply With Quote
 
David R Brooks
Guest
Posts: n/a
 
      02-17-2004
If you do use a bidirectional bus, the receiving end should normally
be set to 'Z'. Basically, the two ends will always "fight" each other,
but std_logic being a resolved type, rules exist for resolving these
conflicts. "Z" will always yield to the other end's value, so you can
receive the signal.

"minkowsky" <> wrote:

:
:"David R Brooks" <> wrote in message
:news:.. .
:> If all you want is to be able to alter a signal's value *from within
:> the block*, then see that change both inside & outside the block, the
:> keyword is "buffer", not "inout".
:
:I'll look into that one
:thanks.
:
:> You only need "inout" if you really intend a bidirectional bus, which
:> will be explicitly driven to "Z" at the receiving end.
:
:That might be the reason I have problems. I understand from what U say that
:I should set to Z outside of my comms componnent.
:
:I'll try that one too.
:
:Thanks Again for the tips
:

 
Reply With Quote
 
minkowsky
Guest
Posts: n/a
 
      02-17-2004
But if I need to send my fpga some config info thru the comms entity, then
wont this init signal override the possible subsequent changes to this init
condition?

Lets say I want to have a pseudo fibonacci U(n)=U(n-1)+U(n-2)... given 2
numbers U(0) U(1) and a clock I want to increment the result each step of
the clock (this is of course a fictitious example). Then at one point I have
to send thos 2 numbers, and then I'd like to read the values generated at
each step.

if I use two IN ports, and two OUT ports, my fear is that the IN values will
override the values of each iteration (unless I find a way to uncouple the
INs from the OUTs, with some kind of reset system)

The Buffer seems out, but the INOUT ports seem perfect (if I read and
understand the docs well....) If only I can manage to set the Z value at the
correct place.

The idea (maybe too generic to be viable) was to be able to have a fibonacci
entity (given two INs gives the OUT when a sync signal is sent), and a
generic Comms entity that would allow me to see the result on my PC. And if
tomorrow, I don't want a fibonacci, then all I need to do is swap the entity
with a new function. But I'd keep all my comms intact, and my pc side
software would stay the same (at least my library for talking both ways to
my chip - maybe not the GUI)

(I think ) I _do_ understand the principle underlying the use of Z but
can't figure out why the compiler is complaining about it. (my intuitive
approch was to look at the "write" process and determine if the write was
enabled, in which case I would just give the new value to the selected
signal, and in the contrary case (ie: no write enabled), give all IO signals
the Z value... Inside the comms component of course... but the compiler
complains.

Think I'll give it a small rest and think it over...

"David R Brooks" <> wrote in message
news:...
> If you do use a bidirectional bus, the receiving end should normally
> be set to 'Z'. Basically, the two ends will always "fight" each other,
> but std_logic being a resolved type, rules exist for resolving these
> conflicts. "Z" will always yield to the other end's value, so you can
> receive the signal.
>
> "minkowsky" <> wrote:
>
> :
> :"David R Brooks" <> wrote in message
> :news:.. .
> :> If all you want is to be able to alter a signal's value *from within
> :> the block*, then see that change both inside & outside the block, the
> :> keyword is "buffer", not "inout".
> :
> :I'll look into that one
> :thanks.
> :
> :> You only need "inout" if you really intend a bidirectional bus, which
> :> will be explicitly driven to "Z" at the receiving end.
> :
> :That might be the reason I have problems. I understand from what U say

that
> :I should set to Z outside of my comms componnent.
> :
> :I'll try that one too.
> :
> :Thanks Again for the tips
> :
>



 
Reply With Quote
 
minkowsky
Guest
Posts: n/a
 
      02-24-2004
"Eyck Jentzsch" <> wrote in message
> Your comms is driving a U to the outside world of both pins. This
> prevents updating the internal signal. You should set mem0 to 'Z' inside
> your comms architecture (you can do it with an concurrent assignment
> since you signals are resolved ones)
>
> -Eyck
>



I tried the following... but it doesn't work as expected... (it is a
simplified version of what I was planning to use (more mems, 64 bits per mem
in my actual code)

The value I write in mem1 is correctly written (I can read it back from my
homemade PC's software), but mem2 is not changed (unless I write in it
myself).

This ZZZZ thing is puZZZZling me to say the least.

Anyone has a suggestion so I can modify mem1 outside of my comm component
justby writing to mem0?

Thx,
Mink

---================================================
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity comms is
-- the actual ports of the device given by the EZUSB chip
Port ( p_rd : in std_logic;
p_wr : in std_logic;
p_address : in std_logic_vector(7 downto 0);
p_data : inout std_logic_vector(7 downto 0);

-- the 2 mems I want to use both ways in other components

p_mem0: inout std_logic_vector(7 downto 0);
p_mem1 : inout std_logic_vector(7 downto 0);
);
end comms;

architecture Behavioral of comms is
signal selector: std_logic_vector (2 downto 0);
signal part: std_logic_vector (2 downto 0);
signal value: std_logic_vector (63 downto 0);
signal partvalue: std_logic_vector (7 downto 0);
begin

PartSelector: process (p_address)
variable l_sel:std_logic_vector (2 downto 0);
variable l_part: std_logic_vector (2 downto 0);
variable l_value: std_logic_vector (63 downto 0);
begin
l_sel:=p_address(6 downto 4);
l_part:=p_address(2 downto 0);

-- we choose the block we (might) want to read next
-- the actual code reads up to 8 addresses
if l_sel = "000" then
l_value:=p_mem0;
elsif l_sel = "001" then
l_value:=p_mem1;
else
l_value:=(others=>'0');
end if;

-- we extract the part we want... (out of 64 bits)
-- but here we stick to 7 bits... so nothing to be done
partvalue<= l_value (7 downto 0);

part<=l_part;
selector<=l_sel;
value<=l_value;
-- We end up with the partvalue and the selector
end process;

writeproc: process (p_wr, selector,part) -- we wanna write something
variable l_value: std_logic_vector (63 downto 0);
begin

if p_wr = '1' and p_wr'event then
-- we grab the area we want to use so we can get the info needed
-- and don't change everything at the same time
if selector = "000" then
l_value:=p_mem0;
elsif selector = "001" then
l_value:=p_mem1;
else
l_value:=(others=>'0'); -- all other case we don't deal with IO,
just OUTs
end if;

--- actual code is using 64 bits signals, 7 bits at a time
--- so here it is only one line
l_value (7 downto 0):= p_data;

-- we then drive the value into the correct mem block
if selector = "000" then
p_mem0<=l_value;
p_mem1<=(others=>'Z');
elsif selector = "001" then
p_mem1<=l_value;
p_mem0<=(others=>'Z');
end if;
end process;

readproc: process (P_rd,partvalue)
-- you wanna read something?
begin
if p_rd='1' then
P_data <= "ZZZZZZZZ";
else
-- lets rock and roll ... here you are with the part value u asked
p_data<= partvalue;
end if;
end process;


end Behavioral;

-----================================================== =====================
======================
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;


entity tester_comms is
Port ( clock: in std_logic;
p_oe_n: in std_logic;
p_wr_n: in std_logic;
p_address: in std_logic_vector (7 downto 0);
p_data: inout std_logic_vector (7 downto 0);
p_led0,p_led1,p_led2,p_led3: out std_logic
);
end tester_comms;


architecture Behavioral of tester_comms is

signal IO_0,IO_1: std_logic_vector (63 downto 0):=(others=>'1');
COMPONENT comms
PORT(
p_rd : IN std_logic;
p_wr : IN std_logic;
p_address : IN std_logic_vector(7 downto 0);
p_data : INOUT std_logic_vector(7 downto 0);
p_mem0 : inout std_logic_vector(63 downto 0);
p_mem1 : inout std_logic_vector(63 downto 0);
);
END COMPONENT;

begin
Inst_comms: comms PORT MAP(
p_rd => p_oe_n,
p_wr => p_wr_n,
p_address => p_address,
p_data => p_data,
sync => clock,
p_mem0 => IO_0,
p_mem1 => IO_1,
);

process (IO_0)
variable tmp: std_logic_vector(63 downto 0):=(others=>'1');
begin
io_1<=io_0 xor tmp;
end process;

--process (IO_1)
-- variable tmp: std_logic_vector(63 downto 0):=(others=>'1');
--begin
-- io_0<=io_1 xor tmp;
--end process;

end Behavioral;

=> we should get a new value in the second mem block mem1 each time we
change mem0
but that doesnt work


 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
Connecting an inout port to another inout port THurkmans VHDL 14 08-11-2009 08:32 PM
How to relate a SQL based entity with an Object based entity in Entity Framework markla ASP .Net 1 10-06-2008 09:42 AM
inout to inout Ken VHDL 2 05-09-2008 01:56 PM
connecting std_logic inout ports and std_logic_vector inout port =?ISO-8859-15?Q?Fr=E9d=E9ric_Lochon?= VHDL 3 11-08-2007 03:55 AM
How can I have multiple drivers of one inout port? cruzin VHDL 2 01-23-2004 05:03 PM



Advertisments
 



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57