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

Subversion Repositories riscv_vhdl

[/] [riscv_vhdl/] [trunk/] [rtl/] [riverlib/] [core/] [execute.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 2016 GNSS Sensor Ltd. All right reserved.
4
--! @author    Sergey Khabarov - sergeykhbr@gmail.com
5
--! @brief     CPU Instruction Execution stage.
6
------------------------------------------------------------------------------
7
 
8
library ieee;
9
use ieee.std_logic_1164.all;
10
use IEEE.std_logic_arith.all;  -- UNSIGNED function
11
library commonlib;
12
use commonlib.types_common.all;
13
--! RIVER CPU specific library.
14
library riverlib;
15
--! RIVER CPU configuration constants.
16
use riverlib.river_cfg.all;
17
 
18
 
19
entity InstrExecute is
20
  port (
21
    i_clk  : in std_logic;
22
    i_nrst : in std_logic;                                      -- Reset active LOW
23
    i_pipeline_hold : in std_logic;                             -- Hold execution by any reason
24
    i_d_valid : in std_logic;                                   -- Decoded instruction is valid
25
    i_d_pc : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);    -- Instruction pointer on decoded instruction
26
    i_d_instr : in std_logic_vector(31 downto 0);               -- Decoded instruction value
27
    i_wb_done : in std_logic;                                   -- write back done (Used to clear hazardness)
28
    i_memop_store : in std_logic;                               -- Store to memory operation
29
    i_memop_load : in std_logic;                                -- Load from memoru operation
30
    i_memop_sign_ext : in std_logic;                            -- Load memory value with sign extending
31
    i_memop_size : in std_logic_vector(1 downto 0);             -- Memory transaction size
32
    i_unsigned_op : in std_logic;                               -- Unsigned operands
33
    i_rv32 : in std_logic;                                      -- 32-bits instruction
34
    i_compressed : in std_logic;                                -- C-extension (2-bytes length)
35
    i_isa_type : in std_logic_vector(ISA_Total-1 downto 0);     -- Type of the instruction's structure (ISA spec.)
36
    i_ivec : in std_logic_vector(Instr_Total-1 downto 0);       -- One pulse per supported instruction.
37
    i_ie : in std_logic;                                        -- Interrupt enable bit
38
    i_mtvec : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);   -- Interrupt descriptor table
39
    i_mode : in std_logic_vector(1 downto 0);                   -- Current processor mode
40
    i_break_mode : in std_logic;                                -- Behaviour on EBREAK instruction: 0 = halt; 1 = generate trap
41
    i_unsup_exception : in std_logic;                           -- Unsupported instruction exception
42
    i_ext_irq : in std_logic;                                   -- External interrupt from PLIC (todo: timer & software interrupts)
43
    i_dport_npc_write : in std_logic;                           -- Write npc value from debug port
44
    i_dport_npc : in std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);-- Debug port npc value to write
45
 
46
    o_radr1 : out std_logic_vector(4 downto 0);                 -- Integer register index 1
47
    i_rdata1 : in std_logic_vector(RISCV_ARCH-1 downto 0);      -- Integer register value 1
48
    o_radr2 : out std_logic_vector(4 downto 0);                 -- Integer register index 2
49
    i_rdata2 : in std_logic_vector(RISCV_ARCH-1 downto 0);      -- Integer register value 2
50
    o_res_addr : out std_logic_vector(4 downto 0);              -- Address to store result of the instruction (0=do not store)
51
    o_res_data : out std_logic_vector(RISCV_ARCH-1 downto 0);   -- Value to store
52
    o_pipeline_hold : out std_logic;                            -- Hold pipeline while 'writeback' not done or multi-clock instruction.
53
    o_xret : out std_logic;                                     -- XRET instruction: MRET, URET or other.
54
    o_csr_addr : out std_logic_vector(11 downto 0);             -- CSR address. 0 if not a CSR instruction with xret signals mode switching
55
    o_csr_wena : out std_logic;                                 -- Write new CSR value
56
    i_csr_rdata : in std_logic_vector(RISCV_ARCH-1 downto 0);   -- CSR current value
57
    o_csr_wdata : out std_logic_vector(RISCV_ARCH-1 downto 0);  -- CSR new value
58
    o_trap_ena : out std_logic;                                 -- Trap occurs  pulse
59
    o_trap_code : out std_logic_vector(4 downto 0);             -- bit[4] : 1=interrupt; 0=exception; bits[3:0]=code
60
    o_trap_pc : out std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);-- trap on pc
61
 
62
    o_memop_sign_ext : out std_logic;                           -- Load data with sign extending
63
    o_memop_load : out std_logic;                               -- Load data instruction
64
    o_memop_store : out std_logic;                              -- Store data instruction
65
    o_memop_size : out std_logic_vector(1 downto 0);            -- 0=1bytes; 1=2bytes; 2=4bytes; 3=8bytes
66
    o_memop_addr : out std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);-- Memory access address
67
 
68
    o_valid : out std_logic;                                    -- Output is valid
69
    o_pc : out std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);     -- Valid instruction pointer
70
    o_npc : out std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);    -- Next instruction pointer. Next decoded pc must match to this value or will be ignored.
71
    o_instr : out std_logic_vector(31 downto 0);                -- Valid instruction value
72
    o_breakpoint : out std_logic;                               -- ebreak instruction
73
    o_call : out std_logic;                                     -- CALL pseudo instruction detected
74
    o_ret : out std_logic                                       -- RET pseudoinstruction detected
75
  );
76
end;
77
 
78
architecture arch_InstrExecute of InstrExecute is
79
 
80
  constant Multi_MUL : integer := 0;
