Exercises 3
Exercises 3
1. Create a new project named Exercises_3, and copy into the project folder
the files prescaler.vhd and pack_pract.vhd. Add the previous source VHDL
files to the project
2. Create a new VHDL source file named display.vhd in the current project, in
order to develop the VHDL description of the display module.
DISPLAY Module
The DISPLAY module controls the 4-digit 7-segment (and a dot segment)
display of the interface board. The input port data[15:0] contains the 16-bit
number which is visualized in the four digits of the display. The input port
dot[3:0] individually enables or disables each of the dots at the right of every
digit. For instance, when data[15:0]=0xA20F (0x means hexadecimal format)
and dot[3:0]=”1010”, the display shows A.20.F
DISPLAY
16 8
data segments
4
dot
en 4
digits
rst
a
f b
e c
d
dp
The segments and dots of the four digits are short-circuited between them in the
interface board (see the schematic of the interface board). The output port
segments[7:0]= {a,b,c,d,e,f,g,dp} attaches to the segments of all the digits. Each
digit is enabled or disabled individually with the output port digits[3:0], where
digits[3] is the left-side digit and digit[0] the right-side one. The control of the
segments[7:0] and digits[3:0] is negated logic. For instance, the next Figure
shows the control done by the DISPLAY module to visualize a 4-bit number in
one of the digits
digits[3.0]=“1011”
3 2 1 0
a b c d e f g dp a b c d e f g dp a b c d e f g dp a b c d e f g dp
segments[7:0]={a,b,c,d,e,f,g,dp}=“00100101”
entity display is
port(
clk: in std_logic;
rst: in std_logic;
en: in std_logic;
data: in std_logic_vector(15 downto 0);
dot: in std_logic_vector(3 downto 0);
digits: out std_logic_vector(3 downto 0);
segments: out std_logic_vector(7 downto 0) );
end entity;
architecture a1 of display is
process begin
wait until rising_edge(clk);
...—assign idx to count from 3 to 0 (repeatedly)
end process;
end architecture;
----------------------------------------------------------------------
-- synthesis translate_off
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
entity tb_display is
end entity;
-- synthesis translate_on
Exercise 2: PWM Module
1. Create a new VHDL source file named pwm.vhd in the current project, in
order to develop the VHDL description of the PWM module
2. Execute the given testbench to verify the functionality of the PWM module
when NPWM=4, and it attaches to a pre-scaler with NPS=10 on a system
providing a clock fCLK=40 MHz. The testbench automatically changes the
d[NPWM+1:0] in all the possible combinations. Run the functional simulation
to test the correct PWM functionality.
3. Change the testbench to test the PWM when NPWM=8 in order to get
fPWM=5KHz when fCLK=100 MHz. Execute the testbench to test the correct
PWM functionality with the new conditions.
PWM Module
The circuits generates a pulse width modulated (PWM) signal according the
required duty-cycle (D) which is periodically repeated at fPWM frequency. The
range of the duty-cycle is from 0 to 1 (0 D 1).
TPWM=1/fPWM
DTPWM
The PWM can be easily described using a NPWM-bit counter cnt[NPWM-1:0] which
runs 2Npwm counts from 0 to 2Npwm-1 continuously. For instance, when NPWM=4,
the cnt[3:0] counts from 0 to 15 (16 counts, from “0000” to “1111” in binary
format) on every PWM cycle. The en input port enables the counter to
increment its count synchronously with the clock input. Since the enable port is
connected to a pre-scaler output, the counter increments the count every
NPS*TCLK. Therefore, the PWM frequency is:
1 1
= = =
2 ∙ ∙ 2 ∙
For instance, when NPWM=4, NPS=10 and fCLK=40 MHz (TCLK=25 ns), the
fPWM=250 KHz (TPWM=16*10*25 ns=4000 ns=4 µs).
The number of bits of the input port d[NPWM:0] is NPWM+1 in order to achieve the
range from d=0 (D=0) to d>=2Npwm (D=1). Otherwise, if d were a NPWM-bit port,
the PWM could not reach D=1 since it would be limited to a maximum
D=(2Npwm-1)/2Npwm. For instance, when NPWM=4, d=0 (“0_0000” in binary)
generates a D=0/16=0 PWM output, d=15 (“0_1111” in binary) generates a
D=15/16 =0.9375 PWM output, and D=16 (“1_0000” in binary) generates a
D=16/16=1. Since the maximum D=1, the PWM circuit must saturate the output
(D=1) when d ≥ 2Npwm (”1_XXXX” in binary).
This way, the duty-cycle generated by the PWM circuit is (d is the natural
number coded in the d[NPWM:0] port):
; ≤2 −1
= 2
1 ; ≥2
To generate the PWM output, the natural number contained in the counter
cnt[NPWM-1:0] is compared against the natural number coded in the input port
d[NPWM:0]. A combinational circuit could generate the PWM output to q=‘1’ when
cnt < d, and q=‘0’ when cnt ≥ d. However, since the output q is connected to a
motor driver, a combinational circuit may generate undesired glitches.
TPWM=16*NPS*TCLK d(4:0)
q D=0/16=0.0 0 0000
q D=1/16=0.0625 0 0001
q D=4/16=0.25 0 0100
q 0 1000
D=8/16=0.5
q
D=12/16=0.75 0 1100
q D=15/16=0.9375 0 1111
q D=16/16=1.0 1 XXXX
cnt=d
The q_new output is a signal which is asserted (q_new=’1’) during a single
clock cycle (TCLK) just before starting a new PWM period. It will be used later to
synchronize the rest of the system with the PWM module. This signal is also
used by the testbench to change the d port (the requested duty-cycle)
TPWM
q_new
TCLK TCLK
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
entity pwm is
generic(
NPWM: integer:=8 );
port(
clk: in std_logic;
rst: in std_logic;
en: in std_logic;
d: in std_logic_vector(NPWM downto 0);
q: out std_logic;
q_new: out std_logic );
end entity;
architecture a1 of pwm is
signal cnt_0, cnt_d: std_logic;
signal q_int: std_logic;
signal cnt: unsigned(NPWM-1 downto 0);
begin
q<=q_int;
end architecture;
------------------------------------------------------------------------------
-- synthesis translate_off
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
entity tb_pwm is
end entity;
end architecture;
-- synthesis translate_on