---------------------------------------------------------------- -- Chapter 4 Composite Data Types and Operations ---------------------------------------------------------------- ---------------------------------------------------------------- -- 4.1 Arrays ---------------------------------------------------------------- -- Page 96 type word is array (0 to 31) of bit; type word is array (31 downto 0) of bit; type controller_state is (initial, idle, active, error); type state_counts is array (idle to error) of natural; type state_counts is array (controller_state range idle to error) 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; -- Page 97 coeff(0) := 0.0; counters(active) := counters(active) + 1; data_register := buffer_register; -- Example 4.1, Page 97 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 for index in coeff_ram_address loop coeff(index) := 0.0; end loop; loop wait on rd, wr, addr, d_in; if rd then d_out <= coeff(addr); end if; if wr then coeff(addr) := d_in; end if; end loop; end process memory; end architecture abstract; ---------------------------------------------------------------- -- 4.1.1 Multidimensional Arrays ---------------------------------------------------------------- -- Page 98 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; transition_table(5, 'd'); -- Example 4.2, Page 98 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; -- Example 4.2, Page 99 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; ---------------------------------------------------------------- -- 4.1.2 Array Aggregates ---------------------------------------------------------------- -- Page 99 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); type coeff_array is array (coeff_ram_address) of real; -- Page 100 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); variable coeff : coeff_array := (0 | 2 => 1.6, 1 => 2.3, others => 0.0); variable coeff : coeff_array := (1.6, 2.3, 2 => 1.6, others => 0.0); -- illegal -- Example 4.3, Page 100 modem_controller : process is 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; begin ... for index in 1 to 20 loop current_state := next_state( current_state, command(index) ); case current_state is ... end case; end loop; ... end process modem_controller; -- Page 102 type byte is array (7 downto 0) of bit; variable d_reg : byte; variable a, b : bit; d_reg := (a, "1001", b, "00"); d_reg := (7 => a, 6 downto 3 => "1001", 2 => b, 1 downto 0 => "00"); ( z_flag, n_flag, v_flag, c_flag ) <= flag_reg; -- Page 103 signal status_reg : bit_vector(7 downto 0); signal int_priority, cpu_priority : bit_vector(2 downto 0); signal int_enable, cpu_mode : bit; (2 downto 0 => int_priority, 6 downto 4 => cpu_priority, 3 => int_enable, 7 => cpu_mode) <= status_reg; ---------------------------------------------------------------- -- 4.1.3 Array Attributes ---------------------------------------------------------------- -- Page 104 type A is array (1 to 4, 31 downto 0) of boolean; assert A'left(1) = 1; assert A'low(1) = 1; assert A'right(2) = 0 ; assert A'high(2) = 31; assert A'length(1) = 4; assert A'length(2) = 32; assert A'ascending(1) = true; assert A'ascending(2) = false; assert A'low = 1; assert A'length = 4; count := 0; for index in free_map'range loop if free_map(index) then count := count + 1; end if; end loop; ---------------------------------------------------------------- -- 4.2 Unconstrained Array Types ---------------------------------------------------------------- -- Page 105 type sample is array (natural range <>) of integer; variable short_sample_buf : sample(0 to 63); subtype long_sample is sample(0 to 255); variable new_sample_buf, old_sample_buf : long_sample; -- Page 106 constant lookup_table : sample := ( 1 => 23, 3 => -16, 2 => 100, 4 => 11); constant beep_sample : sample := ( 127, 63, 0, -63, -127, -63, 0, 63 ); ---------------------------------------------------------------- -- 4.2.1 Predefined Array Types ---------------------------------------------------------------- ---------------------------------------------------------------- -- Strings ---------------------------------------------------------------- -- Page 106 type string is array (positive range <>) of character; constant LCD_display_len : positive := 20; subtype LCD_display_string is string(1 to LCD_display_len); variable LCD_display : LCD_display_string := (others => ' '); ---------------------------------------------------------------- -- Boolean Vectors, Integer Vectors, Real Vectors, and Time Vectors ---------------------------------------------------------------- -- Page 107 type boolean_vector is array (natural range <>) of boolean; type integer_vector is array (natural range <>) of integer; type real_vector is array (natural range <>) of real; type time_vector is array (natural range <>) of time; subtype thresholds is integer_vector(15 downto 0); variable max_temperatures : real_vector(1 to 10); constant Tpd_result : time_vector := (0 to 3 => 100 ps, 4 to 7 => 150 ps); ---------------------------------------------------------------- -- Bit Vectors ---------------------------------------------------------------- -- Page 107 type bit_vector is array (natural range <>) of bit; subtype byte is bit_vector(7 downto 0); variable channel_busy_register : bit_vector(1 to 4); ---------------------------------------------------------------- -- Standard-Logic Arrays ---------------------------------------------------------------- -- Page 108 type std_ulogic_vector is array ( natural range <> ) of std_ulogic; 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 ---------------------------------------------------------------- -- Page 108 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"; ---------------------------------------------------------------- -- 4.2.2 Unconstrained Array Element Types ---------------------------------------------------------------- -- Page 109 type sample is array (natural range <>) of integer; type sample_set is array (positive range <>) of sample; type point is array (1 to 3) of real; type line_segment is array (1 to 2) of point; type dozen_samples is array (1 to 12) of sample; -- Page 110 type path is array (positive range <>) of point; variable main_sample_set : sample_set(1 to 100)(1 to 20); variable alt_sample_set : sample_set(1 to 50)(1 to 10); variable short_path : path(5 downto 1); variable bakers_samples : dozen_samples(open)(0 to 9); subtype dozen_short_samples is dozen_samples(open)(0 to 9); -- Page 111 subtype short_sample_set is sample_set(open)(0 to 9); variable unprocessed_samples : short_sample_set(1 to 20); constant default_sample_pair : sample_set := ( 1 => (39, 25, 6, -4, 5), 2 => (9, 52, 100, 0, -1), 3 => (0, 0, 0, 0, 0) ); constant default_samples : short_sample_set := ( 1 to 20 => (0, 0, 0, 0, 0, 0, 0, 0, 0, 0) ); ---------------------------------------------------------------- -- 4.2.3 Unconstrained Array Ports ---------------------------------------------------------------- -- Example 4.4, Page 112 entity and_multiple is 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; 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_count); -- Example 4.5, Page 112 type bv_array is array (natural range <>) of bit_vector; -- Example 4.5, Page 113 entity and_or_invert is port ( a : in bv_array; z : out bit ); end entity and_or_invert; architecture behavioral of and_or_invert is begin reducer : process ( a ) is variable and_result, result : bit; begin result := '0'; for i in a'range loop and_result := '1'; for j in a'element'range loop and_result := and_result and a(i)(j); end loop; result := result or and_result; end loop; z <= not result; end process reducer; end architecture behavioral; and_result := and a(i); -- Page 113 entity sample_processor is port ( samples : in short_sample_set; ... ); end entity sample_processor; signal sensor_samples : short_sample_set(1 to 3); ... -- Page 114 preprocessor : entity work.sample_processor port map ( samples => sensor_samples, ... ); ---------------------------------------------------------------- -- 4.3 Array Operations and Referencing ---------------------------------------------------------------- ---------------------------------------------------------------- -- 4.3.1 Logical Operators ---------------------------------------------------------------- -- Page 114 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"; assert (B"0011" and '1') = B"0011"; assert (B"0011" and '0') = B"0000"; assert (B"0011" xor '1') = B"1100"; assert (B"0011" xor '0') = B"0011"; -- Example 4.6, Page 115 signal a, b, c, data_bus : std_ulogic_vector(31 downto 0); signal a_sel, b_sel, c_sel : std_ulogic; ... data_bus <= (a and a_sel) or (b and b_sel) or (c and c_sel); -- Page 115 assert (and "0110") = ('0' and '1' and '1' and '0'); assert ( or "0110") = ('0' or '1' or '1' or '0'); assert (xor "0110") = ('0' xor '1' xor '1' xor '0'); assert ('0' and '1' and '1' and '0') = '0'; assert ('0' or '1' or '1' or '0') = '1'; assert ('0' xor '1' xor '1' xor '0') = '0'; assert (nand "0110") = not ('0' and '1' and '1' and '0'); assert ( nor "0110") = not ('0' or '1' or '1' or '0'); assert (xnor "0110") = not ('0' xor '1' xor '1' xor '0'); assert not ('0' and '1' and '1' and '0') = not '0'; assert not ('0' or '1' or '1' or '0') = not '1'; assert not ('0' xor '1' xor '1' xor '0') = not '0'; -- Example 4.7, Page 116 parity <= xor data; parity_error1 <= (xor data) and received_parity; parity_error2 <= xor data and received_parity; ---------------------------------------------------------------- -- 4.3.2 Shift Operators ---------------------------------------------------------------- -- Page 116 assert B"10001010" sll 3 = B"01010000"; assert B"10001010" sll -2 = B"00100010"; assert B"10010111" srl 2 = B"00100101"; assert B"10010111" srl -6 = B"11000000"; assert B"01001011" sra 3 = B"00001001"; assert B"10010111" sra 3 = B"11110010"; assert B"00001100" sla 2 = B"00110000"; assert B"00010001" sla 2 = B"01000111"; -- Page 117 assert B"00010001" sra -2 = B"01000111"; assert B"00110000" sla -2 = B"00001100"; assert B"10010011" rol 1 = B"00100111"; assert B"10010011" ror 1 = B"11001001"; ---------------------------------------------------------------- -- 4.3.3 Relational Operators ---------------------------------------------------------------- -- Example 4.8, Page 118 dev_sel1 <= cs1 and not ncs2 and addr ?= X"A5"; if cs1 and not ncs2 and addr ?= X"A5" then ... if cs1 and ncs2 ?= '0' and addr ?= X"A5" then ... -- Page 118 dev_sel1 <= '1' when cs1 = '1' and ncs2 = '0' and addr = X"A5" else '0'; if cs1 = '1' and ncs2 = '0' and addr = X"A5" then ... if (cs1 and not ncs2) = '1' and addr = X"A5" then ... ---------------------------------------------------------------- -- Maximum and Minimum Operations ---------------------------------------------------------------- -- Page 119 assert minimum(string'(B"0001"), string'(B"0110")) = B"0001"; assert maximum(string'(B"001000"), string'(B"10")) = B"10"; assert maximum(string'("WXYZ")) = 'Z'; assert minimum(string'("WXYZ")) = 'W'; assert maximum(time_vector'(10 ns, 50 ns, 20 ns)) = 50 ns; assert minimum(time_vector'(10 ns, 50 ns, 20 ns)) = 10 ns; ---------------------------------------------------------------- -- 4.3.4 The Concatenation Operator ---------------------------------------------------------------- -- Page 119 assert "abc" & 'd' = "abcd"; assert 'w' & "xyz" = "wxyz"; assert 'a' & 'b' = "ab"; ---------------------------------------------------------------- -- 4.3.5 To_String Operations ---------------------------------------------------------------- -- Page 120 signal x : bit_vector(7 downto 0); ... report "Trace: x = " & to_string(x); assert to_ostring(B"101_011_000") = "530"; assert to_ostring( B"11_000_111") = "307"; assert to_hstring(B"0110_1100") = "6C"; assert to_hstring( B"11_0101") = "35"; ---------------------------------------------------------------- -- 4.3.6 Array Slices ---------------------------------------------------------------- -- Page 121 type array1 is array (1 to 100) of integer; type array2 is array (100 downto 1) of integer; variable a1 : array1; variable a2 : array2; -- Example 4.9, Page 121 subtype halfword is bit_vector(0 to 15); 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; ---------------------------------------------------------------- -- 4.3.7 Array Type Conversions ---------------------------------------------------------------- -- Page 122 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 := display_string(item_name); subtype integer_vector_10 is integer_vector(1 to 10); subtype real_vector_10 is real_vector(1 to 10); variable i_vec : integer_vector_10; variable r_vec : real_vector_10; ... i_vec := integer_vector_10(r_vec); r_vec := real_vector_10(i_vec); type exception_type is (int, ovf, div0, undef, trap); type exception_vector is array (exception_type) of bit; signal d_in, d_out: bit_vector(31 downto 0); signal exception_reg : exception_vector; -- Page 123 exception_vector( d_in(4 downto 0) ) integer_vector(r_vec) bit_vector( exception_reg ) 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; ---------------------------------------------------------------- -- 4.3.8 Arrays in Case Statements ---------------------------------------------------------------- -- Page 124 variable s : bit_vector(3 downto 0); variable c : bit; ... case c & s is when "00000" => ... when "10000" => ... when others => ... end case; -- Page 125 variable s : bit_vector(3 downto 0); ... case s is when ('0', others => '1') => ... when ('1', others => '0') => ... ... end case; variable s : bit_vector(3 downto 0); variable c : bit; subtype bv5 is bit_vector(0 to 4); ... case bv5'(c & s) is ... end case; ---------------------------------------------------------------- -- 4.3.9 Matching Case Statements ---------------------------------------------------------------- -- Example 4.10, Page 126 variable request, grant : std_ulogic_vector(0 to 3); case? request is when "1---" => grant := "1000"; when "01--" => grant := "0100"; when "001-" => grant := "0010"; when "0001" => grant := "0001"; when others => grant := "0000"; end case?; ---------------------------------------------------------------- -- Matching Selected Variable Assignments ---------------------------------------------------------------- -- Example 4.11, Page 127 with request select? grant := "1000" when "1---", "0100" when "01--", "0010" when "001-", "0001" when "0001", "0000" when others; ---------------------------------------------------------------- -- 4.4 Records ---------------------------------------------------------------- -- Page 128 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 time_stamp; variable sample_time, current_time : time_stamp; sample_time := current_time; -- Page 129 sample_hour := sample_time.hours; current_time.seconds := clock mod 60; -- Example 4.12, Page 129 architecture system_level of computer is 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; mem_read <= '1'; wait until mem_ready; instr_reg := read_word.instr; mem_read <= '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; ---------------------------------------------------------------- -- 4.4.1 Record Aggregates ---------------------------------------------------------------- -- Page 131 constant midday : time_stamp := (0, 0, 12); constant midday : time_stamp := (hours => 12, minutes => 0, seconds => 0); constant nop_instr : instruction := ( opcode => addu, source_reg1 | source_reg2 | dest_reg => 0, displacement => 0 ); variable latest_event : time_stamp := (others => 0); -- initially midnight ---------------------------------------------------------------- -- 4.4.2 Unconstrained Record Element Types ---------------------------------------------------------------- -- Page 131 type test_vector is record id : natural; stimulus : bit_vector; response : bit_vector; end record test_vector; -- Page 132 type test_times is record stimulus_time : time; response_delay : delay_length; end record test_times; type test_application is record test_to_apply : test_vector; application_times : test_times; end record; type sample is array (natural range <>) of integer; type dozen_samples is array (1 to 12) of sample; type analyzed_samples is record samples : dozen_samples; result : real; end record analyzed_samples; -- Page 133 variable next_test_vector : test_vector(stimulus(0 to 7), response(0 to 9)); variable scheduled_test : test_application(test_to_apply(stimulus(0 to 7), response(0 to 9))); variable analysis : analyzed_samples(samples(open)(1 to 100)); subtype byte_test_vector is test_vector(stimulus(7 downto 0), response(7 downto 0)); subtype analyzed_short_samples is analyzed_samples(samples(open)(1 to 100)); subtype test_application_word is test_application(test_to_apply(stimulus(0 to 31))); subtype test_application_word is test_application(test_to_apply(stimulus(0 to 31), response(open))); -- Page 134 subtype test_application_word_byte is test_application_word(test_to_apply(response(0 to 7))); subtype test_application_word_byte is test_application_word(test_to_apply(stimulus(open), response(0 to 7))); constant first_test_vector : test_vector := (id => 0, stimulus => B"100010", response => B"00000001"); ---------------------------------------------------------------- -- Exercises ----------------------------------------------------------------