Sei sulla pagina 1di 25

CircuitDesignandSimulationwithVHDL

2ndedition
VolneiA.Pedroni
MITPress,2010
Bookweb:www.vhdl.us

SamplesofExerciseSolutions
Version3

Coveredexercises:2.1,3.1,3.20,3.30,4.4,4.6,4.8,5.4,5.11,6.1,6.8,6.9,7.3,7.7,8.6,
9.6,10.1,10.11,10.12,11.6,11.15,12.2,12.13,13.5,14.10,15.3,16.3,16.6,17.3

CircuitDesignandSimulationwithVHDL,2ndedition,VolneiA.Pedroni,MITPress,2010SolutionstoSelectedExercises

Exercise2.1:Multiplexer
a)Code
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
19
20
21
22
23
24
25
26
27
28

--------------------------------------------------LIBRARY ieee;
USE ieee.std_logic_1164.all;
--------------------------------------------------ENTITY mux IS
PORT (
a, b: IN STD_LOGIC_VECTOR(7 DOWNTO 0);
sel: IN STD_LOGIC_VECTOR(1 DOWNTO 0));
x: OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END mux; --or END ENTITY;
--------------------------------------ARCHITECTURE example OF mux IS
BEGIN
PROCESS (a, b, sel)
BEGIN
IF (sel="00") THEN
x <= "00000000";
ELSIF (sel="01") THEN
x <= a;
ELSIF (sel="10") THEN
x <= b;
ELSE
x <= "ZZZZZZZZ";
END IF;
END PROCESS;
END example; --or END ARCHITECTURE;
---------------------------------------------------

b)Comments:
Lines23:Library/packagedeclarations.BecausethetypeSTD_LOGICisemployed,thepackagestd_logic_1164mustbe
included.Theothertwoindispensablelibraries(stdandwork)aremadevisiblebydefault.
Lines510:ENTITY,herenamedmux.
Lines79:Specificationsofallinputandoutputports(alloftypeSTD_LOGIC_VECTORinthisexample).
Lines1227:ARCHITECTURE,herenamedexample.
Lines1426:APROCESSwasemployedtoconstructthecircuit.Itssensitivitylist(line13)containsthesignalsa,b,and
sel,sowheneveroneofthesesignalschangesitsvaluetheprocessisrun.
Lines1625:Intheprocess,theIFstatementwasusedtoimplementthemuxtliplexer,accordingtothetruthtableof
figure2.9.
Lines1,4,11,28:Usedjusttoimprovecodereadability(theselinesseparatethethreefundamentalcodesections).

Exercise3.1:Possibledatatypes#1
s1
s2
s3
s4

<=
<=
<=
<=

'0';
'Z';
TRUE;
"01000";

--BIT, STD_(U)LOGIC, CHARACTER


--STD_LOGIC, CHARACTER
--BOOLEAN
--BIT_VECTOR, STD_(U)LOGIC_VECTOR, (UN)SIGNED, STRING

Exercise3.20:Typeconversionbyspecificfunctions

Figure3.10isveryhelpfultosolvethisexercise.Typecastingwasalsoincludedinsomecases(seefigure3.10ofthe
book).
a)INTEGERtoSLV:Functionconv_std_logic_vector(a,cs),fromthepackagestd_logic_arith.
b)BVtoSLV:Functionto_stdlogicvector(a,cs),fromthepackagestd_logic_1164.
c)SLVtoUNSIGNED:Functionunsigned(a),fromthepackagenumeric_stdorstd_logic_arith.
d)SLVtoINTEGER:Functionconv_integer(a,cs),fromthepackagestd_logic_signedorstd_logic_unsigned,orfunction
to_integer(a,cs),fromnumeric_std_unsigned.
e)SIGNEDtoSLV:Functionstd_logic_vector(a),fromthepackagenumeric_stdorstd_logic_arith,orfunction
conv_std_logic_vector(a,cs)fromstd_logic_arith.

CircuitDesignandSimulationwithVHDL,2ndedition,VolneiA.Pedroni,MITPress,2010SolutionstoSelectedExercises

Exercise3.30:Illegalassignments#3
a)s4(0)(0) <= s7(1,1,1);
b) s6(1) <= s4(1);
c)s1 <= "00000000";
d)s7(0)(0)(0) <= 'Z';
e)s2(7 DOWNTO 5) <= s1(2 DOWNTO
f)s4(1) <= (OTHERS => 'Z');
g)s6(1,1) <= s2;
h)s2 <= s3(1) AND s4(1);
i)s1(0 TO 1) <= (FALSE, FALSE);
j)s3(1) <= (3, 35, -8, 97);

--cause 1 (BIT x STD_LOGIC)


--cause 2 (pile of BIT_VECTOR x single BIT_VECTOR)
--cause 3 (individual values must be TRUE or FALSE)
--cause 4 (zero is invalid index) + cause 3 (wrong parenthesis)
0); --cause 1 (slice with BIT x slice with BOOLEAN)
--cause 3 ('Z' is an invalid value for BIT)
--cause 4 (correct index is s6(1)(1))
--invalid operator (for INTEGER) + cause 1 (type2 x INTEGER x BV)
--cause 4 (index of s1 must be downward)
--cause 2 (single INTEGER x pile of INTEGER)

Exercise4.4:Logicaloperators

a) a(7 DOWNTO
b) a(7 DOWNTO
c) "1111" NOR
d) b(2 DOWNTO

4) NAND "0111" "1100"


4) XOR NOT b "1100"
b "0000" "0000"
0) XNOR "101" "101"

Exercise4.6:Arithmeticoperators#2

a)x REM y
b)x REM y
c)(x + 2*y) REM y
d)(x + y) REM x
e)x MOD y
f)x MOD y
g)-x MOD y
h)ABS(-y)

---------

=
=
=
=
=
=
=
=

65 (65/7)*7 = 2
65 (65/-7)*-7 = 2
(65 + 2*-7) = 51 51 (51/7)*7 = 2
72 (72/-7)*-7 = 2
x REM y = 2
(x REM y) + y = 2 7 = -5
x REM y = -65 (-65/-7)*-7 = -2
7

Exercise4.8:Shiftandconcatenationoperators
a) x
b) x
c) x
d) x
e) x

SLL
SLA
SRA
ROL
ROR

--"010000"

-2
2
1
-3

--"111100"
--"111100"
--"100101"
--"010110"

a) x(2 DOWNTO 0)
b) x(5) & x(5) &
c) x(5) & x(5) &
d) x(4 DOWNTO 0)
e) x(2 DOWNTO 0)

& "000";
x(5 DOWNTO 2);
x(5 DOWNTO 2);
& x(5);
& x(5 DOWNTO 3);

Exercise5.4:Genericparitygenerator

Noteinthecodebelowtheuseoftherecommendationintroducedinsection7.7.
1
2
3
4
5
6
7
8
9
10

----------------------------------------------ENTITY parity_generator IS
GENERIC (N: INTEGER := 8); --number of bits
PORT (
x: IN BIT_VECTOR(N-1 DOWNTO 0);
y: OUT BIT_VECTOR(N DOWNTO 0));
END ENTITY;
----------------------------------------------ARCHITECTURE structural OF parity_generator IS
SIGNAL internal: BIT_VECTOR(N-1 DOWNTO 0);

CircuitDesignandSimulationwithVHDL,2ndedition,VolneiA.Pedroni,MITPress,2010SolutionstoSelectedExercises

11
12
13
14
15
16
17
18

BEGIN
internal(0) <= x(0);
gen: FOR i IN 1 TO N-1 GENERATE
internal(i) <= internaL(i-1) XOR x(i);
END GENERATE;
y <= internal(N-1) & x;
END structural;
-----------------------------------------------

Exercise5.11:ArithmeticcircuitwithSTD_LOGIC

Noteinthesolutionbelowtheuseofthesignextensionrecommendationseeninsections3.18and5.7.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49

