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

Subversion Repositories plasma

[/] [plasma/] [trunk/] [vhdl/] [mlite_cpu.vhd] - Diff between revs 132 and 139

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

Rev 132 Rev 139
Line 15... Line 15...
-- Executes all MIPS I(tm) opcodes but exceptions and non-aligned
-- Executes all MIPS I(tm) opcodes but exceptions and non-aligned
-- memory accesses.  Based on information found in:
-- 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.
-- The CPU is implemented as a three or four stage pipeline.
-- An add instruction would take the following steps (see cpu.gif):
-- An add instruction would take the following steps (see cpu.gif):
-- Stage #1:
-- Stage #1:
--    1.  The "pc_next" entity passes the program counter (PC) to the 
--    1.  The "pc_next" entity passes the program counter (PC) to the 
--        "mem_ctrl" entity which fetches the opcode from memory.
--        "mem_ctrl" entity which fetches the opcode from memory.
-- Stage #2:
-- Stage #2:
--    2.  "Mem_ctrl" passes the opcode to the "control" entity.
--    2.  The memory returns the opcode.
--    3.  "Control" converts the 32-bit opcode to a 60-bit VLWI opcode
-- Stage #3:
 
--    3.  "Mem_ctrl" passes the opcode to the "control" entity.
 
--    4.  "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" 
--    5.  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"
--    6.  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:
-- Stage #4 (part of stage #3 if using three stage pipeline):
--    6.  Based on the alu_func control signals, "alu" adds the values
--    7.  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
--    8.  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
--    9.  Based on the rd_index control signal, "reg_bank" saves
--        reg_dest into the correct register.
--        reg_dest into the correct register.
 
-- Stage #4b:
 
--   10.  Read or write memory if needed.
--
--
-- All signals are active high.  Writing to high memory where a(31)='1' 
-- All signals are active high. 
-- takes five cycles to meet RAM address hold times.
-- Here are the signals for writing a character to address 0xffff
-- Addresses with a(31)='0' are assumed to be clocked and take three cycles.
-- when using a three stage pipeline:
-- Here are the signals for writing a character to address 0xffff:
 
--
 
--      intr_in                        mem_pause    
 
--   reset_in                        mem_write      
 
--      clk                     mem_byte_sel        
 
--     ns    mem_address m_data_r m_data_w 
 
-- =============================================
 
--   3000 1 0 0 0000002C A2820000 ZZZZZZZZ 0 0 0  (0 fetch write opcode)
 
--   3050 0 0 0 0000002C A2820000 ZZZZZZZZ 0 0 0
 
