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

Subversion Repositories ion

[/] [ion/] [trunk/] [vhdl/] [mips_cpu.vhdl] - Diff between revs 35 and 46

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

Rev 35 Rev 46
Line 19... Line 19...
--  # RTE instruction (or ERET)
--  # RTE instruction (or ERET)
--  # Most of the CP0 registers and of course all of the CP1
--  # Most of the CP0 registers and of course all of the CP1
--  # External interrupts
--  # External interrupts
--
--
--### Things implemented but not tested
--### Things implemented but not tested
--  # Memory pause input
--  # Memory pause input -- not tested with a real cache
--
--
--### Things with provisional implementation
--### Things with provisional implementation
-- 
-- 
-- 1.- Load interlocks: the pipeline is stalled for every load instruction, even
-- 1.- Load interlocks: the pipeline is stalled for every load instruction, even
--     if the target register is not used in the following instruction. So that
--     if the target register is not used in the following instruction. So that
Line 180... Line 180...
 
 
signal load_interlock :     std_logic;
signal load_interlock :     std_logic;
signal stall_pipeline :     std_logic;
signal stall_pipeline :     std_logic;
-- pipeline is stalled for any reason
-- pipeline is stalled for any reason
signal pipeline_stalled :   std_logic;
signal pipeline_stalled :   std_logic;
 
 
 
signal stalled_memwait :    std_logic;
 
signal stalled_muldiv :     std_logic;
-- pipeline is stalled because of a load instruction interlock
-- pipeline is stalled because of a load instruction interlock
signal pipeline_interlocked:std_logic;
signal stalled_interlock :  std_logic;
 
 
 
 
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- CP0 registers and signals
-- CP0 registers and signals
 
 
-- CP0[12]: status register 
-- CP0[12]: status register 
Line 271... Line 275...
                        -- If target register is $zero, ignore write
                        -- If target register is $zero, ignore write
                        p1_rbank_wr_addr/="00000" and
                        p1_rbank_wr_addr/="00000" and
                        -- if the cache controller keeps the cpu stopped, do
                        -- if the cache controller keeps the cpu stopped, do
                        -- not writeback
                        -- not writeback
                        mem_wait='0' and
                        mem_wait='0' and
 
                        -- if stalled because of muldiv, block writeback
 
                        stalled_muldiv='0' and --@note1
                        -- on exception, abort next instruction (by preventing 
                        -- on exception, abort next instruction (by preventing 
                        -- regbank writeback).
                        -- regbank writeback).
                        p2_exception='0'
                        p2_exception='0'
                else '0';
                else '0';
 
 
Line 283... Line 289...
-- FPGA has 3-port BRAMS, or has none.
-- FPGA has 3-port BRAMS, or has none.
synchronous_reg_bank:
synchronous_reg_bank:
process(clk)
process(clk)
begin
begin
    if clk'event and clk='1' then
    if clk'event and clk='1' then
        if p1_rbank_we='1' and
        if p1_rbank_we='1' then
           (pipeline_stalled='0' or pipeline_interlocked='1') then -- @note1
 
            p1_rbank(conv_integer(p1_rbank_wr_addr)) <= p1_rbank_wr_data;
            p1_rbank(conv_integer(p1_rbank_wr_addr)) <= p1_rbank_wr_data;
        end if;
        end if;
 
        -- the rbank read port loads in the same conditions as the IR: don't
 
        -- update Rs or Rt if the pipeline is frozen
 
        if stall_pipeline='0' then
        p1_rt_rbank <= p1_rbank(conv_integer(p0_rt_num));
        p1_rt_rbank <= p1_rbank(conv_integer(p0_rt_num));
        p1_rs_rbank <= p1_rbank(conv_integer(p0_rs_num));
        p1_rs_rbank <= p1_rbank(conv_integer(p0_rs_num));
    end if;
    end if;
 
    end if;
end process synchronous_reg_bank;
end process synchronous_reg_bank;
 
 
-- Register writeback data in case it needs to be forwarded.
-- Register writeback data in case it needs to be forwarded.
data_forward_register:
data_forward_register:
process(clk)
process(clk)
Line 425... Line 434...
process(clk)
process(clk)
begin
begin
    if clk'event and clk='1' then
    if clk'event and clk='1' then
        if reset='1' then
        if reset='1' then
            -- reset to 0xffffffff so that 1st fetch addr is 0x00000000
            -- reset to 0xffffffff so that 1st fetch addr is 0x00000000
 
            -- FIXME reset vector is hardcoded
            p0_pc_reg <= (others => '1');
            p0_pc_reg <= (others => '1');
        else
        else
            -- p0_pc_reg holds the same value as external sync ram addr register
            -- p0_pc_reg holds the same value as external sync ram addr register
            p0_pc_reg <= p0_pc_next;
            p0_pc_reg <= p0_pc_next;
            -- p0_pc_restart = addr saved to EPC on interrupts (@note2)
            -- p0_pc_restart = addr saved to EPC on interrupts (@note2)
