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

Subversion Repositories ion

[/] [ion/] [trunk/] [vhdl/] [mips_cop0.vhdl] - Blame information for rev 252

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 252 ja_rd
--------------------------------------------------------------------------------
2
-- mips_cop0.vhdl -- COP0 for ION CPU.
3
--------------------------------------------------------------------------------
4
--
5
--------------------------------------------------------------------------------
6
-- Copyright (C) 2013 Jose A. Ruiz
7
--                                                              
8
-- This source file may be used and distributed without         
9
-- restriction provided that this copyright statement is not    
10
-- removed from the file and that any derivative work contains  
11
-- the original copyright notice and the associated disclaimer. 
12
--                                                              
13
-- This source file is free software; you can redistribute it   
14
-- and/or modify it under the terms of the GNU Lesser General   
15
-- Public License as published by the Free Software Foundation; 
16
-- either version 2.1 of the License, or (at your option) any   
17
-- later version.                                               
18
--                                                              
19
-- This source is distributed in the hope that it will be       
20
-- useful, but WITHOUT ANY WARRANTY; without even the implied   
21
-- warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      
22
-- PURPOSE.  See the GNU Lesser General Public License for more 
23
-- details.                                                     
24
--                                                              
25
-- You should have received a copy of the GNU Lesser General    
26
-- Public License along with this source; if not, download it   
27
-- from http://www.opencores.org/lgpl.shtml
28
--------------------------------------------------------------------------------
29
 
30
library ieee;
31
use ieee.std_logic_1164.all;
32
use ieee.std_logic_arith.all;
33
use work.mips_pkg.all;
34
 
35
entity mips_cop0 is
36
    generic(
37
        -- Type of memory to be used for register bank in xilinx HW
38
        XILINX_REGBANK  : string    := "distributed" -- {distributed|block}
39
    );
40
    port(
41
        clk             : in std_logic;
42
        reset           : in std_logic;
43
 
44
        cpu_i           : in t_cop0_mosi;
45
        cpu_o           : out t_cop0_miso
46
    );
47
end;
48
 
49
architecture rtl of mips_cop0 is
50
 
51
--------------------------------------------------------------------------------
52
-- CP0 registers and signals
53
 
54
-- CP0[12]: status register, KUo/IEo & KUP/IEp & KU/IE  bits
55
signal cp0_status :         std_logic_vector(5 downto 0);
56
signal cp0_sr_ku_reg :      std_logic;
57
-- CP0[12]: status register, cache control
58
signal cp0_cache_control :  std_logic_vector(17 downto 16);
59
-- CP0[14]: EPC register (PC value saved at exceptions)
60
signal cp0_epc :            t_pc;
61
-- CP0[13]: 'Cause' register (cause and attributes of exception)
62
signal cp0_cause :          t_word;
63
signal cp0_cause_bd :       std_logic;
64
signal cp0_cause_ce :       std_logic_vector(1 downto 0);
65
signal cp0_cause_exc_code : std_logic_vector(4 downto 0);
66
 
67
begin
68
 
69
 
70
cp0_registers:
71
process(clk)
72
begin
73
    if clk'event and clk='1' then
74
        if reset='1' then
75
            -- KU/IE="10"  ==>  mode=kernel; ints=disabled
76
            cp0_status <= "000010";  -- bits (KUo/IEo & KUp/IEp) reset to zero
77
            cp0_sr_ku_reg <= '1'; -- delayed KU flag
78
            cp0_cache_control <= "00";
79
            cp0_cause_exc_code <= "00000";
80
            cp0_cause_bd <= '0';
81
        else
82
            if cpu_i.pipeline_stalled='0' then
83
                if cpu_i.exception='1' then
84
                    -- Exception: do all that needs to be done right here
85
 
86
                    -- Save PC in EPC register...
87
                    cp0_epc <= cpu_i.pc_restart;
88
                    -- ... set KU flag to Kernel mode ...
89
                    cp0_status(1) <= '1';
90
                    -- ... and 'push' old KU/IE flag values 
91
                    cp0_status(5 downto 4) <= cp0_status(3 downto 2);
92
                    cp0_status(3 downto 2) <= cp0_status(1 downto 0);
93
 
94
                    -- Set the 'exception cause' code... 
95
                    if cpu_i.unknown_opcode='1' then
96
                        cp0_cause_exc_code <= "01010"; -- bad opcode ('reserved')
97
                    elsif cpu_i.missing_cop='1' then
98
                        -- this triggers for mtc0/mfc0 in user mode too
99
                        cp0_cause_exc_code <= "01011"; -- CP* unavailable 
100
                    else
101
                        if cpu_i.syscall='1' then
102
                            cp0_cause_exc_code <= "01000"; -- syscall
103
                        else
104
                            cp0_cause_exc_code <= "01001"; -- break
105
                        end if;
106
                    end if;
107
                    -- ... and the BD flag for exceptions in delay slots
108
                    cp0_cause_bd <= cpu_i.in_delay_slot;
109
 
110
                elsif cpu_i.rfe='1' and cp0_status(1)='1' then
111
                    -- RFE: restore ('pop') the KU/IE flag values
112
 
113
                    cp0_status(3 downto 2) <= cp0_status(5 downto 4);
114
                    cp0_status(1 downto 0) <= cp0_status(3 downto 2);
115
 
116
                elsif cpu_i.we='1' and cp0_status(1)='1' then
117
                    -- MTC0: load CP0[xx] with Rt
118
 
119
                    -- NOTE: in MTCx, the source register is Rt
120
                    -- FIXME this works because only SR is writeable; when 
121
                    -- CP0[13].IP1-0 are implemented, check for CP0 reg index.
122
                    cp0_status <= cpu_i.data(cp0_status'high downto 0);
123
                    cp0_cache_control <= cpu_i.data(17 downto 16);
124
                end if;
125
            end if;
126
            if cpu_i.stall='0' then
127
                cp0_sr_ku_reg <= cp0_status(1);
128
            end if;
129
        end if;
130
    end if;
131
end process cp0_registers;
132
 
133
cpu_o.idcache_enable <= cp0_cache_control(17);
134
cpu_o.icache_invalidate <= cp0_cache_control(16);
135
cpu_o.kernel <= cp0_sr_ku_reg;
136
 
137
cp0_cause_ce <= "00"; -- FIXME CP* traps merged with unimplemented opcode traps
138
cp0_cause <= cp0_cause_bd & '0' & cp0_cause_ce &
139
             X"00000" & '0' & cp0_cause_exc_code & "00";
140
 
141
-- FIXME the mux should mask to zero for any unused reg index
142
with cpu_i.index select cpu_o.data <=
143
    X"000000" & "00" & cp0_status   when "01100",
144
    cp0_cause                       when "01101",
145
    cp0_epc & "00"                  when others;
146
 
147
 
148
end architecture rtl;

powered by: WebSVN 2.1.0

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