Learn to create a clock using basic Verilog code on a FPGA development board in order to practice the use of Verilog VHDL.

The basic operating principle of this FPGA clock is to divide the crystal oscillator using a divide-by-n counter so that it gives a 1 Hz signal. Using this signal, increment a display counter. Finally, use the counter's stored value to drive a 7 segment display driver to output the time to the user.

This project was done as a school assignment on VHDL programming and using FPGAs. 

Timer.vhd

 

LIBRARY work;
USE work.Mod10CounterPackage.Mod10Counter;
USE work.Mod6CounterPackage.Mod6Counter;
USE work.SegDriverPackage.SegDriver;
USE work.Mod500ThousandCounterPackage.Mod500ThousandCounter;

ENTITY UpDownTimer IS
	PORT(
		CLOCK_50	:	IN BIT;
		KEY		:	IN BIT_VECTOR(0 DOWNTO 0);
		SW			:	IN BIT_VECTOR(2 DOWNTO 0);
		HEX0		:	OUT BIT_VECTOR(6 DOWNTO 0);
		HEX1		:	OUT BIT_VECTOR(6 DOWNTO 0);
		HEX2		:	OUT BIT_VECTOR(6 DOWNTO 0);
		HEX3		:	OUT BIT_VECTOR(6 DOWNTO 0);
		HEX4		:	OUT BIT_VECTOR(6 DOWNTO 0);
		HEX5		:	OUT BIT_VECTOR(6 DOWNTO 0);
		HEX6		:	OUT BIT_VECTOR(6 DOWNTO 0);
		HEX7		:	OUT BIT_VECTOR(6 DOWNTO 0);
		RCO		:  OUT BIT
		);
END ENTITY;

ARCHITECTURE Behavior OF UpDownTimer IS
	--Instantiate the Display Drivers Signals --
	SIGNAL Display0 : INTEGER RANGE 0 TO 15;
	SIGNAL Display1 : INTEGER RANGE 0 TO 15;
	SIGNAL Display2 : INTEGER RANGE 0 TO 15;
	SIGNAL Display3 : INTEGER RANGE 0 TO 15;
	SIGNAL Display4 : INTEGER RANGE 0 TO 15;
	SIGNAL Display5 : INTEGER RANGE 0 TO 15;
	
	--Instantiate all of our counters Signals --
	SIGNAL RCO0to1 : BIT;
	SIGNAL RCO1to2 : BIT;
	SIGNAL RCO2to3 : BIT;
	SIGNAL RCO3to4 : BIT;
	SIGNAL RCO4to5 : BIT;
	SIGNAL RCO5to6 : BIT;
	
	BEGIN
		-- Initialize the other segments to blank --
		HEX0 <= "1111111";
		HEX1 <= "1111111";
		
		Divider: Mod500ThousandCounter PORT MAP(CLOCK_50, NOT(KEY(0)), SW(2), RCO0to1);
		Hundreths: Mod10Counter PORT MAP(RCO0to1, NOT(KEY(0)), SW(0), RCO1to2, Display0);
		Tenths: Mod10Counter PORT MAP(RCO1to2, NOT(KEY(0)), SW(0), RCO2to3, Display1);
		Seconds: Mod10Counter PORT MAP(RCO2to3, NOT(KEY(0)), SW(0), RCO3to4, Display2);
		Tens:	Mod6Counter PORT MAP(RCO3to4, NOT(KEY(0)), SW(0), RCO4to5, Display3);
		Minutes: Mod10Counter PORT MAP(RCO4to5, NOT(KEY(0)), SW(0), RCO5to6, Display4);
		TensMinutes: Mod6Counter PORT MAP(RCO5to6, NOT(KEY(0)), SW(0), RCO, Display5);
		
		Seg0: SegDriver PORT MAP(Display0, SW(1), HEX2);
		Seg1: SegDriver PORT MAP(Display1, SW(1), HEX3);
		Seg2: SegDriver PORT MAP(Display2, SW(1), HEX4);
		Seg3: SegDriver PORT MAP(Display3, SW(1), HEX5);
		Seg4: SegDriver PORT MAP(Display4, SW(1), HEX6);
		Seg5: SegDriver PORT MAP(Display5, SW(1), HEX7);
			
END ARCHITECTURE;

 

Mod5MillionCounter.vhd

 

LIBRARY ieee;
USE ieee.std_logic_1164.all;

ENTITY Mod500ThousandCounter IS
	PORT(	Clock	:IN BIT;
			Reset :IN BIT;
			Halt	:IN BIT;
			RCO	:OUT BIT);
END ENTITY;

