You are on page 1of 6

Exercises Set#2: VHDL

Create a new ISE project

1. Create a new ISE project in order to create the new source VHDL files that
will be necessary in the following exercises

Exercise 1

1. Copy the prescaler.vhd and pack_pract.vhd files from the tutorial, and add
them to the project, since they will be used in the next step.

2. Create a new VHDL Module file, named pulse_4.vhd which contains a


module pulse_4 (entity pulse_4, architecture beh1).
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;

entity pulse_4 is
port(
clk,rst: in std_logic;
width: in std_logic_vector(3 downto 0);
strt: in std_logic;
rdy: out std_logic;
e: in std_logic;
o: out std_logic );
end entity;

architecture beh1 of pulse_4 is


type T_STATE is (BUSY,START,IDLE);
signal state: T_STATE;
subtype T_CNT is unsigned(3 downto 0);
signal cnt: T_CNT;
begin
o<='1' when state=BUSY else '0';
rdy<='1' when state=IDLE else '0';

counter: process begin


wait until rising_edge(clk);
case state is
when IDLE=>
if strt='1' then cnt<=T_CNT(width); end if;
when others=>
if e='1' then cnt<=cnt-1; end if;
end case;
end process;

fsm: process begin


wait until rising_edge(clk);
case state is
when IDLE=>
if strt='1' then state<=START; end if;
when START=>
if e='1' then state<=BUSY; end if;
when BUSY=>
if e='1' and cnt=0 then state<=IDLE; end if;
end case;
if rst='1' then state<=IDLE; end if;
end process;
end architecture;
It is composed of two processes: one models a finite state machine (fsm) and
the other one models a down-counter (counter). The output port o generates a
pulse where the pulse-width can be changed with the 4-bit input port width(3:0).
The input port e should be connected to a prescaler with a configured NPS. For
instance, if NPS=5 and width(3:0)=”0111” (number 7 codified as unsigned), the
pulse-width=width*NPS=7*5=35 clock cycles. The strt and rdy ports are used
for handshake. The output port rdy is asserted (rdy=’1’) when the module is
ready to start, and the input port strt will start the pulse when it is asserted
(strt=’1’).

3. Add at the botton of the pulse.vhd the testbench tb_pulse_4 which attaches
an instance of the pulse_4 module (dut) with a prescaler instance (ps0)
configured with NPS=5.
-----------------------------------------
--synthesis translate_off
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;

entity tb_pulse_4 is
end entity;

architecture test of tb_pulse_4 is


constant TCLK: time:=10ns;
constant NBIT_WIDTH: integer:=4;
signal clk: std_logic:='1';
signal rst,dut_strt,dut_e,dut_o,dut_rdy: std_logic;
signal dut_width: std_logic_vector(NBIT_WIDTH-1 downto 0);
begin
clk<=not clk after TCLK/2;
rst<='0','1' after 5*TCLK,'0' after 10*TCLK;

process begin
dut_width<=(others=>'X'); dut_strt<='0';
wait until rst='1';
wait until rst='0';
wait for 5*TCLK;

for j in 0 to 2**NBIT_WIDTH-1 loop


dut_width<=std_logic_vector(conv_unsigned(j,NBIT_WIDTH));
dut_strt<='1'; wait for TCLK;
dut_strt<='0'; wait until dut_rdy='1';
end loop;

dut_width<=(others=>'X'); dut_strt<='0';
wait;
end process;

ps0: entity work.prescaler(a1d) generic map(5) port map(


clk=>clk, rst=>rst,
o=>dut_e );

dut: entity work.pulse_4(beh1) port map(


clk=>clk, rst=>rst,
strt=>dut_strt, rdy=>dut_rdy,
e=>dut_e,
o=>dut_o, width=>dut_width );
end architecture;
--synthesis translate_on

Among the ps0 and dut instances, the testbench contains a process which
changes the width(3:0) from “0000” to “1111” (from 0 to 15) , asserting strt=’1’
and incrementing width(3:0) when rdy=’1’, in order to simulate all the possible
pulse-widths.
4. Simulate the tb_pulse_4 for a long time in order to check that the output o is
working as expected (pulse-width=width*5) for every width(3:0) possible
combination.

5. The pulse-width at o is the expected one (pulse-width=width*5), except


when width(3:0)=”0000”. Justify the reason why the pulse_4 module do not
work as expected when width(3:0)=”0000”.

6. Modify the beh1 architecture of pulse_4,in order to get pulse-width=0 when


