An 8 Bit Up/Down Counter

advertisement
8 Bit Up/Down Counter
Version 3.2.0
Jenniffer Estrada
Project 3
EE365 Advanced Digital Design
Prof. Khondker
October 23, 2008
Executive Summary
An eight bit up down counter was implemented on the Altera DE1 Board. The counter ran
on an effective 1 Hertz clock. A direction key, Key0, changed the counting direction depending on
whether it is pressed. A clear button, Key 1, reset the counter to 0x00 and a hold button, Key 2, held
the value in the counter when pressed. The load button, Key 3, loaded an eight bit number based on
the position of switches 0 through 7. The output displayed two hexadecimal numbers on two seven
segment displays and on eight LEDs. The design was tested and debugged using SignalTap II, and
meets all the specifications.
Problem Description
Design a 8-bit binary up-down counter for a 1 Hz effective clock. The counter should count
down when button KEY0 is pressed and should count up when it is released. It should have a clear
button (KEY1) that initializes the sequence (asynchronously) to 0X00 when it is pressed. Also it has
a count button (KEY2) which disables the counting sequence when it is pressed. When button KEY3
is pressed, it stops counting & loads (synchronously) a 8-bit number (N) into the counter. The 8-bit
number to be loaded is provided using the 8 switches (SW7-SW0) on the DE1 board. The counting
process will repeat itself between 0 and N in the up sequence and between N and 0 in the down
counting sequence. The output should be displayed on the LEDs on the DE1 board as well as on the
7 segment displays. The least significant bit (LSB) of the counter should be displayed on LEDR0 and
the MSB on LEDR7. The 7-seqment displays should use 2 HEX numbers to represent the 8 bit
numbers. In this design you must instantiate a SignalTap II logic Analyzer as a tool for debugging
your design.
Design Problem Statement
The binary up down counter is enabled after 50,000,000 pulses from the 50MHerts
clock within the DE1 board. When the button Key 0 is pressed (set to 0), the counter will
initiate the downward counting sequence until released, where it will resume counting up.
When the button Key 1 is pressed, the counter will reset to the value 0x00 without waiting
for the effective clock rising edge. Key 2 will hold the value that the counter has stored for
as long as the button is pressed. Key 3 will synchronously stop the counter, load and set the
maximum value for the counter as the number selected by the eight switches, SW(0)SW(7), and hold the value until released, where it will resume the counting. The output of
the counter will be displayed both on two seven segment displays as Hexadecimal numbers
as well as 8 LEDs on the DE1 board. The two unused seven segment displays will be turned
off and SignalTap II will be used as a debugging tool for the counter.
Problem Decomposition
Project3
“1111111”
Hex
3
ClockCounter
CLOCK_50
50MHz
EffClk
Hex
2
CountEnable
Key 0
DecodeHex
UpDownCounterHold
Key 1
Enable
Key 2
Key 3
BitInput
Hex
1
7
Hex
0
4
Direction
Reset
Output
Hold
SW(0-7)
7
CountValue
8
DecodeHex
4
Load
BitInput
Max
LEDR(7-0)
CountMax
EightBitRegister
load
Output
Vector
Fig.1. Block Diagram of the Eight Bit Up Down Counter
Complying with the design specifications, the top level entity project3, inputs to our
system are the 50MHs clock in the DE1 board, Keys 0-3, Switches 0 to 7. The “1111111”
input is used to keep the unused 7 segment displays, Hex3 and Hex2, off all the time. The
components, ClockCounter, UpDownCounterHold and EightBitRegister, all see the 50Mhz
clock. ClockCounter uses Clock_50 to output the effective clock, EffClk, which enables
UpDownCounterHold. Key0 controls the direction of the counting, Key1 controls the reset
of the counter to 0x00, Key2 controls the loading of the 8 bit number determined by
Switches 0 to 7, SW(0-7), and Key3 controls the hold of the current value in the counter
when pressed. The loaded number from the EightBitRegister will become the maximum
value that the counter can count to before resetting to zero. CountEnable, CountMax and
CountValue are signals within the design. The DecodeHex, instantiated for the two 7
segment displays that will be in use, will use as input, BitInput, the value outputted by
UpDownCounterHold through the signal, CountValue. The signal CountValue will give the
binary number to LEDR(7-0) to display in the 8 LEDs on the DE1 board, and the 8 bit
number will also be divided from 0 to 3 and 3-7 and sent to the corresponding to the
appropriate DecodeHex to be displayed in the 7 segment display on the DE1 board.
Significant Details of Design Process
The design is written to be modular to make it possible for future use in other projects. The Top
Level Entity, project3, has four components, ClockCounter, UpDownCounterHold, EightBitRegister,
DecodeHex.
ClockCounter.vhd uses the 50Mhz clock from the DE1 board to count 50000000 pulses to synchronously
enable the UpDownCounter at 1Hertz.
EightBitRegister.vhd uses the effective clock to load in an eight bit binary vector defined by the user
input of the switches 7 down to 0 and feeds the value to the UpDownCounterHold as the maximum
value that it can count to until resetting to zero.
UpDownCounterHold.vhd, is an eight bit counter enabled by ClockCounter. The component has 7 inputs.
When is Key 1 has a value of ‘0’, pressed, the counter asynchronously resets to 00, which means that it
can be triggered on either edge of the clock. The counting direction is determined by Key0. When Key0
is pressed, the counting decreases by one on every clock edge of the effective clock. The counter holds
the current value as long as Key2 is pressed. The counter stops the counting sequence and
synchronously loads the binary number from the output of EightBitRegister when Key3 is pressed and
sets the new value to be the maximum value. The output of the counter is split two different paths,
going to the LEDR input and breaking off again into 4 bit and input into the corresponding DecodeHex
components. The LEDR will display the 8 bit binary input with LEDR0 being the LSB and LEDR7 being the
MSB.
DecodeHex.vhd takes the four bit binary vector and acts as a 4 to 7 Multiplexer, displaying the
corresponding hexadecimal number on the 7 segment display.
The top level entity uses structural architecture and instantiates the component DecodeHex twice. The
input, “1111111” is used to disable the unused 7 segment displays. The LEDR uses the signal,
CountValue to display the 8 bit binary number on the LEDs.
Alternative Designs
An Alternative design that could have been implemented was to set the upper
bound of our ClockCounter to 49999999 and then instead of using UpperBound-1, we can
use UpperBound. An Example of this would be:
….
COMPONENT ClockCounter IS
GENERIC ( UpperBound: integer:=49999999);
PORT( Clock: IN std_logic;
Enable: IN std_logic;
EffClk: OUT std_logic);
END COMPONENT ClockCounter;
….
ARCHITECTURE behavior OF ClockCounter IS
signal count : integer range 0 to(UpperBound-1);
BEGIN
PROCESS (Clock)
BEGIN
IF (rising_edge(Clock) and Enable = '1') then
IF( count = (UpperBound-1)) then
count <= 0;
EffClk <= '1';
else
count <= count+1;
EffClk <= '0';
end if;
end if;
END PROCESS;
….
The design could be modified to run completely synchronous to avoid glitches. Instead of using
signals, INOUT statements could be used within the design to store data.
Design Documentations:
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
ENTITY project3 IS
PORT( CLOCK_50:
KEY:
SW:
HEX0,HEX1:
HEX2,HEX3:
LEDR:
END project3;
IN std_logic;
IN std_logic_vector(3 downto 0);
IN std_logic_vector(7 downto 0);
OUT std_logic_vector(6 downto 0);
OUT std_logic_vector(6 downto 0);
OUT std_logic_vector(7 downto 0));
ARCHITECTURE structural OF project3 IS
COMPONENT DecodeHex IS
PORT( BitInput:
IN std_logic_vector(3 downto 0);
HexOutput:
OUT std_logic_vector(6 downto 0));
END COMPONENT DecodeHex;
COMPONENT ClockCounter IS
GENERIC ( UpperBound: integer:=50000000);
PORT( Clock: IN std_logic;
Enable: IN std_logic;
EffClk: OUT std_logic);
END COMPONENT ClockCounter;
COMPONENT UpDownCounterHold IS
PORT ( Clock:
IN std_logic;
Enable:
IN std_logic;
Reset:
IN std_logic;
Direction:
IN std_logic;
Hold:
IN std_logic;
Load:
IN std_logic;
Max:
IN std_logic_vector(7 DOWNTO 0);
Output:
OUT std_logic_vector(7 DOWNTO 0));
END COMPONENT UpDownCounterHold;
COMPONENT EightBitRegister IS
PORT ( Clock:
IN std_logic;
Vector:
IN std_logic_vector(7 DOWNTO 0);
Load:
IN std_logic;
Output:
OUT std_logic_vector(7 DOWNTO 0));
END COMPONENT EightBitRegister;
signal CountEnable:
signal CountValue:
signal CountMax:
std_logic;
std_logic_vector(7 downto 0);
std_logic_vector(7 downto 0);
BEGIN
ClockCounter0 : ClockCounter port map( Clock => CLOCK_50,
Enable => '1',
EffClk => CountEnable );
Counter : UpDownCounterHold port map(
Clock => CLOCK_50,
Enable => CountEnable,
Reset => KEY(1),
Direction => KEY(0),
Hold => KEY(2),
Load => KEY(3),
Max => CountMax,
Output => CountValue);
CounterMaximum: EightBitRegister port map(
Hex_0: DecodeHex port map(
Hex_1: DecodeHex port map(
Clock => CLOCK_50,
Vector =>SW(7 downto 0),
Load =>KEY(3),
Output => CountMax);
BitInput => CountValue(3 downto 0),
HexOutput => HEX0);
BitInput => CountValue(7 downto 4),
HexOutput => HEX1);
LEDR <= CountValue;
HEX2 <= "1111111";
HEX3 <= "1111111";
END structural;
Top Level Entity project3 VHDL Code
library ieee;
use ieee.std_logic_1164.all;
ENTITY DecodeHex IS
PORT(
BitInput:
IN std_logic_vector(3 downto 0);
HexOutput: OUT std_logic_vector(6 downto 0));
END DecodeHex;
ARCHITECTURE Behavior OF DecodeHex IS
BEGIN
WITH BitInput SELECT
HexOutput <= "1000000" WHEN "0000",
"1111001" WHEN "0001",
"0100100" WHEN "0010",
"0110000" WHEN "0011",
"0011001" WHEN "0100",
"0010010" WHEN "0101",
"0000010" WHEN "0110",
"1111000" WHEN "0111",
"0000000" WHEN "1000",
"0011000" WHEN "1001",
"0001000" WHEN "1010",
"0000011" WHEN "1011",
"1000110" WHEN "1100",
"0100001" WHEN "1101",
"0000110" WHEN "1110",
"0001110" WHEN "1111",
"1111111" WHEN others;
END Behavior;
DecodeHex Component VHDL Code
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
ENTITY ClockCounter IS
GENERIC (UpperBound: integer);
PORT ( Clock: IN std_logic;
Enable: IN std_logic;
EffClk: OUT std_logic
);
END ClockCounter;
ARCHITECTURE behavior OF ClockCounter IS
signal count : integer range 0 to(UpperBound-1);
BEGIN
PROCESS (Clock)
BEGIN
IF (rising_edge(Clock) and Enable = '1') then
IF( count = (UpperBound-1)) then
count <= 0;
EffClk <= '1';
else
count <= count+1;
EffClk <= '0';
end if;
end if;
END PROCESS;
END behavior;
ClockCounter Component VHDL Code
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_arith.all;
ENTITY UpDownCounterHold IS
PORT (
Clock:
Enable:
Reset:
Direction:
Hold:
Load:
Max:
Output:
);
END UpDownCounterHold;
IN std_logic;
IN std_logic;
IN std_logic;
IN std_logic;
IN std_logic;
IN std_logic;
IN std_logic_vector(7 DOWNTO 0);
OUT std_logic_vector(7 DOWNTO 0)
ARCHITECTURE behavior OF UpDownCounterHold IS
signal count : std_logic_vector(7 downto 0);
BEGIN
PROCESS(Clock)
BEGIN
IF (Reset = '0') THEN
count <= "00000000";
ELSIF (rising_edge(Clock) AND Enable = '1') THEN
IF (Hold = '0') THEN
count <= count;
ELSIF (Load = '0') THEN
count <= Max;
ELSIF (Load = '1' AND Direction = '1') THEN
count <= count + 1;
IF (count+1 > Max) THEN
count <= "00000000";
END IF;
ELSIF (Load = '1' AND Direction = '0') THEN
count <= count - 1;
IF (count-1 > Max) THEN
count <= Max;
END IF;
ELSE
count <= count;
END IF;
END IF;
Output <= count;
END PROCESS;
END Behavior;
UpDownCounterHold Component VHDL Code
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
ENTITY EightBitRegister IS
PORT (
Clock:
Vector:
Load:
Output:
);
END EightBitRegister;
IN std_logic;
IN std_logic_vector(7 DOWNTO 0);
IN std_logic;
OUT std_logic_vector(7 DOWNTO 0)
ARCHITECTURE behavior OF EightBitRegister IS
signal vector_value : std_logic_vector(7 downto 0);
BEGIN
PROCESS(Clock)
BEGIN
IF (rising_edge(Clock) AND Load = '0') THEN
vector_value <= Vector;
ELSE
vector_value <= vector_value;
END IF;
Output <= vector_value;
END PROCESS;
END behavior;
EightBitRegister Component VHDL Code
Performance Results and Analysis
Fig.2. Quartus Resource Summary with SignalTap II Analyzer
The resource summary without the SignalTap II Analyzer uses about one percent of the board. The
inclusion of the debugging tool increases the memory bits used significantly, but still uses only 5
percent of the entire board.
Fig.3.SignalTap II results for Key0
Figure 3 shows that when Key 0 is pressed, the counting downward counting sequence
is initiated, as to be expected.
Fig.4.SignalTap II results for Key1
Figure 4 shows that when Key 1 is pressed, the counter is reset to 0, which is what we
expect to happen.
Fig.5.SignalTap II results for Key2
Figure 5 shows the value of the counter being held when Key 2 is pressed, which is what
we expect.
Fig.6.SignalTap II results for Key3 when loaded number is 18
Figure 6 demonstrates the number 18 being synchronously loaded into the counter when
Key 3 is pressed and holds the value while pressed, which is what we desired with our
design.
Using SignalTap II Analyzer, the eight bit up down counter was able to be debugged in real
time to catch any glitches or wrong outputs that might go unchecked otherwise.
References
“VHDL Tutorials” SignalTap II with VHDL Designs. (July 31, 2008).
ftp://ftp.altera.com/up/pub/Tutorials/DE2/Digital_Logic/tut_signaltapII_vhdlDE2.pdf
(Retrieved on October 23, 2008).
Khondker, A., “Project 4” Design Specificaions. (Fall 2008).
http://people.clarkson.edu/~khondker/ee365_f2008.html (Retrieved on October 23, 2008).
Download