ARCHITECTURE Behavior OF Mod500ThousandCounter IS
	BEGIN
	PROCESS(Clock)
	VARIABLE I: INTEGER := 0;
	BEGIN
		IF(Halt='0') THEN
			IF(Reset='1') THEN
				RCO<='0';
				i := 0;
			ELSIF(Clock'EVENT and Clock='1') THEN
				IF(i = 499999) THEN
					RCO<='1';
					i := 0;
				ELSE
					RCO<='0';
					i := i + 1;
				END IF;
			END IF;
		END IF;
	END PROCESS;
END Behavior;

PACKAGE Mod500ThousandCounterPackage IS
	COMPONENT Mod500ThousandCounter
	PORT(	Clock	:IN BIT;
			Reset :IN BIT;
			Halt	:IN BIT;
			RCO	:OUT BIT);
	END COMPONENT;
END PACKAGE;	

Mod10Counter.vhd

LIBRARY ieee;
USE ieee.std_logic_1164.all;

ENTITY Mod10Counter IS
	PORT(	Clock	:IN BIT;
			Reset :IN BIT;
			Dir	:IN BIT;
			RCO	:OUT BIT;
			OUT_BUS:BUFFER INTEGER RANGE 0 to 9);
END ENTITY;

ARCHITECTURE Behavior OF Mod10Counter IS
	BEGIN
	PROCESS(Clock)
	BEGIN
		IF(Reset = '1') THEN
				RCO<='0';
				OUT_BUS<=0;
		ELSIF(Clock'EVENT AND Clock='1') THEN
			IF(OUT_BUS = 9 AND Dir = '0') THEN
				RCO<='1';
				OUT_BUS<=0;
			ELSIF(OUT_BUS = 0 AND Dir = '1') THEN
				RCO<='1';
				OUT_BUS<=9;
			ELSE
				RCO<='0';
				IF(Dir='0') THEN
					OUT_BUS<=OUT_BUS + 1;
				ELSE
					OUT_BUS<=OUT_BUS - 1;
				END IF;
			END IF;
		END IF;
	END PROCESS;
END Behavior;

PACKAGE Mod10CounterPackage IS
	COMPONENT Mod10Counter
	PORT(	Clock	:IN BIT;
			Reset :IN BIT;
			Dir	:IN BIT;
			RCO	:OUT BIT;
			OUT_BUS:BUFFER INTEGER RANGE 0 to 9);
	END COMPONENT;
END PACKAGE;	

Mod6Counter.vhd

 

LIBRARY ieee;
USE ieee.std_logic_1164.all;

ENTITY Mod6Counter IS
	PORT(	Clock	:IN BIT;
			Reset :IN BIT;
			Dir	:IN BIT;
			RCO	:OUT BIT;
			OUT_BUS:BUFFER INTEGER RANGE 0 to 5);
END ENTITY;

ARCHITECTURE Behavior OF Mod6Counter IS
	BEGIN
	PROCESS(Clock)
	BEGIN
		IF(Reset = '1') THEN
				RCO<='0';
				OUT_BUS<=0;
		ELSIF(Clock'EVENT AND Clock='1') THEN
			IF(OUT_BUS = 5 AND Dir = '0') THEN
				RCO<='1';
				OUT_BUS<=0;
			ELSIF(OUT_BUS = 0 AND Dir = '1') THEN
				RCO<='1';
				OUT_BUS<=5;
			ELSE
				RCO<='0';
				IF(Dir='0') THEN
					OUT_BUS<=OUT_BUS + 1;
				ELSE
					OUT_BUS<=OUT_BUS - 1;
				END IF;
			END IF;
		END IF;
	END PROCESS;
END Behavior;

PACKAGE Mod6CounterPackage IS
	COMPONENT Mod6Counter
		PORT(	Clock	:IN BIT;
			Reset :IN BIT;
			Dir	:IN BIT;
			RCO	:OUT BIT;
			OUT_BUS:BUFFER INTEGER RANGE 0 to 5);
	END COMPONENT;
END PACKAGE;	

SegDriver.vhd

 

LIBRARY ieee;
USE ieee.std_logic_1164.all;

ENTITY SegDriver IS
	PORT(
		Digit		:	IN		INTEGER RANGE 0 TO 15;
		Freeze	:	IN		BIT;
		Segment	:	BUFFER	BIT_VECTOR(6 DOWNTO 0));
END ENTITY;

ARCHITECTURE Behavior OF SegDriver IS
	BEGIN
	PROCESS(Digit)
		BEGIN
			IF(Freeze = '0') THEN
				CASE Digit IS
					WHEN 0 => Segment <= "1000000";
					WHEN 1 => Segment <= "1111001";
					WHEN 2 => Segment <= "0100100";
					WHEN 3 => Segment <= "0110000";
					WHEN 4 => Segment <= "0011001";
					WHEN 5 => Segment <= "0010010";
					WHEN 6 => Segment <= "0000010";
					WHEN 7 => Segment <= "1111000";
					WHEN 8 => Segment <= "0000000";
					WHEN 9 => Segment <= "0010000";
					WHEN 10 => Segment <= "0001000";
					WHEN 11 => Segment <= "0000011";
					WHEN 12 => Segment <= "1000110";
					WHEN 13 => Segment <= "0100001";
					WHEN 14 => Segment <= "0000110";
					WHEN 15 => Segment <= "0001110";
				END CASE;
			ELSE
				Segment<=Segment;
			END IF;
	END PROCESS;
END Behavior;

PACKAGE SegDriverPackage IS
	COMPONENT SegDriver
		PORT(
			Digit		:	IN		INTEGER RANGE 0 TO 15;
			Freeze	:	IN		BIT;
			Segment	:	BUFFER	BIT_VECTOR(6 DOWNTO 0));
	END COMPONENT;
END PACKAGE;
Log in to comment