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

Subversion Repositories ion

[/] [ion/] [trunk/] [vhdl/] [mips_cpu.vhdl] - Diff between revs 8 and 12

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

Rev 8 Rev 12
Line 120... Line 120...
signal p1_ac :              t_alu_control;
signal p1_ac :              t_alu_control;
-- ALU flag outputs (comparison results)
-- ALU flag outputs (comparison results)
signal p1_alu_flags :       t_alu_flags;
signal p1_alu_flags :       t_alu_flags;
-- immediate data, sign- or zero-extended as required by IR
-- immediate data, sign- or zero-extended as required by IR
signal p1_data_imm :        t_word;
signal p1_data_imm :        t_word;
signal p1_muldiv_result :   t_dword;
 
signal p1_branch_offset :   t_pc;
signal p1_branch_offset :   t_pc;
signal p1_branch_offset_sex:std_logic_vector(31 downto 18);
signal p1_branch_offset_sex:std_logic_vector(31 downto 18);
signal p1_rbank_rs_hazard : std_logic;
signal p1_rbank_rs_hazard : std_logic;
signal p1_rbank_rt_hazard : std_logic;
signal p1_rbank_rt_hazard : std_logic;
signal p1_jump_type_set0 :  std_logic_vector(1 downto 0);
signal p1_jump_type_set0 :  std_logic_vector(1 downto 0);
Line 157... Line 156...
signal p1_link :            std_logic;
signal p1_link :            std_logic;
signal p1_jump_cond_sel :   std_logic_vector(2 downto 0);
signal p1_jump_cond_sel :   std_logic_vector(2 downto 0);
signal p1_data_addr :       t_addr;
signal p1_data_addr :       t_addr;
signal p1_data_offset :     t_addr;
signal p1_data_offset :     t_addr;
 
 
 
signal p1_muldiv_result :   t_word;
 
signal p1_muldiv_func :     t_mult_function;
 
signal p1_muldiv_running :  std_logic;
 
signal p1_muldiv_started :  std_logic;
 
signal p1_muldiv_stall :    std_logic;
 
 
 
 
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Pipeline stage 2
-- Pipeline stage 2
 
 
 
signal p2_muldiv_started :  std_logic;
signal p2_exception :       std_logic;
signal p2_exception :       std_logic;
signal p2_rd_addr :         std_logic_vector(1 downto 0);
signal p2_rd_addr :         std_logic_vector(1 downto 0);
signal p2_rd_mux_control :  std_logic_vector(3 downto 0);
signal p2_rd_mux_control :  std_logic_vector(3 downto 0);
signal p2_load_target :     t_regnum;
signal p2_load_target :     t_regnum;
signal p2_do_load :         std_logic;
signal p2_do_load :         std_logic;
Line 182... Line 189...
-- pipeline is stalled for any reason
-- pipeline is stalled for any reason
signal pipeline_stalled :   std_logic;
signal pipeline_stalled :   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 pipeline_interlocked:std_logic;
 
 
 
 
--------------------------------------------------------------------------------
 
-- Multiplier interface registers
 
 
 
signal mdiv_hi_reg :        t_word;
 
signal mdiv_lo_reg :        t_word;
 
 
 
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- CP0 registers and signals
-- CP0 registers and signals
 
 
-- CP0[12]: status register 
-- CP0[12]: status register 
-- FIXME status flags unimplemented
-- FIXME status flags unimplemented
Line 325... Line 325...
 
 
p1_alu_inp1 <= p1_rs;
p1_alu_inp1 <= p1_rs;
 
 
with p1_alu_op2_sel select p1_alu_inp2 <=
with p1_alu_op2_sel select p1_alu_inp2 <=
    p1_data_imm                     when "11",
    p1_data_imm                     when "11",
    p1_muldiv_result(63 downto 32)  when "01",
    p1_muldiv_result    when "01", -- FIXME mux input wasted!
    p1_muldiv_result(31 downto  0)  when "10",
    p1_muldiv_result    when "10",
    p1_rt              when others;
    p1_rt              when others;
 
 
