Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > VHDL > Yet another question about array indexing

Reply
Thread Tools

Yet another question about array indexing

 
 
tudelftrocks@gmail.com
Guest
Posts: n/a
 
      11-26-2008
Hi,

I found several posts about array indexing but I am still confused on
how to use an one-hot address to index the array. The reason why I
want o use a hot-one address is that I have to generate the addresses
myself in another part of the project and therefore there is no need
for an address encoder/decoder if I use the one-hot address. However,
from the posts I read, it seams that I can only index an array with
integer and enumerate types. Is this correct? How can I get avoid the
use of an address encoder/decoder?

In the following code both R_ADR and W_ADR are a 32 bits hot-one
address:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity memory is
generic( addr_width : integer := 5;
data_width : integer := 4);
port(
Q : out std_logic_vector(data_width - 1 downto 0 );
R_ADR : in std_logic_vector(2**addr_width - 1 downto 0); --
This is a hot-one address
W_ADR : in std_logic_vector(2**addr_width - 1 downto 0); --
This is a hot-one address
D : in std_logic_vector(data_width - 1 downto 0 );
W : in std_logic;
R : in std_logic;
ME : in std_logic;
CLK : in std_logic
);
end memory;

architecture synth_mem of memory is
type mem_array is array (std_logic_vector range <>) of
std_logic_vector(data_width - 1 downto 0 );
signal ram : mem_array(2**addr_width - 1 downto 0);

begin
process (ME, CLK)
begin
if ME = '1' then
Q <= (others => '1');
elsif CLK'event and CLK = '1' then
if R = '1' then
Q <= ram(R_ADR);
else
Q <= (others => '1');
end if;
if W = '1' then
ram(W_ADR) <= D;
end if;
end if;
end process;

end synth_mem;

I have the following errors:
Entity <memory> compiled.
ERROR:HDLParsers:201 - "RTL/memory.vhdl" Line 25. Array index subtype
std_logic_vector is not a discrete range.
ERROR:HDLParsers:3312 - "RTL/memory.vhdl" Line 26. Undefined symbol
'mem_array'.
ERROR:HDLParsers:1209 - "RTL/memory.vhdl" Line 26. mem_array:
Undefined symbol (last report in this block)
ERROR:HDLParsers:3313 - "/RTL/memory.vhdl" Line 56. Undefined symbol
'ram'. Should it be: rem?
ERROR:HDLParsers:1209 - "RTL/memory.vhdl" Line 56. ram: Undefined
symbol (last report in this block)

How can I use an one-hot address to index my array?

Thank you in advance.
 
Reply With Quote
 
 
 
 
Tricky
Guest
Posts: n/a
 
      11-27-2008
> The reason why I
> want o use a hot-one address is that I have to generate the addresses
> myself in another part of the project and therefore there is no need
> for an address encoder/decoder if I use the one-hot address.


There may not be on the write side, but the read side has a massive
Mux. This will be ok for small numbers of address lines, but it will
get very slow very quickly.


>
> How can I use an one-hot address to index my array?
>
> Thank you in advance.


Short answer : you cant without a decoder. using a one hot address bus
really just gives you a load of registers with each one hot write
address line connected to the enable on the appropriate register. Its
the read address that then becomes a problem, because the output will
be a large one hot mux, which is just a long chain of 2-1 muxes, that
you will have to define yourself.

Array's in VHDL are always indexed using integers. And so it's easiest
to have the addresses as an integer. They also map nicely to internal
memory blocks. A Std_logic_vector is NOT an integer, its just an array
of bits. I recommend using ieee.numeric_std.all instead of
ieee.std_logic_unsigned.all (this package is NOT an ieee standard and
different vendors implement it differently, whereas numeric_std IS a
standard).

if you REALLY wanted to use one hot addressing, you could use
something like the following (all code assumed address_width = 5 and
data width = 4):

process (CLK)
function find_value_1hot(a : std_logic_vector; mem : mem_array)
return std_logic_vector is
variable ret_slv : std_logic_vector(3 downto 0) := (others =>
'1');
begin
for i in a'range loop
if a(i) = '1' then
ret_slv := mem(i);
end if;
end loop;

