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

Subversion Repositories altor32

[/] [altor32/] [trunk/] [rtl/] [cpu/] [altor32_exec.v] - Blame information for rev 32

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 27 ultra_embe
//-----------------------------------------------------------------
2
//                           AltOR32 
3
//                Alternative Lightweight OpenRisc 
4
//                            V2.0
5
//                     Ultra-Embedded.com
6
//                   Copyright 2011 - 2013
7
//
8
//               Email: admin@ultra-embedded.com
9
//
10
//                       License: LGPL
11
//-----------------------------------------------------------------
12
//
13
// Copyright (C) 2011 - 2013 Ultra-Embedded.com
14
//
15
// This source file may be used and distributed without         
16
// restriction provided that this copyright statement is not    
17
// removed from the file and that any derivative work contains  
18
// the original copyright notice and the associated disclaimer. 
19
//
20
// This source file is free software; you can redistribute it   
21
// and/or modify it under the terms of the GNU Lesser General   
22
// Public License as published by the Free Software Foundation; 
23
// either version 2.1 of the License, or (at your option) any   
24
// later version.
25
//
26
// This source is distributed in the hope that it will be       
27
// useful, but WITHOUT ANY WARRANTY; without even the implied   
28
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      
29
// PURPOSE.  See the GNU Lesser General Public License for more 
30
// details.
31
//
32
// You should have received a copy of the GNU Lesser General    
33
// Public License along with this source; if not, write to the 
34
// Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
35
// Boston, MA  02111-1307  USA
36
//-----------------------------------------------------------------
37
 
38
//`define CONF_CORE_DEBUG
39
//`define CONF_CORE_TRACE
40
 
41
//-----------------------------------------------------------------
42
// Includes
43
//-----------------------------------------------------------------
44
`include "altor32_defs.v"
45
 
46
//-----------------------------------------------------------------
47
// Module - Instruction Execute
48
//-----------------------------------------------------------------
49
module altor32_exec
50
(
51
    // General
52
    input               clk_i /*verilator public*/,
53
    input               rst_i /*verilator public*/,
54
 
55
    // Maskable interrupt    
56
    input               intr_i /*verilator public*/,
57
 
58
    // Unmaskable interrupt
59
    input               nmi_i /*verilator public*/,
60
 
61
    // Fault
62
    output reg          fault_o /*verilator public*/,
63
 
64
    // Breakpoint / Trap
65
    output reg          break_o /*verilator public*/,
66
 
67
    // Cache control
68
    output reg          icache_flush_o /*verilator public*/,
69
    output reg          dcache_flush_o /*verilator public*/,
70
 
71
    // Branch
72
    output              branch_o /*verilator public*/,
73
    output [31:0]       branch_pc_o /*verilator public*/,
74
    output              stall_o /*verilator public*/,
75
 
76
    // Opcode & arguments
77
    input [31:0]        opcode_i /*verilator public*/,
78
    input [31:0]        opcode_pc_i /*verilator public*/,
79
    input               opcode_valid_i /*verilator public*/,
80
 
81
    // Reg A
82
    input [4:0]         reg_ra_i /*verilator public*/,
83
    input [31:0]        reg_ra_value_i /*verilator public*/,
84
 
85
    // Reg B
86
    input [4:0]         reg_rb_i /*verilator public*/,
87
    input [31:0]        reg_rb_value_i /*verilator public*/,
88
 
89
    // Reg D
90
    input [4:0]         reg_rd_i /*verilator public*/,
91
 
92
    // Output
93
    output [31:0]       opcode_o /*verilator public*/,
94
    output [4:0]        reg_rd_o /*verilator public*/,
95
    output [31:0]       reg_rd_value_o /*verilator public*/,
96
    output              mult_o /*verilator public*/,
97
    output [31:0]       mult_res_o /*verilator public*/,
98
 
99
    // Register write back bypass
100
    input [4:0]         wb_rd_i /*verilator public*/,
101
    input [31:0]        wb_rd_value_i /*verilator public*/,
102
 
103
    // Memory Interface
104
    output reg [31:0]   dmem_addr_o /*verilator public*/,
105
    output reg [31:0]   dmem_data_out_o /*verilator public*/,
106
    input [31:0]        dmem_data_in_i /*verilator public*/,
107 32 ultra_embe
    output reg [3:0]    dmem_sel_o /*verilator public*/,
108
    output reg          dmem_we_o /*verilator public*/,
109
    output reg          dmem_stb_o /*verilator public*/,
110
    output reg          dmem_cyc_o /*verilator public*/,
111
    input               dmem_stall_i /*verilator public*/,
112 27 ultra_embe
    input               dmem_ack_i /*verilator public*/
113
);
114
 
115
//-----------------------------------------------------------------
116
// Params
117
//-----------------------------------------------------------------
118
parameter           BOOT_VECTOR         = 32'h00000000;
119
parameter           ISR_VECTOR          = 32'h00000000;
120
 
121
//-----------------------------------------------------------------
122
// Registers
123
//-----------------------------------------------------------------
124
 
125
// Branch PC
126
reg [31:0] r_pc_branch;
127
reg        r_pc_fetch;
128
reg        r_stall;
129
 
130
// Exception saved program counter
131
reg [31:0] r_epc;
132
 
133
// Supervisor register
134
reg [31:0] r_sr;
135
 
136
// Exception saved supervisor register
137
reg [31:0] r_esr;
138
 
139
// Destination register number (post execute stage)
140
reg [4:0] r_e_rd;
141
 
142
// Current opcode (PC for debug)
143
reg [31:0] r_e_opcode;
144
reg [31:0] r_e_opcode_pc;
145
 
146
// ALU input A
147
reg [31:0] r_e_alu_a;
148
 
149
// ALU input B
150
reg [31:0] r_e_alu_b;
151
 
152
// ALU output
153
wire [31:0] r_e_result;
154
 
155
// Resolved RA/RB register contents
156
wire [31:0] ra_value_resolved;
157
wire [31:0] rb_value_resolved;
158
wire        resolve_failed;
159
 
160
// ALU Carry
161
wire alu_carry_out;
162
wire alu_carry_update;
163
 
164
// ALU operation selection
165
reg [3:0] r_e_alu_func;
166
 
167
// Load instruction details
168
reg [4:0] r_load_rd;
169
reg [7:0] r_load_inst;
170
reg [1:0] r_load_offset;
171
 
172
// Load forwarding
173
wire         load_insn;
174
wire [31:0]  load_result;
175
 
176
// Memory access?
177
reg r_mem_load;
178
reg r_mem_store;
179
reg r_mem_access;
180
 
181
wire load_pending;
182
wire store_pending;
183
wire load_insert;
184
wire load_stall;
185
 
186
reg d_mem_load;
187
 
188
// Delayed NMI
189
reg r_nmi;
190
 
191 31 ultra_embe
// SIM PUTC
192
`ifdef SIM_EXT_PUTC
193
    reg [7:0] r_putc;
194
`endif
195
 
196 27 ultra_embe
//-----------------------------------------------------------------
197
// Instantiation
198
//-----------------------------------------------------------------
199
 
200
// ALU
201
altor32_alu alu
202
(
203
    // ALU operation select
204
    .op_i(r_e_alu_func),
205
 
206
    // Operands
207
    .a_i(r_e_alu_a),
208
    .b_i(r_e_alu_b),
209
    .c_i(r_sr[`OR32_SR_CY]),
210
 
211
    // Result
212
    .p_o(r_e_result),
213
 
214
    // Carry
215
    .c_o(alu_carry_out),
216
    .c_update_o(alu_carry_update)
217
);
218
 
219
// Load result forwarding
220
altor32_lfu
221
u_lfu
222
(
223
    // Opcode
224
    .opcode_i(r_load_inst),
225
 
226
    // Memory load result
227
    .mem_result_i(dmem_data_in_i),
228
    .mem_offset_i(r_load_offset),
229
 
230
    // Result
231
    .load_result_o(load_result),
232
    .load_insn_o(load_insn)
233
);
234
 
