Padding strings

Guest
Hello folks,

thought I could save the effort of writing a function to pad strings
by using 'Others =>' in a concatenation assignment as follows.

--some VHDL signal declarations
signal Signal_Name: std_logic;
signal My_String: string(1 to 15);
....
....
....
-- some VHDL signal assignments
My_String <= Signal_Name'Simple_Name & (Others => ' ');


So I'm attempting to pad the remaining 4 chars with a space.

Now the compiler tells me I can't use the 'Others' clause with
unconstrained strings, but 'My_String' is constrained, and
Signal_Name'Simple_Name must be constrained, or is it?

Is the reason this fails due to the way the compiler evaluates the
'Simple_Name attribute?

Any ideas?

Regards
John
 
On Wed, 21 Nov 2007 05:32:42 -0800 (PST), john.williamson@aculab.com
wrote:

Hello folks,

thought I could save the effort of writing a function to pad strings
Rarely a good idea. Because subprograms offer dynamic elaboration,
they make this kind of thing MUCH easier.

by using 'Others =>' in a concatenation assignment as follows.
My_String <= Signal_Name'Simple_Name & (Others => ' ');
But the OTHERS is not related to the target of the assignment,
because it's hidden away inside the expression - which has
an unconstrained subtype.

You could use the TEXTIO procedures, or you could write
your own function or procedure. By the way, why is My_String
a signal?

function padded_string(s: string; n: positive) return string
is
variable ps: string(1 to n) := (others => ' ');
begin
if s'length >= n then
ps := s(1 to n); --- truncate the source string
else
ps(1 to s'length) := s;
ps(s'length+1 to n) := (others => ' ');
end if;
return ps;
end;

Now you can do stuff like...

My_String <=
padded_string(Signal_Name'Simple_Name, My_String'length);

which seems to me to be a lot less hassle.
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
by using 'Others =>' in a concatenation assignment as follows.
My_String <= Signal_Name'Simple_Name & (Others => ' ');

But the OTHERS is not related to the target of the assignment,
because it's hidden away inside the expression - which has
an unconstrained subtype.

But if I did this:

My_String <= (Others => ' '); -- not very useful I know

then the assignment is valid. Is the expression now constrained in
this example?


btw, I used a 'signal' just to test the idea in a single line
assignment outside of a process.


John
 
On Wed, 21 Nov 2007 06:42:41 -0800 (PST),
john.williamson@aculab.com wrote:

My_String <= (Others => ' '); -- not very useful I know

then the assignment is valid. Is the expression now constrained in
this example?
Yes, it's all a bit magical but the aggregate can work out its
subtype from the other side of the assignment. But if you do

target <= str & (others => ' ');

then the aggregate is merely one of two unconstrained
arguments to the "&" function, and it has no clue what
its subtype is supposed to be. All operators in VHDL
are simply functions with funky syntax, and their
operands are just arguments to the operator function.
You could (completely legally) rewrite the assignment
as

target <= "&"(str, (others => ' '));

and then I guess it's more obvious that the "others"
is unlikely to be able to do anything useful.

Something that's always wound me up about VHDL is the
way a function cannot learn anything about the subtype
context of its return value. It would be SOOOO useful
if it could.... but that's another story. And you can
always get that effect with procedures - but the syntax
is nowhere near so pretty when you're doing calculations
and trying to write expressions.

It sounds as though you're trying to do something about
registering signal names so that you can implement your
select-a-signal-by-string-name idea from an earlier post.
Interesting.....
--
Jonathan Bromley, Consultant

DOULOS - Developing Design Know-how
VHDL * Verilog * SystemC * e * Perl * Tcl/Tk * Project Services

Doulos Ltd., 22 Market Place, Ringwood, BH24 1AW, UK
jonathan.bromley@MYCOMPANY.com
http://www.MYCOMPANY.com

The contents of this message may contain personal views which
are not the views of Doulos Ltd., unless specifically stated.
 
john.williamson@aculab.com wrote:

by using 'Others =>' in a concatenation assignment as follows.
My_String <= Signal_Name'Simple_Name & (Others => ' ');

But the OTHERS is not related to the target of the assignment,
because it's hidden away inside the expression - which has
an unconstrained subtype.

But if I did this:

My_String <= (Others => ' '); -- not very useful I know
But it is useful!

You could do:

My_String <= (Others => ' ');
My_String(1 To Signal_Name'Simple_Name'Length) <= Signal_Name'Simple_Name;

The first assignment schedules all characters of My_String to be set to
space. The the second assignment schedules the desired string to put into
My_String.

With signal assignments, the last assignments "wins", so after one delta,
the result is what you want: your string padded with spaces.

Wrapping the above two statements in a procedure will make things easier to
use.

Untested:

Procedure Set_Name
(
Signal S: Out String
) Is
Constant S_Len: natural := S'Length;
Begin
S <= (Others => ' ');
S(1 To S_Len) <= S'Simple_Name;
End Procedure Set_Name;

If "S <= (Others => ' ')" does not work, "S <= (S'Range => ' ')" certainly
will.

Usage:

Set_Name(My_String);


--
Paul Uiterlinden
www.aimvalley.nl
e-mail addres: remove the not.
 
Thanks for the tips and advice guys, a useful discussion.

Regards
John
 

Welcome to EDABoard.com

Sponsor

Back
Top