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