OpenCores
URL https://opencores.org/ocsvn/plasma/plasma/trunk

Subversion Repositories plasma

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /plasma/tags/arelease/vhdl
    from Rev 350 to Rev 352
    Reverse comparison

Rev 350 → Rev 352

/mips_cpu.vhd
0,0 → 1,302
---------------------------------------------------------------------
-- TITLE: MIPS CPU core
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
-- DATE CREATED: 2/15/01
-- FILENAME: mips_cpu.vhd
-- PROJECT: MIPS CPU core
-- COPYRIGHT: Software placed into the public domain by the author.
-- Software 'as is' without warranty. Author liable for nothing.
-- DESCRIPTION:
-- Top level VHDL document that ties the eight other entities together.
-- Implements a MIPS CPU. Based on information found in:
-- "MIPS RISC Architecture" by Gerry Kane and Joe Heinrich
-- and "The Designer's Guide to VHDL" by Peter J. Ashenden
-- An add instruction would take the following steps (see cpu.gif):
-- 1. The "pc_next" entity would have previously passed the program
-- counter (PC) to the "mem_ctrl" entity.
-- 2. "Mem_ctrl" passes the opcode to the "control" entity.
-- 3. "Control" converts the 32-bit opcode to a 60-bit VLWI opcode
-- and sends control signals to the other entities.
-- 4. Based on the rs_index and rt_index control signals, "reg_bank"
-- sends the 32-bit reg_source and reg_target to "bus_mux".
-- 5. Based on the a_source and b_source control signals, "bus_mux"
-- multiplexes reg_source onto a_bus and reg_target onto b_bus.
-- 6. Based on the alu_func control signals, "alu" adds the values
-- from a_bus and b_bus and places the result on c_bus.
-- 7. Based on the c_source control signals, "bus_bux" multiplexes
-- c_bus onto reg_dest.
-- 8. Based on the rd_index control signal, "reg_bank" saves
-- reg_dest into the correct register.
-- The CPU is implemented as a two stage pipeline with step #1 in the
-- first stage and steps #2-8 occuring the second stage.
--
-- The CPU core was synthesized for 0.13 um line widths with an area
-- of 0.2 millimeters squared. The maximum latency was less than 6 ns
-- for a maximum clock speed of 150 MHz.
---------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.mips_pack.all;
 
entity mips_cpu is
port(clk : in std_logic;
reset_in : in std_logic;
intr_in : in std_logic;
 
mem_address : out std_logic_vector(31 downto 0);
mem_data_w : out std_logic_vector(31 downto 0);
mem_data_r : in std_logic_vector(31 downto 0);
mem_sel : out std_logic_vector(3 downto 0);
mem_write : out std_logic;
mem_pause : in std_logic;
 
t_pc : out std_logic_vector(31 downto 0);
t_opcode : out std_logic_vector(31 downto 0);
t_r_dest : out std_logic_vector(31 downto 0)
);
end; --entity mips_cpu
 
architecture logic of mips_cpu is
 
component pc_next
port(clk : in std_logic;
reset_in : in std_logic;
pc_new : in std_logic_vector(31 downto 2);
take_branch : in std_logic;
pause_in : in std_logic;
opcode25_0 : in std_logic_vector(25 downto 0);
pc_source : in pc_source_type;
pc_out : out std_logic_vector(31 downto 0));
end component;
 
component mem_ctrl
port(clk : in std_logic;
reset_in : in std_logic;
pause_in : in std_logic;
nullify_op : in std_logic;
address_pc : in std_logic_vector(31 downto 0);
opcode_out : out std_logic_vector(31 downto 0);
 
address_data : in std_logic_vector(31 downto 0);
mem_source : in mem_source_type;
data_write : in std_logic_vector(31 downto 0);
data_read : out std_logic_vector(31 downto 0);
pause_out : out std_logic;
mem_address : out std_logic_vector(31 downto 0);
mem_data_w : out std_logic_vector(31 downto 0);
mem_data_r : in std_logic_vector(31 downto 0);
mem_byte_sel : out std_logic_vector(3 downto 0);
mem_write : out std_logic;
mem_pause : in std_logic);
end component;
 
component control
port(opcode : in std_logic_vector(31 downto 0);
intr_signal : in std_logic;
rs_index : out std_logic_vector(5 downto 0);
rt_index : out std_logic_vector(5 downto 0);
rd_index : out std_logic_vector(5 downto 0);
imm_out : out std_logic_vector(15 downto 0);
alu_func : out alu_function_type;
shift_func : out shift_function_type;
mult_func : out mult_function_type;
branch_func : out branch_function_type;
a_source_out : out a_source_type;
b_source_out : out b_source_type;
c_source_out : out c_source_type;
pc_source_out: out pc_source_type;
mem_source_out:out mem_source_type);
end component;
 
component reg_bank
port(clk : in std_logic;
rs_index : in std_logic_vector(5 downto 0);
rt_index : in std_logic_vector(5 downto 0);
rd_index : in std_logic_vector(5 downto 0);
reg_source_out : out std_logic_vector(31 downto 0);
reg_target_out : out std_logic_vector(31 downto 0);
reg_dest_new : in std_logic_vector(31 downto 0);
intr_enable : out std_logic);
end component;
 
component bus_mux
port(imm_in : in std_logic_vector(15 downto 0);
reg_source : in std_logic_vector(31 downto 0);
a_mux : in a_source_type;
a_out : out std_logic_vector(31 downto 0);
 
reg_target : in std_logic_vector(31 downto 0);
b_mux : in b_source_type;
b_out : out std_logic_vector(31 downto 0);
 
c_bus : in std_logic_vector(31 downto 0);
c_memory : in std_logic_vector(31 downto 0);
c_pc : in std_logic_vector(31 downto 0);
c_mux : in c_source_type;
reg_dest_out : out std_logic_vector(31 downto 0);
 
branch_func : in branch_function_type;
take_branch : out std_logic);
end component;
 
component alu
port(a_in : in std_logic_vector(31 downto 0);
b_in : in std_logic_vector(31 downto 0);
alu_function : in alu_function_type;
c_alu : out std_logic_vector(31 downto 0));
end component;
 
component shifter
port(value : in std_logic_vector(31 downto 0);
shift_amount : in std_logic_vector(4 downto 0);
shift_func : in shift_function_type;
c_shift : out std_logic_vector(31 downto 0));
end component;
 
component mult
port(clk : in std_logic;
a, b : in std_logic_vector(31 downto 0);
mult_func : in mult_function_type;
c_mult : out std_logic_vector(31 downto 0);
pause_out : out std_logic);
end component;
 
signal opcode : std_logic_vector(31 downto 0);
signal rs_index, rt_index, rd_index : std_logic_vector(5 downto 0);
signal reg_source, reg_target, reg_dest : std_logic_vector(31 downto 0);
signal a_bus, b_bus, c_bus : std_logic_vector(31 downto 0);
signal c_alu, c_shift, c_mult, c_memory
: std_logic_vector(31 downto 0);
signal imm : std_logic_vector(15 downto 0);
signal pc : std_logic_vector(31 downto 0);
signal alu_function : alu_function_type;
signal shift_function : shift_function_type;
signal mult_function : mult_function_type;
signal branch_function: branch_function_type;
signal take_branch : std_logic;
signal a_source : a_source_type;
signal b_source : b_source_type;
signal c_source : c_source_type;
signal pc_source : pc_source_type;
signal mem_source : mem_source_type;
signal pause_mult : std_logic;
signal pause_memory : std_logic;
signal pause : std_logic;
signal nullify_op : std_logic;
signal intr_enable : std_logic;
signal intr_signal : std_logic;
-- signal mem_byte_sel : std_logic_vector(3 downto 0);
-- signal mem_write : std_logic;
begin --architecture
 
pause <= pause_mult or pause_memory;
--nulify_op = pc_source==from_lbranch && take_branch=='0'
nullify_op <= pc_source(1) and pc_source(0) and not take_branch;
c_bus <= c_alu or c_shift or c_mult;
intr_signal <= (intr_in and intr_enable) and
(not pc_source(0) and not pc_source(1)); --from_inc4
 
u1: pc_next PORT MAP (
clk => clk,
reset_in => reset_in,
take_branch => take_branch,
pause_in => pause,
pc_new => c_alu(31 downto 2),
opcode25_0 => opcode(25 downto 0),
pc_source => pc_source,
pc_out => pc);
 
u2: mem_ctrl PORT MAP (
clk => clk,
reset_in => reset_in,
pause_in => pause,
nullify_op => nullify_op,
address_pc => pc,
opcode_out => opcode,
 
address_data => c_alu,
mem_source => mem_source,
data_write => reg_target,
data_read => c_memory,
pause_out => pause_memory,
mem_address => mem_address,
mem_data_w => mem_data_w,
mem_data_r => mem_data_r,
mem_byte_sel => mem_sel,
mem_write => mem_write,
mem_pause => mem_pause);
 
u3: control PORT MAP (
opcode => opcode,
intr_signal => intr_signal,
rs_index => rs_index,
rt_index => rt_index,
rd_index => rd_index,
imm_out => imm,
alu_func => alu_function,
shift_func => shift_function,
mult_func => mult_function,
branch_func => branch_function,
a_source_out => a_source,
b_source_out => b_source,
c_source_out => c_source,
pc_source_out=> pc_source,
mem_source_out=> mem_source);
 
u4: reg_bank port map (
clk => clk,
rs_index => rs_index,
rt_index => rt_index,
rd_index => rd_index,
reg_source_out => reg_source,
reg_target_out => reg_target,
reg_dest_new => reg_dest,
intr_enable => intr_enable);
 
u5: bus_mux port map (
imm_in => imm,
reg_source => reg_source,
a_mux => a_source,
a_out => a_bus,
 
reg_target => reg_target,
b_mux => b_source,
b_out => b_bus,
 
c_bus => c_bus,
c_memory => c_memory,
c_pc => pc,
c_mux => c_source,
reg_dest_out => reg_dest,
 
branch_func => branch_function,
take_branch => take_branch);
 
u6: alu port map (
a_in => a_bus,
b_in => b_bus,
alu_function => alu_function,
c_alu => c_alu);
 
u7: shifter port map (
value => b_bus,
shift_amount => a_bus(4 downto 0),
shift_func => shift_function,
c_shift => c_shift);
 
u8: mult port map (
clk => clk,
a => a_bus,
b => b_bus,
mult_func => mult_function,
c_mult => c_mult,
pause_out => pause_mult);
 
t_pc <= pc;
t_opcode <= opcode;
t_r_dest <= reg_dest;
 
