Connecting an inout port to another inout port

T

THurkmans

Hello,

In:

port
(
mems_in : inout std_logic_vector(7 downto 0); --connected to
sram
mems_out : inout std_logic_vector(7 downto 0) --connected to
core
);

How can I connect mems_in to mems_out and mems_out to mems_in? I am
resetting the signals to Z (as far as I know).

This does not seem to work (generates U):
mems_out <= mems_in;
mems_in <= mems_out;

This does not seem to work either (changes on mems_out do not appear
on mems_in, Z shows):
mems_out <= mems_in;

This does not seem to work either (changes on mems_in do not appear on
mems_out, Z shows):
mems_in <= mems_out;

Does anybody have the solution?
 
T

Tricky

Hello,

In:

        port
        (
                mems_in     : inout std_logic_vector(7 downto 0); --connected to
sram
                mems_out    : inout std_logic_vector(7 downto 0)  --connected to
core
        );

How can I connect mems_in to mems_out and mems_out to mems_in? I am
resetting the signals to Z (as far as I know).

This does not seem to work (generates U):
        mems_out <= mems_in;
        mems_in <= mems_out;

This does not seem to work either (changes on mems_out do not appear
on mems_in, Z shows):
        mems_out <= mems_in;

This does not seem to work either (changes on mems_in do not appear on
mems_out, Z shows):
        mems_in <= mems_out;

Does anybody have the solution?

the problem is with method 1 is that you will have both signals
driving against each other.
With method 2 and 3, the data flow is only in 1 direction.

You will need a control bit that controls which way the data flows:

signal direction : std_logic;
.......
mems_in <= mems_out when direction = '1' else (others => 'Z');
mems_out <= mems_in when direction = '0' else (others => 'Z');

this means you will never get any contentions on the line and you
should be able to read the data.
 
D

Dave

the problem is with method 1 is that you will have both signals
driving against each other.
With method 2 and 3, the data flow is only in 1 direction.

You will need a control bit that controls which way the data flows:

signal direction : std_logic;
......
mems_in  <= mems_out when direction = '1' else (others => 'Z');
mems_out <= mems_in  when direction = '0' else (others => 'Z');

this means you will never get any contentions on the line and you
should be able to read the data.

Couldn't one also tie both ports to the same signal in the higher-
level port map of the instance?

Dave
 
M

Mark McDougall

THurkmans said:
How can I connect mems_in to mems_out and mems_out to mems_in?

At what level of the design is this? Is this in synthesised code or a
testbench?

IMHO inout should _only_ be used on ports mapped to physical device pins.

If you need to connect two inout ports in a testbench, for example, define
a signal and then connect it to both ports.

Regards,
 
T

THurkmans

I'm not that experienced in VHDL. This is my first large/serious
project in VHDL (thesis work). The code above is part of a block that
comes between my SRAM and my core. I have a record specifing write-
enable, address, inoutput and enable for communicating with an SRAM,
and am using procedures readpixel and writepixel to access my SRAM.

The record is defined as:

type sram_connect_type is record
address : std_logic_vector(bit_img_size - 1 downto 0);
enable : std_logic;
write_enable : std_logic; -- 0=read, 1=write
inoutput : std_logic_vector(7 downto 0);
end record;

Right now I have an SRAM connected to an improvised 'bus', which
connects to my core. The input and output of my SRAM are connected to
the mems_in and the mems_out is connected to a part in my core. I need
a block between my SRAM and my core, because I have to do some
switching between my SRAMs without copying data around. Read and write
are separate and the goal is to synthesize the entire design.
Currently, my entire design is working without this block (including
reading and writing).

The goal is to have three inputs of this record type (a,b,c) and three
outputs of this record type (d,e,f). Based on an input
(zero_mem_select) I have to perform something like:

zero_mem_sel | connect
0 | a->d b->e c->f
1 | a->f b->d c->e
2 | a->e b->f c->d

Because of the record type, and the fact that I have to read and
write, I'm having difficulties using the direction method described by
Tricky. I feel that it has something to do with write_enable, but I
can't figure out what exactly.

I must have misunderstood the main concept of VHDL. I thought it was
to describe how hardware is connected. I just want a wire to connect
the records. But apparently you also have to keep the flow of a signal
in mind as well. I was actually hoping for an <=> operator for inout
signals.
 
