Appendix C. Answers to Exercises

In this appendix, we provide sample answers to the quiz-style exercises marked with the symbol “Answers to Exercises”. Readers are encouraged to test their answers to the other, more involved, exercises by running the models on a VHDL simulator.

Chapter 1

1.

Entity declaration: defines the interface to a module, in terms of its ports, their data transfer direction and their types. Behavioral architecture body: defines the function of a module in terms of an algorithm. Structural architecture body: defines an implementation of a module in terms of an interconnected composition of sub-modules. Process statement: encapsulates an algorithm in a behavioral description, contains sequential actions to be performed. Signal assignment statement: specifies values to be applied to signals at some later time. Port map: specifies the interconnection between signals and component instance ports in a structural architecture.

2.

apply_transform : process is
begin
   d_out <= transform(d_in) after 200 ps;
   -- debug_test <= transform(d_in);
   wait on enable, d_in;
end process apply_transform;

3.

Basic identifiers: last_item. Reserved words: buffer. Invalid: prev item, value–1 and element#5 include characters that may not occur within identifiers; _control starts with an underscore; 93_999 starts with a digit; entry_ ends with an underscore.

4.

16#1#      16#22#      16#100.0#       16#0.8#

5.

12  132  44  250000  32768  0.625

6.

The literal 16#23DF# is an integer expressed in base 16, whereas the literal X“23DF” is a string of 16 bits.

7.

O"747" = B"111_100_111"
O"377" = B"011_111_111"
O"1_345" = B"001_011_100_101"
X"F2" = B"1111_0010"
X"0014" = B"0000_0000_0001_0100"
X"0000_0001" = B"0000_0000_0000_0000_0000_0000_0000_0001"

8.

10UO"747" = B"0_111_100_111"
10UO"377" = B"0_011_111_111"
10UO"1_345" = B"1_011_100_101"
10SO"747" = B"1_111_100_111"
10SO"377" = B"0_011_111_111"
10SO"1_345" = B"1_011_100_101
12UX"F2" = B"0000_1111_0010"
12SX"F2" = B"1111_1111_0010"
10UX"F2" is illegal due to truncation of leading 1 bits
10SX"F2" = B"11_1111_0010"

9.

D"24" = B"11000"
12D"24" = B"0000_0001_1000"
4D"24" is illegal due to truncation of a leading 1 bit

Chapter 2

1.

constant bits_per_word : integer := 32;
constant pi : real := 3.14159;

2.

variable counter : integer := 0;
variable busy_status : boolean;
variable temp_result : std_ulogic;

3.

counter := counter + 1;
busy_status := true;
temp_result := 'W';

4.

package misc_types is
   type small_int is range 0 to 255;
   type fraction is range -1.0 to +1.0;
   type current is range integer'low to integer'high
     units nA;
       uA = 1000 nA;
       mA = 1000 uA;
       A = 1000 mA;
     end units;
   type colors is (red, yellow, green);
end package misc_types;

5.

  1. Legal

  2. Illegal, should be: a = ‘1' and b = ‘0’ and state = idle

  3. Illegal, should be: a = ‘0’ and b = ‘1’ and state = idle

  4. Legal

6.

pulse_range'left =  pulse_range'low = 1 ms
pulse_range'right = pulse_range'high = 100 ms
pulse_range'ascending = true
word_index'left = 31 word_index'right = 0
word_index'low = 0 word_index'high  = 31
word_index'ascending = false

7.

state'pos(standby) = 1              state'val(2) = active1
state'succ(active2) is undefined    state'pred(active1) = standby
state'leftof(off) is undefined      state'rightof(off) = standby

8.

2 * 3 + 6 / 4 = 7
3 + -4 is syntactically incorrect
"cat" & character'('0') = "cat0"
true and x and not y or z is syntactically incorrect
B"101110" sll 3 = B"110000"
(B"100010" sra 2) & X"2C"= B"11100000101100"

Chapter 3

1.

if n mod 2 = 1 then
  odd := '1';
else
  odd := '0';
end if;
odd := '1' when n mod 2 = 1 else
       '0';

2.

if year mod 400 = 0 then
   days_in_February := 29;
elsif year mod 100 = 0 then
   days_in_February := 28;