--   3100 1 0 0 00000030 340A0041 ZZZZZZZZ 0 0 0  (1 execute write 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:
-- Program:
-- addr     value  opcode   args
-- addr     value  opcode 
-- ===================================
-- =============================
-- 002c  a2820000      sb   $v0,0($s4)
--   3c: 00000000  nop
-- 0030  340a0041      li   $t2,0x41
--   40: 34040041  li $a0,0x41
-- 0034  340b0042      li   $t3,0x42
--   44: 3405ffff  li $a1,0xffff
 
--   48: a0a40000  sb $a0,0($a1)
 
--   4c: 00000000  nop
 
--   50: 00000000  nop
 
--
 
--      intr_in                             mem_pause 
 
--  reset_in                           mem_byte_we     Stages
 
--     ns     mem_address mem_data_w mem_data_r        40 44 48 4c 50
 
--   3500  0  0  00000040   00000000   00000000  0  0   1
 
--   3600  0  0  00000044   00000000   34040041  0  0   2  1
 
--   3700  0  0  00000048   00000000   3405FFFF  0  0   3  2  1 
 
--   3800  0  0  0000004C   00000000   A0A40000  0  0      3  2  1
 
--   3900  0  0  0000FFFC   41414141   00000000  1  0         3  2
 
--   4000  0  0  00000050   41414141   XXXXXX41  0  0         4b 3  1
 
--   4100  0  0  00000054   00000000   00000000  0  0               2
---------------------------------------------------------------------
---------------------------------------------------------------------
library ieee;
library ieee;
use work.mlite_pack.all;
use work.mlite_pack.all;
--library ieee, mlite_lib;
 
--use mlite_lib.mlite_pack.all;
 
use ieee.std_logic_1164.all;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_unsigned.all;
 
 
entity mlite_cpu is
entity mlite_cpu is
   generic(memory_type     : string  := "DEFAULT"; --DUAL_PORT_XILINX_XC4000XLA
   generic(memory_type     : string  := "XILINX_16X"; --ALTERA_LPM, or DUAL_PORT_
           adder_type      : string  := "DEFAULT"; --AREA_OPTIMIZED
 
           mult_type       : string  := "DEFAULT"; --AREA_OPTIMIZED
           mult_type       : string  := "DEFAULT"; --AREA_OPTIMIZED
           shifter_type    : string  := "DEFAULT"; --AREA_OPTIMIZED
           shifter_type    : string  := "DEFAULT"; --AREA_OPTIMIZED
           alu_type        : string  := "DEFAULT"; --AREA_OPTIMIZED
           alu_type        : string  := "DEFAULT"; --AREA_OPTIMIZED
           pipeline_stages : natural := 3;
           pipeline_stages : natural := 3); --3 or 4
           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);
        mem_data_w  : 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_data_r  : in std_logic_vector(31 downto 0);
        mem_byte_sel: out std_logic_vector(3 downto 0);
        mem_byte_we : out std_logic_vector(3 downto 0);
        mem_write   : out std_logic;
 
        mem_pause   : in std_logic);
        mem_pause   : in std_logic);
end; --entity mlite_cpu
end; --entity mlite_cpu
 
 
architecture logic of mlite_cpu is
architecture logic of mlite_cpu is
   --When using a two stage pipeline "sigD <= sig".
   --When using a three stage pipeline "sigD <= sig".
   --When using a three stage pipeline "sigD <= sig when rising_edge(clk)",
   --When using a four stage pipeline "sigD <= sig when rising_edge(clk)",
   --  so sigD is delayed by one clock cycle.
   --  so sigD is delayed by one clock cycle.
   signal opcode         : std_logic_vector(31 downto 0);
   signal opcode         : std_logic_vector(31 downto 0);
   signal rs_index       : std_logic_vector(5 downto 0);
   signal rs_index       : std_logic_vector(5 downto 0);
   signal rt_index       : std_logic_vector(5 downto 0);
   signal rt_index       : std_logic_vector(5 downto 0);
   signal rd_index       : std_logic_vector(5 downto 0);
   signal rd_index       : std_logic_vector(5 downto 0);
Line 114... Line 110...
   signal c_alu          : std_logic_vector(31 downto 0);
   signal c_alu          : std_logic_vector(31 downto 0);
   signal c_shift        : std_logic_vector(31 downto 0);
   signal c_shift        : std_logic_vector(31 downto 0);
   signal c_mult         : std_logic_vector(31 downto 0);
   signal c_mult         : std_logic_vector(31 downto 0);
   signal c_memory       : std_logic_vector(31 downto 0);
   signal c_memory       : std_logic_vector(31 downto 0);
   signal imm            : std_logic_vector(15 downto 0);
   signal imm            : std_logic_vector(15 downto 0);
   signal pc             : std_logic_vector(31 downto 0);
   signal pc_future      : std_logic_vector(31 downto 2);
   signal pc_plus4       : std_logic_vector(31 downto 0);
   signal pc_current     : std_logic_vector(31 downto 2);
 
   signal pc_plus4       : std_logic_vector(31 downto 2);
   signal alu_func       : alu_function_type;
   signal alu_func       : alu_function_type;
   signal alu_funcD      : alu_function_type;
   signal alu_funcD      : alu_function_type;
   signal shift_func     : shift_function_type;
   signal shift_func     : shift_function_type;
   signal shift_funcD    : shift_function_type;
   signal shift_funcD    : shift_function_type;
   signal mult_func      : mult_function_type;
   signal mult_func      : mult_function_type;