81
  constant Multi_DIV : integer := 1;
82
  constant Multi_Total : integer := 2;
83
  constant zero64 : std_logic_vector(63 downto 0) := (others => '0');
84
 
85
  type multi_arith_type is array (0 to Multi_Total-1)
86
      of std_logic_vector(RISCV_ARCH-1 downto 0);
87
 
88
  type RegistersType is record
89
        d_valid : std_logic;                                   -- Valid decoded instruction latch
90
        pc : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);
91
        npc : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);
92
        instr : std_logic_vector(31 downto 0);
93
        res_addr : std_logic_vector(4 downto 0);
94
        res_val : std_logic_vector(RISCV_ARCH-1 downto 0);
95
        memop_load : std_logic;
96
        memop_store : std_logic;
97
        memop_sign_ext : std_logic;
98
        memop_size : std_logic_vector(1 downto 0);
99
        memop_addr : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);
100
 
101
        multi_res_addr : std_logic_vector(4 downto 0);         -- latched output reg. address while multi-cycle instruction
102
        multi_pc : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);-- latched pc-value while multi-cycle instruction
103
        multi_npc : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);-- latched npc-value while multi-cycle instruction
104
        multi_instr : std_logic_vector(31 downto 0);           -- Multi-cycle instruction is under processing
105
        multi_ena : std_logic_vector(Multi_Total-1 downto 0);  -- Enable pulse for Operation that takes more than 1 clock
106
        multi_rv32 : std_logic;                                -- Long operation with 32-bits operands
107
        multi_unsigned : std_logic;                            -- Long operation with unsiged operands
108
        multi_residual_high : std_logic;                       -- Flag for Divider module: 0=divsion output; 1=residual output
109
                                                               -- Flag for multiplier: 0=usual; 1=get high bits
110
        multiclock_ena : std_logic;
111
        multi_a1 : std_logic_vector(RISCV_ARCH-1 downto 0);    -- Multi-cycle operand 1
112
        multi_a2 : std_logic_vector(RISCV_ARCH-1 downto 0);    -- Multi-cycle operand 2
113
 
114
        hazard_addr0 : std_logic_vector(4 downto 0);           -- Updated register address on previous step
115
        hazard_addr1 : std_logic_vector(4 downto 0);           -- Updated register address on pre-previous step
116
        hazard_depth : std_logic_vector(1 downto 0);           -- Number of modificated registers that wasn't done yet
117
 
118
        ext_irq_pulser : std_logic;                            -- Form 1 clock pulse from strob
119
        trap_ena : std_logic;                                  -- Trap occur, switch mode
120
        breakpoint : std_logic;
121
        trap_code_waiting : std_logic_vector(4 downto 0);      -- To avoid multi-cycle instruction collision
122
        trap_code : std_logic_vector(4 downto 0);              -- bit[4] : 1 = interrupt; 0 = exception
123
                                                               -- bit[3:0] : trap code
124
        trap_pc : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0); -- pc that caused a trap 
125
        call : std_logic;
126
        ret : std_logic;
127
  end record;
128
 
129
  signal r, rin : RegistersType;
130
 
131
  signal wb_arith_res : multi_arith_type;
132
  signal w_arith_valid : std_logic_vector(Multi_Total-1 downto 0);
133
  signal w_arith_busy : std_logic_vector(Multi_Total-1 downto 0);
134
  signal w_hazard_detected : std_logic;
135
 
136
  signal wb_shifter_a1 : std_logic_vector(RISCV_ARCH-1 downto 0);  -- Shifters operand 1
137
  signal wb_shifter_a2 : std_logic_vector(5 downto 0);             -- Shifters operand 2
138
  signal wb_sll : std_logic_vector(RISCV_ARCH-1 downto 0);
139
  signal wb_sllw : std_logic_vector(RISCV_ARCH-1 downto 0);
140
  signal wb_srl : std_logic_vector(RISCV_ARCH-1 downto 0);
141
  signal wb_srlw : std_logic_vector(RISCV_ARCH-1 downto 0);
142
  signal wb_sra : std_logic_vector(RISCV_ARCH-1 downto 0);
143
  signal wb_sraw : std_logic_vector(RISCV_ARCH-1 downto 0);
144
 
145
  component IntMul is port (
146
    i_clk  : in std_logic;
147
    i_nrst : in std_logic;
148
    i_ena : in std_logic;
149
    i_unsigned : in std_logic;
150
    i_high : in std_logic;
151
    i_rv32 : in std_logic;
152
    i_a1 : in std_logic_vector(RISCV_ARCH-1 downto 0);
153
    i_a2 : in std_logic_vector(RISCV_ARCH-1 downto 0);
154
    o_res : out std_logic_vector(RISCV_ARCH-1 downto 0);
155
    o_valid : out std_logic;
156
    o_busy : out std_logic
157
  );
158
  end component;
159
 
160
  component IntDiv is port (
161
    i_clk  : in std_logic;
162
    i_nrst : in std_logic;
163
    i_ena : in std_logic;
164
    i_unsigned : in std_logic;
165
    i_rv32 : in std_logic;
166
    i_residual : in std_logic;
167
    i_a1 : in std_logic_vector(RISCV_ARCH-1 downto 0);
168
    i_a2 : in std_logic_vector(RISCV_ARCH-1 downto 0);
169
    o_res : out std_logic_vector(RISCV_ARCH-1 downto 0);
170
    o_valid : out std_logic;
171
    o_busy : out std_logic
172
  );
173
  end component;
174
 