----------------------------------------------------------------------------LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.numeric_std.all;
----------------------------------------------------------------------------ENTITY adder IS
GENERIC (
N: NATURAL := 4); --number of bits
PORT (
a, b: IN STD_LOGIC_VECTOR(N-1 DOWNTO 0);
cin: IN STD_LOGIC;
opcode: IN STD_LOGIC_VECTOR(2 DOWNTO 0);
y: OUT STD_LOGIC_VECTOR(N-1 DOWNTO 0);
cout: OUT STD_LOGIC);
END ENTITY;
----------------------------------------------------------------------------ARCHITECTURE adder OF adder IS
--define internal unsigned signals:
SIGNAL a_unsig, b_unsig: UNSIGNED(N-1 DOWNTO 0);
SIGNAL y_unsig: UNSIGNED(N DOWNTO 0);
--define internal signed signals:
SIGNAL a_sig, b_sig: SIGNED(N-1 DOWNTO 0);
SIGNAL y_sig: SIGNED(N DOWNTO 0);
BEGIN
--convert inputs to unsigned:
a_unsig <= unsigned(a);
b_unsig <= unsigned(b);
--convert inputs to signed:
a_sig <= signed(a);
b_sig <= signed(b);
--implement circuit and convert to std_logic:
WITH opcode(1 DOWNTO 0) SELECT
y_unsig <= ('0' & a_unsig) + ('0' & b_unsig) WHEN "00",
('0' & a_unsig) - ('0' & b_unsig) WHEN "01",
('0' & b_unsig) - ('0' & a_unsig) WHEN "10",
('0' & a_unsig) + ('0' & b_unsig) + ('0' & cin) WHEN OTHERS;
WITH opcode(1 DOWNTO 0) SELECT
y_sig <= (a_sig(N-1) & a_sig) + (b_sig(N-1) & b_sig) WHEN "00",
(a_sig(N-1) & a_sig) - (b_sig(N-1) & b_sig) WHEN "01",
- (a_sig(N-1) & a_sig) + (b_sig(N-1) & b_sig) WHEN "10",
(a_sig(N-1) & a_sig) + (b_sig(N-1) & b_sig) + ('0' & cin) WHEN OTHERS;
WITH opcode(2) SELECT
y <= std_logic_vector(y_unsig(N-1 DOWNTO 0)) WHEN '0',
std_logic_vector(y_sig(N-1 DOWNTO 0)) WHEN OTHERS;
WITH opcode(2) SELECT
cout <= std_logic(y_unsig(N)) WHEN '0',
std_logic(y_sig(N)) WHEN OTHERS;
END ARCHITECTURE;
-----------------------------------------------------------------------------

Exercise6.1:Latchandflipflop

a)Seefigurebelow.

CircuitDesignandSimulationwithVHDL,2ndedition,VolneiA.Pedroni,MITPress,2010SolutionstoSelectedExercises

clk
d
q

clk
d
q

b)VHDLcodeandsimulation:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25

-----------------------------------LIBRARY ieee;
USE ieee.std_logic_1164.all;
-----------------------------------ENTITY example IS
PORT (
d, clk: IN STD_LOGIC;
q1, q2: OUT STD_LOGIC);
END ENTITY;
-----------------------------------ARCHITECTURE example OF example IS
BEGIN
PROCESS(clk, d)
BEGIN
---Latch:-------IF clk='1' THEN
q1 <= d;
END IF;
---Flip-flop:---IF clk'EVENT AND clk='1' THEN
q2 <= d;
END IF;
END PROCESS;
END ARCHITECTURE;
------------------------------------

Simulationresults:

Exercise6.8:Signalgenerator

clk
a
b
x

Twoadditionalwaveforms(a,b)wereincludedinthefigure.Notethatthereisabigdifferencebetweengeneratinga,b
versusx,y,becauseeachsignalintheformerpairchangesitsstatealwaysatthesameclockedge,soitsresolutionis
oneclockperiod,whileinthelatterpaireachsignalcanchangeatbothclocktransitions,sowitharesolutionequalto
onehalfofaclockperiod(whichisthemaximumresolutionindigitalsystems).Inthecodebelow,firstaandbare
generated,thentriviallogicgatesareemployedtoobtainxandy.Notethatthisimplementationisfreefromglitches
becauseonlytwosignalsenterthegates,andsuchsignalscanneverchangeatthesametime(theyoperateatdifferent
clockedges).

CircuitDesignandSimulationwithVHDL,2ndedition,VolneiA.Pedroni,MITPress,2010SolutionstoSelectedExercises

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22

---------------------------------------ENTITY signal_generator IS
PORT (
clk: IN BIT;
x, y: OUT BIT);
END ENTITY;
---------------------------------------ARCHITECTURE arch OF signal_generator IS
BEGIN
PROCESS(clk)
VARIABLE a, b: BIT;
BEGIN
IF clk'EVENT AND clk='1' THEN
a := NOT a;
ELSIF clk'EVENT AND clk='0' THEN
b := NOT a;
END IF;
x <= a AND b;
y <= a NOR b;
END PROCESS;
END ARCHITECTURE;
----------------------------------------

Exercise6.9:Switchdebouncer
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34

----------------------------------------------------LIBRARY ieee;
USE ieee.std_logic_1164.all;
----------------------------------------------------ENTITY debouncer IS
GENERIC(
fclk: NATURAL := 50;
--clock freq in MHz
twindow: NATURAL := 10);
--time window in ms
PORT (
sw: IN STD_LOGIC;
clk: IN STD_LOGIC;
deb_sw: BUFFER STD_LOGIC);
END ENTITY;
----------------------------------------------------ARCHITECTURE digital_debouncer OF debouncer IS
CONSTANT max: NATURAL := 1000 * fclk * twindow;
BEGIN
PROCESS (clk)
VARIABLE count: NATURAL RANGE 0 TO max;
BEGIN
IF (clk'EVENT AND clk='1') THEN
IF (deb_sw /= sw) THEN
count := count + 1;
IF (count=max) THEN
deb_sw <= sw;
count := 0;
END IF;
ELSE
count := 0;
END IF;
END IF;
END PROCESS;
END ARCHITECTURE;
-----------------------------------------------------

Exercise7.3:Latchesandflipflops

d
clk

q
rst

(a) Latch with reset

d
clk

q
clr

(b) Flip-flop with clear

d
clk

q
clr

(c) Latch with clear

CircuitDesignandSimulationwithVHDL,2ndedition,VolneiA.Pedroni,MITPress,2010SolutionstoSelectedExercises

Code1:ThisisaDtypelatchwithasynchronousreset(figure(a)above).Notethat,contrarytoflipflop
implementations,dneedstobeinthesensitivitylistbecausethecircuitistransparentduringawholesemiperiodof
theclock,notjustduringtheclocktransition.(Eventhoughthecompilermightunderstand,fromthecontext,thata
latchiswantedevenifdisnotinthesensitivitylist,thatisnotagoodpractice.)

Code2:NowwehaveaDtypeflipflopinsteadofaDtypelatch(notethe'EVENTattribute).Becauseresetisonly
activatedwhena(positive)clockedgeoccurs,itissynchronous;sinceinourcontextanasynchronousresetisanactual
reset,whileasynchronousresetisindeedaclearsignal,thepropercircuitisthatoffigure(b).

Code3:Thisisanexampleofbaddesign.Inprinciple,itseemsthatalatchwithcleariswanted,likethatinfigure(c).
However,becauseonlyclkisinthesensitivitylist,theprocesswillonlyberunwhenclkchanges,whichemulatesthe
behaviorofaflipflop.Insummary,theflipflopoffigure(b)mightbeinferred.

Exercise7.7:Registeredcircuits

a)Codeanalysis:
Code1isa8x1multiplexer(8inputs,1biteach),implementedbyline14,followedbyaonebitregister.Henceonly
oneDFFisneeded.Thecompiledcircuitisshowninfigure(a)below.
Code2istheopposite,thatis,itcontainsaregister(8bits,so8DFFsareneeded,inferredbylines1416)followedby
an8x1mux(line17).Thecompiledcircuitisinfigure(b).
Code3issimilartocode1.Theonlydifferenceisthatnointernalsignalwasusedtoimplementthemultiplexer(itwas
implementeddirectlyinline14).Hencethecircuitisthatoffigure(a),withoneDFF.

b)Compilation:Theinferredcircuitsareinthefigurebelow.

c)Codes1and3implementthesamecircuit.Thehardwaresinferredfromthesetwocodesareexactlythesame,so
fromtheimplementationpointofviewtherearenodifferencesbetweenthem.However,code3ismorecompact
(generallypreferred),whilesomemightfindcode1clearertounderstandthatamux,followedbyaregister,isthe
wantedcircuit.

(a)

(b)

Exercise8.6:SynchronouscounterwithCOMPONENT

a
b

'1'

'1'

clk
clk

q0

q1

q2

a)Thestandardcellisillustratedonthelefthandsideofthefigureabove.AcorrespondingVHDLcodefollows,using
method1.

1
2
3
4
5
6
7

----The component:-------------------------ENTITY counter_cell IS


PORT (
clk, a, b: IN BIT;
c, q: BUFFER BIT);
END ENTITY;
--------------------------------------------

