Sunteți pe pagina 1din 25

DIGITAL SYSTEM DESIGN

VHDL Coding for FPGAs


Unit 7
✓INTRODUCTION TO DIGITAL SYSTEM DESIGN:
▪ Digital System Components
▪ Use of generic map to map parameters.
▪ Example: Digital Stopwatch
▪ Example: Lights Pattern
▪ Embedding counters and registers in ASM diagrams.
Daniel Llamocca
✓ DIGITAL SYSTEM DESIGN
▪ Digital System Components:
▪ Finite State Machine, Datapath circuit
▪ Design Steps: Circuit Design, VHDL coding, Synthesis, Simulation,
Place and Route (also pin assignment), and FPGA Programming and
Testing.

DATAPATH CIRCUIT

Inputs
FINITE STATE Outputs
resetn MACHINE
clock
CONTROL CIRCUIT

Daniel Llamocca
✓EXAMPLE: STOPWATCH
▪ The Stopwatch that counts in increments of 1/100th of a second.
Circuit design and VHDL implementation.
▪ Inputs: Pause, resetn, clock
▪ Outputs: Count on four 7-segment displays
▪ Target Board: DIGILENT NEXYS-4 Board
resetn

pause DIGITAL
CIRCUIT
clock

seconds hundredths of a second

Daniel Llamocca
✓EXAMPLE: STOPWATCH
▪ Datapath design: We need four counters. Tree counters modulo-10
and one counter module-6.
resetn

Counter E BCD E BCD E BCD E


z modulo-6 z counter z counter z counter

clock
4 4 4 4

0-5 0-9 0-9 0-9


▪ The figure depicts a generic modulo-N counter, where 𝑛 = log 2 𝑁
TIMING DIAGRAM - COUNTER MODULO 10 (N=10, n = 4)

clock
resetn

n resetn
E COUNTER Q
modulo-N z
clock 0 to N-1 z
Q 0000 0000 0001 0010 0011 0100 0101 0110 0111 1000 1001 0000 0001
0 0 1 2 3 4 5 6 7 8 9 0 1

Daniel Llamocca
library ieee;
✓ DIGITAL COUNTER use ieee.std_logic_1164.all;
DESIGN use ieee.std_logic_unsigned.all;

▪ Counters are usually entity my_bcdcount is


designed as State port ( clock, resetn, E: in std_logic;
Q: out std_logic_vector(3 downto 0);
Machines. However, for z: out std_logic);
different counts, we end my_bcdcount;

need a different state architecture bhv of my_bcdcount is