elsif year mod 4 = 0 then
   days_in_February := 29;
else
   days_in_February := 28;
end if;
days_in_February := 29 when year mod 400 = 0 else
                    28 when year mod 100 = 0 else
                    29 when year mod 4 = 0 else
                    28;

3.

case x is
   when '0' | 'L' => x := '0';
   when '1' | 'H' => x := '1';
   when others => x := 'X';
end case;
with x select
   x := '0' when '0'  | 'L',
         '1' when '1' | 'H',
         'X' when others;

4.

case ch is
   when 'A' to 'Z' | 'a' to 'z' |
         'À' to 'Ö' | 'ø' to 'β' | 'à' to 'ö' | 'ø' to 'ÿ' =>
     character_class := 1;
   when '0' to '9' =>  character_class := 2;
   when nul to usp | del | c128 to c159 =>  character_class := 4;
   when others => character_class := 3;
end case;
with ch select
   character_class :=
     1 when 'A' to 'Z' | 'a' to 'z' |
         'À' to 'Ö' | 'ø' to 'β' | 'à' to 'ö' | 'ø' to 'ÿ',
     2 when '0' to '9',
     4 when nul to usp | del | c128 to c159,
     3 when others;

5.

loop
   wait until clk;
   exit when d;
end loop;

6.

sum := 1.0;
term := 1.0;
n := 0;
while abs term > abs (sum / 1.0E5) loop
   n := n + 1;
   term := term * x / real(n);
   sum := sum + term;
end loop;

7.

sum := 1.0;
term := 1.0;
for n in 1 to 7 loop
   term := term * x / real(n);
   sum := sum + term;
end loop;

8.

assert to_X01(q) = not to_X01(q_n)
   report "flipflop outputs are not complementary";

9.

Insert the statement after the comment “-- at this point, reset = ‘1'":

report "counter is reset";

Chapter 4

1.

type num_vector is array (1 to 30) of integer;
variable numbers : num_vector;
...
sum := 0;
for i in numbers'range loop
   sum := sum + numbers(i);
end loop;
average := sum / numbers'length;

2.

type std_ulogic_to_bit_array is array (std_ulogic) of bit;
constant std_ulogic_to_bit : std_ulogic_to_bit_array
   := ( 'U' => '0', 'X' => '0', '0' => '0', '1' => '1', 'Z' => '0',
        'W' => '0', 'L' => '0', 'H' => '1', '-' => '0' );
...
for index in 0 to 15 loop
   v2(index) := std_ulogic_to_bit(v1(index));
end loop;

3.

type free_map_array is array (0 to 1, 0 to 79, 0 to 17) of bit;
variable free_map : free_map_array;
...
found := false;
search_loop : for side in 0 to 1 loop
   for track in 0 to 79 loop
     for sector in 0 to 17 loop
       if free_map(side, track, sector) then
         found := true;  free_side := side;
         free_track := track;  free_sector := sector;
         exit search_loop;
       end if;
     end loop;
   end loop;
end loop;

4.

subtype std_ulogic_byte is std_ulogic_vector(7 downto 0);
constant Z_byte : std_ulogic_byte := "ZZZZZZZZ";

5.

type times_array is array (positive range <>) of time_vector;
subtype times4_array is times_array(1 to 4);
variable times4_10 : times4_array(open)(0 to 9);

6.

count := 0;
for index in v'range loop
   if v(index) then
     count := count + 1;
   end if;
end loop;

7.

Assuming the declarations

variable v1 : bit_vector(7 downto 0);
variable v2 : bit_vector(31 downto 0);
...
v2(31 downto 24) := v1;
v2 := v2 sra 24;

8.

type test_record is record
     stimulus : bit_vector(0 to 2);
     delay : delay_length;
     expected_response : bit_vector(0 to 7);
   end record test_record;

Chapter 5

1.

