Solutions to homework 04 and 05

------

-- Module Name: SWTS_SSD - Behavioral

-- Project Name: SWTS_TO_SSD.ise

-- Target Devices: NEXYS2 board

-- Tool versions: ISE 10.1

-- Description: The Hex value of the buttons is displayed on the rightmost

-- disits of the seven segment display. The complement of the

-- buttons is displayed on the two left seven segment display

-- digits. Pressing a button will blank its digit.

-- Dependencies: n_parts_v0.vhd, nex.ucf

-- Created: 090128

-- Revision 0.02 - Homework 04

-- Additional Comments:

------

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity SWTS_SSD is

Port ( CLK : in STD_LOGIC;

BTNS : in STD_LOGIC_VECTOR (3 downto 0);

SWTS : in STD_LOGIC_VECTOR (7 downto 0);

LEDS : out STD_LOGIC_VECTOR (7 downto 0);

AN : out STD_LOGIC_VECTOR (3 downto 0);

DP : out STD_LOGIC;

SEG : out STD_LOGIC_VECTOR (6 downto 0));

end SWTS_SSD;

architecture Behavioral of SWTS_SSD is

signal X: std_logic_vector(3 downto 0); --<

signal nSWTS: std_logic_vector(7 downto 0);

begin

U_SSD: entity work.NSSD(Behavioral) port map (hex(7 downto 0) => SWTS, hex(15 downto 8) => nSWTS,

DP => "0000" , CLK => CLK, DISP_SEG(7) => dp, DISP_SEG(6 downto 0) => seg ,

Disp_AN => an, EN => X);

X <= not(btns(3) & btns(2) & btns(1) & btns(0)); --<

LEDS(7 downto 4) <= btns(3 downto 0); -- When button is presed turn on LED

LEDS(3 downto 0) <= "0000"; -- Turn off low order LEDS

nSWTS <= not SWTS;

end Behavioral;


library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

------

-- ENTITY: NSSD - Seven segment display driver for Nexys2 board.

-- Outputs hex input to seven segment

-- display of Nexys 2 board.

-- IN: Hex - 16 bit Hex input to be displayed

-- DP - Specifies decimal points to turn on.

-- "0001" turns on rightmost decimal point.

-- CLK - 50 MHz system clock.

-- EN - If EN(i) = '0' The seven segment display digit i

-- blanked off else it is on.

-- OUT: DISP_SEG - output to drive segments of display.

-- DISP_AN - output to drive anodes of dispaly.

-- NEEDS: NONE

-- VERSION: 1.0

------

entity NSSD is

Port ( clk : in std_logic;

Hex : in std_logic_vector(15 downto 0);

Disp_seg : out std_logic_vector(7 downto 0);

Disp_AN : out std_logic_vector(3 downto 0);

DP : in std_logic_vector(3 downto 0) := "0000";

EN : in std_logic_vector(3 downto 0) := "1111");

end NSSD;

In the nssd architecture change

if EN = '1' then

DISP_AN <= std_logic_vector(anode);

else

DISP_AN <= "1111";

end if;

DISP_SEG(7) <= not DPmux;

to

------

-- Enable unblanked positions

------

DISP_AN <= not EN or anode;

-- pkg_func.vcd V 1.0 1/30/09

library IEEE; use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL;

package pkg_func is

function to_bcd (binary: std_logic_vector) return std_logic_vector;

end pkg_func;

library IEEE; use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL;

package body pkg_func is

------

--Function: to_bcd - Converts 16 bit input to BCD. If input > 9999 then

-- returns x"9999".

-- Input: binary - 16 bit unsigned value.

-- Returns: BCD unsigned.

-- Ussage: BCD = to_bcd(binary);

------

function to_bcd(binary: std_logic_vector) return STD_LOGIC_VECTOR is

variable rsr : std_logic_vector(15 downto 0); -- Shift reg for BCD result

variable bsr : std_logic_vector(15 downto 0); -- Shift reg for binary input

variable correction : std_logic_vector(15 downto 0); -- Add to do BCD correction

begin

if CONV_INTEGER(binary) > 9999 then

rsr := x"9999";

else

rsr := (others => '0');

bsr := binary;

for i in 1 to 16 loop

rsr := rsr(14 downto 0) & bsr(15);

bsr := bsr(14 downto 0) & '0';

if i < 16 then

for j in 0 to 3 loop

if rsr(4*j+3 downto 4*j) >= "0101" then

correction(4*j+3 downto 4*j) := "0011";

else

