Code can be downloaded here

accumulator_reg.vhd
clockdivider.vhd
instruction_reg.vhd
lightreg.vhd
not8.vhd
pause_button.vhd
pcounter.vhd
prog.vhd
wholething.vhd


back to
top
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_arith.ALL;

entity accumulator_reg is
	port (
			clk, rst : in std_logic;
			instruction_reg: in std_logic_vector (4 downto 0);
			light_reg: in std_logic_vector (7 downto 0);
			selector: in std_logic_vector (2 downto 0);
			q: out std_logic_vector (7 downto 0));
end accumulator_reg;

architecture behavioral of accumulator_reg is
	signal a_reg : unsigned (7 downto 0);
begin
	action: process(clk, rst) begin
		if rst = '1' then a_reg <= "00000000";
		elsif clk = '1' and clk'event then
			case selector is 
			when "000" => if instruction_reg(4) = '0' then
								a_reg(3 downto 0) <= unsigned(instruction_reg(3 downto 0));
								a_reg(7 downto 4) <= a_reg(7 downto 4);
							else 
								a_reg(3 downto 0) <= a_reg(3 downto 0);
								a_reg(7 downto 4) <= unsigned(instruction_reg(3 downto 0));
							end if;
			when "001" => a_reg <= unsigned(light_reg);
			when "011" => a_reg <= not a_reg(7) & not a_reg(6) & not a_reg(5) & not a_reg(4) & 
								   not a_reg(3) & not a_reg(2) & not a_reg(1) & not a_reg(0);
			when "100" => a_reg <= a_reg + 1;
			when "101" => a_reg <= a_reg - 1;
			when "110" => a_reg <= a_reg(6 downto 0) & '0';
			when "111" => a_reg <= '0' & a_reg(7 downto 1);
			when others => a_reg <= a_reg;
			end case;
		end if;
	end process action;
	
	q <= std_logic_vector (a_reg);
end behavioral;


back to
top
library ieee;                           -- always include the ieee libraries
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;

entity clockdivider is
	port(reset, clk: in std_logic;  -- reset and clock input signals
             clockbits: out std_logic_vector(7 downto 0));  -- output clock signals
end clockdivider;

architecture behavioral of clockdivider is
	signal counter: unsigned(23 downto 0);  -- big counter
begin
	process (clk) begin
		if reset = '1' then
			counter <= "000000000000000000000000";  -- on reset,
                                                                -- reset the clock
		elsif clk = '1' and clk'event then  -- otherwise, increment the
                                                    -- counter
			counter <= counter + 1;
		end if;
	end process;

	clockbits <= std_logic_vector(counter(23 downto 16));  -- connect the
                                                               -- counter with
                                                               -- the output
                                                               -- vector using
                                                               -- the type
                                                               -- casting function
end behavioral;



back to
top
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_arith.ALL;

entity instruction_reg is
	port (
			clk, rst: in std_logic;
			data: in std_logic_vector (14 downto 0);
			inst_out: out std_logic_vector (14 downto 0));
end instruction_reg;

architecture behavioral of instruction_reg is
	signal inst_reg : unsigned(14 downto 0);

begin
	action: process(clk, rst) begin
		if rst = '1' then inst_reg <= "000000000000000";
		elsif clk = '1' and clk'event then inst_reg <= unsigned(data);
		end if;
	end process action;
	inst_out <= std_logic_vector(inst_reg);
end behavioral;



back to
top
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_arith.ALL;

-- This entity is a register with multiple inputs.
-- When address is 00, the register maintains its value.
-- When address is 01, the register increments itself.
-- When address is 10, the register loads the value on Data1.
-- When address is 11, the register loads the value on Data2.
ENTITY lightreg IS
	PORT(
		Clk, Rst: 		IN	STD_LOGIC;								-- reset, clock
		Sel: 	IN STD_LOGIC_VECTOR(1 downto 0);			-- action selector
		Inst: IN	STD_LOGIC_VECTOR(4 downto 0);	-- alternative load inputs
		Acc: IN STD_LOGIC_VECTOR(7 DOWNTO 0);   
		Q : OUT	STD_LOGIC_VECTOR(7 downto 0));					-- output
END lightreg;

ARCHITECTURE behavioral OF lightreg IS
	SIGNAL Qreg: UNSIGNED (7 downto 0);	-- internal register representation, stores output.
BEGIN
	action:	PROCESS(Clk, Rst) BEGIN
		if Rst = '1' then Qreg <= "00000000";
		elsif clk = '1' and clk'event then
			case Sel is	-- if there is a rising edge, then load from the selected source
			when "00" => if Inst(4) = '0' then 
							Qreg(3 downto 0) <= UNSIGNED(Inst(3 downto 0)); 
							Qreg(7 downto 4) <= Qreg(7 downto 4);-- Load from the instruction register
						else Qreg(3 downto 0) <= Qreg(3 downto 0);
							Qreg(7 downto 4) <= UNSIGNED(Inst(3 downto 0));
						end if;
			when "01" => Qreg <= UNSIGNED(Acc);
			when "11" => Qreg(0) <= not Qreg(0);
							Qreg(1) <= not Qreg(1);
							Qreg(2) <= not Qreg(2);
							Qreg(3) <= not Qreg(3);
							Qreg(4) <= not Qreg(4);
							Qreg(5) <= not Qreg(5);
							Qreg(6) <= not Qreg(6);
							Qreg(7) <= not Qreg(7);
			when others => Qreg <= Qreg;			-- maintain value on all other inputs
			end case;								-- Note: since std_logic is a multi-
		end if;										-- value logic, this keeps the synthesis simple
	END PROCESS action;

	Q <= STD_LOGIC_VECTOR(Qreg);	-- write the register value to the output
		   							-- you could put an output enable switch here as well.