return ret_slv;
end function find_value_1hot;

begin
if rising_edge(clk) then
if R = '1' then
Q <= find_value_1hot(R_ADR, ram);
else
Q <= (others => '1');
end if;


ram_write : for i in ram'range loop
if W = '1' and W_ADR(i) = '1' then
ram(i) <= D;
end if;
end loop ram_write;
end if;
end process;

From synthesis and timing analysis, the Q output mux was one large mux
chain, as expected. The fmax was 284MHz.

I then tried the following (using the numeric_std_package, not
std_logic_unsigned):

process (CLK)
begin
if rising_edge(clk) then
if R = '1' then
Q <= ram( to_integer( unsigned(R_ADR) ));
else
Q <= (others => '1');
end if;


if W = '1' then
ram( to_integer(unsigned(w_adr) )) <= D;
end if;
end if;
end process;

No surprises, the synthesisor built a ram primitive. And the FMax is
now 356Mhz, about 50% faster than the other method.

Dont be worried about address decoders. They are very common, used
alot and easy to understand. When you start doing things 1-hot it
starts getting a little less clear about whats going on.
 
Reply With Quote
 
 
 
 
tudelftrocks@gmail.com
Guest
Posts: n/a
 
      11-27-2008
On Nov 26, 6:16*pm, Rob Gaddi <(E-Mail Removed)> wrote:
> On Wed, 26 Nov 2008 08:00:09 -0800 (PST)
> (E-Mail Removed) wrote:
> > Hi,

>
> > I found several posts about array indexing but I am still confused on
> > how to use an one-hot address to index the array. The reason why I
> > want o use a hot-one address is that I have to generate the addresses
> > myself in another part of the project and therefore there is no need
> > for an address encoder/decoder if I use the one-hot address. However,
> > from the posts I read, it seams that I can only index an array with
> > integer and enumerate types. Is this correct? How can I get avoid the
> > use of an address encoder/decoder?

>
> > In the following code both R_ADR and W_ADR are a 32 bits hot-one
> > address:

>
> > library ieee;
> > use ieee.std_logic_1164.all;
> > use ieee.std_logic_unsigned.all;

>
> > entity memory is
> > * *generic( addr_width : integer := 5;
> > * * * * * * * *data_width : integer := 4);
> > * *port(
> > * * * * * *Q : out std_logic_vector(data_width - 1 downto 0 );
> > * * * * * *R_ADR : in *std_logic_vector(2**addr_width - 1 downto
> > 0); -- This is a hot-one address
> > * * * * * *W_ADR : in *std_logic_vector(2**addr_width - 1 downto
> > 0); -- This is a hot-one address
> > * * * * * *D : in *std_logic_vector(data_width - 1 downto 0 );
> > * * * * * *W : in *std_logic;
> > * * * * * *R : in *std_logic;
> > * * * * * *ME : in *std_logic;
> > * * * * * *CLK : in *std_logic
> > * * * * * *);
> > end memory;

>
> > architecture synth_mem of memory is
> > * *type mem_array is array (std_logic_vector range <>) of
> > std_logic_vector(data_width - 1 downto 0 );
> > * *signal ram : mem_array(2**addr_width - 1 downto 0);

>
> > begin
> > * *process (ME, CLK)
> > * *begin
> > * * * * * *if ME = '1' then
> > * * * * * * * * * *Q <= (others => '1');
> > * * * * * *elsif CLK'event and CLK = '1' then
> > * * * * * * * * * *if R = '1' then
> > * * * * * * * * * * * * * *Q <= ram(R_ADR);
> > * * * * * * * * * *else
> > * * * * * * * * * * * * * *Q <= (others => '1');
> > * * * * * * * * * *end if;
> > * * * * * * * * * *if W = '1' then
> > * * * * * * * * * * * * * *ram(W_ADR) <= D;
> > * * * * * * * * * *end if;
> > * * * * * *end if;
> > * *end process;

>
> > end synth_mem;

