INOUT port on entity

M

minkowsky

Jonathan Bromley said:
Nope. Just gave me an opportunity to make fun of a cultural
difference.

Oki... no problem then. Thought for a second that you wanted to have a bite
at me :)

Many
of us are looking forward to a hardware description language
(VHDL-200x, perhaps) that pushes that likeness much, much further.

I'll be waiting in line too, then... :)

I sure would like some kind of preprocessor thing to tweak things depending
on the weather, my mood and of course the target platform and testbenches.


etc...

And, dare I say it, bidirectional buses.

lol :-D
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.

Yes... Something like that did cross my mind.
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.

That's what happens each time you have two same device talking to each
other.
I realize maybe in real life, the truth is they usually play
paper-cisor-stone to determine who will be master and slave...
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.

Yep... The lack of pre processor/template processor really seemed odd to me.
At one point I was even considering learning langages like ruby to generate
my code automagically with template files and all.
I find that a strange strategy.

Well, I like to see my leds light up :)

And I'm a complete newbie (hadn't known anything about vhdl 2 months ago),
so my first move was to buy a study board and try things on it. then came
the ISE and the whole environment... I discover new things every day.

I did some simming at first, because I had no way of talking to my fpga. But
now, I'm really happy he and I can start communicate. Doing things in
simland really seemed like building things in a vacuum... not concrete. And
also I suspected that in some way the sim wasn't really like real life's
test. As it turned out to be the first time my whole chip began overheating
(or seemed to) because of what I suspect is metastability.

Another guy here told me to turn back to simming.

I believe I'll really have to each time the board acts in an unexpected (and
most of all, incomprehensible way).

I really wanted to check that I really could achieve a GUI on my pc that
could reflect the internal state of my board, before dwelling further in
simland (after all, there might have been things I just couldn't do -lack of
knowledge, time, skill, whatever...).
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.

Well, my payload was already working as expected in the sims (at the time,
that's all I had to test things). Turned out it was too big by itself, that
I made some assumptions that turned out to be wrong and that my comms
component added more slices to the thing. I finaly managed to make
something that fitted in my spartan. Only to find out the comms didn't
behave as expected. Debugging with the pc GUI was easy enough to understand
where the problem laid and feed the beast with test data.

Now I have the comms working fine, I also found out that metastability in
the rest of the design would impair the correct functionning of my usb
comms. Now I'm back to having my reworked payload work according to specs
and fit in the same box as the comms.

So I guess sooner or later, I'll have to take a deep look at what is going
on inside my chip, step by step and I'm sure the
sim will be the main debugging tool.

Another thing that confused me at first was that some instructions that were
functionning inside the "check syntax" of ISE weren't allowed in the sim...
then that some syntax allowed in the sim wasn't allowed in the final
compilation. That's why at one point I felt reluctant to use the sim (I
don't like depending on some syntaxic construct that ends up not being
allowed in the last few meters).
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.

No pre treatment means that If I need to give some info to the component,
lets say a std_logic_vector (63 downto 0), all I need to do is wire it
between the components. No preset to ZZZ depending of in which state each
component is... (again, I felt that if "the outside" needed to know what
state the inside was in to function, "the outside" belonged inside).

Now I _did_ find out the hard way that if I didn't sync things with the same
clock, some nasty things (ie: that I couldn't grasp) would happen to my
design. So maybe I end up using too many clock synchronizations in my
design... I don't really know (the books I read tell me to sync to death to
avoid metastability).
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).

I wasn't aware of that... thanks for the info.

I didn't use that many types... (mainly std_logic stuffs)
If this were not so, you could make an "interface class" that
could be instantiated on a port, which would be good.

Right! exactly the kind of stuff I expected.
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.

Ho well... as long as I don't have to reinvent the whole thing... why not.

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

You must be right, since I suppose that hardware existed before software, I
guess... (looks like a chicken and egg debate to me ;-)...)
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.

And that's fortunate: both our different universe have evolved a same way of
doing things, it means we can't be totally wrong ;-)...

Regards,

Mink.
 
M

minkowsky

Brian,

Thank you for making things clear and confirm to me the model I devised for
myself to understand fully what needed to be done.

