FPGA Central - World's 1st FPGA / CPLD Portal

FPGA Central

World's 1st FPGA Portal

 

Go Back   FPGA Groups > NewsGroup > VHDL

VHDL comp.lang.vhdl newsgroup / Usenet

Reply
 
LinkBack Thread Tools Display Modes
  #1 (permalink)  
Old 10-27-2003, 02:51 PM
Matt North
Guest
 
Posts: n/a
Default Array Types

I have a type which is generated in a package:

<<type matrix is array(natural range<>) of bit_vector(7 downto 0);

the functions in the package return constrained arrays of type matrix:

<<return matrix is variable result: matrix(0 to length);

When i then go to use the type matrix in my entity:

<<variable rom:=matrix;

I get a warning saying that rom cant be an unconstrained type, i understand
that matrix is unconstrained (array(natural range<>)) however the results
returned by the function in the package constrain the array.

Does anyone know of anyway of constraining the type matrix in the package
depending on the size of the array that each individual function returns?
In the finished code i would like to have a number of functions which all
return different sized arrays (all of the same type), which can then be used
by the entity.

Thanks,
Matt


Reply With Quote
  #2 (permalink)  
Old 10-27-2003, 03:39 PM
Jonathan Bromley
Guest
 
Posts: n/a
Default Re: Array Types

"Matt North" <[email protected]_SPAMrl.ac.uk> wrote in
message news:[email protected]

> I have a type which is generated in a package:
> <<type matrix is array(natural range<>) of bit_vector(7 downto 0);
> the functions in the package return constrained arrays of type matrix:
> <<return matrix is variable result: matrix(0 to length);
> When i then go to use the type matrix in my entity:
> <<variable rom:=matrix;
> I get a warning saying that rom cant be an unconstrained type, i

understand
> that matrix is unconstrained (array(natural range<>)) however the results
> returned by the function in the package constrain the array.
>
> Does anyone know of anyway of constraining the type matrix in the package
> depending on the size of the array that each individual function returns?
> In the finished code i would like to have a number of functions which all
> return different sized arrays (all of the same type), which can then be

used
> by the entity.


I suspect you're fighting VHDL here, rather than letting it help you.

First, the answer to your explicit question: Yes, but it's clumsy.
Variables must be given a constrained subtype (so that the compiler
knows how much memory to allocate for them, as a first cut at an
explanation). If each of your functions returns a specific
constrained subtype of "matrix" then you can use it thus:

