390 likes | 529 Views
Composite Data Types and Operations. Instructors: Fu-Chiung Cheng ( 鄭福炯 ) Associate Professor Computer Science & Engineering Tatung University. Array. EBNF: array_type <= array ( discrete_range { , … } ) of element_subtype_indication ;
E N D
Composite Data Types and Operations Instructors: Fu-Chiung Cheng (鄭福炯) Associate Professor Computer Science & Engineering Tatung 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 is begin 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_value);
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 slices entity byte_swap is 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 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);