I believe the tricky part is that there can be only one switch per light
(ie: no switch on both side of the window that would allow two people to
decide the state of the same light at the same time.). So the designer has
to decide which side of the interface will have the main control switch.

And I assume the OE switch people keep on telling me about is the typical
response to this type of problem, on one side it means "lights on" and on
the other side, it means the oposite.

Thanks a lot.

Mink.
 
M

minkowsky

Jonathan,

Thank you for taking the time to understand my problem :).

Jonathan Bromley said:
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...

no problem. It's for clarity's sake.
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* .
Right!

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.

Yes... and I understood that no two component could drive the signal at the
same time. So I did make sure that none of the two could write at the same
time (ie: odd/even clock steps). But that didn't work. Because of the ZZZs I
knew nothing about.
Now, at long last, I think I see where you're coming from.
Sorry it took me so long.

No problem... since in the end we understand each other.
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.

That's completely coherent with my observations (and the source of my
initial post) ;-)
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.

Combined?? wow. you mean that they had a glimpse of what the other side
wrote (especially during my attemps at using the Zs?).
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.

And also, there's never any case in traditional softwares where two
processes try to write the same value at the exact same time.
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.

Oki, some sims thingy that is usefull for debugging but not translatable to
a circuit of any sort.
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.

That's the main reason I distrusted the sims in the first place... the fact
that some commands weren't compatible with synthesis.
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".

Frankly, I was surprised that the solution to using inout ports was to use Z
which seemed like a third state I couldn't figure out was it looked like in
real life (signal wise, 1 is +5v, 0 is 0v, but Z?).

And in my books the Z value was explained mostly in the testbench/simming
chapter along with other "virtual" signals.

My first answers to the Z solutions people gave me was to say "I'll look
into it..." But making a search on just plain Z on the net isn't quite as
rewarding as one would think ;-).
=====================================================

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.

How about talking to multiple components (like 3 or 4 fpgas on the same
bus?).

My intuition is to have ID wires to decide to which fpga I wish to talk and
have a single main fpga being the master of the whole.
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.

oki...

And thanks again for the thorough feedback.

Mink.
 
B

Brian Drummond

Brian,

Thank you for making things clear and confirm to me the model I devised for
myself to understand fully what needed to be done.

I believe the tricky part is that there can be only one switch per light
(ie: no switch on both side of the window that would allow two people to
decide the state of the same light at the same time.). So the designer has
to decide which side of the interface will have the main control switch.

Actually that's the simplest way out - to decide that one side of the
window is in control.

If you have switches on both sides of the window, you have a more
complicated problem to resolve - you, the designer, have to ensure only
one of them gets control, and you need to design some sort of
arbitration mechanism between them, and possibly implement some fairness
policy to prevent one hogging the bus full time. Again the simplest way
is to give one side control - call it "master" - and allow the others to
ASK it to release the bus to them when it is not using the bus itself.

This is NOT more complex than software - think about multi-threading
software, and sharing access between multiple processes to the same
resource, without deadlocking the processes, or building in race
conditions. See semaphores, mutexes, locks, critical sections, etc.
(Actually VHDL handles a lot of these issues more elegantly than any
"software" programming language I have seen, with the possible exception
of occam)
And I assume the OE switch people keep on telling me about is the typical
response to this type of problem, on one side it means "lights on" and on
the other side, it means the oposite.

Almost .. OE means Output Enable.
But usually each light has its own OE, and you need to ensure that only
one (or zero) of these OE signals can become active. Not in itself a
difficult problem.

Multiple OE signals is one way to give you the decoupling between I/O
itself, and the process of arbitration, or deciding who gets to talk,
and who can only listen. With one master device, that arbitration has a
single compartment, but it's up to you to make it watertight.

What you suggest above, is basically
OE_outside <= not OE_inside;
and will work, but is obviously not extensible beyond two devices.

Can you start to see the object orientation here? I am glad it is not
built into the language - that might stop me dropping in another kind of
arbiter, for example - but it can be tested once, packaged in a library
(like a class) and re-used in the form of a component.
Thanks a lot.

You're welcome.

- Brian
 
M

Mike Treseler

