INOUT port on entity

M

minkowsky

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.
 
E

Eyck Jentzsch

minkowsky said:
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
 
M

minkowsky

Eyck Jentzsch said:
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.
 
M

Mike Treseler

minkowsky said:
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
 
D

David R Brooks

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.


: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.
:
 
M

minkowsky

David R Brooks said:
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 :-D
 
M

minkowsky

Mike Treseler said:
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 ;-)
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.
 
D

David R Brooks

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.


:
::> 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 :-D
:
 
M

minkowsky

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... :)
 
M

minkowsky

Eyck Jentzsch said:
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 :-(
 
M

minkowsky

I'm not sure in really understand this Z thing.

Could it be that the components interface functions as a mirrored glass:

if the light is on on your side, you see only yourself, and if you switch
off the light, then you can see what is on the other side? (in our case, we
turn on the light by setting a 0/1 value to the port and we turn off the
light by setting this side's value to Z)

And that count for both side of the mirror/interface? (ie: if the inside of
the component wants to see what is outside, he should first set the value to
Z, then read, and if the outside wants to see the value set by the component
he should first set the value to Z before reading?)

Then what if both side set the value to Z?

Ain't there a way to treat this as a property (like in an object oriented
language)?

Thx for your feedback,
Mink.
 
M

Mike Treseler

minkowsky said:
I'm not sure in really understand this Z thing.

A 'Z' on a fpga pin means no current in or out.
It is the arbitration value for outputs tied together.
It means, drive nothing to the pin.
It means let one external device or other process use the pin.

It is only needed for top level interfaces
to RAM, uPs or other bidirectional devices
where two or more outputs are shorted together.

There are no 'Z' values used inside the fpga except
to drive bidirectional pins.
Inside the fpga you use separate input and output buses instead.
Could it be that the components interface functions as a mirrored glass:

A component interface is best used to
wire together multiple tested and trusted
entities into a larger design.
And that count for both side of the mirror/interface? (ie: if the inside
of the component wants to see what is outside, he should first set the
value to Z, then read, and if the outside wants to see the value set by
the component he should first set the value to Z before reading?)

Yes, but you still need one key ingredient to
keep the outputs digital.

One side or the other must *arbitrate* the
interface so that all outputs
drive 'Z' *except one*.
As John Lennon said,
"I mean, it must be high or low."

External arbitration pins have names like OE, CS, WE etc.
Getting the enable and data direction right
is up to you.
Then what if both side set the value to Z?

That means the pin/bus is idle.
Ain't there a way to treat this as a property (like in an object oriented
language)?

You have to either describe the
"sharing of the wire" or don't share it.

-- Mike Treseler
 
M

minkowsky

It seems awfully complicated.

I understand that in a traditionnal VHDL view, a component is supposed to be
two sided with the flow of info going through (in from one side, and out
from the other). but to be interesting (to guys like me who have a personal
computer in their life) the final component really has to be able to have 2
way communications... otherwise it's just some leds flashing in the night...

I really thought I could achieve a generic 2 way comms component that could
be used to talk to ANY other component (payload) I could add to my design
without ever needing to think about the comms issue again and focus on the
(real) work done by my payload component... :-(

If I use the inout ports, I guess it'll mean a lot of plumbing/syncing on
the other side of the interface. In software engineering that's VERY bad
because it means "strong coupling" between two component that should ignore
everything about the way the other one is implemented. If I touch the comms,
it impacts the payload and vice versa. (yuck!).

Mike Treseler said:
A 'Z' on a fpga pin means no current in or out.
It is the arbitration value for outputs tied together.
It means, drive nothing to the pin.
It means let one external device or other process use the pin.

It is only needed for top level interfaces
to RAM, uPs or other bidirectional devices
where two or more outputs are shorted together.

There are no 'Z' values used inside the fpga except
to drive bidirectional pins.
Inside the fpga you use separate input and output buses instead.

Understood... That means there are 2 kinds of components: oriented ones with
2 sides (ins and outs) and outside components (with inouts that should never
be included inside another one...). That sounds limitative.
glass:

A component interface is best used to
wire together multiple tested and trusted
entities into a larger design.

I was trying just that:
C a trusted comms component
P a trusted payload component
F a final component encapsulating both C and P giving the final component
both the ability to communicate and the ability to "work".
Yes, but you still need one key ingredient to
keep the outputs digital.

One side or the other must *arbitrate* the
interface so that all outputs
drive 'Z' *except one*.
As John Lennon said,
"I mean, it must be high or low."

External arbitration pins have names like OE, CS, WE etc.
Getting the enable and data direction right
is up to you.

You mean I must have some kind of switch that tells which side is lead on
the INOUT port, so only one side at the time tries to (open the light) set
the value.
That means the pin/bus is idle.

Is it a bad thing? in my mirror model, it means it's pitch black, but in the
FPGA world, does it mean trouble?
You have to either describe the
"sharing of the wire" or don't share it.

Looks like a jedi moto to me "do not try, there is no try, do or do not" :)