175
  component Shifter is port (
176
    i_a1 : in std_logic_vector(RISCV_ARCH-1 downto 0);
177
    i_a2 : in std_logic_vector(5 downto 0);
178
    o_sll : out std_logic_vector(RISCV_ARCH-1 downto 0);
179
    o_sllw : out std_logic_vector(RISCV_ARCH-1 downto 0);
180
    o_srl : out std_logic_vector(RISCV_ARCH-1 downto 0);
181
    o_sra : out std_logic_vector(RISCV_ARCH-1 downto 0);
182
    o_srlw : out std_logic_vector(RISCV_ARCH-1 downto 0);
183
    o_sraw : out std_logic_vector(RISCV_ARCH-1 downto 0)
184
  );
185
  end component;
186
 
187
begin
188
 
189
   mul0 : IntMul port map (
190
      i_clk  => i_clk,
191
      i_nrst => i_nrst,
192
      i_ena => r.multi_ena(Multi_MUL),
193
      i_unsigned => r.multi_unsigned,
194
      i_high => r.multi_residual_high,
195
      i_rv32 => r.multi_rv32,
196
      i_a1 => r.multi_a1,
197
      i_a2 => r.multi_a2,
198
      o_res => wb_arith_res(Multi_MUL),
199
      o_valid => w_arith_valid(Multi_MUL),
200
      o_busy => w_arith_busy(Multi_MUL));
201
 
202
   div0 : IntDiv port map (
203
      i_clk  => i_clk,
204
      i_nrst => i_nrst,
205
      i_ena => r.multi_ena(Multi_DIV),
206
      i_unsigned => r.multi_unsigned,
207
      i_residual => r.multi_residual_high,
208
      i_rv32 => r.multi_rv32,
209
      i_a1 => r.multi_a1,
210
      i_a2 => r.multi_a2,
211
      o_res => wb_arith_res(Multi_DIV),
212
      o_valid => w_arith_valid(Multi_DIV),
213
      o_busy => w_arith_busy(Multi_DIV));
214
 
215
  sh0 : Shifter port map (
216
      i_a1 => wb_shifter_a1,
217
      i_a2 => wb_shifter_a2,
218
      o_sll => wb_sll,
219
      o_sllw => wb_sllw,
220
      o_srl => wb_srl,
221
      o_sra => wb_sra,
222
      o_srlw => wb_srlw,
223
      o_sraw => wb_sraw);
224
 
225
  comb : process(i_nrst, i_pipeline_hold, i_d_valid, i_d_pc, i_d_instr,
226
                 i_wb_done, i_memop_load, i_memop_store, i_memop_sign_ext,
227
                 i_memop_size, i_unsigned_op, i_rv32, i_compressed, i_isa_type, i_ivec,
228
                 i_rdata1, i_rdata2, i_csr_rdata, i_ext_irq, i_dport_npc_write,
229
                 i_dport_npc, i_ie, i_mtvec, i_mode, i_break_mode, i_unsup_exception,
230
                 wb_arith_res, w_arith_valid, w_arith_busy, w_hazard_detected,
231
                 wb_sll, wb_sllw, wb_srl, wb_srlw, wb_sra, wb_sraw, r)
232
    variable v : RegistersType;
233
    variable w_interrupt : std_logic;
234
    variable w_exception : std_logic;
235
    variable w_exception_store : std_logic;
236
    variable w_exception_load : std_logic;
237
    variable w_exception_xret : std_logic;
238
    variable wb_exception_code : std_logic_vector(4 downto 0);
239
    variable wb_radr1 : std_logic_vector(4 downto 0);
240
    variable wb_rdata1 : std_logic_vector(RISCV_ARCH-1 downto 0);
241
    variable wb_radr2 : std_logic_vector(4 downto 0);
242
    variable wb_rdata2 : std_logic_vector(RISCV_ARCH-1 downto 0);
243
    variable w_xret : std_logic;
244
    variable w_csr_wena : std_logic;
245
    variable wb_res_addr : std_logic_vector(4 downto 0);
246
    variable wb_csr_addr  : std_logic_vector(11 downto 0);
247
    variable wb_csr_wdata : std_logic_vector(RISCV_ARCH-1 downto 0);
248
    variable wb_res : std_logic_vector(RISCV_ARCH-1 downto 0);
249
    variable wb_npc : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);
250
    variable wb_off : std_logic_vector(RISCV_ARCH-1 downto 0);
251
    variable wb_mask_i31 : std_logic_vector(RISCV_ARCH-1 downto 0);    -- Bits depending instr[31] bits
252
    variable wb_sum64 : std_logic_vector(RISCV_ARCH-1 downto 0);
253
    variable wb_sum32 : std_logic_vector(RISCV_ARCH-1 downto 0);
254
    variable wb_sub64 : std_logic_vector(RISCV_ARCH-1 downto 0);
255
    variable wb_sub32 : std_logic_vector(RISCV_ARCH-1 downto 0);
256
    variable wb_and64 : std_logic_vector(RISCV_ARCH-1 downto 0);
257
    variable wb_or64 : std_logic_vector(RISCV_ARCH-1 downto 0);
258
    variable wb_xor64 : std_logic_vector(RISCV_ARCH-1 downto 0);
259
    variable w_memop_load : std_logic;
260
    variable w_memop_store : std_logic;
261
    variable w_memop_sign_ext : std_logic;
262
    variable wb_memop_size : std_logic_vector(1 downto 0);
263
    variable wb_memop_addr : std_logic_vector(BUS_ADDR_WIDTH-1 downto 0);
264
 
265
    variable w_pc_valid : std_logic;
266
    variable w_d_acceptable : std_logic;
267
    variable w_multi_valid : std_logic;
268
    variable w_multi_ena : std_logic;