CircuitDesignandSimulationwithVHDL,2ndedition,VolneiA.Pedroni,MITPress,2010SolutionstoSelectedExercises

8
9
10
11
12
13
14
15
16
17
18
19
20

ARCHITECTURE counter_cell OF counter_cell IS


SIGNAL d: BIT;
BEGIN
PROCESS (clk, a, b)
BEGIN
c <= a AND b;
d <= c XOR q;
IF clk'EVENT AND clk='1' THEN
q <= d;
END IF;
END PROCESS;
END ARCHITECTURE;
--------------------------------------------

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26

----Main code:--------------------------------------------------------ENTITY N_bit_counter IS


GENERIC (
N: NATURAL := 4); --number of bits
PORT (
clk: IN BIT;
q: OUT BIT_VECTOR(0 TO N-1));
END ENTITY;
----------------------------------------------------------------------ARCHITECTURE structural OF N_bit_counter IS
SIGNAL a, b: BIT_VECTOR(0 TO N);
--component declaration:-COMPONENT counter_cell IS
PORT (
clk, a, b: IN BIT;
c, q: BUFFER BIT);
END COMPONENT;
BEGIN
a(0)<='1';
b(0)<='1';
gen: FOR i IN 0 TO N-1 GENERATE
counter: counter_cell PORT MAP (clk, a(i), b(i), a(i+1), b(i+1));
END GENERATE;
q <= b(1 TO N);
END ARCHITECTURE;
-----------------------------------------------------------------------

b)Havingseenthecodeformethod1,doingitformethod3isstraightforward(seeexample8.4).

Exercise9.6:Functionbcd_to_ssd

Seethefunctioninteger_to_ssdinsection2.5.TheASSERTstatementcanbebasedonthatinexercise9.1.

Exercise10.1:Generationofperiodicstimuli

Allthreesignalsaredepictedinthefigurebelow,followedbyaVHDLcodethatproducesallthree.
NotethattheWAITFORstatementwasusedinthissolution.ThereaderisinvitedtoredoitusingAFTER.Whichis
simplerinthiscase?

sig1

period=75ns

sig2
period=200ns

y
period=80ns

1
2
3
4
5

---------------------------------------------LIBRARY ieee;
USE ieee.std_logic_1164.all;
---------------------------------------------ENTITY stimuli_generator IS

CircuitDesignandSimulationwithVHDL,2ndedition,VolneiA.Pedroni,MITPress,2010SolutionstoSelectedExercises

END ENTITY;
---------------------------------------------ARCHITECTURE testbench OF stimuli_generator IS
SIGNAL sig1, sig2, y: STD_LOGIC;
BEGIN
PROCESS
BEGIN
--signal sig1:-sig1 <= '1';
WAIT FOR 25ns;
sig1 <= '0';
WAIT FOR 50ns;
--signal sig2:-sig2 <= '1';
WAIT FOR 25ns;
sig2 <= '0';
WAIT FOR 50ns;
sig2 <= '1';
WAIT FOR 25ns;
sig2 <= '0';
WAIT FOR 25ns;
sig2 <= '1';
WAIT FOR 50ns;
sig2 <= '0';
WAIT FOR 25ns;
--signal y:-y <= '1';
WAIT FOR 20ns;
y <= '0';
WAIT FOR 10ns;
y <= '1';
WAIT FOR 10ns;
y <= '0';
WAIT FOR 40ns;
END PROCESS;
END ARCHITECTURE;
----------------------------------------------

6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42

Exercise10.11:TypeItestbenchforanaddressdecoder

Thesimulationstimuli(enaandaddress)tobeusedinthisexercisearethoseofexample2.4(figure2.7),repeatedin
thefigurebelow.Theexpectedfunctionalresponse(wordline)derivedfromthemisalsoincludedinthefigure.

ena

address

wordline

11111111

11111110

11111101

11111011

11110111

11101111

11011111

10111111

01111111

11111110

Acorrespondingdesignfile(address_decoder.vhd)ispresentednext.NoticethatonlySTD_LOGICdata(lines810)was
employed,whichistheindustrystandard.Observealsothatthiscodeistotallygeneric;toimplementanaddress
decoderofanysize,theonlychangeneededisinline7.

Thecircuitcanbedesignedinseveralways.Here,concurrentcode(withGENERATEandWHEN)wasemployed.
Anotheroptioncanbeseeninthesolutionsforthe1steditionofthebook.
1
2
3
4
5
6
7
8
9
10
11
12

-----Design file (address_decoder.vhd):----------------LIBRARY ieee;


USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
-------------------------------------------------------ENTITY address_decoder IS
GENERIC (
N: NATURAL := 3); --number of input bits
PORT (
ena: STD_LOGIC;
address: IN STD_LOGIC_VECTOR(N-1 DOWNTO 0);
wordline: OUT STD_LOGIC_VECTOR(2**N-1 DOWNTO 0));

CircuitDesignandSimulationwithVHDL,2ndedition,VolneiA.Pedroni,MITPress,2010SolutionstoSelectedExercises

13
14
15
16
17
18
19
20
21
22
23
24
25

10

END ENTITY;
-------------------------------------------------------ARCHITECTURE decoder OF address_decoder IS
SIGNAL addr: NATURAL RANGE 0 TO 2**N-1;
BEGIN
addr <= CONV_INTEGER(address);
gen: FOR i IN 0 TO 2**N-1 GENERATE
wordline(i) <= '1' WHEN ena='0' ELSE
'0' WHEN i=addr ELSE
'1';
END GENERATE;
END ARCHITECTURE;
--------------------------------------------------------

VHDLcodeforatypeItestbench(fileaddress_decoder_tb.vhd)isshownnext.Theinputwaveformsarethoseinthe
previousfigure,withT=80ns(line9).Thecodeconstructionissimilartothatseeninsection10.8(example10.4).The
statementinline34guaranteesthatafteracertaintime(800nsinthisexampleseeline10)thesimulationwillend.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

-----Testbench file (address_decoder_tb.vhd):--------------------------LIBRARY ieee;


USE ieee.std_logic_1164.all;
USE ieee.std_logic_unsigned.all;
-----------------------------------------------------------------------ENTITY address_decoder_tb IS
GENERIC (
N: NATURAL := 3;
--# of bits at input
T: TIME := 80 ns;
--stimulus period
Tfinal: TIME := 800 ns); --end of simulation time
END ENTITY;
-----------------------------------------------------------------------ARCHITECTURE testbench OF address_decoder_tb IS
--Signal declarations:---SIGNAL ena_tb: STD_LOGIC := '0';
SIGNAL address_tb: STD_LOGIC_VECTOR(N-1 DOWNTO 0) := (OTHERS => '0');
SIGNAL wordline_tb: STD_LOGIC_VECTOR(2**N-1 DOWNTO 0); --from circuit
--DUT declaration:-------COMPONENT address_decoder IS
PORT (
ena: STD_LOGIC;
address: IN STD_LOGIC_VECTOR(N-1 DOWNTO 0);
wordline: OUT STD_LOGIC_VECTOR(2**N-1 DOWNTO 0));
END COMPONENT;
BEGIN
--DUT instantiation:-----dut: address_decoder PORT MAP (ena_tb, address_tb, wordline_tb);
--Generate enable:
ena_tb <= '1' AFTER T;
--Generate address:------PROCESS
BEGIN
WAIT FOR T;
WHILE NOW<Tfinal LOOP --this loop could be unconditional
WAIT FOR T;
IF (address_tb < 2**N-1) THEN
address_tb <= address_tb + 1;
ELSE
address_tb <= (OTHERS => '0');
END IF;
END LOOP;
END PROCESS;
END ARCHITECTURE;
------------------------------------------------------------------------

Simulationresults(fromModelSim)areshowninthenextfigure.Notethat,beingitatypeI(thereforefunctional)
simulation,therearenopropagationdelaysbetweenthetransitionsofaddress_tbandwordline_tb.Observealsothat
theresultproducedbythecircuit(wordline_tb)doesmatchtheexpectedresult(wordline)showninthepreviousfigure.

CircuitDesignandSimulationwithVHDL,2ndedition,VolneiA.Pedroni,MITPress,2010SolutionstoSelectedExercises

11

Exercise10.12:TypeIVtestbenchforanaddressdecoder

Note:Beforeexaminingthissolution,pleasereadtheitemAdditionalDetailsonTypeIVSimulationintheExtra
Materiallinkofthebookwebsite.

