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

Subversion Repositories plasma

[/] [plasma/] [tags/] [V3_0/] [vhdl/] [mlite_cpu.vhd] - Diff between revs 73 and 83

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 73 Rev 83
Line 8... Line 8...
--    Software 'as is' without warranty.  Author liable for nothing.
--    Software 'as is' without warranty.  Author liable for nothing.
-- NOTE:  MIPS(tm) and MIPS I(tm) are registered trademarks of MIPS 
-- NOTE:  MIPS(tm) and MIPS I(tm) are registered trademarks of MIPS 
--    Technologies.  MIPS Technologies does not endorse and is not 
--    Technologies.  MIPS Technologies does not endorse and is not 
--    associated with this project.
--    associated with this project.
-- DESCRIPTION:
-- DESCRIPTION:
-- Top level VHDL document that ties the eight other entities together.
--    Top level VHDL document that ties the nine other entities together.
-- Executes most MIPS I(tm) opcodes.  Based on information found in:
--
 
-- Executes all MIPS I(tm) opcodes but exceptions and non-aligned
 
-- memory accesses.  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
 
--
 
-- The CPU is implemented as a two or three stage pipeline.
-- An add instruction would take the following steps (see cpu.gif):
-- An add instruction would take the following steps (see cpu.gif):
--    1.  The "pc_next" entity would have previously passed the program
-- Stage #1:
--        counter (PC) to the "mem_ctrl" entity.
--    1.  The "pc_next" entity passes the program counter (PC) to the 
 
--        "mem_ctrl" entity which fetches the opcode from memory.
 
-- Stage #2:
--    2.  "Mem_ctrl" passes the opcode to the "control" entity.
--    2.  "Mem_ctrl" passes the opcode to the "control" entity.
--    3.  "Control" converts the 32-bit opcode to a 60-bit VLWI opcode
--    3.  "Control" converts the 32-bit opcode to a 60-bit VLWI opcode
--        and sends control signals to the other entities.
--        and sends control signals to the other entities.
--    4.  Based on the rs_index and rt_index control signals, "reg_bank" 
--    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".
--        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"
--    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.
--        multiplexes reg_source onto a_bus and reg_target onto b_bus.
 
-- Stage #3:
--    6.  Based on the alu_func control signals, "alu" adds the values
--    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.
--        from a_bus and b_bus and places the result on c_bus.
--    7.  Based on the c_source control signals, "bus_bux" multiplexes
--    7.  Based on the c_source control signals, "bus_bux" multiplexes
--        c_bus onto reg_dest.
--        c_bus onto reg_dest.
--    8.  Based on the rd_index control signal, "reg_bank" saves
--    8.  Based on the rd_index control signal, "reg_bank" saves
--        reg_dest into the correct register.
--        reg_dest into the correct register.
-- The CPU is implemented as a two/three stage pipeline with step #1 in 
 
-- the first stage and steps #2-#8 occuring the second stage.  When 
 
-- operating with a three stage pipeline, steps #6-#8 occur in the 
 
-- third stage.
 
--
--
-- Writing to high memory where a(31)='1' takes four cycles to meet RAM 
-- All signals are active high.  Writing to high memory where a(31)='1' 
-- address hold times.
-- takes five cycles to meet RAM address hold times.
-- Addresses with a(31)='0' are assumed to be clocked and take two cycles.
-- Addresses with a(31)='0' are assumed to be clocked and take three cycles.
-- Here are the signals for writing a character to address 0xffff:
-- Here are the signals for writing a character to address 0xffff:
--
--
--      mem_write                           
--      intr_in                        mem_pause    
--    interrupt                     mem_byte_sel
--   reset_in                        mem_write      
--      reset                        mem_pause  
--      clk                     mem_byte_sel        
--       ns    mem_address m_data_w m_data_r    
--     ns    mem_address m_data_r m_data_w 
--   ===========================================
-- =============================================
--     6700 0 0 0 000002A4 ZZZZZZZZ A0AE0000 0 0  (  fetch write opcode)
--   3000 1 0 0 0000002C A2820000 ZZZZZZZZ 0 0 0  (0 fetch write opcode)
--     6800 0 0 0 000002B0 ZZZZZZZZ 0443FFF6 0 0  (1 fetch NEXT opcode)
--   3050 0 0 0 0000002C A2820000 ZZZZZZZZ 0 0 0
--     6900 0 0 1 0000FFFF 31313131 ZZZZZZZZ 0 1  (2 write the low byte)
--   3100 1 0 0 00000030 340A0041 ZZZZZZZZ 0 0 0  (1 execute write opcode)
--     7000 0 0 0 000002B4 ZZZZZZZZ 00441806 0 0  (  execute NEXT opcode)
--   3150 0 0 0 00000030 340A0041 ZZZZZZZZ 0 0 0
 