What do you mean? sharing of the wire=inout, right? don't share= in OR out
but not both, right? So if I decide to share, is my mirror model correct?
should I find a way to coordinate the lights on both side of the mirror?

Ain't there a right way (ie: classical, documented) of doing what I'm
attempting to do (ie: 2 component who can talk both ways to each other)? I
mean, it looks like I'm reinventing the wheel.

When a component talks to a RAM, how does it do it? I mean, at some point or
another, it _does_ write something and at some other point it _does_ read
it, right? typical inout problem. There has to be a way to encapsulate this
complexity... how about some global variable? is that possible?

....

I'm frustrated because I feel this thing is _so_ common (or at least
generic), that spending so much time trying to solve it seems a waste to
me... I can't believe the guys who devised the langage (or the compilers, or
the libraries) in the first place never had a need for this (and devised a
simple solution).

Thanks,

Mink.
 
M

Mike Treseler

minkowsky said:
It seems awfully complicated.

It's just gates and flops.
I understand that in a traditional VHDL view, a component is supposed to
be two sided with the flow of info going through (in from one side, and
out from the other). but to be interesting (to guys like me who have a
personal computer in their life) the final component really has to be able
to have 2 way communications... otherwise it's just some leds flashing in
the night...

If it's a pc you want to talk to, consider ethernet or usb.
I really thought I could achieve a generic 2 way comms component that
could be used to talk to ANY other component (payload) I could add to my
design without ever needing to think about the comms issue again and focus
on the (real) work done by my payload component... :-(

Why not write and sim the guts first?
This will take longer than you think.
Adding an I/O interface is really not that big a deal.
ignore everything about the way the other one is implemented. If I touch
the comms, it impacts the payload and vice versa. (yuck!).

In fpga design, you decouple by writing a sim testbench
that you can quickly rerun after each change, to make
sure nothing got broken.

Use of variables, functions and procedures instead of straightline code
makes changes less likely to cause unexpected effects.
Understood... That means there are 2 kinds of components: oriented ones
with 2 sides (ins and outs) and outside components (with inouts that
should never
be included inside another one...). That sounds limitative.

There is no requirement to use components at all except
in testbench code. I prefer to use a minimum number
of processes in a single entity for synthesis.
This makes things as algorithmic as possible.
You mean I must have some kind of switch that tells which side is lead on
the INOUT port, so only one side at the time tries to (open the light) set
the value.
Yes.

Is it a bad thing?

No, idle is just fine. That's how most fpga's power up.
What do you mean? sharing of the wire=inout, right?

Yes, it's time multiplexed, sometimes in, sometimes out.
but not both, right? So if I decide to share, is my mirror model correct?
should I find a way to coordinate the lights on both side of the mirror?

You should find a way to start writing and siming some code.
Ain't there a right way (ie: classical, documented) of doing what I'm
attempting to do (ie: 2 component who can talk both ways to each other)? I
mean, it looks like I'm reinventing the wheel.

Yes: ethernet, usb, rs232 etc. etc.
When a component talks to a RAM, how does it do it? I mean, at some point
or another, it _does_ write something and at some other point it _does_
read it, right? typical inout problem. There has to be a way to
encapsulate this complexity... how about some global variable? is that
possible?

How about an output signal named OE?
I'm frustrated because I feel this thing is _so_ common (or at least
generic), that spending so much time trying to solve it seems a waste to
me...