END behavioral;






back to
top
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_arith.ALL;

entity not8 is
	port( a: in std_logic_vector (7 downto 0);
			b: out std_logic_vector (7 downto 0) );
end not8;

architecture abc of not8 is

begin
	b(7 downto 0) <= not a(7) & not a(6) & not a(5) & not a(4) 
						& not a(3) & not a(2) & not a(1) & not a(0);
end abc;



back to
top
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_arith.ALL;

ENTITY pause_button IS
	PORT(
	clk, p_button:	IN STD_LOGIC;
	clk_out:	OUT STD_LOGIC);
END pause_button;

ARCHITECTURE behavioral OF pause_button IS	
BEGIN
	clk_out <= p_button and clk;
END behavioral;
	


back to
top
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_arith.ALL;

-- This entity is a register with multiple inputs.
-- When address is 00, the register maintains its value.
-- When address is 01, the register increments itself.
-- When address is 10, the register loads the value on Data1.
-- When address is 11, the register loads the value on Data2.
ENTITY pcounter IS
	PORT(
		Jmp, Acc: IN	STD_LOGIC;							-- reset, clock
		Inputs: IN STD_LOGIC_VECTOR(3 downto 0);			-- action selector
		Q : OUT	STD_LOGIC_VECTOR(3 downto 0));				-- output
END pcounter;

ARCHITECTURE behavioral OF pcounter IS
	SIGNAL Qreg: UNSIGNED (3 downto 0);	-- internal register representation
BEGIN
	action:	PROCESS(Inputs, Jmp, Acc) BEGIN
		if (Jmp = '1' and Acc = '1') then
			Qreg <= UNSIGNED(Inputs) + 1;
		else Qreg <= UNSIGNED(Inputs);
		end if;										-- value logic, this keeps the synthesis simple
	END PROCESS action;

	Q <= STD_LOGIC_VECTOR(Qreg);	-- write the register value to the output
									-- you could put an output enable switch here as well.
END behavioral;





back to
top
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_arith.ALL;

entity prog is
	port(pc: in std_logic_vector (3 downto 0);
		program_am_i_being: in std_logic;
		program_input_address: in std_logic_vector(3 downto 0);
		program_command: in std_logic_vector(7 downto 0);
		program_hilo_toggle: in std_logic;
		data: out std_logic_vector (14 downto 0));
end prog;

architecture abc of prog is
subtype memory_unit is std_logic_vector(14 downto 0);
type total_mem is array(15 downto 0) of memory_unit;
signal mem: total_mem;

begin
	process (program_am_i_being) begin
	if program_am_i_being = '1' then -- we're being programmed
		if program_hilo_toggle = '0' then  -- we're programming the low 8 bits
			case program_input_address is 

				when "0000" => mem(0)(7 downto 0) <= program_command;
				when "0001" => mem(1)(7 downto 0) <= program_command;
				when "0010" => mem(2)(7 downto 0) <= program_command;
				when "0011" => mem(3)(7 downto 0) <= program_command;
				when "0100" => mem(4)(7 downto 0) <= program_command;
				when "0101" => mem(5)(7 downto 0) <= program_command;
				when "0110" => mem(6)(7 downto 0) <= program_command;
				when "0111" => mem(7)(7 downto 0) <= program_command;
				when "1000" => mem(8)(7 downto 0) <= program_command;
				when "1001" => mem(9)(7 downto 0) <= program_command;
				when "1010" => mem(10)(7 downto 0) <= program_command;
				when "1011" => mem(11)(7 downto 0) <= program_command;
				when "1100" => mem(12)(7 downto 0) <= program_command;
				when "1101" => mem(13)(7 downto 0) <= program_command;
				when "1110" => mem(14)(7 downto 0) <= program_command;
				when others => mem(15)(7 downto 0) <= program_command;
			end case;			
		else								-- we're programming the high 8 bits
			case program_input_address is
				when "0000" => mem(0)(14 downto 8) <= program_command(6 downto 0);
				when "0001" => mem(1)(14 downto 8) <= program_command(6 downto 0);
				when "0010" => mem(2)(14 downto 8) <= program_command(6 downto 0);
				when "0011" => mem(3)(14 downto 8) <= program_command(6 downto 0);
				when "0100" => mem(4)(14 downto 8) <= program_command(6 downto 0);
				when "0101" => mem(5)(14 downto 8) <= program_command(6 downto 0);
				when "0110" => mem(6)(14 downto 8) <= program_command(6 downto 0);
				when "0111" => mem(7)(14 downto 8) <= program_command(6 downto 0);
				when "1000" => mem(8)(14 downto 8) <= program_command(6 downto 0);
				when "1001" => mem(9)(14 downto 8) <= program_command(6 downto 0);
				when "1010" => mem(10)(14 downto 8) <= program_command(6 downto 0);
				when "1011" => mem(11)(14 downto 8) <= program_command(6 downto 0);
				when "1100" => mem(12)(14 downto 8) <= program_command(6 downto 0);
				when "1101" => mem(13)(14 downto 8) <= program_command(6 downto 0);
				when "1110" => mem(14)(14 downto 8) <= program_command(6 downto 0);
				when others => mem(15)(14 downto 8) <= program_command(6 downto 0);
			end case;
		end if;  -- end the hi/lo bit if clause
		-- data <= "000000000000000"; 
	end if;