minkowsky said:
I've finally decided to dump the inouts altogether...

I'm glad to hear that.
It was an unnecessary complication to your code.
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.

Try running it on your simulator
and have a look at the waveforms.
Someone warned me about those not being such a good idea if comming from
the non embedded software world.

That is the common advice, but I disagree.
Something I have to check
though is that too many components embedded into one another don't slow
things down or make the code too fat.

Overuse of components makes
code hard for me to understand.
but I thought the whole point of vhdl was concurrent computing instead of
process/serial computing?

It is concurrent either way
because a synchronous process runs in
a single clock tick, whatever the code length.
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.

That is true, and many like to design this way.
I prefer to distill my reusable code into
procedures and functions and give synthesis
a chance to work out the details.
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 ;-) ).

Functions and procedures work well for synthesis.
Synchronization is a separate issue.
Try to use a single clock, and turn
the other "clocks" into regular inputs.
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.

That's a good idea.
Most comm interfaces require
external parts for the odd voltage
levels anyway.
but what you say is interesting, I also have a small lcd screen I was
wondering I could use or not. Its controller talks in 19kbps serial. I was
wondering if it was hard (or if the resulting code was big) to have those
two communicate.

I find that anything I haven't done before is hard.
It's a matter of motivation.
right about what? that I'm wastying my time?? (then yours too, I guess,
sorry sorry)

I wouldn't bother answering questions
if I thought it were a waste of time.
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.

These ideas are difficult to explain
and some authors don't bother.
??? 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...).

VHDL has a very small number of users.
You often have to build your own
procedures, functions and data structures
to support higher level code.
Of course the higher the level, the fatter the code...

I find well named procedure and function calls
easier to read than straight-line coding.
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.

Yes. You've got it.
Make your computer do some of the work.
Do you really
feel the language is less flexible because of the existence of those
operators?

No. I use them whenever the work well
enough with my tools.
The point is providing a high level function doesn't have to isolate you
from the inner lower level sub functions.

I agree in general, however there will always
be some device-specific limits on what is
really possible.
things
are the way they are and we'll have to make do with what we have ;-) ).

Yes. Or maybe write a little more code.
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,

You are welcome.
Good luck on your project.

-- Mike Treseler
 
M

Marcus Harnisch

minkowsky said:
I sure would like some kind of preprocessor thing to tweak things depending
on the weather, my mood and of course the target platform and testbenches.
[...]
Yep... The lack of pre processor/template processor really seemed odd to me.
At one point I was even considering learning langages like ruby to generate
my code automagically with template files and all.

It does seem odd at first. But soon you will realize that the absence
of a preprocessor is a *feature* of VHDL.

BTW, VHDL does support incomplete type declarations already. This is
one step closer to fully generic types.

OTOH, templates (and complex CPP macros for that matter) can be a real
pain to debug.

Just yesterday I ran into problems with C/CPP for I had forgotten to
enable a particular #define. Since everything was nicely encapsulated
by #ifdef's, the code compiled like a charm. Yet, the program didn't
work right. Hard to track down.

In VHDL, every character of your source code has to go through the
compiler. You can use generate blocks to turn things on/off. It is
much harder to shoot yourself in the foot (though possible of course).
Even if the code remains unused (e.g. generate) it still has to be
valid code. You can always check the state of the generics in your
compiled design.

I used to use M4 for a while to work around an issue with a specific
tool. M4 is very neat and fun to play with. It is more powerful than
cpp and has some limited debugging support. I managed to hide the
preprocessing step and have the code be valid VHDL in case M4 happened
not to be available. You just had to use the right compiler. The other
compiler required preprocessing of the source code. Nice hack but it
later turned out to be completely unnecessary ;-)

The good thing with VHDL is that a lot of the things that other
languages require a preprocessor for[1], are actual language
elements. That keeps the code base clean.

Finally, think about the difference that with a typical software
program you can set a break point in a piece of code to check if it
ever gets executed. A rather quick (and dirty) process. The same thing
in a hardware simulation can take days, weeks even, until that part of
the code might possibly be touched.

Best regards,
Marcus

Footnotes:
[1] Think of "magic comments", #ifdef's, etc.
 
J

Jos De Laender

