Line 13... |
Line 13... |
-- Controls the CPU by decoding the opcode and generating control
|
-- Controls the CPU by decoding the opcode and generating control
|
-- signals to the rest of the CPU.
|
-- signals to the rest of the CPU.
|
-- This entity decodes the MIPS(tm) opcode into a
|
-- This entity decodes the MIPS(tm) opcode into a
|
-- Very-Long-Word-Instruction.
|
-- Very-Long-Word-Instruction.
|
-- The 32-bit opcode is converted to a
|
-- The 32-bit opcode is converted to a
|
-- 6+6+6+16+5+2+3+3+2+2+3+2+4 = 60 bit VLWI opcode.
|
-- 6+6+6+16+4+2+4+3+2+2+3+2+4 = 60 bit VLWI opcode.
|
-- Based on information found in:
|
-- Based on information found in:
|
-- "MIPS RISC Architecture" by Gerry Kane and Joe Heinrich
|
-- "MIPS RISC Architecture" by Gerry Kane and Joe Heinrich
|
-- and "The Designer's Guide to VHDL" by Peter J. Ashenden
|
-- and "The Designer's Guide to VHDL" by Peter J. Ashenden
|
---------------------------------------------------------------------
|
---------------------------------------------------------------------
|
library ieee;
|
library ieee;
|
Line 37... |
Line 37... |
branch_func : out branch_function_type;
|
branch_func : out branch_function_type;
|
a_source_out : out a_source_type;
|
a_source_out : out a_source_type;
|
b_source_out : out b_source_type;
|
b_source_out : out b_source_type;
|
c_source_out : out c_source_type;
|
c_source_out : out c_source_type;
|
pc_source_out: out pc_source_type;
|
pc_source_out: out pc_source_type;
|
mem_source_out:out mem_source_type);
|
mem_source_out:out mem_source_type;
|
|
exception_out: out std_logic);
|
end; --entity control
|
end; --entity control
|
|
|
architecture logic of control is
|
architecture logic of control is
|
begin
|
begin
|
|
|
Line 57... |
Line 58... |
variable b_source : b_source_type;
|
variable b_source : b_source_type;
|
variable c_source : c_source_type;
|
variable c_source : c_source_type;
|
variable pc_source : pc_source_type;
|
variable pc_source : pc_source_type;
|
variable branch_function: branch_function_type;
|
variable branch_function: branch_function_type;
|
variable mem_source : mem_source_type;
|
variable mem_source : mem_source_type;
|
|
variable is_syscall : std_logic;
|
begin
|
begin
|
alu_function := ALU_NOTHING;
|
alu_function := ALU_NOTHING;
|
shift_function := SHIFT_NOTHING;
|
shift_function := SHIFT_NOTHING;
|
mult_function := MULT_NOTHING;
|
mult_function := MULT_NOTHING;
|
a_source := A_FROM_REG_SOURCE;
|
a_source := A_FROM_REG_SOURCE;
|
Line 74... |
Line 76... |
rt := '0' & opcode(20 downto 16);
|
rt := '0' & opcode(20 downto 16);
|
rtx := opcode(20 downto 16);
|
rtx := opcode(20 downto 16);
|
rd := '0' & opcode(15 downto 11);
|
rd := '0' & opcode(15 downto 11);
|
func := opcode(5 downto 0);
|
func := opcode(5 downto 0);
|
imm := opcode(15 downto 0);
|
imm := opcode(15 downto 0);
|
|
is_syscall := '0';
|
|
|
case op is
|
case op is
|
when "000000" => --SPECIAL
|
when "000000" => --SPECIAL
|
case func is
|
case func is
|
when "000000" => --SLL r[rd]=r[rt]<<re;
|
when "000000" => --SLL r[rd]=r[rt]<<re;
|
Line 123... |
Line 126... |
|
|
when "001011" => --MOVN if(r[rt]) r[rd]=r[rs]; /*IV*/
|
when "001011" => --MOVN if(r[rt]) r[rd]=r[rs]; /*IV*/
|
-- c_source := FROM_REG_SOURCE_NEZ;
|
-- c_source := FROM_REG_SOURCE_NEZ;
|
|
|
when "001100" => --SYSCALL
|
when "001100" => --SYSCALL
|
-- if(r[4]==0) printf("0x%8.8lx ",r[5]);
|
is_syscall := '1';
|
|
|
when "001101" => --BREAK s->wakeup=1;
|
when "001101" => --BREAK s->wakeup=1;
|
|
is_syscall := '1';
|
|
|
when "001111" => --SYNC s->wakeup=1;
|
when "001111" => --SYNC s->wakeup=1;
|
when "010000" => --MFHI r[rd]=s->hi;
|
when "010000" => --MFHI r[rd]=s->hi;
|
c_source := C_FROM_MULT;
|
c_source := C_FROM_MULT;
|
mult_function := MULT_READ_HI;
|
mult_function := MULT_READ_HI;
|
|
|
Line 474... |
Line 479... |
|
|
if c_source = C_FROM_NULL then
|
if c_source = C_FROM_NULL then
|
rd := "000000";
|
rd := "000000";
|
end if;
|
end if;
|
|
|
if intr_signal = '1' then
|
if intr_signal = '1' or is_syscall = '1' then
|
rs := "111111"; --interrupt vector
|
rs := "111111"; --interrupt vector
|
rt := "000000";
|
rt := "000000";
|
rd := "101110"; --save PC in EPC
|
rd := "101110"; --save PC in EPC
|
alu_function := ALU_OR;
|
alu_function := ALU_OR;
|
shift_function := SHIFT_NOTHING;
|
shift_function := SHIFT_NOTHING;
|
Line 487... |
Line 492... |
a_source := A_FROM_REG_SOURCE;
|
a_source := A_FROM_REG_SOURCE;
|
b_source := B_FROM_REG_TARGET;
|
b_source := B_FROM_REG_TARGET;
|
c_source := C_FROM_PC;
|
c_source := C_FROM_PC;
|
pc_source := FROM_LBRANCH;
|
pc_source := FROM_LBRANCH;
|
mem_source := MEM_FETCH;
|
mem_source := MEM_FETCH;
|
|
exception_out <= '1';
|
|
else
|
|
exception_out <= '0';
|
end if;
|
end if;
|
|
|
rs_index <= rs;
|
rs_index <= rs;
|
rt_index <= rt;
|
rt_index <= rt;
|
rd_index <= rd;
|
rd_index <= rd;
|