subtype field1 is natural range 15 downto 0;
...
begin
memory_data_out_update:process(clk)
begin
...
if(condition)then
mem_do(field1)<=conv_std_logic_vector(128,16);
else
mem_do(field1)<=mem_di(8)(field1);
end if;
...
Mem_di(8)() is a clocked delayed version
of the memory input from a previous read cycle.
What I would like to do is automatically
calculate the "length" of the field1 range
and put it in the conv_std_logic_vector
parameters so that I can change my fields
definitions without changing the
conv_std_logic_vector code.
Brad Smallridge
AiVision
How about
constant field_length: integer := field1'high + 1 - field1'low;
Any chance of persuading you to ditch the old arith
packages in favour of numeric_std? Pretty please?
--
Jonathan Bromley
--
Jonathan Bromley, Verification Engineer
Verilab www.THAT_COMPANY.com
> What I would like to do is automatically
> calculate the "length" of the field1 range
I would use field1'length
-- Mike Treselre
>Brad Smallridge wrote:
>
>> What I would like to do is automatically
>> calculate the "length" of the field1 range
>
>I would use field1'length
Sadly that doesn't work; the 'length attribute
is not applicable to scalar subtypes.
(Confession: My first reaction was exactly the same
as Mike's. But then I tried it and, getting an error
from my simulator, was obliged to look it up.)
I'm assuming (perhaps incorrectly) that 'field1' is some sub-field of
some larger structure, then what I do is define a record with that
collection of fields like this
type t_MY_COLLECTION is record
Field1: std_ulogic_vector(15 downto 0);
Field2: std_ulogic_vector(31 downto 16);
end record t_MY_COLLECTION;
Then I create 'to_std_logic_vector' and 'from_std_logic_vector'
functions that convert the record to and from std_logic_vectors. The
record definition and the to/from functions get put into a package.
To get the length of the field you use...
t_MY_COLLECTION.Field1'length
or
Some_Sig.Field1'length (Some_Sig is of type t_MY_COLLECTION).
Now when any field within the record changes size, the ONLY edit you
will make is to the t_MY_COLLECTION record and then recompile. No
other edits required anywhere, everything gets adjusted and you don't
end up with having to do more than one edit and forgetting to do it
somewhere else
If interested, peruse the following links for previous posts where
I've gone into more detail
http://groups.google.com/group/comp.lang.vhdl/browse_frm/thread/1e9b58b644ff094b/e506f68794286061?hl=en&q=to_std_logic_vector+%22Kevin+Jennings%22
Kevin Jennings
Or perhaps this is a bit naff - but use
subtype field1 is std_logic_vector(15 downto 0);
mem_do(field1'range) <= ...... field1'length);
regards
Alan
--
Alan Fitch
>Or perhaps this is a bit naff - but use
>
>subtype field1 is std_logic_vector(15 downto 0);
>
>mem_do(field1'range) <= ...... field1'length);
I don't think that's naff at all. But it might be even
less naff to keep both the integer range subtype and
also the SLV subtype:
subtype field1_range is integer range 23 downto 8;
subtype field1_vec is std_logic_vector(field1_range);
...
signal field1: field1_vec;
...
field1 <= that_register(field1_range);
And if you want a version of field1 with the usual N-1..0
vector range, that's easy too:
signal normalized_field1 :
std_logic_vector(field1_vec'length-1 downto 0);
...
normalized_field1 <= field1;
See also KJ's post for an alternative approach based on
records. As Alan knows very well (he wrote the training
material on it!) there's an interesting set of tradeoffs
between describing bit-fields as components of a record,
or as slices of a vector; you must make your own choices
based on clarity, convenience and fit with your specific
design.
Thanks, Jonathan
> Any chance of persuading you to ditch the old arith
> packages in favour of numeric_std? Pretty please?
I do both and I believe it was your influence that started
me on numeric_std when I was having trouble with negative
numbers. There is something about numeric_std with something
simple, like +1, maybe, that's longer to write. Then if
you use signed and unsigned, then don't you write more to
send outputs to std_logic_vector outputs?
As Xilinx hangs on to the old package I worry superstitiously
about synthesis templates that create BRAMs. One time I
used both packages in the same module with no apparent
problem. Has any one mapped out all the conversions and
advantages of both libraries?
>> Any chance of persuading you to ditch the old arith
>> packages in favour of numeric_std? Pretty please?
>
>I do both and I believe it was your influence that started
>me on numeric_std when I was having trouble with negative
>numbers. There is something about numeric_std with something
>simple, like +1, maybe, that's longer to write. Then if
>you use signed and unsigned, then don't you write more to
>send outputs to std_logic_vector outputs?
Usually I find it's best to do just one type conversion,
using a simple concurrent signal assignment, to bring a
port in to an internal [un]signed signal and then do another
type conversion back to slv on the way out to an output port.
Then I use [un]signed signals and variables everywhere inside
the logic, and there is basically no unnecessary verbiage.
I agree that this sucks:
counter <= std_logic_vector( unsigned(counter) + 1 );
but it's completely unnecessary if you get the types right
in the first place. Custom conversion functions are your
friend, too.
>As Xilinx hangs on to the old package I worry superstitiously
>about synthesis templates that create BRAMs.
I don't think that's an issue at all. One of the last things
I did at Doulos was to write an appnote on BRAM inference
from Verilog and VHDL. All the examples used numeric_std
and they worked in every tool I tried, including ISE.
FYI that's at http://www.doulos.com/knowhow/fpga/technotes
(I got flamed at the time because of the need for
registration, but it's not really a big deal).
>One time I
>used both packages in the same module with no apparent
>problem.
numeric_std and std_logic_arith together? Weird. That
would have hidden the definitions of UNSIGNED and SIGNED,
rendering the packages pretty much useless.
> Has any one mapped out all the conversions and
>advantages of both libraries?
I guess so... but there's not a lot to say.
numeric_std vs. std_logic_arith
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
No contest; numeric_std is simply std_logic_arith
without the irritations - specifically:
- numeric_std's conversion functions have sensible
names like TO_INTEGER and RESIZE instead of
std_logic_arith's incomprehensible CONV_INTEGER
and EXT;
- numeric_std has a more complete set of operator
overloads, although in fairness that's not really
relevant for synthesis;
- it's properly standardized so you don't have to
rely on your tool vendor redistributing folklore
(although, to be fair, that's never been a problem).
Typically you can migrate code from std_logic_arith
to numeric_std simply by changing the names of a
few conversion functions; the types and operators
should all be OK.
numeric_std vs. std_logic_[un]signed
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Sure, it's kinda handy to be able to do
slv <= slv + 1;
but you lose so much else if you use std_logic_unsigned:
- no sane way to have signed and unsigned vectors in the
same scope;
- std_logic_[un]signed is so feature-poor that you almost
certainly need another package as well, leading to
possible confusion about what's in each package;
- for purists like me, it's distasteful to have slv (which
is supposed to be just a bag of bits) take on a numeric
significance; I want a distinct data type for numeric
vectors, thanks very much, so that I know what I'm working
with at any given time.
If you really, really must have std_logic_[un]signed,
don't forget that you can still use it alongside numeric_std
in just the same way that the dreaded Brand X synthesis
templates do with std_logic_arith:
use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all; -- OK
OK, that's the quarterly arith-packages rant off my chest...