You are right about that.
I can't believe the guys who devised the langrage (or the compilers,
or the libraries) in the first place never had a need for this (and
devised a simple solution).

If they had, VHDL would be much less flexible.
Should Intel start hard-coding Basic or Forth into their uPs
to isolate me from the MOV instruction?

-- Mike Treseler
 
M

minkowsky

I've finaly decided to dump the inouts altogether...
I use buffers to be able to read back the config values and a bit in the
address to decide if I want to read the old value or the computed value.
No ZZZZZs no complicated things and my code is cleaner.

Mike Treseler said:
It's just gates and flops.

This inout thing, I meant. writing inout at one place has too many
repercutions on so many modules of my code is plain bad.

But now, with your help and insights, I've finaly got my stand-alone
component. It handles all the comms and there is no way an outside
component's actions can break it. Zero coupling.
If it's a pc you want to talk to, consider ethernet or usb.

I'm using usb and an ezusb chip in between my spartan and my pc's usb port.

Is there any other way I should know about?
Why not write and sim the guts first?

By guts you mean payload?

It was written first, and simmed. and then I wrote the comms part, and sent
all that thing into the fpga and found out it didn't work as expected. Seems
the comms were luring me into thinking that the info I wrote on the usb port
really reached the payload. so I tried to debug the comms, and found out
(after visiting this NG) I wasn't quite using the inouts like I should
have... or at least that my understanding of what an inout port was false.
This will take longer than you think.

What will?
Adding an I/O interface is really not that big a deal.

well... :) being completely a newbie at this sport, it really took me at
least 2 weeks to make it work... while the payload took me about the same
time... And I thought the payload would really be the hard part to get
working.

(Now I have too many slices, my comms + payload is too fat. and maybe once
refined, the resulting payload won't work anymore... But I'm prepared
psychologicaly to face that kind of hazard)
In fpga design, you decouple by writing a sim testbench
that you can quickly rerun after each change, to make
sure nothing got broken.

I saw a testbench posted by someone (you maybe) and I'm very far from being
able to automate anything the way it was done.

But then again, I'm a complete newbie. My main line of work is software
engineering (not embeded) and I 'm trying to achieve parallel computing by
using a fpga for some fast int computation.
Use of variables, functions and procedures instead of straightline code
makes changes less likely to cause unexpected effects.

Someone warned me about those not being such a good idea if comming from the
non embeded software world. I tried to imerse myself into the
component/entity philosophy (at least the way I percieved it) and up until
now the results have been quite encouraging. Something I have to check
though is that too many components embeded into one another don't slow
things down or make the code too fat.
There is no requirement to use components at all except
in testbench code. I prefer to use a minimum number
of processes in a single entity for synthesis.
This makes things as algorithmic as possible.

but I thought the whole point of vhdl was concurent computing instead of
process/serial computing?

And that making components allows us to "divide and conquer", modules by
modules; and also component seemed the nearest thing to an object I could
find.

At some point I had processes and functions and procedures, but I found the
mix wasn't such a good idea (or at least harder to synchronize for the
newbie that I am)... but that was at a time when I knew nearly nothing (less
than now, I mean ;-) ).

You should find a way to start writing and siming some code.

When I'll be a jedi, I'll refine the way I work...

But right now, I need my project to work (there's a payload, a comms
component, a pc side library and the corresponding GUI to load the rbt file
and to control the beast...).

