Init
This commit is contained in:
commit
d8e66ba4bf
11 changed files with 523 additions and 0 deletions
54
ALU.vhdl
Normal file
54
ALU.vhdl
Normal file
|
@ -0,0 +1,54 @@
|
|||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.STD_LOGIC_ARITH.ALL;
|
||||
use IEEE.STD_LOGIC_UNSIGNED.ALL;
|
||||
|
||||
entity ALU is
|
||||
Port (
|
||||
A, B : in STD_LOGIC_VECTOR(7 downto 0); -- Input operands A and B
|
||||
ALUOp : in STD_LOGIC_VECTOR(2 downto 0); -- ALU operation code
|
||||
ALUSrc : in STD_LOGIC; -- Select between B and an immediate value
|
||||
result : out STD_LOGIC_VECTOR(7 downto 0) -- Output result
|
||||
);
|
||||
end ALU;
|
||||
|
||||
architecture Behavioral of ALU is
|
||||
begin
|
||||
process (A, B, ALUOp, ALUSrc)
|
||||
variable temp_result : STD_LOGIC_VECTOR(7 downto 0);
|
||||
begin
|
||||
-- Initialize temp_result to zero
|
||||
temp_result := (others => '0');
|
||||
|
||||
-- Perform ALU operations based on ALUOp
|
||||
case ALUOp is
|
||||
when "000" =>
|
||||
if ALUSrc = '1' then
|
||||
temp_result := A + B; -- ADD operation
|
||||
else
|
||||
temp_result := A + (others => '1'); -- ADD with immediate value
|
||||
end if;
|
||||
when "001" =>
|
||||
if ALUSrc = '1' then
|
||||
temp_result := A - B; -- SUB operation
|
||||
else
|
||||
temp_result := A - (others => '1'); -- SUB with immediate value
|
||||
end if;
|
||||
when "010" =>
|
||||
temp_result := A AND B; -- AND operation
|
||||
when "011" =>
|
||||
temp_result := A OR B; -- OR operation
|
||||
when "100" =>
|
||||
temp_result := A XOR B; -- XOR operation
|
||||
when "101" =>
|
||||
-- You can add more operations here as needed
|
||||
-- temp_result := ...;
|
||||
|
||||
when others =>
|
||||
-- Handle undefined or unsupported operations
|
||||
temp_result := (others => '0');
|
||||
end case;
|
||||
|
||||
result <= temp_result; -- Output the result
|
||||
end process;
|
||||
end Behavioral;
|
30
dest.vhdl
Normal file
30
dest.vhdl
Normal file
|
@ -0,0 +1,30 @@
|
|||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
|
||||
entity Destination_Block is
|
||||
Port (
|
||||
regEna : in STD_LOGIC; -- Input register enable signal
|
||||
dest : in STD_LOGIC; -- Input destination select signal (0 or 1)
|
||||
ena0 : out STD_LOGIC; -- Output enable signal for register 0
|
||||
ena1 : out STD_LOGIC -- Output enable signal for register 1
|
||||
);
|
||||
end Destination_Block;
|
||||
|
||||
architecture Behavioral of Destination_Block is
|
||||
begin
|
||||
process (regEna, dest)
|
||||
begin
|
||||
-- Initialize outputs to default values
|
||||
ena0 <= '0';
|
||||
ena1 <= '0';
|
||||
|
||||
-- Enable the selected destination register based on dest signal
|
||||
if regEna = '1' then
|
||||
if dest = '0' then
|
||||
ena0 <= '1';
|
||||
else
|
||||
ena1 <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
end Behavioral;
|
70
instruction_decoder.vhdl
Normal file
70
instruction_decoder.vhdl
Normal file
|
@ -0,0 +1,70 @@
|
|||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
|
||||
entity Instruction_Decoder is
|
||||
Port (
|
||||
opcode : in STD_LOGIC_VECTOR(3 downto 0); -- Input opcode
|
||||
z_flag : in STD_LOGIC; -- Input zero flag
|
||||
IntDone : in STD_LOGIC; -- Input interrupt done signal
|
||||
stackOp : out STD_LOGIC; -- Output stack operation signal
|
||||
addrSrc : out STD_LOGIC_VECTOR(1 downto 0); -- Output address source select
|
||||
ALUOp : out STD_LOGIC_VECTOR(2 downto 0); -- Output ALU operation select
|
||||
ALUSrc : out STD_LOGIC; -- Output ALU source select
|
||||
regEna : out STD_LOGIC; -- Output register enable signal
|
||||
OutEna : out STD_LOGIC -- Output data output enable signal
|
||||
);
|
||||
end Instruction_Decoder;
|
||||
|
||||
architecture Behavioral of Instruction_Decoder is
|
||||
begin
|
||||
process (opcode, z_flag, IntDone)
|
||||
begin
|
||||
-- Initialize outputs to default values
|
||||
stackOp <= '0';
|
||||
addrSrc <= "00";
|
||||
ALUOp <= "000";
|
||||
ALUSrc <= '0';
|
||||
regEna <= '0';
|
||||
OutEna <= '0';
|
||||
|
||||
-- Decode instructions based on opcode [12:9]
|
||||
case opcode is
|
||||
when "0000" =>
|
||||
stackOp <= '1'; -- Instruction 0000: Push onto stack
|
||||
when "0001" =>
|
||||
stackOp <= '0'; -- Instruction 0001: Pop from stack
|
||||
when "0010" =>
|
||||
addrSrc <= "01"; -- Instruction 0010: Load address from register
|
||||
regEna <= '1';
|
||||
OutEna <= '1';
|
||||
when "0011" =>
|
||||
ALUOp <= "001"; -- Instruction 0011: ALU operation ADD
|
||||
ALUSrc <= '1';
|
||||
OutEna <= '1';
|
||||
when "0100" =>
|
||||
ALUOp <= "010"; -- Instruction 0100: ALU operation SUB
|
||||
ALUSrc <= '1';
|
||||
OutEna <= '1';
|
||||
when "0101" =>
|
||||
ALUOp <= "011"; -- Instruction 0101: ALU operation AND
|
||||
ALUSrc <= '1';
|
||||
OutEna <= '1';
|
||||
when "0110" =>
|
||||
ALUOp <= "100"; -- Instruction 0110: ALU operation OR
|
||||
ALUSrc <= '1';
|
||||
OutEna <= '1';
|
||||
when "0111" =>
|
||||
ALUOp <= "101"; -- Instruction 0111: ALU operation XOR
|
||||
ALUSrc <= '1';
|
||||
OutEna <= '1';
|
||||
when "1000" =>
|
||||
if z_flag = '1' then
|
||||
addrSrc <= "10"; -- Instruction 1000: Jump if Zero (JZ)
|
||||
else
|
||||
addrSrc <= "11"; -- Instruction 1000: Jump if Not Zero (JNZ)
|
||||
end if;
|
||||
when others =>
|
||||
null; -- Other instructions not specified, outputs remain at default values
|
||||
end case;
|
||||
end process;
|
||||
end Behavioral;
|
60
int_handler_v1.vhdl
Normal file
60
int_handler_v1.vhdl
Normal file
|
@ -0,0 +1,60 @@
|
|||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
|
||||
entity Interrupt_Handler is
|
||||
Port (
|
||||
int0 : in STD_LOGIC; -- Input interrupt request signal
|
||||
int_done : in STD_LOGIC; -- Input signal indicating interrupt processing is done
|
||||
int_addr : out STD_LOGIC_VECTOR(3 downto 0); -- Output interrupt address
|
||||
int_mux : out STD_LOGIC; -- Output interrupt multiplexer control signal
|
||||
save_wreg : out STD_LOGIC; -- Output signal to save work register content
|
||||
restore_wreg: out STD_LOGIC -- Output signal to restore work register content
|
||||
);
|
||||
end Interrupt_Handler;
|
||||
|
||||
architecture Behavioral of Interrupt_Handler is
|
||||
signal pending_interrupt : STD_LOGIC := '0'; -- Internal signal to track pending interrupts
|
||||
|
||||
begin
|
||||
-- Logic to detect an interrupt request
|
||||
process (int0, int_done)
|
||||
begin
|
||||
if int0 = '1' and int_done = '0' then
|
||||
pending_interrupt <= '1'; -- Set pending_interrupt to indicate a new interrupt request
|
||||
else
|
||||
pending_interrupt <= '0';
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Interrupt address generation logic (you can modify this as needed)
|
||||
-- For simplicity, this example just assigns an address based on the presence of a pending interrupt.
|
||||
process (pending_interrupt)
|
||||
begin
|
||||
if pending_interrupt = '1' then
|
||||
int_addr <= "0000"; -- Set the interrupt address
|
||||
else
|
||||
int_addr <= (others => '0'); -- No interrupt pending, so address is all zeros
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Interrupt multiplexer control logic (you can modify this as needed)
|
||||
-- For simplicity, this example enables the multiplexer only if there's a pending interrupt.
|
||||
process (pending_interrupt)
|
||||
begin
|
||||
if pending_interrupt = '1' then
|
||||
int_mux <= '1'; -- Enable the multiplexer
|
||||
else
|
||||
int_mux <= '0'; -- Disable the multiplexer
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Save and restore work register control signals (you can modify this as needed)
|
||||
-- For simplicity, this example sets save_wreg when an interrupt is pending and
|
||||
-- restore_wreg when interrupt processing is done.
|
||||
process (pending_interrupt, int_done)
|
||||
begin
|
||||
save_wreg <= pending_interrupt;
|
||||
restore_wreg <= int_done;
|
||||
end process;
|
||||
|
||||
end Behavioral;
|
71
int_handler_v2.vhdl
Normal file
71
int_handler_v2.vhdl
Normal file
|
@ -0,0 +1,71 @@
|
|||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
|
||||
entity Interrupt_Handler is
|
||||
Port (
|
||||
clk : in STD_LOGIC; -- Clock input
|
||||
rst : in STD_LOGIC; -- Reset input
|
||||
int0 : in STD_LOGIC; -- Input interrupt request signal
|
||||
int_done : in STD_LOGIC; -- Input signal indicating interrupt processing is done
|
||||
ret_addr : in STD_LOGIC_VECTOR(3 downto 0); -- Input return address
|
||||
int_addr : out STD_LOGIC_VECTOR(3 downto 0); -- Output interrupt address
|
||||
int_mux : out STD_LOGIC; -- Output interrupt multiplexer control signal
|
||||
save_wreg : out STD_LOGIC; -- Output signal to save work register content
|
||||
restore_wreg: out STD_LOGIC -- Output signal to restore work register content
|
||||
);
|
||||
end Interrupt_Handler;
|
||||
|
||||
architecture Behavioral of Interrupt_Handler is
|
||||
signal pending_interrupt : STD_LOGIC := '0'; -- Internal signal to track pending interrupts
|
||||
|
||||
begin
|
||||
-- Reset logic
|
||||
process (rst)
|
||||
begin
|
||||
if rst = '1' then
|
||||
pending_interrupt <= '0'; -- Clear pending interrupt on reset
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Logic to detect an interrupt request
|
||||
process (int0, int_done)
|
||||
begin
|
||||
if int0 = '1' and int_done = '0' then
|
||||
pending_interrupt <= '1'; -- Set pending_interrupt to indicate a new interrupt request
|
||||
else
|
||||
pending_interrupt <= '0';
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Interrupt address generation logic (you can modify this as needed)
|
||||
-- For simplicity, this example just assigns an address based on the presence of a pending interrupt.
|
||||
process (pending_interrupt)
|
||||
begin
|
||||
if pending_interrupt = '1' then
|
||||
int_addr <= "0000"; -- Set the interrupt address
|
||||
else
|
||||
int_addr <= (others => '0'); -- No interrupt pending, so address is all zeros
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Interrupt multiplexer control logic (you can modify this as needed)
|
||||
-- For simplicity, this example enables the multiplexer only if there's a pending interrupt.
|
||||
process (pending_interrupt)
|
||||
begin
|
||||
if pending_interrupt = '1' then
|
||||
int_mux <= '1'; -- Enable the multiplexer
|
||||
else
|
||||
int_mux <= '0'; -- Disable the multiplexer
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-- Save and restore work register control signals (you can modify this as needed)
|
||||
-- For simplicity, this example sets save_wreg when an interrupt is pending and
|
||||
-- restore_wreg when interrupt processing is done.
|
||||
process (pending_interrupt, int_done)
|
||||
begin
|
||||
save_wreg <= pending_interrupt;
|
||||
restore_wreg <= int_done;
|
||||
end process;
|
||||
|
||||
end Behavioral;
|
24
mplex_8to1.vhdl
Normal file
24
mplex_8to1.vhdl
Normal file
|
@ -0,0 +1,24 @@
|
|||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
|
||||
entity Multiplexer_8to1 is
|
||||
Port (
|
||||
Data_0 : in STD_LOGIC_VECTOR(7 downto 0);
|
||||
Data_1 : in STD_LOGIC_VECTOR(7 downto 0);
|
||||
Sel : in STD_LOGIC_VECTOR(2 downto 0);
|
||||
Y : out STD_LOGIC_VECTOR(7 downto 0)
|
||||
);
|
||||
end Multiplexer_8to1;
|
||||
|
||||
architecture Behavioral of Multiplexer_8to1 is
|
||||
begin
|
||||
process(Data_0, Data_1, Sel)
|
||||
begin
|
||||
case Sel is
|
||||
when "000" =>
|
||||
Y <= Data_0;
|
||||
when others =>
|
||||
Y <= Data_1;
|
||||
end case;
|
||||
end process;
|
||||
end Behavioral;
|
45
multiplexer.vhdl
Normal file
45
multiplexer.vhdl
Normal file
|
@ -0,0 +1,45 @@
|
|||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.STD_LOGIC_ARITH.ALL;
|
||||
use IEEE.STD_LOGIC_UNSIGNED.ALL;
|
||||
|
||||
entity Multiplexer_8to1 is
|
||||
Port (
|
||||
Data_0 : in STD_LOGIC;
|
||||
Data_1 : in STD_LOGIC;
|
||||
Data_2 : in STD_LOGIC;
|
||||
Data_3 : in STD_LOGIC;
|
||||
Data_4 : in STD_LOGIC;
|
||||
Data_5 : in STD_LOGIC;
|
||||
Data_6 : in STD_LOGIC;
|
||||
Data_7 : in STD_LOGIC;
|
||||
Sel : in STD_LOGIC_VECTOR(2 downto 0);
|
||||
Y : out STD_LOGIC
|
||||
);
|
||||
end Multiplexer_8to1;
|
||||
|
||||
architecture Behavioral of Multiplexer_8to1 is
|
||||
begin
|
||||
process(Sel, Data_0, Data_1, Data_2, Data_3, Data_4, Data_5, Data_6, Data_7)
|
||||
begin
|
||||
case Sel is
|
||||
when "000" =>
|
||||
Y <= Data_0;
|
||||
when "001" =>
|
||||
Y <= Data_1;
|
||||
when "010" =>
|
||||
Y <= Data_2;
|
||||
when "011" =>
|
||||
Y <= Data_3;
|
||||
when "100" =>
|
||||
Y <= Data_4;
|
||||
when "101" =>
|
||||
Y <= Data_5;
|
||||
when "110" =>
|
||||
Y <= Data_6;
|
||||
when others =>
|
||||
Y <= Data_7;
|
||||
end case;
|
||||
end process;
|
||||
end Behavioral;
|
||||
|
31
program_counter.vhdl
Normal file
31
program_counter.vhdl
Normal file
|
@ -0,0 +1,31 @@
|
|||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
use IEEE.STD_LOGIC_ARITH.ALL;
|
||||
use IEEE.STD_LOGIC_UNSIGNED.ALL;
|
||||
|
||||
entity Program_Counter is
|
||||
Port (
|
||||
clk : in STD_LOGIC; -- Clock input
|
||||
rst : in STD_LOGIC; -- Reset input
|
||||
increment : in STD_LOGIC; -- Signal to increment the PC
|
||||
addr : out STD_LOGIC_VECTOR(7 downto 0) -- Program counter output
|
||||
);
|
||||
end Program_Counter;
|
||||
|
||||
architecture Behavioral of Program_Counter is
|
||||
signal pc_reg : STD_LOGIC_VECTOR(7 downto 0) := "00000000"; -- Initial value for the program counter
|
||||
|
||||
begin
|
||||
process (clk, rst, increment)
|
||||
begin
|
||||
if rst = '1' then
|
||||
pc_reg <= "00000000"; -- Reset the program counter to 0
|
||||
elsif rising_edge(clk) then
|
||||
if increment = '1' then
|
||||
pc_reg <= pc_reg + 1; -- Increment the program counter
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
addr <= pc_reg; -- Output the program counter value
|
||||
end Behavioral;
|
29
reg_8.vhdl
Normal file
29
reg_8.vhdl
Normal file
|
@ -0,0 +1,29 @@
|
|||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
|
||||
entity Register_8bit is
|
||||
Port (
|
||||
D : in STD_LOGIC_VECTOR(7 downto 0);
|
||||
ena : in STD_LOGIC;
|
||||
clk : in STD_LOGIC;
|
||||
rst : in STD_LOGIC;
|
||||
Q : out STD_LOGIC_VECTOR(7 downto 0)
|
||||
);
|
||||
end Register_8bit;
|
||||
|
||||
architecture Behavioral of Register_8bit is
|
||||
signal Q_reg : STD_LOGIC_VECTOR(7 downto 0);
|
||||
begin
|
||||
process (clk, rst)
|
||||
begin
|
||||
if rst = '1' then
|
||||
Q_reg <= (others => '0');
|
||||
elsif rising_edge(clk) then
|
||||
if ena = '1' then
|
||||
Q_reg <= D;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
Q <= Q_reg;
|
||||
end Behavioral;
|
40
stack.vhdl
Normal file
40
stack.vhdl
Normal file
|
@ -0,0 +1,40 @@
|
|||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
|
||||
entity Stack is
|
||||
Port (
|
||||
push : in STD_LOGIC; -- Signal to push data onto the stack
|
||||
pop : in STD_LOGIC; -- Signal to pop data from the stack
|
||||
data_in : in STD_LOGIC_VECTOR(7 downto 0); -- Input data to be pushed onto the stack
|
||||
data_out: out STD_LOGIC_VECTOR(7 downto 0) -- Data popped from the stack
|
||||
);
|
||||
end Stack;
|
||||
|
||||
architecture Behavioral of Stack is
|
||||
type Stack_Type is array (0 to 7) of STD_LOGIC_VECTOR(7 downto 0);
|
||||
signal stack_memory : Stack_Type;
|
||||
signal stack_pointer: STD_LOGIC_VECTOR(2 downto 0) := "000"; -- Initial stack pointer
|
||||
|
||||
begin
|
||||
process (push, pop, data_in)
|
||||
begin
|
||||
if push = '1' then
|
||||
if stack_pointer = "111" then
|
||||
-- Stack is full, no more pushing allowed
|
||||
report "Stack Overflow";
|
||||
else
|
||||
stack_memory(to_integer(unsigned(stack_pointer))) <= data_in;
|
||||
stack_pointer <= stack_pointer + 1;
|
||||
end if;
|
||||
elsif pop = '1' then
|
||||
if stack_pointer = "000" then
|
||||
-- Stack is empty, no more popping allowed
|
||||
report "Stack Underflow";
|
||||
else
|
||||
stack_pointer <= stack_pointer - 1;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
data_out <= stack_memory(to_integer(unsigned(stack_pointer))); -- Output the data from the stack
|
||||
end Behavioral;
|
69
work_reg_block.vhdl
Normal file
69
work_reg_block.vhdl
Normal file
|
@ -0,0 +1,69 @@
|
|||
library IEEE;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
|
||||
entity Work_Register_Block is
|
||||
Port (
|
||||
save_wreg : in STD_LOGIC;
|
||||
restore_wreg: in STD_LOGIC;
|
||||
D : in STD_LOGIC_VECTOR(7 downto 0);
|
||||
ena : in STD_LOGIC;
|
||||
clk : in STD_LOGIC;
|
||||
rst : in STD_LOGIC;
|
||||
Q : out STD_LOGIC_VECTOR(7 downto 0)
|
||||
);
|
||||
end Work_Register_Block;
|
||||
|
||||
architecture Behavioral of Work_Register_Block is
|
||||
signal reg1_out : STD_LOGIC_VECTOR(7 downto 0);
|
||||
signal reg2_out : STD_LOGIC_VECTOR(7 downto 0);
|
||||
signal mux_sel : STD_LOGIC_VECTOR(2 downto 0);
|
||||
|
||||
component Multiplexer_8to1 is
|
||||
Port (
|
||||
Data_0 : in STD_LOGIC_VECTOR(7 downto 0);
|
||||
Data_1 : in STD_LOGIC_VECTOR(7 downto 0);
|
||||
Sel : in STD_LOGIC_VECTOR(2 downto 0);
|
||||
Y : out STD_LOGIC_VECTOR(7 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
component Register_8bit is
|
||||
Port (
|
||||
D : in STD_LOGIC_VECTOR(7 downto 0);
|
||||
ena : in STD_LOGIC;
|
||||
clk : in STD_LOGIC;
|
||||
rst : in STD_LOGIC;
|
||||
Q : out STD_LOGIC_VECTOR(7 downto 0)
|
||||
);
|
||||
end component;
|
||||
|
||||
begin
|
||||
mux_sel <= "000" when save_wreg = '1' else "001";
|
||||
reg1_out <= D when save_wreg = '1' else reg2_out;
|
||||
|
||||
Mux1: Multiplexer_8to1
|
||||
port map (
|
||||
Data_0 => reg2_out,
|
||||
Data_1 => D,
|
||||
Sel => mux_sel,
|
||||
Y => reg1_out
|
||||
);
|
||||
|
||||
Register1: Register_8bit
|
||||
port map (
|
||||
D => reg1_out,
|
||||
ena => ena,
|
||||
clk => clk,
|
||||
rst => rst,
|
||||
Q => reg2_out
|
||||
);
|
||||
|
||||
Register2: Register_8bit
|
||||
port map (
|
||||
D => reg2_out,
|
||||
ena => restore_wreg,
|
||||
clk => clk,
|
||||
rst => rst,
|
||||
Q => Q
|
||||
);
|
||||
end Behavioral;
|
Loading…
Reference in a new issue