269
    variable w_res_wena : std_logic;
270
    variable w_pc_branch : std_logic;
271
    variable w_hazard_lvl1 : std_logic;
272
    variable w_hazard_lvl2 : std_logic;
273
    variable w_d_valid : std_logic;
274
    variable w_o_valid : std_logic;
275
    variable w_o_pipeline_hold : std_logic;
276
    variable w_less : std_logic;
277
    variable w_gr_equal : std_logic;
278
    variable wv : std_logic_vector(Instr_Total-1 downto 0);
279
    variable opcode_len : integer;
280
 
281
  begin
282
 
283
    wb_radr1 := (others => '0');
284
    wb_radr2 := (others => '0');
285
    w_xret := '0';
286
    w_csr_wena := '0';
287
    wb_res_addr := (others => '0');
288
    wb_csr_addr := (others => '0');
289
    wb_csr_wdata := (others => '0');
290
    wb_res := (others => '0');
291
    wb_off := (others => '0');
292
    wb_rdata1 := (others => '0');
293
    wb_rdata2 := (others => '0');
294
    w_memop_load := '0';
295
    w_memop_store := '0';
296
    w_memop_sign_ext := '0';
297
    wb_memop_size := (others => '0');
298
    wb_memop_addr := (others => '0');
299
    wv := i_ivec;
300
 
301
    v := r;
302
    v.breakpoint := '0';
303
 
304
    wb_mask_i31 := (others => i_d_instr(31));
305
 
306
    w_pc_valid := '0';
307
    if i_d_pc = r.npc then
308
        w_pc_valid := '1';
309
    end if;
310
    w_d_acceptable := not i_pipeline_hold and i_d_valid
311
                          and w_pc_valid and not r.multiclock_ena;
312
 
313
    v.ext_irq_pulser := i_ext_irq and i_ie;
314
    w_interrupt := '0';
315
    if w_d_acceptable = '1' and (r.trap_code_waiting /= "00000") then
316
        w_interrupt := '1';
317
    end if;
318
 
319
    if i_isa_type(ISA_R_type) = '1' then
320
        wb_radr1 := i_d_instr(19 downto 15);
321
        wb_rdata1 := i_rdata1;
322
        wb_radr2 := i_d_instr(24 downto 20);
323
        wb_rdata2 := i_rdata2;
324
    elsif i_isa_type(ISA_I_type) = '1' then
325
        wb_radr1 := i_d_instr(19 downto 15);
326
        wb_rdata1 := i_rdata1;
327
        wb_radr2 := (others => '0');
328
        wb_rdata2 := wb_mask_i31(63 downto 12) & i_d_instr(31 downto 20);
329
    elsif i_isa_type(ISA_SB_type) = '1' then
330
        wb_radr1 := i_d_instr(19 downto 15);
331
        wb_rdata1 := i_rdata1;
332
        wb_radr2 := i_d_instr(24 downto 20);
333
        wb_rdata2 := i_rdata2;
334
        wb_off(RISCV_ARCH-1 downto 12) := wb_mask_i31(RISCV_ARCH-1 downto 12);
335
        wb_off(12) := i_d_instr(31);
336
        wb_off(11) := i_d_instr(7);
337
        wb_off(10 downto 5) := i_d_instr(30 downto 25);
338
        wb_off(4 downto 1) := i_d_instr(11 downto 8);
339
        wb_off(0) := '0';
340
    elsif i_isa_type(ISA_UJ_type) = '1' then
341
        wb_radr1 := (others => '0');
342
        wb_rdata1 := X"00000000" & i_d_pc;
343
        wb_radr2 := (others => '0');
344
        wb_off(RISCV_ARCH-1 downto 20) := wb_mask_i31(RISCV_ARCH-1 downto 20);
345
        wb_off(19 downto 12) := i_d_instr(19 downto 12);
346
        wb_off(11) := i_d_instr(20);
347
        wb_off(10 downto 1) := i_d_instr(30 downto 21);
348
        wb_off(0) := '0';
349
    elsif i_isa_type(ISA_U_type) = '1'then
350
        wb_radr1 := (others => '0');
351
        wb_rdata1 := X"00000000" & i_d_pc;
352
        wb_radr2 := (others => '0');
353
        wb_rdata2(31 downto 0) := i_d_instr(31 downto 12) & X"000";
354
        wb_rdata2(RISCV_ARCH-1 downto 32) := wb_mask_i31(RISCV_ARCH-1 downto 32);
355
    elsif i_isa_type(ISA_S_type) = '1' then
356
        wb_radr1 := i_d_instr(19 downto 15);
357
        wb_rdata1 := i_rdata1;
358
        wb_radr2 := i_d_instr(24 downto 20);
359
        wb_rdata2 := i_rdata2;
360
        wb_off(RISCV_ARCH-1 downto 12) := wb_mask_i31(RISCV_ARCH-1 downto 12);
361
        wb_off(11 downto 5) := i_d_instr(31 downto 25);
362
        wb_off(4 downto 0) := i_d_instr(11 downto 7);
363
    end if;
364
 
365
    -- parallel ALU:
366
    wb_sum64 := wb_rdata1 + wb_rdata2;
367
    wb_sum32(31 downto 0) := wb_rdata1(31 downto 0) + wb_rdata2(31 downto 0);
368
    wb_sum32(63 downto 32) := (others => wb_sum32(31));
369
    wb_sub64 := wb_rdata1 - wb_rdata2;
370
    wb_sub32(31 downto 0) := wb_rdata1(31 downto 0) - wb_rdata2(31 downto 0);
371
    wb_sub32(63 downto 32) := (others => wb_sub32(31));