entity lookup_ROM is
   port ( address : in lookup_index;  data : out real );
   type lookup_table is array (lookup_index) of real;
   constant lookup_data : lookup_table
              := ( real'high, 1.0, 1.0/2.0, 1.0/3.0, 1.0/4.0, ... );
end entity lookup_ROM;

2.

architecture functional of lookup_ROM is
begin
   data <= lookup_data(address) after 200 ps;
end architecture functional;

3.

Transactions are ‘Z’ at 10ns, ‘0’ at 100ns, ‘1’ at 30ns, ‘1’ at 55 ns, ‘H’ at 65 ns and ‘Z’ at 100 ns. The signal is active at all of these times. Events occur at each time except 55 ns, since the signal already has the value ‘1’ at that time.

4.

s’delayed(5 ns): ‘Z’ at 5 ns, ‘0’ at 15 ns, ‘1’ at 35 ns, ‘H’ at 70 ns, ‘Z’ at 105 ns. s’stable(5 ns): false at 0 ns, true at 5 ns, false at 10 ns, true at 15 ns, false at 30 ns, true at 35 ns, false at 65 ns, true at 70 ns, false at 100 ns, true at 105 ns. s’quiet(5 ns): false at 0 ns, true at 5 ns, false at 10 ns, true at 15 ns, false at 30 ns, true at 35 ns, false at 55 ns, true at 60 ns, false at 65 ns, true at 70 ns, false at 100 ns, true at 105 ns. s’transaction (assuming an initial value of ‘0’): ‘1’ at 0 ns, ‘0’ at 10 ns, ‘1’ at 30 ns, ‘0’ at 55 ns, ‘1’ at 65 ns, ‘0’ at 100 ns. At time 60 ns, s’last_event is 30 ns, s’last_active is 5 ns, and s’last_value is ‘0’.

5.

wait on s until not s and en;

6.

wait until ready for 5 ms;

7.

The variable v1 is assigned false, since s is not updated until the next simulation cycle. The variable v2 is assigned true, since the wait statement causes the process to resume after s is updated with the value ‘1’.

8.

At 0 ns: schedule ‘1’ for 6 ns. At 3 ns: schedule ‘0’ for 7 ns. At 8 ns: schedule ‘1’ for 14 ns. At 9 ns: delete transaction scheduled for 14 ns, schedule ‘0’ for 13 ns. The signal z takes on the values ‘1’ at 6 ns and ‘0’ at 7 ns. The transaction scheduled for 13 ns does not result in an event on z.

9.

At 0 ns: schedule 1 for 7 ns, 23 for 9 ns, 5 for 10 ns, 23 for 12 ns and –5 for 15 ns. At 6 ns: schedule 23 for 13 ns, delete transactions scheduled for 15 ns, 10 ns and 9 ns. The signal x takes on the values 1 at 7 ns and 23 at 12 ns.

10.

The process is sensitive to current_state and in1, as these are the signals read by the process.

11.

mux_logic : process is
begin
   if enable and sel then
     z <= a and not b after 5 ns;
   elsif enable and sel then
     z <= x or y after 6 ns;
   else
     z <= '0' after 4 ns;
   end if;
   wait on a, b, enable, sel, x, y;
end process mux_logic;

12.

process is
begin
   case bit_vector'(s, r) is
     when "00" =>  q <= unaffected;
     when "01" =>  q <= '0';
     when "10" | "11" =>  q <= '1';
   end case;
   wait on s, r;
end process;

13.

assert (not clk'event) or clk'delayed'last_event >= T_pw_clk
     report "interval between changes on clk is too small";

14.

bit_0 : entity work.ttl_74x74(basic)
     port map ( pr_n => '1', d => q0_n, clk => clk, clr_n => reset,
                q => q0, q_n => q0_n );
bit_1 : entity work.ttl_74x74(basic)
   port map ( pr_n => '1', d => q1_n, clk => q0_n, clr_n => reset,
              q => q1, q_n => q1_n );

15.

Chapter 5

16.

One possible order is suggested: analyzing all entity declarations first, followed by all architecture bodies:

  • entity edge_triggered_Dff

  • entity reg4

  • entity add_1

  • entity buf4

  • entity counter

  • architecture behav of edge_triggered_Dff

  • architecture struct of reg4

  • architecture boolean_eqn of add_1

  • architecture basic of buf

  • architecture registered of counter

An alternative is

  • entity counter

  • entity buf4

  • entity add_1

  • entity reg4

  • architecture registered of counter

  • architecture basic of buf

  • architecture boolean_eqn of add_1

  • entity edge_triggered_Dff

  • architecture struct of reg4

  • architecture behav of edge_triggered_Dff

17.

library company_lib, project_lib;
use company_lib.in_pad, company_lib.out_pad, project_lib.all;

18.

context phantom_context is
   library ieee, IP_worx, phantom_lib;
   use ieee.std_logic_1164.all;
   use IP_worx.all, phantom_lib.all;
end context phantom_context;

Chapter 6

1.

constant operand1 : in integer
operand1 : integer
constant tag : in bit_vector(31 downto 16)
tag : bit_vector(31 downto 16)
constant trace : in boolean := false
trace : boolean := false

2.

variable average : out real
average : out real
variable identifier : inout string
identifier : inout string

3.

signal clk : out bit
signal data_in : in std_ulogic_vector
signal data_in : std_ulogic_vector

4.

Some alternatives are

stimulate ( s, 5 ns, 3 );
stimulate ( target => s, delay => 5 ns, cycles => 3 );
stimulate ( s, 10 ns, 1 );
stimulate ( s, 10 ns );
stimulate ( target => s, delay => 10 ns, cycles => open );
stimulate ( target => s, cycles => open, delay => 10 ns );
stimulate ( target => s, delay => 10 ns );
stimulate ( s, 1 ns, 15 );
stimulate ( target => s, delay => open, cycles => 15 );
stimulate ( target => s, cycles => 15 );
stimulate ( s, cycles => 15 );

5.

swapper : process is
begin
   shuffle_bytes ( ext_data, int_data, swap_control, Tpd_swap );
   wait on ext_data, swap_control;
end process swapper;

6.

product_size := approx_log_2(multiplicand)
                + approx_log_2(multiplier);

7.

assert now <= 20 ms
   report "simulation time has exceeded 20 ms";

8.

The third, first, none and third, respectively.

9.

Chapter 6

Chapter 7

1.

package EMS_types is
   type engine_speed is range 0 to integer'high
     units rpm;
     end units engine_speed;
   constant peak_rpm : engine_speed := 6000 rpm;
   type gear is (first, second, third, fourth, reverse);
end package EMS_types;
work.EMS_types.engine_speed
work.EMS_types.rpm            work.EMS_types.peak_rpm
work.EMS_types.gear           work.EMS_types.first
work.EMS_types.second         work.EMS_types.third
work.EMS_types.fourth         work.EMS_types.reverse

2.

procedure increment ( num : inout integer );

3.

function odd ( num : integer ) return boolean;

4.

constant e : real;

5.

No. The package does not contain any subprogram declarations or deferred constant declarations.

6.

use work.EMS_types.engine_speed;

7.

library DSP_lib;
use DSP_lib.systolic_FFT, DSP_lib.DSP_types.all;

Chapter 8

1.

  1. ‘1’.

  2. ‘0’.

  3. Either ‘1’ or ‘0’. The order of contributions within the array passed to the resolution function is not defined. This particular resolution function returns the leftmost non-‘Z’ value in the array, so the result depends on the order in which the simulator assembles the contributions.

2.

subtype wired_and_logic is wired_and tri_state_logic;
signal synch_control : wired_and_logic := '0';

3.

The initial value is ‘X’. The default initial value of type MVL4, ‘X’, is used as the initial value of each driver of int_req. These contributions are passed to the resolution function, which returns the value ‘X’.

4.

No, since the operation represented by the table in the resolution function is commutative and associative, with ‘Z’ as its identity.

5.

  1. “ZZZZ0011”

  2. “XXXX0011”

  3. “0011XX11”

6.

“XXXXZZZZ00111100”

7.

  1. ‘0’

  2. ‘0’

  3. ‘W’

  4. ‘U’

  5. ‘X’

8.

Chapter 8

9.

The resolution function is invoked seven times: for the Mem port, the Cache port, the CPU/Mem Section port, the Serial port, the DMA port, the I/O Section port and the Data Bus signal.

10.

We cannot simply invert the value read from the port, since the value may differ from that driven by the process. Instead, we use the ’driving_value attribute:

synch_T <= not synch_T'driving_value;

Chapter 9

1.

assert std.env.resolution_limit < 1.0E-9 sec;

2.

to_hstring(B"ZZZZ_0100") = "Z4"
to_hstring(B"XX_L01H") = to_hstring(B"XXXX_L01H") = "X3"
to_hstring(B"01_00ZZ") = to_hstring(B"0001_00ZZ") = "1X"

3.

use ieee.numeric_std.all;
...
signal a, b, s : unsigned(23 downto 0);
signal carry_in, carry_out : std_ulogic;
...
(carry_out, s) < = a + b + carry_in;

4.

One approach, using implicit conversion of en to boolean, is

D_ff : process (clk) is
begin
   if rising_edge(clk) then
        if en then
    q <= To_X01(d);
     end if;
   end if;
end process D_ff;

Alternatively:

D_ff : process (clk) is
begin
   if rising_edge(clk) and To_X01(en) = '1' then
     q <= To_X01(d);
   end if;
end process D_ff;

5.

signal a : sfixed(3 downto -6);
...
s <= resize(a*a, 7, -6);  -- resize using left and right bounds
s <= resize(a*a, s);      -- resize using bounds of s

6.

signal x, y : float(7 downto -12)
...
y <= to_float(-1.0, y) when x < -1.0 else
     to_float(+1.0, y) when x > +1.0 else
     x;

Chapter 10

1.

The variable partial_product is used to hold the results of the first pipeline stage computation. It is also used as the source operand for the second pipeline stage computations. If computation is performed for the first stage first, the variable is overwritten before being used for the second stage computation. The same argument applies for the variables used to hold results for subsequent stages in the pipeline.

2.

Since the real part and the imaginary part of the accumulator are each restricted to the range –16.0 to +16.0, any sequence that causes either accumulator part to fall out of this range results in an overflow. An example is the sequence

(–1.0, 0.0) x (–1.0, 0.0) + (–1.0, 0.0) x (–1.0, 0.0) + ...

Each product is the complex value (1.0, 0.0), so after 16 terms, the real part of the accumulator reaches the value 16.0 and overflows.

3.

The values in successive clock cycles after the first rising clock-edge are shown in the following table:

Variable

Value in successive clock cycles

input_x.re

+0.50

+0.20

+0.10

+0.10

   

input_x.im

+0.50

+0.20

-0.10

-0.10

   

input_y.re

+0.50

+0.20

+0.10

+0.10

   

input_y.im

+0.50

+0.20

+0.10

+0.10

   

real_part_product_1

?

+0.25

+0.04

+0.01

+0.01

  

real_part_product_2

?

+0.25

+0.04

-0.01

-0.01

  

imag_part_product_1

?

+0.25

+0.04

+0.01

+0.01

  

imag_part_product_2

?

+0.25

+0.04

-0.01

-0.01

  

product.re

?

?

0.00

0.00

+0.02

+0.02

 

product.im

?

?

+0.50

+0.08

0.00

0.00

 

sum.re

0.00

0.00

0.00

0.00

0.00

+0.02

+0.04

sum.im

0.00

0.00

0.00

+0.50

+0.58

+0.58

+0.58

real_accumulator_ovf

false

false

false

false

false

false

false

imag_accumulator_ovf

false

false

false

false

false

false

false

4.

The values +0.5 and -0.5 are represented as shown in the following table:

Format

+0.5

-0.5

inputs

0100...0

1100...0

partial products

00100...0

11100...0

products

000100 ...0

111100...0

pipelined products

000100...0

111100...0

accumulated sums

00000100...0

11111100...0

outputs

0100...0

1100...0

Chapter 11

1.

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;

2.

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);

3.

alias cons is "&" [ character, string return string ];
report cons ( grade_char, "-grade" );

Chapter 12

1.

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;

2.

clk_gen : entity work.clock_generator
   generic map ( period => 10 ns )
   port map ( clk => master_clk );

3.

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;

4.

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 );

