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