Line 150... Line 147...
   nullify_op <= '1' when (pc_source = FROM_LBRANCH and take_branch = '0')
   nullify_op <= '1' when (pc_source = FROM_LBRANCH and take_branch = '0')
                          or intr_signal = '1'
                          or intr_signal = '1'
                          else '0';
                          else '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';
 
   mem_address(1 downto 0) <= "00";
 
 
   --synchronize reset and interrupt pins
   --synchronize reset and interrupt pins
   intr_proc: process(clk, reset_in, reset_reg, intr_in, intr_enable,
   intr_proc: process(clk, reset_in, reset_reg, intr_in, intr_enable,
      pc_source, pc, pause_any)
      pc_source, pc_current, pause_any)
   begin
   begin
      if reset_in = '1' then
      if reset_in = '1' then
         reset_reg <= "0000";
         reset_reg <= "0000";
         intr_signal <= '0';
         intr_signal <= '0';
      elsif rising_edge(clk) then
      elsif rising_edge(clk) then
Line 166... Line 164...
         end if;
         end if;
 
 
         --don't try to interrupt a multi-cycle instruction
         --don't try to interrupt a multi-cycle instruction
         if pause_any = '0' then
         if pause_any = '0' then
            if intr_in = '1' and intr_enable = '1' and
            if intr_in = '1' and intr_enable = '1' and
                  pc_source = from_inc4 and pc(2) = '0' then
                  pc_source = FROM_INC4 then
               --the epc will be backed up one opcode (pc-4)
               --the epc will contain pc+4
               intr_signal <= '1';
               intr_signal <= '1';
            else
            else
               intr_signal <= '0';
               intr_signal <= '0';
            end if;
            end if;
         end if;
         end if;
Line 185... Line 183...
        take_branch  => take_branch,
        take_branch  => take_branch,
        pause_in     => pause_any,
        pause_in     => pause_any,
        pc_new       => c_bus(31 downto 2),
        pc_new       => c_bus(31 downto 2),
        opcode25_0   => opcode(25 downto 0),
        opcode25_0   => opcode(25 downto 0),
        pc_source    => pc_source,
        pc_source    => pc_source,
        pc_out       => pc,
        pc_future    => pc_future,
        pc_out_plus4 => pc_plus4);
        pc_current   => pc_current,
 
        pc_plus4     => pc_plus4);
 
 
   u2_mem_ctrl: mem_ctrl
   u2_mem_ctrl: mem_ctrl
      generic map (ACCURATE_TIMING => accurate_timing)
 
      PORT MAP (
      PORT MAP (
        clk          => clk,
        clk          => clk,
        reset_in     => reset,
        reset_in     => reset,
        pause_in     => pause_non_ctrl,
        pause_in     => pause_non_ctrl,
        nullify_op   => nullify_op,
        nullify_op   => nullify_op,
        address_pc   => pc,
        address_pc   => pc_future,
        opcode_out   => opcode,
        opcode_out   => opcode,
 
 
        address_data => c_bus,
        address_in   => c_bus,
        mem_source   => mem_source,
        mem_source   => mem_source,
        data_write   => reg_target,
        data_write   => reg_target,
        data_read    => c_memory,
        data_read    => c_memory,
        pause_out    => pause_ctrl,
        pause_out    => pause_ctrl,
 
 
        mem_address  => mem_address,
        mem_address  => mem_address(31 downto 2),
        mem_data_w   => mem_data_w,
        mem_data_w   => mem_data_w,
        mem_data_r   => mem_data_r,
        mem_data_r   => mem_data_r,
        mem_byte_sel => mem_byte_sel,
        mem_byte_we  => mem_byte_we);
        mem_write    => mem_write);
 
 
 
   u3_control: control PORT MAP (
   u3_control: control PORT MAP (
        opcode       => opcode,
        opcode       => opcode,
        intr_signal  => intr_signal,
        intr_signal  => intr_signal,
        rs_index     => rs_index,
        rs_index     => rs_index,
Line 253... Line 250...
        b_mux        => b_source,
        b_mux        => b_source,
        b_out        => b_bus,
        b_out        => b_bus,
 
 
        c_bus        => c_bus,
        c_bus        => c_bus,
        c_memory     => c_memory,
        c_memory     => c_memory,
        c_pc         => pc,
        c_pc         => pc_current,
        c_pc_plus4   => pc_plus4,
        c_pc_plus4   => pc_plus4,
        c_mux        => c_source,
        c_mux        => c_source,
        reg_dest_out => reg_dest,
        reg_dest_out => reg_dest,
 
 
        branch_func  => branch_func,
        branch_func  => branch_func,
        take_branch  => take_branch);
        take_branch  => take_branch);
 
 
   u6_alu: alu
   u6_alu: alu
      generic map (adder_type => adder_type,
      generic map (alu_type => alu_type)
                   alu_type   => alu_type)
 
      port map (
      port map (
        a_in         => a_busD,
        a_in         => a_busD,
        b_in         => b_busD,
        b_in         => b_busD,
        alu_function => alu_funcD,
        alu_function => alu_funcD,
        c_alu        => c_alu);
        c_alu        => c_alu);
