composite data types and operations
DESCRIPTION
Composite Data Types and Operations. Instructors: Fu-Chiung Cheng ( 鄭福炯 ) Associate Professor Computer Science & Engineering Tatung University. Array. EBNF: array_typeTRANSCRIPT
Composite Data Types and Operations
Instructors: Fu-Chiung Cheng
(鄭福炯 )Associate Professor
Computer Science & EngineeringTatung University
Array
• EBNF: array_type <= array ( discrete_range { , … } ) of element_subtype_indication ;
discrete_range<= discrete_subtype_indication | expr (to |downto ) expr discrete_subtype_indication <=
type_mark [ range expr (to |downto ) expr ]• Example:
• type word1 is array (0 to 31) of bit;• type word2 is array (31 downto 0) of bit;
Array
• Examples:• type state is (initial, idle, active, error);• type state_counts1 is array (state) of natural;• type state_counts2 is array (state range initial
to active) of natural;• subtype coeff_ram_address is integer range 0 to 63;• type coeff_array is array (coeff_ram_address) of real;------------------------------------------------------------• variable buffer_register, data_register : word;• variable counters : state_counts;• variable coeff : coeff_array;
entity coeff_ram is port ( rd, wr : in bit; addr : in coeff_ram_address; d_in : in real; d_out : out real );end entity coeff_ram;--------------------------------------------------architecture abstract of coeff_ram isbegin
memory : process is type coeff_array is array (coeff_ram_address) of real; variable coeff : coeff_array; begin -- see next page end process memory;
end architecture abstract;
memory : process is type coeff_array is array (coeff_ram_address) of real; variable coeff : coeff_array; begin for index in coeff_ram_address loop coeff(index) := 0.0; end loop; loop wait on rd, wr, addr, d_in; if rd = '1' then d_out <= coeff(addr); end if; if wr = '1' then coeff(addr) := d_in; end if; end loop; end process memory;
Multi-Dimensional Arrays
• Example:
type symbol is ('a', 't', 'd', 'h', digit, cr, error); type state is range 0 to 6; type transition_matrix is array (state, symbol) of state;
variable transition_table : transition_matrix; variable next_state : state;
transition_table(5, 'd') =2; next_state := transition_table(5, 'd');
Multi-Dimensional Arrays
type point is array (1 to 3) of real; type matrix is array (1 to 3, 1 to 3) of real;
variable p, q : point; variable transform : matrix;
for i in 1 to 3 loop q(i) := 0.0; for j in 1 to 3 loop q(i) := q(i) + transform(i, j) * p(j); end loop; end loop;
Array Aggregates
• Examples: type point is array (1 to 3) of real;
constant origin : point := (0.0, 0.0, 0.0); variable view_point : point := (10.0, 20.0, 0.0);------------------------------------------- variable view_point : point := (1=>10.0, 2=>20.0, 3=>0.0); variable coeff : coeff_array := (0=>1.6, 1=>2.3, 2=>1.6,
3 to 63 => 0.0); variable coeff : coeff_array := (0=>1.6,1=>2.3, 2=>1.6,
others => 0.0);
Array Aggregates
• Examples: variable coeff : coeff_array := (0 | 2 => 1.6, 1 => 2.3, others => 0.0);
• Associations in array aggregate must be all named or all positional -- variable coeff : coeff_array := (1.6, 2.3, 2 => 1.6, others => 0.0); -- illegal
modem_controller : process is -- Fig 4-3 on page 91
type symbol is ('a', 't', 'd', 'h', digit, cr, other);
type symbol_string is array (1 to 20) of symbol;
type state is range 0 to 6;
type transition_matrix is array (state, symbol) of state;
constant next_state : transition_matrix :=
( 0 => ('a' => 1, others => 6),
1 => ('t' => 2, others => 6),
2 => ('d' => 3, 'h' => 5, others => 6),
3 => (digit => 4, others => 6),
4 => (digit => 4, cr => 0, others => 6),
5 => (cr => 0, others => 6),
6 => (cr => 0, others => 6) );
variable command : symbol_string;
variable current_state : state := 0;
modem_controller : process is
-- previous page
begin
-- . . .
for index in 1 to 20 loop
current_state := next_state( current_state, command(index) );
case current_state is
-- . . .
end case;
end process modem_controller;
entity and_multiple is -- useful example 1
port ( i : in bit_vector; y : out bit );
end entity and_multiple;
architecture behavioral of and_multiple is
begin
and_reducer : process ( i ) is variable result : bit;
begin
result := '1';
for index in i'range loop
result := result and i(index);
end loop;
y <= result;
end process and_reducer;
end architecture behavioral;
entity byte_swap is -- useful example 2
port (input : in halfword; output : out halfword);
end entity byte_swap;
--------------------------------------------------
architecture behavior of byte_swap is
begin
swap : process (input)
begin
output(8 to 15) <= input(0 to 7);
output(0 to 7) <= input(8 to 15);
end process swap;
end architecture behavior;
Array Attributes
A’left(n) the left bound of nth dimension of A A’right(n) the right bound of nth dimension of A A’low(n) the lower bound of nth dimension of A A’high(n) the upper bound of nth dimension of A A’range(n) the range of nth dimension of A A’reverse_range(n) the reverse range of nth dimension
of A A’length(n) the length of nth dimension of A A’ascending(n) true if index range of nth dimension of A
is ascending range, false otherwise
Array Attributes
Example:type A is array (1 to 4, 31 downto 0) of boolean;
A’left(1) = ?;A’right(2)=?;A’low(1) = ?A’high(2)=?A’range(1)=? A’reverse_range(2)=?A’length(1)=? A’length(2)=?A’ascending(1)=? A’ascending(2)=?
Example
Counting the number of ‘1’ without knowing the actual size
-- free_map is an array of bits count := 0; for index in free_map'range loop if free_map(index) = '1' then count := count + 1; end if; end loop;
Unconstrained array types
EBNF: array_type <= array ( type_mark range <> ) { , … }) of element_subtype_indication;
Example:type sample is array (natural range <>) of integer;
variable short_sample_buf: sample (0 to 63);
Unconstrained array types
Example:subtype long_sample is sample(0 to 255); variable new_sample_buf: long_sample;
Example:constant lookup_table: sample :=(1=>23, 3=>-16, 2=>100, 4=> 11);
Strings
“string” are pre-defined unconstrained arrays of type character.type string is array (positive range<>) of character;
Examples:constant LCD_DISPLAY_LEN: positive :=20;subtype LCD_display_string is string(1 to LCD_DISPLAY_LEN);variable LCD_display: LCD_display_string := (others => ‘ ‘);constant ready_message : string := "Ready ";
Bit Vectors
“bit_vector” are pre-defined unconstrained arrays of type bit.
type bit_vector is array (natural range <>) of bit;
Examples:subtype byte is bit_vector(7 downto 0);
variable channel_busy_register : bit_vector(1 to 4);
Standard-Logic Arrays
The standard-logic package std_logic_1164 provides an unconstrained array type for vectors of standard logic values.
type std_ulogic_vector is array (natural range <>) of std_ulogic;
Examples:subtype std_ulogic_word is std_ulogic_vector(0 to 31);signal csr_offset : std_ulogic_vector(2 downto 1);
String and Bit-String Literals
Examples:constant ready_message : string := "Ready ";variable current_test : std_ulogic_vector(0 to 13) := "ZZZZZZZZZZ----";channel_busy_register := b"0000";constant all_ones : std_ulogic_vector(15 downto 0) := X"FFFF";
Unconstrained array ports
entity and_multiple is
port ( i : in bit_vector; y : out bit );
end entity and_multiple;
architecture behavioral of and_multiple is
begin
-- next page
end architecture behavioral;
Unconstrained array ports
and_reducer : process ( i ) is variable result : bit; begin result := '1'; for index in i'range loop result := result and i(index); end loop; y <= result; end process and_reducer;
Unconstrained array ports
signal count_value : bit_vector (7 downto 0);signal terminal_count : bit;
tc_gate : entity work.and_multiple(behavioral)port map(i => count_value, y => terminal_valu
e);
Array operations
Logical operators (and, or, nand, nor, xor and xnor) can be applied to two one-dimensional equal sized and same type bit or boolean arrays.
Example:subtype pixel_row is bit_vector (0 to 15); variable current_row, mask : pixel_row; current_row := current_row and not mask; current_row := current_row xor X"FFFF";
Array operations
sll, slr, sal, sar, rol and ror can be used with one-dimensional bit or boolean arrays.
sll or slr fill with zero sla or sra fill with copies of element rol and ror rotate Examples:
B"10001010" sll 3 = B"01010000";B"10001010" sll -2 = B"00100010";B"10010111" srl 2 = B"00100101";B"10010111" srl -6 = B"11000000";
Array operations
Examples: B"01001011" sra 3 = B"00001001";
B"10010111" sra 3 = B"11110010"; B"00001100" sla 2 = B"00110000"; B"00010001" sla 2 = B"01000111";
B"00010001" sra -2 = B"01000111"; B"00110000" sla -2 = B"00001100";
B"10010011" rol 1 = B"00100111"; B"10010011" ror 1 = B"11001001";
Array operations
Relational operators: <, >, <=, >=, =, /=a < b, a(1) < b(1)
Concatenation: &b”0000” & b”1111”=b”0000_1111”;"abc" & 'd' = "abcd";'w' & "xyz" = "wxyz";'a' & 'b' = "ab";
Array slices
Array slices = subset of element of an array Examples:
type array1 is array (1 to 100) of integer;type array2 is array (100 downto 1) of integer;variable a1 : array1;variable a2 : array2; -- OK: a1(11 to 20) , a2(50 downto 41)-- null slices: a1(10 to 1), a2(1 downto 10) -- illegal: a1(10 downto 1) a2(1 to 10)
Array slicesentity byte_swap is port (input : in halfword; output : out halfword);end entity byte_swap;--------------------------------------------------architecture behavior of byte_swap isbegin
swap : process (input) begin output(8 to 15) <= input(0 to 7); output(0 to 7) <= input(8 to 15); end process swap;
end architecture behavior;
Array Type Conversions
Array conversion example:subtype name is string(1 to 20);type display_string is array (integer range 0 to 19) of character;variable item_name : name;variable display : display_string;
-- display := item_name; -- illegal display := display_string(item_name);
Array Type Conversions
Array conversion example: subtype big_endian_upper_halfword is bit_vector(0 to 15);subtype little_endian_upper_halfword is bit_vector(31 downto 16);variable big : big_endian_upper_halfword; variable little : little_endian_upper_halfword; big := little;little := big;
Records
EBNF:record_type <= record
( identifier { , … } : subtype_indication ;){ … }
end record [ identifier ]; Examples:
type time_stamp is record seconds: integer range 0 to 59;minutes : integer range 0 to 59;hours : integer range 0 to 23;
end record;
Records
variable sample_time, current_time : time_stamp;constant midday : time_stamp := (0, 0, 12);constant clock : integer := 79;variable sample_hour : integer;
current_time := (30, 15, 2);sample_time := current_time;sample_hour := sample_time.hours;current_time.seconds := clock mod 60;
architecture system_level of computer is – Fig 4-6 type opcodes is (add, sub, addu, subu, jmp, breq, brne, ld, st, . . .);
type reg_number is range 0 to 31; constant r0 : reg_number := 0;
constant r1 : reg_number := 1; -- . . .
type instruction is record opcode : opcodes; source_reg1, source_reg2, dest_reg : reg_number; displacement : integer; end record instruction;
type word is record instr : instruction; data : bit_vector(31 downto 0); end record word;
signal address : natural; signal read_word, write_word : word; signal mem_read, mem_write : bit := '0'; signal mem_ready : bit := '0';begin cpu : process is variable instr_reg : instruction; variable PC : natural; -- . . . -- other declarations for register file, etc. begin address <= PC; -- fetch instructions mem_read <= '1'; wait until mem_ready = '1'; instr_reg := read_word.instr; mem_read <= '0'; wait until mem_ready = '0'; PC := PC + 4;
case instr_reg.opcode is -- execute the instruction -- . . .
end case; end process cpu;
memory : process is subtype address_range is natural range 0 to 2**14 - 1; type memory_array is array (address_range) of word; variable store : memory_array := ( 0 => ( ( ld, r0, r0, r2, 40 ), X"00000000" ), 1 => ( ( breq, r2, r0, r0, 5 ), X"00000000" ), -- . . . 40 => ( ( nop, r0, r0, r0, 0 ), X"FFFFFFFE"), others => ( ( nop, r0, r0, r0, 0 ), X"00000000") ); begin -- . . .
end process memory;end architecture system_level;
Record Aggregates
Examples:constant midday: time_stamp := (0,0,12);constant midday: time_stamp := (hours=>12, seconds=>0,minutes=>0);constant nop_instr: instruction :=
(opcode => addu, source_reg1|source_reg2|dest_reg =>0, displacement => 0);
variable latest_event:time_stamp := (others => 0);