width(3:0)=”0000”. The modification should be done as easy as possible.
Write the modification in the report and justify it.

Exercise 2

1. Create a new pulse.vhd file, and copy and paste the content from
pulse_4.vhd to pulse.vhd.

2. The pulse_4 module declared the input port width(3:0) as a 4-bit port. Edit
pulse.vhd and rename the entity name as pulse, and add a generic (named
NBIT) to pulse in order to parametrize the number of bits of the pulse-width.
The pulse module should work as expected with an arbitrary number NBIT.
Write the modifications done in the report and justify them.

3. Rename the testbench in pulse.vhd as tb_pulse, and change it in order to


test the dut instance with NBIT=6. Write the modifications done in the report
and justify them.

4. Simulate the tb_pulse for a long time in order to check that the output o is
working as expected (pulse-width=width*NPS=width*5) for every width(5:0)
possible combination.
Exercise 3

1. Create a new architecture beh2 for the pulse entity. This architecture joins
the fsm and counter processes into a single process called fsm_counter.
The fsm sentences are identical. The counter sentences are very similar, but
the cnt is a variable instead of a signal.
fsm_counter: process
subtype T_CNT is unsigned(width'range);
variable cnt: T_CNT;
begin
wait until rising_edge(clk);
case state is --fsm (same sentences as in pulse-beh1)
when IDLE=>
...
when START=>
...
when BUSY=>
...
end case;
if rst='1' then ... end if;

case state is --counter (very similar as in pulse-beh1)


when IDLE=>
if strt='1' then ...; end if;
when others=>
if e='1' then ...; end if;
end case;
end process;

2 Simulate the beh2 in the tb_pulse. Check if the simulation results are the
same as for the beh1 architecture? Justify the answer

3 Create a new architecture beh3 for the pulse entity, which is very similar to
the beh2 architecture, but reversing the set of fsm and counter sentences.
fsm_counter: process
subtype T_CNT is unsigned(width'range);
variable cnt: T_CNT;
begin
wait until rising_edge(clk);
case state is --counter
when IDLE=>
if strt='1' then ...; end if;
when others=>
if e='1' then ...; end if;
end case;

case state is --fsm


when IDLE=>
...
when START=>
...
when BUSY=>
...
end case;
if rst='1' then ... end if;
end process;

4 Simulate the beh3 in the tb_pulse. Check if the simulation results are the
same as for the beh1 architecture? Justify the answer
5 Modify the process fsm_counter (beh2 or beh3, in the different one) in order
to behave as the beh1 architecture (do not change the cnt from variable to
signal, and maintain separately the assignation sentences of the cnt variable
form the state signal). Report the changes done and justity them.

Exercise 4

1. Create a top.vhd file, in order to synthetize the pulse module for the LX9
Microboard. The top module should contain a pulse circuit attached to the
switches or buttons of the board, one of the leds. The ps_o is assigned to ‘1’
(instead to the output of a prescaler) in order to test only the synthesis of the
pulse.
entity top is
port(
clk,rst: in std_logic;
switches: in std_logic_vector(3 downto 0);
led: out std_logic );
end entity;

architecture arch of top is


signal ps_o,rdy: std_logic;
begin
pulse0: entity work.pulse(beh1b) generic map(switches'length) port map(
clk=>clk, rst=>rst,
e=>ps_o,
strt=>rdy, rdy=>rdy,
o=>led, width=>switches );

ps_o<='1';
-- ps0: entity work.prescaler(a1d) generic map(10e+6) port map(
-- clk=>clk, rst=>rst, o=>ps_o );
end architecture;

2. Check the synthesis results of beh1, beh2 and beh3. Justify the results

3. Create a new architecture beh1b for pulse, which is quite similar to beh1 but
using integer type for the signal cnt, instead of unsigned type.

architecture beh1b of pulse is


... --same as beh1
subtype T_CNT is integer;
signal cnt: T_CNT;
begin
o<=...; --same as beh1
rdy<=...; --same as beh1

fsm: process begin


... –-same as beh1
end process;

counter: process begin


... -–same as beh1, except the cnt assignment when strt=’1’
if strt='1' then cnt<=conv_integer(unsigned(width)); end if;
end process;
end architecture;

4. Check the simulation results when compared with beh1. Justify the results
5. Check the synthesis result when compared with beh1. Justify the results

6. Change the T_CNT declaration of beh1b as in the following code, and


repeat the previous two questions
subtype T_CNT is integer range 0 to 2**NBIT-1;

You might also like