function fun_matN (...) return matrix(N-1 downto 0);
...
-- Make a constant whose range matches fun_matN().
-- Function parameters can be any old junk, because
-- you are never going to use the value of its result.
constant const_matN: matrix := fun_matN(...);
-- Use that constant's range to create a variable:
variable var_matN: matrix(const_matN'range);

Now that you've done this, of course, you can with confidence
write procedural code thus:

var_matN := fun_matN(...);

BUT................
in my experience it's pretty rare for it to be useful to return
a variety of fixed-width results from a variety of functions.
I can't speak for your application of course, but generally
it's much more useful to have the function return a result whose
range is determined dynamically, based on the properties of its
parameters. For example, the "+" operator in numeric_std
returns a result whose width is the larger of its two operands'
widths. In this kind of situation, you can generally decide
in advance what ranges your various data items need.

If your function is genuinely returning a constant - for example,
some constant vector that needs calculation but is always the
same, such as a Fibonacci sequence or the values of
arctan(2^-n) needed for a CORDIC engine - then you can drop
its result into a VHDL constant. As my example above shows,
you don't need to specify the range of a constant; it's
determined from the constant's initialisation expression.

Finally, one last idea: Consider writing a "resize"
procedure that allows you to shoe-horn the result of
any "matrix" expression into an arbitrary "matrix"
variable. Of course, the correct behaviour of truncation
and extension depends on what you're trying to do - in
my example I fill from left to right, throwing away
unused right-hand elements of the source matrix, and
padding un-filled right-hand elements of the destination
with a dummy value.

procedure coerce (
dst: out matrix;
src: in matrix;
dummy: bit_vector(7 downot 0) := "00000000") is
-- Normalise array ranges to 1..N layout.
alias norm_src: matrix(1 to src'length) is src;
alias norm_dst: matrix(1 to dst'length) is dst;
begin
for i in norm_dst'range loop
if i > src'length then
norm_dst(i) := dummy;
else
norm_dst(i) := norm_src(i);
end if;
end loop;
end; -- procedure coerce

Give us a bit more detail about what you are trying to do,
and perhaps we can be more helpful for your specific needs.
--
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: [email protected]
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.



Reply With Quote
  #3 (permalink)  
Old 10-27-2003, 04:52 PM
VhdlCohen
Guest
 
Posts: n/a
Default Re: Array Types

>I have a type which is generated in a package:
>
><<type matrix is array(natural range<>) of bit_vector(7 downto 0);
>
>the functions in the package return constrained arrays of type matrix:
>
><<return matrix is variable result: matrix(0 to length);
>
>When i then go to use the type matrix in my entity:
>
><<variable rom:=matrix;
>
>I get a warning saying that rom cant be an unconstrained type, i understand
>that matrix is unconstrained (array(natural range<>)) however the results
>returned by the function in the package constrain the array.
>
>Does anyone know of anyway of constraining the type matrix in the package
>depending on the size of the array that each individual function returns?
>In the finished code i would like to have a number of functions which all
>return different sized arrays (all of the same type), which can then be used
>by the entity.


Matt,
You need to constraint the variable.
function X (data : matrix) return matrix is
variable result : matrix(0 to data'lenth);
begin
...
return result;
end function X;

process ...
variable rom : matrix(0 to 127);
begin
rom := X(rom);
----------------------------------------------------------------------------
Ben Cohen Publisher, Trainer, Consultant (310) 721-4830
http://www.vhdlcohen.com/ [email protected]
Author of following textbooks:
* Using PSL/SUGAR with Verilog and VHDL
Guide to Property Specification Language for ABV, 2003 isbn 0-9705394-4-4
* Real Chip Design and Verification Using Verilog and VHDL, 2002 isbn
0-9705394-2-8
* Component Design by Example ", 2001 isbn 0-9705394-0-1
* VHDL Coding Styles and Methodologies, 2nd Edition, 1999 isbn 0-7923-8474-1
* VHDL Answers to Frequently Asked Questions, 2nd Edition, isbn 0-7923-8115
------------------------------------------------------------------------------
Reply With Quote
  #4 (permalink)  
Old 10-28-2003, 03:07 PM
Matt North
Guest
 
Posts: n/a
Default Re: Array Types

Ive has a go at implementing your comments but i cant seem to get it to
work.
I will explain my situation in greater detail.

I have package which has a number of functions in them which all return a
variable result of type matrix which is an unconstrained array of bit_vector

One of the functions shown below is ChWrite which is given a string of text
which it converts each ascii character into a bit_vector, the length of
array that this functions returns
therefore changes with each call dependant on the variable 'length'.

--declaration in package
type matrix is array (natural range<>) of bit_vector(7 downto 0);

function ChWrite (font: string(1 to 3); char: string; length: integer)
return matrix;

--function
function ChWrite (font: string(1 to 3); char: string; length: integer)
return matrix is
subtype int_r is integer range 0 to 1;
variable i: int_r :=0;
variable n, ch_int: integer :=0;
variable ch: character;
variable result: matrix(0 to length);
begin

while i<1 loop

if font="nrm" then
result(0):=X"1d";
i:=1;
elsif font="sml" then
result(0):=X"1c";
i:=1;
elsif font="lrg" then
result(0):=X"1e";
i:=1;
else
result(0):=X"1d";
i:=1;
end if;

exit when i=1;
end loop;


while n<length loop
ch:=char(n+1);
ch_int:=character'POS(ch);
result(n+1):=to_bitvector(std_logic_vector(to_unsi gned(ch_int, 8)));
n:=n+1;
exit when n=length;
end loop;

return result;
end ChWrite;

The code below shows what i am doing with the result returned from the
function above.
rom is of type matrix, but needs to be constrained by the size of the array
returned by ChWrite.

signal rom: matrix(0 to ??);
signal nxt_line: matrix(0 to 2);

begin

nxt_line<=(X"0d", X"0a", X"20");

process(rst, clk, ilock)
begin
if rising_edge(clk) then
if ilock(0)='0' then
rom<=(ChWrite("sml", "LD1: something", 24) & nxt_line);
elsif ilock(1)='0' then
rom<=(ChWrite("sml", "LD2: something else", 35) & nxt_line);
elsif ilock(2)='0' then
rom<=(ChWrite("sml", "LD3: something different", 14) & nxt_line);
else
rom:=(others=>"00000000");
end if;
end if;
end process;

As you can see the result from ChWrite will be a different size each time,
making it very hard to constrain rom.
"Jonathan Bromley" <[email protected]> wrote in message
news:[email protected]
> "Matt North" <[email protected]_SPAMrl.ac.uk> wrote in
> message news:[email protected]
>
> > I have a type which is generated in a package:
> > <<type matrix is array(natural range<>) of bit_vector(7 downto 0);
> > the functions in the package return constrained arrays of type matrix:
> > <<return matrix is variable result: matrix(0 to length);
> > When i then go to use the type matrix in my entity:
> > <<variable rom:=matrix;
> > I get a warning saying that rom cant be an unconstrained type, i

> understand
> > that matrix is unconstrained (array(natural range<>)) however the

results
> > returned by the function in the package constrain the array.
> >
> > Does anyone know of anyway of constraining the type matrix in the

package
> > depending on the size of the array that each individual function

returns?
> > In the finished code i would like to have a number of functions which

all
> > return different sized arrays (all of the same type), which can then be

> used
> > by the entity.

>
> I suspect you're fighting VHDL here, rather than letting it help you.
>
> First, the answer to your explicit question: Yes, but it's clumsy.
> Variables must be given a constrained subtype (so that the compiler
> knows how much memory to allocate for them, as a first cut at an
> explanation). If each of your functions returns a specific
> constrained subtype of "matrix" then you can use it thus:
>
> function fun_matN (...) return matrix(N-1 downto 0);
> ...
> -- Make a constant whose range matches fun_matN().
> -- Function parameters can be any old junk, because
> -- you are never going to use the value of its result.
> constant const_matN: matrix := fun_matN(...);
> -- Use that constant's range to create a variable:
> variable var_matN: matrix(const_matN'range);
>
> Now that you've done this, of course, you can with confidence
> write procedural code thus:
>
> var_matN := fun_matN(...);
>
> BUT................
> in my experience it's pretty rare for it to be useful to return
> a variety of fixed-width results from a variety of functions.
> I can't speak for your application of course, but generally
> it's much more useful to have the function return a result whose
> range is determined dynamically, based on the properties of its
> parameters. For example, the "+" operator in numeric_std
> returns a result whose width is the larger of its two operands'
> widths. In this kind of situation, you can generally decide
> in advance what ranges your various data items need.
>
> If your function is genuinely returning a constant - for example,
> some constant vector that needs calculation but is always the
> same, such as a Fibonacci sequence or the values of
> arctan(2^-n) needed for a CORDIC engine - then you can drop
> its result into a VHDL constant. As my example above shows,
> you don't need to specify the range of a constant; it's
> determined from the constant's initialisation expression.
>
> Finally, one last idea: Consider writing a "resize"
> procedure that allows you to shoe-horn the result of
> any "matrix" expression into an arbitrary "matrix"
> variable. Of course, the correct behaviour of truncation
> and extension depends on what you're trying to do - in
> my example I fill from left to right, throwing away
> unused right-hand elements of the source matrix, and
> padding un-filled right-hand elements of the destination
> with a dummy value.
>
> procedure coerce (
> dst: out matrix;
> src: in matrix;
> dummy: bit_vector(7 downot 0) := "00000000") is
> -- Normalise array ranges to 1..N layout.
> alias norm_src: matrix(1 to src'length) is src;
> alias norm_dst: matrix(1 to dst'length) is dst;
> begin
> for i in norm_dst'range loop
> if i > src'length then
> norm_dst(i) := dummy;
> else
> norm_dst(i) := norm_src(i);
> end if;
> end loop;
> end; -- procedure coerce
>
> Give us a bit more detail about what you are trying to do,
> and perhaps we can be more helpful for your specific needs.
> --
> 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:

[email protected]
> 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.
>
>
>



Reply With Quote
  #5 (permalink)  
Old 10-28-2003, 03:50 PM
Jonathan Bromley
Guest
 
Posts: n/a
Default Re: Array Types

"Matt North" <[email protected]_SPAMrl.ac.uk> wrote in
message news:[email protected]

[snip function code...]
> The code below shows what i am doing with the result
> returned from the function above.


> rom is of type matrix, but needs to be constrained
> by the size of the array returned by ChWrite.
> signal rom: matrix(0 to ??);
> signal nxt_line: matrix(0 to 2);


I'm kinda bewildered here. If "rom" is a signal, then its size
is fixed for the life of the simulation. You can't make a signal
stretch dynamically according to what you put in it.

Consequently, it would make more sense to arrange your ChWrite
function to return a result of the appropriate size, rather
than trying to squeeze the wrong-size result into "rom".
You can do that either by passing the function an extra
parameter indicating how large a result it should create,
or by re-coding it as a procedure (see below).

> As you can see the result from ChWrite
> will be a different size each time,
> making it very hard to constrain rom.


Indeed!

The question is: what are you REALLY trying to do?

If "rom" is just an internal variable in some kind of
test bench, then you should probably re-cast it as a
variable of access type. The LINE type in std.textio
works like this, and gives you (in effect) variable-length
strings; you can do the same yourself. But of course it
doesn't work for signals, because (as I already mentioned)
a signal is created once and for all at the beginning
of simulation.

But if you genuinely need "rom" to be a signal, perhaps
because it's really a buffer in synthesised logic, then
surely its size will be fixed in hardware; and therefore
you need to modify ChWrite so it puts its result into
an appropriate *part* of "rom". To do this, it's probably
best to re-cast ChWrite as a procedure rather than as a
function. You then supply "rom" as an "out" parameter of
the procedure; the procedure can find out how big its
parameter is, and fill the appropriate slice of it.

Finally, I'll ask again: is "rom" intended to be a constant?
If so, then declare it as a constant and your problems go
away.

To sum up: as I said in an earlier post, I think you're
fighting VHDL instead of letting it work for you; but I
can't help much more without some context about what
you are trying to achieve.

--

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: [email protected]
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.



Reply With Quote
  #6 (permalink)  
Old 10-28-2003, 04:18 PM
Matt North
Guest
 
Posts: n/a
Default Re: Array Types

Jonathan,

Thanks for your quick reply.

> You can't make a signal
> stretch dynamically according to what you put in it.


This would indicate why i am having so much trouble!!

A bit of background to the project this concerns.
I am driving a VFD using a Lattice CPLD, the CPLD looks at a number of
inputs, if an input goes high it indicates an interlock has been tripped
and writes information about the alarm on a VFD screen.
Thus rom cant be constant as different info needs to be written to the VFD
depending on which interlock
has tripped.
I decided to write a package which encompases all of the VFD software
commands as functions, making it neater to write and easier to understand.
Especially when it comes to writing text to the VFD; writing a string is
alot easier than looking at an ascii table and writing the hex. into the
array.

> Consequently, it would make more sense to arrange your ChWrite
> function to return a result of the appropriate size, rather
> than trying to squeeze the wrong-size result into "rom".


My function does this already as you have to specify the string length when
you call the function.

<<function ChWrite (font: string(1 to 3); char: string; length: integer)
<< return matrix is variable result: matrix(0 to length);
<<blahblah.....
<<return result;

Anyway I have managed to solve the trouble i was having, using the code
below (not a very good solution but it does the job)

signal rom: matrix(0 to a_large_no.);

process(rst, clk, ilock)
begin
if rising_edge(clk) then
if ilock(0)='0' then
rom(0 to 27)<=(ChWrite("sml", "LD1: I've switched no. 1", 24) &
nxt_line);

elsif ilock(1)='0' then
rom(0 to 38)<=(ChWrite("sml", "LD2: asdfg", 35) & nxt_line);

elsif ilock(2)='0' then
rom(0 to 17)<=(ChWrite("sml", "LD3: DANGER!!!", 14) & nxt_line);

else
rom<=(others=>"00000000");
end if;
end if;
end process;

Thanks for your help.
Matt

"Jonathan Bromley" <[email protected]> wrote in message
news:[email protected]
> "Matt North" <[email protected]_SPAMrl.ac.uk> wrote in
> message news:[email protected]
>
> [snip function code...]
> > The code below shows what i am doing with the result
> > returned from the function above.

>
> > rom is of type matrix, but needs to be constrained
> > by the size of the array returned by ChWrite.
> > signal rom: matrix(0 to ??);
> > signal nxt_line: matrix(0 to 2);

>
> I'm kinda bewildered here. If "rom" is a signal, then its size
> is fixed for the life of the simulation. You can't make a signal
> stretch dynamically according to what you put in it.
>
> Consequently, it would make more sense to arrange your ChWrite
> function to return a result of the appropriate size, rather
> than trying to squeeze the wrong-size result into "rom".
> You can do that either by passing the function an extra
> parameter indicating how large a result it should create,
> or by re-coding it as a procedure (see below).
>
> > As you can see the result from ChWrite
> > will be a different size each time,
> > making it very hard to constrain rom.

>
> Indeed!
>
> The question is: what are you REALLY trying to do?
>
> If "rom" is just an internal variable in some kind of
> test bench, then you should probably re-cast it as a
> variable of access type. The LINE type in std.textio
> works like this, and gives you (in effect) variable-length
> strings; you can do the same yourself. But of course it
> doesn't work for signals, because (as I already mentioned)
> a signal is created once and for all at the beginning
> of simulation.
>
> But if you genuinely need "rom" to be a signal, perhaps
> because it's really a buffer in synthesised logic, then
> surely its size will be fixed in hardware; and therefore
> you need to modify ChWrite so it puts its result into
> an appropriate *part* of "rom". To do this, it's probably
> best to re-cast ChWrite as a procedure rather than as a
> function. You then supply "rom" as an "out" parameter of
> the procedure; the procedure can find out how big its
> parameter is, and fill the appropriate slice of it.
>
> Finally, I'll ask again: is "rom" intended to be a constant?
> If so, then declare it as a constant and your problems go
> away.
>
> To sum up: as I said in an earlier post, I think you're
> fighting VHDL instead of letting it work for you; but I
> can't help much more without some context about what
> you are trying to achieve.
>
> --
>
> 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:

[email protected]
> 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.
>
>
>



Reply With Quote
  #7 (permalink)  
Old 10-28-2003, 04:59 PM
Jonathan Bromley
Guest
 
Posts: n/a
Default Re: Array Types

"Matt North" <[email protected]_SPAMrl.ac.uk> wrote in
message news:[email protected]

> A bit of background to the project this concerns.
> I am driving a VFD using a Lattice CPLD, the CPLD looks at a number of
> inputs, if an input goes high it indicates an interlock has been tripped
> and writes information about the alarm on a VFD screen.
> Thus rom cant be constant as different info needs to be written to the VFD
> depending on which interlock
> has tripped.
> I decided to write a package which encompases all of the VFD software
> commands as functions, making it neater to write and easier to understand.
> Especially when it comes to writing text to the VFD; writing a string is
> alot easier than looking at an ascii table and writing the hex. into the
> array.


This is good, but may make things a little difficult in hardware...

> > Consequently, it would make more sense to arrange your ChWrite
> > function to return a result of the appropriate size, rather
> > than trying to squeeze the wrong-size result into "rom".

>
> My function does this already as you have to specify the string length

when
> you call the function.


Yes - but the relationship is somewhat indirect. Your "length"
parameter is essentially just the length of the (readable) argument
string. You don't need to pass that; it can easily be derived from
the string parameter anyhow.

> Anyway I have managed to solve the trouble i was having, using the code
> below (not a very good solution but it does the job)


Can I go back to my suggestion about a procedure? Also, you can
exploit constants far more than you have done.

~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~
package VFD_Stuff is
constant next_line: string := CR & LF & ' ';
constant fontSmall: bit_vector := X"1c";
constant fontNormal: bit_vector := X"1d";
constant fontLarge: bit_vector := X"1e";
procedure ChWrite(
signal dest: out matrix;
font: bit_vector;
info: string);
function char_to_bv(c: character) return bit_vector;
end; -- package VFD_Stuff

package body VFD_Stuff is
function char_to_bv(c: character) return bit_vector is
begin
return to_bitvector(std_logic_vector(to_unsigned(c'pos, 8)));
end; -- function char_to_bv
procedure ChWrite(
signal dest: out matrix;
font: bit_vector;
info: string) is
begin
for i in dest'range loop
if i=0 then
-- Put font control into first element
dest(0) <= font;
elsif i <= dest'high then
if i <= info'length then
-- Copy string to destination
dest(i) <= char_to_bv(info(i));
else
-- Pack remainder of dest with null
dest(i) <= (others => '0');
end if;
else
-- Truncate info if we fell off the end of dest
return;
end if;
end loop;
end; -- proc ChWrite
end; -- package body VFD_Stuff
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~
Now let's use it....
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~
constant ROM_SIZE: positive := 40; -- or whatever
signal rom: matrix(0 to ROM_SIZE-1);

process(rst, clk) -- don't need ilock in sensitivity list
begin
if rising_edge(clk) then
-- Default assignment to "rom"...
rom<=(others=>"00000000");
if ilock(0)='0' then
ChWrite(rom, fontSmall, "LD1: I've switched no. 1" & next_line);
elsif ilock(1)='0' then
ChWrite(rom, fontSmall, "LD2: asdfg" & next_line);
elsif ilock(2)='0' then
ChWrite(rom, fontSmall, "LD3: DANGER!!!" & nxt_line);
end if;
end if;
end process;
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~

What I've written above does exactly the same as your
code, but I think it's a bit cleaner and more maintainable.

Question: in hardware, your "rom" will end up as a massive
collection of flip-flops.... is that what you want???
--
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: [email protected]
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.



Reply With Quote
  #8 (permalink)  
Old 10-29-2003, 09:21 AM
Matt North
Guest
 
Posts: n/a
Default Re: Array Types

Johnathan,

I agree that using a procedure as a subprogram is definately the way to go,
as a function can only return one result.
Your example below is a more readable version than my original code,
thankyou for your help.
It is still a slight annoyance that the range of rom cannot be passed from
the procedure making its size dynamic with regard
to the string length, but this cannot be done in the real world with memory
so why should vhdl do it!!!

As regards your comment about rom being a no. of flip-flops. I realise that
i will have to model a ram structure, however different
synthesis tools recognise memory architectures in different ways to enable
them to match the process to a memory macro (as i am sure you well know!).
I am using Leonardo Spectrum, i haven't modelled ram in it before, it will
be interesting to see how well it models ram.

Thanks,

Matt

"Jonathan Bromley" <[email protected]> wrote in message
news:[email protected]
> "Matt North" <[email protected]_SPAMrl.ac.uk> wrote in
> message news:[email protected]
>
> > A bit of background to the project this concerns.
> > I am driving a VFD using a Lattice CPLD, the CPLD looks at a number of
> > inputs, if an input goes high it indicates an interlock has been tripped
> > and writes information about the alarm on a VFD screen.
> > Thus rom cant be constant as different info needs to be written to the

VFD
> > depending on which interlock
> > has tripped.
> > I decided to write a package which encompases all of the VFD software
> > commands as functions, making it neater to write and easier to

understand.
> > Especially when it comes to writing text to the VFD; writing a string is
> > alot easier than looking at an ascii table and writing the hex. into the
> > array.

>
> This is good, but may make things a little difficult in hardware...
>
> > > Consequently, it would make more sense to arrange your ChWrite
> > > function to return a result of the appropriate size, rather
> > > than trying to squeeze the wrong-size result into "rom".

> >
> > My function does this already as you have to specify the string length

> when
> > you call the function.

>
> Yes - but the relationship is somewhat indirect. Your "length"
> parameter is essentially just the length of the (readable) argument
> string. You don't need to pass that; it can easily be derived from
> the string parameter anyhow.
>
> > Anyway I have managed to solve the trouble i was having, using the code
> > below (not a very good solution but it does the job)

>
> Can I go back to my suggestion about a procedure? Also, you can
> exploit constants far more than you have done.
>
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~
> package VFD_Stuff is
> constant next_line: string := CR & LF & ' ';
> constant fontSmall: bit_vector := X"1c";
> constant fontNormal: bit_vector := X"1d";
> constant fontLarge: bit_vector := X"1e";
> procedure ChWrite(
> signal dest: out matrix;
> font: bit_vector;
> info: string);
> function char_to_bv(c: character) return bit_vector;
> end; -- package VFD_Stuff
>
> package body VFD_Stuff is
> function char_to_bv(c: character) return bit_vector is
> begin
> return to_bitvector(std_logic_vector(to_unsigned(c'pos, 8)));
> end; -- function char_to_bv
> procedure ChWrite(
> signal dest: out matrix;
> font: bit_vector;
> info: string) is
> begin
> for i in dest'range loop
> if i=0 then
> -- Put font control into first element
> dest(0) <= font;
> elsif i <= dest'high then
> if i <= info'length then
> -- Copy string to destination
> dest(i) <= char_to_bv(info(i));
> else
> -- Pack remainder of dest with null
> dest(i) <= (others => '0');
> end if;
> else
> -- Truncate info if we fell off the end of dest
> return;
> end if;
> end loop;
> end; -- proc ChWrite
> end; -- package body VFD_Stuff
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~
> Now let's use it....
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~
> constant ROM_SIZE: positive := 40; -- or whatever
> signal rom: matrix(0 to ROM_SIZE-1);
>
> process(rst, clk) -- don't need ilock in sensitivity list
> begin
> if rising_edge(clk) then
> -- Default assignment to "rom"...
> rom<=(others=>"00000000");
> if ilock(0)='0' then
> ChWrite(rom, fontSmall, "LD1: I've switched no. 1" & next_line);
> elsif ilock(1)='0' then
> ChWrite(rom, fontSmall, "LD2: asdfg" & next_line);
> elsif ilock(2)='0' then
> ChWrite(rom, fontSmall, "LD3: DANGER!!!" & nxt_line);
> end if;
> end if;
> end process;
> ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~
>
> What I've written above does exactly the same as your
> code, but I think it's a bit cleaner and more maintainable.
>
> Question: in hardware, your "rom" will end up as a massive
> collection of flip-flops.... is that what you want???
> --
> 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:

[email protected]ulos.com
> 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.
>
>
>



Reply With Quote
Reply

Bookmarks

Thread Tools
Display Modes

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 On


Similar Threads
Thread Thread Starter Forum Replies Last Post
Using contents of one array to index into another array kb33 Verilog 3 10-08-2006 07:12 PM
Reconfigurable Array of Array Antti Lukats FPGA 5 01-23-2006 08:20 PM
Using nested, unconstrained array types? Alex Rast VHDL 3 10-06-2003 08:08 PM
Different types of ASICs? Michael VHDL 1 09-01-2003 01:14 PM
Different types of ASICs? Michael FPGA 1 09-01-2003 09:35 AM


All times are GMT +1. The time now is 06:00 PM.


Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2020, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.2.0
Copyright 2008 @ FPGA Central. All rights reserved