Re: [vhdl-200x] VHDL-2008: Records and aggregates

From: David Koontz <diogratia@gmail.com>
Date: Thu Apr 16 2015 - 19:45:54 PDT
On 15/04/2015, at 9:57 pm, Lehmann, Patrick <patrick.lehmann@tu-dresden.de> wrote:

> Hello,
> 
> Sorry I was not aware of that it's possible to use range
>> type myRange is RANGE 7 downto 0;
> without any integer type/subtype or similar.
> 
> Any other suggestions to declare a pure range? Or alternatively, any 
> suggestions to
> use integer type/subtype definitions as a range in slices and aggregates?
> 

library ieee;
use ieee.std_logic_1164.all;

package index is
    subtype myRange is natural range 7 downto 0;
    constant my_range: std_logic_vector (myRange) := (others => '0');
    function "+" (l: std_logic_vector; stride: natural) return std_logic_vector; 
end package;

package body index is
    
    function "+" (l: std_logic_vector;
                  stride: natural) return std_logic_vector is
        variable retval: std_logic_vector( 
                        l'LEFT  + l'LENGTH * stride 
                        downto 
                        l'RIGHT + l'LENGTH * stride );
    begin
        -- report "stride = " & INTEGER'IMAGE(stride);
        -- report "retval'LEFT  = " & INTEGER'IMAGE(retval'LEFT);
        -- report "retval'RIGHT = " & INTEGER'IMAGE(retval'RIGHT);
        return retval;
    end function;
    
end package body;

library ieee;
use ieee.std_logic_1164.all;
use work.index.all;

entity indx is
end entity;

architecture foo of indx is 
    signal big_range: std_logic_vector (63 downto 0) := x"feedfacedeadbeef";
    signal little_range: std_logic_vector (myRange);
    
    function to_string(inp: std_logic_vector) return string is
        variable image_str: string (1 to inp'length);
        alias input_str:  std_logic_vector (1 to inp'length) is inp;
    begin
        for i in input_str'range loop
            image_str(i) := character'VALUE(std_ulogic'IMAGE(input_str(i)));
        end loop;
        -- report "image_str = " & image_str;
        return image_str;
    end;
    
begin
STIMULUS:  
    process 
    begin
        wait for 1 ns;
        for stride in myRange loop
            report "stride = " & INTEGER'IMAGE(stride);
            little_range <= big_range( "+"(my_range, stride)'RANGE );
            wait for 1 ns;
        end loop;
        wait;
    end process;
MONITOR:
    process (little_range)
    begin
        report "little_range = " & to_string (little_range);
    end process;
end architecture;


david_koontz@Macbook: ghdl -a index.vhdl
david_koontz@Macbook: ghdl -e indx
david_koontz@Macbook: ghdl -r indx
index.vhdl:64:9:@0ms:(report note): little_range = uuuuuuuu
index.vhdl:55:13:@1ns:(report note): stride = 7
index.vhdl:64:9:@1ns:(report note): little_range = 11111110  -- x"FE"
index.vhdl:55:13:@2ns:(report note): stride = 6
index.vhdl:64:9:@2ns:(report note): little_range = 11101101  -- x"ED"
index.vhdl:55:13:@3ns:(report note): stride = 5
index.vhdl:64:9:@3ns:(report note): little_range = 11111010  -- x"FA"
index.vhdl:55:13:@4ns:(report note): stride = 4
index.vhdl:64:9:@4ns:(report note): little_range = 11001110  -- x"CE"
index.vhdl:55:13:@5ns:(report note): stride = 3
index.vhdl:64:9:@5ns:(report note): little_range = 11011110  -- x"DE"
index.vhdl:55:13:@6ns:(report note): stride = 2
index.vhdl:64:9:@6ns:(report note): little_range = 10101101  -- x"AD"
index.vhdl:55:13:@7ns:(report note): stride = 1
index.vhdl:64:9:@7ns:(report note): little_range = 10111110  -- x"BE"
index.vhdl:55:13:@8ns:(report note): stride = 0
index.vhdl:64:9:@8ns:(report note): little_range = 11101111  -- x"EF"


You might note the use of a function_call form instead of the infix operator form of "+", this allows the use of the return value as a prefix for the range attribute name.

Range is a constraint. There are a couple of issues with promoting range to type. Anything that uses a range is a basic operation, which hides all that complexity today while maintaining eligibility as formal notation for formal proofs.  

Uncovering range as a type would require redoing everything that depends on range and isn't necessary unless you allow write access to the range record (and you shouldn't).

I think exposing range as a type while possible would be more trouble than it's worth.  

This:

    big_range( "+"(my_range, stride)'RANGE )

could become this:

    big_range(my_range + stride)

The simpler form is simply dangerous for the uninformed, and you could while away an afternoon pursuing the reasoning and citations for why the above example is 'legal' VHDL.

It also isn't particularly clear what benefit there is to using either form, other than the fact it made a compact M:N multiplexer that's likely not supported for synthesis. 

And we can already do that by defining a composite and index ranges without any risk of providing out of bounds ranges, all while maintaining synthesis eligibility.

library ieee;
use ieee.std_logic_1164.all;

entity union is
end entity;

architecture fum of union is
    type union32 is array (integer range 1 to 4) of std_logic_vector(7 downto 0);
    signal UartData:    std_logic_vector(7 downto 0);
    subtype BYTE1 is natural range 31 downto 24;
    subtype BYTE2 is natural range 23 downto 16;
    subtype BYTE3 is natural range 15 downto 8;
    subtype BYTE4 is natural range 7 downto 0;
begin

TEST:
    process 
    variable quad:    union32;
    constant fourbytes:    std_logic_vector(31 downto 0) := X"deadbeef";
    begin
        -- and all this allows endianness changes
        quad := union32'(fourbytes(BYTE1), fourbytes(BYTE2),
                         fourbytes(BYTE3), fourbytes(BYTE4));

        for i in union32'RANGE loop
            wait for 9.6 us;
            UartData <= quad(i);
        end loop; 
        
        wait for 9.6 us;  -- to display the last byte
        wait; 
    end process;
end architecture;

This is an involution of the idea, organize the big data instead of the extracted data. 

For those of us with too short attention spans there are editors you can write snippet code generators for to take some of the burden away from actually authoring the code.

You could imagine keeping a package handy with common slice subtypes and array types (e.g. BYTE1 etc.), or separate packages for different organizations. 

You'd almost get the idea someone was struggling hard to describe hardware in software terms.

 --

Harry Harrison 'Make Room! Make Room!' - "Soylent Green is People!"

only in this case it's "VHDL is hardware!"





-- 
This message has been scanned for viruses and
dangerous content by MailScanner, and is
believed to be clean.
Received on Thu Apr 16 19:46:06 2015

This archive was generated by hypermail 2.1.8 : Thu Apr 16 2015 - 19:46:10 PDT