The comms now work fine. the payload works fine under the sim (but I haven't
tested the timings - and don't know how to... there is a huge chapter on
this in the book I use... My approach is try to slow down the computation as
much as possible and see if things work as expected. If so, I raise the Mhz
up untill things start to break. If the speed limit is high enough, I stay
that way. If not, I guess I'll have to switch to siming...)

The pc side library is well under way (it's not packaged yet, but the
various functions are all over my present code), the GUI is functionnal, but
the errors are not correctly handled (ie: if I unplug the fpga board).

It's a prrof of concept thing... Having a board that anyone could use to do
the things we want.
Yes: ethernet, usb, rs232 etc. etc.

Yes there is?
hum... I'm using an spartan fpga... My feeling is that it would be easier to
use dedicated chips (ezusb, max232 etc) for all of those and use the fpga
for data processing. am I wrong there?

but what you say is interesting, I also have a small lcd screen I was
wondering I could use or not. Its controler talks in 19kbps serial. I was
wondering if it was hard (or if the resulting code was big) to have those
two communicate.
How about an output signal named OE?

??

I did use WR and OE (from the example code I got with the ezusb thing), but
don't really know what they mean.
Must be a traditional thing (of the foo/foobar type) from the embeded
world. :)

You are right about that.

right about what? that I'm wastying my time?? (then yours too, I guess,
sorry sorry)
Or that it is so common? I have two books on the subject and both fly over
the ZZZZs and INOUT in about a page or two.
If they had, VHDL would be much less flexible.
Should Intel start hard-coding Basic or Forth into their uPs
to isolate me from the MOV instruction?

??? I can code in delphi and switch to low level MOV,JPZ etc code whenever I
wish (all I need is to start an asm inline block of code). but it does
provide the high level things I need to write code fast. (I believe that can
be done in C++ too...).

That way I can focus on the result and if I need to look into the small
details of code (to refine things, make the code leaner, faster etc), I can
override his jugdment and tell him how I want things to be done.

Of course the higher the level, the fatter the code...

But take the := in vhdl processes. It's quite magical. Suddenly you're not
talking wires anymore, nor concurrent programming; and the compiler handles
the complexity for you. he translates those high level commands to low level
wirings.

or again, the + - * / so many people use in vhdl. those are high level
notations that do magical things without your knowing... Do you really feel
the langage is less flexible because of the existence of those operators?
you can do without them and write your own primitives if you wish. But
still, I bet most of the time most people use the operator notation instead
of their own cascading muxes (I believe that's the way it's done, right?).

if they decided to have a magical inout_V2, that would take the value of the
last "drive" to have taken place, and some kind of automagic resolution of
conflict when 2 (or more) drive take place at the same time... wouldn't that
be great? it would generate some "micro vhdl code" that we could study and
refine if we want... and you could still do the same thing in your own
precise way... would you really feel restrained or betrayed by the compiler
if that V2 existed?

The point is providing a high level fucntion doesn't have to isolate you
from the inner lower level sub functions.

But that's a philosophic issue... I agree :) (And whatever we say, things
are the way they are and we'll have to make do with what we have ;-) ).

Anyway, you've been a great help to solve my current problem(s) and your
inputs where enlightening to say the least.

Thank you for your time,

Mink.
 
J

Jonathan Bromley

It seems awfully complicated.

Hardware is complicated. That's why we often find that software
weenies can't deal with it :)

Seriously though, you have a valid point for *modelling*, although
I suspect you are completely missing the *electronics design*
ramifications of what you're saying.