M

Mike Treseler

THurkmans said:
I must have misunderstood the main concept of VHDL. I thought it was
to describe how hardware is connected.

No. Vhdl describes what is *in* the boxes
as well as the wires *between* the boxes
I just want a wire to connect
the records. But apparently you also have to keep the flow of a signal
in mind as well. I was actually hoping for an <=> operator for inout
signals.

I would use separate inputs and outputs to start with.
see also:
http://groups.google.com/groups/search?q=vhdl+records+separate+in+out

good luck

-- Mike Treseler
 
T

THurkmans

No. Vhdl describes what is *in* the boxes
as well as the wires *between* the boxes


I would use separate inputs and outputs to start with.
see also:http://groups.google.com/groups/search?q=vhdl+records+separate+in+out

good luck

       -- Mike Treseler

I've now separated the signals coming out of my sram, and combining
them into an inout port after my translation block. Now I run into
another problem:

Originally I had:
| ---CORE--- |
|RAM| <-> | mems.image0 |
| 0 | | |
| |
|RAM| <-> | mems.image1 |
| 1 | | |
| |
|RAM| <-> | mems.image2 |
| 2 | | |

Three rams, with an inout port <-> to my core, which provided access
to the sram through a record mems.image0/1/2. For read, the address
was put into the ram, and one clock tick later the result would be
available on the inout port.

I now have:

|RAM| -> | | <-> | ---CORE--- |
| 0 | <- | Translate | | |
| | | |
|RAM| -> | | <-> | |
| 1 | <- | | | |
|(currently)| | |
|RAM| -> |->---------| <-> | |
| 2 | <- |-<---------| | |

Three RAMs, connected to a translation unit, using in and out ports.
The translation unit currently only reconnects the RAMs to the output.
This is the same principle as before. The read/write principle stays
the same (one tick delay for read). Only, now there is an additional
entity with signal in between. The simulation now fails (there are
results on the bus after one tick, but the core does not use them),
and I think it is because of the delta-delay of the extra signal.

Does anybody have any idea how I can circumvent this issue?
 
M

Mike Treseler

THurkmans said:
Does anybody have any idea how I can circumvent this issue?

I circumvent it by only using signals in port maps.
Is your design synchronized to one clock?

-- Mike
 
P

Paul Uiterlinden

THurkmans said:
The simulation now fails (there are
results on the bus after one tick, but the core does not use them),
and I think it is because of the delta-delay of the extra signal.

Does anybody have any idea how I can circumvent this issue?

If one signal is delayed by a delta cycle (by a signal assignment in your
translate block) and another signal is not delayed, and this skew is not
allowed, then simply insert an extra signal and signal assignment in the
other signal. That way the signals will be aligned again.

Another trick is to put a real delay (say 1 ns) in the last signal
assignment that is the last in a chain of signal assignments. A real delay
will eat up all delta delays. Of course that must be done with all signals
that are related (that should be aligned).

I have done this in the past in a case where the foundry insisted that clock
buffer should be instantiated in the VHDL. By putting a real delay in each
leaf clock buffer, all clocks where aligned, though delayed a bit.

On the other hand: trouble like this can be caused by poor modeling style.
In that case, solve that first. I don't know i which category your problem
falls.
 
T

THurkmans

Thanks for all the tips. It's an enormous help. They just don't teach
best practices at university (at least not at mine).
I circumvent it by only using signals in port maps.
Is your design synchronized to one clock?

There is only one clock. I'm not experienced enough to work with
multiple clocks.

I am trying to avoid signals when I can. I use them in port maps, and
use a two processes approach for other logic. The thing is that this
translate-block requires to select certain port maps and output them
differently at the outputs. For example, input a can become output b,
c or d. The solution I know for this requires an intermediate signal
for the actual selection. Is there another way?
If one signal is delayed by a delta cycle (by a signal assignment in your
translate block) and another signal is not delayed, and this skew is not
allowed, then simply insert an extra signal and signal assignment in the
other signal. That way the signals will be aligned again.

The answer from the sram is delayed. My current fix is to delay the
clock of my core with one delta cycle. This seems to work when just
assigning signals, but not in my switch process.