Line 808... Line 818...
 
 
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
 
 
-- FIXME stall when needed: mem pause, mdiv pause and load interlock
-- FIXME stall when needed: mem pause, mdiv pause and load interlock
 
 
 
 
 
-- FIXME make sure this combinational will not have bad glitches
 
stall_pipeline <= mem_wait or load_interlock or p1_muldiv_stall;
 
 
 
 
 
-- FIXME load interlock should happen only if the instruction following 
 
-- the load actually uses the load target register. Something like this:
 
-- (p1_do_load='1' and (p1_rd_num=p0_rs_num or p1_rd_num=p0_rt_num))
 
load_interlock <= '1' when
 
    p1_do_load='1' and      -- this is a load instruction
 
    pipeline_stalled='0' and -- not already stalled (i.e. assert for 1 cycle)
 
    (p1_rs1_hazard='1' or p1_rs2_hazard='1')
 
    else '0';
 
 
 
 
 
 
 
 
 
pipeline_stalled <= stalled_interlock or stalled_memwait or stalled_muldiv;
 
 
pipeline_stall_registers:
pipeline_stall_registers:
process(clk)
process(clk)
begin
begin
    if clk'event and clk='1' then
    if clk'event and clk='1' then
        if reset='1' then
        if reset='1' then
            pipeline_stalled <= '0';
            stalled_interlock <= '0';
            pipeline_interlocked <= '0';
            stalled_memwait <= '0';
 
            stalled_muldiv <= '0';
 
        else
 
            if mem_wait='1' then
 
                stalled_memwait <= '1';
        else
        else
            if stall_pipeline='1' then
                stalled_memwait <= '0';
                pipeline_stalled <= '1';
            end if;
 
 
 
            if p1_muldiv_stall='1' then
 
                stalled_muldiv <= '1';
            else
            else
                pipeline_stalled <= '0';
                stalled_muldiv <= '0';
            end if;
            end if;
 
 
            -- stalls caused by mem_wait and load_interlock are independent and
            -- stalls caused by mem_wait and load_interlock are independent and
            -- must not overlap; so when mem_wait='1' the cache stall takes
            -- must not overlap; so when mem_wait='1' the cache stall takes
            -- precedence and the loa interlock must wait.
            -- precedence and the loa interlock must wait.
            if mem_wait='0' then
            if mem_wait='0' then
                if load_interlock='1' then
                if load_interlock='1' then
                    pipeline_interlocked <= '1';
                    stalled_interlock <= '1';
                else
                else
                    pipeline_interlocked <= '0';
                    stalled_interlock <= '0';
                end if;
                end if;
            end if;
            end if;
        end if;
        end if;
    end if;
    end if;
end process pipeline_stall_registers;
end process pipeline_stall_registers;
 
 
-- FIXME make sure this combinational will not have bad glitches
 
stall_pipeline <= mem_wait or load_interlock or p1_muldiv_stall;
 
 
 
 
 
-- FIXME load interlock should happen only if the instruction following 
 
-- the load actually uses the load target register. Something like this:
 
-- (p1_do_load='1' and (p1_rd_num=p0_rs_num or p1_rd_num=p0_rt_num))
 
load_interlock <= '1' when
 
    p1_do_load='1' and      -- this is a load instruction
 
    pipeline_stalled='0' and -- not already stalled (i.e. assert for 1 cycle)
 
    (p1_rs1_hazard='1' or p1_rs2_hazard='1')
 
 
 
    else '0';
 
 
 
p1_rs1_hazard <= '1'; --'1' when p0_uses_rs1='1' and p1_rd_num=p0_rs_num else '0';
p1_rs1_hazard <= '1'; --'1' when p0_uses_rs1='1' and p1_rd_num=p0_rs_num else '0';
p1_rs2_hazard <= '1'; --'1' when p0_uses_rs2='1' and p1_rd_num=p0_rt_num else '0';
p1_rs2_hazard <= '1'; --'1' when p0_uses_rs2='1' and p1_rd_num=p0_rt_num else '0';
 
 
with p1_ir_op select p0_uses_rs1 <=
with p1_ir_op select p0_uses_rs1 <=
    '0' when "000010",
    '0' when "000010",
Line 974... Line 996...
-- Implementation notes
-- Implementation notes
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- @note1 : 
-- @note1 : 
--
--
-- This is the meaning of these two signals:
-- This is the meaning of these two signals:
-- pipeline_stalled & pipeline_interlocked =>
-- pipeline_stalled & stalled_interlock =>
--  "00" => normal state
--  "00" => normal state
--  "01" => normal state (makes for easier decoding)
--  "01" => normal state (makes for easier decoding)
--  "10" => all stages of pipeline stalled, including rbank
--  "10" => all stages of pipeline stalled, including rbank
--  "11" => all stages of pipeline stalled, except reg bank write port
--  "11" => all stages of pipeline stalled, except reg bank write port
-- 
-- 

powered by: WebSVN 2.1.0

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