I think that the problem with a language-native way is that there is no
dynamic typing. Each field can have a different data type, and so there is
no expression type that could represent any field in the record. An
alternative is to use the VHPI.
Peter.
From: owner-vhdl-200x@eda.org [mailto:owner-vhdl-200x@eda.org] On Behalf Of
Huffman, Nathanael D (GE Healthcare)
Sent: 17 July 2012 23:02
To: vhdl-200x@eda.org
Subject: RE: EXTERNAL: Re: [vhdl-200x] Directional records proposal
I use record types as command and status registers. In order to make this
useful I have a tcl script that generates overloaded pack() and unpack()
functions that convert the records into slvs for interfacing with a databus
for the processor. I think the ability to loop through record elements
could allow a language-native way of doing this rather than using a
pre-processor to generate these functions. The individual functions would
still be required due to the different types for each register, but they
could be coded in a generic way by looping through the record and
concatenating rather than the "hard-coded" method of assigning record fields
to slices of the returned vector.
Nathanael
From: owner-vhdl-200x@eda.org [mailto:owner-vhdl-200x@eda.org] On Behalf Of
Brent Hayhoe
Sent: Tuesday, July 17, 2012 4:50 PM
To: vhdl-200x@eda.org
Subject: Re: EXTERNAL: Re: [vhdl-200x] Directional records proposal
Daniel,
I would agree that iterating through elements of records is required and
although I can't think of any obvious examples, I'm sure I've had code in
the past that would have benefited from it.
Maybe we need something like a 'foreach rec_type loop' structure to cycle
through the record's elements.
On 17/07/2012 16:45, Daniel Kho wrote:
Andy,
<quote>
Can a for-loop iterate through the elements of a record? If so, are there
any restrictions? This ability would be really nice for converting records
of slv elements to one long slv, (and back), etc. But other than that fairly
narrow application, I can't think of any huge benefits of it. Anybody have
some other useful applications?
For I in sub_record_type'range loop
My_vector(j to j + my_record.i'length) := my_record.i;
J := j + my_record.i'length + 1;
End loop;
</quote
I was thinking of using something like this in a resolution function to
selectively iterate across a record:
<code>
/* same like before. */
type t_cpu_bus is record
...
end record t_cpu_bus;
/* vector of records that needs to be resolved. */
type t_cpuBusVector is array(natural range <>) of t_cpu_bus;
/* the resolution function - just an idea, more work needed here. */
function resolveRecords(signal someRecordArray: t_cpuBusVector) return
t_cpu_bus is
variable resolvedRecord: t_cpu_bus := (adr | dat => (others=>'0'), we |
en => '1', others=>'-'); -- possible use of don't-cares for inputs here?
begin
/* Here we resolve between 2 records that drive the same signals. But,
we need a more complete solution that iterates the resolution of N records.
*/
/* Loop across elements of record.
someRecordArray(0) = the record.
someRecordArray(0).i = one of the record's elements (assume
an array type, can be array of std_logic, std_ulogic, bit. E.gs.:
unsigned/signed, std_ulogic_vector, bit_vector).
(someRecordArray(0).i)(j) = one of the record's subelements
(assume the subelement is std_ulogic).
*/
/* Here we are assuming the lengths and datatypes for both records are
identical. We can implement extra checks / assertions here.
I use "someRecordArray(0)" though it may as well be
"someRecordArray(1)".
Note: Accessing i from (someRecordArray(0).i) in the for-declaration
may be illegal as of current version of the standard.
*/
for i in (someRecordArray(0).i)'range loop
/* Compare the sub-elements of each record type. Here, the
sub-elements are concatenated, then compared. */
case? (someRecordArray(0).i)(j) & (someRecordArray(1).i)(j) is
when "--" => (resolvedRecord.i)(j) <= '-';
when "UX" | "XU" => (resolvedRecord.i)(j) <= 'X';
when "U-" => (resolvedRecord.i)(j) <=
(someRecordArray(1).i)(j);
when "-U" => (resolvedRecord.i)(j) <=
(someRecordArray(0).i)(j);
when "X-" | "-X" => (resolvedRecord.i)(j) <= 'X';
when "W-" | "-W" => (resolvedRecord.i)(j) <= 'W';
when "ZZ" => (resolvedRecord.i)(j) <= 'Z';
when "Z-" => (resolvedRecord.i)(j) <=
(someRecordArray(1).i)(j);
when "-Z" => (resolvedRecord.i)(j) <=
(someRecordArray(0).i)(j);
when "10" | "01" => (resolvedRecord.i)(j) <= 'X';
when "HH" => (resolvedRecord.i)(j) <= 'H';
when "11" | "1H" | "H1" => (resolvedRecord.i)(j) <= '1';
when "00" | "0L" | "L0" => (resolvedRecord.i)(j) <= '0';
when others => (resolvedRecord.i)(j) <= 'X';
end case?;
j := j + someRecordArray(0).i'length + 1;
return resolvedRecord;
end function resolveRecords;
signal cpu_bus: resolveRecords t_cpu_bus;
</code>
This is an example that tries to resolve between 2 records I/Os. More work
needed here to have a more generic function that resolves N number of
records.
Also, this example tries to resolve _every_ element of the record. We could
implement more conditionals within the resolution function to be more
selective in resolving only those elements we need.
I have used some constructs that are not supported by the current version of
the standard, such as accessing record subelements [using
someRecordArray(0).i)(j)], which may need more rethinking.
Another question raised before by Ryan: how do we get the compiler to
distinguish between a custom mode and a resolution function?
<quote>Regarding resolution functions, it doesn't make sense to have a
user-defined mode for a type with a resolution function. I suggest that
such a model be illegal.</quote>
Previously we had this:
bus_rio : m_master t_cpu_bus;
which is a port definition with a custom mode.
And now, to resolve between various records, we have this:
signal cpu_bus: resolveRecords t_cpu_bus;
As suggested before by Ryan, it's probably good to make illegal trying to
associate a port or signal to both a resolution function and a custom mode.
We should only be able to either associate a resolution function, or a
custom mode to a port or signal, not both at the same time. Then it becomes
clear and unambiguous to the compiler as to whether a mode association is
required or a resolution function is required.
-daniel
--
Regards,
Brent Hayhoe.
Aftonroy Limited Telephone: +44 (0)20-8449-1852
135 Lancaster Road,
New Barnet, Mobile: +44 (0)79-6647-2574
Herts., EN4 8AJ, U.K. Email:
Brent.Hayhoe@Aftonroy.com
Registered Number: 1744190 England.
Registered Office:
4th Floor, Imperial House,
15 Kingsway,
London, WC2B 6UN, U.K.
Received on Wed Jul 18 07:31:20 2012
This archive was generated by hypermail 2.1.8 : Wed Jul 18 2012 - 07:31:51 PDT