LIBRARY ieee;
USE ieee.std_logic_1164.all;
--USE ieee.std_logic_arith.all;


ENTITY clockField IS PORT(
	clk			: IN std_logic; -- System clock; clockField is triggered by rising edges on this clock
	reset		: IN std_logic; -- If '1' resets the values to either 'minLSD' and 'minMSD' (if 'direction' is high) or 'maxLSD' and 'maxMSD' (if 'direction' is low)
	inc			: IN std_logic; -- If '1' on a rising clock edge, increments or decrements the current value (as dependant on 'direction')
	direction	: IN std_logic; -- '1' == up, '0' == down

	-- These min & max values define the two numbers between which the field is permitted to operate.  They apply only in pairs, i.e. if minLSD = 1 and minMSD = 2, the field will never go below '21'.  This doesn't stop the LSD counting about 1; it will always count from 0 to 9.

	minLSD		: IN integer RANGE 0 to 9; -- The minimum value of the LSD (only applies if the MSD is equal to 'minMSD'
	minMSD		: IN integer RANGE 0 to 9; -- The minimum value of the MSD
	maxLSD		: IN integer RANGE 0 to 9; -- The maximum value of the LSD (only applies if the MSD is equal to 'maxMSD'
	maxMSD		: IN integer RANGE 0 to 9; -- The maximum value of the MSD

	lsd			: BUFFER integer range 0 to 9; -- The 7-segment display on which to put the LSD
	msd			: BUFFER integer range 0 to 9; -- The 7-segment display on which to put the MSD
	carry		: BUFFER std_logic); -- Will be high for one clock cycle if the field overflows
END clockField;

ARCHITECTURE main OF clockField IS
BEGIN
	fieldClocker: process(clk) begin
		if (clk'event and clk = '1') then
			carry <= '0'; -- Default to zero

			if ((reset = '1') or (msd < minMSD) or ((msd = minMSD) and (lsd < minLSD)) or (msd > maxMSD) or ((msd = maxMSD) and (lsd > maxLSD))) then
				if (direction = '1') then
					lsd <= minLSD;
					msd <= minMSD;
				else
					lsd <= maxLSD;
					msd <= maxMSD;
				end if;
			else
				if (inc = '1') then
					if (direction = '1') then
						if ((lsd = maxLSD) and (msd = maxMSD)) then
							carry <= '1';
							lsd <= minLSD;
							msd <= minMSD;
						else
							if (lsd = 9) then
								if (msd = 9) then
									msd <= 0;
								else
									msd <= msd + 1;
								end if;
	
								lsd <= 0;
							else
								lsd <= lsd + 1;
							end if;
						end if;
					else
						if ((lsd = minLSD) and (msd = minMSD)) then
							carry <= '1';
							lsd <= maxLSD;
							msd <= maxMSD;
						else
							if (lsd = 0) then
								if (msd = 0) then
									msd <= 9;
								else
									msd <= msd - 1;
								end if;

								lsd <= 9;
							else
								lsd <= lsd - 1;
							end if;
						end if;
					end if;
				end if;
			end if;
		end if;
	end process;
END main;