372
    wb_and64 := wb_rdata1 and wb_rdata2;
373
    wb_or64 := wb_rdata1 or wb_rdata2;
374
    wb_xor64 := wb_rdata1 xor wb_rdata2;
375
 
376
    wb_shifter_a1 <= wb_rdata1;
377
    wb_shifter_a2 <= wb_rdata2(5 downto 0);
378
 
379
    w_multi_valid := w_arith_valid(Multi_MUL) or w_arith_valid(Multi_DIV);
380
 
381
    -- Don't modify registers on conditional jumps:
382
    w_res_wena := not (wv(Instr_BEQ) or wv(Instr_BGE) or wv(Instr_BGEU)
383
               or wv(Instr_BLT) or wv(Instr_BLTU) or wv(Instr_BNE)
384
               or wv(Instr_SD) or wv(Instr_SW) or wv(Instr_SH) or wv(Instr_SB)
385
               or wv(Instr_MRET) or wv(Instr_URET)
386
               or wv(Instr_ECALL) or wv(Instr_EBREAK));
387
 
388
    if w_multi_valid = '1' then
389
        wb_res_addr := r.multi_res_addr;
390
        v.multiclock_ena := '0';
391
    elsif w_res_wena = '1' then
392
        wb_res_addr := i_d_instr(11 downto 7);
393
    else
394
        wb_res_addr := (others => '0');
395
    end if;
396
    w_less := '0';
397
    w_gr_equal := '0';
398
    if UNSIGNED(wb_rdata1) < UNSIGNED(wb_rdata2) then
399
        w_less := '1';
400
    end if;
401
    if UNSIGNED(wb_rdata1) >= UNSIGNED(wb_rdata2) then
402
        w_gr_equal := '1';
403
    end if;
404
 
405
    -- Relative Branch on some condition:
406
    w_pc_branch := '0';
407
    if ((wv(Instr_BEQ) = '1' and (wb_sub64 = zero64))
408
        or (wv(Instr_BGE) = '1' and (wb_sub64(63) = '0'))
409
        or (wv(Instr_BGEU) = '1' and (w_gr_equal = '1'))
410
        or (wv(Instr_BLT) = '1' and (wb_sub64(63) = '1'))
411
        or (wv(Instr_BLTU) = '1' and (w_less = '1'))
412
        or (wv(Instr_BNE) = '1' and (wb_sub64 /= zero64))) then
413
        w_pc_branch := '1';
414
    end if;
415
 
416
    opcode_len := 4;
417
    if i_compressed = '1' then
418
        opcode_len := 2;
419
    end if;
420
 
421
    if w_pc_branch = '1' then
422
        wb_npc := i_d_pc + wb_off(BUS_ADDR_WIDTH-1 downto 0);
423
    elsif wv(Instr_JAL) = '1' then
424
        wb_res(63 downto 32) := (others => '0');
425
        wb_res(31 downto 0) := i_d_pc + opcode_len;
426
        wb_npc := wb_rdata1(BUS_ADDR_WIDTH-1 downto 0) + wb_off(BUS_ADDR_WIDTH-1 downto 0);
427
    elsif wv(Instr_JALR) = '1' then
428
        wb_res(63 downto 32) := (others => '0');
429
        wb_res(31 downto 0) := i_d_pc + opcode_len;
430
        wb_npc := wb_rdata1(BUS_ADDR_WIDTH-1 downto 0) + wb_rdata2(BUS_ADDR_WIDTH-1 downto 0);
431
        wb_npc(0) := '0';
432
    elsif wv(Instr_MRET) = '1' or wv(Instr_URET) = '1' then
433
        wb_res(63 downto 32) := (others => '0');
434
        wb_res(31 downto 0) := i_d_pc + opcode_len;
435
        w_xret := i_d_valid and w_pc_valid;
436
        w_csr_wena := '0';
437
        if wv(Instr_URET) = '1' then
438
            wb_csr_addr := CSR_uepc;
439
        else
440
            wb_csr_addr := CSR_mepc;
441
        end if;
442
        wb_npc := i_csr_rdata(BUS_ADDR_WIDTH-1 downto 0);
443
    else
444
        -- Instr_HRET, Instr_SRET, Instr_FENCE, Instr_FENCE_I:
445
        wb_npc := i_d_pc + opcode_len;
446
    end if;
447
 
448
    if i_memop_load = '1' then
449
        wb_memop_addr := wb_rdata1(BUS_ADDR_WIDTH-1 downto 0)
450
                      + wb_rdata2(BUS_ADDR_WIDTH-1 downto 0);
451
    elsif i_memop_store = '1' then
452
        wb_memop_addr := wb_rdata1(BUS_ADDR_WIDTH-1 downto 0)
453
                       + wb_off(BUS_ADDR_WIDTH-1 downto 0);
454
    end if;
455
 
456
    v.memop_addr := (others => '0');
457
    v.memop_load := '0';
458
    v.memop_store := '0';
459
    v.memop_sign_ext := '0';
460
    v.memop_size := (others => '0');
461
    w_exception_store := '0';
462
    w_exception_load := '0';
463
    w_exception_xret := '0';
464
 
465
    if ((wv(Instr_LD) = '1' and wb_memop_addr(2 downto 0) /= "000")
466
        or ((wv(Instr_LW) or wv(Instr_LWU)) = '1' and wb_memop_addr(1 downto 0) /= "00")
467
        or ((wv(Instr_LH) or wv(Instr_LHU)) = '1' and wb_memop_addr(0) /= '0'))  then
468
        w_exception_load := not w_hazard_detected;
469
    end if;