So right now I have (Sorry for all the code):
entity image_translator is
port
(
clk : in std_logic; --real clock, not the delta-delayed one
zero_select : in natural range 0 to 2;
mems_image : inout memories_inout_type --connected to core
);
end;

lbl_sram_image0: sram
generic map
(
ram_width => bits_per_pixel,
ram_addr_bits => bit_img_size
)
port map
(
clk => clk,
address => image0.address,
enable => image0.enable,
write_enable => image0.write_enable,
input => image0.input,
output => image0.output
);

image0.address <= mems_image.image0.address;
image0.enable <= mems_image.image0.enable;
image0.write_enable <= mems_image.image0.write_enable;
image0.input <= mems_image.image0.inoutput;
mems_image.image0.inoutput <= image0.output;

the above works, but this fails:

comb : process(r)
variable v : reg_type;
begin

-- default assignment
v := r;

v.zero_select := zero_select;

case v.zero_select is
when 0 =>
--image 0->0, 1->1, 2->2 (only 0 shown)
image0.address <= mems_image.image0.address;
image0.enable <= mems_image.image0.enable;
image0.write_enable <= mems_image.image0.write_enable;
image0.input <= mems_image.image0.inoutput;
mems_image.image0.inoutput <= image0.output;
when 1 =>
--image 0->2, 1->0, 2->1
when 2 =>
--image 0->1, 1->2, 2->0
when others =>
report "Wrong loop entry in image translator encountered" severity
failure;
end case;

-- drive register inputs
rin <= v;

-- Keep bus free
resetMemoryAccess(mems_image.image0);
resetMemoryAccess(mems_image.image1);
resetMemoryAccess(mems_image.image2);
resetMemoryAccess(mems_image.it);
resetMemoryAccess(mems_image.ix);
resetMemoryAccess(mems_image.iy);
end process;

-- sequential process
regs : process(clk)
begin
if rising_edge(clk) then r <= rin; end if;
end process;

Somewhere there are more delays and I can't figure out where. Can you
tell me what the delay is? And where I'm going wrong with this.
Another trick is to put a real delay (say 1 ns) in the last signal
assignment that is the last in a chain of signal assignments. A real delay
will eat up all delta delays. Of course that must be done with all signals
that are related (that should be aligned).

How can I add a real delay for synthesis? Or is the trick only
relevant for simulation (and synthesis won't experience the problem)?
 
M

Mike Treseler

THurkmans said:
I am trying to avoid signals when I can. I use them in port maps, and
use a two processes approach for other logic. The thing is that this
translate-block requires to select certain port maps and output them
differently at the outputs. For example, input a can become output b,
c or d. The solution I know for this requires an intermediate signal
for the actual selection. Is there another way?

multiple signals in an architecture is analogous to
multiple variables in a process
for the purposes of logic description.
for example, see:

http://mysite.verizon.net/miketreseler/stack.vhd
http://mysite.verizon.net/miketreseler/stack.pdf

-- Mike Treseler
 
T

THurkmans

multiple signals in an architecture is analogous to
multiple variables in a process
for the purposes of logic description.
for example, see:

http://mysite.verizon.net/miketreseler/stack.vhd
http://mysite.verizon.net/miketreseler/stack.pdf

     -- Mike Treseler

Thanks for the example. It is a more elaborate template than the one I
was using.

So if it is analogous, and signals in an architecture don't solve the
problem of an additional delta delay, how can variables in a process
solve it instead?
 
Joined
Jun 2, 2009
Messages
23
Reaction score
1
@ thread started....

P.S - I have not read all the replies. I have read only the original post and 2 subsequent replies and answering accordingly !!

Why don't u use a tri-state buffer between the Core & the RAM ?
Keep an enable signal, which will allow you to transfer data either in or out (as when the enable is '0' or '1')!

Actually I did something like this a few weeks ago the only difference was that my driving line is single bit. I have a UART which has inout port in one end. And at the other end there is a master device which also has an inout port.
 
M

Mike Treseler

THurkmans said:
So if it is analogous, and signals in an architecture don't solve the
problem of an additional delta delay, how can variables in a process
solve it instead?

Because variables allow me to combine logic
on either the D side or the Q side in the
same synchronous process.

-- Mike Treseler
 

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,997
Messages
2,570,239
Members
46,827
Latest member
DMUK_Beginner

Latest Threads

Top