ECE4623/5623
Computer Hardware Design
HW-4 (25 pts.) Due: 10/17/12
1. (15 Pts.) A synchronous 4-bit up/down decade counter (similar to a 74LS168) works as follows: All state changes occur on the rising edge of the CLK input, except when the asynchronous clear signal, CLRN, is asserted. If the LOADN input is 0, the parallel load inputs, D0-D3, are loaded into the counter synchronously on the next rising CLK edge. Use Q0-Q3 as the count signals, declared as “inout” in the Entity. (You may wish to choose integer types, with range values, for D and Q, but is not required, just easier.) PN and TN are the propagate and toggle inputs, respectively, and both must be asserted low for the counter to count up or down. If LOADN=1, PN=TN=0, and UD=1, the counter increments on the rising CLK edge. If LOADN=1, PN=TN=0 and UD=0, the counter decrements on the rising CLK edge. If TN=0, UD=1 and the counter is in state 9, "1001", the carryout, CON, is asserted low (CON=0). If TN=0, UD=0, and the counter is in state 0, "0000", the carryout, CON, is asserted low (CON=0). The CLRN signal clears the counter to 0, “0000”, when UD=1. When UD=0, CLRN clears the counter to 9, “1001”. If the D inputs are invalid BCD digits (0xA-0xF) and LOADN is asserted, the circuit will force a parallel load of 9, “1001”, on the rising clock edge.
(a) Code a VHDL module that describes a single 4-bit counter. (You may wish to simulate this module to insure its correct operation).
(b) Code a VHDL module that instantiates four 4-bit counters to form a four-digit decade counter that counts 0000 to 9999 (up) and 9999 to 0000 (down). Provide all input and output signals for the top-level VHDL device, i.e., clock, clear, load, P, T, parallel inputs, parallel outputs, and carry out. Using the ISim/ModelSim simulator, construct a test bench for the BCD 0000-9999 counter. Provide the following simulation sequence: an initial parallel load of 0000, count up to 12, clear the counter (CLRN asserted for one clock period), a parallel load of 0098, count up to 0100, count down to 0099, parallel load of 0999, count up to 1000, down to 0999, parallel load of 9999, count up to 0001, count down to 9999, attempt to parallel load (“1010”, “1011”, “1100”, “1111”) into the four stages, respectively, then clear the counter (CLRN asserted for one clock period). Show parallel load inputs, D, and parallel outputs, Q, as hex busses on the timing diagram. Provide the VHDL source code, test bench, and a screen dump image(s) or printout of the simulator timing diagram.
2. (10 Pts) Use VHDL to describe a timing generator circuit that produces six evenly spaced timing signals, T0 through T5. One and only one T signal is asserted for each clock period. An asynchronous reset input, RESETN, is asserted low and causes the circuit to reset to the T0 state. A clock input, CLK, drives the circuit. The circuit should change outputs on the rising edge of the clock. An enable signal, E, asserted high, must be high to advance the timing; otherwise, the circuit holds the current output T signal.
(a). Implement the circuit using a mod-6 counter.
(b). Implement the circuit using a circular shift register (ring counter).
Provide an ISim/ ModelSim test bench (used for both circuits) that resets the circuit, enables the circuit and runs for 8 clock periods, de-asserts the enable, E, for one clock period, asserts E and counts for another 6 clock periods, then resets the circuit. Turn in the VHDL circuit source code, the VHDL test bench, and the simulation timing window.
Problem 1 Solution
-- ECE4623/5623
-- Parallel BCD up/down counter stage
-- CLRN clears counter to 0 if UD=1, clears to 9 if UD=0
-- LOADN is synchronous parallel load of D inputs
-- loading D>9 forces Q=9
-- UD=1 counts up, UD=0 counts down on rising CLK edge
-- CON is carry-out asserted low
--------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity BCD_Counter is
Port ( CLK : in std_logic;
CLRN : in std_logic; -- Asynchronous clear
LOADN : in std_logic; -- Synchronous parallel load asserted low
UD : in std_logic; -- up/down control input
PN : in std_logic; -- enable P asserted low
TN : in std_logic; -- enable T asserted low
D : in std_logic_vector(3 downto 0); -- parallel load inputs
Q : inout std_logic_vector(3 downto 0); -- parallel outputs
CON : out std_logic); -- carry-out asserted low
end BCD_Counter;
architecture BCD_Counter_Arch of BCD_Counter is
begin
process(CLK, CLRN)
begin
if CLRN = '0' then
if UD = '1' then
Q <= "0000"; -- clear to 0 if counting up
else Q <= "1001"; -- clear to 9 if counting down
end if;
elsif Rising_Edge(CLK) then
if LOADN = '0' then -- synchronous load
if D > "1001" then -- check for invalid BCD
Q <= "1001";
else Q <= D;
end if;
elsif PN = '0' and TN = '0' and UD = '1' then -- count up
if Q = "1001" then -- check for max count
Q <= "0000";
else Q <= Q + "0001"; -- count up
end if;
elsif PN = '0' and TN = '0' and UD = '0' then -- count down
if Q = "0000" then -- check for min count
Q <= "1001";
else Q <= Q - "0001"; -- count down
end if;
end if;
end if;
end process;
-- Generate the carry-out
CON <= '0' when TN = '0' and UD = '1' and Q = "1001" else
'0' when TN = '0' and UD = '0' and Q = "0000" else
'1';
end BCD_Counter_Arch;
-- ECE4623/5623
-- 4-Digit BCD parallel load up/down counter
-- Instantiates 4 copies of a 4-bit BCD up/down counter
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity BCD_4_Digit_Counter is
Port ( CLK : in std_logic;
CLRN : in std_logic; -- Asynchronous clear
LOADN : in std_logic; -- Synchronous parallel load
UD : in std_logic; -- up/down control input
PN : in std_logic; -- enable P
TN : in std_logic; -- enable T
D : in std_logic_vector(15 downto 0); -- parallel load inputs
Q : inout std_logic_vector(15 downto 0); -- parallel outputs
CON : out std_logic); -- carry-out
end BCD_4_Digit_Counter;
architecture BCD_4_Digit_Arch of BCD_4_Digit_Counter is
component BCD_Counter
Port ( CLK : in std_logic;
CLRN : in std_logic; -- Asynchronous clear
LOADN : in std_logic; -- Synchronous parallel load
UD : in std_logic; -- up/down control input
PN : in std_logic; -- enable P
TN : in std_logic; -- enable T
D : in std_logic_vector(3 downto 0); -- parallel load inputs
Q : inout std_logic_vector(3 downto 0); -- parallel outputs
CON : out std_logic); -- carry-out
end component;
signal Cout: std_logic_vector(2 downto 0); -- carry-out signal vector
begin
GenLoop: for i in 0 to 3 generate
begin
Counter0: if i = 0 generate
begin
Stage0: BCD_Counter
port map(CLK => CLK, CLRN => CLRN, LOADN => LOADN, UD => UD,
PN => PN, TN => TN, D => D(3 downto 0),
Q => Q(3 downto 0), CON => Cout(0));
end generate;
Counter1_2: if (i = 1 or i = 2) generate
begin
Stages1_2: BCD_Counter
port map(CLK => CLK, CLRN => CLRN, LOADN => LOADN, UD => UD,
PN => Cout(0), TN => Cout(i-1), D => D((4*i)+3 downto 4*i),
Q => Q((4*i)+3 downto 4*i), CON => Cout(i));
end generate;
Counter3: if i = 3 generate
begin
Stage3: BCD_Counter
port map(CLK => CLK, CLRN => CLRN, LOADN => LOADN, UD => UD,
PN => Cout(0), TN => Cout(2), D => D(15 downto 12),
Q => Q(15 downto 12), CON => CON);
end generate;
end generate;
end BCD_4_Digit_Arch;
-- 4-digit BCD up/down counter test bench
-- MP Tull
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;
ENTITY BCD74168_TB1 IS
END BCD74168_TB1;
ARCHITECTURE behavior OF BCD74168_TB1 IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT BCD_4_Digit_Counter
PORT(
CLK : IN std_logic;
CLRN : IN std_logic;
LOADN : IN std_logic;
UD : IN std_logic;
PN : IN std_logic;
TN : IN std_logic;
D : IN std_logic_vector(15 downto 0);
Q : INOUT std_logic_vector(15 downto 0);
CON : OUT std_logic
);
END COMPONENT;
--Inputs
signal CLK : std_logic := '0';
signal CLRN : std_logic := '0';
signal LOADN : std_logic := '0';
signal UD : std_logic := '0';
signal PN : std_logic := '0';
signal TN : std_logic := '0';
signal D : std_logic_vector(15 downto 0) := (others => '0');
--BiDirs
signal Q : std_logic_vector(15 downto 0);
--Outputs
signal CON : std_logic;
constant CLK_period: time := 100 ns;
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: BCD_4_Digit_Counter PORT MAP (
CLK => CLK,
CLRN => CLRN,
LOADN => LOADN,
UD => UD,
PN => PN,
TN => TN,
D => D,
Q => Q,
CON => CON
);
CLK_process :process
begin
CLK <= '0';
wait for CLK_period/2;
CLK <= '1';
wait for CLK_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
CLRN <= '1';
UD <= '1';
PN <= '0';
TN <= '0';
D <= x"0000";
WAIT FOR 25 ns;
LOADN <= '0';
WAIT FOR 100 ns;
LOADN <= '1';
WAIT FOR 1200 ns;
CLRN <= '0';
WAIT FOR 100 ns;
CLRN <= '1';
LOADN <= '0';
D <= x"0098";
WAIT FOR 100 ns;
LOADN <= '1';
WAIT FOR 200 ns;
UD <= '0';
WAIT FOR 100 ns;
LOADN <= '0';
UD <= '1';
D <= x"0999";
WAIT FOR 100 ns;
LOADN <= '1';
WAIT FOR 100 ns;
UD <= '0';
WAIT FOR 100 ns;
LOADN <= '0';
UD <= '1';
D <= x"9999";
WAIT FOR 100 ns;
LOADN <= '1';
WAIT FOR 75 ns;
UD <= '0';
WAIT FOR 25 ns;
WAIT FOR 200 ns;
CLRN <= '0';
WAIT FOR 100 ns;
CLRN <= '1';
D <= x"ABCF";
LOADN <= '0';
WAIT FOR 150 ns;
Assert (FALSE)
Report "Simulation Successful - Not a Failure"
Severity Failure;
end process;
END;
16
ECE4623/5623
Computer Hardware Design
HW-4 (25 pts.) Due: 10/17/12
16
ECE4623/5623
Computer Hardware Design
HW-4 (25 pts.) Due: 10/17/12
Problem 2 Solution
-- This circuit generates 6 timing state signals T0-T5.
-- A counter is used to drive a decoder.
-- The counter must be enabled to count.
-- RESETN is an asynchronous reset.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity TimeGen6 is
Port ( CLK : in STD_LOGIC;
RESETN : in STD_LOGIC; -- asynchronous reset
E : in STD_LOGIC; -- enable signal to count or load
T : out STD_LOGIC_VECTOR (5 downto 0)); -- output timing states
end TimeGen6;
architecture TimeGen6_Arch of TimeGen6 is
signal Count: std_logic_vector(2 downto 0);
begin
process(CLK, RESETN)
begin
if RESETN = '0' then
Count <= "000";
elsif Rising_Edge(CLK) then
if E = '1' then
if Count = "101" then -- check for max count
Count <= "000";
else
Count <= Count + '1'; -- count
end if;
end if;
end if;
end process;
-- Generate timing states with a decoder
with Count select
T <= "000001" when "000",
"000010" when "001",
"000100" when "010",
"001000" when "011",
"010000" when "100",
"100000" when "101",
"000000" when others;
end TimeGen6_Arch;
-- Timing generator Test Bench
-- MP Tull
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;
ENTITY TimeGen6_TB1 IS
END TimeGen6_TB1;
ARCHITECTURE behavior OF TimeGen6_TB1 IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT TimeGen6
PORT(
CLK : IN std_logic;
RESETN : IN std_logic;
E : IN std_logic;
T : OUT std_logic_vector(5 downto 0)
);
END COMPONENT;
--Inputs
signal CLK : std_logic := '0';
signal RESETN : std_logic := '0';
signal E : std_logic := '0';
--Outputs
signal T : std_logic_vector(5 downto 0);
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: TimeGen6 PORT MAP (
CLK => CLK,
RESETN => RESETN,
E => E,
T => T
);
CLK_process :process
constant CLK_period: time := 100 ns;
begin
CLK <= '0';
wait for CLK_period/2;
CLK <= '1';
wait for CLK_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
RESETN <= '0'; -- reset the circuit
wait for 125 ns;
RESETN <= '1'; -- de-assert reset
E <= '1'; -- enable circuit
wait for 800 ns; -- run counter for 8 cycles
E <= '0'; -- de-assert ENABLE
wait for 100 ns;
E <= '1'; -- enable the circuit
wait for 600 ns; -- count for 6 cycles
RESETN <= '0'; -- reset circuit
wait for 100 ns;
assert (false) report
"Simulation Successful - Not a Failure"
severity failure;
end process;
END;
16
ECE4623/5623
Computer Hardware Design
HW-4 (25 pts.) Due: 10/17/12
16
ECE4623/5623
Computer Hardware Design
HW-4 (25 pts.) Due: 10/17/12
-- This circuit generates 6 timing state signals T0-T5.
-- A shift register is used to produce the T0-T5.
-- The shift register must be enabled to shift.
-- RESETN is an asynchronous reset that initializes to T0.
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
entity TimeGen6 is
Port ( CLK : in STD_LOGIC;
RESETN : in STD_LOGIC; -- asynchronous reset
E : in STD_LOGIC; -- enable signal to count or load
T : inout STD_LOGIC_VECTOR (5 downto 0)); -- output timing states
end TimeGen6;
architecture TimeGen6_Arch of TimeGen6 is
begin
process(CLK, RESETN)
begin
if RESETN = '0' then
T <= "000001"; -- reset to T(0)
elsif Rising_Edge(CLK) then
if E = '1' then
T <= T(4 downto 0) & T(5); -- circular shift left
end if;
end if;
end process;
end TimeGen6_Arch;
-- Timing generator Test Bench
-- MP Tull
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;
ENTITY TimeGen6_TB1 IS
END TimeGen6_TB1;
ARCHITECTURE behavior OF TimeGen6_TB1 IS
-- Component Declaration for the Unit Under Test (UUT)
COMPONENT TimeGen6
PORT(
CLK : IN std_logic;
RESETN : IN std_logic;
E : IN std_logic;
T : INOUT std_logic_vector(5 downto 0)
);
END COMPONENT;
--Inputs
signal CLK : std_logic := '0';
signal RESETN : std_logic := '0';
signal E : std_logic := '0';
--Outputs
signal T : std_logic_vector(5 downto 0);
BEGIN
-- Instantiate the Unit Under Test (UUT)
uut: TimeGen6 PORT MAP (
CLK => CLK,
RESETN => RESETN,
E => E,
T => T
);
CLK_process :process
constant CLK_period: time := 100 ns;
begin
CLK <= '0';
wait for CLK_period/2;
CLK <= '1';
wait for CLK_period/2;
end process;
-- Stimulus process
stim_proc: process
begin
RESETN <= '0'; -- reset the circuit