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

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [rtl/] [riverlib/] [core/] [csr.vhd] - Blame information for rev 5

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 5 sergeykhbr
-----------------------------------------------------------------------------
2
--! @file
3
--! @copyright Copyright 2018 GNSS Sensor Ltd. All right reserved.
4
--! @author    Sergey Khabarov - sergeykhbr@gmail.com
5
--! @brief     CSR registers module.
6
------------------------------------------------------------------------------
7
 
8
library ieee;
9
use ieee.std_logic_1164.all;
10
library commonlib;
11
use commonlib.types_common.all;
12
--! RIVER CPU specific library.
13
library riverlib;
14
--! RIVER CPU configuration constants.
15
use riverlib.river_cfg.all;
16
 
17
entity CsrRegs is
18
  port (
19
    i_clk : in std_logic;                                   -- CPU clock
20
    i_nrst : in std_logic;                                  -- Reset. Active LOW.
21
    i_xret : in std_logic;                                  -- XRet instruction signals mode switching
22
    i_addr : in std_logic_vector(11 downto 0);              -- CSR address, if xret=1 switch mode accordingly
23
    i_wena : in std_logic;                                  -- Write enable
24
    i_wdata : in std_logic_vector(RISCV_ARCH-1 downto 0);   -- CSR writing value
25
    o_rdata : out std_logic_vector(RISCV_ARCH-1 downto 0);  -- CSR read value
26
    i_break_mode : in std_logic;                            -- Behaviour on EBREAK instruction: 0 = halt; 1 = generate trap
27
    i_breakpoint : in std_logic;                            -- Breakpoint (Trap or not depends of mode)
28
    i_trap_ena : in std_logic;                              -- Trap pulse
29
    i_trap_code : in std_logic_vector(4 downto 0);          -- bit[4] : 1=interrupt; 0=exception; bits[3:0]=code
30
    i_trap_pc : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);-- trap on pc
31
 
32
    o_ie : out std_logic;                                    -- Interrupt enable bit
33
    o_mode : out std_logic_vector(1 downto 0);               -- CPU mode
34
    o_mtvec : out std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);-- Interrupt descriptors table
35
 
36
    i_dport_ena : in std_logic;                              -- Debug port request is enabled
37
    i_dport_write : in std_logic;                            -- Debug port Write enable
38
    i_dport_addr : in std_logic_vector(11 downto 0);         -- Debug port CSR address
39
    i_dport_wdata : in std_logic_vector(RISCV_ARCH-1 downto 0);-- Debug port CSR writing value
40
    o_dport_rdata : out std_logic_vector(RISCV_ARCH-1 downto 0)-- Debug port CSR read value
41
  );
42
end;
43
 
44
architecture arch_CsrRegs of CsrRegs is
45
 
46
  type RegistersType is record
47
      mtvec : std_logic_vector(RISCV_ARCH-1 downto 0);
48
      mscratch : std_logic_vector(RISCV_ARCH-1 downto 0);
49
      mbadaddr : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);
50
      mode : std_logic_vector(1 downto 0);
51
      uie : std_logic;                       -- User level interrupts ena for current priv. mode
52
      mie : std_logic;                       -- Machine level interrupts ena for current priv. mode
53
      mpie : std_logic;                      -- Previous MIE value
54
      mpp : std_logic_vector(1 downto 0);    -- Previous mode
55
      mepc : std_logic_vector(RISCV_ARCH-1 downto 0);
56
 
57
      trap_irq : std_logic;
58
      trap_code : std_logic_vector(3 downto 0);
59
  end record;
60
 
61
  signal r, rin : RegistersType;
62
 
63
  procedure procedure_RegAccess(
64
     iaddr  : in std_logic_vector(11 downto 0);
65
     iwena  : in std_logic;
66
     iwdata : in std_logic_vector(RISCV_ARCH-1 downto 0);
67
     ir : in RegistersType;
68
     ov : out RegistersType;
69
     ordata : out std_logic_vector(RISCV_ARCH-1 downto 0)) is
70
  begin
71
    ov := ir;
72
    ordata := (others => '0');
73
    case iaddr is
74
    when CSR_misa =>
75
        --! Base[XLEN-1:XLEN-2]
76
        --!     1 = 32
77
        --!     2 = 64
78
        --!     3 = 128
79
        --!
80
        ordata(RISCV_ARCH-1 downto RISCV_ARCH-2) := "10";
81
        --! BitCharacterDescription
82
        --! 0  A Atomic extension
83
        --! 1  B Tentatively reserved for Bit operations extension
84
        --! 2  C Compressed extension
85
        --! 3  D Double-precision Foating-point extension
86
        --! 4  E RV32E base ISA (embedded)
87
        --! 5  F Single-precision Foating-point extension
88
        --! 6  G Additional standard extensions present
89
        --! 7  H Hypervisor mode implemented
90
        --! 8  I RV32I/64I/128I base ISA
91
        --! 9  J Reserved
92
        --! 10 K Reserved
93
        --! 11 L Tentatively reserved for Decimal Floating-Point extension
94
        --! 12 M Integer Multiply/Divide extension
95
        --! 13 N User-level interrupts supported
96
        --! 14 O Reserved
97
        --! 15 P Tentatively reserved for Packed-SIMD extension
98
        --! 16 Q Quad-precision Foating-point extension
99
        --! 17 R Reserved
100
        --! 18 S Supervisor mode implemented
101
        --! 19 T Tentatively reserved for Transactional Memory extension
102
        --! 20 U User mode implemented
103
        --! 21 V Tentatively reserved for Vector extension
104
        --! 22 W Reserved