5.

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 );

6.

The formal generic type is used as the type of the variable v, so the actual generic type must be a fully constrained type. The type unsigned is unconstrained, and so cannot be used as the type of a variable.

7.

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);

8.

The call with the actual parameter 1 is unambiguous, and calls the first overloaded version (with formal parameter of type T1). The call with the actual parameter ‘1’ is ambiguous, since the literal ‘1’ could be interpreted as a std_ulogic or a bit value. The second overloaded version has a formal parameter of type T2, which represents std_ulogic, and the third overloaded version has a formal parameter of type bit. So the call could refer to either of these versions. The call with the actual parameter b is unambiguous, and calls the third overloaded version.

9.

while not is_full(test_buffer) loop
   write(test_buffer, "00000000");
end loop;

10.

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);

11.

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 );

12.

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,
                 "<" => ">" );

13.

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 );

Chapter 13

1.

An entity declaration uses the keyword entity where a component declaration uses the keyword component. An entity declaration is a design unit that is analyzed and placed into a design library, whereas a component declaration is simply a declaration in an architecture body or a package. An entity declaration has a declarative part and a statement part, providing part of the implementation of the interface, whereas a component declaration simply declares an interface with no implementation information. An entity declaration represents the interface of a “real” electronic circuit, whereas a component declaration represents a “virtual” or “template” interface.