end process;



process (pc) begin
--	else 		-- we are not being programmed
		case pc is
			when "0000" => data <= mem(0);
			when "0001" => data <= mem(1);
			when "0010" => data <= mem(2);
			when "0011" => data <= mem(3);
			when "0100" => data <= mem(4);
			when "0101" => data <= mem(5);
			when "0110" => data <= mem(6);
			when "0111" => data <= mem(7);
			when "1000" => data <= mem(8);
			when "1001" => data <= mem(9);
			when "1010" => data <= mem(10);
			when "1011" => data <= mem(11);
			when "1100" => data <= mem(12);
			when "1101" => data <= mem(13);
			when "1110" => data <= mem(14);
			when others => data <= mem(15);
		end case;
	--end if;
end process;

end abc;



back to
top
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.std_logic_arith.ALL;

ENTITY wholething IS
	PORT(Clk, Rst, p_button: 	IN	STD_LOGIC;		-- reset, clock
		Q : 	OUT	STD_LOGIC_VECTOR(7 downto 0));
END wholething;

ARCHITECTURE structural OF wholething IS
	component not8                                   -- the not gates 
	port( a: in std_logic_vector (7 downto 0);
			b: out std_logic_vector (7 downto 0) );
	end component;

	component pause_button
	port( clk, p_button: in std_logic;
			clk_out: out std_logic);
	end component;
	
	component lightreg 
	port(Clk, Rst: 	IN	STD_LOGIC;							-- reset, clock
		Sel: 		IN STD_LOGIC_VECTOR(1 downto 0);		-- action selector
		Inst: 		IN	STD_LOGIC_VECTOR(4 downto 0);		-- alternative load inputs
		Acc: 		IN STD_LOGIC_VECTOR(7 DOWNTO 0);   		
		Q : 		OUT	STD_LOGIC_VECTOR(7 downto 0));		-- output
	end component;
	component accumulator_reg 
	port (	clk, rst : in std_logic;
			instruction_reg: in std_logic_vector (4 downto 0);
			light_reg: in std_logic_vector (7 downto 0);
			selector: in std_logic_vector (2 downto 0);
			q: out std_logic_vector (7 downto 0));
	end component;
	component instruction_reg
	port (
			clk, rst: in std_logic;
			data: in std_logic_vector (14 downto 0);
			inst_out: out std_logic_vector (14 downto 0));
	end component;
	component prog
		port(pc: in std_logic_vector (3 downto 0);
		data: out std_logic_vector (14 downto 0));
	end component;
	component pcounter
	PORT(
		Jmp, Acc: IN	STD_LOGIC;							-- reset, clock
		Inputs: IN STD_LOGIC_VECTOR(3 downto 0);			-- action selector
		Q : OUT	STD_LOGIC_VECTOR(3 downto 0));				-- output
	end component;		
	component clockdivider
		port(reset, clk: in std_logic;  -- reset and clock input signals
             clockbits: out std_logic_vector(7 downto 0));  -- output clock signals
	end component;
	
	signal pause_button_out: std_logic;
	signal light_reg_out : std_logic_vector(7 downto 0);
	signal accumulator_out : std_logic_vector(7 downto 0);
	signal inst_out			: std_logic_vector(14 downto 0);
	signal program_out		: std_logic_vector(14 downto 0);
	signal pc_out			: std_logic_vector(3 downto 0);
	signal clock_out		: std_logic_vector(7 downto 0);
BEGIN
	pause_button_0: pause_button port map( clk, p_button, pause_button_out ); 
	clockdivider_0: clockdivider port map (rst, pause_button_out, clock_out);
	pcounter_0: pcounter port map (inst_out(14), accumulator_out(0), inst_out(3 downto 0), pc_out);
	prog_0: prog port map (pc_out, program_out);
	instruction_reg_0: instruction_reg port map (clock_out(7), rst, program_out, inst_out);
	accumulator_0: accumulator_reg port map(clock_out(7), rst, inst_out(8 downto 4), light_reg_out, 
											inst_out(13 downto 11), accumulator_out);
	lightreg_0: lightreg port map(clock_out(7), Rst, inst_out(10 downto 9), inst_out(8 downto 4), 
									accumulator_out, light_reg_out);
	not8_0 : not8 port map(light_reg_out, Q);
END structural;