105
        --! 23 X Non-standard extensions present
106
        --! 24 Y Reserved
107
        --! 25 Z Reserve
108
        --!
109
        ordata(8) := '1';
110
        ordata(12) := '1';
111
        ordata(20) := '1';
112
        ordata(2) := '1';
113
    when CSR_mvendorid =>
114
    when CSR_marchid =>
115
    when CSR_mimplementationid =>
116
    when CSR_mhartid =>
117
    when CSR_uepc =>    -- User mode program counter
118
    when CSR_mstatus => -- Machine mode status register
119
        ordata(0) := ir.uie;
120
        ordata(3) := ir.mie;
121
        ordata(7) := ir.mpie;
122
        ordata(12 downto 11) := ir.mpp;
123
        if iwena = '1' then
124
            ov.uie := iwdata(0);
125
            ov.mie := iwdata(3);
126
            ov.mpie := iwdata(7);
127
            ov.mpp := iwdata(12 downto 11);
128
        end if;
129
    when CSR_medeleg => -- Machine exception delegation
130
    when CSR_mideleg => -- Machine interrupt delegation
131
    when CSR_mie =>     -- Machine interrupt enable bit
132
    when CSR_mtvec =>
133
        ordata := ir.mtvec;
134
        if iwena = '1' then
135
            ov.mtvec := iwdata;
136
        end if;
137
    when CSR_mtimecmp => -- Machine wall-clock timer compare value
138
    when CSR_mscratch => -- Machine scratch register
139
        ordata := ir.mscratch;
140
        if iwena = '1' then
141
            ov.mscratch := iwdata;
142
        end if;
143
    when CSR_mepc => -- Machine program counter
144
        ordata := ir.mepc;
145
        if iwena = '1' then
146
            ov.mepc := iwdata;
147
        end if;
148
    when CSR_mcause => -- Machine trap cause
149
        ordata(63) := ir.trap_irq;
150
        ordata(3 downto 0) := ir.trap_code;
151
    when CSR_mbadaddr => -- Machine bad address
152
        ordata(BUS_ADDR_WIDTH-1 downto 0) := ir.mbadaddr;
153
    when CSR_mip =>      -- Machine interrupt pending
154
    when others =>
155
    end case;
156
  end;
157
 
158
begin
159
 
160
  comb : process(i_nrst, i_xret, i_addr, i_wena, i_wdata,
161
                 i_break_mode, i_breakpoint, i_trap_ena,
162
                 i_dport_ena, i_dport_write, i_dport_addr, i_dport_wdata,
163
                 i_trap_code, i_trap_pc, r)
164
    variable v : RegistersType;
165
    variable wb_rdata : std_logic_vector(RISCV_ARCH-1 downto 0);
166
    variable wb_dport_rdata : std_logic_vector(RISCV_ARCH-1 downto 0);
167
    variable w_ie : std_logic;
168
    variable w_dport_wena : std_logic;
169
  begin
170
 
171
    v := r;
172
 
173
    w_dport_wena := i_dport_ena and i_dport_write;
174
 
175
    procedure_RegAccess(i_addr, i_wena, i_wdata,
176
                        v, v, wb_rdata);
177
 
178
    procedure_RegAccess(i_dport_addr, w_dport_wena,
179
                        i_dport_wdata, v, v, wb_dport_rdata);
180
 
181
    if i_addr = CSR_mepc and i_xret = '1' then
182
        -- Switch to previous mode
183
        v.mie := r.mpie;
184
        v.mpie := '1';
185
        v.mode := r.mpp;
186
        v.mpp := PRV_U;
187
    end if;
188
 
189
    if (i_trap_ena and (i_break_mode or not i_breakpoint)) = '1' then
190
        v.mie := '0';
191
        v.mpp := r.mode;
192
        v.mepc(RISCV_ARCH-1 downto BUS_ADDR_WIDTH) := (others => '0');
193
        v.mepc(BUS_ADDR_WIDTH-1 downto 0) := i_trap_pc;
194
        v.mbadaddr := i_trap_pc;
195
        v.trap_code := i_trap_code(3 downto 0);
196
        v.trap_irq := i_trap_code(4);
197
        v.mode := PRV_M;
198
        case r.mode is
199
        when PRV_U =>
200
            v.mpie := r.uie;
201
        when PRV_M =>
202
            v.mpie := r.mie;
203
        when others =>
204
        end case;
205
    end if;
206
 
207
    w_ie := '0';
208
    if (r.mode /= PRV_M) or r.mie = '1' then
209
        w_ie := '1';
210
    end if;
211
 
212
    if i_nrst = '0' then
213
        v.mtvec := (others => '0');
214
        v.mscratch := (others => '0');
215
        v.mbadaddr := (others => '0');
216
        v.mode := PRV_M;
217
        v.uie := '0';
218
        v.mie := '0';
219
        v.mpie := '0';
220
        v.mpp := (others => '0');
221
        v.mepc := (others => '0');
222
        v.trap_code := (others => '0');
223
        v.trap_irq := '0';
224
    end if;
225
 
226
    o_rdata <= wb_rdata;
227
    o_ie <= w_ie;
228
    o_mode <= r.mode;
229
    o_mtvec <= r.mtvec(BUS_ADDR_WIDTH-1 downto 0);
230
    o_dport_rdata <= wb_dport_rdata;
231
 
232
    rin <= v;
233
  end process;
234
 
235
  -- registers:
236
  regs : process(i_clk)
237
  begin
238
     if rising_edge(i_clk) then
239
        r <= rin;
240
     end if;
241
  end process;
242
 
243
end;

powered by: WebSVN 2.1.0

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