|
10.18 Problems
Chapter start Previous page Next
page
10.18 Problems
* = Difficult ** = Very
difficult *** = Extremely difficult
10.1 (Hello World,
10 min.) Set up a new, empty, directory (use mkdir VHDL
, for example) to run your VHDL simulator (the exact details
will depend on your computer and simulator). Copy the code below to a file
called hw_1.vhd in your VHDL directory (leave
out comments to save typing). Hint: Use the vi editor (
i inserts text, x deletes text, dd deletes
a line, ESC :w writes the file, ESC :q
quits) or use cat > hw_1.vhd and type in the code
(use CTRL-D to end typing) on a UNIX machine. Remember to save
in 'Text Only' mode (Frame or MS Word) on an IBM PC or Apple Macintosh.
Analyze, elaborate, and
simulate your model (include the output in your answer). Comment on how
easy or hard it was to follow the instructions to use the software and suggest
improvements.
entity HW_1 is end; architecture Behave of HW_1 is
constant M : STRING := "hello, world"; signal Ch : CHARACTER := ' ';
begin process begin
for i in M'RANGE loop Ch <= M(i); wait for 1 ns; end loop; wait;
end process; end;
10.2 (Running
a VHDL simulation, 20 min.) Copy the example from Section 10.1 into
a file called Counter1.vhd in your VHDL directory
(leave out the comments to save typing). Complete the compile (analyze),
elaborate (build), and execute (initialize and simulate) or other equivalent
steps for your simulator. After each step list the contents of your directory
VHDL and any subdirectories and files that are created (use
ls -alR on a UNIX system).
10.3 (Simulator
commands, 10 min.) Make a "cheat sheet" for your simulator, listing
the commands that can be used to control simulation.
10.4 (BNF addresses,
10 min.) Create a BNF description of a name including: optional title (Prof.,
Dr., Mrs., Mr., Miss, or Ms.), optional first name and middle initials (allow
up to two), and last name (including unusual hyphenated and foreign names,
such as Miss A-S. de La Salle, and Prof. John T. P. McTavish-f Fiennes).
The lowest level constructs are letter ::= a-Z ,
'.' (period) and '-' (hyphen). Add BNF productions
for a postal address in the form: company name, mail stop, street address,
address lines (1 to 4), and country.
10.5 (BNF e-mail,
10 min.) Create a BNF description of a valid internet e-mail address in
terms of letters, '@' , '.' , 'gov'
, 'com ', 'org ', and 'edu' . Create
a state diagram that "parses" an e-mail address for validity.
10.6 (BNF equivalence)
Are the following BNF productions exactly equivalent? If they are not, produce
a counterexample that shows a difference.
term ::= factor { multiplying_operator factor }
term ::= factor | term multiplying_operator factor
10.7 (Environment,
20 min.) Write a simple VHDL model to check and demonstrate that you can
get to the IEEE library and have the environment variables, library statements,
and such correctly set up for your simulator.
10.8 (Work, 20
min.) Write simple VHDL models to demonstrate that you can retrieve and
use previously analyzed design units from the library work and
that you can also remove design units from work . Explain how
your models prove that access to work is functioning correctly.
10.9 (Packages,
60 min.) Write a simple package (use filename PackH.vhd ) and
package body (filename PackB.vhd ). Demonstrate that you can
store your package (call it MyPackage ) in the library work
. Then store, move, or rename (the details will depend on your software)
your package to a library called MyLibrary in a directory called
MyDir , and use its contents with a library clause (
library MyLibrary ) and a use clause ( use MyLibrary.MyPackage.all
) in a testbench called PackTest (filename PackT.vhd
) in another directory MyWork . You may or may not be amazed
at how complicated this can be and how poorly most software companies document
this process.
10.10 (***IEEE Std 1164,
60 min.) Prior to VHDL-93 the xnor function was not available,
and therefore older versions of the std_logic_1164 library
did not provide the xnor function for STD_LOGIC
types either (it was actually included but commented out). Write a simple
model that checks to see if you have the newer version of std_logic_1164
. Can you do this without crashing the simulator?
You are an engineer on
a very large project and find that your design fails to compile because
your design must use the xnor function and the library setup
on your company's system still points to the old IEEE std_logic_1164
library, even though the new library was installed. You are apparently the
first person to realize the problem. Your company has a policy that any
time a library is changed all design units that use that library must be
rebuilt from source. This might require days or weeks of work. Explain in
detail, using code, the alternative solutions. What will you recommend to
your manager?
10.11 (**VHDL-93
test, 20 min.) Write a simple test to check if your simulator is a VHDL-87
or VHDL-93 environment--without crashing the simulator.
10.12 (Declarations,
10 min.) Analyze the following changes to the code in Section 10.8
and include the simulator output in your answers:
Uncomment the
declarations for Bad100 and Bad4 in Declaration
_1 .
Add the following
to Constant_2:
signal wacky : wackytype (31 downto 0); -- wacky
Remove the library
and use clause in Constant_2.
10.13 (
STRING type, 10 min.) Replace the write statement that
prints the string " count=" in Text(Behave)
in Section 10.6.3 with the following, compile it, and explain the result:
write(L, " count=" ); -- No type qualification.
10.14 (Sequential
statements, 10 min.) Uncomment the following line in Wait_1(Behave) in Section 10.10,
analyze the code, and explain the result:
wait on x(1 to v); -- v is a variable.
10.15 (VHDL logical
operators, 10 min.)
Explain the problem
with the following VHDL statement:
Z <= A nand B nand C;
Explain why this problem
does not occur with this statement:
Z <= A and B and C;
What can you say about
the logical operators: and , or , nand
, nor , xnor , xor ?
Is the following code
legal?
Z <= A and B or C;
10.16 (*Initialization,
45 min.) Consider the following code:
entity DFF_Plain is port (Clk, D : in BIT; Q : out BIT); end;
architecture Bad of DFF_Plain is begin process (Clk) begin
if Clk = '0' and Clk'EVENT then Q <= D after 1 ns; end if;
end process; end;
Analyze and simulate
this model using a testbench.
Rewrite architecture
Bad using an equivalent process including a wait
statement. Simulate this equivalent model and confirm the behaviors are
identical.
What is the behavior
of the output Q during initial execution of the process?
Why does this happen?
Why does this not happen
with the following code:
architecture Good of DFF_Plain is
begin process begin wait until Clk = '0'; Q <= D after 1 ns;
end process; end;
10.17 (Initial
and default values, 20 min.) Use code examples to explain the difference
between: default expression, default value, implicit default value, initial
value, initial value expression, and default initial value.
10.18 (Enumeration
types, 20 min.) Explain the analysis results for the following:
type MVL4 is ('X', '0', '1', 'Z'); signal test : MVL4;
process begin
test <= 1; test <= Z; test <= z; test <= '1'; test <= 'Z';
end process;
Alter the type declaration
to the following, analyze your code again, and comment:
type Mixed4 is (X , '0', '1', Z);
10.19 (Type declarations,
10 min.) Correct these declarations:
type BadArray is array (0 to 7) of BIT_VECTOR;
type Byte is array (NATURAL range 7 downto 0) of BIT;
subtype BadNibble is Byte(3 downto 0);
type BadByte is array (range 7 downto 0) of BIT;
10.20 (Procedure
parameters, 10 min.) Analyze the following package; explain and correct
the error. Finally, build a testbench to check your solution.
package And_Pkg_Bad is procedure V_And(a, b : BIT; c: out BIT); end;
package body And_Pkg_Bad is
procedure V_And(a,b : BIT;c : out BIT) is begin c <= a and b;end;
end And_Pkg_Bad;
10.21 (Type checking,
20 min.) Test the following code and explain the results:
type T is INTEGER range 0 to 32; variable a: T;
a := (16 + 17) - 12; a := 16 - 12 + 17; a := 16 + (17 - 12);
10.22 (Debugging
VHDL code, 30 min.) Find and correct the errors in the following code. Create
a testbench for your code to check that it works correctly.
entity UpDownCount_Bad is
port(clock, reset, up: STD_LOGIC; D: STD_LOGIC_VECTOR (7 to 0));
end UpDownCount_Bad;
architecture Behave of UpDownCount_Bad is
begin process (clock, reset, up); begin
if (reset = '0') then D <= '0000000';
elseif (rising_edge(clock)) then
if (up = 1) D <= D+1; else D <= D-1; end if;
end if; end process; end Behave;
10.23 (Subprograms,
20 min.) Write and test subprograms for these declarations:
function Is_X_Zero (signal X : in BIT) return BIT;
procedure Is_A_Eq_B (signal A, B : BIT; signal Y : out BIT);
10.24 (Simulator
error messages, 10 min.) Analyze and attempt to simulate Arithmetic_2(Behave)
from Section 10.12 and compare the error message you receive with that
from the MTI simulator (not all simulators are as informative). There are
no standards for error messages.
10.25 (Exhaustive
property of case statement, 30 min.) Write and simulate a testbench for
the state machine of Table 10.8 and include your results. Is every
state transition tested by your program and is every transition covered
by an assignment statement in the code? (Hint: Think very carefully.) Repeat
this exercise for the state machine in Section 10.10.6.
10.26 (Default
values for inputs, 20 min.) Replace the interface declaration for entity
Half_Adder in Section 10.5 with the following (to remove the default
values):
port (X, Y: in BIT ; Sum, Cout: out BIT);
Attempt to compile, elaborate,
and simulate configuration Simplest (the other entities needed, AndGate
and XorGate , must already be in work or in the
same file). You should get an error at some stage (different systems find
this error at different points--just because an entity compiles, that does
not mean it is error-free).
The LRM says "...
A port of mode in may be unconnected ...only if its declaration includes
a default expression..." [VHDL
93LRM1.1.1.2].
We face a dilemma here.
If we do not drive inputs with test signals and leave an input port unconnected,
we can compile the model (since it is syntactically correct) but the model
is not semantically correct. On the other hand, if we give the inputs default
values, we might accidentally forget to make a connection and not notice.
10.27 (Adder
generation, 10 min.) Draw the schematic for Adder_1(Structure) of Section 10.13.7,
labeling each instance with the VHDL instance name.
10.28 (Generate
statement, 20 min.) Draw a schematic corresponding to the following code
(label the cells with their instance names):
B1: block begin L1 : C port map (T, B, A(0), B(0)) ;
L2: for i in 1 to 3 generate L3 : for j in 1 to 3 generate
L4: if i+j > 4 generate L5: C port map (A(i-1), B(j-1), A(i), B(j)) ;
end generate; end generate; end generate;
L6: for i in 1 to 3 generate L7: for j in 1 to 3 generate
L8: if i+j < 4 generate L9: C port map (A(i+1), B(j+1), A(i), B(j)) ;
end generate; end generate; end generate;
end block B1;
Rewrite the code without
generate statements. How would you prove that your code really
is exactly equivalent to the original?
10.29 (Case statement,
20 min.) Create a package ( my_equal ) that overloads the equality
operator so that 'X' = '0' and 'X' = '1' are both
TRUE . Test your package. Simulate the following design unit
and explain the result.
entity Case_1 is end; architecture Behave of Case_1 is
signal r : BIT; use work.my_equal.all;
begin process variable twobit:STD_LOGIC_VECTOR(1 to 2); begin
twobit := "X0";
case twobit is
when "10" => r <= '1';
when "00" => r <= '1';
when others => r <= '0';
end case; wait;
end process; end;
10.30 (State
machine) Create a testbench for the state machine of Section 10.2.5.
10.31 (Mealy
state machine, 60 min.) Rewrite the state machine of Section 10.2.5
as a Mealy state machine (the outputs depend on the inputs and on the current
state).
10.32 (Gate-level
D flip-flop, 30 min.) Draw the schematic for the following D flip-flop model.
Create a testbench (check for correct operation with combinations of Clear
, Preset , Clock , and Data ). Have
you covered all possible modes of operation? Justify your answer of yes
or no.
architecture RTL of DFF_To_Test is
signal A, B, C, D, QI, QBarI : BIT; begin
A <= not (Preset and D and B) after 1 ns;
B <= not (A and Clear and Clock) after 1 ns;
C <= not (B and Clock and D) after 1 ns;
D <= not (C and Clear and Data) after 1 ns;
QI <= not (Preset and B and QBarI) after 1 ns;
QBarI <= not (QI and Clear and C) after 1 ns;
Q <= QI; QBar <= QBarI;
end;
10.33 (Flip-flop
model, 20 min.) Add an asynchronous active-low preset to the D flip-flop
model of Table 10.3. Generate a testbench that includes interaction
of the preset and clear inputs. What issue do you face and how did you solve
it?
10.34 (Register,
45 min.) Design a testbench for the register of Table 10.4. Adapt the
8-bit register design to a 4-bit version with the following interface declaration:
entity Reg4 is port (D : in STD_LOGIC_VECTOR(7 downto 0);
Clk,Pre,Clr : in STD_LOGIC;Q,QB : out STD_LOGIC_VECTOR(7 downto 0));
end Reg8;
Create a testbench for
your 4-bit register with the following component declaration:
component DFF
port(Preset,Clear,Clock,Data:STD_LOGIC;Q,QBar:out STD_LOGIC_VECTOR);
end component;
10.35 (*Conversion
functions, 30 min.) Write a conversion function from
NATURAL to STD_LOGIC_VECTOR using the following declaration:
function Convert (N, L: NATURAL) return STD_LOGIC_VECTOR;
-- N is NATURAL, L is length of STD_LOGIC_VECTOR
Write a similar conversion
function from STD_LOGIC_VECTOR to NATURAL:
function Convert (B: STD_LOGIC_VECTOR) return NATURAL;
Create a testbench to
test your functions by including them in a package.
10.36 (Clock
procedure, 20 min.) Design a clock procedure for a two-phase clock (C1,
C2) with variable high times ( HT1 , HT2 ) and
low times ( LT1 , LT2 ) and the following interface.
Include your procedure in a package and write a model to test it.
procedure Clock (C1, C2 : out STD_LOGIC; HT1, HT2, LT1, LT2 : TIME);
10.37 (Random
number, 20 min.) Design a testbench for the following procedure:
procedure uniform (seed : inout INTEGER range 0 to 15) is
variable x : INTEGER;
begin x := (seed*11) + 7; seed := x mod 16;
end uniform;
10.38 (Full-adder,
30 min.) Design and test a behavioral model of a full adder with the following
interface:
entity FA is port (X, Y, Cin : STD_LOGIC; Cout, Sum : out STD_LOGIC);
end;
Repeat the exercise for
inputs and outputs of type UNSIGNED .
10.39 (8-bit
adder testbench, 60 min.) Write out the code corresponding to the generate
statements of Adder_1 ( Structure ) in Section 10.13.7.
Write a testbench to check your adder. What problems do you encounter? How
thorough do you believe your tests are?
10.40 (Shift-register
testbench, 60 min.) Design a testbench for the shift register of Table 10.4.
Convert this model to use STD_LOGIC types with the following
interface:
entity ShiftN is
port (CLK, CLR, LD, SH, DIR : STD_LOGIC;
D : STD_LOGIC_VECTOR; Q : out STD_LOGIC_VECTOR);
end;
10.41 (Multiplier,
60 min.) Design and test a multiplier with the following interface:
entity Mult8 is
port (A, B : STD_LOGIC_VECTOR(3 downto 0);
Start, CLK, Reset : in STD_LOGIC;
Result : out STD_LOGIC_VECTOR(7 downto 0); Done : out BIT);
end;
Create testbench
code to check your model.
Catalog each compile
step with the syntax errors as you debug your code.
Include a listing of
the first code you write together with the final version.
An interesting class project
is to collect statistics from other students working on this problem and
create a table showing the types and frequency of syntax errors made with
each compile step, and the number of compile steps required. Does this information
suggest ways that you could improve the compiler, or suggest a new type
of tool to use when writing VHDL?
10.42 (Port maps,
5 min.) What is wrong with this VHDL statement?
U1 : nand2 port map (a <= set, b <= qb, c <= q);
10.43 (DRIVING_VALUE,
15 min.) Use the VHDL-93 attribute Clock'DRIVING_VALUE to rewrite the following
clock generator model without using a temporary variable.
entity ClockGen_2 is port (Clock : out BIT); end;
architecture Behave of ClockGen_2 is
begin process variable Temp : BIT := '1'; begin
Temp := not Temp ; Clock <= Temp after 10 ns; wait for 10 ns;
if (now > 100 ns) then wait; end if; end process;
end;
10.44 (Records,
15 min.) Write an architecture (based on the following skeleton) that uses
the record structure shown:
entity Test_Record_1 is end; architecture Behave of Test_Record_1 is
begin process type Coordinate is record X, Y : INTEGER; end record;
-- a record declaration for an attribute declaration:
attribute Location:Coordinate; -- an attribute declaration
begin wait; end process; end Behave;
10.45 (**Communication
between processes, 30 min.) Explain and correct the problem with the following
skeleton code:
variable v1 : INTEGER := 1; process begin v1 := v1+3; wait; end process;
process variable v2 : INTEGER := 2; begin v2 := v1 ; wait; end process;
10.46 (*Resolution,
30 min.) Explain and correct the problems with the following:
entity R_Bad_1 is port (i : in BIT; o out BIT); end;
architecture Behave of R_Bad_1 is
begin o <= not i after 1 ns; o <= i after 2 ns; end;
10.47 (*Inputs,
30 min.) Analyze the following and explain the result:
entity And2 is port (A1, A2: in BIT; ZN: out BIT); end;
architecture Simple of And2 is begin ZN <= A1 and A2; end;
entity Input_Bad_1 is end; architecture Netlist of Input_Bad_1 is
component And2 port (A1, A2 : in BIT; ZN : out BIT); end component;
signal X, Z : BIT begin G1 : And2 port map (X, X, Z); end;
10.48 (Association,
15 min.) Analyze the following and explain the problem:
entity And2 is port (A1, A2 : in BIT; ZN : out BIT); end;
architecture Simple of And2 is begin ZN <= A1 and A2; end;
entity Assoc_Bad_1 is port (signal X, Y : in BIT; Z : out BIT); end;
architecture Netlist of Assoc_Bad_1 is
component And2 port (A1, A2 : in BIT; ZN : out BIT); end component;
begin
G1: And2 port map (X, Y, Z);
G2: And2 port map (A2 => Y, ZN => Z, A1 => X);
G3: And2 port map (X, ZN => Z, A2 => Y);
end;
10.49 (Modes,
30 min.) Analyze and explain the errors in the following:
entity And2 is port (A1, A2 : in BIT; ZN : out BIT); end;
architecture Simple of And2 is begin ZN <= A1 and A2; end;
entity Mode_Bad_1 is port (X : in BIT; Y : out BIT; Z : inout BIT); end;
architecture Netlist of Mode_Bad_1 is
component And2 port (A1, A2 : in BIT; ZN : out BIT); end component;
begin G1 : And2 port map (X, Y, Z); end;
entity Mode_Bad_2 is port (X : in BIT; Y : out BIT; Z : inout BIT); end;
architecture Netlist of Mode_Bad_1 is
component And2 port (A1, A2 : in BIT; ZN : inout BIT); end component;
begin G1 : And2 port map (X, Y, Z); end;
10.50 (*Mode
association, 60 min.) Analyze and explain the errors in the following code.
The number of errors, types of error, and the information in the error messages
given by different simulators vary tremendously in this area.
entity Allmode is port
(I : in BIT; O : out BIT; IO : inout BIT; B : buffer BIT);
end;
architecture Simple of Allmode is begin O<=I; IO<=I; B<=I; end;
entity Mode_1 is port
(I : in BIT; O : out BIT; IO : inout BIT; B : buffer BIT);
end;
architecture Netlist of Mode_1 is
component Allmode port
(I : in BIT; O : out BIT; IO : inout BIT; B : buffer BIT); end component;
begin
G1:Allmode port map (I , O , IO, B );
G2:Allmode port map (O , IO, B , I );
G3:Allmode port map (IO, B , I , O );
G4:Allmode port map (B , I , O , IO);
end;
10.51 (**Declarations,
60 min.) Write a tutorial (approximately two pages of text, five pages with
code) with examples explaining the difference between: a component declaration,
a component configuration, a configuration declaration, a configuration
specification, and a block configuration.
10.52 (**Guards
and guarded signals, 60 min.) Write some simple models to illustrate the
use of guards, guarded signals, and the disconnect statement. Include an
experiment that shows and explains the use of the implicit signal GUARD
in assignment statements.
10.53 (**
Std_logic_1164 , 120 min.) Write a short (two pages of text) tutorial,
with (tested) code examples, explaining the std_logic_1164 types,
their default values, the difference between the 'ulogic' and
'logic' types, and their vector forms. Include an example that
shows and explains the problem of connecting a std_logic_vector
to a std_ulogic_vector.
10.54 (Data swap,
20 min.) Consider the following code:
library ieee; use ieee.std_logic_1164.all;
package config is
type type1 is record
f1 : std_logic_vector(31 downto 0); f2 : std_logic_vector(3 downto 0);
end record;
type type2 is record
f1 : std_logic_vector(31 downto 0); f2 : std_logic_vector(3 downto 0);
end record;
end config;
library ieee; use ieee.STD_LOGIC_1164.all; use work.config.all;
entity Swap_1 is
port (Data1 : type1; Data2 : type2; sel : STD_LOGIC;
Data1Swap : out type1; Data2Swap : out type2); end Swap_1;
architecture Behave of Swap_1 is begin
Swap: process (Data1, Data2, sel) begin case sel is
when '0' => Data1Swap <= Data1; Data2Swap <= Data2;
when others => Data1Swap <= Data2; Data2Swap <= Data1;
end case; end process Swap; end Behave;
Compile this code. What
is the problem? Suggest a fix. Now write a testbench and test your code.
Have you considered all possibilities?
10.55 (***RTL,
30 min.) "RTL stands for register-transfer level. ...when referencing
VHDL, the term means that the description includes only concurrent signal
assignment statements and possibly block statements. In particular, VHDL
data flow descriptions explicitly do not contain either process statements
(which describe behavior) or component instantiation statements (which describe
structure)" (Dr. VHDL from VHDL International).
With your knowledge
of process statements and components, comment on Dr. VHDL's explanation.
In less than 100 words
offer your own definition of the difference between RTL, data flow, behavioral,
and structural models.
10.56 (*Operators
mod and rem , 20 min.) Confirm and explain the
following:
i1 := (-12) rem 7; -- i1 = -5
i2 := 12 rem (-7); -- i2 = 5
i3 := (12) rem (-7); -- i3 = -5
i4 := 12 mod 7; -- i4 = 5
i5 := (-12) mod 7; -- i5 = 2
i6 := 12 mod (-7); -- i6 = -2
i7 := (12) mod (-7); -- i7 = -5
Evaluate -5 rem
2 and explain the result.
10.57 (***Event
and stable, 60 min.) Investigate the differences between clk'EVENT
and clk'STABLE . Write a minitutorial (in the form of a "cheat
sheet") with examples showing the differences and potential dangers
of using clk'STABLE .
10.58 (PREP benchmark
#2, 60 min.) The following code models a benchmark circuit used by PREP
to measure the capacity of FPGAs. Rewrite the concurrent signal assignment
statements (labeled mux and comparator) as equivalent processes. Draw a
datapath schematic corresponding to PREP2(Behave_1). Write a testbench for
the model. Finally (for extra credit) rewrite the model and testbench to
use STD_LOGIC instead of BIT types.
library ieee; use ieee.STD_LOGIC_1164.all;
use ieee.NUMERIC_BIT.all; use ieee.NUMERIC_STD.all;
entity PREP2 is
port(CLK,Reset,Sel,Ldli,Ldhi : BIT; D1,D2 : STD_LOGIC_VECTOR(7 downto 0);
DQ:out STD_LOGIC_VECTOR(7 downto 0));
end;
architecture Behave_1 of PREP2 is
signal EQ : BIT; signal y,lo,hi,Q_i : STD_LOGIC_VECTOR(7 downto 0);
begin
outputDriver: Q <= Q_i;
mux: with Sel select y <= hi when '0', D1 when '1';
comparator: EQ <= '1' when Q_i = lo else '0';
register: process(Reset, CLK) begin
if Reset = '1' then hi <= "00000000"; lo <= "00000000";
elsif CLK = '1' and CLK'EVENT then
if Ldhi='1' then hi<=D2;end if;if Ldlo='1' then lo<=D2;end if;
end if;
end process register;
counter: process(Reset, CLK) begin
if Reset = '1' then Q_i <= "00000000";
elsif CLK = '1' and CLK'EVENT then
if EQ = '1' then Q_i <= y;
elsif EQ = '0' then Q_i <= Q_i + "00000001";
end if;
end if;
end process counter;
end;
10.59 (PREP #3,
state machine) Draw the state diagram for the following PREP benchmark (see
Problem 10.58). Is this a Mealy or Moore machine? Write a testbench and
test this code.
library ieee; use ieee.STD_LOGIC_1164.all;
entity prep3_1 is port(Clk, Reset: STD_LOGIC;
I : STD_LOGIC_VECTOR(7 downto 0); O : out STD_LOGIC_VECTOR(7 downto 0));
end prep3_1;
architecture Behave of prep3_1 is
type STATE_TYPE is (sX,s0,sa,sb,sc,sd,se,sf,sg);
signal state : STATE_TYPE; signal Oi : STD_LOGIC_VECTOR(7 downto 0);
begin
O <= Oi;
process (Reset, Clk) begin
if (Reset = '1') then state <= s0; Oi <= (others => '0');
elsif rising_edge(Clk) then
case state is
when s0 =>
if (I = X"3c") then state <= sa; Oi <= X"82";
else state <= s0; Oi <= (others => '0');
end if;
when sa =>
if (I = X"2A") then state <= sc; Oi <= X"40";
elsif (I = X"1F") then state <= sb; Oi <= X"20";
else state <= sa; Oi <= X"04";
end if;
when sb =>
if (I = X"AA") then state <= se; Oi <= X"11";
else state <= sf; Oi <= X"30";
end if;
when sc => state <= sd; Oi <= X"08";
when sd => state <= sg; Oi <= X"80";
when se => state <= s0; Oi <= X"40";
when sf => state <= sg; Oi <= X"02";
when sg => state <= s0; Oi <= X"01";
when others => state <= sX; Oi <= (others => 'X');
end case;
end if;
end process;
end;
10.60 (Edge detection,
30 min) Explain the construction of the IEEE 1164 function to detect the
rising edge of a signal, rising_edge(s) . List all the changes
in signal s that correspond to a rising edge.
function rising_edge (signal s : STD_ULOGIC) return BOOLEAN is
begin return
(s'EVENT and (To_X01(s) = '1') and (To_X01(s'LAST_VALUE) = '0')); end;
10.61 (*Real,
10 min.) Determine the smallest real in your VHDL environment.
10.62 (*Stop,
30 min.) How many ways are there to stop a VHDL simulator?
10.63 (*Arithmetic
package, 60 min.) Write a function for an arithmetic package to subtract
two's complement numbers. Create a test bench to check your function. Your
declarations in the package header should look like this:
type TC is array (INTEGER range <>) of STD_LOGIC;
function "-"(L : TC; R : TC) return TC;
10.64 (***Reading
documentation, hours) There are a few gray areas in the interpretation of
the VHDL-87 LRM some of which were clarified in the VHDL-93 revision. One
VHDL system has a "compatibility mode" that allows alternative
interpretations. For each of the following "issues" taken from
the actual tool documentation try to interpret what was meant, determine
the interpretation taken by your own software, and then rewrite the explanation
clearly using examples.
* "Unassociated
variable and signal parameters. Compatibility mode allows variable and signal
parameters to subprograms to be unassociated if they have a default value.
Otherwise, an error is generated."
Example answer: Consider
the following code:
package Util_2 is
procedure C(signal Clk : out BIT; signal P : TIME := 10 ns);
end Util_2;
package body Util_2 is
procedure C(signal Clk : out BIT; signal P : TIME := 10 ns) is
begin loop Clk <= '1' after P/2, '0' after P;
wait for P; end loop; end; end Util_2;
entity Test_Compatibility_1 is end; use work.Util_2.all;
architecture Behave of Test_Compatibility_1 is
signal v,w,x,y,z : BIT; signal s : TIME := 5 ns;
begin process variable v : TIME := 5 ns; begin
C(v, s); -- parameter s is OK since P is declared as signal
-- C(w, v); -- would be OK if P is declared as variable instead
-- C(x, 5 ns); -- would be OK if P is declared as constant instead
-- C(y); -- unassociated, an error if P is signal or variable
-- C(z,open); -- open, an error if P is signal or variable
end process; end;
The Compass Scout simulator
(which does not have a compatibility mode) generates an error during analysis
if a signal or variable subprogram parameter is open or unassociated (a
constant subprogram parameter may be unassociated or open).
* "Allow others
in an aggregate within a record aggregate. The LRM [7.3.2.2] defines nine
situations where others may appear in an aggregate. In compatibility
mode, a tenth case is added. In this case, others is allowed
in an aggregate that appears as an element association in a record element."
* " BIT'('1')
parsed as BIT ' ('1') . The tick ( '
) character is being used twice in this example. In the first case as an
attribute indicator, in the second case, to form a character literal. Without
the compatibility option, the analyzer adopts a strict interpretation of
the LRM, and without white space around the first tick, the fragment is
parsed as BIT '('1') , that is, the left parenthesis (
'(' ) is the character literal."
** "Generate
statement declarative region. Generate statements form their own declarative
region. In compatibility mode, configuration specifications will apply to
items being instantiated within a generate statement."
** "Allow type
conversion functions on open parameters. If a parameter is specified as
open, it indicates a parameter without an explicit association. In such
cases, the presence of a type conversion function is meaningless. Compatibility
mode allows the type conversion functions."
*** "Entity class
flexibility. Section [3.1.2] of the LRM defines the process of creating
a new integer type. The type name given is actually assigned to a subtype
name, related to an anonymous base type. This implies that the entity class
used during an attribute specification [LRM 5.1] should indicate subtype,
rather than type. Because the supplied declaration was type rather than
subtype, compatibility mode allows type."
*** "Allowing
declarations beyond an all/others specification. Section [5.1] of the LRM
states that the first occurrence of the reserved word all or
others in an attribute specification terminates the declaration
of the related entity class. The LRM declares that the entity/architecture
and package/package body library units form single declaration regions [LRM
10.1] that are the concatenation of the two individual library declarative
regions. For example, if a signal attribute specification with all
or others was specified in the entity, it would be impossible
to declare a signal in the architecture. In compatibility mode, this LRM
limitation is removed."
*** "User-defined
attributes on overloaded functions. In compatibility mode, user-defined
attributes are allowed to be associated with overloaded functions. Note:
Even in compatibility mode, there is no way to retrieve the different attributes."
10.65 (*1076 interpretations,
30 min.) In a DAC paper, the author writes: `It was experienced that (company
R) might have interpreted IEEE 1076 differently than (company S) did, e.g.
concatenations (&) are not allowed in "case selector" expressions
for (company S).' Can you use concatenation in your VHDL tool for either
the expression or choices for a case
statement?
10.66 (**Interface
declarations, 15 min.) Analyze the following and comment:
entity Interface_1 is
generic (I : INTEGER; J : INTEGER := I; K, L : INTEGER);
port (A : BIT_VECTOR; B : BIT_VECTOR(A'RANGE); C : BIT_VECTOR (K to L));
procedure X(P, Q : INTEGER; R : INTEGER range P to Q);
procedure Y(S : INTEGER range K to L);
end Interface_1;
10.67 (**Wait
statement, 10 min.) Construct the sensitivity set and thus the sensitivity
list for the following wait statement (that is, rewrite the
wait statement in the form wait on sensitivity_list until
condition ).
entity Complex_Wait is end;
architecture Behave of Complex_Wait is
type A is array (1 to 5) of BOOLEAN;
function F (P : BOOLEAN) return BOOLEAN;
signal S : A; signal i, j : INTEGER range 1 to 5;
begin process begin
wait until F(S(3)) and (S(i) or S(j));
end process;
end;
10.68 (**Shared
variables, 20 min.) Investigate the following code and comment:
architecture Behave of Shared_1 is
subtype S is INTEGER range 0 to 1; shared variable C : S := 0; begin
process begin C := C + 1; wait; end process;
process begin C := C - 1; wait; end process;
end;
10.69 (Undocumented
code and ranges, 20 min.) Explain the purpose of the following function
(part of a package from a well-known synthesis company) with a parameter
of type SIGNED. Write a testbench to check your explanation. Investigate
what happens when you call this function with a string-literal argument,
for example with the statement X <= IM("11100").
What is the problem and why does it happen? Rewrite the code, including
documentation, to avoid this problem.
type SIGNED is array (NATURAL range <> ) of BIT;
function IM (L : SIGNED) return INTEGER is variable M : INTEGER;
begin M := L'RIGHT-1;
for i in L'LEFT-1 downto L'RIGHT loop
if (L(i) = (not L(L'LEFT))) then M := i; exit; end if;
end loop; return M;
end;
10.70 (Timing
parameters, 20 min.) Write a model and a testbench for a two-input AND gate
with separate rising (tpLH) and falling (tpHL) delays using the following
interface:
entity And_Process is
generic (tpLH, tpHL : TIME); port (a, b : BIT; z : out BIT) end;
10.71 (Passive
code in entities, 30 min.) Write a procedure (CheckTiming, part of a package
Timing_Pkg ) to check that two timing parameters (tPLH and
tPHL) are both greater than zero. Include this procedure in a two-input
AND gate model ( And_Process ). Write a testbench to show your
procedure and gate model both work. Rewrite the entity for And_Process
to include the timing check as part of the entity declaration. You are allowed
to include passive code (no assignments to signals and so on) directly in
each entity. This avoids having to include the timing checks in each architecture.
10.72 (Buried
code, 30 min.) Some companies bury instructions to the software within their
packages. Here is an example of part of the arithmetic package from an imaginary
company called SissyN:
function UN_plus(A, B : UN) return UN is
variable CRY : STD_ULOGIC; variable X,SUM : UN (A'LEFT downto 0);
-- pragma map_to_operator ADD_UNS_OP
-- pragma type_function LEFT_UN_ARG
-- pragma return_port_name Z
begin
-- sissyn synthesis_off
if (A(A'LEFT) = 'X' or B(B'LEFT) = 'X') then SUM := (others => 'X');
return(SUM);
end if;
-- sissyn synthesis_on
CRY := '0'; X := B;
for i in 0 to A'LEFT loop
SUM(i) := A(i) xor X(i) xor carry;
CRY := (A(i) and X(i)) or (A(i) and CRY) or (CRY and X(i));
end loop; return SUM;
end;
Explain what this function
does. Can you now hazard a guess at what each of the comments means? What
are the repercussions of using comments in this fashion?
10.73 (*Deferred
constants, 15 min.) "If the assignment symbol ':=' followed
by an expression is not present in a constant declaration, then the declaration
declares a deferred constant. Such a constant declaration may only appear
in a package declaration. The corresponding full constant declaration, which
defines the value of the constant, must appear in the body of the package"
[VHDL 93LRM4.3.1.1].
package Constant is constant s1, s2 : BIT_VECTOR; end Constant;
package body Constant is
constant s0 : BIT_VECTOR := "00"; constant s1 : BIT_VECTOR := "01";
end Constant;
It is tempting to use
deferred constants to hide information. However, there are problems with
this approach. Analyze the following code, explain the results, and correct
the problems:
entity Deferred_1 is end; architecture Behave of Deferred_1 is
use work.all; signal y,i1,i2 : INTEGER; signal sel : INTEGER range 0 to 1;
begin with sel select y <= i1 when s0, i2 when s1; end;
10.74 (***Viterbi
code, days) Convert the Verilog model of the Viterbi decoder in Chapter 11
to VHDL. This problem is tedious without the help of some sort of Verilog
to VHDL conversion process. There are two main approaches to this problem.
The first uses a synthesis tool to read the behavioral Verilog and write
structural VHDL (the Compass ASIC Synthesizer can do this, for example).
The second approach uses conversion programs (Alternative System Concepts
Inc. at http://www.ascinc.com is one source). Some of these
companies allow you to e-mail code to them and they will automatically return
a translated version.
10.75 (*Wait
statement, 30 min.) Rewrite the code below using a single wait
statement and write a testbench to prove that both approaches are exactly
equivalent:
entity Wait_Exit is port (Clk : in BIT); end;
architecture Behave of Wait_Exit is
begin process begin
loop wait on Clk; exit when Clk = '1'; end loop;
end process;
end;
10.76 (Expressions,
10 min.) Explain and correct the problems with the following:
variable b : BOOLEAN; b := "00" < "11";
variable bv8 : BIT_VECTOR (7 downto 0) := "1000_0000";
10.77 (Combinational
logic using case statement, 10 min.) A Verilog user suggests
the following method to model combinational logic. What are the problems
with this approach? Can you get it to work?
entity AndCase is port (a, b : BIT; y : out BIT); end;
architecture Behave of AndCase is begin process (a , b) begin
case a & b is
when '1'&'1' => y <= '1'; when others => y <= '0';
end case;
end process; end;
10.78 (*Generics
and back-annotation, 60 min.)
Construct design
entities And_3(Behave), a two-input AND gate, and Xor_3(Behave)
, a two-input XOR gate. Include generic constants to model the propagation
delay from each input to the output separately. Use the following entity
declaration for And_3:
entity And_3 is port (I1, I2 : BIT; O : out BIT);
generic (I1toO, I2toO : DELAY_LENGTH := 0.4 ns); end;
Create and test a
package, P_1, that contains And_3 and Xor_3 as components.
Create and test a
design entity Half_Adder_3 (Structure_3) that uses P_1, with
the following interface:
entity Half_Adder_3 is port (X, Y : BIT; Sum, Carry : out BIT); end;
Modify and test the
architecture Structure_3 for Half_Adder_3 so that you can use the following
configuration:
configuration Structure_3 of Half_Adder_3 is
for Structure_3
for L1 : XOR generic map (0.66 ns,0.69 ns); end for;
for L2 : AND generic map (0.5 ns, 0.6 ns) port map (I2 => HI); end for;
end for; end;
10.79 (SNUG'95,
*60 min.) In 1995 John Cooley organized a contest between VHDL and Verilog
for ASIC designers. The goal was to design the fastest 9-bit counter in
under one hour using Synopsys synthesis tools and an LSI Logic vendor technology
library. The VHDL interface is as follows:
library ieee; use ieee.std_logic_1164.all;
-- use ieee.std_logic_arith.all; -- substitute your package here
entity counter is port (
data_in : in std_logic_vector(8 downto 0);
up : in std_logic;
down : in std_logic;
clock : in std_logic;
count_out : inout std_logic_vector(8 downto 0);
carry_out : out std_logic;
borrow_out : out std_logic;
parity_out : out std_logic ); end counter;
architecture example of counter is begin
-- insert your design here
end example;
The counter is positive-edge
triggered, counts up with up = '1' and down with down
= '1' . The contestants had the advantage of a predefined testbench
with a set of test vectors, you do not. Design a model for the counter and
a testbench. How confident are you that you have thoroughly tested your
model? (In the real contest none of the VHDL contestants managed to even
complete a working design in under one hour. In addition, the VHDL experts
that had designed the testbench omitted a test case for one of the design
specifications.)
10.80 (*A test
procedure, 45 min.) Write a procedure all (for a package test
) that serially generates all possible input values for a signal spaced
in time by a delay, dly . Use the following interface:
library ieee; use ieee.std_logic_1164.all; package test is
procedure all (signal SLV : out STD_LOGIC_VECTOR; dly : in TIME);
end package test ;
10.81 (Direct
instantiation, 20 min.) Write an architecture for a full-adder, entity Full_Adder_2,
that directly instantiates units And_2(Behave) and Xor_2(Behave). This is
only possible in a VHDL-93 environment.
entity And_2 is port (i1, i2 : BIT; y : out BIT); end;
entity Xor_2 is port (i1, i2 : BIT; y : out BIT); end;
entity Full_Adder_2 is port (a, b, c : BIT ; sum, cout : out BIT); end;
10.82 (**Shift
operators for 1164, 60 min.) Write a package body to implement the VHDL-93
shift operators, sll and srl, for the type STD_LOGIC_VECTOR. Use the following
package header:
package 1164_shift is
function "sll"(x : STD_LOGIC_VECTOR; n : INTEGER)
return STD_LOGIC_VECTOR;
function "srl"(x : STD_LOGIC_VECTOR; n : INTEGER)
return STD_LOGIC_VECTOR;
end package 1164_shift;
10.83 (**VHDL
wait statement, 60 min.) What is the problem with the following
VHDL code? Hint: You may need to consult the VHDL LRM.
procedure p is begin wait on b; end;
process (a) is begin procedure p; end process;
10.84 (**Null
range, 45 min.) A range such as 1 to -1 or 0 downto 1
is a null range ( 0 to 0 is a legal range). Write
a one-page summary on null ranges, including code examples. Is a null range
treated as an ascending or descending range?
10.85 (**Loops,
45 min.) Investigate the following issues with loops, including code examples
and the results of analysis and simulation:
Try to alter
the loop parameter within a loop. What happens?
What is the type of
the loop parameter?
Can the condition
inside a loop depend on a loop parameter?
What happens in a
for loop if the range is null?
Can you pass a loop
parameter out of a procedure as a procedure parameter?
10.86 (Signals
and variables, 30 min.) Write a summary on signals and variables, including
code examples.
10.87 (Type conversion,
60 min.) There are some very subtle rules involving type conversion, [VHDL 93LRM7.3.5]. Does the following
work? Explain the type conversion rules.
BV <= BIT_VECTOR("1111");
Chapter start Previous page Next page
|