VHDL: MIPS final project
TOP
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
use work.MIPS_LIB.all;
entity Mips is
port (
clk : in std_logic;
rst : in std_logic;
sw_inport_data : in std_logic_vector(8 downto 0);
sw_inport_sel : in std_logic;
sw_inport_wr : in std_logic;
outport: out std_logic_vector(31 downto 0)
);
end Mips;
architecture logic of Mips is
signal PC_write : std_logic;
signal I_or_D : std_logic;
signal mem_write : std_logic;
signal mem_read : std_logic;
signal mem_reg : std_logic;
signal ir_write : std_logic;
signal is_signed : std_logic;
signal reg_write : std_logic;
signal jmp_link: std_logic;
signal reg_dst : std_logic;
signal alu_A : std_logic;
signal alu_B : std_logic_vector(1 downto 0);
signal PC_src : std_logic_vector(1 downto 0);
signal alu_op : std_logic_vector(5 downto 0);
signal branch : std_logic;
signal IR : std_logic_vector(31 downto 0);
begin
U_Controller: entity work.Controller
port map(
clk=>clk,
rst => rst,
ir_opcode => IR(31 downto 26), -- IR Bits[31:26]
ir_function => IR(5 downto 0), -- IR Bits[05:00]
ir_high_bit16 => IR(16), -- IR Bit [16]
branch => branch,
PC_write => PC_write,
I_or_D => I_or_D ,
mem_write => mem_write ,
mem_read => mem_read ,
mem_reg => mem_reg,
ir_write => ir_write,
is_signed => is_signed,
reg_write => reg_write,
jmp_link => jmp_link,
reg_dst => reg_dst,
alu_A => alu_A ,
alu_B => alu_B,
PC_src => PC_src,
alu_op => alu_op
);
U_Datapath: entity work.datapath
port map(
clk=> clk,
rst=> rst,
pc_load=> PC_write,
IorD => I_or_D,
mem_read=> mem_read,
mem_write=> mem_write,
mem_reg=> mem_reg,
ir_write=> ir_write,
reg_dest=> reg_dst,
reg_write=> reg_write,
alu_A => alu_A,
alu_B=> alu_B,
alu_op=> alu_op,
PC_src=> PC_src ,
is_signed=> is_signed,
jmp_link=> jmp_link,
sw_inport_data=> sw_inport_data,
sw_inport_sel=> sw_inport_sel,
sw_inport_wr=>sw_inport_wr,
branch=> branch,
IR =>IR,
outport=> outport
);
end logic;
CONTROLLER
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
use work.MIPS_LIB.all;
entity controller is
port (
clk, rst : in std_logic;
ir_opcode : in std_logic_vector(5 downto 0); -- IR Bits[31:26]
ir_function : in std_logic_vector(5 downto 0); -- IR Bits[05:00]
ir_high_bit16 : in std_logic; -- IR Bit [16]
branch: in std_logic;
PC_write : out std_logic;
I_or_D : out std_logic;
mem_write : out std_logic;
mem_read : out std_logic;
mem_reg : out std_logic;
ir_write : out std_logic;
is_signed : out std_logic;
reg_write : out std_logic;
jmp_link: out std_logic;
reg_dst : out std_logic;
alu_A : out std_logic;
alu_B : out std_logic_vector(1 downto 0);
PC_src : out std_logic_vector(1 downto 0);
alu_op : out std_logic_vector(5 downto 0)
);
end controller;
architecture logic of controller is
type STATE_TYPE is ( IR_FETCH, IR_DECODE,
RTYPE_EXEC, ITYPE_EXEC, REGFILE_WR,
LOAD_PC_JUMP_BRANCH, MEM_READ_ST,MEM_WRITE_ST, State_OPCODE_HALT );
signal state, next_state : STATE_TYPE;
begin
process(clk, rst)
begin
if (rst = '1') then
state <= IR_FETCH;
elsif(clk'event and clk = '1') then
state <= next_state;
end if;
end process;
process(state, ir_opcode, ir_function, ir_high_bit16, branch )
begin
case state is
when IR_FETCH =>
PC_write <= '1'; -- Update PC (PC<-PC+4)
I_or_D <= '0';
mem_write <= '0';
mem_read <= '1'; -- Read Mem (Next Instruction)
mem_reg <= '0';
ir_write <= '1'; -- Load Next Instruction IR<-MEM[PC]
is_signed <= '0';
reg_write <= '0';
jmp_link <= '0';
reg_dst <= '0';
alu_A <= '0'; -- Select ALU-A = PC
alu_B <= "01"; -- Select ALU-B = 4 (Used to Inc PC by 1)
alu_op <= ALU_OP_ADDU; -- Result = PC + 4
PC_src <= "00"; -- Seelct ALU RESULT
next_state <= IR_DECODE;
when IR_DECODE =>
-- Defaults
PC_write <= '0';
I_or_D <= '0';
mem_write <= '0';
mem_read <= '0';
mem_reg <= '0';
ir_write <= '0';
is_signed <= '0';
reg_write <= '0';
jmp_link <= '0';
reg_dst <= '0';
alu_A <= '1'; -- Select RegFile-A
alu_B <= "00"; -- Select RegFile-B
alu_op <= ALU_OP_ADDU;
PC_src <= "00"; -- N/A
if ( ir_opcode = OPCODE_RTYPE ) then
next_state <= RTYPE_EXEC;
elsif ( ir_opcode = OPCODE_HALT ) then
next_state <= State_OPCODE_HALT;
elsif( ir_opcode = OPCODE_J ) then
next_state<=LOAD_PC_JUMP_BRANCH;
else
next_state <= ITYPE_EXEC;
end if;
when RTYPE_EXEC =>
PC_write <= '0';
I_or_D <= '0';
mem_write <= '0';
mem_read <= '0';
mem_reg <= '0';
ir_write <= '0';
is_signed <= '0';
reg_write <= '0';
jmp_link <= '0';
reg_dst <= '0';
alu_A <= '1'; -- Select RegFile-A
alu_B <= "00"; -- Select RegFile-B
PC_src <= "00"; -- N/A
next_state <= REGFILE_WR;
if ( ir_function = OP0_FUNC_ADDU ) then
alu_op <= ALU_OP_ADDU;
elsif ( ir_function = OP0_FUNC_SUBU ) then
alu_op <= ALU_OP_SUBU;
elsif ( ir_function = OP0_FUNC_MULT ) then
alu_op <= ALU_OP_MULT;
next_state <= IR_FETCH; -- Note: No RegFile Write needed
elsif ( ir_function = OP0_FUNC_MULTU ) then
alu_op <= ALU_OP_MULTU;
next_state <= IR_FETCH; -- Note: No RegFile Write needed
elsif ( ir_function = OP0_FUNC_AND ) then
alu_op <= ALU_OP_AND;
elsif ( ir_function = OP0_FUNC_OR ) then
alu_op <= ALU_OP_OR;
elsif ( ir_function = OP0_FUNC_XOR ) then
alu_op <= ALU_OP_XOR;
elsif ( ir_function = OP0_FUNC_SRL ) then
alu_op <= ALU_OP_SRL;
elsif ( ir_function = OP0_FUNC_SLL ) then
alu_op <= ALU_OP_SLL;
elsif ( ir_function = OP0_FUNC_SRA ) then
alu_op <= ALU_OP_SRA;
elsif ( ir_function = OP0_FUNC_SLT ) then
alu_op <= ALU_OP_SLT;
elsif ( ir_function = OP0_FUNC_SLTU ) then
alu_op <= ALU_OP_SLTU;
elsif ( ir_function = OP0_FUNC_SRA ) then
alu_op <= ALU_OP_SRA;
elsif ( ir_function = OP0_FUNC_MFHI ) then
alu_op <= ALU_OP_MFHI;
elsif ( ir_function = OP0_FUNC_MFLO ) then
alu_op <= ALU_OP_MFLO;
elsif ( ir_function = OP0_FUNC_JR ) then
alu_op <= ALU_OP_PASSA; -- RESULT = RegA Bits[25:21]
next_state <= LOAD_PC_JUMP_BRANCH; -- Note: No RregFile Write Needed
else
alu_op <= ALU_OP_ADDU;
end if;
when ITYPE_EXEC =>
PC_write <= '0';
I_or_D <= '0';
mem_write <= '0';
mem_read <= '0';
mem_reg <= '0';
ir_write <= '0';
is_signed <= '0'; -- Default is Immediate = Unsigned
reg_write <= '0';
jmp_link <= '0';
reg_dst <= '0';
alu_A <= '1'; -- Select RegFile-A ($s)
alu_B <= "10"; -- Select Offset IR Bits[15:0] = Immediate
PC_src <= "00"; -- N/A
next_state <= REGFILE_WR;
if ( ir_opcode = OPCODE_ADDIU ) then
alu_op <= ALU_OP_ADDIU;
is_signed <= '1'; -- Set Offset is a Signed
elsif ( ir_opcode = OPCODE_SUBIU ) then
alu_op <= ALU_OP_SUBIU;
is_signed <= '1'; -- Set Offset is Signed
elsif ( ir_opcode = OPCODE_ANDI ) then
alu_op <= ALU_OP_ANDI;
elsif ( ir_opcode = OPCODE_ORI ) then
alu_op <= ALU_OP_ORI;
elsif ( ir_opcode = OPCODE_XORI ) then
alu_op <= ALU_OP_XORI;
elsif ( ir_opcode = OPCODE_SLTI ) then
alu_op <= ALU_OP_SLTI;
is_signed <= '1';
elsif ( ir_opcode = OPCODE_SLTIU ) then
alu_op <= ALU_OP_SLTIU;
elsif ( ir_opcode = OPCODE_BEQ ) then
alu_op <= ALU_OP_BEQ;
alu_B <= "00"; -- Select RegFile as B-Operand
if ( branch = '1' ) then
next_state <= LOAD_PC_JUMP_BRANCH;
else
next_state <= IR_FETCH;
end if;
elsif(ir_opcode = OPCODE_BNE) then
alu_op<= OPCODE_BNE;
alu_B <= "00";
if ( branch = '1' ) then
next_state <= LOAD_PC_JUMP_BRANCH;
else
next_state <= IR_FETCH;
end if;
elsif(ir_opcode = OPCODE_BLEZ ) then
alu_op<= ALU_OP_BLEZ;
alu_B <= "00";
if ( branch = '1' ) then
next_state <= LOAD_PC_JUMP_BRANCH;
else
next_state <= IR_FETCH;
end if;
elsif(ir_opcode = OPCODE_BGTZ ) then
alu_op<= ALU_OP_BGTZ;
alu_B <= "00";
if ( branch = '1' ) then
next_state <= LOAD_PC_JUMP_BRANCH;
else
next_state <= IR_FETCH;
end if;
--check BIT 16 for which function to do
elsif(ir_opcode = OPCODE_BLTZ_GEZ) then
if(ir_high_bit16 = '1') then
alu_op<= ALU_OP_BGEZ;
alu_B <= "00";
if ( branch = '1' ) then
next_state <= LOAD_PC_JUMP_BRANCH;
else
next_state <= IR_FETCH;
end if;
else
alu_op<= ALU_OP_BLTZ;
alu_B <= "00";
if ( branch = '1' ) then
next_state <= LOAD_PC_JUMP_BRANCH;
else
next_state <= IR_FETCH;
end if;
end if;
elsif ( ir_opcode = OPCODE_LW ) then
alu_op <= ALU_OP_ADDU;
next_state <= MEM_READ_ST; -- Proceed to access Memory [$S+Offset]
elsif ( ir_opcode = OPCODE_SW ) then
alu_op <= ALU_OP_ADDU;
next_state <= MEM_WRITE_ST; -- Proceed to Write Memory [$S+Offset]
elsif(ir_opcode = OPCODE_JAL) then
alu_B <= "01"; -- Need to add 4
alu_A <= '0'; -- Need to add pc
alu_op <= ALU_OP_PASSA; -- PassA; Need to Add if After JAL is a NOP to make it plus 8
next_state <= Load_PC_jump_branch;
else
next_state <= IR_FETCH; --never get here
end if;
when LOAD_PC_JUMP_BRANCH =>
PC_write <= '1'; -- Update PC (Based on Instruction)
I_or_D <= '0';
mem_write <= '0';
mem_read <= '0';
mem_reg <= '0';
ir_write <= '0';
is_signed <= '0';
reg_write <= '0';
jmp_link <= '0';
reg_dst <= '0';
alu_A <= '0';
alu_B <= "00";
PC_src <= "01"; -- ALU OUT = $S (RegA)
alu_op <= ALU_OP_ADDU;
next_state <= IR_FETCH;
if ( ir_opcode = OPCODE_BEQ ) then
alu_op <= ALU_OP_PASSB; -- Pass OFFSET
alu_B <= "11"; -- 3: Select Offset<<2
PC_src <= "00"; -- 0: Select ALU Resut=RegB=Offset<<2
elsif(ir_opcode = OPCODE_BNE) then
alu_op <= ALU_OP_PASSB; -- Pass OFFSET
alu_B <= "11"; -- 3: Select Offset<<2
PC_src <= "00"; -- 0: Select ALU Resut=RegB=Offset<<2
elsif(ir_opcode = OPCODE_BLEZ ) then
alu_op <= ALU_OP_PASSB; -- Pass OFFSET
alu_B <= "11"; -- 3: Select Offset<<2
PC_src <= "00"; -- 0: Select ALU Resut=RegB=Offset<<2
elsif(ir_opcode = OPCODE_BGTZ ) then
-- Need to provide ALU with Opcode = PASS B (Offset)
alu_op <= ALU_OP_PASSB; -- Pass OFFSET
alu_B <= "11"; -- 3: Select Offset<<2
PC_src <= "00"; -- 0: Select ALU Resut=RegB=Offset<<2
elsif(ir_opcode = OPCODE_BLTZ_GEZ) then
-- Need to provide ALU with Opcode = PASS B (Offset)
alu_op <= ALU_OP_PASSB; -- Pass OFFSET
alu_B <= "11"; -- 3: Select Offset<<2
PC_src <= "00"; -- 0: Select ALU Resut=RegB=Offset<<2
elsif( ir_opcode = OPCODE_J ) then
PC_src <= "10"; --Pcsrc = IR[25:0] shifted left by 2
elsif( ir_opcode = OPCODE_Jal ) then
PC_src <= "10"; --Pcsrc = IR[25:0] shifted left by 2
reg_write<= '1';
jmp_link<= '1';
end if;
when REGFILE_WR =>
PC_write <= '0';
I_or_D <= '0';
mem_write <= '0';
mem_read <= '0';
mem_reg <= '0'; -- Select ALU Output Mux (RegFile WrData)
ir_write <= '0';
is_signed <= '0';
reg_write <= '1'; -- Write RegFile
jmp_link <= '0';
reg_dst <= '0'; -- WrAdrs <- IR Bits[20:16]
alu_A <= '0';
alu_B <= "00";
alu_op <= ALU_OP_ADDU;
PC_src <= "00"; -- N/A
next_state <= IR_FETCH;
if ( ir_opcode = OPCODE_RTYPE ) then
reg_dst <= '1';
if ( ir_function = OP0_FUNC_MFHI ) then
alu_op <= ALU_OP_MFHI;
elsif ( ir_function = OP0_FUNC_MFLO ) then
alu_op <= ALU_OP_MFLO;
end if;
elsif ( ir_opcode = OPCODE_LW ) then
mem_reg <= '1';
end if;
when MEM_READ_ST =>
-- Defaults
PC_write <= '0';
I_or_D <= '1'; -- Select ALU OUT as MemAdrs versus PC
mem_write <= '0';
mem_read <= '1'; -- Access Memory
mem_reg <= '0';
ir_write <= '0';
is_signed <= '0';
reg_write <= '0';
jmp_link <= '0';
reg_dst <= '0';
alu_A <= '0';
alu_B <= "00";
alu_op <= ALU_OP_ADDU;
PC_src <= "00";
next_state <= REGFILE_WR;
when MEM_WRITE_ST=>
-- Defaults
PC_write <= '0';
I_or_D <= '1'; -- Select ALU OUT as MemAdrs
mem_write <= '1'; -- Write memory
mem_read <= '0';
mem_reg <= '0';
ir_write <= '0';
is_signed <= '0';
reg_write <= '0';
jmp_link <= '0';
reg_dst <= '0';
alu_A <= '0';
alu_B <= "00";
alu_op <= ALU_OP_ADDU;
PC_src <= "00";
reg_dst <= '0';
next_state<= IR_FETCH;
when State_OPCODE_HALT =>
-- Defaults
PC_write <= '0';
I_or_D <= '0';
mem_write <= '0';
mem_read <= '0';
mem_reg <= '0';
ir_write <= '0';
is_signed <= '0';
reg_write <= '0';
jmp_link <= '0';
reg_dst <= '0';
alu_A <= '0';
alu_B <= "00";
alu_op <= ALU_OP_ADDU;
PC_src <= "00";
next_state <= state_OPCODE_HALT;
when others => null;
end case;
end process;
end logic;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
use work.MIPS_LIB.all;
entity Mips is
port (
clk : in std_logic;
rst : in std_logic;
sw_inport_data : in std_logic_vector(8 downto 0);
sw_inport_sel : in std_logic;
sw_inport_wr : in std_logic;
outport: out std_logic_vector(31 downto 0)
);
end Mips;
architecture logic of Mips is
signal PC_write : std_logic;
signal I_or_D : std_logic;
signal mem_write : std_logic;
signal mem_read : std_logic;
signal mem_reg : std_logic;
signal ir_write : std_logic;
signal is_signed : std_logic;
signal reg_write : std_logic;
signal jmp_link: std_logic;
signal reg_dst : std_logic;
signal alu_A : std_logic;
signal alu_B : std_logic_vector(1 downto 0);
signal PC_src : std_logic_vector(1 downto 0);
signal alu_op : std_logic_vector(5 downto 0);
signal branch : std_logic;
signal IR : std_logic_vector(31 downto 0);
begin
U_Controller: entity work.Controller
port map(
clk=>clk,
rst => rst,
ir_opcode => IR(31 downto 26), -- IR Bits[31:26]
ir_function => IR(5 downto 0), -- IR Bits[05:00]
ir_high_bit16 => IR(16), -- IR Bit [16]
branch => branch,
PC_write => PC_write,
I_or_D => I_or_D ,
mem_write => mem_write ,
mem_read => mem_read ,
mem_reg => mem_reg,
ir_write => ir_write,
is_signed => is_signed,
reg_write => reg_write,
jmp_link => jmp_link,
reg_dst => reg_dst,
alu_A => alu_A ,
alu_B => alu_B,
PC_src => PC_src,
alu_op => alu_op
);
U_Datapath: entity work.datapath
port map(
clk=> clk,
rst=> rst,
pc_load=> PC_write,
IorD => I_or_D,
mem_read=> mem_read,
mem_write=> mem_write,
mem_reg=> mem_reg,
ir_write=> ir_write,
reg_dest=> reg_dst,
reg_write=> reg_write,
alu_A => alu_A,
alu_B=> alu_B,
alu_op=> alu_op,
PC_src=> PC_src ,
is_signed=> is_signed,
jmp_link=> jmp_link,
sw_inport_data=> sw_inport_data,
sw_inport_sel=> sw_inport_sel,
sw_inport_wr=>sw_inport_wr,
branch=> branch,
IR =>IR,
outport=> outport
);
end logic;
CONTROLLER
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
use work.MIPS_LIB.all;
entity controller is
port (
clk, rst : in std_logic;
ir_opcode : in std_logic_vector(5 downto 0); -- IR Bits[31:26]
ir_function : in std_logic_vector(5 downto 0); -- IR Bits[05:00]
ir_high_bit16 : in std_logic; -- IR Bit [16]
branch: in std_logic;
PC_write : out std_logic;
I_or_D : out std_logic;
mem_write : out std_logic;
mem_read : out std_logic;
mem_reg : out std_logic;
ir_write : out std_logic;
is_signed : out std_logic;
reg_write : out std_logic;
jmp_link: out std_logic;
reg_dst : out std_logic;
alu_A : out std_logic;
alu_B : out std_logic_vector(1 downto 0);
PC_src : out std_logic_vector(1 downto 0);
alu_op : out std_logic_vector(5 downto 0)
);
end controller;
architecture logic of controller is
type STATE_TYPE is ( IR_FETCH, IR_DECODE,
RTYPE_EXEC, ITYPE_EXEC, REGFILE_WR,
LOAD_PC_JUMP_BRANCH, MEM_READ_ST,MEM_WRITE_ST, State_OPCODE_HALT );
signal state, next_state : STATE_TYPE;
begin
process(clk, rst)
begin
if (rst = '1') then
state <= IR_FETCH;
elsif(clk'event and clk = '1') then
state <= next_state;
end if;
end process;
process(state, ir_opcode, ir_function, ir_high_bit16, branch )
begin
case state is
when IR_FETCH =>
PC_write <= '1'; -- Update PC (PC<-PC+4)
I_or_D <= '0';
mem_write <= '0';
mem_read <= '1'; -- Read Mem (Next Instruction)
mem_reg <= '0';
ir_write <= '1'; -- Load Next Instruction IR<-MEM[PC]
is_signed <= '0';
reg_write <= '0';
jmp_link <= '0';
reg_dst <= '0';
alu_A <= '0'; -- Select ALU-A = PC
alu_B <= "01"; -- Select ALU-B = 4 (Used to Inc PC by 1)
alu_op <= ALU_OP_ADDU; -- Result = PC + 4
PC_src <= "00"; -- Seelct ALU RESULT
next_state <= IR_DECODE;
when IR_DECODE =>
-- Defaults
PC_write <= '0';
I_or_D <= '0';
mem_write <= '0';
mem_read <= '0';
mem_reg <= '0';
ir_write <= '0';
is_signed <= '0';
reg_write <= '0';
jmp_link <= '0';
reg_dst <= '0';
alu_A <= '1'; -- Select RegFile-A
alu_B <= "00"; -- Select RegFile-B
alu_op <= ALU_OP_ADDU;
PC_src <= "00"; -- N/A
if ( ir_opcode = OPCODE_RTYPE ) then
next_state <= RTYPE_EXEC;
elsif ( ir_opcode = OPCODE_HALT ) then
next_state <= State_OPCODE_HALT;
elsif( ir_opcode = OPCODE_J ) then
next_state<=LOAD_PC_JUMP_BRANCH;
else
next_state <= ITYPE_EXEC;
end if;
when RTYPE_EXEC =>
PC_write <= '0';
I_or_D <= '0';
mem_write <= '0';
mem_read <= '0';
mem_reg <= '0';
ir_write <= '0';
is_signed <= '0';
reg_write <= '0';
jmp_link <= '0';
reg_dst <= '0';
alu_A <= '1'; -- Select RegFile-A
alu_B <= "00"; -- Select RegFile-B
PC_src <= "00"; -- N/A
next_state <= REGFILE_WR;
if ( ir_function = OP0_FUNC_ADDU ) then
alu_op <= ALU_OP_ADDU;
elsif ( ir_function = OP0_FUNC_SUBU ) then
alu_op <= ALU_OP_SUBU;
elsif ( ir_function = OP0_FUNC_MULT ) then
alu_op <= ALU_OP_MULT;
next_state <= IR_FETCH; -- Note: No RegFile Write needed
elsif ( ir_function = OP0_FUNC_MULTU ) then
alu_op <= ALU_OP_MULTU;
next_state <= IR_FETCH; -- Note: No RegFile Write needed
elsif ( ir_function = OP0_FUNC_AND ) then
alu_op <= ALU_OP_AND;
elsif ( ir_function = OP0_FUNC_OR ) then
alu_op <= ALU_OP_OR;
elsif ( ir_function = OP0_FUNC_XOR ) then
alu_op <= ALU_OP_XOR;
elsif ( ir_function = OP0_FUNC_SRL ) then
alu_op <= ALU_OP_SRL;
elsif ( ir_function = OP0_FUNC_SLL ) then
alu_op <= ALU_OP_SLL;
elsif ( ir_function = OP0_FUNC_SRA ) then
alu_op <= ALU_OP_SRA;
elsif ( ir_function = OP0_FUNC_SLT ) then
alu_op <= ALU_OP_SLT;
elsif ( ir_function = OP0_FUNC_SLTU ) then
alu_op <= ALU_OP_SLTU;
elsif ( ir_function = OP0_FUNC_SRA ) then
alu_op <= ALU_OP_SRA;
elsif ( ir_function = OP0_FUNC_MFHI ) then
alu_op <= ALU_OP_MFHI;
elsif ( ir_function = OP0_FUNC_MFLO ) then
alu_op <= ALU_OP_MFLO;
elsif ( ir_function = OP0_FUNC_JR ) then
alu_op <= ALU_OP_PASSA; -- RESULT = RegA Bits[25:21]
next_state <= LOAD_PC_JUMP_BRANCH; -- Note: No RregFile Write Needed
else
alu_op <= ALU_OP_ADDU;
end if;
when ITYPE_EXEC =>
PC_write <= '0';
I_or_D <= '0';
mem_write <= '0';
mem_read <= '0';
mem_reg <= '0';
ir_write <= '0';
is_signed <= '0'; -- Default is Immediate = Unsigned
reg_write <= '0';
jmp_link <= '0';
reg_dst <= '0';
alu_A <= '1'; -- Select RegFile-A ($s)
alu_B <= "10"; -- Select Offset IR Bits[15:0] = Immediate
PC_src <= "00"; -- N/A
next_state <= REGFILE_WR;
if ( ir_opcode = OPCODE_ADDIU ) then
alu_op <= ALU_OP_ADDIU;
is_signed <= '1'; -- Set Offset is a Signed
elsif ( ir_opcode = OPCODE_SUBIU ) then
alu_op <= ALU_OP_SUBIU;
is_signed <= '1'; -- Set Offset is Signed
elsif ( ir_opcode = OPCODE_ANDI ) then
alu_op <= ALU_OP_ANDI;
elsif ( ir_opcode = OPCODE_ORI ) then
alu_op <= ALU_OP_ORI;
elsif ( ir_opcode = OPCODE_XORI ) then
alu_op <= ALU_OP_XORI;
elsif ( ir_opcode = OPCODE_SLTI ) then
alu_op <= ALU_OP_SLTI;
is_signed <= '1';
elsif ( ir_opcode = OPCODE_SLTIU ) then
alu_op <= ALU_OP_SLTIU;
elsif ( ir_opcode = OPCODE_BEQ ) then
alu_op <= ALU_OP_BEQ;
alu_B <= "00"; -- Select RegFile as B-Operand
if ( branch = '1' ) then
next_state <= LOAD_PC_JUMP_BRANCH;
else
next_state <= IR_FETCH;
end if;
elsif(ir_opcode = OPCODE_BNE) then
alu_op<= OPCODE_BNE;
alu_B <= "00";
if ( branch = '1' ) then
next_state <= LOAD_PC_JUMP_BRANCH;
else
next_state <= IR_FETCH;
end if;
elsif(ir_opcode = OPCODE_BLEZ ) then
alu_op<= ALU_OP_BLEZ;
alu_B <= "00";
if ( branch = '1' ) then
next_state <= LOAD_PC_JUMP_BRANCH;
else
next_state <= IR_FETCH;
end if;
elsif(ir_opcode = OPCODE_BGTZ ) then
alu_op<= ALU_OP_BGTZ;
alu_B <= "00";
if ( branch = '1' ) then
next_state <= LOAD_PC_JUMP_BRANCH;
else
next_state <= IR_FETCH;
end if;
--check BIT 16 for which function to do
elsif(ir_opcode = OPCODE_BLTZ_GEZ) then
if(ir_high_bit16 = '1') then
alu_op<= ALU_OP_BGEZ;
alu_B <= "00";
if ( branch = '1' ) then
next_state <= LOAD_PC_JUMP_BRANCH;
else
next_state <= IR_FETCH;
end if;
else
alu_op<= ALU_OP_BLTZ;
alu_B <= "00";
if ( branch = '1' ) then
next_state <= LOAD_PC_JUMP_BRANCH;
else
next_state <= IR_FETCH;
end if;
end if;
elsif ( ir_opcode = OPCODE_LW ) then
alu_op <= ALU_OP_ADDU;
next_state <= MEM_READ_ST; -- Proceed to access Memory [$S+Offset]
elsif ( ir_opcode = OPCODE_SW ) then
alu_op <= ALU_OP_ADDU;
next_state <= MEM_WRITE_ST; -- Proceed to Write Memory [$S+Offset]
elsif(ir_opcode = OPCODE_JAL) then
alu_B <= "01"; -- Need to add 4
alu_A <= '0'; -- Need to add pc
alu_op <= ALU_OP_PASSA; -- PassA; Need to Add if After JAL is a NOP to make it plus 8
next_state <= Load_PC_jump_branch;
else
next_state <= IR_FETCH; --never get here
end if;
when LOAD_PC_JUMP_BRANCH =>
PC_write <= '1'; -- Update PC (Based on Instruction)
I_or_D <= '0';
mem_write <= '0';
mem_read <= '0';
mem_reg <= '0';
ir_write <= '0';
is_signed <= '0';
reg_write <= '0';
jmp_link <= '0';
reg_dst <= '0';
alu_A <= '0';
alu_B <= "00";
PC_src <= "01"; -- ALU OUT = $S (RegA)
alu_op <= ALU_OP_ADDU;
next_state <= IR_FETCH;
if ( ir_opcode = OPCODE_BEQ ) then
alu_op <= ALU_OP_PASSB; -- Pass OFFSET
alu_B <= "11"; -- 3: Select Offset<<2
PC_src <= "00"; -- 0: Select ALU Resut=RegB=Offset<<2
elsif(ir_opcode = OPCODE_BNE) then
alu_op <= ALU_OP_PASSB; -- Pass OFFSET
alu_B <= "11"; -- 3: Select Offset<<2
PC_src <= "00"; -- 0: Select ALU Resut=RegB=Offset<<2
elsif(ir_opcode = OPCODE_BLEZ ) then
alu_op <= ALU_OP_PASSB; -- Pass OFFSET
alu_B <= "11"; -- 3: Select Offset<<2
PC_src <= "00"; -- 0: Select ALU Resut=RegB=Offset<<2
elsif(ir_opcode = OPCODE_BGTZ ) then
-- Need to provide ALU with Opcode = PASS B (Offset)
alu_op <= ALU_OP_PASSB; -- Pass OFFSET
alu_B <= "11"; -- 3: Select Offset<<2
PC_src <= "00"; -- 0: Select ALU Resut=RegB=Offset<<2
elsif(ir_opcode = OPCODE_BLTZ_GEZ) then
-- Need to provide ALU with Opcode = PASS B (Offset)
alu_op <= ALU_OP_PASSB; -- Pass OFFSET
alu_B <= "11"; -- 3: Select Offset<<2
PC_src <= "00"; -- 0: Select ALU Resut=RegB=Offset<<2
elsif( ir_opcode = OPCODE_J ) then
PC_src <= "10"; --Pcsrc = IR[25:0] shifted left by 2
elsif( ir_opcode = OPCODE_Jal ) then
PC_src <= "10"; --Pcsrc = IR[25:0] shifted left by 2
reg_write<= '1';
jmp_link<= '1';
end if;
when REGFILE_WR =>
PC_write <= '0';
I_or_D <= '0';
mem_write <= '0';
mem_read <= '0';
mem_reg <= '0'; -- Select ALU Output Mux (RegFile WrData)
ir_write <= '0';
is_signed <= '0';
reg_write <= '1'; -- Write RegFile
jmp_link <= '0';
reg_dst <= '0'; -- WrAdrs <- IR Bits[20:16]
alu_A <= '0';
alu_B <= "00";
alu_op <= ALU_OP_ADDU;
PC_src <= "00"; -- N/A
next_state <= IR_FETCH;
if ( ir_opcode = OPCODE_RTYPE ) then
reg_dst <= '1';
if ( ir_function = OP0_FUNC_MFHI ) then
alu_op <= ALU_OP_MFHI;
elsif ( ir_function = OP0_FUNC_MFLO ) then
alu_op <= ALU_OP_MFLO;
end if;
elsif ( ir_opcode = OPCODE_LW ) then
mem_reg <= '1';
end if;
when MEM_READ_ST =>
-- Defaults
PC_write <= '0';
I_or_D <= '1'; -- Select ALU OUT as MemAdrs versus PC
mem_write <= '0';
mem_read <= '1'; -- Access Memory
mem_reg <= '0';
ir_write <= '0';
is_signed <= '0';
reg_write <= '0';
jmp_link <= '0';
reg_dst <= '0';
alu_A <= '0';
alu_B <= "00";
alu_op <= ALU_OP_ADDU;
PC_src <= "00";
next_state <= REGFILE_WR;
when MEM_WRITE_ST=>
-- Defaults
PC_write <= '0';
I_or_D <= '1'; -- Select ALU OUT as MemAdrs
mem_write <= '1'; -- Write memory
mem_read <= '0';
mem_reg <= '0';
ir_write <= '0';
is_signed <= '0';
reg_write <= '0';
jmp_link <= '0';
reg_dst <= '0';
alu_A <= '0';
alu_B <= "00";
alu_op <= ALU_OP_ADDU;
PC_src <= "00";
reg_dst <= '0';
next_state<= IR_FETCH;
when State_OPCODE_HALT =>
-- Defaults
PC_write <= '0';
I_or_D <= '0';
mem_write <= '0';
mem_read <= '0';
mem_reg <= '0';
ir_write <= '0';
is_signed <= '0';
reg_write <= '0';
jmp_link <= '0';
reg_dst <= '0';
alu_A <= '0';
alu_B <= "00";
alu_op <= ALU_OP_ADDU;
PC_src <= "00";
next_state <= state_OPCODE_HALT;
when others => null;
end case;
end process;
end logic;
DATAPATH
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
use work.MIPS_LIB.all;
entity datapath is
port (
clk : in std_logic;
rst : in std_logic;
pc_load : in std_logic;
IorD : in std_logic;
mem_read : in std_logic;
mem_write : in std_logic;
mem_reg : in std_logic;
ir_write : in std_logic;
reg_dest : in std_logic;
reg_write : in std_logic;
alu_A : in std_logic;
alu_B : in std_logic_vector(1 downto 0);
alu_op: in std_logic_vector(5 downto 0);
PC_src : in std_logic_vector(1 downto 0);
is_signed : in std_logic;
jmp_link : in std_logic;
sw_inport_data : in std_logic_vector(8 downto 0);
sw_inport_sel : in std_logic;
sw_inport_wr : in std_logic;
branch: out std_logic;
IR : out std_logic_vector(31 downto 0);
outport: out std_logic_vector(31 downto 0)
);
end datapath;
architecture logic of datapath is
signal pc_out : std_logic_vector(31 downto 0);
signal mux21_out: std_logic_vector(31 downto 0);
signal memout: std_logic_vector(31 downto 0);
signal IR25_0: std_logic_vector(25 downto 0);
signal IR31_26: std_logic_vector(5 downto 0);
signal IR25_21: std_logic_vector(4 downto 0);
signal IR20_16: std_logic_vector(4 downto 0);
signal IR15_11: std_logic_vector(4 downto 0);
signal IR15_0: std_logic_vector(15 downto 0);
signal memoryRegOut: std_logic_vector(31 downto 0);
signal writeReg: std_logic_vector(4 downto 0);
signal writedata: std_logic_vector(31 downto 0);
signal InRegA : std_logic_vector( 31 downto 0);
signal InRegB : std_logic_vector( 31 downto 0);
signal Signextend_out : std_logic_vector(31 downto 0);
signal shiftleft2_out: std_logic_vector(31 downto 0);
signal RegA_out : std_logic_vector( 31 downto 0);
signal RegB_out : std_logic_vector( 31 downto 0);
signal Aluinput1 : std_logic_vector( 31 downto 0);
signal Aluinput2 : std_logic_vector( 31 downto 0);
signal Shiftleft_concat: std_logic_vector( 31 downto 0);
signal Alu_out_reg : std_logic_vector(31 downto 0);
signal Alu_result : std_logic_vector(31 downto 0);
signal mux31_out : std_logic_vector(31 downto 0);
signal alu_lo_hi_out : std_logic_vector(31 downto 0);
begin
U_PC: entity work.pc port map(
rst => rst,
clk=> clk,
address_to_load=> mux31_out,
cntrl_in=> pc_load,
current_address=> pc_out
);
U_Mux21_1: entity work.mux21
generic map( width=> 32)
port map(
input0 =>pc_out,
input1=>Alu_out_reg,
sel => IorD,
output=> mux21_out
);
U_MEMORY: entity work.Memory
port map(
clk=>clk,
rst=>rst,
pc=> mux21_out,
mem_read=> mem_read,
mem_write=> mem_write,
sw_inport_data =>sw_inport_data,
sw_inport_sel=> sw_inport_sel,
sw_inport_wr => sw_inport_wr,
reg_B => RegB_out,
mem_out => memout,
out_port => outport
);
U_InstructionReg: entity work.instruction_reg
port map(
clk=> clk,
rst => rst,
memdata => memout,
ir_write=> ir_write ,
instr31_26=> IR31_26,
instr25_21 => IR25_21,
instr20_16=> IR20_16,
instr15_11 => IR15_11,
instr25_0 => IR25_0,
instr15_0 => IR15_0
);
U_MemoryDataReg: entity work.reg
generic map( width=> 32)
port map(
clk=> clk,
rst => rst,
input=> memout,
output=>memoryRegOut
);
U_Mux21_2: entity work.mux21
generic map( width=> 5)
port map(
input0=> IR20_16,
input1=> IR15_11,
sel=> reg_dest,
output =>writeReg
);
U_Mux21_3: entity work.mux21
generic map( width=> 32)
port map(
input0 => alu_lo_hi_out,
input1=>memoryRegOut,
sel => mem_reg,
output=> writedata
);
U_Registerfile: entity work.regfile
generic map( width=> 32)
port map(
clk=>clk,
rst=>rst,
rd_adrs1=> IR25_21,
rd_adrs2=> IR20_16,
cntrl_reg_wr=> reg_write,
cntrl_jal=> jmp_link,
wr_adrs=>writeReg,
wr_data=>writedata,
rd_data1=>InRegA,
rd_data2=> InRegB
);
U_SignExtend: entity work.sign_extend
port map(
x=> IR15_0,
is_signed=> is_signed,
y=>Signextend_out
);
U_REGA: entity work.reg
generic map( width=> 32)
port map(
clk=> clk,
rst => rst,
input=> InRegA,
output=> RegA_out
);
U_REGB: entity work.reg
generic map( width=> 32)
port map(
clk=> clk,
rst=> rst,
input=> inRegB,
output=> RegB_out
);
U_Shiftleft2: entity work.SHIFT_L2_32
port map(
input=>Signextend_out,
output=> shiftleft2_out
);
U_Mux21_4: entity work.mux21
generic map( width=> 32)
port map(
input0=> pc_out,
input1=> RegA_out,
sel => alu_A,
output => Aluinput1
);
U_Mux41: entity work.mux41
generic map( width=> 32)
port map(
input0 => RegB_out,
input1 => std_logic_vector(to_unsigned(4,32)),
input2=> Signextend_out,
input3 => shiftleft2_out,
sel => alu_B,
output =>Aluinput2
);
U_Shiftleft2Concat: entity work.SHIFT_Concat_PC
port map(
input=> IR25_0,
pc=>pc_out(3 downto 0),
output=>Shiftleft_concat
);
U_ALUTOP: entity work.alu_top
generic map(width=>32)
port map(
clk=> clk,
rst=> rst,
opcode => alu_op,
ir_shift=> IR15_0(10 downto 6),
A=> Aluinput1,
B => Aluinput2 ,
result=> alu_result,
out_reg=> Alu_out_reg,
hilo_reg=> alu_lo_hi_out,
branch => branch
);
U_Mux31: entity work.mux31
generic map( width=> 32)
port map(
input0=> alu_result,
input1 => Alu_out_reg,
input2 => Shiftleft_concat,
sel => PC_src,
output =>mux31_out
);
IR<= IR31_26 & IR25_21 & IR20_16 & IR15_0;
end logic;
Comments
Post a Comment