>
> > I have the following errors:
> > Entity <memory> compiled.
> > ERROR:HDLParsers:201 - "RTL/memory.vhdl" Line 25. Array index subtype
> > std_logic_vector is not a discrete range.
> > ERROR:HDLParsers:3312 - "RTL/memory.vhdl" Line 26. Undefined symbol
> > 'mem_array'.
> > ERROR:HDLParsers:1209 - "RTL/memory.vhdl" Line 26. mem_array:
> > Undefined symbol (last report in this block)
> > ERROR:HDLParsers:3313 - "/RTL/memory.vhdl" Line 56. Undefined symbol
> > 'ram'. *Should it be: rem?
> > ERROR:HDLParsers:1209 - "RTL/memory.vhdl" Line 56. ram: Undefined
> > symbol (last report in this block)

>
> > How can I use an one-hot address to index my array?

>
> > Thank you in advance.

>
> The first question is: are you sure this is actually what you want to
> do? *The answer to that question depends on what you envision the
> actual hardware implementation of this thing looking like (assuming
> that this code is meant to one day see hardware). *If you're planning
> to try to implement this in a real RAM, then the decoding functionality
> is hardwired into the RAM block. *I suppose you CAN use a RAM in which
> the address is always a one-hot value, but it means throwing away the
> vast majority of it.
>
> If, on the other hand, your intended result is a register file of
> discrete flip-flops with selection logic on the input and output sides
> of things, this is a reasonable way to be attacking the problem. *If
> that's the case, the decision to declare your address widths to be
> powers of two long is something of a strange one, but I digress. *If
> that's the implementation you're looking to generate, then look into
> using a process with a for loop to AND each register with it's
> selector, then OR the results together. *Note that this approach will
> rapidly become unwieldly for any serious number of registers.
>
> --
> Rob Gaddi, Highland Technology
> Email address is currently out of order
> - Hide quoted text -
>
> - Show quoted text -

Hi,

Thank you for your answer. Yes, I am sure that is what I want to do.
the memory sizes I need can be quite small, so the option of using
a real RAM will take more area then using a "synthesizable" memory.
Moroever, because I generate my own addresses I do not need a decoder
therefore taking even less area than a real RAM implementation.

Your idea of using a for loop seams interesting but I got a bit lost
on
how to actually code this. Could you please explain a bit more what
you
mean with AND the register and the selector? From the code I sent you
mean:
D AND W_ADR?

Could you please also elaborate on why you consider the option of
using a
hot-one address a strange one? From which point of view do you mean?

Thanks.

Filipa
 
Reply With Quote
 
KJ
Guest
Posts: n/a
 
      11-27-2008