2.

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;

3.

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 );

4.

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;

5.

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;

6.

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;

7.

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;

8.

use entity work.multiplexer
   generic map ( Tpd => 3.5 ns );

9.

Chapter 13

10

generic map ( Tpd_01 => open, Tpd_10 => open )
port map ( a => a, b => b, c => c, d => open, y => y )

11.

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;

12.

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;

Chapter 14

1.

Chapter 14

2.

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;

3.

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;

4.

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;

5.

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 positive_clock is false when the design is elaborated.

Chapter 15

1.

type character_ptr is access character;
variable char : character_ptr := new character'(ETX);
...
char.all := 'A';

2.

The statement “r := r + 1.0;” should be “r.all := r.all+ 1.0;”. The name r in the statement denotes the pointer, rather than the value pointed to. It is an error to perform an arithmetic operation on a pointer value.

3.

Chapter 15

4.

a = b is true, a.all= b.all is true, c = d is false, c.all = d.all is true.

5.

type string_ptr is access string;
variable str : string_ptr := new string'(" ");
...
str(1) := NUL;

6.

z.re := x.re * y.re - x.im * y.im;
z.im := x.re * y.im + x.im * y.re;

7.

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 );

8.

The first statement copies the pointer to the first cell to the access variable cell_to_be_deleted and leaves value_list also pointing to that cell. The call to deallocate reclaims the storage and sets cell_to_be_deleted to the null pointer, but leaves value_list unchanged. The host computer system is free to reuse or remove the reclaimed storage, so the access using value_list in the third statement may not be valid.