470
    if ((wv(Instr_SD) = '1' and wb_memop_addr(2 downto 0) /= "000")
471
        or (wv(Instr_SW) = '1' and wb_memop_addr(1 downto 0) /= "00")
472
        or (wv(Instr_SH) = '1' and wb_memop_addr(0) /= '0')) then
473
        w_exception_store := not w_hazard_detected;
474
    end if;
475
    if (wv(Instr_MRET) = '1' and i_mode /= PRV_M)
476
        or (wv(Instr_URET) = '1' and i_mode /= PRV_U) then
477
        w_exception_xret := '1';
478
    end if;
479
 
480
 
481
    w_exception := w_d_acceptable
482
        and ((i_unsup_exception and w_pc_valid) or w_exception_load
483
             or w_exception_store or w_exception_xret
484
             or wv(Instr_ECALL) or wv(Instr_EBREAK));
485
 
486
 
487
    --! Default number of cycles per instruction = 0 (1 clock per instr)
488
    --! If instruction is multicycle then modify this value.
489
    --!
490
    v.multi_ena := (others => '0');
491
    v.multi_rv32 := i_rv32;
492
    v.multi_unsigned := i_unsigned_op;
493
    v.multi_residual_high := '0';
494
    v.multi_a1 := i_rdata1;
495
    v.multi_a2 := i_rdata2;
496
 
497
    w_multi_ena := wv(Instr_MUL) or wv(Instr_MULW) or wv(Instr_DIV)
498
                    or wv(Instr_DIVU) or wv(Instr_DIVW) or wv(Instr_DIVUW)
499
                    or wv(Instr_REM) or wv(Instr_REMU) or wv(Instr_REMW)
500
                    or wv(Instr_REMUW);
501
    if (w_multi_ena and w_d_acceptable and (not w_exception)
502
        and (not w_interrupt)) = '1' then
503
        v.multiclock_ena := '1';
504
        v.multi_res_addr := wb_res_addr;
505
        v.multi_pc := i_d_pc;
506
        v.multi_instr := i_d_instr;
507
        v.multi_npc := wb_npc;
508
    end if;
509
 
510
 
511
    -- ALU block selector:
512
    if w_arith_valid(Multi_MUL) = '1' then
513
        wb_res := wb_arith_res(Multi_MUL);
514
    elsif w_arith_valid(Multi_DIV) = '1' then
515
        wb_res := wb_arith_res(Multi_DIV);
516
    elsif i_memop_load = '1' then
517
        w_memop_load := not w_hazard_detected;
518
        w_memop_sign_ext := i_memop_sign_ext;
519
        wb_memop_size := i_memop_size;
520
    elsif i_memop_store = '1' then
521
        w_memop_store := not w_hazard_detected;
522
        wb_memop_size := i_memop_size;
523
        wb_res := wb_rdata2;
524
    elsif (wv(Instr_ADD) or wv(Instr_ADDI) or wv(Instr_AUIPC)) = '1' then
525
        wb_res := wb_sum64;
526
    elsif (wv(Instr_ADDW) or wv(Instr_ADDIW)) = '1' then
527
        wb_res := wb_sum32;
528
    elsif wv(Instr_SUB) = '1' then
529
        wb_res := wb_sub64;
530
    elsif wv(Instr_SUBW) = '1' then
531
        wb_res := wb_sub32;
532
    elsif (wv(Instr_SLL) or wv(Instr_SLLI)) = '1' then
533
        wb_res := wb_sll;
534
    elsif (wv(Instr_SLLW) or wv(Instr_SLLIW)) = '1' then
535
        wb_res := wb_sllw;
536
    elsif (wv(Instr_SRL) or wv(Instr_SRLI)) = '1' then
537
        wb_res := wb_srl;
538
    elsif (wv(Instr_SRLW) or wv(Instr_SRLIW)) = '1' then
539
        wb_res := wb_srlw;
540
    elsif (wv(Instr_SRA) or wv(Instr_SRAI)) = '1' then
541
        wb_res := wb_sra;
542
    elsif (wv(Instr_SRAW) or wv(Instr_SRAW) or wv(Instr_SRAIW)) = '1' then
543
        wb_res := wb_sraw;
544
    elsif (wv(Instr_AND) or wv(Instr_ANDI)) = '1' then
545
        wb_res := wb_and64;
546
    elsif (wv(Instr_OR) or wv(Instr_ORI)) = '1' then
547
        wb_res := wb_or64;
548
    elsif (wv(Instr_XOR) or wv(Instr_XORI)) = '1' then
549
        wb_res := wb_xor64;
550
    elsif (wv(Instr_SLT) or wv(Instr_SLTI)) = '1' then
551
        wb_res(RISCV_ARCH-1 downto 1) := (others => '0');
552
        wb_res(0) := wb_sub64(63);
553
    elsif (wv(Instr_SLTU) or wv(Instr_SLTIU)) = '1' then
554
        wb_res(63 downto 1) := (others => '0');
555
        wb_res(0) := w_less;
556
    elsif wv(Instr_LUI) = '1' then
557
        wb_res := wb_rdata2;
558
    elsif (wv(Instr_MUL) or wv(Instr_MULW)) = '1' then
559
        v.multi_ena(Multi_MUL) := w_d_acceptable and (not w_exception)
560
                                  and (not w_interrupt);
561
    elsif (wv(Instr_DIV) or wv(Instr_DIVU)
562
            or wv(Instr_DIVW) or wv(Instr_DIVUW)) = '1' then
563
        v.multi_ena(Multi_DIV) := w_d_acceptable and (not w_exception)
564
                                 and (not w_interrupt);
565
    elsif (wv(Instr_REM) or wv(Instr_REMU)
566
            or wv(Instr_REMW) or wv(Instr_REMUW)) = '1' then