We spanner-wielding, dirty-handed hardware grunts also have
communications-oriented ways of modelling things. Find out about
SystemC channels, for example. Problem is, in the real world of
hardware you need an awful lot of detailed infrastructure to
make it work. If there had been no horrible strongly-coupled
designs around to make the hardware, how do you think you could
colonise your object-oriented ivory tower that you've built
on your PC?
I really thought I could achieve a generic 2 way comms component that could
be used to talk to ANY other component (payload) I could add to my design
without ever needing to think about the comms issue again and focus on the
(real) work done by my payload component... :-(

For that you need a standardised interface of some kind, surely,
otherwise the comms component will find that it can't talk to
anything else, which rather defeats its purpose. The conventional
bidirectional parallel bus is one such interface. If you want to
plaster a network layer on top of that, you're very welcome to do so.

If you are only modelling, and you don't need to create real hardware,
then it's fairly easy to create such bidirectional communications
using custom VHDL resolution functions. But that conversation
should be saved for another day...
If I use the inout ports, I guess it'll mean a lot of plumbing/syncing on
the other side of the interface. In software engineering that's VERY bad
because it means "strong coupling" between two component that should ignore
everything about the way the other one is implemented.

Unfortunately, the physical wires that are tiresomely required
to link the physical transistors inside the two physical components
will of necessity impose strong coupling between them. Decoupling
is achieved by standardising the interface that's used.
If I touch the comms,
it impacts the payload and vice versa. (yuck!).

Yup. Standardise, standardise, standardise.

I guess the nearest software parallel would be this: Your
"generic comms component" can work only if the compiler provides
you with standardised calling conventions, allowing any one
function to invoke any other and pass it argument values.
Your desired "generic" behaviour is all predicated on that.
You could not create a "generic comms component" that could
link two objects written in entirely different programming
languages and running on entirely different operating systems;
instead you would need to provide adaptors or bridges that would
match each end to the generic interface standard (TCP/IP?).

--

Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * Perl * Tcl/Tk * Verification * Project Services

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail: (e-mail address removed)
Fax: +44 (0)1425 471573 Web: http://www.doulos.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
M

minkowsky

Jonathan Bromley said:
Hardware is complicated. That's why we often find that software
weenies can't deal with it :)

Ho so that's the reason I have problems !! ;-))
Seriously though, you have a valid point for *modelling*, although
I suspect you are completely missing the *electronics design*
ramifications of what you're saying.

Hum, yes, certainly... Some of the things that my compiler generates don't
always look useful to me (but I'm sure he knows his job better than I do and
that he's just doing what I ask him to do )
We spanner-wielding, dirty-handed hardware grunts also have
communications-oriented ways of modelling things. Find out about
SystemC channels, for example. Problem is, in the real world of
hardware you need an awful lot of detailed infrastructure to
make it work. If there had been no horrible strongly-coupled
designs around to make the hardware, how do you think you could
colonise your object-oriented ivory tower that you've built
on your PC?

"your object-oriented ivory tower " ?? wow. Did I crush your finger, stepped
on your lawn? Do you see the evolution of the way people do electronics as a
threat to your career?

So sorry for anything I might have done to you...

Please note that I'm well aware of the complexity of things at the lower
level.

Don't think that I do object oriented things out of fun. I do them because
that's the fastest way of doing things (time being the only thing we possess
in limited quantity). I know it does have a cost (bigger software, faster
hardware and such), that I am paying willingly.

Those software engineering devices called objects are the result of hard
life evolution. Decoupling is not just for my own convenience, it is also to
allow industrialization of processes. It'll allow some other guy to reuse my
component or derive from it. And I'm no specialist, but I'm pretty sure
that's how professionals in the electronic field are working too (I can't
imagine the chips that are built today don't rely heavily on object
orientation of some kind, if not at the design level, at least at the
silicon level).

Of course you'll see people doing software programming the old way, but IMHO
they won't last long... I believe that's the direction history takes. Look
at everything around you: components with standardized interfaces are
everywhere, from power outlets, window frames, car parts, airplanes, etc...

Divide and conquer.... To my (limited?) knowledge, that's one of the best
way to treat difficult problems. and to be able to prove that what you built
works too.

You can of course decide to tackle any problem you meet as a whole, and if
that's your quest, well, I wish you all the luck... :)

I guess that's the main difference of point of view between industrials and
craftmen.

Both accomplish interesting things, mind you.
For that you need a standardised interface of some kind, surely,
otherwise the comms component will find that it can't talk to
anything else, which rather defeats its purpose. The conventional
bidirectional parallel bus is one such interface. If you want to
plaster a network layer on top of that, you're very welcome to do so.

?? Is this what I achieved? wow, I'm better than I thought I was :)