Thesimulationstimuli(enaandaddress)tobeusedinthisexercisearethoseofexample2.4(figure2.7),repeatedin
thefigurebelow.Fromthem,theexpectedfunctionalresponse(idealwordline,wlideal)isthatalsoincludedinthefigure,
alreadyseeninthesolutiontoexercise10.11.Thelastwaveform(worstcasewordline,wlwc)isthesignalexpectedto
beproducedbythecircuit,whichwillbeusedasareferencetodefinethecomparisonpointsandstabilitytest
intervals.

ena

address
wlideal
wlwc

11111111

11111110

11111101

11111011

11110111

11101111

11011111

10111111

01111111

11111110

11111111

11111110

Tafter
tpmax
Tbefore

11111101

11111011

compare

11110111

11101111

check stability

11011111

10111111

01111111

11111110

no-sampling region

Thedesignfile(address_decoder.vhd)isthesameseeninthepreviousexercise.Acorrespondingtestbenchfile
(address_decoder_tb.vhd)fortypeIVsimulationispresentedbelow.Themaximumpropagationdelayforthedevice
usedinthisproject(aCycloneIIFPGA,fromAltera,synthesizedwithQuartusII;forXilinxdevices,ISEwouldbethe
naturalchoice)wasapproximately13ns,sotpmax=15nswasadopted(line10).Thestimulus(address)periodis80ns
(line9),andbothtimemarginsare1ns(lines1112).Thetotalsimulationtimeis800ns(line13).

Thesimulationprocedureisthatdescribedinchapter10andappendixD(mustincludetheSDFanddelayannotated
files).Seesection10.11andexample10.6foradditionaldetails.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27

--Testbench file (address_decoder_tb.vhd)-----------------------------------------------Note 1: Because GENERIC parameters cannot be passed to the .vho file, if the value of
--N below must be changed, then the design must be resynthesized to get a new .vho file.
LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
--------------------------------------------------------------------------------------ENTITY address_decoder_tb IS
GENERIC (
N: NATURAL := 3;
--# of bits at input (see Note 1 above)
T: TIME := 80 ns;
--stimulus period
tpmax: TIME := 15 ns;
--maximum propagation delay
Tbefore: TIME := 1 ns;
--time margin before transition
Tafter: TIME := 1 ns;
--time margin after transition
Tfinal: TIME := 800 ns); --end of simulation
END ENTITY;
--------------------------------------------------------------------------------------ARCHITECTURE testbench OF address_decoder_tb IS
--Constant and signal declarations:---------CONSTANT T1: TIME := Tpmax + Tafter;
--16ns
CONSTANT T2: TIME := T - T1 - Tbefore; --63ns
SIGNAL ena_tb: STD_LOGIC := '0';
SIGNAL address_tb: STD_LOGIC_VECTOR(N-1 DOWNTO 0) := (OTHERS => '0');
SIGNAL wordline_ideal: STD_LOGIC_VECTOR(2**N-1 DOWNTO 0) := (OTHERS => '1'); --ideal
SIGNAL wordline_tb: STD_LOGIC_VECTOR(2**N-1 DOWNTO 0); --actual circuit output
--DUT declaration:--------------------------COMPONENT address_decoder IS --see Note 1 above

CircuitDesignandSimulationwithVHDL,2ndedition,VolneiA.Pedroni,MITPress,2010SolutionstoSelectedExercises

28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74

12

PORT (
ena: STD_LOGIC;
address: IN STD_LOGIC_VECTOR(N-1 DOWNTO 0);
wordline: OUT STD_LOGIC_VECTOR(2**N-1 DOWNTO 0));
END COMPONENT;
BEGIN
--DUT instantiation (see Note 1 above):-----dut: address_decoder PORT MAP (ena_tb, address_tb, wordline_tb);
--Generate enable:--------------------------ena_tb <= '1' AFTER T;
--Generate address + expected ideal output:-PROCESS
VARIABLE count: NATURAL RANGE 0 TO 2**N-1 := 0;
BEGIN
WAIT FOR T;
WHILE NOW<Tfinal LOOP --this loop could be unconditional
address_tb <= conv_std_logic_vector(count, N);
wordline_ideal <= (count=>'0', OTHERS=>'1');
WAIT FOR T;
IF (count < 2**N-1) THEN
count := count + 1;
ELSE
count := 0;
END IF;
END LOOP;
END PROCESS;
--Comparison + stability test:--------------PROCESS
BEGIN
IF (NOW<Tfinal) THEN
WAIT FOR T1;
ASSERT (wordline_tb=wordline_ideal)
REPORT "Error: Signal values are not equal!"
SEVERITY FAILURE;
WAIT FOR T2;
ASSERT wordline_tb'STABLE(T2)
REPORT "Error: Signal is unstable!"
SEVERITY FAILURE;
WAIT FOR Tbefore;
ELSE
ASSERT FALSE
REPORT "END OF SIMULATION: No error found!"
SEVERITY FAILURE;
END IF;
END PROCESS;
END ARCHITECTURE;
-----------------------------------------------------------------

Simulationresultsaredepictedinthefigurebelow.Observethattheactualoutput(wordline_tb)doesexhibit
propagationdelays(oftheorderof13nsforthechosendevice)aftercorrespondingaddress(address_tb)transitions.

Thefollowing(veryimportant)challengesarelefttothereader:
1)Toplaywiththetestbenchfile.Forexample,whathappensifthevalueoftpmaxisreducedtoavaluebelowtheactual
propagationdelay(say,8ns)?Andwhathappensifline60ischangedtoASSERT wordline_tb'STABLE(T2 + 5
ns)...?
2)ToincludeintheASSERTstatementsthecodeneededforthesimulatortodisplaythetimevalueandthesignal
valuesincaseanerrorisfound(asinexample10.6).

CircuitDesignandSimulationwithVHDL,2ndedition,VolneiA.Pedroni,MITPress,2010SolutionstoSelectedExercises

13

Exercise11.6:Signalgenerator#2

cont<19
clk
output

cont<39
cont=19

20 T0

40 T0

OutputLow

OutputHigh

(output=0)

(output=1)

T=60T0

cont=39

a)Thestatetransitiondiagramisincludedinthefigureabove.A0to39counterwaschosentocontrolthestate
transitions(itcountsfrom0to19inonestate,hence20clockperiods,then0to39intheotherstate,thus40clock
cycles),butrecallthatanycounterwith40stateswoulddo[Pedroni2008].Anotheroptionwouldbetousea60state
counter,whichwouldonlyberesetafterreaching59.AVHDLcodeforthestatemachineshowninthefigureis
presentedbelow.Becausetheoutputcoincideswiththestaterepresentation(thatis,output=pr_state),theoutput
comesdirectlyfromaflipflop,sothecircuitisautomaticallyglitchfree.(Suggestion:toeasetheinspectionofthe
simulationresultsuse2and4insteadof20and40forthegenericparametersPulsesLowandPulsesHigh,respectively.)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45

------------------------------------------------------------------ENTITY signal_generator IS
GENERIC (
PulsesLow: NATURAL := 20;
--time in state OutputLow
PulsesHigh: NATURAL := 40);
--time in state OutputHigh
PORT (
clk, rst: IN BIT;
output: OUT BIT);
END ENTITY;
------------------------------------------------------------------ARCHITECTURE fsm OF signal_generator IS
TYPE state IS (OutputLow, OutputHigh);
SIGNAL pr_state, nx_state: state;
SIGNAL number_of_pulses: NATURAL RANGE 0 TO PulsesHigh;
BEGIN
----Lower section of FSM:----------PROCESS (rst, clk)
VARIABLE count: NATURAL RANGE 0 TO PulsesHigh;
BEGIN
IF (rst='1') THEN
pr_state <= OutputLow;
ELSIF (clk'EVENT AND clk='1') THEN
count := count + 1;
IF (count=number_of_pulses) THEN
count := 0;
pr_state <= nx_state;
END IF;
END IF;
END PROCESS;
----Upper section of FSM:----------PROCESS (pr_state)
BEGIN
CASE pr_state IS
WHEN OutputLow =>
output <= '0';
number_of_pulses <= PulsesLow;
nx_state <= OutputHigh;
WHEN OutputHigh =>
output <= '1';
number_of_pulses <= PulsesHigh;
nx_state <= OutputLow;
END CASE;
END PROCESS;
END ARCHITECTURE;
-------------------------------------------------------------------

Exercise11.15:FSMwithembeddedtimer#2

Firstweneedtoclarifythediagramabove.Therearetwooptionsforthetimedtransitions(BCandCA).TakingtheBC
transition,forexample,thespecificationscanbetheasfollows.

CircuitDesignandSimulationwithVHDL,2ndedition,VolneiA.Pedroni,MITPress,2010SolutionstoSelectedExercises

14

i)Themachinemuststaytime1secondsinBandthenevaluatex;ifx=2afterthattimeinterval,thenthemachinemust
proceedtostateC.
ii)Thevalueofxmustbex=2foratleasttime1seconds;therefore,ifxchangesitsvaluebeforetime1hasbeen
completed,thetimecountingmustrestart.
Bothoptionscanoccur,dependingontheapplication.Inthepresentsolution,wewillconsiderthatcase(ii)iswanted.
AcorrespondingVHDLcodefollows.Notethatbecausethepr_state<=nx_state;assignmentonlyoccurswhenall
conditionsaremet,thereisnoneedforspecifyingothernextstatesbesidestheactualnextstateineachstate
specifications(thatis,instateA,theonlypossiblenextstateisB;inB,itisC;andinC,itisA).
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63