--   3200 1 0 0 00000030 340A0041 ZZZZZZZZ 0 0 0  (2 calculating address)
 
--   3250 0 0 0 00000030 340A0041 ZZZZZZZZ 0 0 0
 
--   3300 1 0 0 0000FFFF ZZZZZZZZ 6A6A6A6A 1 1 0  (3 writing value)
 
--   3350 0 0 0 0000FFFF ZZZZZZZZ 6A6A6A6A 1 1 0
 
--   3400 1 0 0 00000034 340B0042 ZZZZZZZZ 0 0 0
 
--   3450 0 0 0 00000034 340B0042 ZZZZZZZZ 0 0 0
 
--
 
-- Program:
 
-- addr     value  opcode   args
 
-- ===================================
 
-- 002c  a2820000      sb   $v0,0($s4)
 
-- 0030  340a0041      li   $t2,0x41
 
-- 0034  340b0042      li   $t3,0x42
---------------------------------------------------------------------
---------------------------------------------------------------------
library ieee;
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_unsigned.all;
use work.mlite_pack.all;
use work.mlite_pack.all;
 
 
entity mlite_cpu is
entity mlite_cpu is
   generic(memory_type     : string  := "ALTERA";
   generic(memory_type     : string  := "ALTERA";
           pipeline_stages : natural := 3;
           pipeline_stages : natural := 3;
           accurate_timing : boolean := false);
           accurate_timing : boolean := true);
   port(clk         : in std_logic;
   port(clk         : in std_logic;
        reset_in    : in std_logic;
        reset_in    : in std_logic;
        intr_in     : in std_logic;
        intr_in     : in std_logic;
 
 
        mem_address : out std_logic_vector(31 downto 0);
        mem_address : out std_logic_vector(31 downto 0);
Line 124... Line 140...
begin  --architecture
begin  --architecture
 
 
   pause_any <= (mem_pause or pause_ctrl) or (pause_mult or pause_pipeline);
   pause_any <= (mem_pause or pause_ctrl) or (pause_mult or pause_pipeline);
   pause_non_ctrl <= (mem_pause or pause_mult) or pause_pipeline;
   pause_non_ctrl <= (mem_pause or pause_mult) or pause_pipeline;
   pause_bank <= (mem_pause or pause_ctrl or pause_mult) and not pause_pipeline;
   pause_bank <= (mem_pause or pause_ctrl or pause_mult) and not pause_pipeline;
   nullify_op <= '1' when pc_source = from_lbranch and
   nullify_op <= '1' when pc_source = from_lbranch and take_branchD = '0' else
                     (take_branchD = '0' or branch_func = branch_yes) else
 
                 '0';
                 '0';
   c_bus <= c_alu or c_shift or c_mult;
   c_bus <= c_alu or c_shift or c_mult;
   reset <= '1' when reset_in = '1' or reset_reg /= "1111" else '0';
   reset <= '1' when reset_in = '1' or reset_reg /= "1111" else '0';
 
 
   --synchronize reset and interrupt pins
   --synchronize reset and interrupt pins
   intr_proc: process(clk, reset_in, intr_in, intr_enable, pc_source, pc, pause_any)
   intr_proc: process(clk, reset_in, reset_reg, intr_in, intr_enable,
 
      pc_source, pc, pause_any)
   begin
   begin
      if reset_in = '1' then
      if reset_in = '1' then
         reset_reg <= "0000";
         reset_reg <= "0000";
      elsif rising_edge(clk) then
      elsif rising_edge(clk) then
         if reset_reg /= "1111" then
         if reset_reg /= "1111" then

powered by: WebSVN 2.1.0

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