correction(4*j+3 downto 4*j) := "0000";

end if;

end loop;

rsr := rsr + correction;

end if;

end loop;

end if;

return rsr;

end to_bcd;

end pkg_func;


Additions to n_parts.vhd

-- N_PARTS.VHD V3.0 updated 9/12/08

LIBRARY IEEE;

USE work.ALL;

USE IEEE.std_logic_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

------

-- ENTITY: EDGE - Generates a TP of one clock cycle when X has changed

-- from 0 to 1.

-- IN: CLK - Use rising edge as clock.

-- X - Input sampled on rising edge of clock

-- OUT: TP - Timing Pulse. Produced when X changes from 0 to 1.

-- NEEDS: NONE

------

ENTITY EDGE IS

PORT (CLK : IN STD_LOGIC;

X : IN STD_LOGIC;

TP : OUT STD_LOGIC := '0'

);

END ENTITY EDGE;

ARCHITECTURE arch OF EDGE IS

BEGIN

PROCESS(CLK)

variable xold: std_logic := '0';

BEGIN

if clk'event and clk = '1' then

if xold = '0' and X = '1' then

TP <= '1';

else

TP <= '0';

end if;

xold := X;

end if;

END PROCESS;

END;

------

-- ENTITY: Debounce - Outputs Xin after Xin is stable for DB_COUNT.

-- Generic: DB_COUNT - Specifies number of clock cycles for which Xin

-- must be stable.

-- IN: CLK - Use rising edge as clock.

-- Xin - Input signal to be debounced.

-- OUT: Xout- Debounced output.

-- NEEDS: NONE

------

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

entity Debounce is

Generic (DB_COUNT: integer := 1000);

Port ( clk : in STD_LOGIC;

Xin : in STD_LOGIC;

Xout : out STD_LOGIC);

end Debounce;


architecture Behavioral of Debounce is

begin

process(clk)

variable count: integer range 0 to DB_COUNT := 0;

variable xold: std_logic := '0';

variable vxout: std_logic := '0';

begin

if clk'event and clk = '1' then

if xin = vxout then

count := 0;

else

count := count + 1;

end if;

if count = DB_COUNT then

count := 0;

vxout := xin;

end if;

xout <= vxout;

end if;

end process;

end Behavioral;


LIBRARY IEEE; USE work.ALL; USE IEEE.std_logic_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL;

------

-- ENTITY: NCNT - Outputs a terminal pulse of one clock period every

-- Nth clock. For the Nth clock period TP = '1' for