-----------------------------------------------------------LIBRARY ieee;
USE ieee.std_logic_1164.all;
-----------------------------------------------------------ENTITY fsm IS
GENERIC (
time1: NATURAL := 3; -- # of clock periods in B
time2: NATURAL := 4); -- # of clock periods in C
PORT (
clk, rst: IN STD_LOGIC;
x: IN NATURAL RANGE 0 TO 3;
y: OUT STD_LOGIC);
END ENTITY;
-----------------------------------------------------------ARCHITECTURE fsm OF fsm IS
TYPE state IS (A, B, C);
SIGNAL pr_state, nx_state: state;
ATTRIBUTE enum_encoding: STRING;
ATTRIBUTE enum_encoding OF state: TYPE IS "sequential";
SIGNAL T: NATURAL RANGE 0 TO time2;
SIGNAL input1, input2: NATURAL RANGE x'RANGE;
BEGIN
----Lower section of FSM:--------PROCESS (rst, clk)
VARIABLE count: NATURAL RANGE 0 TO time2;
BEGIN
IF (rst='1') THEN
pr_state <= A;
ELSIF (clk'EVENT AND clk='1') THEN
IF (x=input1 OR x=input2) THEN
count := count + 1;
IF (count=T) THEN
count := 0;
pr_state <= nx_state;
END IF;
ELSE
count := 0;
END IF;
END IF;
END PROCESS;
----Upper section of FSM:--------PROCESS (pr_state, x)
BEGIN
CASE pr_state IS
WHEN A =>
y <= '1';
T <= 1;
input1<=0; input2<=1;
nx_state <= B;
WHEN B =>
y <= '0';
T <= time1;
input1<=2; input2<=2;
nx_state <= C;
WHEN C =>
y <= '1';
T <= time2;
input1<=3; input2<=3;
nx_state <= A;
END CASE;
END PROCESS;
END ARCHITECTURE;
-----------------------------------------------------------

CircuitDesignandSimulationwithVHDL,2ndedition,VolneiA.Pedroni,MITPress,2010SolutionstoSelectedExercises

15

Theviewproducedbythestatemachineviewer(withtheenum_encodingattributecommentedout)isshownbelow.

Simulationresults:

Exercise12.2:CounterwithLCDdisplay

AVHDLcodeforthisproblemispresentedbelow.Thecodefortheup/downcounter,with0.5secondsineachstate,is
shownexplicitly,whilethepartsalreadyseeninexamplesinthebookarejustindicated.Theclockfrequency(entered
asagenericparameter)wasassumedtobe50MHz.(Suggestion:Seefirstthedesigninsection12.2.)
1
2
3
4
5
6
7
8

-----Package with function:----------------------------------------------LIBRARY ieee;


USE ieee.std_logic_1164.all;
PACKAGE my_functions IS
FUNCTION integer_to_lcd (SIGNAL input: NATURAL) RETURN STD_LOGIC_VECTOR;
... (insert function integer_to_lcd seen in sec. 12.2)
END my_functions;
--------------------------------------------------------------------------

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32

------Main code:---------------------------------------------------------LIBRARY ieee;


USE ieee.std_logic_1164.all;
USE work.my_functions.all;
-------------------------------------------------------------------------ENTITY counter_with_LCD IS
GENERIC (
fclk: POSITIVE := 50_000_000;
--clock frequency (50MHz)
clk_divider: POSITIVE := 50_000);
--for LCD clock (500Hz)
PORT (
clk, rst, up: IN STD_LOGIC;
RS, RW, LCD_ON, BKL_ON: OUT STD_LOGIC;
E: BUFFER STD_LOGIC;
DB: OUT STD_LOGIC_VECTOR(7 DOWNTO 0));
END ENTITY;
-------------------------------------------------------------------------ARCHITECTURE counter_with_LCD OF counter_with_LCD IS
TYPE state IS (FunctionSet1, FunctionSet2, FunctionSet3, FunctionSet4,
ClearDisplay, DisplayControl, EntryMode, WriteData, ReturnHome);
SIGNAL pr_state, nx_state: state;
SIGNAL counter_output: NATURAL RANGE 0 TO 15;
SIGNAL lcd_input: STD_LOGIC_VECTOR(7 DOWNTO 0);
BEGIN
-----Counter (up/down, 0.5s per state):----PROCESS (clk, rst, up)
VARIABLE counter1: INTEGER RANGE 0 TO fclk/2;
VARIABLE counter2: INTEGER RANGE 0 TO 15;
BEGIN
IF (rst='1') THEN
counter1 := 0;
IF (up='1') THEN counter2 := 0;
ELSE counter2 := 15;

CircuitDesignandSimulationwithVHDL,2ndedition,VolneiA.Pedroni,MITPress,2010SolutionstoSelectedExercises

33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62

16

END IF;
ELSIF (clk'EVENT AND clk='1') THEN
IF (up='1') THEN
IF (counter2 /= 15) THEN
counter1 := counter1 + 1;
IF (counter1=fclk/2) THEN
counter1 := 0;
counter2 := counter2 + 1;
END IF;
END IF;
ELSE
IF (counter2 /= 0) THEN
counter1 := counter1 + 1;
IF (counter1=fclk/2) THEN
counter1 := 0;
counter2 := counter2 - 1;
END IF;
END IF;
END IF;
END IF;
counter_output <= counter2;
END PROCESS;
-----LCD driver [Pedroni 2008]:---------lcd_input <= integer_to_lcd(counter_output);
LCD_ON <= '1'; BKL_ON <= '1';
PROCESS (clk)
... (insert code for LCD driver seen in sec. 12.2)
END PROCESS;
END ARCHITECTURE;
--------------------------------------------------------------------------

Exercise12.13:FrequencymeterwithGraycounter

Thesubjectofthisexerciseistheveryinterestingandimportantissueofclockdomaincrossing.Onlyabriefvisittothe
subjectispresentedhere,withthehelpofthefigurebelow.

clock domain 1 cross

clock domain 1 cross clock domain 2


data

d1

q1

d2

q2

data

data

clk1

d1

q1

d2

q2

d3

data

q3

clk1

clk2

clk2

(a)
clock domain 1

clk1

clock domain 2

over

over

gray
counter

q1

(b)
cross clock domain 2
over

d
q
register

clock domain 1
data
clk1

gray
counter

cross
over

clock domain 2
d2

q1

q2

d3

q3

data

clk2

clk2

(c)

(d)

Figure(a)showstwointerconnecteddomains.Theyoperatewithdistinct(asynchronouswithrespecttoeachother)
clocks,calledclk1andclk2.Theproblemthatmightoccuristheoccurrenceofapositiveedgeinclk2whiletheoutput
ofDFF1(q1)ischangingitsvalue;insuchacase,becausethesetup/holdtimesofDFF2arenotrespected,ametastable
state(astatebetween0and1,whichnormallytakesarelativelylongtimetosettle)canoccurattheoutputofDFF2
(dataoutput)

Thesimplestsynchronizerforclockdomaincrossingisdepictedinfigure(b);itconsistssimplyinaddingaregistertothe
originalcircuit,sothesignal(data)isnotreceivedwithmetastablestatesdownstream.Anotheralternativeisdepicted
in(c),whichisadequateforthecasewhendataistheoutputofacounter.Becauseinagraycounter[Pedroni2008]
onlyonebitchangesatatime,ifclk2activatestheregisterwhileitischangingitsvalue(thatis,whenthischange

CircuitDesignandSimulationwithVHDL,2ndedition,VolneiA.Pedroni,MITPress,2010SolutionstoSelectedExercises

17

occursduringthesetup+holdtimesoftheregister),atmostonebitwillbestoredwithincorrectvalue,sotheoutput
cannotbemorethanoneunitofftheactualvalue.This,however,doesnotpreventtheregisterfromproducinga
metastablestate,whichcanbecleanedusingthesamearrangementoffigure(b),thusresultingthecombined
implementationoffigure(d).

Intermsofhardwareusage,thesolutionwithasimplesynchronizer(figure(b))requiresjustanextraregister(thatis,N
flipflops,whereNisthenumberofbitsindata),whilethesolutionwithjustagraycounter(figure(c))doesnotrequire
additionalflipflops,butdoesrequireadditionalcombinationallogic(whichalsogrowswithN).Obviously,themore
completesolution(figure(d))requiresthesumofboth.

Astraightforwardimplementationforagraycounteristoimplementaregularsequentialcounterthenconvertits
outputtograycodeusingtheequationsbelow,wherebistheoutputfromthebinarycounterandgisthe
correspondinggrayrepresentation:

g(N1)=b(N1)

g(i)=b(i)b(i+1)fori=0,1,...,N2

Acorrespondingcircuitisshowninthefigurebelow(forN=4).

binary b3
counter
b2
clk
b1
b0

g3
g2
g1

gray
output

g0

Iftheapproachaboveisusedtoimplementthegraycounteroffigure(c),itrequiresN1twoinputXORgatesin
additiontothehardwarerequiredbytheregularcounter,whiletheregisterbasedsynchronizeroffigure(b)requiresN
flipflopsinadditiontotheregularimplementationoffigure(a).Thecombined(recommended)implementation(figure
(d))thenrequirestheinclusionofN1XORgatesandNflipflops.

Exercise13.5:ROMimplementedwithaHEXfile#1

Theonlychangesneededinthecodeofsection13.4,whichemployedCONSTANTtoimplementtheROM,areinthe
architecturedeclarations,replacingtheoriginaltextwiththatbelow:

ARCHITECTURE rom OF rom_with_hex_file IS


SIGNAL reg_address: INTEGER RANGE 0 TO 15;
TYPE memory IS ARRAY (0 TO 15) OF STD_LOGIC_VECTOR(7 DOWNTO 0);
SIGNAL myrom: memory;
ATTRIBUTE ram_init_file: STRING;
ATTRIBUTE ram_init_file OF myrom: SIGNAL IS "rom_contents.hex";
BEGIN

Remembertocreateaplaintextfilewiththecontentsbelow(seetheconstructionofMIFfilesinsection13.3),saved
withthenamerom_contents.hexintheworkdirectory:

: 10 0000 00 00 00 FF 1A 05 50 B0 00 00 00 00 00 00 00 00 11 C1
: 00 0000 01 FF

Exercise14.10:I2CinterfaceforanRTC

Note:Beforeexaminingthissolution,pleasereadthetopicAdditionalDetailsontheI2CInterfaceintheExtra
Materialpartofthebookwebsite.

PCF8563,PCF8573,PCF8583,andPCF8593arepartoftheNXPfamilyofRTC(realtimeclock)devices.Foravailability
reasons,theRTCemployedinthissolutionwasPFC8593,whichisanRTCwithclock/calendarplustimer/alarmoptions.

CircuitDesignandSimulationwithVHDL,2ndedition,VolneiA.Pedroni,MITPress,2010SolutionstoSelectedExercises

18

Theclock/calendarfeatureswereexploredinthisdesign,whicharesetusingthefirsteightmemorybytes,shownin
figure1.

Registername

Address

Control

Subseconds

Bit7

Bit6

Bit5

Bit4

Bit3

Bit2

Bit1

RTCsetup

1/10sec

1/100sec

Seconds

10sec

sec

Minutes

Hours

Year/Date

Weekday/Month

Timer

Bit0

10min
AM/
PM

12/
24

year
weekday

min
10hour

hour

10date

date

10mo

month

Timersetup

Figure1.FirsteightbytesofthePCF8593register.

IntheVHDLcode,theeightregistersabove(addressesfrom0to7)werefilledwiththefollowingvalues:
Control:00000000
Subseconds:00000000(0.00seconds)
Seconds:00000000(00seconds)
Minutes:00110000(30minutes)
Hours:00010100(14hours,24houroptionchosen)
Year/date:00000001(day01)
Weekday/month:00010001(month11=November)
Timer:00000000

Thesetupfortheexperimentsisshowninfigure2.

5V

MASTER
FPGA

5V
10
k

10
k

SCL
SDA

SLAVE
PCF
8593

GND

chip_rst
clk
rst
rd
wr

hours

minutes

seconds

32.768 kHz
crystal
1
2

chip_rst

GND

PCF
8593

5V

interrupt

SCL

SDA

ssd_10hour(6:0)
ssd_hour(6:0)
ssd_10min(6:0)
ssd_min(6:0)
ssd_10sec(6:0)
ssd_sec(6:0)

ack_error

GND

Figure2.Setupfortheexperiments.

VHDLcodeforthisexerciseispresentednext.Notethatdatawaswrittentoall8RTCregistersoffigure1,butonly
informationregardingseconds,minutes,andhourswasretrieved,whichillustratestheuseofdifferentstarting
addressesforwritingandreading.Notealsothattheinitialtime(14:30:00HH/MM/SS)wasenteredusingGENERIC,but
severalotherpossibilitiesexist.Finally,observethattheclockingschemeissimilartothatinsection14.4ofthebook,
butthatinAdditionalDetailsontheI2CInterfaceintheExtraMaterialpartofthebookwebsitewouldalsodo.
1
2
3
4
5
6
7

----Package with a function:------------------------------------------------------LIBRARY ieee;


USE ieee.std_logic_1164.all;
PACKAGE my_functions IS
FUNCTION bin_to_ssd (CONSTANT input: STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR;
END my_functions;
-----------------------------------------------------------------------------------

CircuitDesignandSimulationwithVHDL,2ndedition,VolneiA.Pedroni,MITPress,2010SolutionstoSelectedExercises

8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33

PACKAGE BODY my_functions IS


FUNCTION bin_to_ssd (CONSTANT input: STD_LOGIC_VECTOR) RETURN STD_LOGIC_VECTOR IS
VARIABLE output: STD_LOGIC_VECTOR(6 DOWNTO 0);
BEGIN
CASE input IS
WHEN "0000" => output:="0000001";
--"0" on SSD
WHEN "0001" => output:="1001111";
--"1" on SSD
WHEN "0010" => output:="0010010";
--"2" on SSD
WHEN "0011" => output:="0000110";
--"3" on SSD
WHEN "0100" => output:="1001100";
--"4" on SSD
WHEN "0101" => output:="0100100";
--"5" on SSD
WHEN "0110" => output:="0100000";
--"6" on SSD
WHEN "0111" => output:="0001111";
--"7" on SSD
WHEN "1000" => output:="0000000";
--"8" on SSD
WHEN "1001" => output:="0000100";
--"9" on SSD
WHEN "1010" => output:="0001000";
--"A" on SSD
WHEN "1011" => output:="1100000";
--"b" on SSD
WHEN "1100" => output:="0110001";
--"C" on SSD
WHEN "1101" => output:="1000010";
--"d" on SSD
WHEN "1110" => output:="0110000";
--"E" on SSD
WHEN OTHERS => output:="0111000";
--"F" on SSD
END CASE;
RETURN output;
END bin_to_ssd;
END PACKAGE BODY;
-----------------------------------------------------------------------------------

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47

----Main code:------------------------------------------------------------LIBRARY ieee;


USE ieee.std_logic_1164.all;
USE work.my_functions.all; --package with "integer_to_ssd" function.
--------------------------------------------------------------------------ENTITY rtc_i2c IS
GENERIC (
--System paramenters:
fclk: POSITIVE := 50_000; --Freq. of system clock (in kHz)
data_rate: POSITIVE := 100; --Desired I2C bus speed (in kbps)
slave_addr_for_write: STD_LOGIC_VECTOR(7 DOWNTO 0):= "10100010";
slave_addr_for_read: STD_LOGIC_VECTOR(7 DOWNTO 0) := "10100011";
initial_address_wr: STD_LOGIC_VECTOR(7 DOWNTO 0):= "00000000";
initial_address_rd: STD_LOGIC_VECTOR(7 DOWNTO 0):= "00000010";
--Values to store in the RTC memory (clock/calendar settings):
set_control: STD_LOGIC_VECTOR(7 DOWNTO 0):= "00000000";
set_subsec: STD_LOGIC_VECTOR(7 DOWNTO 0):= "00000000"; --0.00 sec
set_sec: STD_LOGIC_VECTOR(7 DOWNTO 0):= "00000000";
--00 sec
set_min: STD_LOGIC_VECTOR(7 DOWNTO 0):= "00110000";
--30 min
set_hour: STD_LOGIC_VECTOR(7 DOWNTO 0):= "00010100";
--14 h
set_date: STD_LOGIC_VECTOR(7 DOWNTO 0):= "00000001";
--01 day
set_month: STD_LOGIC_VECTOR(7 DOWNTO 0):= "00010001";
--11 November
set_timer: STD_LOGIC_VECTOR(7 DOWNTO 0):= "00000000");
PORT (
--Clock and control signals:
clk, rst, wr, rd: IN STD_LOGIC;
--I2C signals:
SCL: OUT STD_LOGIC;
SDA: INOUT STD_LOGIC;
--System outputs (to SSD displays):
chip_rst: OUT STD_LOGIC;
ssd_sec: OUT STD_LOGIC_VECTOR(6 DOWNTO 0);
--units of seconds
ssd_10sec: OUT STD_LOGIC_VECTOR(6 DOWNTO 0);
--tens of seconds
ssd_min: OUT STD_LOGIC_VECTOR(6 DOWNTO 0);
--units of minutes
ssd_10min: OUT STD_LOGIC_VECTOR(6 DOWNTO 0);
--tens of minutes
ssd_hour: OUT STD_LOGIC_VECTOR(6 DOWNTO 0);
--units of hours
ssd_10hour: OUT STD_LOGIC_VECTOR(6 DOWNTO 0); --tens of hours
ack_error: OUT STD_LOGIC); --to an LED
END ENTITY;
--------------------------------------------------------------------------------ARCHITECTURE fsm OF rtc_i2c IS
--General signals:
CONSTANT divider: INTEGER := (fclk/8)/data_rate;
SIGNAL timer: NATURAL RANGE 0 TO 8;
SIGNAL aux_clk, bus_clk, data_clk: STD_LOGIC;
SIGNAL wr_flag, rd_flag: STD_LOGIC;
SIGNAL sec: STD_LOGIC_VECTOR(7 DOWNTO 0);

19

CircuitDesignandSimulationwithVHDL,2ndedition,VolneiA.Pedroni,MITPress,2010SolutionstoSelectedExercises

48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122

SIGNAL min: STD_LOGIC_VECTOR(7 DOWNTO 0);


SIGNAL hour: STD_LOGIC_VECTOR(7 DOWNTO 0);
SHARED VARIABLE i: NATURAL RANGE 0 TO 7 := 0;
--State-machine signals:
TYPE state IS (
--Common write+read states:
idle, start_wr, slave_addr_wr, ack1, stop,
--Write-only states:
initial_addr_wr, ack2, wr_control, ack3, wr_subsec, ack4, wr_sec, ack5, wr_min, ack6,
wr_hour, ack7, wr_date, ack8, wr_month, ack9, wr_timer, ack10,
--Read-only states:
initial_addr_rd, ack11, start_rd, slave_addr_rd, ack12, rd_sec, ack13, rd_min, ack14,
rd_hour, no_ack);
SIGNAL pr_state, nx_state: state;
BEGIN
chip_rst <= NOT rst; --to reset the chip (pin 3)
-------Display signals:-------------------ssd_sec <= bin_to_ssd(sec(3 DOWNTO 0));
ssd_10sec <= bin_to_ssd(sec(7 DOWNTO 4));
ssd_min <= bin_to_ssd(min(3 DOWNTO 0));
ssd_10min <= bin_to_ssd(min(7 DOWNTO 4));
ssd_hour <= bin_to_ssd(hour(3 DOWNTO 0));
ssd_10hour <= bin_to_ssd("00" & hour(5 DOWNTO 4));
-------Auxiliary clock (400kHz):----------PROCESS (clk)
VARIABLE count1: INTEGER RANGE 0 TO divider;
BEGIN
IF (clk'EVENT AND clk='1') THEN
count1 := count1 + 1;
IF (count1=divider) THEN
aux_clk <= NOT aux_clk;
count1 := 0;
END IF;
END IF;
END PROCESS;
-------Bus & data clocks (100kHz):--------PROCESS (aux_clk)
VARIABLE count2: NATURAL RANGE 0 TO 3;
BEGIN
IF (aux_clk'EVENT AND aux_clk='1') THEN
count2 := count2 + 1;
IF (count2=0) THEN
bus_clk <= '0';
ELSIF (count2=1) THEN
data_clk <= '1';
ELSIF (count2=2) THEN
bus_clk <= '1';
ELSE
data_clk <= '0';
END IF;
END IF;
END PROCESS;
-------Lower section of FSM:--------------PROCESS (rst, data_clk)
VARIABLE error_flag: STD_LOGIC;
BEGIN
IF (rst='1') THEN
pr_state <= idle;
wr_flag <= '0';
rd_flag <= '0';
error_flag := '0';
i := 0;
--Enter data for I2C bus:
ELSIF (data_clk'EVENT AND data_clk='1') THEN
IF (i=timer-1) THEN
pr_state <= nx_state;
i := 0;
ELSE
i := i + 1;
END IF;
ELSIF (data_clk'EVENT AND data_clk='0') THEN
--Store data read from RTC memory:
IF (pr_state=rd_sec) THEN
sec(7-i) <= SDA;
ELSIF (pr_state=rd_min) THEN

20

CircuitDesignandSimulationwithVHDL,2ndedition,VolneiA.Pedroni,MITPress,2010SolutionstoSelectedExercises

123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197

min(7-i) <= SDA;


ELSIF (pr_state=rd_hour) THEN
hour(7-i) <= SDA;
END IF;
--Store write/read/error flags:
IF (pr_state=idle) THEN
wr_flag <= wr;
rd_flag <= rd;
ELSIF (pr_state=stop) THEN
wr_flag <= '0';
rd_flag <= '0';
ELSIF (pr_state=ack1 OR pr_state=ack2 OR pr_state=ack3 OR pr_state=ack4 OR
pr_state=ack5 OR pr_state=ack6OR pr_state=ack7 OR pr_state=ack8 OR pr_state=ack9
OR pr_state=ack10) THEN
error_flag := error_flag OR SDA;
END IF;
END IF;
ack_error <= error_flag;
END PROCESS;
-------Upper section of FSM:--------------PROCESS (pr_state, bus_clk, data_clk, wr_flag, rd_flag)
BEGIN
CASE pr_state IS
--common write-read states:
WHEN idle =>
SCL <= '1';
SDA <= '1';
timer <= 1;
IF (wr_flag='1' OR rd_flag='1') THEN
nx_state <= start_wr;
ELSE
nx_state <= idle;
END IF;
WHEN start_wr =>
SCL <= '1';
SDA <= data_clk; --or '0'
timer <= 1;
nx_state <= slave_addr_wr;
WHEN slave_addr_wr =>
SCL <= bus_clk;
SDA <= slave_addr_for_write(7-i);
timer <= 8;
nx_state <= ack1;
WHEN ack1 =>
SCL <= bus_clk;
SDA <= 'Z';
timer <= 1;
IF (wr_flag='1') THEN
nx_state <= initial_addr_wr;
ELSE
nx_state <= initial_addr_rd;
END IF;
--data-write states:
WHEN initial_addr_wr =>
SCL <= bus_clk;
SDA <= initial_address_wr(7-i);
timer <= 8;
nx_state <= ack2;
WHEN ack2 =>
SCL <= bus_clk;
SDA <= 'Z';
timer <= 1;
nx_state <= wr_control;
WHEN wr_control =>
SCL <= bus_clk;
SDA <= set_control(7-i);
timer <= 8;
nx_state <= ack3;
WHEN ack3 =>
SCL <= bus_clk;
SDA <= 'Z';
timer <= 1;
nx_state <= wr_subsec;
WHEN wr_subsec =>
SCL <= bus_clk;

21

CircuitDesignandSimulationwithVHDL,2ndedition,VolneiA.Pedroni,MITPress,2010SolutionstoSelectedExercises

198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272

SDA <= set_subsec(7-i);


timer <= 8;
nx_state <= ack4;
WHEN ack4 =>
SCL <= bus_clk;
SDA <= 'Z';
timer <= 1;
nx_state <= wr_sec;
WHEN wr_sec =>
SCL <= bus_clk;
SDA <= set_sec(7-i);
timer <= 8;
nx_state <= ack5;
WHEN ack5 =>
SCL <= bus_clk;
SDA <= 'Z';
timer <= 1;
nx_state <= wr_min;
WHEN wr_min =>
SCL <= bus_clk;
SDA <= set_min(7-i);
timer <= 8;
nx_state <= ack6;
WHEN ack6 =>
SCL <= bus_clk;
SDA <= 'Z';
timer <= 1;
nx_state <= wr_hour;
WHEN wr_hour =>
SCL <= bus_clk;
SDA <= set_hour(7-i);
timer <= 8;
nx_state <= ack7;
WHEN ack7 =>
SCL <= bus_clk;
SDA <= 'Z';
timer <= 1;
nx_state <= wr_date;
WHEN wr_date =>
SCL <= bus_clk;
SDA <= set_date(7-i);
timer <= 8;
nx_state <= ack8;
WHEN ack8 =>
SCL <= bus_clk;
SDA <= 'Z';
timer <= 1;
nx_state <= wr_month;
WHEN wr_month =>
SCL <= bus_clk;
SDA <= set_month(7-i);
timer <= 8;
nx_state <= ack9;
WHEN ack9 =>
SCL <= bus_clk;
SDA <= 'Z';
timer <= 1;
nx_state <= wr_timer;
WHEN wr_timer =>
SCL <= bus_clk;
SDA <= set_timer(7-i);
timer <= 8;
nx_state <= ack10;
WHEN ack10 =>
SCL <= bus_clk;
SDA <= 'Z';
timer <= 1;
nx_state <= stop;
--data-read states:
WHEN initial_addr_rd =>
SCL <= bus_clk;
SDA <= initial_address_rd(7-i);
timer <= 8;
nx_state <= ack11;
WHEN ack11 =>

22

CircuitDesignandSimulationwithVHDL,2ndedition,VolneiA.Pedroni,MITPress,2010SolutionstoSelectedExercises

273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331

23

SCL <= bus_clk;


SDA <= 'Z';
timer <= 1;
nx_state <= start_rd;
WHEN start_rd =>
SCL <= '1'; --or bus_clk;
SDA <= data_clk;
timer <= 1;
nx_state <= slave_addr_rd;
WHEN slave_addr_rd =>
SCL <= bus_clk;
SDA <= slave_addr_for_read(7-i);
timer <= 8;
nx_state <= ack12;
WHEN ack12 =>
SCL <= bus_clk;
SDA <= 'Z';
timer <= 1;
nx_state <= rd_sec;
WHEN rd_sec =>
SCL <= bus_clk;
SDA <= 'Z';
timer <= 8;
nx_state <= ack13;
WHEN ack13 =>
SCL <= bus_clk;
SDA <= '0';
timer <= 1;
nx_state <= rd_min;
WHEN rd_min =>
SCL <= bus_clk;
SDA <= 'Z';
timer <= 8;
nx_state <= ack14;
WHEN ack14 =>
SCL <= bus_clk;
SDA <= '0';
timer <= 1;
nx_state <= rd_hour;
WHEN rd_hour =>
SCL <= bus_clk;
SDA <= 'Z';
timer <= 8;
nx_state <= no_ack;
WHEN no_ack =>
SCL <= bus_clk;
SDA <= '1';
timer <= 1;
nx_state <= stop;
--Common write-read state:
WHEN stop =>
SCL <= bus_clk;
SDA <= NOT data_clk; --or '0'
timer <= 1;
nx_state <= idle;
END CASE;
END PROCESS;
END ARCHITECTURE;
-----------------------------------------------------------------------

Exercise15.3:Imagegenerationwithhardware#2(suninthesky)

Asmentionedabove,amajoradvantageofbreakingthevideointerfacesintostandardandnonstandardparts,asdone
inchapters1517,isthatmostofthedesignstaysalwaysthesame.Tosolvethepresentexercise,weonlyneedto
replacethecodeforPart2(imagegenerator)insection15.9withanewcode,forthenewimage,becausetherest
(controlsignals)remainthesame.Acodethatsolvesthisexerciseisshownbelow(justreplacelines78115ofthecode
insection15.9withthiscode).
1
2
3

-----------------------------------------------Part 2: IMAGE GENERATOR


----------------------------------------------

CircuitDesignandSimulationwithVHDL,2ndedition,VolneiA.Pedroni,MITPress,2010SolutionstoSelectedExercises

24

PROCESS (pixel_clk, Hsync, dena)


VARIABLE x: NATURAL RANGE 0 TO Hd;
VARIABLE y: NATURAL RANGE 0 TO Vd;
BEGIN
----Count columns:-------IF (pixel_clk'EVENT AND pixel_clk='1') THEN
IF (Hactive='1') THEN x := x + 1;
ELSE x := 0;
END IF;
END IF;
----Count lines:---------IF (Hsync'EVENT AND Hsync='1') THEN
IF (Vactive='1') THEN y := y + 1;
ELSE y := 0;
END IF;
END IF;
--Generate the image:----IF (dena='1') THEN
IF (((x-320)**2+(y-240)**2)<14400) THEN
R <= (OTHERS => '1');
G <= (OTHERS => '1');
B <= (OTHERS => '0');
ELSE
R <= (OTHERS => red_switch);
G <= (OTHERS => green_switch);
B <= (OTHERS => blue_switch);
END IF;
ELSE
R <= (OTHERS => '0');
G <= (OTHERS => '0');
B <= (OTHERS => '0');
END IF;
END PROCESS;
----------------------------------------------

4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37

Exercise16.3:Imagegenerationwithhardware#2(suninthesky)

Asmentionedabove,thesamecodeusedinsection16.7canbeemployedherebecauseitwasalreadyseparatedinto
standardandnonstandardparts.Takethecodeofsection16.7andreplaceitsPart1(imagegenerator)withacodefor
thenewimage,whichcanbeeasilywrittenbasedonthesolutiontoexercise17.3,shownahead.Recallthatthecircles
centermustbeatthecenterofthescreen,soitscoordinatesmustbeadjustedaccordingwiththeresolutionchosenfor
thedisplay.DonotforgettocreateafileforthePLL(seesections14.2and16.7).

Exercise17.3:Imagegenerationwithhardware#2(suninthesky)

Asseenintheexamplesofchapters1517,amajoradvantageofseparatingthevideointerfaceinstandardandnon
standardpartsisthatmostofthemstayalwaysthesame.Thusthecodeofsection17.4canbeusedhere,replacing
onlyPart1(imagegenerator)withthecodebelow.Obviously,becausetheimagegeneratorisinstantiatedinthemain
code,someadjustmentsmightbeneededinthedeclarationandinstantiationoftheimagegeneratorthere.Recallthat
thescreensizeis600800pixelsandthatthesunsradiusmustbe150pixels(seethefigurebelow).Donotforgetto
createafileforthePLL(seesections14.2and17.4).

Sun in the sky (600800)


150

switches
yellow

300

150

250

1
2
3

300

250

-----Image generator:-----------------------------------------LIBRARY ieee;


USE ieee.std_logic_1164.all;

CircuitDesignandSimulationwithVHDL,2ndedition,VolneiA.Pedroni,MITPress,2010SolutionstoSelectedExercises

4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48

--------------------------------------------------------------ENTITY image_generator IS
PORT (
red_switch, green_switch, blue_switch: IN STD_LOGIC;
clk50, Hsync, Vsync, Hactive, Vactive, dena: IN STD_LOGIC;
R, G, B: OUT STD_LOGIC_VECTOR(5 DOWNTO 0));
END image_generator;
--------------------------------------------------------------ARCHITECTURE image_generator OF image_generator IS
BEGIN
PROCESS (clk50, Hsync, dena)
VARIABLE x: INTEGER RANGE 0 TO 800;
VARIABLE y: INTEGER RANGE 0 TO 600;
BEGIN
--Count columns:-------------IF (clk50'EVENT AND clk50='1') THEN
IF (Hactive='1') THEN x := x + 1;
ELSE x := 0;
END IF;
END IF;
--Count lines:---------------IF (Hsync'EVENT AND Hsync='1') THEN
IF (Vactive='1') THEN y := y + 1;
ELSE y := 0;
END IF;
END IF;
--Generate the image:--------IF (dena='1') THEN
IF (((x-400)**2+(y-300)**2)<22500) THEN
R <= (OTHERS => '1');
G <= (OTHERS => '1');
B <= (OTHERS => '0');
ELSE
R <= (OTHERS => red_switch);
G <= (OTHERS => green_switch);
B <= (OTHERS => blue_switch);
END IF;
ELSE
R <= (OTHERS => '0');
G <= (OTHERS => '0');
B <= (OTHERS => '0');
END IF;
END PROCESS;
END image_generator;
--------------------------------------------------------------

25

Potrebbero piacerti anche