If you are only modelling, and you don't need to create real hardware,
then it's fairly easy to create such bidirectional communications
using custom VHDL resolution functions. But that conversation
should be saved for another day...

If you read the previous posts, you would have seen that I'm not simming
enough according to one of the other helpful guy here. I'm working on my own
hardware. PC, usb port, ezusb chip, spartan. and it works fine now, thanks
to our friends on this NG.

This is what I do: "while not (perfect) do {modifs, compile, upload into
hardware, test}"... no simming AT ALL.
Unfortunately, the physical wires that are tiresomely required
to link the physical transistors inside the two physical components
will of necessity impose strong coupling between them. Decoupling
is achieved by standardising the interface that's used.

If what you say is true, then we have a paradox: how did I manage to make an
non coupled design??

Four possibilities: My design doesn't work, my design is coupled, or you
should reconsider your point of view. ;-) Or I didn't understand what you
wrote.
Yup. Standardise, standardise, standardise.
I guess the nearest software parallel would be this: Your
"generic comms component" can work only if the compiler provides
you with standardised calling conventions, allowing any one
function to invoke any other and pass it argument values.
Your desired "generic" behaviour is all predicated on that.

I use only components.

My way of seeing things is that once the interface of my component is set,
once the contract is made, the outside components should just rely on the
fact that they give the interface the correct data (with no pre treatment)
and expect the contract to be fulfilled.

Once you've achived this, you've decoupled both components to the max.

The discussion was about INOUT ports between components. My point was that
those kind of ports encourage bad practise because they force you to have
code on both side of the interface to deal with what is happening on the
other side of the interface (through the use of ZZZZs and OEs and stuffs on
both side). Both sides must be in sync (operational wise).

Now if you use Buffers, in and out ports, you can manage an interface where
the inside doesnt care how the data is used on the outside and the outside
doesn't care about how things are done on the inside (as long as it respects
the contract, of course).

That's what I did in the end. And the way I see it my component is generic.
It does talk to my usb port both ways and to my other components both ways.
You could not create a "generic comms component" that could
link two objects written in entirely different programming
languages and running on entirely different operating systems;
instead you would need to provide adaptors or bridges that would
match each end to the generic interface standard (TCP/IP?).

Yep, multi layer style programming (that's encapsulation, middleware and all
those ivory tower stuffs you dislike ;-) ).

Is that so hard to achieve/conceive?

Regards,

Mink.
 
J

Jonathan Bromley

minkowsky said:
"your object-oriented ivory tower " ?? wow. Did I crush your finger, stepped
on your lawn?

Nope. Just gave me an opportunity to make fun of a cultural
difference.
Do you see the evolution of the way people do electronics as a
threat to your career?

No; I've been evolving the way I do electronics for twenty-five
years already, and see no reason to stop now.
Don't think that I do object oriented things out of fun. I do them because
that's the fastest way of doing things (time being the only thing we possess
in limited quantity). I know it does have a cost (bigger software, faster
hardware and such), that I am paying willingly.

Electronic components have an "object-oriented" feel to them, and
have had for a long time. The data sheet looks like a class
definition, and we instantiate the things by plugging 'em into
sockets. Different versions of a device, and mode control
inputs, give us an admittedly weak form of inheritance. Many
of us are looking forward to a hardware description language
(VHDL-200x, perhaps) that pushes that likeness much, much further.
You don't need to convince me that OO design styles are worth the
effort.

[...]
Look at everything around you: components with standardized interfaces are
everywhere, from power outlets, window frames, car parts, airplanes,
etc...

And, dare I say it, bidirectional buses. I can only guess here, but
I suspect that our mutual misunderstanding is partly because you
are in some way hoping for an inout port (or, more specifically,
two inout ports linked by a signal) to form a self-sufficient
bidirectional communications link. The reality is that such a link
can be implemented only with the help of some additional control and
synchronisation signals. This larger ensemble of signals CAN be
treated as a standardised, self-contained interface - although for
practical reasons it's normal to make it somewhat asymmetric, with
one end acting as master and the other as slave. It is possible
to build distributed, symmetrical arbitration schemes, but it's
tricky and usually inappropriate.