-- other clock periods TC = '0'. (i.e. TP goes to 1 after the

-- rising enge of the N-1 clock and then goes to 0 after the

-- rising edge of the N th clock.

-- GENERIC: N - Number of clocks required to produce terminal

-- pulse. Assume N > 1.

-- IN: CLK - Use rising edge as clock.

-- OUT: TP - Terminal Pulse. At the Nth CLK TP = '1' for

-- that clock period otherwise TP = '0'.

-- NEEDS: NONE

------

ENTITY NCNT IS

GENERIC(N: integer := 5);

PORT (CLK : IN STD_LOGIC;

TP : OUT STD_LOGIC := '0' );

END ENTITY NCNT;

ARCHITECTURE arch OF NCNT IS

BEGIN

PROCESS(CLK)

variable COUNT : INTEGER range 1 to N := 2;

BEGIN

IF clk'event and clk = '1' THEN

if COUNT = N then

COUNT := 1;

TP <= '1';

else

COUNT := COUNT + 1;

TP <= '0';

end if;

end if;

END PROCESS;

END arch;

LIBRARY IEEE; USE work.ALL; USE IEEE.std_logic_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL; use IEEE.STD_LOGIC_UNSIGNED.ALL;

------

-- ENTITY: ENCNT - Outputs a terminal pulse of one clock period every

-- Nth enabled clocks.

-- GENERIC: N - Number of enabled clocks required to produce terminal

-- pulse. Assume N > 1.

-- IN: CLK - Use rising edge as clock.

-- EN - Enables CLK. If EN = '1' on rising edge of CLK clocks

-- are counted otherwise clocks are not counted.

-- OUT: TP - Terminal Pulse. At the Nth enabled CLK TP = '1' for

-- that clock period otherwise TP = '0'.

-- NEEDS: NONE

------

ENTITY ENCNT IS

GENERIC(N: integer := 5);

PORT (CLK : IN STD_LOGIC;

EN : IN STD_LOGIC;

TP : OUT STD_LOGIC := '0'

);

END ENTITY ENCNT;

ARCHITECTURE arch OF ENCNT IS

BEGIN

PROCESS(CLK)

variable COUNT : INTEGER range 1 to N;

BEGIN

IF clk'event and clk = '1' THEN

if EN = '1' then

if COUNT = N then

COUNT := 1;

TP <= '1' after 1 ns;

else

COUNT := COUNT + 1;

TP <= '0' after 1 ns;

end if;

else

TP <= '0' after 1 ns;

end if;

end if;

END PROCESS;

END arch;


Top_CNT_SSD.VHD

------

-- Module Name: TOP_CNT_SSD - Behavioral

-- Project Name: CNT_TO_SSD.ise

-- Description: Increment the deimal count to SSD each .1 sec

-- Dependencies: n_parts_v0.vhd, nex.ucf, pkg_func.vhd

------

library IEEE;

use IEEE.STD_LOGIC_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

use work.all;

use pkg_func.all;

entity CNT_SSD is

Port ( CLK : in STD_LOGIC;

LEDS : out STD_LOGIC_VECTOR (7 downto 0);

AN : out STD_LOGIC_VECTOR (3 downto 0);

DP : out STD_LOGIC;

SEG : out STD_LOGIC_VECTOR (6 downto 0));

end CNT_SSD;

architecture Behavioral of CNT_SSD is

signal Cnt, Dec: std_logic_vector(15 downto 0) := (others => '0');

signal TP_ms, TP: std_logic := '0';

begin

U_ms: entity work.ncnt(arch) generic map (50_000)

port map(clk, TP_ms);

T_ts: entity work.encnt(arch) generic map (100)

port map(clk, TP_ms, TP);

U_SSD: entity work.NSSD(Behavioral) port map (hex => dec,

DP => "0000" , CLK => CLK, DISP_SEG(7) => dp, DISP_SEG(6 downto 0) => seg ,

Disp_AN => an, EN => "1111");

LEDS(7 downto 0) <= x"00"; -- Turn off LEDS

dec <= to_bcd(CNT);

process(clk)

begin

if clk'event and clk = '1' then

if TP = '1' then

CNT <= CNT + 1;

end if;

end if;

end process;

end Behavioral;


Homework 06

Due Monday 2/9/09

1. Create a Xilinx ISE project using top_cnt_ssd.vhd, nex.vhd, pkg_func.vhd and n_parts_v3.vhd. Correct any errors required to make the project work.

Complete bitdb.vhd turn in source code and your simulation.

tb_bitdb.vhd

LIBRARY IEEE;

USE work.all;

USE IEEE.Std_Logic_1164.all;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

use IEEE.MATH_REAL.ALL; --<---

ENTITY tb is END tb ;

ARCHITECTURE Test OF tb IS

signal x, y, b: std_logic_vector(15 downto 0) := X"0000";

signal G, N : integer := 0;

signal dB, rdB, rN: real := 0.0;

BEGIN

x <= not x(0) & x(15 downto 1) after 10 ns;

y <= (x(14 downto 0) & not x(15)) + 1 after 10 ns;

b <= x xor y;

N <= conv_integer(b);

U1: entity bitdb port map(b, G);

dB <= -real(G)/2.0;

rN <= real(N);

rdb <= 20.0*log10(rN/65535.0) when rn > 0.0 else 96.0;

end Test;

LIBRARY IEEE;

USE work.ALL;

USE IEEE.std_logic_1164.ALL;

use IEEE.STD_LOGIC_ARITH.ALL;

use IEEE.STD_LOGIC_UNSIGNED.ALL;

------

-- ENTITY: BITDB - Component based on IEEE Southeastcon 07 paper

-- "Quick and Easy Binary to dB Conversion"

-- IN: B - A 16 bit unsigned binary number.

-- OUT: G2 - An interger equal to the negative of twice the

-- dB value of w.

-- NEEDS: NONE

------

ENTITY BITDB IS

PORT (B: IN STD_LOGIC_VECTOR(15 downto 0);

G2: OUT integer range 0 to 255

);

END ENTITY BITDB;

ARCHITECTURE arch OF BITDB IS

BEGIN

GETmR: PROCESS(B)

variable w: std_logic_vector(15 downto 0);

variable m: integer range 0 to 15;

variable R: integer range 0 to 15;

variable kGR: integer range 0 to 255;

variable kGcGm: integer range 0 to 255;

BEGIN

-- Enter your code here

G2 <= kGcGm - kGR;

END PROCESS;

END arch;

11

Simulation waveforms.

11