Marcus said:
minkowsky said:
I sure would like some kind of preprocessor thing to tweak things
depending on the weather, my mood and of course the target platform and
testbenches.
[...]
Yep... The lack of pre processor/template processor really seemed odd to
me. At one point I was even considering learning langages like ruby to
generate my code automagically with template files and all.

It does seem odd at first. But soon you will realize that the absence
of a preprocessor is a *feature* of VHDL.

It would have been a _feature_ if VHDL had templates.
Or rather the generics of Ada.
At one time I found myself writing n versions of the xor_reduce or
and_reduce etc problem. For std_logic_vector , unsigned , signed etc etc..
A simple neat generic approach could have prevented me at that time from
switching to an m4 (indeed :)))) approach.

<snip>
 
M

Mike Treseler

Marcus said:
In VHDL, every character of your source code has to go through the
compiler. You can use generate blocks to turn things on/off. It is
much harder to shoot yourself in the foot (though possible of course).
Even if the code remains unused (e.g. generate) it still has to be
valid code. You can always check the state of the generics in your
compiled design.

Good point.

VHDL's automatic validation of "unused" code can also be used
to documenting changes and bug fixes. Instead of commenting
out offending lines, I sometimes define procedures
for the old_way and the new_way.

Even though I'm *sure* the old_way procedure will never
be used, sometimes it is. Or, I may run a compile
weeks later and learn that I just broke the "old_way".
This forces a decision to delete or
continue support for the old_way.

-- Mike Treseler
 
M

Marcus Harnisch

Jos De Laender said:
It would have been a _feature_ if VHDL had templates.
Or rather the generics of Ada.

Absolutely correct. I am just not sure whether I will be able to enjoy
that before I retire.[1]
At one time I found myself writing n versions of the xor_reduce or
and_reduce etc problem. For std_logic_vector , unsigned , signed etc etc..
A simple neat generic approach could have prevented me at that time from
switching to an m4 (indeed :)))) approach.

So given the fact that you had to define a function xor_reduce at
least once anyway

,----
| function xor_reduce(A: std_logic_vector) return std_logic
`----

, you are saying you felt you had to use a preprocessor just to avoid
typing this:

,----
| signal uv: unsigned(4 downto 0);
| signal sv: signed(uv'range);
| signal bv: bit_vector(uv'range);
|
| signal s : std_logic;
| signal b : bit;
|
| s <= xor_reduce(std_logic_vector(uv));
| s <= xor_reduce(std_logic_vector(sv));
| b <= to_bit(xor_reduce(to_stdlogicvector(bv)));
`----

???

You must enjoy hacking m4 just as much as I do :)

Best regards,
Marcus

Footnotes:
[1] I am not that concerned about the language itself, but rather
about a timely acceptance by EDA vendors.
 
J

Jos De Laender

Marcus Harnisch wrote:

, you are saying you felt you had to use a preprocessor just to avoid
typing this:

,----
| signal uv: unsigned(4 downto 0);
| signal sv: signed(uv'range);
| signal bv: bit_vector(uv'range);
|
| signal s : std_logic;
| signal b : bit;
|
| s <= xor_reduce(std_logic_vector(uv));
| s <= xor_reduce(std_logic_vector(sv));
| b <= to_bit(xor_reduce(to_stdlogicvector(bv)));
`----

???

You must enjoy hacking m4 just as much as I do :)

Reading it like this , I must have been quite dumb at that moment ;-)

Honestly , I don't recall the exact reason for not doing it like this. It
got to see with developing independent packages for all kind of utilities
on signed, unsigned, bit_vector, but also boolean vectors , large integers
as a custom type. For some reason it was much more handy to have one m4
description that expanded itself to correct support functions for all of
above types. All in different packages.

Anyhow , I can find a lot of other examples where it does make more sense.
Just look to the classic algorithms. They now all tend to be written in
generic format(ada) or templates(C++)


Best regards,
Marcus

Footnotes:
[1] I am not that concerned about the language itself, but rather
about a timely acceptance by EDA vendors.
 

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,744
Messages
2,569,484
Members
44,904
Latest member
HealthyVisionsCBDPrice

Latest Threads

Top