VHDL is not perfect for this, since it lacks any kind of type
parameterisation (type templates). However, something close
to this goal can be achieved using packages to tweak the
data type of the payload part of your interface.

[...]
This is what I do: "while not (perfect) do {modifs, compile, upload into
hardware, test}"... no simming AT ALL.

I find that a strange strategy. Simulation gives you vastly better
control and visibility of the design than hardware prototyping,
and therefore more reliable and productive debugging. Hardware
prototyping has its place, particularly later in the design cycle
where (a) you want to push large amounts of data through the
design very quickly and (b) you want the design to interact with
real running software on a real running machine. But it's much
less helpful early in the process.

[...]
My way of seeing things is that once the interface of my component is set,
once the contract is made, the outside components should just rely on the
fact that they give the interface the correct data (with no pre treatment)
and expect the contract to be fulfilled.

I reckon that's my way of seeing things too, but I'm not quite sure
what you mean by "with no pre treatment"; in hardware you ALWAYS need
some kind of synchronisation signal, strobe, clock or the like in
order to push data into a port, or out of it. In every other sense
I totally agree with you.
Once you've achived this, you've decoupled both components to the max.
The discussion was about INOUT ports between components. My point was that
those kind of ports encourage bad practise because they force you to have
code on both side of the interface to deal with what is happening on the
other side of the interface (through the use of ZZZZs and OEs and stuffs on
both side). Both sides must be in sync (operational wise).

Yes, and there are a few synchronisation signals forming part of the
interface, so that the interface remains fully defined and no component
needs magical knowledge of the behaviour of any other - except what it
can see at its own interface. In this regard VHDL has a significant
weakness: although you can make signals of record type, you can't
easily use this feature to encapsulate the various data and control
signals that form a bidirectional interface, because every element
of a record port must have the same direction (in, out or inout).
If this were not so, you could make an "interface class" that
could be instantiated on a port, which would be good. In the absence
of such facilities, we must be content with an interface that is
made up of several distinct signals that, sadly, we cannot
encapsulate.
Yep, multi layer style programming (that's encapsulation, middleware and all
those ivory tower stuffs you dislike ;-) ).

Tee hee. Hardware people spend large fractions of their working
lives building bridges between disparate standardised interfaces.
I'm afraid we got there before you :)

Thanks for rattling my cage. It's always good to have your
long-standing assumptions challenged. But I think that, in the
end, we will be seen to have a remarkably similar approach.

--

Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * Perl * Tcl/Tk * Verification * Project Services

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail: (e-mail address removed)
Fax: +44 (0)1425 471573 Web: http://www.doulos.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
J

Jonathan Bromley

minkowsky said:
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.

[...]

I just re-read most of this thread, and I *think* that my poor aged
brain has finally kicked-in and worked out why you were having
so much difficulty with this, and why many people (me included)
didn't quite see why you were having so much difficulty.
Please forgive me if I take this one step at a time...

You had two component instances, both able to drive the same
shared signal through their inout ports.

You were, if I understand it correctly, hoping that within each
of these component instances you could look at this common
signal and read from it whatever value had most recently been
written to it *by either of the two components* .

This didn't work, for reasons that are obvious to experienced
VHDL users but far from obvious to others, and you were
understandably frustrated that each component had to write
Zs to the common signal in order to see what the other
component had written.

Now, at long last, I think I see where you're coming from.
Sorry it took me so long. I'm also aware that you have
solved the problem independently by using a full-duplex
comms scheme, but it is still interesting to understand
why your original scheme makes no sense in VHDL.

So, here's an explanation that may possibly help.

Each of your two components contained a process that
was driving the shared signal. That process maintained
its own local state containing the value most recently
written BY THAT PROCESS ONLY. Each process is
permanently and continuously driving its own local value
on to the signal. However, any process attempting
to *read* the signal's value will see a so-called
"resolved" value, representing the combined effect of
all processes driving values on to that signal. This,
of course, makes perfect sense for electronic hardware
whose component parts are linked by conductors. It
is very far from a traditional software arrangement
in which any object's state is a single piece of
storage that can be written from various places and
that stores only the most recently written value.

