In this appendix, we provide sample answers to the quiz-style exercises marked with the symbol “”. Readers are encouraged to test their answers to the other, more involved, exercises by running the models on a VHDL simulator.
alias received_source is received_packet.source; alias received_dest is received_packet.dest; alias received_flags is received_packet.flags; alias received_payload is received_packet.payload; alias received_checksum is received_packet.checksum; | |
alias received_AK is received_packet.flags(0); alias received_ACKNO : bit_vector(2 downto 0) is received_packet.flags(1 to 3); alias received_SEQNO : bit_vector(2 downto 0) is received_packet.flags(4 to 6); alias received_UD is received_packet.flags(7); | |
alias cons is "&" [ character, string return string ]; report cons ( grade_char, "-grade" ); | |
entity flipflop is generic ( Tpw_clk_h, T_pw_clk_l : delay_length := 3 ns ); port ( clk, d : in bit; q, q_n : out bit ); end entity flipflop; | |
clk_gen : entity work.clock_generator generic map ( period => 10 ns ) port map ( clk => master_clk ); | |
entity adder is generic ( data_length : positive ); port ( a, b : in std_ulogic_vector(data_length - 1 downto 0); sum : out std_ulogic_vector(data_length - 1 downto 0) ); end entity adder; | |
io_control_reg : entity work.reg generic map ( width => 4 ) port map ( d => data_out(3 downto 0), q(0) => io_en, q(1) => io_int_en, q(2) => io_dir, q(3) => io_mode, clk => io_write, reset => io_reset ); | |
bv_mux : entity work.generic_mux2(rtl) generic map ( data_type => bit_vector(7 downto 0) ) port map ( sel => sel, a => d_in1, b => d_in2, z => d_out ); | |
The formal generic type is used as the type of the variable | |
package int_stacks is new work.generic_stacks generic map ( size => 100, element_type => integer ); use int_stacks.all; variable int_stack : stack_type; ... push(int_stack, -1); | |
The call with the actual parameter 1 is unambiguous, and calls the first overloaded version (with formal parameter of type | |
while not is_full(test_buffer) loop write(test_buffer, "00000000"); end loop; | |
procedure check_bv_setup is new check_setup generic map ( signal_type => bit_vector, clk_type => bit, clk_active_value => '0', T_su => 100ps ); ... check_bv_setup(s, clk); | |
function bv_increment(bv : bit_vector) return bit_vector is use ieee.numeric_bit_unsigned.all; begin return bv + 1; end function bv_increment; ... val_counter : work.generic_counter(rtl) generic map ( count_type => bit_vector(9 downto 0), reset_value => (others => '0'), increment => bv_increment ) port map ( clk => clk, reset => reset, data => val_count ); | |
use ieee.numeric_std.all; package unsigned_dictionaries is new work.dictionaries generic map ( size => 1000, element_type => unsigned(63 downto 0), key_type => string, key_of => to_hstring, "<" => ">" ); | |
package float_generic_math_ops is generic ( package float_pkg_for_math is new ieee.float_generic_pkg generic map (<>) ); use fixed_pkg_for_math.all; function exp ( x : float ) return float; function log ( x : float ) return float; ... end package float_generic_math_ops; package float_math_ops is new float_generic_math_ops generic map ( float_pkg_for_math => ieee.float_pkg ); | |
An entity declaration uses the keyword | |
component magnitude_comparator is generic ( width : positive; Tpd : delay_length ); port ( a, b : in std_ulogic_vector(width - 1 downto 0); a_equals_b, a_less_than_b : out std_ulogic ); end component magnitude_comparator; | |
position_comparator : component magnitude_comparator generic map ( width => current_position'length, Tpd => 12 ns ) port map ( a => current_position, b => upper_limit, a_less_than_b => position_ok, a_equals_b => open ); | |
package small_number_pkg is subtype small_number is natural range 0 to 255; component adder is port ( a, b : in small_number; s : out small_number ); end component adder; end package small_number_pkg; | |
library dsp_lib; configuration digital_filter_rtl of digital_filter is for register_transfer for coeff_1_multiplier : multiplier use entity dsp_lib.fixed_point_mult(algorithmic); end for; end for; end configuration digital_filter_rtl; | |
library dsp_lib; configuration digital_filter_std_cell of digital_filter is for register_transfer for coeff_1_multiplier : multiplier use configuration dsp_lib.fixed_point_mult_std_cell; end for; end for; end configuration digital_filter_std_cell; | |
library dsp_lib; architecture register_transfer of digital_filter is ... begin coeff_1_multiplier : configuration dsp_lib.fixed_point_mult_std_cell port map ( ... ); ... end architecture register_transfer; | |
use entity work.multiplexer generic map ( Tpd => 3.5 ns ); | |
![]() | |
generic map ( Tpd_01 => open, Tpd_10 => open ) port map ( a => a, b => b, c => c, d => open, y => y ) | |
for interface_decoder : decoder_2_to_4 use entity work.decoder_3_to_8(basic) generic map ( Tpd_01 => prop_delay, Tpd_10 => prop_delay ) port map ( s0 => in0, s1 => in1, s2 => '0', enable => '1', y0 => out0, y1 => out1, y2 => out2, y3 => out3, y4 => open, y5 => open, y6 => open, y7 => open ); end for; | |
configuration rebound of computer_system is for structure for interface_decoder : decoder_2_to_4 generic map ( Tpd_01 => 4.3 ns, Tpd_10 => 3.8 ns ); end for; end for; end configuration rebound; | |
![]() | |
inverter_array : for index in data_in'range generate inv : component inverter port map ( i => data_in(index), y_n => data_out_n(index) ); end generate inverter_array; | |
direct_clock : if positive_clock generate internal_clock <= external_clock; else generate clock_inverter : component inverter port map ( i => external_clock, y => internal_clock ); end generate inverting_clock; | |
for synch_delay_line(1) for delay_ff : d_ff use entity parts_lib.d_flipflop(low_input_load); end for; end for; for synch_delay_line(2 to 4) for delay_ff : d_ff use entity parts_lib.d_flipflop(standard_input_load); end for; end for; | |
A block configuration is not required for the alternative that directly connects the signals, since the statement does not include any component instances. In order to write a block configuration for the other alternative, we need to revise the generate statement to include an alternative label: direct_clock : if noninverting : positive_clock generate internal_clock <= external_clock; else inverting : generate clock_inverter : component inverter port map ( i => external_clock, y => internal_clock ); end generate inverting_clock; The required block configuration is: for inverting_clock(inverting) for clock_inverter : inverter use entity parts_lib.inverter; end for; end for; This block configuration is only used if the generic | |
type character_ptr is access character; variable char : character_ptr := new character'(ETX); ... char.all := 'A'; | |
The statement “ | |
![]() | |
| |
type string_ptr is access string; variable str : string_ptr := new string'(" "); ... str(1) := NUL; | |
z.re := x.re * y.re - x.im * y.im; z.im := x.re * y.im + x.im * y.re; | |
type message_cell; type message_ptr is access message_cell; type message_cell is record source, destination : natural; data : bit_vector(0 to 255); next_cell : message_ptr; end record message_cell; variable message_list : message_ptr; ... message_list := new message_cell'( source => 1, destination => 5, data => (others => '0'), next_cell => message_list ); | |
The first statement copies the pointer to the first cell to the access variable | |
type real_file is file of real; file sample_file : real_file open read_mode is "samples.dat"; ... read ( sample_file, x ); | |
type bv_file is file of bit_vector; file trace_file : bv_file open write_mode is "/tmp/trace.tmp"; ... write ( trace_file, addr & d_bus ); | |
file_open ( status => waveform_status, f => waveform_file, external_name => "waveform", open_kind => read_mode); assert waveform_status = open_ok report file_open_status'image(waveform_status) & " occurred opening waveform file" severity error; | |
The first call returns the bit value ‘1’. The second call returns the integer value 23. The third call returns the real value 4.5. The fourth call returns the three-character string “ 67”. | |
use std.textio.all; variable prompt_line, input_line : line; variable number : integer; ... write(prompt_line, string'("Enter a number:"); writeline(output, prompt_line); readline(input, input_line); read(input_line, number); | |
" 3500 ns 00111100 ok " | |
package memories_support_1Kx24 is new work.memories_suppor generic map ( width => 24, depth => 10, fixed_pkg => ieee.fixed_pkg, float_pkg => ieee.float_pkg ); use memories_support_1Kx24.all; package memories_1Kx24 is new work.memories generic map ( width => 24, depth => 10, control_type => bit, address_type => std_ulogic_vector(9 downto 0), data_type => std_ulogic_vector(23 downto 0) ); | |
package memories_support_32x128 is new work.memories_suppor generic map ( width => 128, depth => 5, fixed_pkg => ieee.fixed_pkg, float_pkg => ieee.float_pkg ); use memories_support_32x128.all; package memories_32x128 is new work.memories generic map ( width => 128, depth => 5, control_type => std_ulogic, address_type => unsigned(4 downto 0), data_type => float128 ); | |
<<constant .test_bench.dp.d_width : positive>> <<signal .test_bench.dp.d_bus : std_ulogic_vector(7 downto 0)>> <<signal .test_bench.dp.adder(3).carry : std_ulogic>> | |
alias d_width is <<constant .test_bench.dp.d_width : positive>>; alias d_bus is <<signal .test_bench.dp.d_bus : std_ulogic_vector(7 downto 0)>>; alias carry is <<signal .test_bench.dp.adder(3).carry : std_ulogic>>; | |
<<constant dp.d_width : positive>> <<signal dp.d_bus : std_ulogic_vector(7 downto 0)>> <<signal dp.adder(3).carry : std_ulogic>> | |
reset <= force '1'; wait for 200 ns; reset <= release; | |
alias mem_d is <<signal mem.d : std_logic_vector(7 downto 0)>>; ... mem_d <= force out "ZZZZZZZZ"; mem_d <= force in "ZZZZZZZZ"; ... mem_d <= release out; mem_d <= release in; | |
configuration verifying of bus_interface is use vunit verify_protocol; for behavior end for; end configuration verifying; | |
for ext : ext_interface use entity bus_interface(behavior); use vunit verify_protocol; end for; | |
If the host computer system has multiple processors, | |
type shared_integer is protected procedure set ( i : integer ); impure function get return integer; end protected shared_integer; type shared_integer is protected body variable value : integer; procedure set ( i : integer ) is begin value := i; end procedure set; impure function get return integer is begin return value; end function get; end protected body shared_integer; | |
word'path_name = ":proj_lib:cpu_types:word" mult_unsigned'path_name = ":proj_lib:bit_vector_signed_arithmetic:" & "mult_unsigned[bit_vector, bit_vector return bit_vector]:" bv2'path_name = ":proj_lib:bit_vector_signed_arithmetic:" & "mult_unsigned[bit_vector, bit_vector return bit_vector]:bv2" next_test_case'path_name = ":tes_tbench:stim_gen:next_test_case" next_test_case'instance_name = ":test_bench(test_rtl):stim_gen:next_test_case" get_ID'path_name = ":test_bench:stim_gen:ID_manager:" & "get_ID[return natural:" get_ID'instance_name = ":test_bench(test_rtl):stim_gen:ID_manager:" & "get_ID[return natural]:" | |
val0_reg'path_name = ":test_bench:dut:val0_reg:" val0_reg'instance_name = ":test_bench(counter_test)" & ":dut@counter(registered):val0_reg@reg4(struct):" bit0'path_name = ":test_bench:dut:val1_reg:bit0" bit0'instance_name = ":test_bench(counter_test)" & ":dut@counter(registered):val1_reg@reg4(struct)" & ":bit0@edge_triggered_dff(behavioral):" clr'path_name = ":test_bench:dut:val1_reg:bit0:clr" clr'instance_name = ":test_bench(counter_test)" & ":dut@counter(registered):val1_reg@reg4(struct)" & ":bit0@edge_triggered_dff(behavioral):clr" | |
attribute load : capacitance; attribute load of d_in : signal is 3 pF; | |
type area is range 0 to integer'high units um_2; end units area; attribute cell_area : area; attribute cell_area of library_cell : architecture is 15 um_2; | |
attribute optimization of test_empty [ list_ptr, boolean ] : procedure is "inline"; | |
group statement_set is ( label, label <> ); group steps_1_and_2 : statement_set ( step_1, step_2 ); attribute resource_allocation of steps_1_and_2 : group is max_sharing; | |
| |
A 2-to-1 multiplexer with | |
A synthesis tool might infer the hardware shown at the left below. This might subsequently be optimized as shown at the right. ![]() | |
logic_block : process (enable_n, adr, reg1, reg2) is begin if std_match(enable_n, '0') then if std_match(adr, '0') then dat_o <= reg1; else dat_o <= reg2; end if; ack_o <= '1'; else dat_o <= "ZZZZZZZZ"; ack_o <= 'Z'; end if; end process logic_block; | |
The process makes no assignment to | |
en_reg : process ( clk ) is begin if rising_edge(clk) then if en = '1' then reg_out <= data_in; end if; end if; end process en_reg; | |
type RAM_type is array (0 to 8191) of signed(15 downto 0); signal RAM : RAM_type := (others => X"0000"); | |
type decoder_array is array (0 to 15) of std_ulogic_vector(1 to 7); constant decoder_ROM : decoder_array := ( 0 => "0111111", 1 => "0000110", 2 => "1011011", 3 => "1001111", 4 => "1100110", 5 => "1101101", 6 => "1111101", 7 => "0000111", 8 => "1111111", 9 => "1101111", others => "1000000" ); ... decoder : seg <= decoder_ROM(to_integer(bcd)); | |
We can decorate the type attribute enum_encoding of state : type is "00 01 11"; Alternatively, we could decorate attribute fsm_state of state : type is "00 01 11"; or we could decorate the signals attribute fsm_state of current_state, next_state : signal is "00 01 11"; |
| |
| |
signal serial_bus : wired_or_bit bus; signal d_node : unique_bit register; | |
When the resolution function for a standard-logic signal is passed an empty vector, it returns the value ‘Z’. Thus, the values on | |
‘U’, ‘0’ after 10 ns, ‘1’ after 20 ns, ‘0’ after 30 ns, ‘X’ after 35 ns, ‘1’ after 40 ns, ‘0’ after 45 ns. | |
vote <= 3 after 2 us, null after 5 us; | |
Initially false, true at 160 ns, false at 270 ns. | |
inverting_latch : block ( en ) is begin q_out_n <= guarded not d_in; end block inverting_latch; | |
disconnect source1 : wired_word after 3.5 ns; disconnect others : wired_word after 3.2 ns; disconnect all : wired_bit after 2.8 ns; | |
Initially 0, 3 at 51 ns, 5 at 81 ns, 0 at 102 ns. | |
inverting_ff : block is signal q_internal : bit; begin the_dff : component dff port map ( clk => sys_clk, d => d_in, q => q_internal ); the_inverter : component inverter port map ( i => q_internal, y => q_out_n ); end block inverting_ff; | |
for inverting_ff for the_dff : dff use entity work.d_flipflop(basic); end for; for the_inverter : inverter use entity work.inverter(basic); end for; end for; | |
architecture rtl of ethernet_mac is 'protect data_keyowner = "IP_werx" 'protect data_keyname = "IP_werx_sim" 'protect data_method = "3des-cbc" 'protect begin signal fifo_enable : std_ulogic; ... begin rx_fifo : IP_werx_fifo port map ( ... ); ... 'protect end end architecture rtl; | |
architecture rtl of ethernet_mac is 'protect key_keyowner = "Aero Industries" 'protect key_keyname = "Aero Design" 'protect key_method = "pgp-rsa" 'protect key_block 'protect data_method = "aes192-cbc" 'protect encoding = (enctype="base64") 'protect begin signal fifo_enable : std_ulogic; ... begin rx_fifo : IP_werx_fifo port map ( ... ); ... 'protect end end architecture rtl; | |
architecture vhpi_implementation of control is attribute foreign of vhpi_implementation : architecture is "VHPIDIRECT $VHPIUSERLIB/control.so control_elab control_exec"; begin end architecture vhpi_implementation; | |
architecture vhpi_implementation of control is attribute foreign of vhpi_implementation : architecture is "VHPI control_lib control_model"; begin end architecture vhpi_implementation; The line in the tabular registry is control_lib control_model vhpiArchF control_elab control_exe This requires that the logical name control_lib be mapped to the object library. | |
The function | |
We need to define a conversion function from function cvt_to_bit ( s : std_ulogic ) return bit is begin return To_bit(s); end function cvt_to_bit; We can use this function and the standard-logic conversion function gate1 : component nand2 port map ( a => To_stdulogic(s1), b => To_stdulogic(s2), cvt_to_bit(y_n) => s3 ); | |
3.144.10.69