alu_inst : entity work.mips_alu
alu_inst : entity work.mips_alu
    port map (
    port map (
        clk             => clk,
        clk             => clk,
Line 345... Line 345...
 
 
 
 
--------------------------------------------------------------------------------
--------------------------------------------------------------------------------
-- Mul/Div block interface
-- Mul/Div block interface
 
 
-- FIXME when MUL*/DIV* are implemented, these registers and the load enable
-- Compute the mdiv block function word. If p1_muldiv_func has any value other
-- logic will change a little. It may be better to move them into the alu.
-- than MULT_NOTHING a new mdiv operation will start, truncating whatever other
mult_registers:
-- operation that may have been in course.
process(clk)
-- So we encode here the function to be performed and make sure the value stays
begin
-- there for only one cycle (the first ALU cycle of the mul/div instruction).
    if clk'event and clk='1' then
 
        -- MTHI, MTLO are never involved in stall cycles, no need to check
-- This will be '1' for all mul/div operations other than NOP...
        if p1_load_hi='1' then
p1_muldiv_func(3) <= '1' when p1_op_special='1' and
            mdiv_hi_reg <= p1_rs;
                              p1_ir_fn(5 downto 4)="01" and
        end if;
                              -- ...but only if the mdiv is not already running
        if p1_load_lo='1' then
                              p2_muldiv_started = '0' and
            mdiv_lo_reg <= p1_rs;
                              p1_muldiv_running ='0'
        end if;
                      else '0';
    end if;
 
end process mult_registers;
-- When bit(3) is zero, the rest are zeroed too. Otherwise, they come from IR
 
p1_muldiv_func(2 downto 0) <=
 
    p1_ir_fn(3) & p1_ir_fn(1 downto 0) when p1_muldiv_func(3)='1'
 
    else "000";
 
 
p1_muldiv_result <= mdiv_hi_reg & mdiv_lo_reg; -- FIXME stub, mdiv missing
mult_div: entity work.mips_mult
 
    port map (
 
        a           => p1_rs,
 
        b           => p1_rt,
 
        c_mult      => p1_muldiv_result,
 
        pause_out   => p1_muldiv_running,
 
        mult_func   => p1_muldiv_func,
 
        clk         => clk,
 
        reset_in    => reset
 
    );
 
 
 
-- Active only for the 1st ALU cycle of any mul/div instruction
 
p1_muldiv_started <= '1' when p1_op_special='1' and
 
                              p1_ir_fn(5 downto 3)="011" and
 
                              -- 
 
                              p1_muldiv_running='0'
 
                      else '0';
 
 
 
-- Stall the pipeline to enable mdiv operation completion.
 
-- We need p2_muldiv_started to distinguish the cycle before p1_muldiv_running
 
-- is asserted and the cycle after it deasserts.
 
-- Otherwise we would reexecute the same muldiv endlessly instruction after 
 
-- deassertion of p1_muldiv_running, since the IR was stalled and still contains 
 
-- the mul opcode...
 
p1_muldiv_stall <= '1' when
 
        -- Active for the cycle immediately before p1_muldiv_running asserts
 
        -- and NOT for the cycle after it deasserts
 
        (p1_muldiv_started='1' and p2_muldiv_started='0') or
 
        -- Active until operation is complete
 
        p1_muldiv_running = '1'
 
        else '0';
 
 
 
 
--##############################################################################
--##############################################################################
-- PC register and branch logic
-- PC register and branch logic
 
 
Line 634... Line 667...
            p1_rbank_rt_hazard <= p0_rbank_rt_hazard;
            p1_rbank_rt_hazard <= p0_rbank_rt_hazard;
        end if;
        end if;
    end if;
    end if;
end process pipeline_stage1_register;
end process pipeline_stage1_register;
 
 
 
pipeline_stage1_register2:
 
process(clk)
 
begin
 
    if clk'event and clk='1' then
 
        if reset='1' then
 
            p2_muldiv_started <= '0';
 
        else
 
            p2_muldiv_started <= p1_muldiv_running;
 
        end if;
 
    end if;
 
end process pipeline_stage1_register2;
 
 
 
 
-- Stage 2 pipeline register. Split in two for convenience.
-- Stage 2 pipeline register. Split in two for convenience.
-- This register deals with two kinds of stalls:
-- This register deals with two kinds of stalls:
-- * When the pipeline stalls because of a load interlock, this register is 
-- * When the pipeline stalls because of a load interlock, this register is 
--   allowed to update so that the load operation can complete while the rest of
--   allowed to update so that the load operation can complete while the rest of
Line 719... Line 764...
        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
-- FIXME make sure this combinational will not have bad glitches
stall_pipeline <= mem_wait or load_interlock;
stall_pipeline <= mem_wait or load_interlock or p1_muldiv_stall;
 
 
 
 
-- FIXME load interlock should happen only if the instruction following 
-- FIXME load interlock should happen only if the instruction following 
-- the load actually uses the load target register. Something like this:
-- 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))
-- (p1_do_load='1' and (p1_rd_num=p0_rs_num or p1_rd_num=p0_rt_num))

powered by: WebSVN 2.1.0

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