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

Subversion Repositories altor32

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

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_DEBUG_BUBBLE
40
//`define CONF_CORE_TRACE
41
//`define CONF_CORE_FAULT_ON_OPCODE0
42
 
43
//-----------------------------------------------------------------
44
// Includes
45
//-----------------------------------------------------------------
46
`include "altor32_defs.v"
47
 
48
//-----------------------------------------------------------------
49
// Module - Instruction Execute
50
//-----------------------------------------------------------------
51
module altor32_exec
52
(
53
    // General
54
    input               clk_i /*verilator public*/,
55
    input               rst_i /*verilator public*/,
56
 
57
    // Maskable interrupt    
58
    input               intr_i /*verilator public*/,
59
 
60
    // Unmaskable interrupt
61
    input               nmi_i /*verilator public*/,
62
 
63
    // Fault
64
    output reg          fault_o /*verilator public*/,
65
 
66
    // Breakpoint / Trap
67
    output reg          break_o /*verilator public*/,
68
 
69
    // Cache control
70
    output reg          icache_flush_o /*verilator public*/,
71
    output reg          dcache_flush_o /*verilator public*/,
72
 
73
    // Branch
74
    output              branch_o /*verilator public*/,
75
    output [31:0]       branch_pc_o /*verilator public*/,
76
    output              stall_o /*verilator public*/,
77
 
78
    // Opcode & arguments
79
    input [31:0]        opcode_i /*verilator public*/,
80
    input [31:0]        opcode_pc_i /*verilator public*/,
81
    input               opcode_valid_i /*verilator public*/,
82
 
83
    // Reg A
84
    input [4:0]         reg_ra_i /*verilator public*/,
85
    input [31:0]        reg_ra_value_i /*verilator public*/,
86
 
87
    // Reg B
88
    input [4:0]         reg_rb_i /*verilator public*/,
89
    input [31:0]        reg_rb_value_i /*verilator public*/,
90
 
91
    // Reg D
92
    input [4:0]         reg_rd_i /*verilator public*/,
93
 
94
    // Output
95
    output [31:0]       opcode_o /*verilator public*/,
96
    output [4:0]        reg_rd_o /*verilator public*/,
97
    output [31:0]       reg_rd_value_o /*verilator public*/,
98
    output              mult_o /*verilator public*/,
99
    output [31:0]       mult_res_o /*verilator public*/,
100
 
101
    // Register write back bypass
102
    input [4:0]         wb_rd_i /*verilator public*/,
103
    input [31:0]        wb_rd_value_i /*verilator public*/,
104
 
105
    // Memory Interface
106
    output reg [31:0]   dmem_addr_o /*verilator public*/,
107
    output reg [31:0]   dmem_data_out_o /*verilator public*/,
108
    input [31:0]        dmem_data_in_i /*verilator public*/,
109
    output reg [3:0]    dmem_wr_o /*verilator public*/,
110
    output reg          dmem_rd_o /*verilator public*/,
111
    input               dmem_accept_i /*verilator public*/,
112
    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
always @ *
753
begin
754
    compare_result_r = 1'b0;
755 27 ultra_embe
 
756 31 ultra_embe
    case (1'b1)
757
    inst_sfeq_w: // l.sfeq
758
    begin
759
        if (reg_ra_r == reg_rb_r)
760
            compare_result_r = 1'b1;
761
        else
762
            compare_result_r = 1'b0;
763
    end
764 27 ultra_embe
 
765 31 ultra_embe
    inst_sfeqi_w: // l.sfeqi
766
    begin
767
        if (reg_ra_r == int32_r)
768
            compare_result_r = 1'b1;
769
        else
770
            compare_result_r = 1'b0;
771
    end
772 27 ultra_embe
 
773 31 ultra_embe
    inst_sfges_w: // l.sfges
774
    begin
775
        if (greater_than_equal_signed(reg_ra_r, reg_rb_r) == 1'b1)
776
            compare_result_r = 1'b1;
777
        else
778
            compare_result_r = 1'b0;
779
    end
780 27 ultra_embe
 
781 31 ultra_embe
    inst_sfgesi_w: // l.sfgesi
782
    begin
783
        if (greater_than_equal_signed(reg_ra_r, int32_r) == 1'b1)
784
            compare_result_r = 1'b1;
785
        else
786
            compare_result_r = 1'b0;
787
    end
788 27 ultra_embe
 
789 31 ultra_embe
    inst_sfgeu_w: // l.sfgeu
790
    begin
791
        if (reg_ra_r >= reg_rb_r)
792
            compare_result_r = 1'b1;
793
        else
794
            compare_result_r = 1'b0;
795
    end
796 27 ultra_embe
 
797 31 ultra_embe
    inst_sfgeui_w: // l.sfgeui
798
    begin
799
        if (reg_ra_r >= int32_r)
800
            compare_result_r = 1'b1;
801
        else
802
            compare_result_r = 1'b0;
803
    end
804 27 ultra_embe
 
805 31 ultra_embe
    inst_sfgts_w: // l.sfgts
806
    begin
807
        if (greater_than_signed(reg_ra_r, reg_rb_r) == 1'b1)
808
            compare_result_r = 1'b1;
809
        else
810
            compare_result_r = 1'b0;
811
    end
812 27 ultra_embe
 
813 31 ultra_embe
    inst_sfgtsi_w: // l.sfgtsi
814
    begin
815
        if (greater_than_signed(reg_ra_r, int32_r) == 1'b1)
816
            compare_result_r = 1'b1;
817
        else
818
            compare_result_r = 1'b0;
819
    end
820 27 ultra_embe
 
821 31 ultra_embe
    inst_sfgtu_w: // l.sfgtu
822
    begin
823
        if (reg_ra_r > reg_rb_r)
824
            compare_result_r = 1'b1;
825
        else
826
            compare_result_r = 1'b0;
827
    end
828 27 ultra_embe
 
829 31 ultra_embe
    inst_sfgtui_w: // l.sfgtui
830
    begin
831
        if (reg_ra_r > int32_r)
832
            compare_result_r = 1'b1;
833
        else
834
            compare_result_r = 1'b0;
835
    end
836 27 ultra_embe
 
837 31 ultra_embe
    inst_sfles_w: // l.sfles
838
    begin
839
        if (less_than_equal_signed(reg_ra_r, reg_rb_r) == 1'b1)
840
            compare_result_r = 1'b1;
841
        else
842
            compare_result_r = 1'b0;
843
    end
844 27 ultra_embe
 
845 31 ultra_embe
    inst_sflesi_w: // l.sflesi
846
    begin
847
        if (less_than_equal_signed(reg_ra_r, int32_r) == 1'b1)
848
            compare_result_r = 1'b1;
849
        else
850
            compare_result_r = 1'b0;
851
    end
852 27 ultra_embe
 
853 31 ultra_embe
    inst_sfleu_w: // l.sfleu
854
    begin
855
        if (reg_ra_r <= reg_rb_r)
856
            compare_result_r = 1'b1;
857
        else
858
            compare_result_r = 1'b0;
859
    end
860 27 ultra_embe
 
861 31 ultra_embe
    inst_sfleui_w: // l.sfleui
862
    begin
863
        if (reg_ra_r <= int32_r)
864
            compare_result_r = 1'b1;
865
        else
866
            compare_result_r = 1'b0;
867
    end
868 27 ultra_embe
 
869 31 ultra_embe
    inst_sflts_w: // l.sflts
870
    begin
871
        if (less_than_signed(reg_ra_r, reg_rb_r) == 1'b1)
872
            compare_result_r = 1'b1;
873
        else
874
            compare_result_r = 1'b0;
875
    end
876 27 ultra_embe
 
877 31 ultra_embe
    inst_sfltsi_w: // l.sfltsi
878
    begin
879
        if (less_than_signed(reg_ra_r, int32_r) == 1'b1)
880
            compare_result_r = 1'b1;
881
        else
882
            compare_result_r = 1'b0;
883
    end
884 27 ultra_embe
 
885 31 ultra_embe
    inst_sfltu_w: // l.sfltu
886
    begin
887
        if (reg_ra_r < reg_rb_r)
888
            compare_result_r = 1'b1;
889
        else
890
            compare_result_r = 1'b0;
891
    end
892 27 ultra_embe
 
893 31 ultra_embe
    inst_sfltui_w: // l.sfltui
894
    begin
895
        if (reg_ra_r < int32_r)
896
            compare_result_r = 1'b1;
897
        else
898
            compare_result_r = 1'b0;
899
    end
900 27 ultra_embe
 
901 31 ultra_embe
    inst_sfne_w: // l.sfne
902
    begin
903
        if (reg_ra_r != reg_rb_r)
904
            compare_result_r = 1'b1;
905
        else
906
            compare_result_r = 1'b0;
907
    end
908 27 ultra_embe
 
909 31 ultra_embe
    inst_sfnei_w: // l.sfnei
910
    begin
911
        if (reg_ra_r != int32_r)
912
            compare_result_r = 1'b1;
913
        else
914
            compare_result_r = 1'b0;
915
    end
916
    default:
917
        ;
918
    endcase
919
end
920 27 ultra_embe
 
921 31 ultra_embe
//-----------------------------------------------------------------
922
// Load/Store operation?
923
//-----------------------------------------------------------------
924
reg         load_inst_r;
925
reg         store_inst_r;
926
reg [31:0]  mem_addr_r;
927
always @ *
928
begin
929
    load_inst_r  = inst_lbs_w | inst_lhs_w | inst_lws_w |
930
                   inst_lbz_w | inst_lhz_w | inst_lwz_w;
931
    store_inst_r = inst_sb_w  | inst_sh_w  | inst_sw_w;
932 27 ultra_embe
 
933 31 ultra_embe
    // Memory address is relative to RA
934
    mem_addr_r = reg_ra_r + (store_inst_r ? store_int32_r : int32_r);
935
end
936 27 ultra_embe
 
937 31 ultra_embe
//-----------------------------------------------------------------
938
// Branches
939
//-----------------------------------------------------------------
940
reg         branch_r;
941
reg         branch_link_r;
942
reg [31:0]  branch_target_r;
943
reg         branch_except_r;
944 27 ultra_embe
 
945 31 ultra_embe
always @ *
946
begin
947 27 ultra_embe
 
948 31 ultra_embe
    branch_r        = 1'b0;
949
    branch_link_r   = 1'b0;
950
    branch_except_r = 1'b0;
951 27 ultra_embe
 
952 31 ultra_embe
    // Default branch target is relative to current PC
953
    branch_target_r = (opcode_pc_i + {target_int26_r[29:0],2'b00});
954 27 ultra_embe
 
955 31 ultra_embe
    case (1'b1)
956
    inst_bf_w: // l.bf
957
        branch_r      = r_sr[`OR32_SR_F];
