Parametrized memory module

P

Pulzar

Guest
Let's say that you have a module that contains some memory storage, X*Y
bits large:

reg[X-1:0] RAM[Y-1:0];

X and Y are parameters of the module. Now, you have an index into the
memory that's one-hot encoded, so it is Y bits wide:

input[Y-1:0] index;

You'd like to output the appropriate piece of data, using something
like this...:

wire[X-1:0] oData =
(index[0]) ? RAM[0] :
(index[1]) ? RAM[1] :
(index[2]) ? ...

or through a similar case statement. Now, writing that out assumes a
constant value of Y. Is there a way to write that piece of logic using
the Y parameter so that the module can be truly parametrized?

Obviously, I could write a funciton that will convert one-hot to an
unsigned integer and then write

assign oData = RAM[unsigned_index];

....but synthesizing something like that would produce a less optimal
logic than a parallel case statement using the one-hot encoded index.

Any thoughts?

Stan
 
Are you using an ASIC RAM that has one-hot addressible memory elements or do
you just want a 2-D array of registers?

How large can Y be?
_______

reg [X-1:0] oData;
always @*
for( i=Y; i>0; i=i-1 )
if( index[i-1] ) oData = RAM[i-1];

You should have a parameterized combinatorial assignment for oData that
matches the priority structure you want to do one-hot addressing of a 2-D
register array.


"Pulzar" <sokorac@gmail.com> wrote in message
news:1149286293.817509.103360@j55g2000cwa.googlegroups.com...
Let's say that you have a module that contains some memory storage, X*Y
bits large:

reg[X-1:0] RAM[Y-1:0];

X and Y are parameters of the module. Now, you have an index into the
memory that's one-hot encoded, so it is Y bits wide:

input[Y-1:0] index;

You'd like to output the appropriate piece of data, using something
like this...:

wire[X-1:0] oData =
(index[0]) ? RAM[0] :
(index[1]) ? RAM[1] :
(index[2]) ? ...

or through a similar case statement. Now, writing that out assumes a
constant value of Y. Is there a way to write that piece of logic using
the Y parameter so that the module can be truly parametrized?

Obviously, I could write a funciton that will convert one-hot to an
unsigned integer and then write

assign oData = RAM[unsigned_index];

...but synthesizing something like that would produce a less optimal
logic than a parallel case statement using the one-hot encoded index.

Any thoughts?

Stan
 
John_H wrote:
oData;
always @*
for( i=Y; i>0; i=i-1 )
if( index[i-1] ) oData = RAM[i-1];
Using something like that, ncsim complains that "@* references a memory
which is not standard or portable", and oData doesn't show the correct
value. Putting RAM in always @() fails with a "Memory reference
requires an index".

Am I running into an ncsim limitation here?

Stan
 
Pulzar wrote:
Using something like that, ncsim complains that "@* references a memory
which is not standard or portable", and oData doesn't show the correct
value. Putting RAM in always @() fails with a "Memory reference
requires an index".

Am I running into an ncsim limitation here?
You are running into a Verilog limitation here. The definition of @*
would create an event control with RAM in it, which as you have found
out, is not legal. Therefore @* is not defined when a memory is
involved. So ncsim is warning you that you are using something that is
not defined by the standard.

However, ncsim will do what is necessary to get the desired
combinational logic simulation behavior. The @* will be sensitive to
any change to any element of RAM. If you use nchelp to get the
extended help message for the warning you were given, it will tell you
this. So oData should be showing the correct value. It is possible
that there is a bug in this in ncsim, but none have been reported, so
it is more likely that you have made a mistake in your testing.
 

Welcome to EDABoard.com

Sponsor

Back
Top