567
        v.multi_ena(Multi_DIV) := w_d_acceptable and (not w_exception)
568
                                  and (not w_interrupt);
569
        v.multi_residual_high := '1';
570
    elsif wv(Instr_CSRRC) = '1' then
571
        wb_res := i_csr_rdata;
572
        w_csr_wena := '1';
573
        wb_csr_addr := wb_rdata2(11 downto 0);
574
        wb_csr_wdata := i_csr_rdata and (not i_rdata1);
575
    elsif wv(Instr_CSRRCI) = '1' then
576
        wb_res := i_csr_rdata;
577
        w_csr_wena := '1';
578
        wb_csr_addr := wb_rdata2(11 downto 0);
579
        wb_csr_wdata(RISCV_ARCH-1 downto 5) := i_csr_rdata(RISCV_ARCH-1 downto 5);
580
        wb_csr_wdata(4 downto 0) := i_csr_rdata(4 downto 0) and not wb_radr1;  -- zero-extending 5 to 64-bits
581
    elsif wv(Instr_CSRRS) = '1' then
582
        wb_res := i_csr_rdata;
583
        w_csr_wena := '1';
584
        wb_csr_addr := wb_rdata2(11 downto 0);
585
        wb_csr_wdata := i_csr_rdata or i_rdata1;
586
    elsif wv(Instr_CSRRSI) = '1' then
587
        wb_res := i_csr_rdata;
588
        w_csr_wena := '1';
589
        wb_csr_addr := wb_rdata2(11 downto 0);
590
        wb_csr_wdata(RISCV_ARCH-1 downto 5) := i_csr_rdata(RISCV_ARCH-1 downto 5);
591
        wb_csr_wdata(4 downto 0) := i_csr_rdata(4 downto 0) or wb_radr1;  -- zero-extending 5 to 64-bits
592
    elsif wv(Instr_CSRRW) = '1' then
593
        wb_res := i_csr_rdata;
594
        w_csr_wena := '1';
595
        wb_csr_addr := wb_rdata2(11 downto 0);
596
        wb_csr_wdata := i_rdata1;
597
    elsif wv(Instr_CSRRWI) = '1' then
598
        wb_res := i_csr_rdata;
599
        w_csr_wena := '1';
600
        wb_csr_addr := wb_rdata2(11 downto 0);
601
        wb_csr_wdata(RISCV_ARCH-1 downto 5) := (others => '0');
602
        wb_csr_wdata(4 downto 0) := wb_radr1;  -- zero-extending 5 to 64-bits
603
    end if;
604
 
605
    wb_exception_code := (others => '0');
606
    if (i_ext_irq and i_ie and not r.ext_irq_pulser) = '1' then -- Maskable traps (interrupts)
607
        v.trap_code_waiting(4) := '1';
608
        -- INTERRUPT_MExternal - INTERRUPT_USoftware
609
        v.trap_code_waiting(3 downto 0) := X"B";
610
    elsif w_exception = '1' then      -- Unmaskable traps (exceptions)
611
        wb_exception_code(4) := '0';
612
        if w_exception_load = '1' then
613
            wb_exception_code(3 downto 0) := EXCEPTION_LoadMisalign;
614
        elsif w_exception_store = '1' then
615
            wb_exception_code(3 downto 0) := EXCEPTION_StoreMisalign;
616
        elsif w_exception_xret = '1' then
617
            wb_exception_code(3 downto 0) := EXCEPTION_InstrIllegal;
618
        elsif wv(Instr_ECALL) = '1' then
619
            if i_mode = PRV_M then
620
                wb_exception_code(3 downto 0) := EXCEPTION_CallFromMmode;
621
            else
622
                wb_exception_code(3 downto 0) := EXCEPTION_CallFromUmode;
623
            end if;
624
        elsif wv(Instr_EBREAK) = '1' then
625
            v.breakpoint := '1';
626
            wb_exception_code(3 downto 0) := EXCEPTION_Breakpoint;
627
        else
628
            wb_exception_code(3 downto 0) := EXCEPTION_InstrIllegal;
629
        end if;
630
    elsif w_interrupt = '1' then
631
        v.trap_code_waiting := (others => '0');
632
    end if;
633
 
634
    w_d_valid :=
635
        (w_d_acceptable and (not w_interrupt) and (not w_exception)
636
         and (not w_multi_ena)) or w_multi_valid;
637
 
638
 
639
    v.trap_ena := '0';
640
    v.call := '0';
641
    v.ret := '0';
642
    if i_dport_npc_write = '1' then
643
        v.npc := i_dport_npc;
644
    elsif w_interrupt = '1' then
645
        v.trap_ena := '1';
646
        v.trap_pc := i_d_pc;
647
        v.trap_code := r.trap_code_waiting;
648
        v.npc := i_mtvec;
649
    elsif w_exception = '1' then
650
        v.trap_ena := '1';
651
        v.trap_pc := i_d_pc;
652
        v.trap_code := wb_exception_code;
653
        if wv(Instr_EBREAK) = '1' and i_break_mode = '0' then
654
            v.npc := i_d_pc;
655
        else
656
            v.npc := i_mtvec;
657
        end if;
658
    elsif w_d_valid = '1' then
659
        if w_multi_valid = '1' then
660
            v.pc := r.multi_pc;
661
            v.instr := r.multi_instr;
662
            v.npc := r.multi_npc;
663
            v.memop_load := '0';
664
            v.memop_sign_ext := '0';
665
            v.memop_store := '0';
666
            v.memop_size := (others => '0');
667
            v.memop_addr := (others => '0');