end; --architecture logic
 
/ram.vhd
0,0 → 1,113
---------------------------------------------------------------------
-- TITLE: Random Access Memory
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
-- DATE CREATED: 4/21/01
-- FILENAME: ram.vhd
-- PROJECT: MIPS CPU core
-- COPYRIGHT: Software placed into the public domain by the author.
-- Software 'as is' without warranty. Author liable for nothing.
-- DESCRIPTION:
-- Implements the RAM, reads the executable from "code.txt",
-- and saves a character to "output.txt" upon a write to 0xffff.
-- Modified from "The Designer's Guide to VHDL" by Peter J. Ashenden
---------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_misc.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_textio.all;
use std.textio.all;
 
use ieee.std_logic_unsigned.all;
use work.mips_pack.all;
 
entity ram is
generic(load_file_name : string);
port(clk : in std_logic;
mem_byte_sel : in std_logic_vector(3 downto 0);
mem_write : in std_logic;
mem_address : in std_logic_vector;
mem_data_w : in std_logic_vector(31 downto 0);
mem_data_r : out std_logic_vector(31 downto 0));
end; --entity ram
 
architecture logic of ram is
begin
 
ram_proc: process
variable data : std_logic_vector(31 downto 0);
variable d : std_logic_vector(31 downto 0);
variable datab : std_logic_vector(31 downto 0);
variable value : natural;
subtype word is std_logic_vector(mem_data_w'length-1 downto 0);
type storage_array is
array(natural range 0 to 2**mem_address'length-1) of word;
variable storage : storage_array;
variable index : natural;
file load_file : text is in load_file_name;
file store_file : text is out "output.txt";
variable hex_file_line : line;
variable c : character;
variable line_length : natural := 0;
begin
--load in the ram executable image
index := 0;
while not endfile(load_file) loop
readline(load_file, hex_file_line);
hread(hex_file_line, data);
storage(index) := data;
index := index + 1;
end loop;
assert false report "done reading code" severity note;
 
wait on clk; --wait for line noise to go away
 
loop
wait on clk, mem_address, mem_write;
 
--support putchar() when writing to address 0xffff
if rising_edge(clk) then
if mem_write = '1' and mem_address = ONES(15 downto 0) then
index := conv_integer(mem_data_w(6 downto 0));
if index /= 10 then
c := character'val(index);
write(hex_file_line, c);
line_length := line_length + 1;
end if;
if index = 10 or line_length >= 72 then
writeline(store_file, hex_file_line);
line_length := 0;
end if;
end if;
end if;
 
index := conv_integer(mem_address(mem_address'length-1 downto 2));
data := storage(index);
 
if mem_write = '0' then
mem_data_r <= data;
end if;
if mem_byte_sel(0) = '1' then
data(7 downto 0) := mem_data_w(7 downto 0);
end if;
if mem_byte_sel(1) = '1' then
data(15 downto 8) := mem_data_w(15 downto 8);
end if;
if mem_byte_sel(2) = '1' then
data(23 downto 16) := mem_data_w(23 downto 16);
end if;
if mem_byte_sel(3) = '1' then
data(31 downto 24) := mem_data_w(31 downto 24);
end if;
if rising_edge(clk) then
if mem_write = '1' then
storage(index) := data;
end if;
end if;
end loop;
end process;
 
end; --architecture logic
 
 
/control.vhd
0,0 → 1,440
---------------------------------------------------------------------
-- TITLE: Controller / Opcode Decoder
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
-- DATE CREATED: 2/8/01
-- FILENAME: control.vhd
-- PROJECT: MIPS CPU core
-- COPYRIGHT: Software placed into the public domain by the author.
-- Software 'as is' without warranty. Author liable for nothing.
-- DESCRIPTION:
-- Controls the CPU by decoding the opcode and generating control
-- signals to the rest of the CPU.
-- This entity decodes the MIPS opcode into a Very-Long-Word-Instruction.
-- 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.
-- Based on information found in:
-- "MIPS RISC Architecture" by Gerry Kane and Joe Heinrich
-- and "The Designer's Guide to VHDL" by Peter J. Ashenden
---------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.mips_pack.all;
 
entity control is
port(opcode : in std_logic_vector(31 downto 0);
intr_signal : in std_logic;
rs_index : out std_logic_vector(5 downto 0);
rt_index : out std_logic_vector(5 downto 0);
rd_index : out std_logic_vector(5 downto 0);
imm_out : out std_logic_vector(15 downto 0);
alu_func : out alu_function_type;
shift_func : out shift_function_type;
mult_func : out mult_function_type;
branch_func : out branch_function_type;
a_source_out : out a_source_type;
b_source_out : out b_source_type;
c_source_out : out c_source_type;
pc_source_out: out pc_source_type;
mem_source_out:out mem_source_type);
end; --entity control
 
architecture logic of control is
-- type alu_function_type is (alu_nothing, alu_add, alu_subtract,
-- alu_less_than, alu_less_than_signed, alu_equal, alu_not_equal,
-- alu_ltz, alu_lez, alu_eqz, alu_nez, alu_gez, alu_gtz,
-- alu_or, alu_and, alu_xor, alu_nor);
-- type shift_function_type is (
-- shift_nothing, shift_left_unsigned,
-- shift_right_signed, shift_right_unsigned);
-- type mult_function_type is (
-- mult_nothing, mult_read_lo, mult_read_hi, mult_write_lo,
-- mult_write_hi, mult_mult, mult_divide, mult_signed_divide);
-- type a_source_type is (from_reg_source, from_imm10_6);
-- type b_source_type is (from_reg_target, from_imm, from_signed_imm);
-- type c_source_type is (from_null, from_alu, from_shift,
-- from_mult, from_memory, from_pc, from_imm_shift16,
-- from_reg_source_nez, from_reg_source_eqz);
-- type pc_source_type is (from_inc4, from_inc8, from_reg_source,
-- from_opcode25_0, from_branch, from_lbranch);
begin
 
control_proc: process(opcode, intr_signal)
variable op, func : std_logic_vector(5 downto 0);
variable rs, rt, rd : std_logic_vector(5 downto 0);
variable re, rtx : std_logic_vector(4 downto 0);
variable imm : std_logic_vector(15 downto 0);
variable alu_function : alu_function_type;
variable shift_function : shift_function_type;
variable mult_function : mult_function_type;
variable a_source : a_source_type;
variable b_source : b_source_type;
variable c_source : c_source_type;
variable pc_source : pc_source_type;
variable branch_function: branch_function_type;
variable mem_source : mem_source_type;
begin
alu_function := alu_nothing;
shift_function := shift_nothing;
mult_function := mult_nothing;
a_source := a_from_reg_source;
b_source := b_from_reg_target;
c_source := c_from_null;
pc_source := from_inc4;
branch_function := branch_eq;
mem_source := mem_none;
op := opcode(31 downto 26);
rs := '0' & opcode(25 downto 21);
rt := '0' & opcode(20 downto 16);
rtx := opcode(20 downto 16);
rd := '0' & opcode(15 downto 11);
re := opcode(10 downto 6);
func := opcode(5 downto 0);
imm := opcode(15 downto 0);
 
case op is
when "000000" => --00 SPECIAL
case func is
when "000000" => --00 SLL r[rd]=r[rt]<<re;
a_source := a_from_imm10_6;
c_source := c_from_shift;
shift_function := shift_left_unsigned;
when "000010" => --02 SRL r[rd]=u[rt]>>re;
a_source := a_from_imm10_6;
c_source := c_from_shift;
shift_function := shift_right_unsigned;
when "000011" => --03 SRA r[rd]=r[rt]>>re;
a_source := a_from_imm10_6;
c_source := c_from_shift;
shift_function := shift_right_signed;
when "000100" => --04 SLLV r[rd]=r[rt]<<r[rs];
c_source := c_from_shift;
shift_function := shift_left_unsigned;
when "000110" => --06 SRLV r[rd]=u[rt]>>r[rs];
c_source := c_from_shift;
shift_function := shift_right_unsigned;
when "000111" => --07 SRAV r[rd]=r[rt]>>r[rs];
c_source := c_from_shift;
shift_function := shift_right_signed;
when "001000" => --08 JR s->pc_next=r[rs];
pc_source := from_branch;
alu_function := alu_add;
branch_function := branch_yes;
when "001001" => --09 JALR r[rd]=s->pc_next; s->pc_next=r[rs];
c_source := c_from_pc;
pc_source := from_branch;
alu_function := alu_add;
branch_function := branch_yes;
when "001010" => --0a MOVZ if(!r[rt]) r[rd]=r[rs]; /*IV*/
-- c_source := c_from_reg_source_eqz;
when "001011" => --0b MOVN if(r[rt]) r[rd]=r[rs]; /*IV*/
-- c_source := from_reg_source_nez;
when "001100" => --0c SYSCALL
-- if(r[4]==0) printf("0x%8.8lx ",r[5]);
when "001101" => --0d BREAK s->wakeup=1;
when "001111" => --0f SYNC s->wakeup=1;
when "010000" => --10 MFHI r[rd]=s->hi;
c_source := c_from_mult;
mult_function := mult_read_hi;
when "010001" => --11 FTHI s->hi=r[rs];
mult_function := mult_write_hi;
when "010010" => --12 MFLO r[rd]=s->lo;
c_source := c_from_mult;
mult_function := mult_read_lo;
when "010011" => --13 MTLO s->lo=r[rs];
mult_function := mult_write_lo;
when "011000" => --18 MULT s->lo=r[rs]*r[rt]; s->hi=0;
mult_function := mult_mult;
when "011001" => --19 MULTU s->lo=r[rs]*r[rt]; s->hi=0;
mult_function := mult_mult;
when "011010" => --1a DIV s->lo=r[rs]/r[rt]; s->hi=r[rs]%r[rt];
mult_function := mult_signed_divide;
when "011011" => --1b DIVU s->lo=r[rs]/r[rt]; s->hi=r[rs]%r[rt];
mult_function := mult_divide;
when "100000" => --20 ADD r[rd]=r[rs]+r[rt];
c_source := c_from_alu;
alu_function := alu_add;
when "100001" => --21 ADDU r[rd]=r[rs]+r[rt];
c_source := c_from_alu;
alu_function := alu_add;
when "100010" => --22 SUB r[rd]=r[rs]-r[rt];
c_source := c_from_alu;
alu_function := alu_subtract;
when "100011" => --23 SUBU r[rd]=r[rs]-r[rt];
c_source := c_from_alu;
alu_function := alu_subtract;
when "100100" => --24 AND r[rd]=r[rs]&r[rt];
c_source := c_from_alu;
alu_function := alu_and;
when "100101" => --25 OR r[rd]=r[rs]|r[rt];
c_source := c_from_alu;
alu_function := alu_or;
when "100110" => --26 XOR r[rd]=r[rs]^r[rt];
c_source := c_from_alu;
alu_function := alu_xor;
when "100111" => --27 NOR r[rd]=~(r[rs]|r[rt]);
c_source := c_from_alu;
alu_function := alu_nor;
when "101010" => --2a SLT r[rd]=r[rs]<r[rt];
c_source := c_from_alu;
alu_function := alu_less_than_signed;
when "101011" => --2b SLTU r[rd]=u[rs]<u[rt];
c_source := c_from_alu;
alu_function := alu_less_than;
when "101101" => --2d DADDU r[rd]=r[rs]+u[rt];
c_source := c_from_alu;
alu_function := alu_add;
when "110001" => --31 TGEU
when "110010" => --32 TLT
when "110011" => --33 TLTU
when "110100" => --34 TEQ
when "110110" => --36 TNE
when others =>
end case;
when "000001" => --00 REGIMM
rt := "000000";
rd := "011111";
a_source := a_from_pc;
b_source := b_from_immX4;
alu_function := alu_add;
pc_source := from_branch;
branch_function := branch_gtz;
--if(test) pc=pc+imm*4
case rtx is
when "10000" => --10 BLTZAL r[31]=s->pc_next; branch=r[rs]<0;
c_source := c_from_pc;
branch_function := branch_ltz;
when "00000" => --00 BLTZ branch=r[rs]<0;
branch_function := branch_ltz;
when "10001" => --11 BGEZAL r[31]=s->pc_next; branch=r[rs]>=0;
c_source := c_from_pc;
branch_function := branch_gez;
when "00001" => --01 BGEZ branch=r[rs]>=0;
branch_function := branch_gez;
when "10010" => --12 BLTZALL r[31]=s->pc_next; lbranch=r[rs]<0;
c_source := c_from_pc;
pc_source := from_lbranch;
branch_function := branch_ltz;
when "00010" => --02 BLTZL lbranch=r[rs]<0;
pc_source := from_lbranch;
branch_function := branch_ltz;
when "10011" => --13 BGEZALL r[31]=s->pc_next; lbranch=r[rs]>=0;
c_source := c_from_pc;
pc_source := from_lbranch;
branch_function := branch_gez;
when "00011" => --03 BGEZL lbranch=r[rs]>=0;
pc_source := from_lbranch;
branch_function := branch_gez;
when others =>
end case;
when "000011" => --03 JAL r[31]=s->pc_next; s->pc_next=(s->pc&0xf0000000)|target;
c_source := c_from_pc;
rd := "011111";
pc_source := from_opcode25_0;
when "000010" => --02 J s->pc_next=(s->pc&0xf0000000)|target;
pc_source := from_opcode25_0;
when "000100" => --04 BEQ branch=r[rs]==r[rt];
a_source := a_from_pc;
b_source := b_from_immX4;
alu_function := alu_add;
pc_source := from_branch;
branch_function := branch_eq;
when "000101" => --05 BNE branch=r[rs]!=r[rt];
a_source := a_from_pc;
b_source := b_from_immX4;
alu_function := alu_add;
pc_source := from_branch;
branch_function := branch_ne;
when "000110" => --06 BLEZ branch=r[rs]<=0;
a_source := a_from_pc;
b_source := b_from_immX4;
alu_function := alu_add;
pc_source := from_branch;
branch_function := branch_ltz;
when "000111" => --07 BGTZ branch=r[rs]>0;
a_source := a_from_pc;
b_source := b_from_immX4;
alu_function := alu_add;
pc_source := from_branch;
branch_function := branch_gtz;
when "001000" => --08 ADDI r[rt]=r[rs]+(short)imm;
b_source := b_from_signed_imm;
c_source := c_from_alu;
rd := rt;
alu_function := alu_add;
when "001001" => --09 ADDIU u[rt]=u[rs]+(short)imm;
b_source := b_from_signed_imm;
c_source := c_from_alu;
rd := rt;
alu_function := alu_add;
when "001010" => --0a SLTI r[rt]=r[rs]<(short)imm;
b_source := b_from_signed_imm;
c_source := c_from_alu;
rd := rt;
alu_function := alu_less_than;
when "001011" => --0b SLTIU u[rt]=u[rs]<(unsigned long)(short)imm;
b_source := b_from_imm;
c_source := c_from_alu;
rd := rt;
alu_function := alu_less_than;
when "001100" => --0c ANDI r[rt]=r[rs]&imm;
b_source := b_from_imm;
c_source := c_from_alu;
rd := rt;
alu_function := alu_and;
when "001101" => --0d ORI r[rt]=r[rs]|imm;
b_source := b_from_imm;
c_source := c_from_alu;
rd := rt;
alu_function := alu_or;
when "001110" => --0e XORI r[rt]=r[rs]^imm;
b_source := b_from_imm;
c_source := c_from_alu;
rd := rt;
alu_function := alu_xor;
when "001111" => --0f LUI r[rt]=(imm<<16);
c_source := c_from_imm_shift16;
rd := rt;
when "010000" => --10 COP0
alu_function := alu_or;
c_source := c_from_alu;
if opcode(23) = '0' then --move from CP0
rs := '1' & opcode(15 downto 11);
rt := "000000";
rd := '0' & opcode(20 downto 16);
else --move to CP0
rs := "000000";
rd(5) := '1';
end if;
when "010001" => --11 COP1
when "010010" => --12 COP2
when "010011" => --13 COP3
when "010100" => --14 BEQL lbranch=r[rs]==r[rt];
a_source := a_from_pc;
b_source := b_from_immX4;
alu_function := alu_add;
pc_source := from_lbranch;
branch_function := branch_eq;
when "010101" => --15 BNEL lbranch=r[rs]!=r[rt];
a_source := a_from_pc;
b_source := b_from_immX4;
alu_function := alu_add;
pc_source := from_lbranch;
branch_function := branch_ne;
when "010110" => --16 BLEZL lbranch=r[rs]<=0;
a_source := a_from_pc;
b_source := b_from_immX4;
alu_function := alu_add;
pc_source := from_lbranch;
branch_function := branch_lez;
when "010111" => --17 BGTZL lbranch=r[rs]>0;
a_source := a_from_pc;
b_source := b_from_immX4;
alu_function := alu_add;
pc_source := from_lbranch;
branch_function := branch_gtz;
when "100000" => --20 LB r[rt]=*(signed char*)ptr;
a_source := a_from_reg_source;
b_source := b_from_imm;
alu_function := alu_add;
rd := rt;
c_source := c_from_memory;
mem_source := mem_read8s; --address=(short)imm+r[rs];
when "100001" => --21 LH r[rt]=*(signed short*)ptr;
a_source := a_from_reg_source;
b_source := b_from_imm;
alu_function := alu_add;
rd := rt;
c_source := c_from_memory;
mem_source := mem_read16s; --address=(short)imm+r[rs];
when "100010" => --22 LWL //fixme
when "100011" => --23 LW r[rt]=*(long*)ptr;
a_source := a_from_reg_source;
b_source := b_from_imm;
alu_function := alu_add;
rd := rt;
c_source := c_from_memory;
mem_source := mem_read32;
when "100100" => --24 LBU r[rt]=*(unsigned char*)ptr;
a_source := a_from_reg_source;
b_source := b_from_imm;
alu_function := alu_add;
rd := rt;
c_source := c_from_memory;
mem_source := mem_read8; --address=(short)imm+r[rs];
when "100101" => --25 LHU r[rt]=*(unsigned short*)ptr;
a_source := a_from_reg_source;
b_source := b_from_imm;
alu_function := alu_add;
rd := rt;
c_source := c_from_memory;
mem_source := mem_read16; --address=(short)imm+r[rs];
when "100110" => --26 LWR //fixme
when "101000" => --28 SB *(char*)ptr=(char)r[rt];
a_source := a_from_reg_source;
b_source := b_from_imm;
alu_function := alu_add;
mem_source := mem_write8; --address=(short)imm+r[rs];
when "101001" => --29 SH *(short*)ptr=(short)r[rt];
a_source := a_from_reg_source;
b_source := b_from_imm;
alu_function := alu_add;
mem_source := mem_write16;
when "101010" => --2a SWL //fixme
when "101011" => --2b SW *(long*)ptr=r[rt];
a_source := a_from_reg_source;
b_source := b_from_imm;
alu_function := alu_add;
mem_source := mem_write32; --address=(short)imm+r[rs];
when "101110" => --2e SWR //fixme
when "101111" => --2f CACHE
when "110000" => --30 LL r[rt]=*(long*)ptr;
when "110001" => --31 LWC1
when "110010" => --32 LWC2
when "110011" => --33 LWC3
when "110101" => --35 LDC1
when "110110" => --36 LDC2
when "110111" => --37 LDC3
when "111000" => --38 SC *(long*)ptr=r[rt]; r[rt]=1;
when "111001" => --39 SWC1
when "111010" => --3a SWC2
when "111011" => --3b SWC3
when "111101" => --3d SDC1
when "111110" => --3e SDC2
when "111111" => --3f SDC3
when others =>
end case;
 
if c_source = c_from_null then
rd := "000000";
end if;
 
if intr_signal = '1' then
rd := "101110"; --EPC
c_source := c_from_pc;
rs := "111111"; --interrupt vector
rt := "000000";
a_source := a_from_reg_source;
b_source := b_from_reg_target;
alu_function := alu_or;
pc_source := from_branch;
branch_function := branch_yes;
end if;
 
rs_index <= rs;
rt_index <= rt;
rd_index <= rd;
imm_out <= imm;
alu_func <= alu_function;
shift_func <= shift_function;
mult_func <= mult_function;
branch_func <= branch_function;
a_source_out <= a_source;
b_source_out <= b_source;
c_source_out <= c_source;
pc_source_out <= pc_source;
mem_source_out <= mem_source;
 
end process;
 
end; --logic
 
/pc_next.vhd
0,0 → 1,67
---------------------------------------------------------------------
-- TITLE: Program Counter Next
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
-- DATE CREATED: 2/8/01
-- FILENAME: pc_next.vhd
-- PROJECT: MIPS CPU core
-- COPYRIGHT: Software placed into the public domain by the author.
-- Software 'as is' without warranty. Author liable for nothing.
-- DESCRIPTION:
-- Implements the Program Counter logic.
---------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.mips_pack.all;
 
entity pc_next is
port(clk : in std_logic;
reset_in : in std_logic;
pc_new : in std_logic_vector(31 downto 2);
take_branch : in std_logic;
pause_in : in std_logic;
opcode25_0 : in std_logic_vector(25 downto 0);
pc_source : in pc_source_type;
pc_out : out std_logic_vector(31 downto 0));
end; --pc_next
 
architecture logic of pc_next is
-- type pc_source_type is (from_inc4, from_opcode25_0, from_branch,
-- from_lbranch);
signal pc_reg : std_logic_vector(31 downto 2); --:= ZERO(31 downto 2);
begin
 
pc_next: process(clk, reset_in, pc_new, take_branch, pause_in,
opcode25_0, pc_source,
pc_reg)
variable pc_inc, pc_next : std_logic_vector(31 downto 2);
begin
pc_inc := bv_increment(pc_reg); --pc_reg+1
pc_next := pc_reg;
case pc_source is
when from_inc4 =>
if pause_in = '0' then
pc_next := pc_inc;
end if;
when from_opcode25_0 =>
pc_next := pc_reg(31 downto 28) & opcode25_0;
when from_branch | from_lbranch =>
if take_branch = '1' then
pc_next := pc_new;
else
pc_next := pc_inc;
end if;
when others =>
end case;
if reset_in = '1' then
pc_next := ZERO(31 downto 2);
end if;
 
if rising_edge(clk) then
pc_reg <= pc_next;
end if;
 
pc_out <= pc_reg & "00";
end process;
 
end; --logic
 
/alu.vhd
0,0 → 1,106
---------------------------------------------------------------------
-- TITLE: Arithmetic Logic Unit
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
-- DATE CREATED: 2/8/01
-- FILENAME: alu.vhd
-- PROJECT: MIPS CPU core
-- COPYRIGHT: Software placed into the public domain by the author.
-- Software 'as is' without warranty. Author liable for nothing.
-- DESCRIPTION:
-- Implements the ALU.
---------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.mips_pack.all;
 
entity alu is
port(a_in : in std_logic_vector(31 downto 0);
b_in : in std_logic_vector(31 downto 0);
alu_function : in alu_function_type;
c_alu : out std_logic_vector(31 downto 0));
end; --alu
 
architecture logic of alu is
-- type alu_function_type is (alu_nothing, alu_add, alu_subtract,
-- alu_less_than, alu_less_than_signed, alu_equal, alu_not_equal,
-- alu_ltz, alu_lez, alu_eqz, alu_nez, alu_gez, alu_gtz,
-- alu_or, alu_and, alu_xor, alu_nor);
begin
 
alu_proc: process(a_in, b_in, alu_function)
variable c : std_logic_vector(31 downto 0);
variable aa, bb, sum : std_logic_vector(32 downto 0);
variable do_sub : std_logic;
variable a_eq_b : std_logic;
variable a_zero : std_logic;
variable sign_ext : std_logic;
begin
c := ZERO;
if alu_function = alu_add then
do_sub := '0';
else
do_sub := '1';
end if;
if alu_function = alu_less_than then
sign_ext := '0';
else
sign_ext := '1';
end if;
aa := (a_in(31) and sign_ext) & a_in;
bb := (b_in(31) and sign_ext) & b_in;
sum := bv_adder(aa, bb, do_sub);
-- sum := bv_adder_lookahead(aa, bb, do_sub);
if a_in = b_in then
a_eq_b := '1';
else
a_eq_b := '0';
end if;
if a_in = ZERO then
a_zero := '1';
else
a_zero := '0';
end if;
case alu_function is
when alu_add | alu_subtract => --c=a+b
c := sum(31 downto 0);
when alu_less_than => --c=a<b
c(0) := sum(32);
when alu_less_than_signed => --c=a<b;
c(0) := sum(32);
when alu_equal => --c=a==b
c(0) := a_eq_b;
when alu_not_equal => --c=a!=b
c(0) := not a_eq_b;
when alu_ltz => --c=a<0
c(0) := a_in(31);
when alu_lez => --c=a<=0
c(0) := a_in(31) or a_zero;
when alu_eqz => --c=a==0
c(0) := a_zero;
when alu_nez => --c=a!=0
c(0) := not a_zero;
when alu_gez => --c=a>=0
c(0) := not a_in(31);
when alu_gtz => --c=a>0
c(0) := not a_zero and not a_in(31);
when alu_or => --c=a|b
c := a_in or b_in;
when alu_and => --c=a&b
c := a_in and b_in;
when alu_xor => --c=a^b
c := a_in xor b_in;
when alu_nor => --c=~(a|b)
c := a_in nor b_in;
when others => --alu_function = alu_nothing
c := ZERO;
end case;
 
-- if alu_function = alu_nothing then
-- c_alu <= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ";
-- else
c_alu <= c;
-- end if;
end process;
 
end; --architecture logic
 
/mult.vhd
0,0 → 1,185
---------------------------------------------------------------------
-- TITLE: Multiplication and Division Unit
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
-- DATE CREATED: 1/31/01
-- FILENAME: mult.vhd
-- PROJECT: MIPS CPU core
-- COPYRIGHT: Software placed into the public domain by the author.
-- Software 'as is' without warranty. Author liable for nothing.
-- DESCRIPTION:
-- Implements the multiplication and division unit.
-- Normally takes 32 clock cycles.
---------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.mips_pack.all;
 
entity mult is
port(clk : in std_logic;
a, b : in std_logic_vector(31 downto 0);
mult_func : in mult_function_type;
c_mult : out std_logic_vector(31 downto 0);
pause_out : out std_logic);
end; --entity mult
 
architecture logic of mult is
-- type mult_function_type is (
-- mult_nothing, mult_read_lo, mult_read_hi, mult_write_lo,
-- mult_write_hi, mult_mult, mult_divide, mult_signed_divide);
signal do_div_reg : std_logic;
signal do_signed_reg : std_logic;
signal count_reg : std_logic_vector(5 downto 0);
signal reg_a : std_logic_vector(31 downto 0);
signal reg_b : std_logic_vector(63 downto 0);
signal answer_reg : std_logic_vector(31 downto 0);
begin
 
--multiplication/division unit
mult_proc: process(clk, a, b, mult_func,
do_div_reg, do_signed_reg, count_reg,
reg_a, reg_b, answer_reg)
variable do_div_temp : std_logic;
variable do_signed_temp : std_logic;
variable count_temp : std_logic_vector(5 downto 0);
variable a_temp : std_logic_vector(31 downto 0);
variable b_temp : std_logic_vector(63 downto 0);
variable answer_temp : std_logic_vector(31 downto 0);
 
variable sign_extension : std_logic;
variable aa, bb : std_logic_vector(32 downto 0);
variable sum : std_logic_vector(32 downto 0);
variable start : std_logic;
variable do_write : std_logic;
variable do_hi : std_logic;
 
begin
do_div_temp := do_div_reg;
do_signed_temp := do_signed_reg;
count_temp := count_reg;
a_temp := reg_a;
b_temp := reg_b;
answer_temp := answer_reg;
 
sign_extension := '0';
aa := '0' & ZERO;
bb := '0' & ZERO;
sum := '0' & ZERO;
start := '0';
do_write := '0';
do_hi := '0';
 
case mult_func is
when mult_read_lo =>
when mult_read_hi =>
do_hi := '1';
when mult_write_lo =>
do_write := '1';
when mult_write_hi =>
do_write := '1';
do_hi := '1';
when mult_mult =>
start := '1';
do_div_temp := '0';
when mult_divide =>
start := '1';
do_div_temp := '1';
do_signed_temp := '0';
when mult_signed_divide =>
start := '1';
do_div_temp := '1';
do_signed_temp := '1';
when others =>
end case;
 
if start = '1' then
count_temp := "000000";
a_temp := a;
answer_temp := ZERO;
if do_div_temp = '1' then
if do_signed_temp = '0' or b(31) = '0' then
b_temp(62 downto 31) := b;
else
b_temp(62 downto 31) := bv_negate(b);
a_temp := bv_negate(a);
end if;
b_temp(30 downto 0) := ZERO(30 downto 0);
else --multiply
b_temp := zero & b;
end if;
elsif do_write = '1' then
if do_hi = '0' then
b_temp(31 downto 0) := a;
else
b_temp(63 downto 32) := a;
end if;
end if;
 
if do_div_reg = '1' then
bb := reg_b(32 downto 0);
else
bb := '0' & reg_b(63 downto 32);
end if;
sign_extension := reg_a(31) and do_signed_reg;
aa := sign_extension & reg_a;
sum := bv_adder(aa, bb, do_div_reg);
-- sum := bv_adder_lookahead(aa, bb, do_div_reg);
 
if count_reg(5) = '0' and start = '0' then
count_temp := bv_inc6(count_reg);
if do_div_reg = '1' then
answer_temp(31 downto 1) := answer_reg(30 downto 0);
if reg_b(63 downto 32) = ZERO and sum(32) = '0' then
a_temp := sum(31 downto 0); --aa=aa-bb;
answer_temp(0) := '1';
else
answer_temp(0) := '0';
end if;
if count_reg /= "011111" then
b_temp(62 downto 0) := reg_b(63 downto 1);
else
b_temp(63 downto 32) := a_temp;
b_temp(31 downto 0) := answer_temp;
end if;
else -- mult_mode
if reg_b(0) = '1' then
b_temp(63 downto 31) := sum;
else
b_temp(63 downto 31) := '0' & reg_b(63 downto 32);
end if;
b_temp(30 downto 0) := reg_b(31 downto 1);
if count_reg = "010000" and --early stop
reg_b(15 downto 0) = zero(15 downto 0) then
count_temp := "111111";
b_temp(31 downto 0) := reg_b(47 downto 16);
end if;
end if;
end if;
 
if rising_edge(clk) then
do_div_reg <= do_div_temp;
do_signed_reg <= do_signed_temp;
count_reg <= count_temp;
reg_a <= a_temp;
reg_b <= b_temp;
answer_reg <= answer_temp;
end if;
 
if count_reg(5) = '0' and mult_func/= mult_nothing and start = '0' then
pause_out <= '1';
else
pause_out <= '0';
end if;
if mult_func = mult_read_lo then
c_mult <= reg_b(31 downto 0);
elsif mult_func = mult_read_hi then
c_mult <= reg_b(63 downto 32);
else
-- c_mult <= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ";
c_mult <= ZERO;
end if;
 
end process;
 
end; --architecture logic
 
 
/bus_mux.vhd
0,0 → 1,135
---------------------------------------------------------------------
-- TITLE: Bus Multiplexer / Signal Router
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
-- DATE CREATED: 2/8/01
-- FILENAME: bus_mux.vhd
-- PROJECT: MIPS CPU core
-- COPYRIGHT: Software placed into the public domain by the author.
-- Software 'as is' without warranty. Author liable for nothing.
-- DESCRIPTION:
-- This entity is the main signal router.
-- It multiplexes signals from multiple sources to the correct location.
-- The outputs are as follows:
-- a_bus : goes to the ALU
-- b_bus : goes to the ALU
-- reg_dest_out : goes to the register bank
-- take_branch : a signal to pc_next
---------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.mips_pack.all;
 
entity bus_mux is
port(imm_in : in std_logic_vector(15 downto 0);
reg_source : in std_logic_vector(31 downto 0);
a_mux : in a_source_type;
a_out : out std_logic_vector(31 downto 0);
 
reg_target : in std_logic_vector(31 downto 0);
b_mux : in b_source_type;
b_out : out std_logic_vector(31 downto 0);
 
c_bus : in std_logic_vector(31 downto 0);
c_memory : in std_logic_vector(31 downto 0);
c_pc : in std_logic_vector(31 downto 0);
c_mux : in c_source_type;
reg_dest_out : out std_logic_vector(31 downto 0);
 
branch_func : in branch_function_type;
take_branch : out std_logic);
end; --entity bus_mux
 
architecture logic of bus_mux is
begin
-- type a_source_type is (a_from_reg_source, a_from_imm10_6);
-- type b_source_type is (b_from_reg_target, b_from_imm, b_from_signed_imm);
-- type c_source_type is (c_from_null, c_from_alu, c_from_shift,
-- c_from_mult, c_from_memory, c_from_pc, c_from_imm_shift16,
-- c_from_reg_source_nez, c_from_reg_source_eqz);
amux: process(reg_source, imm_in, a_mux, c_pc)
begin
a_out(31 downto 5) <= reg_source(31 downto 5);
case a_mux is
when a_from_reg_source =>
a_out(4 downto 0) <= reg_source(4 downto 0);
when a_from_imm10_6 =>
a_out(4 downto 0) <= imm_in(10 downto 6);
when others => --a_from_pc
a_out <= c_pc;
end case;
end process;
 
bmux: process(reg_target, imm_in, b_mux)
begin
case b_mux is
when b_from_reg_target =>
b_out <= reg_target;
when b_from_imm =>
b_out <= ZERO(31 downto 16) & imm_in;
when b_from_signed_imm =>
if imm_in(15) = '0' then
b_out(31 downto 16) <= ZERO(31 downto 16);
else
b_out(31 downto 16) <= "1111111111111111";
end if;
b_out(15 downto 0) <= imm_in;
when others => --b_from_immX4
if imm_in(15) = '0' then
b_out(31 downto 18) <= "00000000000000";
else
b_out(31 downto 18) <= "11111111111111";
end if;
b_out(17 downto 0) <= imm_in & "00";
end case;
end process;
 
cmux: process(c_bus, c_memory, c_pc, imm_in, c_mux)
begin
case c_mux is
when c_from_alu | c_from_shift | c_from_mult =>
reg_dest_out <= c_bus;
when c_from_memory =>
reg_dest_out <= c_memory;
when c_from_pc =>
reg_dest_out <= c_pc;
when c_from_imm_shift16 =>
reg_dest_out <= imm_in & ZERO(15 downto 0);
-- when from_reg_source_nez =>
--????
-- when from_reg_source_eqz =>
--????
when others =>
reg_dest_out <= c_bus;
end case;
end process;
 
pc_mux: process(branch_func, reg_source, reg_target)
variable is_equal : std_logic;
begin
if reg_source = reg_target then
is_equal := '1';
else
is_equal := '0';
end if;
case branch_func is
when branch_ltz =>
take_branch <= reg_source(31);
when branch_lez =>
take_branch <= reg_source(31) or is_equal;
when branch_eq =>
take_branch <= is_equal;
when branch_ne =>
take_branch <= not is_equal;
when branch_gez =>
take_branch <= not reg_source(31);
when branch_gtz =>
take_branch <= not reg_source(31) and not is_equal;
when branch_yes =>
take_branch <= '1';
when others =>
take_branch <= is_equal;
end case;
end process;
 
end; --architecture logic
 
/mem_ctrl.vhd
0,0 → 1,178
---------------------------------------------------------------------
-- TITLE: Memory Controller
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
-- DATE CREATED: 1/31/01
-- FILENAME: mem_ctrl.vhd
-- PROJECT: MIPS CPU core
-- COPYRIGHT: Software placed into the public domain by the author.
-- Software 'as is' without warranty. Author liable for nothing.
-- DESCRIPTION:
-- Memory controller for the MIPS CPU.
-- Supports Big or Little Endian mode.
-- This entity could implement interfaces to:
-- Data cache
-- Address cache
-- Memory management unit (MMU)
-- DRAM controller
---------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.mips_pack.all;
 
entity mem_ctrl is
port(clk : in std_logic;
reset_in : in std_logic;
pause_in : in std_logic;
nullify_op : in std_logic;
address_pc : in std_logic_vector(31 downto 0);
opcode_out : out std_logic_vector(31 downto 0);
 
address_data : in std_logic_vector(31 downto 0);
mem_source : in mem_source_type;
data_write : in std_logic_vector(31 downto 0);
data_read : out std_logic_vector(31 downto 0);
pause_out : out std_logic;
mem_address : out std_logic_vector(31 downto 0);
mem_data_w : out std_logic_vector(31 downto 0);
mem_data_r : in std_logic_vector(31 downto 0);
mem_byte_sel : out std_logic_vector(3 downto 0);
mem_write : out std_logic;
mem_pause : in std_logic);
end; --entity mem_ctrl
 
architecture logic of mem_ctrl is
--"00" = big_endian; "11" = little_endian
constant little_endian : std_logic_vector(1 downto 0) := "00";
signal opcode_reg : std_logic_vector(31 downto 0);
signal next_opcode_reg : std_logic_vector(31 downto 0);
signal setup_done : std_logic;
begin
 
mem_proc: process(clk, reset_in, pause_in, nullify_op, address_pc,
address_data, mem_source, data_write, mem_data_r,
mem_pause,
opcode_reg, next_opcode_reg, setup_done)
variable data, datab : std_logic_vector(31 downto 0);
variable opcode_temp : std_logic_vector(31 downto 0);
variable byte_sel_temp : std_logic_vector(3 downto 0);
variable write_temp : std_logic;
variable setup_done_var : std_logic;
variable pause : std_logic;
variable address_temp : std_logic_vector(31 downto 0);
variable bits : std_logic_vector(1 downto 0);
variable mem_data_w_v : std_logic_vector(31 downto 0);
begin
byte_sel_temp := "0000";
write_temp := '0';
pause := '0';
setup_done_var := setup_done;
 
address_temp := address_pc;
data := mem_data_r;
datab := ZERO;
mem_data_w_v := ZERO; --"ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ";
 
case mem_source is
when mem_read32 =>
datab := data;
when mem_read16 | mem_read16s =>
if address_data(1) = little_endian(1) then
datab(15 downto 0) := data(31 downto 16);
else
datab(15 downto 0) := data(15 downto 0);
end if;
if mem_source = mem_read16 or datab(15) = '0' then
datab(31 downto 16) := ZERO(31 downto 16);
else
datab(31 downto 16) := ONES(31 downto 16);
end if;
when mem_read8 | mem_read8s =>
bits := address_data(1 downto 0) xor little_endian;
case bits is
when "00" => datab(7 downto 0) := data(31 downto 24);
when "01" => datab(7 downto 0) := data(23 downto 16);
when "10" => datab(7 downto 0) := data(15 downto 8);
when others => datab(7 downto 0) := data(7 downto 0);
end case;
if mem_source = mem_read8 or datab(7) = '0' then
datab(31 downto 8) := ZERO(31 downto 8);
else
datab(31 downto 8) := ONES(31 downto 8);
end if;
when mem_write32 =>
write_temp := '1';
mem_data_w_v := data_write;
byte_sel_temp := "1111";
when mem_write16 =>
write_temp := '1';
mem_data_w_v := data_write(15 downto 0) & data_write(15 downto 0);
if address_data(1) = little_endian(1) then
byte_sel_temp := "1100";
else
byte_sel_temp := "0011";
end if;
when mem_write8 =>
write_temp := '1';
mem_data_w_v := data_write(7 downto 0) & data_write(7 downto 0) &
data_write(7 downto 0) & data_write(7 downto 0);
bits := address_data(1 downto 0) xor little_endian;
case bits is
when "00" =>
byte_sel_temp := "1000";
when "01" =>
byte_sel_temp := "0100";
when "10" =>
byte_sel_temp := "0010";
when others =>
byte_sel_temp := "0001";
end case;
when others =>
end case;
 
opcode_temp := opcode_reg;
if mem_source = mem_none then
setup_done_var := '0';
if pause_in = '0' and mem_pause = '0' then
if nullify_op = '0' then
opcode_temp := data;
else
opcode_temp := ZERO; --NOP
end if;
end if;
else
pause := not setup_done;
setup_done_var := '1';
if setup_done = '1' then
address_temp := address_data;
if mem_pause = '0' then
opcode_temp := next_opcode_reg;
setup_done_var := '0';
end if;
end if;
end if;
if reset_in = '1' then
setup_done_var := '0';
opcode_temp := ZERO;
end if;
 
if rising_edge(clk) then
opcode_reg <= opcode_temp;
if setup_done = '0' then
next_opcode_reg <= data;
end if;
setup_done <= setup_done_var;
end if;
 
opcode_out <= opcode_reg;
data_read <= datab;
pause_out <= mem_pause or pause;
mem_byte_sel <= byte_sel_temp;
mem_address <= address_temp;
mem_write <= write_temp and setup_done;
mem_data_w <= mem_data_w_v;
 
end process; --data_proc
 
end; --architecture logic
 
/tbench.vhd
0,0 → 1,99
---------------------------------------------------------------------
-- TITLE: Test Bench
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
-- DATE CREATED: 4/21/01
-- FILENAME: tbench.vhd
-- PROJECT: MIPS CPU core
-- COPYRIGHT: Software placed into the public domain by the author.
-- Software 'as is' without warranty. Author liable for nothing.
-- DESCRIPTION:
-- This entity provides a test bench for testing the MIPS CPU core.
---------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.mips_pack.all;
 
entity tbench is
port(clk_out : out std_logic;
pc : out std_logic_vector(31 downto 0)
);
end; --entity tbench
 
architecture logic of tbench is
 
component mips_cpu
port(clk : in std_logic;
reset_in : in std_logic;
intr_in : in std_logic;
 
mem_address : out std_logic_vector(31 downto 0);
mem_data_w : out std_logic_vector(31 downto 0);
mem_data_r : in std_logic_vector(31 downto 0);
mem_sel : out std_logic_vector(3 downto 0);
mem_write : out std_logic;
mem_pause : in std_logic;
 
t_pc : out std_logic_vector(31 downto 0);
t_opcode : out std_logic_vector(31 downto 0);
t_r_dest : out std_logic_vector(31 downto 0)
);
end component;
 
component ram
generic(load_file_name : string);
port(clk : in std_logic;
mem_byte_sel : in std_logic_vector(3 downto 0);
mem_write : in std_logic;
mem_address : in std_logic_vector;
mem_data_w : in std_logic_vector(31 downto 0);
mem_data_r : out std_logic_vector(31 downto 0));
end component;
 
signal clk : std_logic := '0';
signal reset : std_logic := '1'; --, '0' after 100 ns;
signal interrupt : std_logic := '0';
signal mem_sel : std_logic_vector(3 downto 0);
signal mem_write : std_logic;
signal mem_address : std_logic_vector(31 downto 0);
signal mem_data_w : std_logic_vector(31 downto 0);
signal mem_data_r : std_logic_vector(31 downto 0);
signal mem_pause : std_logic;
signal t_pc : std_logic_vector(31 downto 0);
signal t_opcode : std_logic_vector(31 downto 0);
signal t_r_dest : std_logic_vector(31 downto 0);
signal mem_byte_sel: std_logic_vector(3 downto 0);
begin --architecture
clk <= not clk after 50 ns;
reset <= '0' after 100 ns;
mem_pause <= '0';
 
u1: mips_cpu PORT MAP (
clk => clk,
reset_in => reset,
intr_in => interrupt,
 
mem_address => mem_address,
mem_data_w => mem_data_w,
mem_data_r => mem_data_r,
mem_sel => mem_byte_sel,
mem_write => mem_write,
mem_pause => mem_pause,
 
t_pc => t_pc,
t_opcode => t_opcode,
t_r_dest => t_r_dest);
 
u2: ram generic map ("code.txt")
PORT MAP (
clk => clk,
mem_byte_sel => mem_byte_sel,
mem_write => mem_write,
mem_address => mem_address(15 downto 0),
mem_data_w => mem_data_w,
mem_data_r => mem_data_r);
 
clk_out <= clk;
pc <= t_pc;
 
end; --architecture logic
 
/shifter.vhd
0,0 → 1,107
---------------------------------------------------------------------
-- TITLE: Shifter Unit
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
-- DATE CREATED: 2/2/01
-- FILENAME: shifter.vhd
-- PROJECT: MIPS CPU core
-- COPYRIGHT: Software placed into the public domain by the author.
-- Software 'as is' without warranty. Author liable for nothing.
-- DESCRIPTION:
-- Implements the 32-bit shifter unit.
---------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.mips_pack.all;
 
entity shifter is
port(value : in std_logic_vector(31 downto 0);
shift_amount : in std_logic_vector(4 downto 0);
shift_func : in shift_function_type;
c_shift : out std_logic_vector(31 downto 0));
end; --entity shifter
 
architecture logic of shifter is
-- type shift_function_type is (
-- shift_nothing, shift_left_unsigned,
-- shift_left_signed, shift_right_unsigned);
begin
 
shift_proc: process(value, shift_amount, shift_func) --barrel shifter unit
variable shift1, shift2, shift4,
shift8, shift16 : std_logic_vector(31 downto 0);
variable fills : std_logic_vector(31 downto 16);
variable go_right : std_logic;
begin
if shift_func = shift_right_unsigned or shift_func = shift_right_signed then
go_right := '1';
else
go_right := '0';
end if;
if shift_func = shift_right_signed and value(31) = '1' then
fills := "1111111111111111";
else
fills := "0000000000000000";
end if;
if go_right = '0' then --shift left
if shift_amount(0) = '1' then
shift1 := value(30 downto 0) & '0';
else
shift1 := value;
end if;
if shift_amount(1) = '1' then
shift2 := shift1(29 downto 0) & "00";
else
shift2 := shift1;
end if;
if shift_amount(2) = '1' then
shift4 := shift2(27 downto 0) & "0000";
else
shift4 := shift2;
end if;
if shift_amount(3) = '1' then
shift8 := shift4(23 downto 0) & "00000000";
else
shift8 := shift4;
end if;
if shift_amount(4) = '1' then
shift16 := shift8(15 downto 0) & ZERO(15 downto 0);
else
shift16 := shift8;
end if;
else --shift right
if shift_amount(0) = '1' then
shift1 := fills(31) & value(31 downto 1);
else
shift1 := value;
end if;
if shift_amount(1) = '1' then
shift2 := fills(31 downto 30) & shift1(31 downto 2);
else
shift2 := shift1;
end if;
if shift_amount(2) = '1' then
shift4 := fills(31 downto 28) & shift2(31 downto 4);
else
shift4 := shift2;
end if;
if shift_amount(3) = '1' then
shift8 := fills(31 downto 24) & shift4(31 downto 8);
else
shift8 := shift4;
end if;
if shift_amount(4) = '1' then
shift16 := fills(31 downto 16) & shift8(31 downto 16);
else
shift16 := shift8;
end if;
end if; --shift_dir
if shift_func = shift_nothing then
-- c_shift <= "ZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZZ";
c_shift <= ZERO;
else
c_shift <= shift16;
end if;
end process;
 
end; --architecture logic
 
/mips_pack.vhd
0,0 → 1,274
---------------------------------------------------------------------
-- TITLE: MIPS Misc. Package
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
-- DATE CREATED: 2/15/01
-- FILENAME: mips_pack.vhd
-- PROJECT: MIPS CPU core
-- COPYRIGHT: Software placed into the public domain by the author.
-- Software 'as is' without warranty. Author liable for nothing.
-- DESCRIPTION:
-- Data types, constants, and add functions needed for the MIPS CPU.
---------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
 
package mips_pack is
constant ZERO : std_logic_vector(31 downto 0) :=
"00000000000000000000000000000000";
constant ONES : std_logic_vector(31 downto 0) :=
"11111111111111111111111111111111";
-- type alu_function_type is (alu_nothing, alu_add, alu_subtract,
-- alu_less_than, alu_less_than_signed, alu_equal, alu_not_equal,
-- alu_ltz, alu_lez, alu_eqz, alu_nez, alu_gez, alu_gtz,
-- alu_or, alu_and, alu_xor, alu_nor);
subtype alu_function_type is std_logic_vector(4 downto 0);
constant alu_nothing : alu_function_type := "00000";
constant alu_add : alu_function_type := "00010";
constant alu_subtract : alu_function_type := "00011";
constant alu_less_than : alu_function_type := "00100";
constant alu_less_than_signed : alu_function_type := "00101";
constant alu_equal : alu_function_type := "00110";
constant alu_not_equal : alu_function_type := "00111";
constant alu_ltz : alu_function_type := "01000";
constant alu_lez : alu_function_type := "01001";
constant alu_eqz : alu_function_type := "01010";
constant alu_nez : alu_function_type := "01011";
constant alu_gez : alu_function_type := "01100";
constant alu_gtz : alu_function_type := "01101";
constant alu_or : alu_function_type := "01110";
constant alu_and : alu_function_type := "01111";
constant alu_xor : alu_function_type := "10001";
constant alu_nor : alu_function_type := "10010";
 
-- type shift_function_type is (
-- shift_nothing, shift_left_unsigned,
-- shift_right_signed, do_right_unsigned);
subtype shift_function_type is std_logic_vector(1 downto 0);
constant shift_nothing : shift_function_type := "00";
constant shift_left_unsigned : shift_function_type := "01";
constant shift_right_signed : shift_function_type := "11";
constant shift_right_unsigned : shift_function_type := "10";
 
-- type mult_function_type is (
-- mult_nothing, mult_read_lo, mult_read_hi, mult_write_lo,
-- mult_write_hi, mult_mult, mult_divide, mult_signed_divide);
subtype mult_function_type is std_logic_vector(2 downto 0);
constant mult_nothing : mult_function_type := "000";
constant mult_read_lo : mult_function_type := "001";
constant mult_read_hi : mult_function_type := "010";
constant mult_write_lo : mult_function_type := "011";
constant mult_write_hi : mult_function_type := "100";
constant mult_mult : mult_function_type := "101";
constant mult_divide : mult_function_type := "110";
constant mult_signed_divide : mult_function_type := "111";
 
-- type a_source_type is (from_reg_source, from_imm10_6);
subtype a_source_type is std_logic_vector(1 downto 0);
constant a_from_reg_source : a_source_type := "00";
constant a_from_imm10_6 : a_source_type := "01";
constant a_from_pc : a_source_type := "10";
 
-- type b_source_type is (from_reg_target, from_imm, from_signed_imm);
subtype b_source_type is std_logic_vector(1 downto 0);
constant b_from_reg_target : b_source_type := "00";
constant b_from_imm : b_source_type := "01";
constant b_from_signed_imm : b_source_type := "10";
constant b_from_immX4 : b_source_type := "11";
 
-- type c_source_type is (from_null, from_alu, from_shift,
-- from_mult, from_memory, from_pc, from_imm_shift16,
-- from_reg_source_nez, from_reg_source_eqz);
subtype c_source_type is std_logic_vector(2 downto 0);
constant c_from_alu : c_source_type := "000";
constant c_from_shift : c_source_type := "001";
constant c_from_mult : c_source_type := "010";
constant c_from_memory : c_source_type := "011";
constant c_from_pc : c_source_type := "100";
constant c_from_imm_shift16: c_source_type := "101";
constant c_from_reg_sourcen: c_source_type := "110";
constant c_from_null : c_source_type := "111";
 
-- type pc_source_type is (from_inc4, from_inc8, from_reg_source,
-- from_opcode25_0, from_branch, from_lbranch);
subtype pc_source_type is std_logic_vector(1 downto 0);
constant from_inc4 : pc_source_type := "00";
constant from_opcode25_0 : pc_source_type := "01";
constant from_branch : pc_source_type := "10";
constant from_lbranch : pc_source_type := "11";
 
subtype branch_function_type is std_logic_vector(2 downto 0);
constant branch_ltz : branch_function_type := "000";
constant branch_lez : branch_function_type := "001";
constant branch_eq : branch_function_type := "010";
constant branch_ne : branch_function_type := "011";
constant branch_gez : branch_function_type := "100";
constant branch_gtz : branch_function_type := "101";
constant branch_yes : branch_function_type := "110";
 
-- mode(32=1,16=2,8=3), signed, write
subtype mem_source_type is std_logic_vector(3 downto 0);
constant mem_none : mem_source_type := "0000";
constant mem_read32 : mem_source_type := "0100";
constant mem_write32 : mem_source_type := "0101";
constant mem_read16 : mem_source_type := "1000";
constant mem_read16s : mem_source_type := "1010";
constant mem_write16 : mem_source_type := "1001";
constant mem_read8 : mem_source_type := "1100";
constant mem_read8s : mem_source_type := "1110";
constant mem_write8 : mem_source_type := "1101";
 
function bv_to_integer(bv: in std_logic_vector) return integer;
function bv_adder(a : in std_logic_vector(32 downto 0);
b : in std_logic_vector(32 downto 0);
do_sub: in std_logic) return std_logic_vector;
function bv_adder_lookahead(
a : in std_logic_vector(32 downto 0);
b : in std_logic_vector(32 downto 0);
do_sub: in std_logic) return std_logic_vector;
function bv_negate(a : in std_logic_vector) return std_logic_vector;
function bv_increment(a : in std_logic_vector(31 downto 2)
) return std_logic_vector;
function bv_inc6(a : in std_logic_vector
) return std_logic_vector;
end; --package mips_pack
 
package body mips_pack is
 
function add_1(a:integer) return integer is
begin
return a+1;
end; --function
 
function bv_to_integer(bv: in std_logic_vector) return integer is
variable result : integer;
variable b : integer;
begin
result := 0;
b := 0;
for index in bv'range loop
if bv(index) = '1' then
b := 1;
else
b := 0;
end if;
result := result * 2 + b;
end loop;
return result;
end; --function bv_to_integer
 
function bv_adder(a : in std_logic_vector(32 downto 0);
b : in std_logic_vector(32 downto 0);
do_sub: in std_logic) return std_logic_vector is
variable carry_in : std_logic;
variable bb : std_logic_vector(32 downto 0);
variable result : std_logic_vector(32 downto 0);
begin
result := "000000000000000000000000000000000";
if do_sub = '0' then
bb := b;
carry_in := '0';
else
bb := not b;
carry_in := '1';
end if;
for index in 0 to 32 loop
result(index) := a(index) xor bb(index) xor carry_in;
carry_in := (carry_in and (a(index) or bb(index))) or
(a(index) and bb(index));
end loop;
return result;
end; --function
 
function bv_adder_lookahead(
a : in std_logic_vector(32 downto 0);
b : in std_logic_vector(32 downto 0);
do_sub: in std_logic) return std_logic_vector is
variable carry : std_logic_vector(32 downto 0);
variable p, g : std_logic_vector(32 downto 0);
variable bb : std_logic_vector(32 downto 0);
variable result : std_logic_vector(32 downto 0);
variable i : natural;
begin
carry := "000000000000000000000000000000000";
if do_sub = '0' then
bb := b;
carry(0) := '0';
else
bb := not b;
carry(0) := '1';
end if;
 
p := a or bb; --propogate
g := a and bb; --generate
for index in 0 to 7 loop
i := index*4;
carry(i+1) := g(i) or
(p(i) and carry(i));
i := index*4+1;
carry(i+1) := g(i) or
(p(i) and g(i-1)) or
((p(i) and p(i-1)) and carry(i-1));
i := index*4+2;
carry(i+1) := g(i) or
(p(i) and g(i-1)) or
(p(i) and p(i-1) and g(i-2)) or
((p(i) and p(i-1) and p(i-2)) and carry(i-2));
i := index*4+3;
carry(i+1) := g(i) or
(p(i) and g(i-1)) or
(p(i) and p(i-1) and g(i-2)) or
(p(i) and p(i-1) and p(i-2) and g(i-3)) or
(((p(i) and p(i-1)) and (p(i-2) and p(i-3)))
and carry(i-3));
end loop;
result := (a xor bb) xor carry;
return result;
end; --function
 
function bv_negate(a : in std_logic_vector) return std_logic_vector is
variable carry_in : std_logic;
variable not_a : std_logic_vector(31 downto 0);
variable result : std_logic_vector(31 downto 0);
begin
result := ZERO;
not_a := not a;
carry_in := '1';
for index in a'reverse_range loop
result(index) := not_a(index) xor carry_in;
carry_in := carry_in and not_a(index);
end loop;
return result;
end; --function
 
function bv_increment(a : in std_logic_vector(31 downto 2)
) return std_logic_vector is
variable carry_in : std_logic;
variable result : std_logic_vector(31 downto 2);
begin
result := "000000000000000000000000000000";
carry_in := '1';
for index in 2 to 31 loop
result(index) := a(index) xor carry_in;
carry_in := a(index) and carry_in;
end loop;
return result;
end; --function
 
function bv_inc6(a : in std_logic_vector
) return std_logic_vector is
variable carry_in : std_logic;
variable result : std_logic_vector(5 downto 0);
begin
result := "000000";
carry_in := '1';
for index in 0 to 5 loop
result(index) := a(index) xor carry_in;
carry_in := a(index) and carry_in;
end loop;
return result;
end; --function
 
end; --package body
 
 
/code.txt
0,0 → 1,640
341d8000
afbf0014
041100cb
00000000
8fbf0014
03e00008
27bd0018
80ae0000
00801825
24840001
a08effff
8082ffff
24a50001
10400008
00000000
80af0000
24840001
24a50001
a08fffff
8082ffff
5440fffb
80af0000
03e00008
00601025
27bdffa8
afb10018
afb00014
00c08025
00e08825
afbf001c
afa40058
afa5005c
240e0020
240f0020
24180020
a3b80042
a3af0041
a3ae0040
27a30043
27a4004f
24020020
24630004
a062fffc
a062fffd
a062fffe
1464fffb
a062ffff
8fb90058
a3a0004f
8fa90058
07230005
24080001
2401000a
12010002
2408ffff
24080001
01280019
2405000e
27a6004e
2407000f
00002012
00000000
00000000
0090001b
16000002
00000000
0007000d
00001010
00002012
2841000a
54200002
24430030
24430057
14800006
a0c30000
8e2b0000
00e55023
014b082a
50200005
2401ffff
24a5ffff
04a1ffed
24c6ffff
2401ffff
15010004
240c002d
a0ccffff
24a5ffff
24c6ffff
8e220000
240d000f
01a58023
10400003
0050082a
10200006
8fa4005c
8fa4005c
0411ffa5
00c02825
10000005
ae300000
00027023
27af004f
0411ff9f
01cf2821
8fb00014
8fb10018
8fbf001c
03e00008
27bd0058
27bdff58
afa600b0
00a03025
afbf0014
afa500ac
27a50020
0411ffa3
27a700b0
83af0020
27ae0020
01c01025
51e00010
8fbf0014
81c30000
2406000d
2405000a
3404ffff
a0830000
80580000
24420001
54b80004
80430000
2442ffff
a0460000
80430000
5460fff8
a0830000
8fbf0014
03e00008
27bd00a8
2402001c
3405ffff
00441806
3063000f
2c61000a
10200004
2442fffc
246e0030
10000003
a0ae0000
246f0057
a0af0000
0443fff6
00441806
03e00008
00000000
27bdffd8
afbf0024
afb30020
afb2001c
afb10018
afb00014
24100003
241303e9
24120020
3411ffff
2a010004
14200012
24020003
0202001a
14400002
00000000
0007000d
2401ffff
14410004
3c018000
16010002
00000000
0006000d
00007010
51c00005
00001025
24420002
0050082a
1420fff0
00000000
50400007
26100002
02002025
2405000a
0411ffaf
00003025
a2320000
26100002
5613ffe4
2a010004
240f000a
a22f0000
8fbf0024
8fb30020
8fb2001c
8fb10018
8fb00014
00001025
03e00008
27bd0028
27bdff40
afbf0034
afb70030
afb6002c
afb50028
afb40024
afb30020
afb2001c
afb10018
afb00014
3c121234
36525678
00008025
24150020
3414ffff
24110020
0411ffad
02122007
26100001
1611fffc
a2950000
2417000a
3c139234
a2970000
36735678
00008025
0411ffa3
02132007
26100001
1611fffc
a2950000
a2970000
00008025
0411ff9c
02122004
26100001
1611fffc
a2950000
a2970000
a2970000
00008825
2410004d
02202025
2405000a
0411ff73
00003025
26310007
1630fffa
a2950000
3c11038f
3c10038f
a2970000
36106dab
36315ae5
0411ff87
02202025
26310321
1630fffc
a2950000
3c1105fb
3c10061a
a2970000
3610e149
36314e83
0411ff7d
02202025
3c010005
34214321
02218821
1630fffa
a2950000
3c110001
a2970000
36312345
24100001
2416000a
0230001a
16000002
00000000
0007000d
2401ffff
16010004
3c018000
16210002
00000000
0006000d
00002012
0411ff66
00000000
26100001
1616fff1
a2950000
a2970000
24100001
0230001a
16000002
00000000
0007000d
2401ffff
16010004
3c018000
16210002
00000000
0006000d
00002010
0411ff54
00000000
26100001
1616fff1
a2950000
a2970000
a2970000
00008025
0411ff4c
26041234
26100001
1616fffc
a2950000
a2970000
00008025
24111234
0411ff44
02302023
26100001
1616fffc
a2950000
a2970000
a2970000
0411ff3d
24040220
a2950000
0411ff3a
24045335
a2950000
0411ff37
24045115
a2950000
0411ff34
2404edcb
a2950000
0411ff31
24041246
a2950000
0411ff2e
24041222
a2970000
a2970000
240e0001
240f0001
24180001
afb8004c
a7af008a
a3ae00a9
afa00048
a7a00088
a3a000a8
24100002
27b200aa
27b3008c
27b10050
26020001
26030002
26040003
a2500000
a6700000
ae300000
26100004
a2440003
a6640006
ae24000c
a2430002
a6630004
ae230008
a2420001
a6620002
ae220004
26520004
26730008
1616ffed
26310010
27b200a8
27b30088
27b10048
27b60070
82440000
2405000a
0411fee5
00003025
a2950000
86640000
2405000a
0411fee0
00003025
a2950000
8e240000
2405000a
0411fedb
00003025
26310004
a2970000
26520001
1636ffee
26730002
0411ff02
a2970000
24190064
a2990000
2408006f
a2880000
2409006e
a2890000
240a0065
a28a0000
a2970000
8fbf0034
8fb70030
8fb6002c
8fb50028
8fb40024
8fb30020
8fb2001c
8fb10018
8fb00014
03e00008
27bd00c0
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00001000
0000101c
00000000
00000000
00001008
00001060
000011b8
00000000
00000000
00001080
000011b8
00001230
00000000
00000000
000011cc
00001270
00001338
00000000
00000000
00001288
00001338
000016bc
00000000
00000000
00001360
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
00000000
/reg_bank.vhd
0,0 → 1,169
---------------------------------------------------------------------
-- TITLE: Register Bank
-- AUTHOR: Steve Rhoads (rhoadss@yahoo.com)
-- DATE CREATED: 2/2/01
-- FILENAME: reg_bank.vhd
-- PROJECT: MIPS CPU core
-- COPYRIGHT: Software placed into the public domain by the author.
-- Software 'as is' without warranty. Author liable for nothing.
-- DESCRIPTION:
-- Implements a register bank with 32 registers that are 32-bits wide.
-- There are two read-ports and one write port.
---------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use work.mips_pack.all;
 
entity reg_bank is
port(clk : in std_logic;
rs_index : in std_logic_vector(5 downto 0);
rt_index : in std_logic_vector(5 downto 0);
rd_index : in std_logic_vector(5 downto 0);
reg_source_out : out std_logic_vector(31 downto 0);
reg_target_out : out std_logic_vector(31 downto 0);
reg_dest_new : in std_logic_vector(31 downto 0);
intr_enable : out std_logic);
end; --entity reg_bank
 
architecture logic of reg_bank is
signal reg31, reg01, reg02, reg03 : std_logic_vector(31 downto 0);
--For Altera simulations, comment out reg04 through reg30
signal reg04, reg05, reg06, reg07 : std_logic_vector(31 downto 0);
signal reg08, reg09, reg10, reg11 : std_logic_vector(31 downto 0);
signal reg12, reg13, reg14, reg15 : std_logic_vector(31 downto 0);
signal reg16, reg17, reg18, reg19 : std_logic_vector(31 downto 0);
signal reg20, reg21, reg22, reg23 : std_logic_vector(31 downto 0);
signal reg24, reg25, reg26, reg27 : std_logic_vector(31 downto 0);
signal reg28, reg29, reg30 : std_logic_vector(31 downto 0);
signal reg_epc : std_logic_vector(31 downto 0);
signal reg_status : std_logic;
begin
 
reg_proc: process(clk, rs_index, rt_index, rd_index, reg_dest_new,
reg31, reg01, reg02, reg03, reg04, reg05, reg06, reg07,
reg08, reg09, reg10, reg11, reg12, reg13, reg14, reg15,
reg16, reg17, reg18, reg19, reg20, reg21, reg22, reg23,
reg24, reg25, reg26, reg27, reg28, reg29, reg30,
reg_epc, reg_status)
begin
case rs_index is
when "000000" => reg_source_out <= ZERO;
when "000001" => reg_source_out <= reg01;
when "000010" => reg_source_out <= reg02;
when "000011" => reg_source_out <= reg03;
when "000100" => reg_source_out <= reg04;
when "000101" => reg_source_out <= reg05;
when "000110" => reg_source_out <= reg06;
when "000111" => reg_source_out <= reg07;
when "001000" => reg_source_out <= reg08;
when "001001" => reg_source_out <= reg09;
when "001010" => reg_source_out <= reg10;
when "001011" => reg_source_out <= reg11;
when "001100" => reg_source_out <= reg12;
when "001101" => reg_source_out <= reg13;
when "001110" => reg_source_out <= reg14;
when "001111" => reg_source_out <= reg15;
when "010000" => reg_source_out <= reg16;
when "010001" => reg_source_out <= reg17;
when "010010" => reg_source_out <= reg18;
when "010011" => reg_source_out <= reg19;
when "010100" => reg_source_out <= reg20;
when "010101" => reg_source_out <= reg21;
when "010110" => reg_source_out <= reg22;
when "010111" => reg_source_out <= reg23;
when "011000" => reg_source_out <= reg24;
when "011001" => reg_source_out <= reg25;
when "011010" => reg_source_out <= reg26;
when "011011" => reg_source_out <= reg27;
when "011100" => reg_source_out <= reg28;
when "011101" => reg_source_out <= reg29;
when "011110" => reg_source_out <= reg30;
when "011111" => reg_source_out <= reg31;
when "101100" => reg_source_out <= ZERO(31 downto 1) & reg_status;
when "101110" => reg_source_out <= reg_epc; --CP0 14
when "111111" => reg_source_out <= '1' & ZERO(30 downto 0); --intr vector
when others => reg_source_out <= ZERO;
end case;
 
case rt_index is
when "000000" => reg_target_out <= ZERO;
when "000001" => reg_target_out <= reg01;
when "000010" => reg_target_out <= reg02;
when "000011" => reg_target_out <= reg03;
when "000100" => reg_target_out <= reg04;
when "000101" => reg_target_out <= reg05;
when "000110" => reg_target_out <= reg06;
when "000111" => reg_target_out <= reg07;
when "001000" => reg_target_out <= reg08;
when "001001" => reg_target_out <= reg09;
when "001010" => reg_target_out <= reg10;
when "001011" => reg_target_out <= reg11;
when "001100" => reg_target_out <= reg12;
when "001101" => reg_target_out <= reg13;
when "001110" => reg_target_out <= reg14;
when "001111" => reg_target_out <= reg15;
when "010000" => reg_target_out <= reg16;
when "010001" => reg_target_out <= reg17;
when "010010" => reg_target_out <= reg18;
when "010011" => reg_target_out <= reg19;
when "010100" => reg_target_out <= reg20;
when "010101" => reg_target_out <= reg21;
when "010110" => reg_target_out <= reg22;
when "010111" => reg_target_out <= reg23;
when "011000" => reg_target_out <= reg24;
when "011001" => reg_target_out <= reg25;
when "011010" => reg_target_out <= reg26;
when "011011" => reg_target_out <= reg27;
when "011100" => reg_target_out <= reg28;
when "011101" => reg_target_out <= reg29;
when "011110" => reg_target_out <= reg30;
when "011111" => reg_target_out <= reg31;
when others => reg_target_out <= ZERO;
end case;
 
if rising_edge(clk) then
-- assert reg_dest_new'last_event >= 10 ns
-- report "Reg_dest timing error";
case rd_index is
when "000001" => reg01 <= reg_dest_new;
when "000010" => reg02 <= reg_dest_new;
when "000011" => reg03 <= reg_dest_new;
when "000100" => reg04 <= reg_dest_new;
when "000101" => reg05 <= reg_dest_new;
when "000110" => reg06 <= reg_dest_new;
when "000111" => reg07 <= reg_dest_new;
when "001000" => reg08 <= reg_dest_new;
when "001001" => reg09 <= reg_dest_new;
when "001010" => reg10 <= reg_dest_new;
when "001011" => reg11 <= reg_dest_new;
when "001100" => reg12 <= reg_dest_new;
when "001101" => reg13 <= reg_dest_new;
when "001110" => reg14 <= reg_dest_new;
when "001111" => reg15 <= reg_dest_new;
when "010000" => reg16 <= reg_dest_new;
when "010001" => reg17 <= reg_dest_new;
when "010010" => reg18 <= reg_dest_new;
when "010011" => reg19 <= reg_dest_new;
when "010100" => reg20 <= reg_dest_new;
when "010101" => reg21 <= reg_dest_new;
when "010110" => reg22 <= reg_dest_new;
when "010111" => reg23 <= reg_dest_new;
when "011000" => reg24 <= reg_dest_new;
when "011001" => reg25 <= reg_dest_new;
when "011010" => reg26 <= reg_dest_new;
when "011011" => reg27 <= reg_dest_new;
when "011100" => reg28 <= reg_dest_new;
when "011101" => reg29 <= reg_dest_new;
when "011110" => reg30 <= reg_dest_new;
when "011111" => reg31 <= reg_dest_new;
when "101100" => reg_status <= reg_dest_new(0);
when "101110" => reg_epc <= reg_dest_new; --CP0 14
reg_status <= '0'; --disable interrupts
when others =>
end case;
end if;
intr_enable <= reg_status;
end process;
 
end; --architecture logic
 
/makefile
0,0 → 1,52
VHD = mips_pack alu bus_mux control mem_ctrl mult pc_next reg_bank shifter \
mips_cpu
 
all: work/tbench/_primary.dat
 
work/mips_pack/_primary.dat: mips_pack.vhd
vcom -check_synthesis mips_pack.vhd
 
work/alu/_primary.dat: mips_pack.vhd alu.vhd
vcom -check_synthesis alu.vhd
 
work/bus_mux/_primary.dat: mips_pack.vhd bus_mux.vhd
vcom -check_synthesis bus_mux.vhd
 
work/control/_primary.dat: mips_pack.vhd control.vhd
vcom -check_synthesis control.vhd
 
work/mem_ctrl/_primary.dat: mips_pack.vhd mem_ctrl.vhd
vcom -check_synthesis mem_ctrl.vhd
 
work/mult/_primary.dat: mips_pack.vhd mult.vhd
vcom -check_synthesis mult.vhd
 
work/pc_next/_primary.dat: mips_pack.vhd pc_next.vhd
vcom -check_synthesis pc_next.vhd
 
work/reg_bank/_primary.dat: mips_pack.vhd reg_bank.vhd
vcom -check_synthesis reg_bank.vhd
 
work/shifter/_primary.dat: mips_pack.vhd shifter.vhd
vcom -check_synthesis shifter.vhd
 
work/mips_cpu/_primary.dat: mips_cpu.vhd \
work/mips_pack/_primary.dat \
work/alu/_primary.dat \
work/bus_mux/_primary.dat \
work/control/_primary.dat \
work/mem_ctrl/_primary.dat \
work/mult/_primary.dat \
work/pc_next/_primary.dat \
work/reg_bank/_primary.dat \
work/shifter/_primary.dat
vcom -check_synthesis mips_cpu.vhd
 
work/ram/_primary.dat: ram.vhd
vcom -explicit ram.vhd
 
work/tbench/_primary.dat: tbench.vhd \
work/mips_cpu/_primary.dat \
work/ram/_primary.dat
vcom tbench.vhd
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.