![]() |
|
|
|
#1 |
|
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 john.williamson@aculab.com |
|
|
|
|
#2 |
|
Posts: n/a
|
On Wed, 21 Nov 2007 05:32:42 -0800 (PST),
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 http://www.MYCOMPANY.com The contents of this message may contain personal views which are not the views of Doulos Ltd., unless specifically stated. Jonathan Bromley |
|
|
|
#3 |
|
Posts: n/a
|
> >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 john.williamson@aculab.com |
|
|
|
#4 |
|
Posts: n/a
|
On Wed, 21 Nov 2007 06:42:41 -0800 (PST),
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 http://www.MYCOMPANY.com The contents of this message may contain personal views which are not the views of Doulos Ltd., unless specifically stated. Jonathan Bromley |
|
|
|
#5 |
|
Posts: n/a
|
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. Paul Uiterlinden |
|
|
|
#6 |
|
Posts: n/a
|
Thanks for the tips and advice guys, a useful discussion.
Regards John john.williamson@aculab.com |
|