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);
data: out std_logic_vector (14 downto 0));
end prog;
architecture abc of prog is
begin
process (pc) begin
data <= "010001000000000";
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
program_assert: in STD_LOGIC;
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;