machine. Moreover, if signal Qt: std_logic_vector(3 downto 0);
begin
the count is large, the process (resetn,clock,E)
FSM gets intractable. begin
if resetn = '0' then Qt <= "0000";
▪ More efficient manner: elsif (clock'event and clock='1') then
Think of them as if E = '1' then
if Qt = "1001"' then
accumulators. This way, Qt <= "0000";
the VHDL code is easier else
Qt <= Qt + "0001";
to read and modify (if end if;
we require a different end if;
end if;
count). end process;
z <= '1' when Qt = "1001" else '0';
▪ Example: BCD counter Q <= Qt;
Daniel Llamocca end bhv;
✓ COUNTER DESIGN: PARAMETRIC CODE
▪ The previous VHDL code allows for easy
parameterization of counters with arbitrary counts.
▪ Parametric VHDL code: The following VHDL code has a parameter
COUNT. This is the ‘my_genpulse.vhd’ code (Unit 5).
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
use ieee.math_real.log2.all;
use ieee.math_real_ceil.all;

entity my_genpulse is
generic (COUNT: INTEGER:= 10);
port ( clock, resetn, E: in std_logic;
Q: out std_logic_vector(integer(ceil(log2(real(COUNT))))-1 downto 0);
z: out std_logic);
end my_genpulse;

architecture bhv of my_genpulse is


constant nbits:= INTEGER:= integer(ceil(log2(real(COUNT))));
signal Qt: std_logic_vector(nbits - 1 downto 0);
...

Daniel Llamocca
✓ COUNTER DESIGN: PARAMETRIC CODE
▪ This parametric counter is not only useful to
generate pulses, but also to generate counters with any arbitrary
counts.
...
begin
process (resetn,clock,E)
begin
if resetn = '0' then Qt <= (others => '0');
elsif (clock'event and clock='1') then
if E = '1' then
if Qt = conv_std_logic_vector(COUNT-1,nbits) then
Qt <= (others => '0');
else
Qt <= Qt + conv_std_logic_vector(1,nbits);
end if;
end if;
end if;
end process;
z <= '1' when Qt = conv_std_logic_vector (COUNT-1, nbits) else '0';
Q <= Qt;
end bhv;

Daniel Llamocca
✓EXAMPLE: STOPWATCH
▪ Datapath design: A cascade interconnection allows the counters to
behave as desired.
pause

resetn

Counter E BCD E BCD E BCD E


z modulo-6 z counter z counter z counter
zC zB zA

clock
4 QD 4 QC 4 QB 4 QA

clock

resetn

pause

QA 0 0 1 2 3 4 5 6 7 8 9 0 1 2 3 3 4 5

zA
QB 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1

Daniel Llamocca
✓ EXAMPLE: STOPWATCH
▪ ‘pause’ input: If the user asserts this input, the count must freeze.
This is achieved by using not(pause) to enable all the counters.
▪ Note that it is possible to come up with this circuit by designing an
FSM that controls the four enable inputs of the counters.
▪ Timing diagram: note what needs to happen so that the third
counter (QC) increments its count.

clock

pause

QA 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1

zA
QB 8 8 8 8 8 8 9 9 9 9 9 9 9 9 9 9 0 0

zB
QC 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1

Daniel Llamocca
✓STOPWATCH DESIGN
▪ NEXYS-4 Board: 100 MHz clock. Thus, the
counter QA will increment its count every 10 ns.
▪ We want QA to increment its count every 0.01s (10 ms).
▪ Straightforward solution: Change the input clock to 100 Hz
(period 10 ms). This can be a hard problem if precise input clock
is required. If we modify the frequency using counters, we might
have FPGA clock skew since the 100 Hz clock will not go in the
clock tree (among other problems).
▪ Efficient solution: We use the counter that generates a pulse
every 10 ms. The output ‘z’ is then connected to every enable
input of the counters. This way, we get the same effect as
modifying the clock frequency to 100 Hz.
▪ The pulse is of duration of the input clock period (10 ns). To
generate a pulse every 10 ms, we need a counter that counts up
to (10ms/10ns) -1 = 106 -1. Note that our generic counter with
COUNT=106 allows for a quick implementation of this circuit.
Daniel Llamocca
✓STOPWATCH DESIGN
▪ Datapath circuit: The figure shows the stopwatch with the
counter up to 106 (named 0.01s counter).
▪ Note how the output ‘z’ of the 0.01s counter is now connected
to all the enables in the counters. This way we make sure that
every transition in the counter only occurs every 0.01 s (10 ms)

pause
E Counter z
z
(0.01s)

resetn

Counter E BCD E BCD E BCD E


z modulo-6 z counter z counter z counter

clock
4 4 4 4

Daniel Llamocca
✓STOPWATCH DESIGN
▪ Datapath circuit: Final system with four 7-segment decoders
so that the counter outputs can be seen in the displays.
pause
E z
Counter z
(0.01s)

resetn

Counter E BCD E BCD E BCD E


z modulo-6 z counter z counter z counter

clock
4 4 4 4

7-segment 7-segment 7-segment 7-segment


Decoder Decoder Decoder Decoder

7 7 7 7

Daniel Llamocca
✓STOPWATCH DESIGN
▪ NEXYS-4 Board: It has eight 7-segment displays, but all the
displays share the same inputs. We can also enable (negative
logic) a particular 7-segment display via the common anode
(see Seven Display section in NEXYS4 datasheet).
▪ Why do we have then eight 7-seg displays, if apparently all of
them will display the same pattern?
▪ OUTPUT SERIALIZATION: With an enable for each 7-segment
display, we can use one 7-segment display at a time. In order
for each digit to appear bright and continuously illuminated, we
illuminate each digit for only 1ms every 4 ms.
▪ We need only one 7-segment decoder, a Multiplexor, and an
FSM that control the selector of the multiplexor.
▪ If we want the multiplexor selector to transition only 1 ms every
4 ms, we connect the output ‘z’ of a new counter (to 0.001s,
COUNT = 105) to the enable input of the FSM.
▪ In our design, we only use four 7-segment displays.
Daniel Llamocca
✓STOPWATCH DESIGN
▪ Final Design: Datapath Circuit + FSM resetn=0
pause
E Counter z S1
z
(0.01s) s  00
resetn
0
E
Counter E BCD E BCD E BCD E
z modulo-6 z counter z counter z counter 1
S2
clock s  01
4 4 4 4

0
3 2 1 0 E

1
7-segment S3
Decoder Counter z s  10
(0.001s)

7 7 7 7 0
E
2
1
S4
s  11

1 0
E
s
EN(3) EN(2) EN(1) EN(0) 4 2-to-4 E
EN decoder FSM

Daniel Llamocca
✓STOPWATCH DESIGN
▪ FSM Timing Diagram:
clock

resetn

state S1 S1 S1 S2 S2 S2 S2 S3 S3 S3 S3 S4 S4

s 00 00 00 01 01 01 01 10 10 10 10 11 11

▪ Xilinx ISE Project:


▪ VHDL code: Instantiation (port map, generic map). For VHDL
styling, see other units in VHDL for FPGAs Tutorial.
▪ Simulation: Testbench. If 0.01s counter is omitted and z = E, we
can easily simulate the circuit. ➢ dig_stopwatch.zip:
dig_stopwatch.vhd,
▪ Place-and-Route (pin assignment) my_genpulse.vhd,
▪ FPGA programming and testing sevenseg.vhd,
tb_dig_stopwatch.vhd,
dig_stopwatch.ucf
Daniel Llamocca
✓USE OF generic map
▪ Digital system design: many VHDL components available, some as
parameterized VHDL code (for re-usability). So, when instantiating these
components into a top-level file, we both map the signals (port map) and
the parameters (generic map).

▪ StopWatch design: We need to instantiate six counters. Parametric VHDL


counter: my_genpulse.vhd. We have 3 counters modulo-10, 1 counter
modulo-6, 1 counter modulo-106, and 1 counter modulo-105.
▪ Here, we must use generic map (see dig_stopwatch.vhd. We first
declare my_genpulse.vhd in the top file:
...
architecture struct of dig_stopwatch is
...
component my_genpulse We copy what
generic (COUNT: INTEGER:= (10**8)/2); is in the entity of
port (clock, resetn, E: in std_logic; my_genpulse.vhd
Q: out std_logic_vector(integer(ceil(log2(real(COUNT))))-1 downto 0);
z: out std_logic);
end component;
...
begin
...
Daniel Llamocca
✓USE OF generic map
▪ The port map statement takes care of interconnecting the signals.
▪ The generic map statement maps the parameters. More than one
parameter can be mapped. my_genpulse only has one parameter:
generic map (parameter name in my_genpulse => parameter value in top file).
▪ Here, we map 5 counters, each with a different count.
▪ If parameters are not mapped, the parameter values in the component
declaration inside the architecture are assigned. This is a bad coding style:
we might need to use a component more than once in the design, each
time with different parameters.
...
gz: my_genpulse generic map(COUNT => 10**6) -- modulo-106 counter
port map(clock => clock, resetn =>resetn, E => npause, z => z);
g0: my_genpulse generic map(COUNT => 10) -- BCD counter
port map(clock => clock, resetn =>resetn, E => z, Q=>Q0,z=>z_0);
g1: my_genpulse generic map(COUNT => 10) -- BCD counter
port map(clock => clock, resetn =>resetn, E =>E_1,Q=>Q1,z=>z_1);
g2: my_genpulse generic map(COUNT => 10) -- BCD counter
port map(clock => clock, resetn =>resetn, E =>E_2,Q=>Q2,z=>z_2);
g3: my_genpulse generic map(COUNT => 6) -- modulo-6 counter
port map(clock => clock, resetn =>resetn, E =>E_3,Q=>Q3,z=>z_3);
...
end struct;
Daniel Llamocca
✓EXAMPLE: LIGTHS PATTERN
▪ Configurable lights’ pattern generator: sel: selects pattern, stop:
freezes the pattern. X: selects the rate at which lights’ pattern change
(every 1.5, 1.0, 0.5, or 0.25 s)
segs[7..0] : sel 2
8 segs
7 6
x 2
0

1
5

4
stop
resetn
?
2 3 clock
sel

00

01

10

11

Daniel Llamocca
✓EXAMPLE: LIGTHS PATTERN
▪ Entire System:
x stop sel
resetn
clock
Q ?? 2 2
On the NEXYS4, only one 7-segment
7 display can be used at a time
z dseg 0
0
8 8 7
counter (1.5s) D Q
E FINITE STATE
1 MACHINE Esg
E 7
1
Q ?? 2

3
z

counter (1.0s) Counter z


(0.001s)

E
Q ?? FINITE STATE 1-to-2 buf buf(1) buf(0)
MACHINE s decoder

z
counter (0.5s) x = 00 → Lights change every 1.5 s
x = 01 → Lights change every 1.0 s
x = 10 → Lights change every 0.5 s
Q ??
x = 11 → Lights change every 0.25 s

counter (0.25s)
Daniel Llamocca
✓EXAMPLE: LIGTHS PATTERN resetn=0

▪ FSMs:
S1

0
E resetn=0
1
S1
00 11
sel s0
01 10

dseg00000111, Esg1 dseg00000101, Esg1 dseg00010001, Esg1 dseg00110011, Esg1


0
E
S2a S2b S2c S2d

1
S2
0 0 0 0
E E E E s1
1 1 1 1

dseg00001110, Esg1 dseg00010100, Esg1 dseg00100010, Esg1 dseg11100111, Esg1 1 0


E
S3a S3b S3c S3d

0 0 0 0
E E E E
1 1 1 1

dseg00011100, Esg1 dseg01010000, Esg1 dseg01000100, Esg1 dseg11001100, Esg1


S4a S4b S4c S4d

0 0 0 0
E E E E
1 1 1 1
➢ lights_pattern.zip:
dseg00111000, Esg1 dseg01000001, Esg1 dseg10001000, Esg1 dseg11111001, Esg1
S5a S5d lights_pattern.vhd,
dseg01110000, Esg1
1
E
0
E
0 my_genpulse.vhd,
S6a 1
my_rege.vhd,
tb_lights_pattern.vhd,
dseg10000111, Esg1

0 1 S6d
E dseg11100000, Esg1

S7a
0
lights_pattern.ucf
E

1 0 1
dseg11000001, Esg1 E
dseg01111000, Esg1
S8a

0
E
1
Daniel Llamocca dseg10000011, Esg1
✓EMBEDDING COUNTERS AND
REGISTER IN ASM diagrams
▪ FSMs usually require counters and registers for proper control. In VHDL
code, this requires integrating the fsm description with port map/generic
map to instantiate the counters and registers.
▪ Example: digsys_ex: An FSM, a counter, a register, and a shift register.
▪ Asserting EQ or sclrQ can update the counter output Q, which can only be
updated (Q0, QQ+1) at the clock edge. For example: after asserting
EQ1, we must wait until the clock edge for QQ+1. For the register,
asserting ED  1 means that QD  D on the next clock cycle.
QD
4
S FSM
S1
resetn=0
Shift Register:
4 4
0
LEFT
SCLK  0
ES 1: After this signal is
D D Q

E
din
EL
dout
zQ
0
EQ  1 asserted, the shift register
ED
4
4 1 (Q  Q+1) shifts data on the next clock
ES

QS
LS

SCLK
EQ, sclrQ  1 (Q  0)
ED, ES, LS  1 (QD  D, QS  S)
cycle.
FSM
S2 ES 1, LS  1: After these 2
SCLK  1
signals are asserted, the shift
sclrQ
EQ

3
E Q Q
sclr z zQ
zQ
0 EQ  1
ES  1
(Q  Q+1) register will load parallel data
(shift QS)
counter
0 to 7
1 on the next clock
Daniel Llamocca
EQ, sclrQ  1 (Q  0) cycle.
✓EMBEDDING COUNTERS AND
REGISTER IN ASMs ➢ dig_sys_ex.zip: my_digsys_ex.vhd,
my_genpulse_sclr.vhd, my_rege.vhd,
▪ Timing diagram: digsys_ex. my_pashiftreg.vhd, tb_digsys_ex.vhd.

clk

resetn

D 1100 0101 1001 0101 1011

S 0110 1101 1001 1100 0111

EQ

sclrQ

Q 0 0 1 2 3 4 5 6 7 0 1 2 3 4 5 6 7 0 1

zQ

state S1 S1 S1 S1 S1 S1 S1 S1 S1 S2 S2 S2 S2 S2 S2 S2 S2 S1 S1

SCLK

ED

ES

LS

QD 0000 0101

QS 0000 1101 1010 0100 1000 0000

Daniel Llamocca
✓EMBEDDING COUNTERS AND
REGISTER IN ASM diagrams
▪ Alternative coding style: we can embed counters and registers inside
the ASM description in VHDL (no need of port map). Note that the
resulting circuit is not technically an FSM, since now some of the outputs
are registered. For digsys_ex, only SCLK is now a combinational output.
▪ Procedure: Include the statements to infer counters and registers in the
State Transitions process. We need to clear their outputs when resetn=0.
▪ New circuit: It is functionally the same as the previous circuit, but the
representation is different.
FSMemb resetn=0
S1
SCLK  0
Updated ASM Diagram (FSMemb): It is
QD S a bit misleading. The statements
4 4 Q=7
0
Q  Q+1 indicating updates to the counter,
D
4
4
SCLK 1
These statements register, and shift register outputs do not
FSMemb Q  0, QD  D,
take effect immediately, but rather on
QS are executed on the
QS  S clock edge

S2 Technically,
not an FSM the immediate clock edge.
SCLK  1

So, even though this representation can


Q  Q+1
be helpful, it can also be confusing.
0
Q=7
QS  QSx2
1

Q0
Daniel Llamocca
✓EMBEDDING COUNTERS AND
REGISTER IN ASM diagrams
▪ VHDL code: Use this coding style sparingly, as it is difficult to debug when
there are too many inferred counters and registers.
▪ The output signals QD, QS, sclk, behave exactly the same as in the original
digsys_ex circuit (the one with FSM and port map/generic map).
library ieee;
use ieee.std_logic_1164.all;
Note that Q is defined as an use ieee.std_logic_unsigned.all;
integer to simplify coding.
QSt: we need this auxiliary entity digsys_ex is
port ( clock, resetn: in std_logic;
signal as we cannot D,S: in std_logic_vector(3 downto 0);
feedback the output QS QD,QS: out std_logic_vector(3 downto 0);
back to the circuit (we need sclk: out std_logic);
this for shifting). end digsys_ex;

architecture bhv of digsys_ex is


type state is (S1, S2);
➢ dig_sys_exp.zip: signal y: state;
my_digsys_ex.vhd, signal Q: integer range 0 to 7;
tb_digsys_ex.vhd. signal QSt: std_logic_vector(3 downto 0);

begin
Daniel Llamocca ...
✓EMBEDDING COUNTERS AND
REGISTER IN ASM diagrams
...
Transitions: process (resetn, clock)
begin
if resetn = '0' then -- asynchronous signal
y <= S1; QD<="0000"; Q <= 0; QSt<="0000" -- values on reset
Note how easy elsif (clock'event and clock='1') then
case y is
it is to update a when S1 =>
counter, a if Q=7 then y<=S2; Q<=0; QD <= D; QSt <= S;
register, or shift else y<=S1; Q <= Q+1; end if;
when S2 =>
register. if Q=7 then y<=S1; Q<=0;
else
Do not forget to y<=S2; Q <= Q+1; QSt(0) <= '0';
assign the QSt(3 downto 1) <= QSt(2 downto 0);
values on reset. end if;
end case;
This avoids end if;
having to use end process;
Q <= QSt;
port map Outputs: process (y,Q)
instructions. begin
sclk <= '0';
case y is
when S1 =>
when S2 => sclk <= '1';
end case;
end process;
Daniel Llamocca end bhv;

S-ar putea să vă placă și