In Verilog, the other popular hardware description
language, it is possible to represent the
"most-recent-update" mechanism that I believe you
were hoping for. However, it doesn't map on to
sensible hardware and therefore it is not likely
to be synthesisable.

In a VHDL simulation, but not in real hardware,
a process can read back the value that it
has most recently written, using the 'DRIVING_VALUE
attribute of a signal. What you cannot do, however,
is to read the individual driving values of any
other processes - you can see only the resolved value
of all the processes driving a given signal. Hence
the need to assert Z on to your signal if you wish
to read it, because the resolved value of Z with
any other driver is the other driver's value -
Z represents "undriven".

=====================================================

The net result of all this is that if you want to use
a single common signal to carry values from more than
one source, you must somehow multiplex the values.

The most obvious approach is straightforward time-division
multiplexing, which is what happens in a typical multi-drop
hardware bus structure. You can get excellent decoupling
of your components this way, but you will definitely need
a handful of additional signals to carry control and timing
information, and you will need some kind of arbitration
scheme to ensure that only one driver is driving a value
other than Z at any one time. For a link between only
two components, this arbitration is not at all difficult.

Other multiplexing schemes are possible, although they
are unlikely to be supported by the resolution function
for std_logic signals, and they may not be synthesisable.
This is what I was alluding to in my other post when I
mentioned custom resolution functions.

What you were trying to do is much closer to a shared
or multiport memory idea than it is to traditional
electronic signals. You can, of course, implement
shared memory in VHDL - but not as a side-effect of
the standard signal mechanism.

--

Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * Perl * Tcl/Tk * Verification * Project Services

Doulos Ltd. Church Hatch, 22 Market Place, Ringwood, Hampshire, BH24 1AW, UK
Tel: +44 (0)1425 471223 mail: (e-mail address removed)
Fax: +44 (0)1425 471573 Web: http://www.doulos.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
B

Brian Drummond

I'm not sure in really understand this Z thing.

Could it be that the components interface functions as a mirrored glass:

if the light is on on your side, you see only yourself, and if you switch
off the light, then you can see what is on the other side? (in our case, we
turn on the light by setting a 0/1 value to the port and we turn off the
light by setting this side's value to Z)

Quite a good analogy.
The only way to see what's on the other side is to switch your own light
off. But even that is not enough - the other side also has to switch his
light on - drive a signal value instead of "ZZZZ".
And that count for both side of the mirror/interface?

Yes. If the other side wants to see you, he has to switch his own light
off. But even then, he can't see you unless your light is on.

And this is the key. One way to solve it - easy and reliable - is to put
one entity (you) in control - you have both (or all) light switches,
with a wire going through the mirror frame to control the other light.

Another is to broadcast an address to all the lights (including your
own), AND a single "On" signal. The addressed light obeys the "On"
signal, all others remain off. That way either all lights are off, or
only one is on.
Then what if both side set the value to Z?

It's dark.

Which usually isn't a problem. But if you are still watching, and acting
on what you see,(say, to fire the missile) THAT could be a problem,
because electrical interference can create "hallucinations" on the bus.

Now if both lights are on, you have a problem. It is possible to destroy
hardware this way (though you are not likely to, inside an FPGA, only on
its output pins). If one side is driving a wire with '1', and the other
with '0', the stronger one will win, and it is possible to burn one or
both out in a puff of smoke.
Ain't there a way to treat this as a property (like in an object oriented
language)?

Not exactly. The problem is not in VHDL, but in the hardware it is
trying to model. There ARE some simple and clean ways of enabling only
one driver (light) - hopefully the above will give some ideas. You are
right that it CAN get complicated and ugly, but it doesn't have to if
you pick a simple interface standard and stick to it.

- Brian
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,767
Messages
2,569,570
Members
45,045
Latest member
DRCM

Latest Threads

Top