958 27 ultra_embe
 
959 31 ultra_embe
    inst_bnf_w: // l.bnf
960
        branch_r      = ~r_sr[`OR32_SR_F];
961 27 ultra_embe
 
962 31 ultra_embe
    inst_j_w: // l.j
963
        branch_r      = 1'b1;
964 27 ultra_embe
 
965 31 ultra_embe
    inst_jal_w: // l.jal
966
    begin
967
        // Write to REG_9_LR
968
        branch_link_r = 1'b1;
969
        branch_r      = 1'b1;
970
    end
971 27 ultra_embe
 
972 31 ultra_embe
    inst_jalr_w: // l.jalr
973
    begin
974
        // Write to REG_9_LR
975
        branch_link_r   = 1'b1;
976
        branch_r        = 1'b1;
977
        branch_target_r = reg_rb_r;
978
    end
979 27 ultra_embe
 
980 31 ultra_embe
    inst_jr_w: // l.jr
981
    begin
982
        branch_r        = 1'b1;
983
        branch_target_r = reg_rb_r;
984
    end
985 27 ultra_embe
 
986 31 ultra_embe
    inst_rfe_w: // l.rfe
987
    begin
988
        branch_r        = 1'b1;
989
        branch_target_r = r_epc;
990
    end
991 27 ultra_embe
 
992 31 ultra_embe
    inst_sys_w: // l.sys
993
    begin
994
        branch_r        = 1'b1;
995
        branch_except_r = 1'b1;
996
        branch_target_r = ISR_VECTOR + `VECTOR_SYSCALL;
997
    end
998 27 ultra_embe
 
999 31 ultra_embe
    inst_trap_w: // l.trap
1000
    begin
1001
        branch_r        = 1'b1;
1002
        branch_except_r = 1'b1;
1003
        branch_target_r = ISR_VECTOR + `VECTOR_TRAP;
1004
    end
1005 27 ultra_embe
 
1006 31 ultra_embe
    default:
1007
        ;
1008
    endcase
1009
end
1010
 
1011
//-----------------------------------------------------------------
1012
// Invalid instruction
1013
//-----------------------------------------------------------------
1014
reg invalid_inst_r;
1015
 
1016
always @ *
1017
begin
1018
    case (1'b1)
1019
       inst_add_w,
1020
       inst_addc_w,
1021
       inst_and_w,
1022
       inst_or_w,
1023
       inst_sll_w,
1024
       inst_sra_w,
1025
       inst_srl_w,
1026
       inst_sub_w,
1027
       inst_xor_w,
1028
       inst_addi_w,
1029
       inst_andi_w,
1030
       inst_bf_w,
1031
       inst_bnf_w,
1032
       inst_j_w,
1033
       inst_jal_w,
1034
       inst_jalr_w,
1035
       inst_jr_w,
1036
       inst_lbs_w,
1037
       inst_lhs_w,
1038
       inst_lws_w,
1039
       inst_lbz_w,
1040
       inst_lhz_w,
1041
       inst_lwz_w,
1042
       inst_mfspr_w,
1043
       inst_mtspr_w,
1044
       inst_movhi_w,
1045
       inst_nop_w,
1046
       inst_ori_w,
1047
       inst_rfe_w,
1048
       inst_sb_w,
1049
       inst_sh_w,
1050
       inst_sw_w,
1051
       inst_xori_w,
1052
       inst_slli_w,
1053
       inst_srai_w,
1054
       inst_srli_w,
1055
       inst_sfeq_w,
1056
       inst_sfeqi_w,
1057
       inst_sfges_w,
1058
       inst_sfgesi_w,
1059
       inst_sfgeu_w,
1060
       inst_sfgeui_w,
1061
       inst_sfgts_w,
1062
       inst_sfgtsi_w,
1063
       inst_sfgtu_w,
1064
       inst_sfgtui_w,
1065
       inst_sfles_w,
1066
       inst_sflesi_w,
1067
       inst_sfleu_w,
1068
       inst_sfleui_w,
1069
       inst_sflts_w,
1070
       inst_sfltsi_w,
1071
       inst_sfltu_w,
1072
       inst_sfltui_w,
1073
       inst_sfne_w,
1074
       inst_sfnei_w,
1075
       inst_sys_w,
1076
       inst_trap_w:
1077
          invalid_inst_r = 1'b0;
1078
       default:
1079
          invalid_inst_r = 1'b1;
1080
    endcase
1081
end
1082
 
1083
//-----------------------------------------------------------------
1084
// Execute: ALU control
1085
//-----------------------------------------------------------------
1086
always @ (posedge clk_i or posedge rst_i)
1087
begin
1088
   if (rst_i == 1'b1)
1089
   begin
1090
       r_e_alu_func         <= `ALU_NONE;
1091
       r_e_alu_a            <= 32'h00000000;
1092
       r_e_alu_b            <= 32'h00000000;
1093
       r_e_rd               <= 5'b00000;
1094
   end
1095
   else
1096
   begin
1097
       //---------------------------------------------------------------
1098
       // Instruction not ready
1099
       //---------------------------------------------------------------
1100
       if (~execute_inst_r | stall_inst_r)
1101
       begin
1102
           // Insert load result?
1103
           if (load_insert)
1104 27 ultra_embe
           begin
1105 31 ultra_embe
               // Feed load result into pipeline
1106
               r_e_alu_func   <= `ALU_NONE;
1107
               r_e_alu_a      <= load_result;
1108
               r_e_alu_b      <= 32'b0;
1109
               r_e_rd         <= r_load_rd;
1110 27 ultra_embe
           end
1111 31 ultra_embe
           else
1112 27 ultra_embe
           begin
1113 31 ultra_embe
               // No ALU operation (output == input_a)
1114
               r_e_alu_func   <= `ALU_NONE;
1115
               r_e_alu_a      <= 32'b0;
1116
               r_e_alu_b      <= 32'b0;
1117
               r_e_rd         <= 5'b0;
1118 27 ultra_embe
           end
1119 31 ultra_embe
       end
1120 27 ultra_embe
       //---------------------------------------------------------------
1121 31 ultra_embe
       // Valid instruction
1122 27 ultra_embe
       //---------------------------------------------------------------
1123 31 ultra_embe
       else if (~invalid_inst_r)
1124
       begin
1125
           // Update ALU input flops
1126
           r_e_alu_func         <= alu_func_r;
1127
           r_e_alu_a            <= alu_input_a_r;
1128
           r_e_alu_b            <= alu_input_b_r;
1129 27 ultra_embe
 
1130 31 ultra_embe
           // Branch and link (Rd = LR/R9)
1131
           if (branch_link_r)
1132
              r_e_rd            <= 5'd9;
1133
           // Instruction with register writeback
1134
           else if (write_rd_r)
1135
              r_e_rd            <= reg_rd_i;
1136
           else
1137
              r_e_rd            <= 5'b0;
1138 27 ultra_embe
       end
1139 31 ultra_embe
   end
1140
end
1141
 
1142
//-----------------------------------------------------------------
1143
// Execute: Update executed PC / opcode
1144
//-----------------------------------------------------------------
1145
always @ (posedge clk_i or posedge rst_i)
1146
begin
1147
   if (rst_i == 1'b1)
1148
   begin
1149
       r_e_opcode           <= 32'h00000000;
1150
       r_e_opcode_pc        <= 32'h00000000;
1151
 
1152
       r_stall              <= 1'b0;
1153
   end
1154
   else
1155
   begin
1156
       r_stall              <= stall_inst_r;
1157
 
1158
       // Instruction not ready
1159
       if (~execute_inst_r | stall_inst_r)
1160 27 ultra_embe
       begin
1161 31 ultra_embe
           // Store bubble opcode
1162
           r_e_opcode            <= `OPCODE_INST_BUBBLE;
1163
           r_e_opcode_pc         <= opcode_pc_i;
1164
       end
1165
       // Valid instruction
1166
       else if (~invalid_inst_r)
1167 27 ultra_embe
       begin
1168 31 ultra_embe
           // Store opcode
1169
           r_e_opcode            <= opcode_i;
1170
           r_e_opcode_pc         <= opcode_pc_i;
1171 27 ultra_embe
 
1172 31 ultra_embe
        `ifdef CONF_CORE_TRACE
1173
           $display("%08x: Execute 0x%08x", opcode_pc_i, opcode_i);
1174
           $display(" rA[%d] = 0x%08x", reg_ra_i, reg_ra_r);
1175
           $display(" rB[%d] = 0x%08x", reg_rb_i, reg_rb_r);
1176
        `endif
1177 27 ultra_embe
       end
1178 31 ultra_embe
   end
1179
end
1180 27 ultra_embe
 
1181 31 ultra_embe
//-----------------------------------------------------------------
1182
// Execute: Branch / exceptions
1183
//-----------------------------------------------------------------
1184
always @ (posedge clk_i or posedge rst_i)
1185
begin
1186
   if (rst_i == 1'b1)
1187
   begin
1188
       r_pc_branch          <= 32'h00000000;
1189
       r_pc_fetch           <= 1'b0;
1190 27 ultra_embe
 
1191 31 ultra_embe
       // Status registers
1192
       r_epc                <= 32'h00000000;
1193
       r_sr                 <= 32'h00000000;
1194
       r_esr                <= 32'h00000000;
1195 27 ultra_embe
 
1196 31 ultra_embe
       fault_o              <= 1'b0;
1197 27 ultra_embe
 
1198 31 ultra_embe
       r_nmi                <= 1'b0;
1199
   end
1200
   else
1201
   begin
1202
      // Record NMI in-case it can't be processed this cycle
1203
      if (nmi_i)
1204
          r_nmi             <= 1'b1;
1205 27 ultra_embe
 
1206 31 ultra_embe
       // Reset branch request
1207
       r_pc_fetch           <= 1'b0;
1208 27 ultra_embe
 
1209 31 ultra_embe
       // Update SR
1210
       r_sr                 <= next_sr_r;
1211
 
1212
       // Instruction ready
1213
       if (execute_inst_r & ~stall_inst_r)
1214 27 ultra_embe
       begin
1215 31 ultra_embe
           // Exception: Instruction opcode not valid / supported, invalid PC
1216
           if (invalid_inst_r || (opcode_pc_i[1:0] != 2'b00))
1217
           begin
1218
                // Save PC of next instruction
1219
                r_epc       <= next_pc_r;
1220
                r_esr       <= next_sr_r;
1221 27 ultra_embe
 
1222 31 ultra_embe
                // Disable further interrupts
1223
                r_sr        <= 32'b0;
1224 27 ultra_embe
 
1225 31 ultra_embe
                // Set PC to exception vector
1226
                if (invalid_inst_r)
1227
                    r_pc_branch <= ISR_VECTOR + `VECTOR_ILLEGAL_INST;
1228
                else
1229
                    r_pc_branch <= ISR_VECTOR + `VECTOR_BUS_ERROR;
1230
                r_pc_fetch  <= 1'b1;
1231 27 ultra_embe
 
1232 31 ultra_embe
                fault_o     <= 1'b1;
1233
           end
1234
           // Exception: Syscall / Break
1235
           else if (branch_except_r)
1236
           begin
1237
                // Save PC of next instruction
1238
                r_epc       <= next_pc_r;
1239
                r_esr       <= next_sr_r;
1240
 
1241
                // Disable further interrupts
1242
                r_sr        <= 32'b0;
1243
 
1244
                // Set PC to exception vector
1245
                r_pc_branch <= branch_target_r;
1246
                r_pc_fetch  <= 1'b1;
1247
 
1248
    `ifdef CONF_CORE_DEBUG
1249
               $display(" Exception 0x%08x", branch_target_r);
1250
    `endif
1251
           end
1252
           // Non-maskable interrupt
1253
           else if (nmi_i | r_nmi)
1254
           begin
1255
                r_nmi       <= 1'b0;
1256
 
1257
                // Save PC of next instruction
1258
                if (branch_r)
1259
                    r_epc <= branch_target_r;
1260
                // Next expected PC (current PC + 4)
1261
                else
1262
                    r_epc <= next_pc_r;
1263
 
1264
                r_esr       <= next_sr_r;
1265
 
1266
                // Disable further interrupts
1267
                r_sr        <= 32'b0;
1268
 
1269
                // Set PC to exception vector
1270
                r_pc_branch <= ISR_VECTOR + `VECTOR_NMI;
1271
                r_pc_fetch  <= 1'b1;
1272
 
1273
    `ifdef CONF_CORE_DEBUG
1274
               $display(" NMI 0x%08x", ISR_VECTOR + `VECTOR_NMI);
1275
    `endif
1276
           end
1277
           // External interrupt
1278
           else if (intr_i && next_sr_r[`OR32_SR_IEE])