Chapter 16

1.

type real_file is file of real;
file sample_file : real_file open read_mode is "samples.dat";
...
read ( sample_file, x );

2.

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 );

3.

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;

4.

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”.

5.

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);

6.

"   3500 ns 00111100 ok   "

Chapter 17

1.

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) );

2.

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 );

Chapter 18

1.

<<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>>

2.

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>>;

3.

<<constant dp.d_width : positive>>
<<signal dp.d_bus : std_ulogic_vector(7 downto 0)>>
<<signal dp.adder(3).carry : std_ulogic>>

4.

reset <= force '1';
wait for 200 ns;
reset <= release;

5.

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;

6.

configuration verifying of bus_interface is
   use vunit verify_protocol;
   for behavior
   end for;
end configuration verifying;

7.

for ext : ext_interface
   use entity bus_interface(behavior);
   use vunit verify_protocol;
end for;

Chapter 19

1.

If the host computer system has multiple processors, m1 and m2 may be resumed concurrently on different processors. Suppose the variable starts with the value 0. A possible sequence of events is the following: m1 reads the variable and gets the value 0, m2 reads the variable and gets the value 0, m1 updates the variable with the value 1, m1 updates the variable with the value 1. Thus, the final value of the variable is 1, even though there were two increments performed.

2.

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;

Chapter 20

1.

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]:"

2.

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"

3.

attribute load : capacitance;
attribute load of d_in : signal is 3 pF;

4.

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;

5.

attribute optimization of
   test_empty [ list_ptr, boolean ] : procedure is "inline";

6.

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;

Chapter 21

1.