235
// Load / store pending logic
236
altor32_lsu
237
u_lsu
238
(
239
    // Current instruction
240
    .opcode_valid_i(opcode_valid_i & ~r_pc_fetch),
241
    .opcode_i({2'b00,opcode_i[31:26]}),
242
 
243
    // Load / Store pending
244
    .load_pending_i(r_mem_load),
245
    .store_pending_i(r_mem_store),
246
 
247
    // Load dest register
248
    .rd_load_i(r_load_rd),
249
 
250
    // Load insn in WB stage
251
    .load_wb_i(d_mem_load),
252
 
253
    // Memory status
254
    .mem_access_i(r_mem_access),
255
    .mem_ack_i(dmem_ack_i),
256
 
257
    // Load / store still pending
258
    .load_pending_o(load_pending),
259
    .store_pending_o(store_pending),
260
 
261
    // Insert load result into pipeline
262
    .write_result_o(load_insert),
263
 
264
    // Stall pipeline due
265
    .stall_o(load_stall)
266
);
267
 
268
// Operand forwarding
269
altor32_dfu
270
u_dfu
271
(
272
    // Input registers
273
    .ra_i(reg_ra_i),
274
    .rb_i(reg_rb_i),
275
 
276
    // Input register contents
277
    .ra_regval_i(reg_ra_value_i),
278
    .rb_regval_i(reg_rb_value_i),
279
 
280
    // Dest register (EXEC stage)
281
    .rd_ex_i(r_e_rd),
282
 
283
    // Dest register (WB stage)
284
    .rd_wb_i(wb_rd_i),
285
 
286
    // Load pending / target
287
    .load_pending_i(load_pending),
288
    .rd_load_i(r_load_rd),
289
 
290
    // Multiplier status
291
    .mult_lo_ex_i(1'b0),
292
    .mult_hi_ex_i(1'b0),
293
    .mult_lo_wb_i(1'b0),
294
    .mult_hi_wb_i(1'b0),
295
 
296
    // Multiplier result
297
    .result_mult_i(64'b0),
298
 
299
    // Result (EXEC)
300
    .result_ex_i(r_e_result),
301
 
302
    // Result (WB)
303
    .result_wb_i(wb_rd_value_i),
304
 
305
    // Resolved register values
306
    .result_ra_o(ra_value_resolved),
307
    .result_rb_o(rb_value_resolved),
308
 
309
    // Stall due to failed resolve
310
    .stall_o(resolve_failed)
311
);
312
 
313 31 ultra_embe
//-----------------------------------------------------------------
314
// Opcode decode
315
//-----------------------------------------------------------------
316
reg [7:0]  inst_r;
317
reg [7:0]  alu_op_r;
318
reg [1:0]  shift_op_r;
319
reg [15:0] sfxx_op_r;
320
reg [15:0] uint16_r;
321
reg [31:0] uint32_r;
322
reg [31:0] int32_r;
323
reg [31:0] store_int32_r;
324
reg [15:0] mxspr_uint16_r;
325
reg [31:0] target_int26_r;
326
reg [31:0] reg_ra_r;
327
reg [31:0] reg_rb_r;
328
reg [31:0] shift_rb_r;
329
reg [31:0] shift_imm_r;
330 27 ultra_embe
 
331 31 ultra_embe
always @ *
332 27 ultra_embe
begin
333 31 ultra_embe
    // Instruction
334
    inst_r               = {2'b00,opcode_i[31:26]};
335 27 ultra_embe
 
336 31 ultra_embe
    // Sub instructions
337
    alu_op_r             = {opcode_i[9:6],opcode_i[3:0]};
338
    sfxx_op_r            = {5'b00,opcode_i[31:21]};
339
    shift_op_r           = opcode_i[7:6];
340 27 ultra_embe
 
341 31 ultra_embe
    // Branch target
342
    target_int26_r       = sign_extend_imm26(opcode_i[25:0]);
343 27 ultra_embe
 
344 31 ultra_embe
    // Store immediate
345
    store_int32_r        = sign_extend_imm16({opcode_i[25:21],opcode_i[10:0]});
346 27 ultra_embe
 
347 31 ultra_embe
    // Signed & unsigned imm -> 32-bits
348
    uint16_r             = opcode_i[15:0];
349
    int32_r              = sign_extend_imm16(opcode_i[15:0]);
350
    uint32_r             = extend_imm16(opcode_i[15:0]);
351 27 ultra_embe
 
352 31 ultra_embe
    // Register values [ra/rb]
353
    reg_ra_r             = ra_value_resolved;
354
    reg_rb_r             = rb_value_resolved;
355 27 ultra_embe
 
356 31 ultra_embe
    // Shift ammount (from register[rb])
357
    shift_rb_r           = {26'b00,rb_value_resolved[5:0]};
358 27 ultra_embe
 
359 31 ultra_embe
    // Shift ammount (from immediate)
360
    shift_imm_r          = {26'b00,opcode_i[5:0]};
361 27 ultra_embe
 
362 31 ultra_embe
    // MTSPR/MFSPR operand
363
    mxspr_uint16_r       = (ra_value_resolved[15:0] | {5'b00000,opcode_i[10:0]});
364
end
365 27 ultra_embe
 
366 31 ultra_embe
//-----------------------------------------------------------------
367
// Instruction Decode
368
//-----------------------------------------------------------------
369
wire inst_add_w     = (inst_r == `INST_OR32_ALU) & (alu_op_r == `INST_OR32_ADD);  // l.add
370
wire inst_addc_w    = (inst_r == `INST_OR32_ALU) & (alu_op_r == `INST_OR32_ADDC); // l.addc
371
wire inst_and_w     = (inst_r == `INST_OR32_ALU) & (alu_op_r == `INST_OR32_AND);  // l.and
372
wire inst_or_w      = (inst_r == `INST_OR32_ALU) & (alu_op_r == `INST_OR32_OR);   // l.or
373
wire inst_sll_w     = (inst_r == `INST_OR32_ALU) & (alu_op_r == `INST_OR32_SLL);  // l.sll
374
wire inst_sra_w     = (inst_r == `INST_OR32_ALU) & (alu_op_r == `INST_OR32_SRA);  // l.sra
375
wire inst_srl_w     = (inst_r == `INST_OR32_ALU) & (alu_op_r == `INST_OR32_SRL);  // l.srl
376
wire inst_sub_w     = (inst_r == `INST_OR32_ALU) & (alu_op_r == `INST_OR32_SUB);  // l.sub
377
wire inst_xor_w     = (inst_r == `INST_OR32_ALU) & (alu_op_r == `INST_OR32_XOR);  // l.xor
378 27 ultra_embe
 
379 31 ultra_embe
wire inst_addi_w    = (inst_r == `INST_OR32_ADDI);  // l.addi
380
wire inst_andi_w    = (inst_r == `INST_OR32_ANDI);  // l.andi
381
wire inst_bf_w      = (inst_r == `INST_OR32_BF);    // l.bf
382
wire inst_bnf_w     = (inst_r == `INST_OR32_BNF);   // l.bnf
383
wire inst_j_w       = (inst_r == `INST_OR32_J);     // l.j
384
wire inst_jal_w     = (inst_r == `INST_OR32_JAL);   // l.jal
385
wire inst_jalr_w    = (inst_r == `INST_OR32_JALR);  // l.jalr
386
wire inst_jr_w      = (inst_r == `INST_OR32_JR);    // l.jr
387
wire inst_lbs_w     = (inst_r == `INST_OR32_LBS);   // l.lbs
388
wire inst_lhs_w     = (inst_r == `INST_OR32_LHS);   // l.lhs
389
wire inst_lws_w     = (inst_r == `INST_OR32_LWS);   // l.lws
390
wire inst_lbz_w     = (inst_r == `INST_OR32_LBZ);   // l.lbz
391
wire inst_lhz_w     = (inst_r == `INST_OR32_LHZ);   // l.lhz
392
wire inst_lwz_w     = (inst_r == `INST_OR32_LWZ);   // l.lwz
393
wire inst_mfspr_w   = (inst_r == `INST_OR32_MFSPR); // l.mfspr
394
wire inst_mtspr_w   = (inst_r == `INST_OR32_MTSPR); // l.mtspr
395
wire inst_movhi_w   = (inst_r == `INST_OR32_MOVHI); // l.movhi
396
wire inst_nop_w     = (inst_r == `INST_OR32_NOP);   // l.nop
397
wire inst_ori_w     = (inst_r == `INST_OR32_ORI);   // l.ori
398
wire inst_rfe_w     = (inst_r == `INST_OR32_RFE);   // l.rfe
399 27 ultra_embe
 
400 31 ultra_embe
wire inst_sb_w      = (inst_r == `INST_OR32_SB);    // l.sb
401
wire inst_sh_w      = (inst_r == `INST_OR32_SH);    // l.sh
402
wire inst_sw_w      = (inst_r == `INST_OR32_SW);    // l.sw
403 27 ultra_embe
 
404 31 ultra_embe
wire inst_slli_w    = (inst_r == `INST_OR32_SHIFTI) & (shift_op_r == `INST_OR32_SLLI);  // l.slli
405
wire inst_srai_w    = (inst_r == `INST_OR32_SHIFTI) & (shift_op_r == `INST_OR32_SRAI);  // l.srai
406
wire inst_srli_w    = (inst_r == `INST_OR32_SHIFTI) & (shift_op_r == `INST_OR32_SRLI);  // l.srli
407 27 ultra_embe
 
408 31 ultra_embe
wire inst_xori_w    = (inst_r == `INST_OR32_XORI);   // l.xori
409 27 ultra_embe
 
410 31 ultra_embe
wire inst_sfxx_w    = (inst_r == `INST_OR32_SFXX);
411
wire inst_sfxxi_w   = (inst_r == `INST_OR32_SFXXI);
412 27 ultra_embe
 
413 31 ultra_embe
wire inst_sfeq_w    = (inst_r == `INST_OR32_SFXX) & (sfxx_op_r == `INST_OR32_SFEQ);   // l.sfeq
414
wire inst_sfges_w   = (inst_r == `INST_OR32_SFXX) & (sfxx_op_r == `INST_OR32_SFGES);  // l.sfges
415 27 ultra_embe
 
416 31 ultra_embe
wire inst_sfgeu_w   = (inst_r == `INST_OR32_SFXX) & (sfxx_op_r == `INST_OR32_SFGEU);  // l.sfgeu
417
wire inst_sfgts_w   = (inst_r == `INST_OR32_SFXX) & (sfxx_op_r == `INST_OR32_SFGTS);  // l.sfgts
418
wire inst_sfgtu_w   = (inst_r == `INST_OR32_SFXX) & (sfxx_op_r == `INST_OR32_SFGTU);  // l.sfgtu
419
wire inst_sfles_w   = (inst_r == `INST_OR32_SFXX) & (sfxx_op_r == `INST_OR32_SFLES);  // l.sfles
420
wire inst_sfleu_w   = (inst_r == `INST_OR32_SFXX) & (sfxx_op_r == `INST_OR32_SFLEU);  // l.sfleu
421
wire inst_sflts_w   = (inst_r == `INST_OR32_SFXX) & (sfxx_op_r == `INST_OR32_SFLTS);  // l.sflts
422
wire inst_sfltu_w   = (inst_r == `INST_OR32_SFXX) & (sfxx_op_r == `INST_OR32_SFLTU);  // l.sfltu
423
wire inst_sfne_w    = (inst_r == `INST_OR32_SFXX) & (sfxx_op_r == `INST_OR32_SFNE);   // l.sfne
424 27 ultra_embe
 
425 31 ultra_embe
wire inst_sfeqi_w   = (inst_r == `INST_OR32_SFXXI) & (sfxx_op_r == `INST_OR32_SFEQI);  // l.sfeqi
426
wire inst_sfgesi_w  = (inst_r == `INST_OR32_SFXXI) & (sfxx_op_r == `INST_OR32_SFGESI); // l.sfgesi
427
wire inst_sfgeui_w  = (inst_r == `INST_OR32_SFXXI) & (sfxx_op_r == `INST_OR32_SFGEUI); // l.sfgeui
428
wire inst_sfgtsi_w  = (inst_r == `INST_OR32_SFXXI) & (sfxx_op_r == `INST_OR32_SFGTSI); // l.sfgtsi
429
wire inst_sfgtui_w  = (inst_r == `INST_OR32_SFXXI) & (sfxx_op_r == `INST_OR32_SFGTUI); // l.sfgtui
430
wire inst_sflesi_w  = (inst_r == `INST_OR32_SFXXI) & (sfxx_op_r == `INST_OR32_SFLESI); // l.sflesi
431 27 ultra_embe
 
432 31 ultra_embe
wire inst_sfleui_w  = (inst_r == `INST_OR32_SFXXI) & (sfxx_op_r == `INST_OR32_SFLEUI); // l.sfleui
433
wire inst_sfltsi_w  = (inst_r == `INST_OR32_SFXXI) & (sfxx_op_r == `INST_OR32_SFLTSI); // l.sfltsi
434
wire inst_sfltui_w  = (inst_r == `INST_OR32_SFXXI) & (sfxx_op_r == `INST_OR32_SFLTUI); // l.sfltui
435
wire inst_sfnei_w   = (inst_r == `INST_OR32_SFXXI) & (sfxx_op_r == `INST_OR32_SFNEI);  // l.sfnei
436 27 ultra_embe
 
437 31 ultra_embe
wire inst_sys_w     = (inst_r == `INST_OR32_MISC) & (opcode_i[31:24] == `INST_OR32_SYS);  // l.sys
438
wire inst_trap_w    = (inst_r == `INST_OR32_MISC) & (opcode_i[31:24] == `INST_OR32_TRAP); // l.trap
439 27 ultra_embe
 
440 31 ultra_embe
//-----------------------------------------------------------------
441
// Stall / Execute
442
//-----------------------------------------------------------------
443
reg execute_inst_r;
444
reg stall_inst_r;
445 27 ultra_embe
 
446 31 ultra_embe
always @ *
447
begin
448
    execute_inst_r  = 1'b1;
449
    stall_inst_r    = 1'b0;
450 27 ultra_embe
 
451 31 ultra_embe
    // No opcode ready or branch delay slot
452
    if (~opcode_valid_i | r_pc_fetch)
453
        execute_inst_r  = 1'b0;
454
    // Valid instruction, but load result / operand not ready
455
    else if (resolve_failed | load_stall)
456
        stall_inst_r    = 1'b1;
457
end
458 27 ultra_embe
 
459 31 ultra_embe
//-----------------------------------------------------------------
460
// Next PC
461
//-----------------------------------------------------------------
462
reg [31:0]  next_pc_r;
463 27 ultra_embe
 
464 31 ultra_embe
always @ *
465
begin
466
    // Next expected PC (current PC + 4)
467
    next_pc_r  = (opcode_pc_i + 4);
468
end
469 27 ultra_embe
 
470 31 ultra_embe
//-----------------------------------------------------------------
471
// Next SR
472
//-----------------------------------------------------------------
473
reg [31:0]  next_sr_r;
474
reg         compare_result_r;
475
always @ *
476
begin
477
    next_sr_r = r_sr;
478 27 ultra_embe
 
479 31 ultra_embe
    // Latch carry if updated
480
    if (alu_carry_update)
481
        next_sr_r[`OR32_SR_CY] = alu_carry_out;
482 27 ultra_embe
 
483 31 ultra_embe
    // If valid instruction, check if SR needs updating
484
    if (execute_inst_r & ~stall_inst_r)
485
    begin
486
      case (1'b1)
487
      inst_mtspr_w:
488
      begin
489
          case (mxspr_uint16_r)
490
          // SR - Supervision register
491
          `SPR_REG_SR:
492
          begin
493
              next_sr_r = reg_rb_r;
494 27 ultra_embe
 
495 31 ultra_embe
              // Don't store cache flush requests
496
              next_sr_r[`OR32_SR_ICACHE_FLUSH] = 1'b0;
497
              next_sr_r[`OR32_SR_DCACHE_FLUSH] = 1'b0;
498
          end
499
          default:
500
            ;
501
          endcase
502
      end
503
      inst_rfe_w:
504
          next_sr_r = r_esr;
505
      inst_sfxx_w,
506
      inst_sfxxi_w:
507
           next_sr_r[`OR32_SR_F] = compare_result_r;
508
      default:
509
        ;
510
      endcase
511
    end
512
end
513 27 ultra_embe
 
514 31 ultra_embe
//-----------------------------------------------------------------
515
// Next EPC/ESR
516
//-----------------------------------------------------------------
517
reg [31:0]  next_epc_r;
518
reg [31:0]  next_esr_r;
519 27 ultra_embe
 
520 31 ultra_embe
always @ *
521
begin
522
    next_epc_r = r_epc;
523
    next_esr_r = r_esr;
524
 
525
    case (1'b1)
526
    inst_mtspr_w: // l.mtspr
527
    begin
528
       case (mxspr_uint16_r)
529
           // EPCR - EPC Exception saved PC
530
           `SPR_REG_EPCR:   next_epc_r = reg_rb_r;
531 27 ultra_embe
 
532 31 ultra_embe
           // ESR - Exception saved SR
533
           `SPR_REG_ESR:    next_esr_r = reg_rb_r;
534
       endcase
535
    end
536
    default:
537
      ;
538
    endcase
539
end
540 27 ultra_embe
 
541 31 ultra_embe
//-----------------------------------------------------------------
542
// ALU inputs
543
//-----------------------------------------------------------------
544 27 ultra_embe
 
545 31 ultra_embe
// ALU operation selection
546
reg [3:0]  alu_func_r;
547 27 ultra_embe
 
548 31 ultra_embe
// ALU operands
549
reg [31:0] alu_input_a_r;
550
reg [31:0] alu_input_b_r;
551
reg        write_rd_r;
552 27 ultra_embe
 
553 31 ultra_embe
always @ *
554
begin
555
   alu_func_r     = `ALU_NONE;
556
   alu_input_a_r  = 32'b0;
557
   alu_input_b_r  = 32'b0;
558
   write_rd_r     = 1'b0;
559 27 ultra_embe
 
560 31 ultra_embe
   case (1'b1)
561 27 ultra_embe
 
562 31 ultra_embe
     inst_add_w: // l.add
563
     begin
564
       alu_func_r     = `ALU_ADD;
565
       alu_input_a_r  = reg_ra_r;
566
       alu_input_b_r  = reg_rb_r;
567
       write_rd_r     = 1'b1;
568
     end
569
 
570
     inst_addc_w: // l.addc
571
     begin
572
         alu_func_r     = `ALU_ADDC;
573
         alu_input_a_r  = reg_ra_r;
574
         alu_input_b_r  = reg_rb_r;
575
         write_rd_r     = 1'b1;
576
     end
577 27 ultra_embe
 
578 31 ultra_embe
     inst_and_w: // l.and
579
     begin
580
         alu_func_r     = `ALU_AND;
581
         alu_input_a_r  = reg_ra_r;
582
         alu_input_b_r  = reg_rb_r;
583
         write_rd_r     = 1'b1;
584
     end
585 27 ultra_embe
 
586 31 ultra_embe
     inst_or_w: // l.or
587
     begin
588
         alu_func_r     = `ALU_OR;
589
         alu_input_a_r  = reg_ra_r;
590
         alu_input_b_r  = reg_rb_r;
591
         write_rd_r     = 1'b1;
592
     end
593 27 ultra_embe
 
594 31 ultra_embe
     inst_sll_w: // l.sll
595
     begin
596
         alu_func_r     = `ALU_SHIFTL;
597
         alu_input_a_r  = reg_ra_r;
598
         alu_input_b_r  = shift_rb_r;
599
         write_rd_r     = 1'b1;
600
     end
601 27 ultra_embe
 
602 31 ultra_embe
     inst_sra_w: // l.sra
603
     begin
604
         alu_func_r     = `ALU_SHIRTR_ARITH;
605
         alu_input_a_r  = reg_ra_r;
606
         alu_input_b_r  = shift_rb_r;
607
         write_rd_r     = 1'b1;
608
     end
609 27 ultra_embe
 
610 31 ultra_embe
     inst_srl_w: // l.srl
611
     begin
612
         alu_func_r     = `ALU_SHIFTR;
613
         alu_input_a_r  = reg_ra_r;
614
         alu_input_b_r  = shift_rb_r;
615
         write_rd_r     = 1'b1;
616
     end
617 27 ultra_embe
 
618 31 ultra_embe
     inst_sub_w: // l.sub
619
     begin
620
         alu_func_r     = `ALU_SUB;
621
         alu_input_a_r  = reg_ra_r;
622
         alu_input_b_r  = reg_rb_r;
623
         write_rd_r     = 1'b1;
624
     end
625
 
626
     inst_xor_w: // l.xor
627
     begin
628
         alu_func_r     = `ALU_XOR;
629
         alu_input_a_r  = reg_ra_r;
630
         alu_input_b_r  = reg_rb_r;
631
         write_rd_r     = 1'b1;
632
     end
633
 
634
     inst_addi_w: // l.addi
635
     begin
636
         alu_func_r     = `ALU_ADD;
637
         alu_input_a_r  = reg_ra_r;
638
         alu_input_b_r  = int32_r;
639
         write_rd_r     = 1'b1;
640
     end
641
 
642
     inst_andi_w: // l.andi
643
     begin
644
         alu_func_r     = `ALU_AND;
645
         alu_input_a_r  = reg_ra_r;
646
         alu_input_b_r  = uint32_r;
647
         write_rd_r     = 1'b1;
648
     end
649
 
650
     inst_jal_w: // l.jal
651
     begin
652
         alu_input_a_r  = next_pc_r;
653
         write_rd_r     = 1'b1;
654
     end
655
 
656
     inst_jalr_w: // l.jalr
657
     begin
658
         alu_input_a_r  = next_pc_r;
659
         write_rd_r     = 1'b1;
660
     end
661
 
662
     inst_mfspr_w: // l.mfspr
663
     begin
664
        case (mxspr_uint16_r)
665
           // SR - Supervision register
666
           `SPR_REG_SR:
667 27 ultra_embe
           begin
668 31 ultra_embe
               alu_input_a_r = next_sr_r;
669
               write_rd_r    = 1'b1;
670 27 ultra_embe
           end
671
 
672 31 ultra_embe
           // EPCR - EPC Exception saved PC
673
           `SPR_REG_EPCR:
674 27 ultra_embe
           begin
675 31 ultra_embe
               alu_input_a_r  = r_epc;
676
               write_rd_r     = 1'b1;
677 27 ultra_embe
           end
678
 
679 31 ultra_embe
           // ESR - Exception saved SR
680
           `SPR_REG_ESR:
681 27 ultra_embe
           begin
682 31 ultra_embe
               alu_input_a_r  = r_esr;
683
               write_rd_r     = 1'b1;
684 27 ultra_embe
           end
685 31 ultra_embe
           default:
686
              ;
687
        endcase
688
     end
689 27 ultra_embe
 
690 31 ultra_embe
     inst_movhi_w: // l.movhi
691
     begin
692
         alu_input_a_r  = {uint16_r,16'h0000};
693
         write_rd_r     = 1'b1;
694
     end
695 27 ultra_embe
 
696 31 ultra_embe
     inst_ori_w: // l.ori
697
     begin
698
         alu_func_r     = `ALU_OR;
699
         alu_input_a_r  = reg_ra_r;
700
         alu_input_b_r  = uint32_r;
701
         write_rd_r     = 1'b1;
702
     end
703 27 ultra_embe
 
704 31 ultra_embe
     inst_slli_w: // l.slli
705
     begin
706
         alu_func_r     = `ALU_SHIFTL;
707
         alu_input_a_r  = reg_ra_r;
708
         alu_input_b_r  = shift_imm_r;
709
         write_rd_r     = 1'b1;
710
     end
711 27 ultra_embe
 
712 31 ultra_embe
     inst_srai_w: // l.srai
713
     begin
714
         alu_func_r     = `ALU_SHIRTR_ARITH;
715
         alu_input_a_r  = reg_ra_r;
716
         alu_input_b_r  = shift_imm_r;
717
         write_rd_r     = 1'b1;
718
     end
719 27 ultra_embe
 
720 31 ultra_embe
     inst_srli_w: // l.srli
721
     begin
722
         alu_func_r     = `ALU_SHIFTR;
723
         alu_input_a_r  = reg_ra_r;
724
         alu_input_b_r  = shift_imm_r;
725
         write_rd_r     = 1'b1;
726
     end
727 27 ultra_embe
 
728 31 ultra_embe
     // l.lbs l.lhs l.lws l.lbz l.lhz l.lwz
729
     inst_lbs_w,
730
     inst_lhs_w,
731
     inst_lws_w,
732
     inst_lbz_w,
733
     inst_lhz_w,
734
     inst_lwz_w:
735
          write_rd_r    = 1'b1;
736 27 ultra_embe
 
737 31 ultra_embe
     inst_xori_w: // l.xori
738
     begin
739
         alu_func_r     = `ALU_XOR;
740
         alu_input_a_r  = reg_ra_r;
741
         alu_input_b_r  = int32_r;
742
         write_rd_r     = 1'b1;
743
     end
744
     default:
745
        ;
746
   endcase
747
end
748 27 ultra_embe
 
749 31 ultra_embe
//-----------------------------------------------------------------
750
// Comparisons
751
//-----------------------------------------------------------------
752 32 ultra_embe
reg [31:0] compare_a_r;
753
reg [31:0] compare_b_r;
754 31 ultra_embe
always @ *
755
begin
756 32 ultra_embe
    compare_a_r = reg_ra_r;
757
    compare_b_r = reg_rb_r;
758
 
759
    case (1'b1)
760
    inst_sfeqi_w,  // l.sfeqi
761
    inst_sfgesi_w, // l.sfgesi
762
    inst_sfgeui_w, // l.sfgeui
763
    inst_sfgtsi_w, // l.sfgtsi
764
    inst_sfgtui_w, // l.sfgtui
765
    inst_sflesi_w, // l.sflesi
766
    inst_sfleui_w, // l.sfleui
767
    inst_sfltsi_w, // l.sfltsi
768
    inst_sfltui_w, // l.sfltui
769
    inst_sfnei_w:  // l.sfnei
770
        compare_b_r = int32_r;
771
    default:
772
        ;
773
    endcase
774
end
775
 
776
reg compare_equal_r;
777
reg compare_gts_r;
778
reg compare_gt_r;
779
reg compare_lts_r;
780
reg compare_lt_r;
781
always @ *
782
begin
783
    if (compare_a_r == compare_b_r)
784
        compare_equal_r = 1'b1;
785
    else
786
        compare_equal_r = 1'b0;
787
 
788
    compare_lts_r = less_than_signed(compare_a_r, compare_b_r);
789
 
790
    if (compare_a_r < compare_b_r)
791
        compare_lt_r = 1'b1;
792
    else
793
        compare_lt_r = 1'b0;
794
 
795
    // Greater than (signed)
796
    compare_gts_r = ~(compare_lts_r | compare_equal_r);
797
 
798
    if (compare_a_r > compare_b_r)
799
        compare_gt_r = 1'b1;
800
    else
801
        compare_gt_r = 1'b0;
802
end
803
 
804
always @ *
805
begin
806 31 ultra_embe
    compare_result_r = 1'b0;
807 27 ultra_embe
 
808 31 ultra_embe
    case (1'b1)
809 32 ultra_embe
    inst_sfeq_w, // l.sfeq
810 31 ultra_embe
    inst_sfeqi_w: // l.sfeqi
811 32 ultra_embe
        compare_result_r = compare_equal_r;
812 27 ultra_embe
 
813 32 ultra_embe
    inst_sfges_w,  // l.sfges
814 31 ultra_embe
    inst_sfgesi_w: // l.sfgesi
815 32 ultra_embe
        compare_result_r = compare_gts_r | compare_equal_r;
816 27 ultra_embe
 
817 32 ultra_embe
    inst_sfgeu_w,  // l.sfgeu
818 31 ultra_embe
    inst_sfgeui_w: // l.sfgeui
819 32 ultra_embe
        compare_result_r = compare_gt_r | compare_equal_r;
820 27 ultra_embe
 
821 32 ultra_embe
    inst_sfgts_w,  // l.sfgts
822 31 ultra_embe
    inst_sfgtsi_w: // l.sfgtsi
823 32 ultra_embe
        compare_result_r = compare_gts_r;
824 27 ultra_embe
 
825 32 ultra_embe
    inst_sfgtu_w,  // l.sfgtu
826 31 ultra_embe
    inst_sfgtui_w: // l.sfgtui
827 32 ultra_embe
        compare_result_r = compare_gt_r;
828 27 ultra_embe
 
829 32 ultra_embe
    inst_sfles_w,  // l.sfles
830 31 ultra_embe
    inst_sflesi_w: // l.sflesi
831 32 ultra_embe
        compare_result_r = compare_lts_r | compare_equal_r;
832 27 ultra_embe
 
833 32 ultra_embe
    inst_sfleu_w,  // l.sfleu
834 27 ultra_embe
 
835 31 ultra_embe
    inst_sfleui_w: // l.sfleui
836 32 ultra_embe
        compare_result_r = compare_lt_r | compare_equal_r;
837 27 ultra_embe
 
838 32 ultra_embe
    inst_sflts_w,  // l.sflts
839 27 ultra_embe
 
840 31 ultra_embe
    inst_sfltsi_w: // l.sfltsi
841 32 ultra_embe
        compare_result_r = compare_lts_r;
842 27 ultra_embe
 
843 32 ultra_embe
    inst_sfltu_w,  // l.sfltu
844 27 ultra_embe
 
845 31 ultra_embe
    inst_sfltui_w: // l.sfltui
846 32 ultra_embe
        compare_result_r = compare_lt_r;
847 27 ultra_embe
 
848 32 ultra_embe
    inst_sfne_w,  // l.sfne
849 27 ultra_embe
 
850 31 ultra_embe
    inst_sfnei_w: // l.sfnei
851 32 ultra_embe
        compare_result_r = ~compare_equal_r;
852 31 ultra_embe
    default:
853
        ;
854
    endcase
855
end
856 27 ultra_embe
 
857 31 ultra_embe
//-----------------------------------------------------------------
858
// Load/Store operation?
859
//-----------------------------------------------------------------
860
reg         load_inst_r;
861
reg         store_inst_r;
862
reg [31:0]  mem_addr_r;
863
always @ *
864
begin
865
    load_inst_r  = inst_lbs_w | inst_lhs_w | inst_lws_w |
866
                   inst_lbz_w | inst_lhz_w | inst_lwz_w;
867
    store_inst_r = inst_sb_w  | inst_sh_w  | inst_sw_w;
868 27 ultra_embe
 
869 31 ultra_embe
    // Memory address is relative to RA
870
    mem_addr_r = reg_ra_r + (store_inst_r ? store_int32_r : int32_r);
871
end
872 27 ultra_embe
 
873 31 ultra_embe
//-----------------------------------------------------------------
874
// Branches
875
//-----------------------------------------------------------------
876
reg         branch_r;
877
reg         branch_link_r;
878
reg [31:0]  branch_target_r;
879
reg         branch_except_r;
880 27 ultra_embe
 
881 31 ultra_embe
always @ *
882
begin
883 27 ultra_embe
 
884 31 ultra_embe
    branch_r        = 1'b0;
885
    branch_link_r   = 1'b0;
886
    branch_except_r = 1'b0;
887 27 ultra_embe
 
888 31 ultra_embe
    // Default branch target is relative to current PC
889
    branch_target_r = (opcode_pc_i + {target_int26_r[29:0],2'b00});
890 27 ultra_embe
 
891 31 ultra_embe
    case (1'b1)
892
    inst_bf_w: // l.bf
893
        branch_r      = r_sr[`OR32_SR_F];
894 27 ultra_embe
 
895 31 ultra_embe
    inst_bnf_w: // l.bnf
896
        branch_r      = ~r_sr[`OR32_SR_F];
897 27 ultra_embe
 
898 31 ultra_embe
    inst_j_w: // l.j
899
        branch_r      = 1'b1;
900 27 ultra_embe
 
901 31 ultra_embe
    inst_jal_w: // l.jal
902
    begin
903
        // Write to REG_9_LR
904
        branch_link_r = 1'b1;
905
        branch_r      = 1'b1;
906
    end
907 27 ultra_embe
 
908 31 ultra_embe
    inst_jalr_w: // l.jalr
909
    begin
910
        // Write to REG_9_LR
911
        branch_link_r   = 1'b1;
912
        branch_r        = 1'b1;
913
        branch_target_r = reg_rb_r;
914
    end
915 27 ultra_embe
 
916 31 ultra_embe
    inst_jr_w: // l.jr
917
    begin
918
        branch_r        = 1'b1;
919
        branch_target_r = reg_rb_r;
920
    end
921 27 ultra_embe
 
922 31 ultra_embe
    inst_rfe_w: // l.rfe
923
    begin
924
        branch_r        = 1'b1;
925
        branch_target_r = r_epc;
926
    end
927 27 ultra_embe
 
928 31 ultra_embe
    inst_sys_w: // l.sys
929
    begin
930
        branch_r        = 1'b1;
931
        branch_except_r = 1'b1;
932
        branch_target_r = ISR_VECTOR + `VECTOR_SYSCALL;
933
    end
934 27 ultra_embe
 
935 31 ultra_embe
    inst_trap_w: // l.trap
936
    begin
937
        branch_r        = 1'b1;
938
        branch_except_r = 1'b1;
939
        branch_target_r = ISR_VECTOR + `VECTOR_TRAP;
940
    end
941 27 ultra_embe
 
942 31 ultra_embe
    default:
943
        ;
944
    endcase
945
end
946
 
947
//-----------------------------------------------------------------
948
// Invalid instruction
949
//-----------------------------------------------------------------
950
reg invalid_inst_r;
951
 
952
always @ *
953
begin
954
    case (1'b1)
955
       inst_add_w,
956
       inst_addc_w,
957
       inst_and_w,
958
       inst_or_w,
959
       inst_sll_w,
960
       inst_sra_w,
961
       inst_srl_w,
962
       inst_sub_w,
963
       inst_xor_w,
964
       inst_addi_w,
965
       inst_andi_w,
966
       inst_bf_w,
967
       inst_bnf_w,
968
       inst_j_w,
969
       inst_jal_w,
970
       inst_jalr_w,
971
       inst_jr_w,
972
       inst_lbs_w,
973
       inst_lhs_w,
974
       inst_lws_w,
975
       inst_lbz_w,
976
       inst_lhz_w,
977
       inst_lwz_w,
978
       inst_mfspr_w,
979
       inst_mtspr_w,
980
       inst_movhi_w,
981
       inst_nop_w,
982
       inst_ori_w,
983
       inst_rfe_w,
984
       inst_sb_w,
985
       inst_sh_w,
986
       inst_sw_w,
987
       inst_xori_w,
988
       inst_slli_w,
989
       inst_srai_w,
990
       inst_srli_w,
991
       inst_sfeq_w,
992
       inst_sfeqi_w,
993
       inst_sfges_w,
994
       inst_sfgesi_w,
995
       inst_sfgeu_w,
996
       inst_sfgeui_w,
997
       inst_sfgts_w,
998
       inst_sfgtsi_w,
999
       inst_sfgtu_w,
1000
       inst_sfgtui_w,
1001
       inst_sfles_w,
1002
       inst_sflesi_w,
1003
       inst_sfleu_w,
1004
       inst_sfleui_w,
1005
       inst_sflts_w,
1006
       inst_sfltsi_w,
1007
       inst_sfltu_w,
1008
       inst_sfltui_w,
1009
       inst_sfne_w,
1010
       inst_sfnei_w,
1011
       inst_sys_w,
1012
       inst_trap_w:
1013
          invalid_inst_r = 1'b0;
1014
       default:
1015
          invalid_inst_r = 1'b1;
1016
    endcase
1017
end
1018
 
1019
//-----------------------------------------------------------------
1020
// Execute: ALU control
1021
//-----------------------------------------------------------------
1022
always @ (posedge clk_i or posedge rst_i)
1023
begin
1024
   if (rst_i == 1'b1)
1025
   begin
1026
       r_e_alu_func         <= `ALU_NONE;
1027
       r_e_alu_a            <= 32'h00000000;
1028
       r_e_alu_b            <= 32'h00000000;
1029
       r_e_rd               <= 5'b00000;
1030
   end
1031
   else
1032
   begin
1033
       //---------------------------------------------------------------
1034
       // Instruction not ready
1035
       //---------------------------------------------------------------
1036
       if (~execute_inst_r | stall_inst_r)
1037
       begin
1038
           // Insert load result?
1039
           if (load_insert)
1040 27 ultra_embe
           begin
1041 31 ultra_embe
               // Feed load result into pipeline
1042
               r_e_alu_func   <= `ALU_NONE;
1043
               r_e_alu_a      <= load_result;
1044
               r_e_alu_b      <= 32'b0;
1045
               r_e_rd         <= r_load_rd;
1046 27 ultra_embe
           end
1047 31 ultra_embe
           else
1048 27 ultra_embe
           begin
1049 31 ultra_embe
               // No ALU operation (output == input_a)
1050
               r_e_alu_func   <= `ALU_NONE;
1051
               r_e_alu_a      <= 32'b0;
1052
               r_e_alu_b      <= 32'b0;
1053
               r_e_rd         <= 5'b0;
1054 27 ultra_embe
           end
1055 31 ultra_embe
       end
1056 27 ultra_embe
       //---------------------------------------------------------------
1057 31 ultra_embe
       // Valid instruction
1058 27 ultra_embe
       //---------------------------------------------------------------
1059 31 ultra_embe
       else if (~invalid_inst_r)
1060
       begin
1061
           // Update ALU input flops
1062
           r_e_alu_func         <= alu_func_r;
1063
           r_e_alu_a            <= alu_input_a_r;
1064
           r_e_alu_b            <= alu_input_b_r;
1065 27 ultra_embe
 
1066 31 ultra_embe
           // Branch and link (Rd = LR/R9)
1067
           if (branch_link_r)
1068
              r_e_rd            <= 5'd9;
1069
           // Instruction with register writeback
1070
           else if (write_rd_r)
1071
              r_e_rd            <= reg_rd_i;
1072
           else
1073
              r_e_rd            <= 5'b0;
1074 27 ultra_embe
       end
1075 31 ultra_embe
   end
1076
end
1077
 
1078
//-----------------------------------------------------------------
1079
// Execute: Update executed PC / opcode
1080
//-----------------------------------------------------------------
1081
always @ (posedge clk_i or posedge rst_i)
1082
begin
1083
   if (rst_i == 1'b1)
1084
   begin
1085
       r_e_opcode           <= 32'h00000000;
1086
       r_e_opcode_pc        <= 32'h00000000;
1087
 
1088
       r_stall              <= 1'b0;
1089
   end
1090
   else
1091
   begin
1092
       r_stall              <= stall_inst_r;
1093
 
1094
       // Instruction not ready
1095
       if (~execute_inst_r | stall_inst_r)
1096 27 ultra_embe
       begin
1097 31 ultra_embe
           // Store bubble opcode
1098
           r_e_opcode            <= `OPCODE_INST_BUBBLE;
1099
           r_e_opcode_pc         <= opcode_pc_i;
1100
       end
1101
       // Valid instruction
1102
       else if (~invalid_inst_r)
1103 27 ultra_embe
       begin
1104 31 ultra_embe
           // Store opcode
1105
           r_e_opcode            <= opcode_i;
1106
           r_e_opcode_pc         <= opcode_pc_i;
1107 27 ultra_embe
 
1108 31 ultra_embe
        `ifdef CONF_CORE_TRACE
1109
           $display("%08x: Execute 0x%08x", opcode_pc_i, opcode_i);
1110
           $display(" rA[%d] = 0x%08x", reg_ra_i, reg_ra_r);
1111
           $display(" rB[%d] = 0x%08x", reg_rb_i, reg_rb_r);
1112
        `endif
1113 27 ultra_embe
       end
1114 31 ultra_embe
   end
1115
end
1116 27 ultra_embe
 
1117 31 ultra_embe
//-----------------------------------------------------------------
1118
// Execute: Branch / exceptions
1119
//-----------------------------------------------------------------
1120
always @ (posedge clk_i or posedge rst_i)
1121
begin
1122
   if (rst_i == 1'b1)
1123
   begin
1124
       r_pc_branch          <= 32'h00000000;
1125
       r_pc_fetch           <= 1'b0;
1126 27 ultra_embe
 
1127 31 ultra_embe
       // Status registers
1128
       r_epc                <= 32'h00000000;
1129
       r_sr                 <= 32'h00000000;
1130
       r_esr                <= 32'h00000000;
1131 27 ultra_embe
 
1132 31 ultra_embe
       fault_o              <= 1'b0;
1133 27 ultra_embe
 
1134 31 ultra_embe
       r_nmi                <= 1'b0;
1135
   end
1136
   else
1137
   begin
1138
      // Record NMI in-case it can't be processed this cycle
1139
      if (nmi_i)
1140
          r_nmi             <= 1'b1;
1141 27 ultra_embe
 
1142 31 ultra_embe
       // Reset branch request
1143
       r_pc_fetch           <= 1'b0;
1144 27 ultra_embe
 
1145 31 ultra_embe
       // Update SR
1146
       r_sr                 <= next_sr_r;
1147
 
1148
       // Instruction ready
1149
       if (execute_inst_r & ~stall_inst_r)
1150 27 ultra_embe
       begin
1151 31 ultra_embe
           // Exception: Instruction opcode not valid / supported, invalid PC
1152
           if (invalid_inst_r || (opcode_pc_i[1:0] != 2'b00))
1153
           begin
1154
                // Save PC of next instruction
1155
                r_epc       <= next_pc_r;
1156
                r_esr       <= next_sr_r;
1157 27 ultra_embe
 
1158 31 ultra_embe
                // Disable further interrupts
1159
                r_sr        <= 32'b0;
1160 27 ultra_embe
 
1161 31 ultra_embe
                // Set PC to exception vector
1162
                if (invalid_inst_r)
1163
                    r_pc_branch <= ISR_VECTOR + `VECTOR_ILLEGAL_INST;
1164
                else
1165
                    r_pc_branch <= ISR_VECTOR + `VECTOR_BUS_ERROR;
1166
                r_pc_fetch  <= 1'b1;
1167 27 ultra_embe
 
1168 31 ultra_embe
                fault_o     <= 1'b1;
1169
           end
1170
           // Exception: Syscall / Break
1171
           else if (branch_except_r)
1172
           begin
1173
                // Save PC of next instruction
1174
                r_epc       <= next_pc_r;
1175
                r_esr       <= next_sr_r;
1176
 
1177
                // Disable further interrupts
1178
                r_sr        <= 32'b0;
1179
 
1180
                // Set PC to exception vector
1181
                r_pc_branch <= branch_target_r;
1182
                r_pc_fetch  <= 1'b1;
1183
 
1184
    `ifdef CONF_CORE_DEBUG
1185
               $display(" Exception 0x%08x", branch_target_r);
1186
    `endif
1187
           end
1188
           // Non-maskable interrupt
1189
           else if (nmi_i | r_nmi)
1190
           begin
1191
                r_nmi       <= 1'b0;
1192
 
1193
                // Save PC of next instruction
1194
                if (branch_r)
1195
                    r_epc <= branch_target_r;
1196
                // Next expected PC (current PC + 4)
1197
                else
1198
                    r_epc <= next_pc_r;
1199
 
1200
                r_esr       <= next_sr_r;
1201
 
1202
                // Disable further interrupts
1203
                r_sr        <= 32'b0;
1204
 
1205
                // Set PC to exception vector
1206
                r_pc_branch <= ISR_VECTOR + `VECTOR_NMI;
1207
                r_pc_fetch  <= 1'b1;
1208
 
1209
    `ifdef CONF_CORE_DEBUG
1210
               $display(" NMI 0x%08x", ISR_VECTOR + `VECTOR_NMI);
1211
    `endif
1212
           end
1213
           // External interrupt
1214
           else if (intr_i && next_sr_r[`OR32_SR_IEE])
1215
           begin
1216
                // Save PC of next instruction & SR
1217
                if (branch_r)
1218
                    r_epc <= branch_target_r;
1219
                // Next expected PC (current PC + 4)
1220
                else
1221
                    r_epc <= next_pc_r;
1222
 
1223
                r_esr       <= next_sr_r;
1224
 
1225
                // Disable further interrupts
1226
                r_sr        <= 32'b0;
1227
 
1228
                // Set PC to external interrupt vector
1229
                r_pc_branch <= ISR_VECTOR + `VECTOR_EXTINT;
1230
                r_pc_fetch  <= 1'b1;
1231
 
1232
    `ifdef CONF_CORE_DEBUG
1233
               $display(" External Interrupt 0x%08x", ISR_VECTOR + `VECTOR_EXTINT);
1234
    `endif
1235
           end
1236
           // Branch (l.bf, l.bnf, l.j, l.jal, l.jr, l.jalr, l.rfe)
1237
           else if (branch_r)
1238
           begin
1239
                // Perform branch
1240
                r_pc_branch    <= branch_target_r;
1241
                r_pc_fetch     <= 1'b1;
1242
 
1243
    `ifdef CONF_CORE_DEBUG
1244
               $display(" Branch to 0x%08x", branch_target_r);
1245
    `endif
1246
           end
1247
           // Non branch
1248
           else
1249
           begin
1250
                // Update EPC / ESR which may have been updated
1251
                // by an MTSPR write
1252
                r_epc          <= next_epc_r;
1253
                r_esr          <= next_esr_r;
1254
           end
1255
      end
1256
   end
1257
end
1258
 
1259
//-----------------------------------------------------------------
1260
// Execute: Memory operations
1261
//-----------------------------------------------------------------
1262
always @ (posedge clk_i or posedge rst_i)
1263
begin
1264
   if (rst_i == 1'b1)
1265
   begin
1266
       // Data memory
1267
       dmem_addr_o          <= 32'h00000000;
1268
       dmem_data_out_o      <= 32'h00000000;
1269 32 ultra_embe
       dmem_we_o            <= 1'b0;
1270
       dmem_sel_o           <= 4'b0000;
1271
       dmem_stb_o           <= 1'b0;
1272
       dmem_cyc_o           <= 1'b0;
1273 27 ultra_embe
 
1274 31 ultra_embe
       r_mem_load           <= 1'b0;
1275
       r_mem_store          <= 1'b0;
1276
       r_mem_access         <= 1'b0;
1277
 
1278
       r_load_rd            <= 5'b00000;
1279
       r_load_inst          <= 8'h00;
1280
       r_load_offset        <= 2'b00;
1281
 
1282
       d_mem_load           <= 1'b0;
1283
   end
1284
   else
1285
   begin
1286
 
1287
       // If memory access accepted by slave
1288 32 ultra_embe
       if (~dmem_stall_i)
1289
           dmem_stb_o   <= 1'b0;
1290
 
1291
       if (dmem_ack_i)
1292
            dmem_cyc_o  <= 1'b0;
1293 31 ultra_embe
       r_mem_access     <= 1'b0;
1294
       d_mem_load       <= r_mem_access & r_mem_load;
1295
 
1296
       // Pending accesses
1297
       r_mem_load   <= load_pending;
1298
       r_mem_store  <= store_pending;
1299
 
1300
       //---------------------------------------------------------------
1301
       // Valid instruction
1302
       //---------------------------------------------------------------
1303
       if (execute_inst_r & ~stall_inst_r & ~invalid_inst_r)
1304 27 ultra_embe
       begin
1305 31 ultra_embe
           // Branch and link (Rd = LR/R9)
1306
           if (branch_link_r)
1307
           begin
1308
              // Load outstanding, check if result target is being
1309
              // overwritten (to avoid WAR hazard)
1310
              if (r_load_rd == 5'd9)
1311
                  // Ditch load result when it arrives
1312
                  r_load_rd     <= 5'b00000;
1313
           end
1314
           // Instruction with register writeback
1315
           else if (write_rd_r)
1316
           begin
1317
              // Load outstanding, check if result target is being
1318
              // overwritten (to avoid WAR hazard)
1319
              if (reg_rd_i == r_load_rd && ~load_inst_r)
1320
                  // Ditch load result when it arrives
1321
                  r_load_rd     <= 5'b00000;
1322
           end
1323
 
1324
           case (1'b1)
1325
 
1326
             // l.lbs l.lhs l.lws l.lbz l.lhz l.lwz
1327
             load_inst_r:
1328
             begin
1329
                 dmem_addr_o      <= mem_addr_r;
1330
                 dmem_data_out_o  <= 32'h00000000;
1331 32 ultra_embe
                 dmem_sel_o       <= 4'b1111;
1332
                 dmem_we_o        <= 1'b0;
1333
                 dmem_stb_o       <= 1'b1;
1334
                 dmem_cyc_o       <= 1'b1;
1335 31 ultra_embe
 
1336
                 // Mark load as pending
1337
                 r_mem_load      <= 1'b1;
1338
                 r_mem_access    <= 1'b1;
1339
 
1340
                 // Record target register
1341
                 r_load_rd        <= reg_rd_i;
1342
                 r_load_inst      <= inst_r;
1343
                 r_load_offset    <= mem_addr_r[1:0];
1344
 
1345
  `ifdef CONF_CORE_DEBUG
1346
                 $display(" Load from 0x%08x to R%d", mem_addr_r, reg_rd_i);
1347
  `endif
1348
             end
1349
 
1350
             inst_sb_w: // l.sb
1351
             begin
1352
                 dmem_addr_o <= mem_addr_r;
1353
                 r_mem_access <= 1'b1;
1354
                 case (mem_addr_r[1:0])
1355
                     2'b00 :
1356
                     begin
1357
                         dmem_data_out_o  <= {reg_rb_r[7:0],24'h000000};
1358 32 ultra_embe
                         dmem_sel_o       <= 4'b1000;
1359
                         dmem_we_o        <= 1'b1;
1360
                         dmem_stb_o       <= 1'b1;
1361
                         dmem_cyc_o       <= 1'b1;
1362 31 ultra_embe
                         r_mem_store      <= 1'b1;
1363
                     end
1364
                     2'b01 :
1365
                     begin
1366
                         dmem_data_out_o  <= {{8'h00,reg_rb_r[7:0]},16'h0000};
1367 32 ultra_embe
                         dmem_sel_o       <= 4'b0100;
1368
                         dmem_we_o        <= 1'b1;
1369
                         dmem_stb_o       <= 1'b1;
1370
                         dmem_cyc_o       <= 1'b1;
1371 31 ultra_embe
                         r_mem_store      <= 1'b1;
1372
                     end
1373
                     2'b10 :
1374
                     begin
1375
                         dmem_data_out_o  <= {{16'h0000,reg_rb_r[7:0]},8'h00};
1376 32 ultra_embe
                         dmem_sel_o       <= 4'b0010;
1377
                         dmem_we_o        <= 1'b1;
1378
                         dmem_stb_o       <= 1'b1;
1379
                         dmem_cyc_o       <= 1'b1;
1380 31 ultra_embe
                         r_mem_store      <= 1'b1;
1381
                     end
1382
                     2'b11 :
1383
                     begin
1384
                         dmem_data_out_o  <= {24'h000000,reg_rb_r[7:0]};
1385 32 ultra_embe
                         dmem_sel_o       <= 4'b0001;
1386
                         dmem_we_o        <= 1'b1;
1387
                         dmem_stb_o       <= 1'b1;
1388
                         dmem_cyc_o       <= 1'b1;
1389 31 ultra_embe
                         r_mem_store      <= 1'b1;
1390
                     end
1391
                     default :
1392 32 ultra_embe
                        ;
1393 31 ultra_embe
                 endcase
1394
             end
1395
 
1396
            inst_sh_w: // l.sh
1397 27 ultra_embe
            begin
1398 31 ultra_embe
                 dmem_addr_o <= mem_addr_r;
1399
                 r_mem_access <= 1'b1;
1400
                 case (mem_addr_r[1:0])
1401
                     2'b00 :
1402
                     begin
1403
                         dmem_data_out_o  <= {reg_rb_r[15:0],16'h0000};
1404 32 ultra_embe
                         dmem_sel_o       <= 4'b1100;
1405
                         dmem_we_o        <= 1'b1;
1406
                         dmem_stb_o       <= 1'b1;
1407
                         dmem_cyc_o       <= 1'b1;
1408 31 ultra_embe
                         r_mem_store      <= 1'b1;
1409
                     end
1410
                     2'b10 :
1411
                     begin
1412
                         dmem_data_out_o  <= {16'h0000,reg_rb_r[15:0]};
1413 32 ultra_embe
                         dmem_sel_o       <= 4'b0011;
1414
                         dmem_we_o        <= 1'b1;
1415
                         dmem_stb_o       <= 1'b1;
1416
                         dmem_cyc_o       <= 1'b1;
1417 31 ultra_embe
                         r_mem_store      <= 1'b1;
1418
                     end
1419
                     default :
1420 32 ultra_embe
                        ;
1421 31 ultra_embe
                 endcase
1422
            end
1423 27 ultra_embe
 
1424 31 ultra_embe
            inst_sw_w: // l.sw
1425
            begin
1426
                 dmem_addr_o      <= mem_addr_r;
1427
                 dmem_data_out_o  <= reg_rb_r;
1428 32 ultra_embe
                 dmem_sel_o       <= 4'b1111;
1429
                 dmem_we_o        <= 1'b1;
1430
                 dmem_stb_o       <= 1'b1;
1431
                 dmem_cyc_o       <= 1'b1;
1432 31 ultra_embe
                 r_mem_access     <= 1'b1;
1433
                 r_mem_store      <= 1'b1;
1434
 
1435
  `ifdef CONF_CORE_DEBUG
1436
                 $display(" Store R%d to 0x%08x = 0x%08x", reg_rb_i, {mem_addr_r[31:2],2'b00}, reg_rb_r);
1437
  `endif
1438 27 ultra_embe
            end
1439 31 ultra_embe
            default:
1440
                ;
1441
         endcase
1442
       end
1443
   end
1444
end
1445 27 ultra_embe
 
1446 31 ultra_embe
//-----------------------------------------------------------------
1447
// Execute: Misc operations
1448
//-----------------------------------------------------------------
1449
always @ (posedge clk_i or posedge rst_i)
1450
begin
1451
   if (rst_i == 1'b1)
1452
   begin
1453
       break_o              <= 1'b0;
1454
       icache_flush_o       <= 1'b0;
1455
       dcache_flush_o       <= 1'b0;
1456
   end
1457
   else
1458
   begin
1459
       break_o              <= 1'b0;
1460
       icache_flush_o       <= 1'b0;
1461
       dcache_flush_o       <= 1'b0;
1462
 
1463
       //---------------------------------------------------------------
1464
       // Valid instruction
1465
       //---------------------------------------------------------------
1466
       if (execute_inst_r & ~stall_inst_r & ~invalid_inst_r)
1467
       begin
1468
          case (1'b1)
1469
          inst_mtspr_w: // l.mtspr
1470
          begin
1471
               case (mxspr_uint16_r)
1472
                   // SR - Supervision register
1473
                   `SPR_REG_SR:
1474
                   begin
1475
                       // Cache flush request?
1476
                       icache_flush_o <= reg_rb_r[`OR32_SR_ICACHE_FLUSH];
1477
                       dcache_flush_o <= reg_rb_r[`OR32_SR_DCACHE_FLUSH];
1478
                   end
1479
               endcase
1480
          end
1481
 
1482
          inst_trap_w: // l.trap
1483
              break_o <= 1'b1;
1484
          default:
1485
              ;
1486
         endcase
1487 27 ultra_embe
       end
1488
   end
1489
end
1490
 
1491 31 ultra_embe
//-----------------------------------------------------------------
1492
// Execute: NOP (simulation) operations
1493
//-----------------------------------------------------------------
1494
`ifdef SIMULATION
1495
    always @ (posedge clk_i or posedge rst_i)
1496
    begin
1497
       if (rst_i == 1'b1)
1498
       begin
1499
    `ifdef SIM_EXT_PUTC
1500
          r_putc                <= 8'b0;
1501
    `endif
1502
       end
1503
       else
1504
       begin
1505
    `ifdef SIM_EXT_PUTC
1506
          r_putc                <= 8'b0;
1507
    `endif
1508
           //---------------------------------------------------------------
1509
           // Valid instruction
1510
           //---------------------------------------------------------------
1511
           if (execute_inst_r & ~stall_inst_r & ~invalid_inst_r)
1512
           begin
1513
 
1514
               case (1'b1)
1515
               inst_nop_w: // l.nop
1516
                begin
1517
                    case (uint16_r)
1518
                    // NOP_PUTC
1519
                    16'h0004:
1520
                    begin
1521
      `ifdef SIM_EXT_PUTC
1522
                      r_putc  <= reg_ra_r[7:0];
1523
      `else
1524
                      $write("%c", reg_ra_r[7:0]);
1525
      `endif
1526
                    end
1527
                    // NOP
1528
                    16'h0000: ;
1529
                    endcase
1530
                end
1531
                default:
1532
                    ;
1533
             endcase
1534
           end
1535
       end
1536
    end
1537
`endif
1538
 
1539 27 ultra_embe
//-------------------------------------------------------------------
1540
// Assignments
1541
//-------------------------------------------------------------------
1542
 
1543
assign branch_pc_o          = r_pc_branch;
1544
assign branch_o             = r_pc_fetch;
1545
assign stall_o              = r_stall;
1546
 
1547
assign opcode_o             = r_e_opcode;
1548
 
1549
assign reg_rd_o             = r_e_rd;
1550
assign reg_rd_value_o       = r_e_result;
1551
 
1552
assign mult_o               = 1'b0;
1553
assign mult_res_o           = 32'b0;
1554
 
1555
`include "altor32_funcs.v"
1556
 
1557
//-------------------------------------------------------------------
1558
// Hooks for debug
1559
//-------------------------------------------------------------------
1560
`ifdef verilator
1561
   function [31:0] get_opcode_ex;
1562
      // verilator public
1563
      get_opcode_ex = r_e_opcode;
1564
   endfunction
1565
   function [31:0] get_pc_ex;
1566
      // verilator public
1567
      get_pc_ex = r_e_opcode_pc;
1568
   endfunction
1569 31 ultra_embe
   function [7:0] get_putc;
1570
      // verilator public
1571
   `ifdef SIM_EXT_PUTC
1572
      get_putc = r_putc;
1573
   `else
1574
      get_putc = 8'b0;
1575
   `endif
1576
   endfunction
1577 32 ultra_embe
   function [0:0] get_reg_valid;
1578
      // verilator public
1579
      get_reg_valid = ~(resolve_failed | load_stall);
1580
   endfunction
1581
   function [4:0] get_reg_ra;
1582
      // verilator public
1583
      get_reg_ra = reg_ra_i;
1584
   endfunction
1585
   function [31:0] get_reg_ra_value;
1586
      // verilator public
1587
      get_reg_ra_value = ra_value_resolved;
1588
   endfunction
1589
   function [4:0] get_reg_rb;
1590
      // verilator public
1591
      get_reg_rb = reg_rb_i;
1592
   endfunction
1593
   function [31:0] get_reg_rb_value;
1594
      // verilator public
1595
      get_reg_rb_value = rb_value_resolved;
1596
   endfunction
1597 27 ultra_embe
`endif
1598
 
1599
endmodule

powered by: WebSVN 2.1.0

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