Line 279... Line 275...
        shift_amount => a_busD(4 downto 0),
        shift_amount => a_busD(4 downto 0),
        shift_func   => shift_funcD,
        shift_func   => shift_funcD,
        c_shift      => c_shift);
        c_shift      => c_shift);
 
 
   u8_mult: mult
   u8_mult: mult
      generic map (adder_type => adder_type,
      generic map (mult_type => mult_type)
                   mult_type  => mult_type)
 
      port map (
      port map (
        clk       => clk,
        clk       => clk,
        reset_in  => reset,
        reset_in  => reset,
        a         => a_busD,
        a         => a_busD,
        b         => b_busD,
        b         => b_busD,
        mult_func => mult_funcD,
        mult_func => mult_funcD,
        c_mult    => c_mult,
        c_mult    => c_mult,
        pause_out => pause_mult);
        pause_out => pause_mult);
 
 
   pipeline2: if pipeline_stages <= 2 generate
   pipeline3: if pipeline_stages <= 3 generate
      a_busD <= a_bus;
      a_busD <= a_bus;
      b_busD <= b_bus;
      b_busD <= b_bus;
      alu_funcD <= alu_func;
      alu_funcD <= alu_func;
      shift_funcD <= shift_func;
      shift_funcD <= shift_func;
      mult_funcD <= mult_func;
      mult_funcD <= mult_func;
      rd_indexD <= rd_index;
      rd_indexD <= rd_index;
 
 
      reg_destD <= reg_dest;
      reg_destD <= reg_dest;
      pause_pipeline <= '0';
      pause_pipeline <= '0';
   end generate; --pipeline2
   end generate; --pipeline2
 
 
   pipeline3: if pipeline_stages >= 3 generate
   pipeline4: if pipeline_stages > 3 generate
      --When operating in three stage pipeline mode, the following signals
      --When operating in four stage pipeline mode, the following signals
      --are delayed by one clock cycle:  a_bus, b_bus, alu/shift/mult_func,
      --are delayed by one clock cycle:  a_bus, b_bus, alu/shift/mult_func,
      --c_source, and rd_index.
      --c_source, and rd_index.
   u9_pipeline: pipeline port map (
   u9_pipeline: pipeline port map (
        clk            => clk,
        clk            => clk,
        reset          => reset,
        reset          => reset,
Line 334... Line 328...
        b_source       => b_source,
        b_source       => b_source,
        c_source       => c_source,
        c_source       => c_source,
        c_bus          => c_bus,
        c_bus          => c_bus,
        pause_any      => pause_any,
        pause_any      => pause_any,
        pause_pipeline => pause_pipeline);
        pause_pipeline => pause_pipeline);
   end generate; --pipeline3
 
 
 
end; --architecture logic
   end generate; --pipeline4
 
 
 
end; --architecture logic
 
 
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

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