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