1279
           begin
1280
                // Save PC of next instruction & SR
1281
                if (branch_r)
1282
                    r_epc <= branch_target_r;
1283
                // Next expected PC (current PC + 4)
1284
                else
1285
                    r_epc <= next_pc_r;
1286
 
1287
                r_esr       <= next_sr_r;
1288
 
1289
                // Disable further interrupts
1290
                r_sr        <= 32'b0;
1291
 
1292
                // Set PC to external interrupt vector
1293
                r_pc_branch <= ISR_VECTOR + `VECTOR_EXTINT;
1294
                r_pc_fetch  <= 1'b1;
1295
 
1296
    `ifdef CONF_CORE_DEBUG
1297
               $display(" External Interrupt 0x%08x", ISR_VECTOR + `VECTOR_EXTINT);
1298
    `endif
1299
           end
1300
           // Branch (l.bf, l.bnf, l.j, l.jal, l.jr, l.jalr, l.rfe)
1301
           else if (branch_r)
1302
           begin
1303
                // Perform branch
1304
                r_pc_branch    <= branch_target_r;
1305
                r_pc_fetch     <= 1'b1;
1306
 
1307
    `ifdef CONF_CORE_DEBUG
1308
               $display(" Branch to 0x%08x", branch_target_r);
1309
    `endif
1310
           end
1311
           // Non branch
1312
           else
1313
           begin
1314
                // Update EPC / ESR which may have been updated
1315
                // by an MTSPR write
1316
                r_epc          <= next_epc_r;
1317
                r_esr          <= next_esr_r;
1318
           end
1319
      end
1320
   end
1321
end
1322
 
1323
//-----------------------------------------------------------------
1324
// Execute: Memory operations
1325
//-----------------------------------------------------------------
1326
always @ (posedge clk_i or posedge rst_i)
1327
begin
1328
   if (rst_i == 1'b1)
1329
   begin
1330
       // Data memory
1331
       dmem_addr_o          <= 32'h00000000;
1332
       dmem_data_out_o      <= 32'h00000000;
1333
       dmem_rd_o            <= 1'b0;
1334
       dmem_wr_o            <= 4'b0000;
1335 27 ultra_embe
 
1336 31 ultra_embe
       r_mem_load           <= 1'b0;
1337
       r_mem_store          <= 1'b0;
1338
       r_mem_access         <= 1'b0;
1339
 
1340
       r_load_rd            <= 5'b00000;
1341
       r_load_inst          <= 8'h00;
1342
       r_load_offset        <= 2'b00;
1343
 
1344
       d_mem_load           <= 1'b0;
1345
   end
1346
   else
1347
   begin
1348
 
1349
       // If memory access accepted by slave
1350
       if (dmem_accept_i)
1351 27 ultra_embe
       begin
1352 31 ultra_embe
           dmem_rd_o            <= 1'b0;
1353
           dmem_wr_o            <= 4'b0000;
1354 27 ultra_embe
       end
1355 31 ultra_embe
 
1356
       r_mem_access     <= 1'b0;
1357
       d_mem_load       <= r_mem_access & r_mem_load;
1358
 
1359
       // Pending accesses
1360
       r_mem_load   <= load_pending;
1361
       r_mem_store  <= store_pending;
1362
 
1363
       //---------------------------------------------------------------
1364
       // Valid instruction
1365
       //---------------------------------------------------------------
1366
       if (execute_inst_r & ~stall_inst_r & ~invalid_inst_r)
1367 27 ultra_embe
       begin
1368 31 ultra_embe
           // Branch and link (Rd = LR/R9)
1369
           if (branch_link_r)
1370
           begin
1371
              // Load outstanding, check if result target is being
1372
              // overwritten (to avoid WAR hazard)
1373
              if (r_load_rd == 5'd9)
1374
                  // Ditch load result when it arrives
1375
                  r_load_rd     <= 5'b00000;
1376
           end
1377
           // Instruction with register writeback
1378
           else if (write_rd_r)
1379
           begin
1380
              // Load outstanding, check if result target is being
1381
              // overwritten (to avoid WAR hazard)
1382
              if (reg_rd_i == r_load_rd && ~load_inst_r)
1383
                  // Ditch load result when it arrives
1384
                  r_load_rd     <= 5'b00000;
1385
           end
1386
 
1387
           case (1'b1)
1388
 
1389
             // l.lbs l.lhs l.lws l.lbz l.lhz l.lwz
1390
             load_inst_r:
1391
             begin
1392
                 dmem_addr_o      <= mem_addr_r;
1393
                 dmem_data_out_o  <= 32'h00000000;
1394
                 dmem_rd_o        <= 1'b1;
1395
 
1396
                 // Mark load as pending
1397
                 r_mem_load      <= 1'b1;
1398
                 r_mem_access    <= 1'b1;
1399
 
1400
                 // Record target register
1401
                 r_load_rd        <= reg_rd_i;
1402
                 r_load_inst      <= inst_r;
1403
                 r_load_offset    <= mem_addr_r[1:0];
1404
 
1405
  `ifdef CONF_CORE_DEBUG
1406
                 $display(" Load from 0x%08x to R%d", mem_addr_r, reg_rd_i);
1407
  `endif
1408
             end
1409
 
1410
             inst_sb_w: // l.sb
1411
             begin
1412
                 dmem_addr_o <= mem_addr_r;
1413
                 r_mem_access <= 1'b1;
1414
                 case (mem_addr_r[1:0])
1415
                     2'b00 :
1416
                     begin
1417
                         dmem_data_out_o  <= {reg_rb_r[7:0],24'h000000};
1418
                         dmem_wr_o        <= 4'b1000;
1419
                         r_mem_store      <= 1'b1;
1420
                     end
1421
                     2'b01 :
1422
                     begin
1423
                         dmem_data_out_o  <= {{8'h00,reg_rb_r[7:0]},16'h0000};
1424
                         dmem_wr_o        <= 4'b0100;
1425
                         r_mem_store      <= 1'b1;
1426
                     end
1427
                     2'b10 :
1428
                     begin
1429
                         dmem_data_out_o  <= {{16'h0000,reg_rb_r[7:0]},8'h00};
1430
                         dmem_wr_o        <= 4'b0010;
1431
                         r_mem_store      <= 1'b1;
1432
                     end
1433
                     2'b11 :
1434
                     begin
1435
                         dmem_data_out_o  <= {24'h000000,reg_rb_r[7:0]};
1436
                         dmem_wr_o        <= 4'b0001;
1437
                         r_mem_store      <= 1'b1;
1438
                     end
1439
                     default :
1440
                     begin
1441
                         dmem_data_out_o  <= 32'h00000000;
1442
                         dmem_wr_o        <= 4'b0000;
1443
                     end
1444
                 endcase
1445
             end
1446
 
1447
            inst_sh_w: // l.sh
1448 27 ultra_embe
            begin
1449 31 ultra_embe
                 dmem_addr_o <= mem_addr_r;
1450
                 r_mem_access <= 1'b1;
1451
                 case (mem_addr_r[1:0])
1452
                     2'b00 :
1453
                     begin
1454
                         dmem_data_out_o  <= {reg_rb_r[15:0],16'h0000};
1455
                         dmem_wr_o        <= 4'b1100;
1456
                         r_mem_store      <= 1'b1;
1457
                     end
1458
                     2'b10 :
1459
                     begin
1460
                         dmem_data_out_o  <= {16'h0000,reg_rb_r[15:0]};
1461
                         dmem_wr_o        <= 4'b0011;
1462
                         r_mem_store      <= 1'b1;
1463
                     end
1464
                     default :
1465
                     begin
1466
                         dmem_data_out_o  <= 32'h00000000;
1467
                         dmem_wr_o        <= 4'b0000;
1468
                     end
1469
                 endcase
1470
            end
1471 27 ultra_embe
 
1472 31 ultra_embe
            inst_sw_w: // l.sw
1473
            begin
1474
                 dmem_addr_o      <= mem_addr_r;
1475
                 dmem_data_out_o  <= reg_rb_r;
1476
                 dmem_wr_o        <= 4'b1111;
1477
                 r_mem_access     <= 1'b1;
1478
                 r_mem_store      <= 1'b1;
1479
 
1480
  `ifdef CONF_CORE_DEBUG
1481
                 $display(" Store R%d to 0x%08x = 0x%08x", reg_rb_i, {mem_addr_r[31:2],2'b00}, reg_rb_r);
1482
  `endif
1483 27 ultra_embe
            end
1484 31 ultra_embe
            default:
1485
                ;
1486
         endcase
1487
       end
1488
   end
1489
end
1490 27 ultra_embe
 
1491 31 ultra_embe
//-----------------------------------------------------------------
1492
// Execute: Misc operations
1493
//-----------------------------------------------------------------
1494
always @ (posedge clk_i or posedge rst_i)
1495
begin
1496
   if (rst_i == 1'b1)
1497
   begin
1498
       break_o              <= 1'b0;
1499
       icache_flush_o       <= 1'b0;
1500
       dcache_flush_o       <= 1'b0;
1501
   end
1502
   else
1503
   begin
1504
       break_o              <= 1'b0;
1505
       icache_flush_o       <= 1'b0;
1506
       dcache_flush_o       <= 1'b0;
1507
 
1508
       //---------------------------------------------------------------
1509
       // Valid instruction
1510
       //---------------------------------------------------------------
1511
       if (execute_inst_r & ~stall_inst_r & ~invalid_inst_r)
1512
       begin
1513
          case (1'b1)
1514
          inst_mtspr_w: // l.mtspr
1515
          begin
1516
               case (mxspr_uint16_r)
1517
                   // SR - Supervision register
1518
                   `SPR_REG_SR:
1519
                   begin
1520
                       // Cache flush request?
1521
                       icache_flush_o <= reg_rb_r[`OR32_SR_ICACHE_FLUSH];
1522
                       dcache_flush_o <= reg_rb_r[`OR32_SR_DCACHE_FLUSH];
1523
                   end
1524
               endcase
1525
          end
1526
 
1527
          inst_trap_w: // l.trap
1528
              break_o <= 1'b1;
1529
          default:
1530
              ;
1531
         endcase
1532 27 ultra_embe
       end
1533
   end
1534
end
1535
 
1536 31 ultra_embe
//-----------------------------------------------------------------
1537
// Execute: NOP (simulation) operations
1538
//-----------------------------------------------------------------
1539
`ifdef SIMULATION
1540
    always @ (posedge clk_i or posedge rst_i)
1541
    begin
1542
       if (rst_i == 1'b1)
1543
       begin
1544
    `ifdef SIM_EXT_PUTC
1545
          r_putc                <= 8'b0;
1546
    `endif
1547
       end
1548
       else
1549
       begin
1550
    `ifdef SIM_EXT_PUTC
1551
          r_putc                <= 8'b0;
1552
    `endif
1553
           //---------------------------------------------------------------
1554
           // Valid instruction
1555
           //---------------------------------------------------------------
1556
           if (execute_inst_r & ~stall_inst_r & ~invalid_inst_r)
1557
           begin
1558
 
1559
               case (1'b1)
1560
               inst_nop_w: // l.nop
1561
                begin
1562
                    case (uint16_r)
1563
                    // NOP_PUTC
1564
                    16'h0004:
1565
                    begin
1566
      `ifdef SIM_EXT_PUTC
1567
                      r_putc  <= reg_ra_r[7:0];
1568
      `else
1569
                      $write("%c", reg_ra_r[7:0]);
1570
      `endif
1571
                    end
1572
                    // NOP
1573
                    16'h0000: ;
1574
                    endcase
1575
                end
1576
                default:
1577
                    ;
1578
             endcase
1579
           end
1580
       end
1581
    end
1582
`endif
1583
 
1584 27 ultra_embe
//-------------------------------------------------------------------
1585
// Assignments
1586
//-------------------------------------------------------------------
1587
 
1588
assign branch_pc_o          = r_pc_branch;
1589
assign branch_o             = r_pc_fetch;
1590
assign stall_o              = r_stall;
1591
 
1592
assign opcode_o             = r_e_opcode;
1593
 
1594
assign reg_rd_o             = r_e_rd;
1595
assign reg_rd_value_o       = r_e_result;
1596
 
1597
assign mult_o               = 1'b0;
1598
assign mult_res_o           = 32'b0;
1599
 
1600
`include "altor32_funcs.v"
1601
 
1602
//-------------------------------------------------------------------
1603
// Hooks for debug
1604
//-------------------------------------------------------------------
1605
`ifdef verilator
1606
   function [31:0] get_opcode_ex;
1607
      // verilator public
1608
      get_opcode_ex = r_e_opcode;
1609
   endfunction
1610
   function [31:0] get_pc_ex;
1611
      // verilator public
1612
      get_pc_ex = r_e_opcode_pc;
1613
   endfunction
1614 31 ultra_embe
   function [7:0] get_putc;
1615
      // verilator public
1616
   `ifdef SIM_EXT_PUTC
1617
      get_putc = r_putc;
1618
   `else
1619
      get_putc = 8'b0;
1620
   `endif
1621
   endfunction
1622 27 ultra_embe
`endif
1623
 
1624
endmodule

powered by: WebSVN 2.1.0

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