668
        else
669
            v.pc := i_d_pc;
670
            v.instr := i_d_instr;
671
            v.npc := wb_npc;
672
            v.memop_load := w_memop_load;
673
            v.memop_sign_ext := w_memop_sign_ext;
674
            v.memop_store := w_memop_store;
675
            v.memop_size := wb_memop_size;
676
            v.memop_addr := wb_memop_addr;
677
        end if;
678
        v.res_addr := wb_res_addr;
679
        v.res_val := wb_res;
680
 
681
        v.hazard_addr1 := r.hazard_addr0;
682
        v.hazard_addr0 := wb_res_addr;
683
 
684
        if wv(Instr_JAL) = '1' and conv_integer(wb_res_addr) = Reg_ra then
685
            v.call := '1';
686
        end if;
687
        if wv(Instr_JALR) = '1' then
688
            if conv_integer(wb_res_addr) = Reg_ra then
689
                v.call := '1';
690
            elsif wb_rdata2 = zero64 and conv_integer(wb_radr1) = Reg_ra then
691
                v.ret := '1';
692
            end if;
693
        end if;
694
    end if;
695
 
696
    v.d_valid := w_d_valid;
697
 
698
    if w_d_valid = '1' and i_wb_done = '0' then
699
        v.hazard_depth := r.hazard_depth + 1;
700
        v.hazard_addr0 := wb_res_addr;
701
    elsif w_d_valid = '0' and i_wb_done = '1' then
702
        v.hazard_depth := r.hazard_depth - 1;
703
    end if;
704
    w_hazard_lvl1 := '0';
705
    if (wb_radr1 /= "00000" and wb_radr1 = r.hazard_addr0) or
706
       (wb_radr2 /= "00000" and wb_radr2 = r.hazard_addr0) then
707
        w_hazard_lvl1 := '1';
708
    end if;
709
    w_hazard_lvl2 := '0';
710
    if (wb_radr1 /= "00000" and wb_radr1 = r.hazard_addr1) or
711
       (wb_radr2 /= "00000" and wb_radr2 = r.hazard_addr1) then
712
        w_hazard_lvl2 := '1';
713
    end if;
714
 
715
    if r.hazard_depth = "01" then
716
        w_hazard_detected <= w_hazard_lvl1;
717
    elsif r.hazard_depth = "10" then
718
        w_hazard_detected <= w_hazard_lvl1 or w_hazard_lvl2;
719
    else
720
        w_hazard_detected <= '0';
721
    end if;
722
 
723
    w_o_valid := r.d_valid;
724
    w_o_pipeline_hold := w_hazard_detected or r.multiclock_ena;
725
 
726
 
727
    if i_nrst = '0' then
728
        v.d_valid := '0';
729
        v.pc := (others => '0');
730
        v.npc := RESET_VECTOR;
731
        v.instr := (others => '0');
732
        v.res_addr := (others => '0');
733
        v.res_val := (others => '0');
734
        v.memop_load := '0';
735
        v.memop_sign_ext := '0';
736
        v.memop_store := '0';
737
        v.memop_size := (others => '0');
738
        v.memop_addr := (others => '0');
739
        v.hazard_depth := (others => '0');
740
        v.hazard_addr0 := (others => '0');
741
        v.hazard_addr1 := (others => '0');
742
 
743
        v.multiclock_ena := '0';
744
        v.multi_pc := (others => '0');
745
        v.multi_instr := (others => '0');
746
        v.multi_npc := (others => '0');
747
        v.multi_res_addr := (others => '0');
748
        v.multi_ena := (others => '0');
749
        v.multi_rv32 := '0';
750
        v.multi_unsigned := '0';
751
        v.multi_residual_high := '0';
752
        v.multi_a1 := (others => '0');
753
        v.multi_a2 := (others => '0');
754
 
755
        v.ext_irq_pulser := '0';
756
        v.trap_code_waiting := (others => '0');
757
        v.trap_ena := '0';
758
        v.trap_code := (others => '0');
759
        v.trap_pc := (others => '0');
760
        v.call := '0';
761
        v.ret := '0';
762
    end if;
763
 
764
    o_radr1 <= wb_radr1;
765
    o_radr2 <= wb_radr2;
766
    o_res_addr <= r.res_addr;
767
    o_res_data <= r.res_val;
768
    o_pipeline_hold <= w_o_pipeline_hold;
769
 
770
    o_xret <= w_xret;
771
    o_csr_wena <= w_csr_wena and w_pc_valid and not w_hazard_detected;
772
    o_csr_addr <= wb_csr_addr;
773
    o_csr_wdata <= wb_csr_wdata;
774
    o_trap_ena <= r.trap_ena;
775
    o_trap_code <= r.trap_code;
776
    o_trap_pc <= r.trap_pc;
777
 
778
    o_memop_sign_ext <= r.memop_sign_ext;
779
    o_memop_load <= r.memop_load;
780
    o_memop_store <= r.memop_store;
781
    o_memop_size <= r.memop_size;
782
    o_memop_addr <= r.memop_addr;
783
 
784
    o_valid <= w_o_valid;
785
    o_pc <= r.pc;
786
    o_npc <= r.npc;
787
    o_instr <= r.instr;
788
    o_breakpoint <= r.breakpoint;
789
    o_call <= r.call;
790
    o_ret <= r.ret;
791
 
792
    rin <= v;
793
  end process;
794
 
795
  -- registers:
796
  regs : process(i_clk)
797
  begin
798
     if rising_edge(i_clk) then
799
        r <= rin;
800
     end if;
801
  end process;
802
 
803
end;

powered by: WebSVN 2.1.0

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