Temp is allowed, as it is an integer type. Temp_vec is allowed, as it is an array type indexed by an integer type and has an integer element type. Location is allowed, as it is an enumeration type. Local_temp_vec is not allowed, as its index type is not an integer type. Location_vec is allowed, as it is an array type indexed by an integer type and has an enumeration element type. Word_vec is allowed, as it is an array type indexed by an integer type and has as its element type a one-dimensional array of an enumeration type representing bits.

2.

A 2-to-1 multiplexer with sel as its select input, in0 and in1 as the data inputs, and z as the data output. The tests for ‘U’ and other metalogical values would be ignored by the synthesis tool.

3.

A synthesis tool might infer the hardware shown at the left below. This might subsequently be optimized as shown at the right.

Chapter 21

4.

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;

5.

The process makes no assignment to operand on the path in which sel is “11”. Hence, the previous value of operand must be stored when sel changes to “11”. The storage takes the form of a transparent latch enabled by sel being other than “11”. We can eliminate this storage by adding an assignment of a default value to operand in the others alternative of the case statement.

6.

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;

7.

type RAM_type is array (0 to 8191) of signed(15 downto 0);
signal RAM : RAM_type := (others => X"0000");

8.

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));

9.

We can decorate the type state with the enum_encoding attribute as follows:

attribute enum_encoding of state : type is "00 01 11";

Alternatively, we could decorate state with the fsm_state attribute:

attribute fsm_state of state : type is "00 01 11";

or we could decorate the signals current_state and next_state:

attribute fsm_state of
   current_state, next_state : signal is "00 01 11";

Chapter 22

1.

  1. sub r2, r1, r0: 11 1001 0001 0000 0010 = 0x39102

  2. and r4, r4, 0x30: 01 0010 0100 0011 0000 = 0x12430

  3. ror r1, r1, 2: 11 0000 1001 0100 0011 = 0x30943

  4. ldm r6, (r2)-1: 10 0011 0010 1111 1111 = 0x232FF

  5. out r4, 0x10: 10 1110 0000 0000 1010 = 0x2E00A

  6. bz +7: 11 1110 0000 0000 0111 = 3E007

  7. jsb 0xD0: 11 1101 0000 1101 0000 = 3D0D0

2.

  1. 0DBC0 = 00 1101 1011 1100 0000: subc r3, r3, 0xC0

  2. 38326 = 11 1000 0011 0010 0110: xor r0, r3, r1

  3. 33D63 = 11 0011 1101 0110 0011: ror r7, r5, 3

  4. 25906 = 10 0101 1001 0000 0110: stm r3, (r1)+6

  5. 3EC11 = 11 1110 1100 0001 0001: bnc +17

  6. 3DC70 = 11 1101 1100 0111 0000: jsb 0xC70

  7. 3F200 = 11 1111 0010 0000 0000: enai

Chapter 23

1.

signal serial_bus : wired_or_bit bus;
signal d_node : unique_bit register;

2.

When the resolution function for a standard-logic signal is passed an empty vector, it returns the value ‘Z’. Thus, the values on rx_bus are ‘Z’, ‘0’ after 10 ns, ‘1’ after 20 ns, ‘0’ after 30 ns, ‘X’ after 35 ns, ‘1’ after 40 ns, ‘0’ after 45 ns and ‘Z’ after 55 ns.

3.

‘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.

4.

vote <= 3 after 2 us, null after 5 us;

5.

Initially false, true at 160 ns, false at 270 ns.

6.

inverting_latch : block ( en ) is
begin
   q_out_n <= guarded not d_in;
end block inverting_latch;

7.

disconnect source1 : wired_word after 3.5 ns;
disconnect others : wired_word after 3.2 ns;
disconnect all : wired_bit after 2.8 ns;

8.

Initially 0, 3 at 51 ns, 5 at 81 ns, 0 at 102 ns.

9.

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;

10

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;

11.

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;

12.

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;

13.

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;

14.

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.

15.

The function To_bit has two parameters: the value to be converted and the parameter xmap that indicates how an unknown logic level should be converted. A conversion function in an association list must have only one parameter.

16.

We need to define a conversion function from std_ulogic to bit:

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 To_stdulogic in the association list:

gate1 : component nand2
   port map ( a => To_stdulogic(s1), b => To_stdulogic(s2),
              cvt_to_bit(y_n) => s3 );

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.144.10.69