<(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Hi,
>
> I found several posts about array indexing but I am still confused on
> how to use an one-hot address to index the array.


The same way you would use any other vector, by converting it to an integer.
address_integer <= to_integer(unsigned(my_one_hot_address_vector));

This doesn't 'cost' anything in terms of logic resources, it is simply
applying a specific interpretation (i.e. integer) to something that is
defined to be another type (presumalbly your one hot address is
std_logic_vector).

> However,
> from the posts I read, it seams that I can only index an array with
> integer and enumerate types. Is this correct?


Yes, arrays can only be indexed by discrete types, integers and enumerations
being the ones most commonly used.

> How can I get avoid the
> use of an address encoder/decoder?
>


The encoder doesn't cost anything in terms of generated logic resources. A
collection of arbitrary bits can always be interpreted as an integer number
without it generating any logic. It is simply a type conversion operation
that is required by the language because from a language perspective it
requires proper conversion when things are of different types. This does
not imply though that these conversions generate any logic in synthesized
code.

The fact that your address is 'one hot' is totally irrelevant to using it to
address the memory. The fact that you choose to only read/write N addresses
out of a possible 2**N doesn't factor into the implementation at all.

Kevin Jennings


 
Reply With Quote
 
Andy
Guest
Posts: n/a
 
      12-02-2008
On Nov 27, 3:47*am, Tricky <(E-Mail Removed)> wrote:
>
> if you REALLY wanted to use one hot addressing, you could use
> something like the following (all code assumed address_width = 5 and
> data width = 4):
>
> process (CLK)
> * * function find_value_1hot(a : std_logic_vector; mem : mem_array)
> return std_logic_vector is
> * * * variable ret_slv : std_logic_vector(3 downto 0) := (others =>
> '1');
> * * begin
> * * * for i in a'range loop
> * * * * if a(i) = '1' then
> * * * * * ret_slv := mem(i);
> * * * * end if;
> * * * end loop;
>
> * * * return ret_slv;
> * * end function find_value_1hot;
>


The problem with converting the one-hot address to an integer-encoded
index is that the synthesis tool does not know that only one bit in a
() is set, i.e. that a() is mutually exclusive. So prioritization
logic is inserted for you. As written the rightmost set bit in a()
will determine which element of mem is returned.

To avoid this, you have to create an and-or mux, or use a tri-state
assignment such that, when converted to a mux, the synthesis tool can
assume the tri-state enables are mutually exclusive.

And-or priority-less mux:
variable temp : std_logic_vector(mem(0)'range) := (others => '0');
....
for i in a'range loop
temp := temp or ((mem(i)'range => a(i)) and mem(i));
end loop;
return temp;

Or for a tri-state approach that will be converted to a mux (must be a
concurrent generate statement, so it won't work in a function):

ts: for i in a'range generate
output <= mem(i) when a(i) = '1' else (others => 'Z');
end generate;

For tri-state buses to work (or be converted to priority-less muxes)
each conditional assignment must be a separate concurrent statement,
not sequential statements.

In some ways the t-state version is easier to understand, but it also
requires the reader to understand that no real tri-state signals are
being used, it will all get converted to mux logic. It also cannot be
implemented in a function or procedure.

Andy
 
Reply With Quote
 
Mike Treseler
Guest
Posts: n/a
 
      12-02-2008
Andy wrote:

> And-or priority-less mux:
> variable temp : std_logic_vector(mem(0)'range) := (others => '0');
> ...
> for i in a'range loop
> temp := temp or ((mem(i)'range => a(i)) and mem(i));
> end loop;
> return temp;


So how does this compare with Tricky's
second example in synthesis?

-- Mike Treseler
 
Reply With Quote
 
KJ
Guest
Posts: n/a
 
      12-03-2008
On Dec 2, 3:19 pm, Andy <(E-Mail Removed)> wrote:

> In some ways the t-state version is easier to understand, but it also
> requires the reader to understand that no real tri-state signals are
> being used, it will all get converted to mux logic. It also cannot be
> implemented in a function or procedure.
>


For an example of an encoding method that does not prioritize hark
back to the overly windy "New keyword 'orif' and its implications"
thread in this group from Sep, 2007

http://groups.google.com/group/comp....3697772e2d7f94

From there is an example of 8->3 encoding (shown below) that can be
implemented in a function and can be generalized to work with other
bit widths as well and will be implemented in minimal logic.

Encoded_OneHotInps(0) <= OneHotInps(1) xor OneHotInps(3) xor
OneHotInps(5) xor OneHotInps(7);
Encoded_OneHotInps(1) <= OneHotInps(2) xor OneHotInps(3) xor
OneHotInps(6) xor OneHotInps(7);
Encoded_OneHotInps(2) <= OneHotInps(4) xor OneHotInps(5) xor
OneHotInps(6) xor OneHotInps(7);

Kevin Jennings
 
Reply With Quote
 
 
 
Reply

Thread Tools

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

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


Similar Threads
Thread Thread Starter Forum Replies Last Post
Dynamic indexing (multi-dimensional-indexing) (probably my most important/valuable posting up to this date) Skybuck Flying C Programming 30 09-18-2011 11:29 PM
Indexing services under Windows XP SP2 - Can I disable MS Indexing Service to hasten Google's OR does Google Desktop uses this MS Indexing Service? ricardodefaria Computer Support 6 08-05-2007 04:14 AM
How much slower is dict indexing vs. list indexing? Emin Python 4 01-12-2007 02:40 PM
Indexing PDF's using MS Indexing Service C ASP General 3 10-17-2003 05:47 PM
Indexing PDF Files using MS Indexing Service C ASP .Net 0 10-17-2003 04:27 PM



Advertisments