INOUT port on entity

Discussion in 'VHDL' started by minkowsky, Feb 16, 2004.

  1. minkowsky

    minkowsky Guest

    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.
    minkowsky, Feb 16, 2004
    #1
    1. Advertising

  2. 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
    Eyck Jentzsch, Feb 16, 2004
    #2
    1. Advertising

  3. minkowsky

    minkowsky Guest

    "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.
    minkowsky, Feb 16, 2004
    #3
  4. 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
    Mike Treseler, Feb 16, 2004
    #4
  5. 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,
    : );
    :
    :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.
    :
    David R Brooks, Feb 16, 2004
    #5
  6. minkowsky

    minkowsky Guest

    "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 :-D
    minkowsky, Feb 16, 2004
    #6
  7. minkowsky

    minkowsky Guest

    "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.
    minkowsky, Feb 16, 2004
    #7
  8. 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 :-D
    :
    David R Brooks, Feb 17, 2004
    #8
  9. minkowsky

    minkowsky Guest

    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 :-D
    > :
    >
    minkowsky, Feb 17, 2004
    #9
  10. minkowsky

    minkowsky Guest

    "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 :-(
    minkowsky, Feb 24, 2004
    #10
  11. minkowsky

    minkowsky Guest

    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.
    minkowsky, Feb 24, 2004
    #11
  12. minkowsky wrote:

    > 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
    Mike Treseler, Feb 24, 2004
    #12
  13. minkowsky

    minkowsky Guest

    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" <> wrote in message
    news:...
    > minkowsky wrote:
    >
    > > 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.


    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.

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


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

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


    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.

    > > Then what if both side set the value to Z?

    >
    > 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?

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


    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.
    minkowsky, Feb 24, 2004
    #13
  14. minkowsky wrote:

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

    >> That means the pin/bus is idle.

    > 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
    Mike Treseler, Feb 24, 2004
    #14
  15. minkowsky

    minkowsky Guest

    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" <> wrote in message
    news:...
    > minkowsky wrote:
    >
    > > It seems awfully complicated.

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

    > > 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'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?

    > > 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?


    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)

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


    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.

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


    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 ;-) ).


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


    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.

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


    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.

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


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


    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.

    > > 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?


    ??? 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.
    minkowsky, Feb 25, 2004
    #15
  16. "minkowsky" <> wrote in message
    news:403bc9ae$0$28455$...

    > 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:
    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.
    Jonathan Bromley, Feb 25, 2004
    #16
  17. minkowsky

    minkowsky Guest

    "Jonathan Bromley" <> wrote
    > "minkowsky" <> wrote
    >
    > > It seems awfully complicated.

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

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


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

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

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


    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.
    minkowsky, Feb 25, 2004
    #17
  18. "minkowsky" <> wrote in message
    news:403cab19$0$28437$...
    >
    > "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.

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


    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.

    > > 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 ;-) ).


    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:
    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.
    Jonathan Bromley, Feb 25, 2004
    #18
  19. "minkowsky" <> wrote in
    message news:40304056$0$28663$...
    >
    > 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:
    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.
    Jonathan Bromley, Feb 25, 2004
    #19
  20. On Tue, 24 Feb 2004 15:47:19 +0100, "minkowsky"
    <> wrote:

    >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
    Brian Drummond, Feb 25, 2004
    #20
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. cruzin
    Replies:
    2
    Views:
    4,126
    PO Laprise
    Jan 23, 2004
  2. =?ISO-8859-15?Q?Fr=E9d=E9ric_Lochon?=

    connecting std_logic inout ports and std_logic_vector inout port

    =?ISO-8859-15?Q?Fr=E9d=E9ric_Lochon?=, Nov 6, 2007, in forum: VHDL
    Replies:
    3
    Views:
    854
  3. Ken

    inout to inout

    Ken, May 9, 2008, in forum: VHDL
    Replies:
    2
    Views:
    597
    Aiken
    May 9, 2008
  4. markla
    Replies:
    1
    Views:
    540
    Steven Cheng
    Oct 6, 2008
  5. THurkmans
    Replies:
    14
    Views:
    1,803
    Mike Treseler
    Aug 11, 2009
Loading...

Share This Page