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

Subversion Repositories altor32

[/] [altor32/] [trunk/] [rtl/] [cpu_lite/] [altor32_lite.v] - Blame information for rev 36

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

Line No. Rev Author Line
1 34 ultra_embe
//-----------------------------------------------------------------
2
//                           AltOR32 
3
//                Alternative Lightweight OpenRisc 
4 36 ultra_embe
//                            V2.1
5 34 ultra_embe
//                     Ultra-Embedded.com
6 36 ultra_embe
//                   Copyright 2011 - 2014
7 34 ultra_embe
//
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 - Simple AltOR32 (non-pipelined, small, single WB interface)
48
//-----------------------------------------------------------------
49
module altor32_lite
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
    // Enable core
62
    input               enable_i /*verilator public*/,
63
 
64
    // Fault
65
    output reg          fault_o /*verilator public*/,
66
 
67
    // Breakpoint / Trap
68
    output reg          break_o /*verilator public*/,
69
 
70
    // Memory interface
71
    output reg [31:0]   mem_addr_o /*verilator public*/,
72
    input [31:0]        mem_dat_i /*verilator public*/,
73
    output reg [31:0]   mem_dat_o /*verilator public*/,
74
    output [2:0]        mem_cti_o /*verilator public*/,
75
    output reg          mem_cyc_o /*verilator public*/,
76
    output reg          mem_stb_o /*verilator public*/,
77
    output reg          mem_we_o /*verilator public*/,
78
    output reg [3:0]    mem_sel_o /*verilator public*/,
79
    input               mem_stall_i/*verilator public*/,
80
    input               mem_ack_i/*verilator public*/
81
);
82
 
83
//-----------------------------------------------------------------
84
// Params
85
//-----------------------------------------------------------------
86
parameter           BOOT_VECTOR         = 32'h00000000;
87
parameter           ISR_VECTOR          = 32'h00000000;
88
parameter           REGISTER_FILE_TYPE  = "SIMULATION";
89
parameter           SUPPORT_32REGS      = "ENABLED";
90
 
91
//-----------------------------------------------------------------
92
// Registers
93
//-----------------------------------------------------------------
94
 
95
// PC
96
reg [31:0]  r_pc;
97
 
98
// Exception saved program counter
99
reg [31:0]  r_epc;
100
 
101
// Supervisor register
102
reg [31:0]  r_sr;
103
 
104
// Exception saved supervisor register
105
reg [31:0]  r_esr;
106
 
107
// Destination register number (post execute stage)
108
reg [4:0]   r_e_rd;
109
 
110
// ALU input A
111
reg [31:0]  r_e_alu_a;
112
 
113
// ALU input B
114
reg [31:0]  r_e_alu_b;
115
 
116
// ALU output
117
wire [31:0] r_e_result;
118
 
119
// ALU Carry
120
wire        alu_carry_out;
121
wire        alu_carry_update;
122
 
123 36 ultra_embe
// ALU Comparisons
124
wire        compare_equal_w;
125
wire        compare_gts_w;
126
wire        compare_gt_w;
127
wire        compare_lts_w;
128
wire        compare_lt_w;
129
wire        alu_flag_update;
130
 
131 34 ultra_embe
// ALU operation selection
132
reg [3:0]   r_e_alu_func;
133
 
134
// Delayed NMI
135
reg         r_nmi;
136
 
137
// SIM PUTC
138
`ifdef SIM_EXT_PUTC
139
    reg [7:0] r_putc;
140
`endif
141
 
142
wire [4:0]  w_ra;
143
wire [4:0]  w_rb;
144
wire [4:0]  w_rd;
145
 
146
wire [31:0] w_reg_ra;
147
wire [31:0] w_reg_rb;
148
 
149
reg [31:0]  r_opcode;
150
 
151
reg [31:0]  r_load_result;
152
 
153
reg [1:0]   mem_offset;
154
 
155
// Current state
156
parameter STATE_IDLE        = 0;
157
parameter STATE_FETCH       = 1;
158
parameter STATE_FETCH_WAIT  = 2;
159
parameter STATE_EXEC        = 3;
160
parameter STATE_MEM         = 4;
161
parameter STATE_WRITE_BACK  = 5;
162
 
163
reg [3:0]   state;
164
 
165
//-----------------------------------------------------------------
166
// Instantiation
167
//-----------------------------------------------------------------
168
 
169
// ALU
170
altor32_alu alu
171
(
172
    // ALU operation select
173
    .op_i(r_e_alu_func),
174
 
175
    // Operands
176
    .a_i(r_e_alu_a),
177
    .b_i(r_e_alu_b),
178
    .c_i(r_sr[`OR32_SR_CY]),
179
 
180
    // Result
181
    .p_o(r_e_result),
182
 
183
    // Carry
184
    .c_o(alu_carry_out),
185 36 ultra_embe
    .c_update_o(alu_carry_update),
186
 
187
    // Comparisons
188
    .equal_o(compare_equal_w),
189
    .greater_than_signed_o(compare_gts_w),
190
    .greater_than_o(compare_gt_w),
191
    .less_than_signed_o(compare_lts_w),
192
    .less_than_o(compare_lt_w),
193
    .flag_update_o(alu_flag_update)
194 34 ultra_embe
);
195
 
196
// Writeback result
197
wire [31:0] w_write_res     = (state == STATE_MEM) ? r_load_result : r_e_result;
198
 
199
// Writeback enable
200
wire        w_write_en      = (state == STATE_MEM & mem_ack_i) | (state == STATE_WRITE_BACK);
201
 
202
// Register file
203
generate
204
if (REGISTER_FILE_TYPE == "XILINX")
205
begin : REGFILE_XIL
206
    altor32_regfile_xil
207
    #(
208
        .SUPPORT_32REGS(SUPPORT_32REGS)
209
    )
210
    reg_bank
211
    (
212
        // Clocking
213
        .clk_i(clk_i),
214
        .rst_i(rst_i),
215
        .wr_i(w_write_en),
216
 
217
        // Tri-port
218
        .rs_i(w_ra),
219
        .rt_i(w_rb),
220
        .rd_i(r_e_rd),
221
        .reg_rs_o(w_reg_ra),
222
        .reg_rt_o(w_reg_rb),
223
        .reg_rd_i(w_write_res)
224
    );
225
end
226
else if (REGISTER_FILE_TYPE == "ALTERA")
227
begin : REGFILE_ALT
228
    altor32_regfile_alt
229
    #(
230
        .SUPPORT_32REGS(SUPPORT_32REGS)
231
    )
232
    reg_bank
233
    (
234
        // Clocking
235
        .clk_i(clk_i),
236
        .rst_i(rst_i),
237
        .wr_i(w_write_en),
238
 
239
        // Tri-port
240
        .rs_i(w_ra),
241
        .rt_i(w_rb),
242
        .rd_i(r_e_rd),
243
        .reg_rs_o(w_reg_ra),
244
        .reg_rt_o(w_reg_rb),
245
        .reg_rd_i(w_write_res)
246
    );
247
end
248
else
249
begin : REGFILE_SIM
250
    altor32_regfile_sim
251
    #(
252
        .SUPPORT_32REGS(SUPPORT_32REGS)
253
    )
254
    reg_bank
255
    (
256
        // Clocking
257
        .clk_i(clk_i),
258
        .rst_i(rst_i),
259
        .wr_i(w_write_en),
260
 
261
        // Tri-port
262
        .rs_i(w_ra),
263
        .rt_i(w_rb),
264
        .rd_i(r_e_rd),
265
        .reg_rs_o(w_reg_ra),
266
        .reg_rt_o(w_reg_rb),
267
        .reg_rd_i(w_write_res)
268
    );
269
end
270
endgenerate
271
 
272
//-----------------------------------------------------------------
273
// Opcode decode
274
//-----------------------------------------------------------------
275
reg [7:0]  inst_r;
276
reg [7:0]  alu_op_r;
277
reg [1:0]  shift_op_r;
278
reg [15:0] sfxx_op_r;
279
reg [15:0] uint16_r;
280
reg [31:0] uint32_r;
281
reg [31:0] int32_r;
282
reg [31:0] store_int32_r;
283
reg [15:0] mxspr_uint16_r;
284
reg [31:0] target_int26_r;
285
reg [31:0] reg_ra_r;
286
reg [31:0] reg_rb_r;
287
reg [31:0] shift_rb_r;
288
reg [31:0] shift_imm_r;
289
 
290
always @ *
291
begin
292
    // Instruction
293
    inst_r               = {2'b00,r_opcode[31:26]};
294
 
295
    // Sub instructions
296
    alu_op_r             = {r_opcode[9:6],r_opcode[3:0]};
297 36 ultra_embe
    sfxx_op_r            = {5'b00,r_opcode[31:21]} & `INST_OR32_SFMASK;
298 34 ultra_embe
    shift_op_r           = r_opcode[7:6];
299
 
300
    // Branch target
301
    target_int26_r       = sign_extend_imm26(r_opcode[25:0]);
302
 
303
    // Store immediate
304
    store_int32_r        = sign_extend_imm16({r_opcode[25:21],r_opcode[10:0]});
305
 
306
    // Signed & unsigned imm -> 32-bits
307
    uint16_r             = r_opcode[15:0];
308
    int32_r              = sign_extend_imm16(r_opcode[15:0]);
309
    uint32_r             = extend_imm16(r_opcode[15:0]);
310
 
311
    // Register values [ra/rb]
312
    reg_ra_r             = w_reg_ra;
313
    reg_rb_r             = w_reg_rb;
314
 
315
    // Shift ammount (from register[rb])
316
    shift_rb_r           = {26'b00,w_reg_rb[5:0]};
317
 
318
    // Shift ammount (from immediate)
319
    shift_imm_r          = {26'b00,r_opcode[5:0]};
320
 
321
    // MTSPR/MFSPR operand
322
    mxspr_uint16_r       = (w_reg_ra[15:0] | {5'b00000,r_opcode[10:0]});
323
end
324
 
325
//-----------------------------------------------------------------
326
// Instruction Decode
327
//-----------------------------------------------------------------
328
wire inst_add_w     = (inst_r == `INST_OR32_ALU) & (alu_op_r == `INST_OR32_ADD);  // l.add
329
wire inst_addc_w    = (inst_r == `INST_OR32_ALU) & (alu_op_r == `INST_OR32_ADDC); // l.addc
330
wire inst_and_w     = (inst_r == `INST_OR32_ALU) & (alu_op_r == `INST_OR32_AND);  // l.and
331
wire inst_or_w      = (inst_r == `INST_OR32_ALU) & (alu_op_r == `INST_OR32_OR);   // l.or
332
wire inst_sll_w     = (inst_r == `INST_OR32_ALU) & (alu_op_r == `INST_OR32_SLL);  // l.sll
333
wire inst_sw_ra     = (inst_r == `INST_OR32_ALU) & (alu_op_r == `INST_OR32_SRA);  // l.sra
334
wire inst_srl_w     = (inst_r == `INST_OR32_ALU) & (alu_op_r == `INST_OR32_SRL);  // l.srl
335
wire inst_sub_w     = (inst_r == `INST_OR32_ALU) & (alu_op_r == `INST_OR32_SUB);  // l.sub
336
wire inst_xor_w     = (inst_r == `INST_OR32_ALU) & (alu_op_r == `INST_OR32_XOR);  // l.xor
337
wire inst_mul_w     = (inst_r == `INST_OR32_ALU) & (alu_op_r == `INST_OR32_MUL);  // l.mul
338
wire inst_mulu_w    = (inst_r == `INST_OR32_ALU) & (alu_op_r == `INST_OR32_MULU); // l.mulu
339
 
340
wire inst_addi_w    = (inst_r == `INST_OR32_ADDI);  // l.addi
341
wire inst_andi_w    = (inst_r == `INST_OR32_ANDI);  // l.andi
342
wire inst_bf_w      = (inst_r == `INST_OR32_BF);    // l.bf
343
wire inst_bnf_w     = (inst_r == `INST_OR32_BNF);   // l.bnf
344
wire inst_j_w       = (inst_r == `INST_OR32_J);     // l.j
345
wire inst_jal_w     = (inst_r == `INST_OR32_JAL);   // l.jal
346
wire inst_jalr_w    = (inst_r == `INST_OR32_JALR);  // l.jalr
347
wire inst_jr_w      = (inst_r == `INST_OR32_JR);    // l.jr
348
wire inst_lbs_w     = (inst_r == `INST_OR32_LBS);   // l.lbs
349
wire inst_lhs_w     = (inst_r == `INST_OR32_LHS);   // l.lhs
350
wire inst_lws_w     = (inst_r == `INST_OR32_LWS);   // l.lws
351
wire inst_lbz_w     = (inst_r == `INST_OR32_LBZ);   // l.lbz
352
wire inst_lhz_w     = (inst_r == `INST_OR32_LHZ);   // l.lhz
353
wire inst_lwz_w     = (inst_r == `INST_OR32_LWZ);   // l.lwz
354
wire inst_mfspr_w   = (inst_r == `INST_OR32_MFSPR); // l.mfspr
355
wire inst_mtspr_w   = (inst_r == `INST_OR32_MTSPR); // l.mtspr
356
wire inst_movhi_w   = (inst_r == `INST_OR32_MOVHI); // l.movhi
357
wire inst_nop_w     = (inst_r == `INST_OR32_NOP);   // l.nop
358
wire inst_ori_w     = (inst_r == `INST_OR32_ORI);   // l.ori
359
wire inst_rfe_w     = (inst_r == `INST_OR32_RFE);   // l.rfe
360
 
361
wire inst_sb_w      = (inst_r == `INST_OR32_SB);    // l.sb
362
wire inst_sh_w      = (inst_r == `INST_OR32_SH);    // l.sh
363
wire inst_sw_w      = (inst_r == `INST_OR32_SW);    // l.sw
364
 
365
wire inst_slli_w    = (inst_r == `INST_OR32_SHIFTI) & (shift_op_r == `INST_OR32_SLLI);  // l.slli
366
wire inst_srai_w    = (inst_r == `INST_OR32_SHIFTI) & (shift_op_r == `INST_OR32_SRAI);  // l.srai
367
wire inst_srli_w    = (inst_r == `INST_OR32_SHIFTI) & (shift_op_r == `INST_OR32_SRLI);  // l.srli
368
 
369
wire inst_xori_w    = (inst_r == `INST_OR32_XORI);   // l.xori
370
 
371
wire inst_sfxx_w    = (inst_r == `INST_OR32_SFXX);
372
wire inst_sfxxi_w   = (inst_r == `INST_OR32_SFXXI);
373
 
374 36 ultra_embe
wire inst_sfeq_w    = (inst_sfxx_w || inst_sfxxi_w) & (sfxx_op_r == `INST_OR32_SFEQ);   // l.sfeq
375
wire inst_sfges_w   = (inst_sfxx_w || inst_sfxxi_w) & (sfxx_op_r == `INST_OR32_SFGES);  // l.sfges
376 34 ultra_embe
 
377 36 ultra_embe
wire inst_sfgeu_w   = (inst_sfxx_w || inst_sfxxi_w) & (sfxx_op_r == `INST_OR32_SFGEU);  // l.sfgeu
378
wire inst_sfgts_w   = (inst_sfxx_w || inst_sfxxi_w) & (sfxx_op_r == `INST_OR32_SFGTS);  // l.sfgts
379
wire inst_sfgtu_w   = (inst_sfxx_w || inst_sfxxi_w) & (sfxx_op_r == `INST_OR32_SFGTU);  // l.sfgtu
380
wire inst_sfles_w   = (inst_sfxx_w || inst_sfxxi_w) & (sfxx_op_r == `INST_OR32_SFLES);  // l.sfles
381
wire inst_sfleu_w   = (inst_sfxx_w || inst_sfxxi_w) & (sfxx_op_r == `INST_OR32_SFLEU);  // l.sfleu
382
wire inst_sflts_w   = (inst_sfxx_w || inst_sfxxi_w) & (sfxx_op_r == `INST_OR32_SFLTS);  // l.sflts
383
wire inst_sfltu_w   = (inst_sfxx_w || inst_sfxxi_w) & (sfxx_op_r == `INST_OR32_SFLTU);  // l.sfltu
384
wire inst_sfne_w    = (inst_sfxx_w || inst_sfxxi_w) & (sfxx_op_r == `INST_OR32_SFNE);   // l.sfne
385 34 ultra_embe
 
386
wire inst_sys_w     = (inst_r == `INST_OR32_MISC) & (r_opcode[31:24] == `INST_OR32_SYS);  // l.sys
387
wire inst_trap_w    = (inst_r == `INST_OR32_MISC) & (r_opcode[31:24] == `INST_OR32_TRAP); // l.trap
388
 
389
//-----------------------------------------------------------------
390
// Load/Store operation?
391
//-----------------------------------------------------------------
392
reg         load_inst_r;
393
reg         store_inst_r;
394
reg [31:0]  mem_addr_r;
395
always @ *
396
begin
397
    load_inst_r  = inst_lbs_w | inst_lhs_w | inst_lws_w |
398
                   inst_lbz_w | inst_lhz_w | inst_lwz_w;
399
    store_inst_r = inst_sb_w  | inst_sh_w  | inst_sw_w;
400
 
401
    // Memory address is relative to RA
402
    mem_addr_r = reg_ra_r + (store_inst_r ? store_int32_r : int32_r);
403
end
404
 
405
//-----------------------------------------------------------------
406
// Next State Logic
407
//-----------------------------------------------------------------
408
reg [3:0] next_state_r;
409
always @ *
410
begin
411
    next_state_r = state;
412
 
413
    case (state)
414
    //-----------------------------------------
415
    // IDLE - 
416
    //-----------------------------------------
417
    STATE_IDLE :
418
    begin
419
        if (enable_i)
420
            next_state_r    = STATE_FETCH;
421
    end
422
    //-----------------------------------------
423
    // FETCH - Fetch line from memory
424
    //-----------------------------------------
425
    STATE_FETCH :
426
    begin
427
        next_state_r    = STATE_FETCH_WAIT;
428
    end
429
    //-----------------------------------------
430
    // FETCH_WAIT - Wait for read responses
431
    //-----------------------------------------
432
    STATE_FETCH_WAIT:
433
    begin
434
        // Read from memory complete
435
        if (mem_ack_i)
436
            next_state_r = STATE_EXEC;
437
    end
438
    //-----------------------------------------
439
    // EXEC
440
    //-----------------------------------------
441
    STATE_EXEC :
442
    begin
443
        if (load_inst_r || store_inst_r)
444
            next_state_r    = STATE_MEM;
445
        else
446
            next_state_r    = STATE_WRITE_BACK;
447
    end
448
    //-----------------------------------------
449
    // MEM
450
    //-----------------------------------------
451
    STATE_MEM :
452
    begin
453
        // Read from memory complete
454
        if (mem_ack_i)
455
            next_state_r = STATE_FETCH;
456
    end
457
    //-----------------------------------------
458
    // WRITE_BACK
459
    //-----------------------------------------
460
    STATE_WRITE_BACK :
461
    begin
462
        if (enable_i)
463
            next_state_r    = STATE_FETCH;
464
    end
465
    default:
466
        ;
467
   endcase
468
end
469
 
470
// Update state
471
always @ (posedge rst_i or posedge clk_i )
472
begin
473
   if (rst_i == 1'b1)
474
        state   <= STATE_IDLE;
475
   else
476
        state   <= next_state_r;
477
end
478
 
479
//-----------------------------------------------------------------
480
// Memory Access / Instruction Fetch
481
//-----------------------------------------------------------------
482
always @ (posedge rst_i or posedge clk_i )
483
begin
484
   if (rst_i == 1'b1)
485
   begin
486
        mem_addr_o      <= 32'h00000000;
487
        mem_dat_o       <= 32'h00000000;
488
        mem_sel_o       <= 4'b0;
489
        mem_we_o        <= 1'b0;
490
        mem_stb_o       <= 1'b0;
491
        mem_cyc_o       <= 1'b0;
492
 
493
        r_opcode        <= 32'h00000000;
494
        mem_offset      <= 2'b0;
495
   end
496
   else
497
   begin
498
 
499
        if (~mem_stall_i)
500
            mem_stb_o    <= 1'b0;
501
 
502
        case (state)
503
 
504
            //-----------------------------------------
505
            // FETCH - Issue instruction fetch
506
            //-----------------------------------------
507
            STATE_FETCH :
508
            begin
509
                // Start fetch from memory
510
                mem_addr_o  <= r_pc;
511
                mem_stb_o   <= 1'b1;
512
                mem_we_o    <= 1'b0;
513
                mem_cyc_o   <= 1'b1;
514
            end
515
            //-----------------------------------------
516
            // FETCH_WAIT - Wait for response
517
            //-----------------------------------------
518
            STATE_FETCH_WAIT :
519
            begin
520
                // Data ready from memory?
521
                if (mem_ack_i)
522
                begin
523
                    r_opcode    <= mem_dat_i;
524
                    mem_cyc_o   <= 1'b0;
525
                end
526
            end
527
            //-----------------------------------------
528
            // EXEC - Issue read / write
529
            //-----------------------------------------            
530
            STATE_EXEC :
531
            begin
532
            `ifdef CONF_CORE_TRACE
533
                $display("%08x: Execute 0x%08x", r_pc, r_opcode);
534
                $display(" rA[%d] = 0x%08x", w_ra, reg_ra_r);
535
                $display(" rB[%d] = 0x%08x", w_rb, reg_rb_r);
536
            `endif
537
 
538
                case (1'b1)
539
                 // l.lbs l.lhs l.lws l.lbz l.lhz l.lwz
540
                 load_inst_r:
541
                 begin
542
                     mem_addr_o      <= {mem_addr_r[31:2], 2'b0};
543
                     mem_offset      <= mem_addr_r[1:0];
544
                     mem_dat_o       <= 32'h00000000;
545
                     mem_sel_o       <= 4'b1111;
546
                     mem_we_o        <= 1'b0;
547
                     mem_stb_o       <= 1'b1;
548
                     mem_cyc_o       <= 1'b1;
549
 
550
      `ifdef CONF_CORE_DEBUG
551
                     $display(" Load from 0x%08x to R%d", mem_addr_r, w_rd);
552
      `endif
553
                 end
554
 
555
                 inst_sb_w: // l.sb
556
                 begin
557
                     mem_addr_o      <= {mem_addr_r[31:2], 2'b0};
558
                     mem_offset      <= mem_addr_r[1:0];
559
                     case (mem_addr_r[1:0])
560
                         2'b00 :
561
                         begin
562
                             mem_dat_o       <= {reg_rb_r[7:0],24'h000000};
563
                             mem_sel_o       <= 4'b1000;
564
                             mem_we_o        <= 1'b1;
565
                             mem_stb_o       <= 1'b1;
566
                             mem_cyc_o       <= 1'b1;
567
                         end
568
                         2'b01 :
569
                         begin
570
                             mem_dat_o       <= {{8'h00,reg_rb_r[7:0]},16'h0000};
571
                             mem_sel_o       <= 4'b0100;
572
                             mem_we_o        <= 1'b1;
573
                             mem_stb_o       <= 1'b1;
574
                             mem_cyc_o       <= 1'b1;
575
                         end
576
                         2'b10 :
577
                         begin
578
                             mem_dat_o       <= {{16'h0000,reg_rb_r[7:0]},8'h00};
579
                             mem_sel_o       <= 4'b0010;
580
                             mem_we_o        <= 1'b1;
581
                             mem_stb_o       <= 1'b1;
582
                             mem_cyc_o       <= 1'b1;
583
                         end
584
                         2'b11 :
585
                         begin
586
                             mem_dat_o       <= {24'h000000,reg_rb_r[7:0]};
587
                             mem_sel_o       <= 4'b0001;
588
                             mem_we_o        <= 1'b1;
589
                             mem_stb_o       <= 1'b1;
590
                             mem_cyc_o       <= 1'b1;
591
                         end
592
                         default :
593
                            ;
594
                     endcase
595
                 end
596
 
597
                inst_sh_w: // l.sh
598
                begin
599
                     mem_addr_o      <= {mem_addr_r[31:2], 2'b0};
600
                     mem_offset      <= mem_addr_r[1:0];
601
                     case (mem_addr_r[1:0])
602
                         2'b00 :
603
                         begin
604
                             mem_dat_o       <= {reg_rb_r[15:0],16'h0000};
605
                             mem_sel_o       <= 4'b1100;
606
                             mem_we_o        <= 1'b1;
607
                             mem_stb_o       <= 1'b1;
608
                             mem_cyc_o       <= 1'b1;
609
                         end
610
                         2'b10 :
611
                         begin
612
                             mem_dat_o       <= {16'h0000,reg_rb_r[15:0]};
613
                             mem_sel_o       <= 4'b0011;
614
                             mem_we_o        <= 1'b1;
615
                             mem_stb_o       <= 1'b1;
616
                             mem_cyc_o       <= 1'b1;
617
                         end
618
                         default :
619
                            ;
620
                     endcase
621
                end
622
 
623
                inst_sw_w: // l.sw
624
                begin
625
                     mem_addr_o      <= {mem_addr_r[31:2], 2'b0};
626
                     mem_offset      <= mem_addr_r[1:0];
627
                     mem_dat_o       <= reg_rb_r;
628
                     mem_sel_o       <= 4'b1111;
629
                     mem_we_o        <= 1'b1;
630
                     mem_stb_o       <= 1'b1;
631
                     mem_cyc_o       <= 1'b1;
632
 
633
      `ifdef CONF_CORE_DEBUG
634
                     $display(" Store R%d to 0x%08x = 0x%08x", w_rb, {mem_addr_r[31:2],2'b00}, reg_rb_r);
635
      `endif
636
                end
637
                default:
638
                    ;
639
             endcase
640
            end
641
            //-----------------------------------------
642
            // MEM - Wait for response
643
            //-----------------------------------------
644
            STATE_MEM :
645
            begin
646
                // Data ready from memory?
647
                if (mem_ack_i)
648
                begin
649
                    mem_cyc_o   <= 1'b0;
650
                end
651
            end
652
            default:
653
                ;
654
           endcase
655
   end
656
end
657
 
658
assign mem_cti_o        = 3'b111;
659
 
660
// If simulation, RA = 03 if NOP instruction
661
`ifdef SIMULATION
662
    wire [7:0] v_fetch_inst = {2'b00, r_opcode[31:26]};
663
    wire       v_is_nop     = (v_fetch_inst == `INST_OR32_NOP);
664
    assign     w_ra         = v_is_nop ? 5'd3 : r_opcode[20:16];
665
`else
666
    assign     w_ra         = r_opcode[20:16];
667
`endif
668
 
669
assign w_rb        = r_opcode[15:11];
670
assign w_rd        = r_opcode[25:21];
671
 
672
//-----------------------------------------------------------------
673
// Next PC
674
//-----------------------------------------------------------------
675
reg [31:0]  next_pc_r;
676
 
677
always @ *
678
begin
679
    // Next expected PC (current PC + 4)
680
    next_pc_r  = (r_pc + 4);
681
end
682
 
683
//-----------------------------------------------------------------
684
// Next SR
685
//-----------------------------------------------------------------
686
reg [31:0]  next_sr_r;
687
reg         compare_result_r;
688
always @ *
689
begin
690
    next_sr_r = r_sr;
691
 
692 36 ultra_embe
    // Update SR.F
693
    if (alu_flag_update)
694
        next_sr_r[`OR32_SR_F] = compare_result_r;
695
 
696 34 ultra_embe
    // Latch carry if updated
697
    if (alu_carry_update)
698
        next_sr_r[`OR32_SR_CY] = alu_carry_out;
699
 
700
    case (1'b1)
701
      inst_mtspr_w:
702
      begin
703
          case (mxspr_uint16_r)
704
          // SR - Supervision register
705
          `SPR_REG_SR:
706
          begin
707
              next_sr_r[`OR32_SR_F]     = reg_rb_r[`OR32_SR_F];
708
              next_sr_r[`OR32_SR_CY]    = reg_rb_r[`OR32_SR_CY];
709
              next_sr_r[`OR32_SR_IEE]   = reg_rb_r[`OR32_SR_IEE];
710
          end
711
          default:
712
            ;
713
          endcase
714
      end
715
      inst_rfe_w:
716
      begin
717
          next_sr_r[`OR32_SR_F]         = r_esr[`OR32_SR_F];
718
          next_sr_r[`OR32_SR_CY]        = r_esr[`OR32_SR_CY];
719
          next_sr_r[`OR32_SR_IEE]       = r_esr[`OR32_SR_IEE];
720
      end
721
      inst_sfxx_w,
722
      inst_sfxxi_w:
723
           next_sr_r[`OR32_SR_F] = compare_result_r;
724
      default:
725
        ;
726
    endcase
727
end
728
 
729
//-----------------------------------------------------------------
730
// Next EPC/ESR
731
//-----------------------------------------------------------------
732
reg [31:0]  next_epc_r;
733
reg [31:0]  next_esr_r;
734
 
735
always @ *
736
begin
737
    next_epc_r = r_epc;
738
    next_esr_r = r_esr;
739
 
740
    case (1'b1)
741
    inst_mtspr_w: // l.mtspr
742
    begin
743
       case (mxspr_uint16_r)
744
           // EPCR - EPC Exception saved PC
745
           `SPR_REG_EPCR:   next_epc_r = reg_rb_r;
746
 
747
           // ESR - Exception saved SR
748
           `SPR_REG_ESR:    next_esr_r = reg_rb_r;
749
       endcase
750
    end
751
    default:
752
      ;
753
    endcase
754
end
755
 
756
//-----------------------------------------------------------------
757
// ALU inputs
758
//-----------------------------------------------------------------
759
 
760
// ALU operation selection
761
reg [3:0]  alu_func_r;
762
 
763
// ALU operands
764
reg [31:0] alu_input_a_r;
765
reg [31:0] alu_input_b_r;
766
reg        write_rd_r;
767
 
768
always @ *
769
begin
770
   alu_func_r     = `ALU_NONE;
771
   alu_input_a_r  = 32'b0;
772
   alu_input_b_r  = 32'b0;
773
   write_rd_r     = 1'b0;
774
 
775
   case (1'b1)
776
 
777
     inst_add_w: // l.add
778
     begin
779
       alu_func_r     = `ALU_ADD;
780
       alu_input_a_r  = reg_ra_r;
781
       alu_input_b_r  = reg_rb_r;
782
       write_rd_r     = 1'b1;
783
     end
784
 
785
     inst_addc_w: // l.addc
786
     begin
787
         alu_func_r     = `ALU_ADDC;
788
         alu_input_a_r  = reg_ra_r;
789
         alu_input_b_r  = reg_rb_r;
790
         write_rd_r     = 1'b1;
791
     end
792
 
793
     inst_and_w: // l.and
794
     begin
795
         alu_func_r     = `ALU_AND;
796
         alu_input_a_r  = reg_ra_r;
797
         alu_input_b_r  = reg_rb_r;
798
         write_rd_r     = 1'b1;
799
     end
800
 
801
     inst_or_w: // l.or
802
     begin
803
         alu_func_r     = `ALU_OR;
804
         alu_input_a_r  = reg_ra_r;
805
         alu_input_b_r  = reg_rb_r;
806
         write_rd_r     = 1'b1;
807
     end
808
 
809
     inst_sll_w: // l.sll
810
     begin
811
         alu_func_r     = `ALU_SHIFTL;
812
         alu_input_a_r  = reg_ra_r;
813
         alu_input_b_r  = shift_rb_r;
814
         write_rd_r     = 1'b1;
815
     end
816
 
817
     inst_sw_ra: // l.sra
818
     begin
819
         alu_func_r     = `ALU_SHIRTR_ARITH;
820
         alu_input_a_r  = reg_ra_r;
821
         alu_input_b_r  = shift_rb_r;
822
         write_rd_r     = 1'b1;
823
     end
824
 
825
     inst_srl_w: // l.srl
826
     begin
827
         alu_func_r     = `ALU_SHIFTR;
828
         alu_input_a_r  = reg_ra_r;
829
         alu_input_b_r  = shift_rb_r;
830
         write_rd_r     = 1'b1;
831
     end
832
 
833
     inst_sub_w: // l.sub
834
     begin
835
         alu_func_r     = `ALU_SUB;
836
         alu_input_a_r  = reg_ra_r;
837
         alu_input_b_r  = reg_rb_r;
838
         write_rd_r     = 1'b1;
839
     end
840
 
841
     inst_xor_w: // l.xor
842
     begin
843
         alu_func_r     = `ALU_XOR;
844
         alu_input_a_r  = reg_ra_r;
845
         alu_input_b_r  = reg_rb_r;
846
         write_rd_r     = 1'b1;
847
     end
848
 
849
     inst_mul_w,   // l.mul
850
     inst_mulu_w:  // l.mulu
851
     begin
852
         write_rd_r     = 1'b1;
853
     end
854
 
855
     inst_addi_w: // l.addi
856
     begin
857
         alu_func_r     = `ALU_ADD;
858
         alu_input_a_r  = reg_ra_r;
859
         alu_input_b_r  = int32_r;
860
         write_rd_r     = 1'b1;
861
     end
862
 
863
     inst_andi_w: // l.andi
864
     begin
865
         alu_func_r     = `ALU_AND;
866
         alu_input_a_r  = reg_ra_r;
867
         alu_input_b_r  = uint32_r;
868
         write_rd_r     = 1'b1;
869
     end
870
 
871
     inst_jal_w: // l.jal
872
     begin
873
         alu_input_a_r  = next_pc_r;
874
         write_rd_r     = 1'b1;
875
     end
876
 
877
     inst_jalr_w: // l.jalr
878
     begin
879
         alu_input_a_r  = next_pc_r;
880
         write_rd_r     = 1'b1;
881
     end
882
 
883
     inst_mfspr_w: // l.mfspr
884
     begin
885
        case (mxspr_uint16_r)
886
           // SR - Supervision register
887
           `SPR_REG_SR:
888
           begin
889
               alu_input_a_r                = 32'b0;
890
               alu_input_a_r[`OR32_SR_F]    = next_sr_r[`OR32_SR_F];
891
               alu_input_a_r[`OR32_SR_CY]   = next_sr_r[`OR32_SR_CY];
892
               alu_input_a_r[`OR32_SR_IEE]  = next_sr_r[`OR32_SR_IEE];
893
               write_rd_r                   = 1'b1;
894
           end
895
 
896
           // EPCR - EPC Exception saved PC
897
           `SPR_REG_EPCR:
898
           begin
899
               alu_input_a_r  = r_epc;
900
               write_rd_r     = 1'b1;
901
           end
902
 
903
           // ESR - Exception saved SR
904
           `SPR_REG_ESR:
905
           begin
906
               alu_input_a_r                = 32'b0;
907
               alu_input_a_r[`OR32_SR_F]    = r_esr[`OR32_SR_F];
908
               alu_input_a_r[`OR32_SR_CY]   = r_esr[`OR32_SR_CY];
909
               alu_input_a_r[`OR32_SR_IEE]  = r_esr[`OR32_SR_IEE];
910
               write_rd_r                   = 1'b1;
911
           end
912
           default:
913
              ;
914
        endcase
915
     end
916
 
917
     inst_movhi_w: // l.movhi
918
     begin
919
         alu_input_a_r  = {uint16_r,16'h0000};
920
         write_rd_r     = 1'b1;
921
     end
922
 
923
     inst_ori_w: // l.ori
924
     begin
925
         alu_func_r     = `ALU_OR;
926
         alu_input_a_r  = reg_ra_r;
927
         alu_input_b_r  = uint32_r;
928
         write_rd_r     = 1'b1;
929
     end
930
 
931
     inst_slli_w: // l.slli
932
     begin
933
         alu_func_r     = `ALU_SHIFTL;
934
         alu_input_a_r  = reg_ra_r;
935
         alu_input_b_r  = shift_imm_r;
936
         write_rd_r     = 1'b1;
937
     end
938
 
939
     inst_srai_w: // l.srai
940
     begin
941
         alu_func_r     = `ALU_SHIRTR_ARITH;
942
         alu_input_a_r  = reg_ra_r;
943
         alu_input_b_r  = shift_imm_r;
944
         write_rd_r     = 1'b1;
945
     end
946
 
947
     inst_srli_w: // l.srli
948
     begin
949
         alu_func_r     = `ALU_SHIFTR;
950
         alu_input_a_r  = reg_ra_r;
951
         alu_input_b_r  = shift_imm_r;
952
         write_rd_r     = 1'b1;
953
     end
954
 
955 36 ultra_embe
     // l.sf*i
956
     inst_sfxxi_w:
957
     begin
958
         alu_func_r     = `ALU_COMPARE;
959
         alu_input_a_r  = reg_ra_r;
960
         alu_input_b_r  = int32_r;
961
     end
962
 
963
     // l.sf*
964
     inst_sfxx_w:
965
     begin
966
         alu_func_r     = `ALU_COMPARE;
967
         alu_input_a_r  = reg_ra_r;
968
         alu_input_b_r  = reg_rb_r;
969
     end
970
 
971 34 ultra_embe
     // l.lbs l.lhs l.lws l.lbz l.lhz l.lwz
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
          write_rd_r    = 1'b1;
979
 
980
     inst_xori_w: // l.xori
981
     begin
982
         alu_func_r     = `ALU_XOR;
983
         alu_input_a_r  = reg_ra_r;
984
         alu_input_b_r  = int32_r;
985
         write_rd_r     = 1'b1;
986
     end
987
     default:
988
        ;
989
   endcase
990
end
991
 
992
//-----------------------------------------------------------------
993
// Comparisons
994
//-----------------------------------------------------------------
995
always @ *
996
begin
997
    case (1'b1)
998 36 ultra_embe
    inst_sfges_w: // l.sfges
999
        compare_result_r = compare_gts_w | compare_equal_w;
1000 34 ultra_embe
 
1001 36 ultra_embe
    inst_sfgeu_w: // l.sfgeu
1002
        compare_result_r = compare_gt_w | compare_equal_w;
1003 34 ultra_embe
 
1004 36 ultra_embe
    inst_sfgts_w: // l.sfgts
1005
        compare_result_r = compare_gts_w;
1006 34 ultra_embe
 
1007 36 ultra_embe
    inst_sfgtu_w: // l.sfgtu
1008
        compare_result_r = compare_gt_w;
1009 34 ultra_embe
 
1010 36 ultra_embe
    inst_sfles_w: // l.sfles
1011
        compare_result_r = compare_lts_w | compare_equal_w;
1012 34 ultra_embe
 
1013 36 ultra_embe
    inst_sfleu_w: // l.sfleu
1014
        compare_result_r = compare_lt_w | compare_equal_w;
1015 34 ultra_embe
 
1016 36 ultra_embe
    inst_sflts_w: // l.sflts
1017
        compare_result_r = compare_lts_w;
1018 34 ultra_embe
 
1019 36 ultra_embe
    inst_sfltu_w: // l.sfltu
1020
        compare_result_r = compare_lt_w;
1021 34 ultra_embe
 
1022 36 ultra_embe
    inst_sfne_w: // l.sfne
1023
        compare_result_r = ~compare_equal_w;
1024 34 ultra_embe
 
1025 36 ultra_embe
    default: // l.sfeq
1026
        compare_result_r = compare_equal_w;
1027
    endcase
1028 34 ultra_embe
end
1029
 
1030
//-----------------------------------------------------------------
1031
// Branches
1032
//-----------------------------------------------------------------
1033
reg         branch_r;
1034
reg         branch_link_r;
1035
reg [31:0]  branch_target_r;
1036
reg         branch_except_r;
1037
 
1038
always @ *
1039
begin
1040
 
1041
    branch_r        = 1'b0;
1042
    branch_link_r   = 1'b0;
1043
    branch_except_r = 1'b0;
1044
 
1045
    // Default branch target is relative to current PC
1046
    branch_target_r = (r_pc + {target_int26_r[29:0],2'b00});
1047
 
1048
    case (1'b1)
1049
    inst_bf_w: // l.bf
1050
        branch_r      = r_sr[`OR32_SR_F];
1051
 
1052
    inst_bnf_w: // l.bnf
1053
        branch_r      = ~r_sr[`OR32_SR_F];
1054
 
1055
    inst_j_w: // l.j
1056
        branch_r      = 1'b1;
1057
 
1058
    inst_jal_w: // l.jal
1059
    begin
1060
        // Write to REG_9_LR
1061
        branch_link_r = 1'b1;
1062
        branch_r      = 1'b1;
1063
    end
1064
 
1065
    inst_jalr_w: // l.jalr
1066
    begin
1067
        // Write to REG_9_LR
1068
        branch_link_r   = 1'b1;
1069
        branch_r        = 1'b1;
1070
        branch_target_r = reg_rb_r;
1071
    end
1072
 
1073
    inst_jr_w: // l.jr
1074
    begin
1075
        branch_r        = 1'b1;
1076
        branch_target_r = reg_rb_r;
1077
    end
1078
 
1079
    inst_rfe_w: // l.rfe
1080
    begin
1081
        branch_r        = 1'b1;
1082
        branch_target_r = r_epc;
1083
    end
1084
 
1085
    inst_sys_w: // l.sys
1086
    begin
1087
        branch_r        = 1'b1;
1088
        branch_except_r = 1'b1;
1089
        branch_target_r = ISR_VECTOR + `VECTOR_SYSCALL;
1090
    end
1091
 
1092
    inst_trap_w: // l.trap
1093
    begin
1094
        branch_r        = 1'b1;
1095
        branch_except_r = 1'b1;
1096
        branch_target_r = ISR_VECTOR + `VECTOR_TRAP;
1097
    end
1098
 
1099
    default:
1100
        ;
1101
    endcase
1102
end
1103
 
1104
//-----------------------------------------------------------------
1105
// Invalid instruction
1106
//-----------------------------------------------------------------
1107
reg invalid_inst_r;
1108
 
1109
always @ *
1110
begin
1111
    case (1'b1)
1112
       inst_add_w,
1113
       inst_addc_w,
1114
       inst_and_w,
1115
       inst_or_w,
1116
       inst_sll_w,
1117
       inst_sw_ra,
1118
       inst_srl_w,
1119
       inst_sub_w,
1120
       inst_xor_w,
1121
       inst_addi_w,
1122
       inst_andi_w,
1123
       inst_bf_w,
1124
       inst_bnf_w,
1125
       inst_j_w,
1126
       inst_jal_w,
1127
       inst_jalr_w,
1128
       inst_jr_w,
1129
       inst_lbs_w,
1130
       inst_lhs_w,
1131
       inst_lws_w,
1132
       inst_lbz_w,
1133
       inst_lhz_w,
1134
       inst_lwz_w,
1135
       inst_mfspr_w,
1136
       inst_mtspr_w,
1137
       inst_movhi_w,
1138
       inst_nop_w,
1139
       inst_ori_w,
1140
       inst_rfe_w,
1141
       inst_sb_w,
1142
       inst_sh_w,
1143
       inst_sw_w,
1144
       inst_xori_w,
1145
       inst_slli_w,
1146
       inst_srai_w,
1147
       inst_srli_w,
1148
       inst_sfeq_w,
1149
       inst_sfges_w,
1150
       inst_sfgeu_w,
1151
       inst_sfgts_w,
1152
       inst_sfgtu_w,
1153
       inst_sfles_w,
1154
       inst_sfleu_w,
1155
       inst_sflts_w,
1156
       inst_sfltu_w,
1157
       inst_sfne_w,
1158
       inst_sys_w,
1159
       inst_trap_w:
1160
          invalid_inst_r = 1'b0;
1161
       default:
1162
          invalid_inst_r = 1'b1;
1163
    endcase
1164
end
1165
 
1166
//-----------------------------------------------------------------
1167
// Execute: ALU control
1168
//-----------------------------------------------------------------
1169
always @ (posedge clk_i or posedge rst_i)
1170
begin
1171
   if (rst_i == 1'b1)
1172
   begin
1173
       r_e_alu_func         <= `ALU_NONE;
1174
       r_e_alu_a            <= 32'h00000000;
1175
       r_e_alu_b            <= 32'h00000000;
1176
       r_e_rd               <= 5'b00000;
1177
   end
1178
   else
1179
   begin
1180
           // Update ALU input flops
1181
           r_e_alu_func         <= alu_func_r;
1182
           r_e_alu_a            <= alu_input_a_r;
1183
           r_e_alu_b            <= alu_input_b_r;
1184
 
1185
           // Branch and link (Rd = LR/R9)
1186
           if (branch_link_r)
1187
              r_e_rd            <= 5'd9;
1188
           // Instruction with register writeback
1189
           else if (write_rd_r)
1190
              r_e_rd            <= w_rd;
1191
           else
1192
              r_e_rd            <= 5'b0;
1193
   end
1194
end
1195
 
1196
//-----------------------------------------------------------------
1197
// Execute: Branch / exceptions
1198
//-----------------------------------------------------------------
1199
always @ (posedge clk_i or posedge rst_i)
1200
begin
1201
   if (rst_i == 1'b1)
1202
   begin
1203
       r_pc                 <= BOOT_VECTOR + `VECTOR_RESET;
1204
 
1205
       // Status registers
1206
       r_epc                <= 32'h00000000;
1207
       r_sr                 <= 32'h00000000;
1208
       r_esr                <= 32'h00000000;
1209
 
1210
       fault_o              <= 1'b0;
1211
 
1212
       r_nmi                <= 1'b0;
1213
   end
1214
   else
1215
   begin
1216
      // Record NMI in-case it can't be processed this cycle
1217
      if (nmi_i)
1218
          r_nmi             <= 1'b1;
1219
 
1220
       // Core disabled?
1221
       if (~enable_i)
1222
       begin
1223
           // Reset
1224
           r_pc                 <= BOOT_VECTOR + `VECTOR_RESET;
1225
 
1226
           // Status registers
1227
           r_epc                <= 32'h00000000;
1228
           r_sr                 <= 32'h00000000;
1229
           r_esr                <= 32'h00000000;
1230
 
1231
           fault_o              <= 1'b0;
1232
 
1233
           r_nmi                <= 1'b0;
1234
       end
1235
       // Write-back?
1236
       else if (w_write_en)
1237
       begin
1238
           // Update SR
1239
           r_sr                 <= next_sr_r;
1240
 
1241
           // Exception: Instruction opcode not valid / supported, invalid PC
1242
           if (invalid_inst_r || (r_pc[1:0] != 2'b00))
1243
           begin
1244
                // Save PC of next instruction
1245
                r_epc       <= next_pc_r;
1246
                r_esr       <= next_sr_r;
1247
 
1248
                // Disable further interrupts
1249
                r_sr        <= 32'b0;
1250
 
1251
                // Set PC to exception vector
1252
                if (invalid_inst_r)
1253
                    r_pc    <= ISR_VECTOR + `VECTOR_ILLEGAL_INST;
1254
                else
1255
                    r_pc    <= ISR_VECTOR + `VECTOR_BUS_ERROR;
1256
 
1257
                fault_o     <= 1'b1;
1258
           end
1259
           // Exception: Syscall / Break
1260
           else if (branch_except_r)
1261
           begin
1262
                // Save PC of next instruction
1263
                r_epc       <= next_pc_r;
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_target_r;
1271
 
1272
    `ifdef CONF_CORE_DEBUG
1273
               $display(" Exception 0x%08x", branch_target_r);
1274
    `endif
1275
           end
1276
           // Non-maskable interrupt
1277
           else if (nmi_i | r_nmi)
1278
           begin
1279
                r_nmi       <= 1'b0;
1280
 
1281
                // Save PC of next instruction
1282
                if (branch_r)
1283
                    r_epc <= branch_target_r;
1284
                // Next expected PC (current PC + 4)
1285
                else
1286
                    r_epc <= next_pc_r;
1287
 
1288
                r_esr       <= next_sr_r;
1289
 
1290
                // Disable further interrupts
1291
                r_sr        <= 32'b0;
1292
 
1293
                // Set PC to exception vector
1294
                r_pc        <= ISR_VECTOR + `VECTOR_NMI;
1295
 
1296
    `ifdef CONF_CORE_DEBUG
1297
               $display(" NMI 0x%08x", ISR_VECTOR + `VECTOR_NMI);
1298
    `endif
1299
           end
1300
           // External interrupt
1301
           else if (intr_i && next_sr_r[`OR32_SR_IEE])
1302
           begin
1303
                // Save PC of next instruction & SR
1304
                if (branch_r)
1305
                    r_epc <= branch_target_r;
1306
                // Next expected PC (current PC + 4)
1307
                else
1308
                    r_epc <= next_pc_r;
1309
 
1310
                r_esr       <= next_sr_r;
1311
 
1312
                // Disable further interrupts
1313
                r_sr        <= 32'b0;
1314
 
1315
                // Set PC to external interrupt vector
1316
                r_pc        <= ISR_VECTOR + `VECTOR_EXTINT;
1317
 
1318
    `ifdef CONF_CORE_DEBUG
1319
               $display(" External Interrupt 0x%08x", ISR_VECTOR + `VECTOR_EXTINT);
1320
    `endif
1321
           end
1322
           // Branch (l.bf, l.bnf, l.j, l.jal, l.jr, l.jalr, l.rfe)
1323
           else if (branch_r)
1324
           begin
1325
                // Perform branch
1326
                r_pc        <= branch_target_r;
1327
 
1328
    `ifdef CONF_CORE_DEBUG
1329
               $display(" Branch to 0x%08x", branch_target_r);
1330
    `endif
1331
           end
1332
           // Non branch
1333
           else
1334
           begin
1335
                // Update EPC / ESR which may have been updated
1336
                // by an MTSPR write
1337
                r_pc           <= next_pc_r;
1338
                r_epc          <= next_epc_r;
1339
                r_esr          <= next_esr_r;
1340
           end
1341
      end
1342
   end
1343
end
1344
 
1345
//-------------------------------------------------------------------
1346
// Load result
1347
//-------------------------------------------------------------------
1348
always @ *
1349
begin
1350
    r_load_result   = 32'h00000000;
1351
 
1352
    case (1'b1)
1353
 
1354
        inst_lbs_w, // l.lbs
1355
        inst_lbz_w: // l.lbz
1356
        begin
1357
            case (mem_offset)
1358
                2'b00 :   r_load_result[7:0] = mem_dat_i[31:24];
1359
                2'b01 :   r_load_result[7:0] = mem_dat_i[23:16];
1360
                2'b10 :   r_load_result[7:0] = mem_dat_i[15:8];
1361
                2'b11 :   r_load_result[7:0] = mem_dat_i[7:0];
1362
                default : ;
1363
            endcase
1364
 
1365
            // Sign extend LB
1366
            if (inst_lbs_w && r_load_result[7])
1367
                r_load_result[31:8] = 24'hFFFFFF;
1368
        end
1369
 
1370
        inst_lhs_w, // l.lhs
1371
        inst_lhz_w: // l.lhz
1372
        begin
1373
            case (mem_offset)
1374
                2'b00 :   r_load_result[15:0] = mem_dat_i[31:16];
1375
                2'b10 :   r_load_result[15:0] = mem_dat_i[15:0];
1376
                default : ;
1377
            endcase
1378
 
1379
            // Sign extend LH
1380
            if (inst_lhs_w && r_load_result[15])
1381
                r_load_result[31:16] = 16'hFFFF;
1382
        end
1383
 
1384
        // l.lwz l.lws
1385
        default :
1386
            r_load_result   = mem_dat_i;
1387
    endcase
1388
end
1389
 
1390
//-----------------------------------------------------------------
1391
// Execute: Misc operations
1392
//-----------------------------------------------------------------
1393
always @ (posedge clk_i or posedge rst_i)
1394
begin
1395
   if (rst_i == 1'b1)
1396
   begin
1397
       break_o              <= 1'b0;
1398
   end
1399
   else
1400
   begin
1401
       break_o              <= 1'b0;
1402
 
1403
       case (1'b1)
1404
       inst_trap_w: // l.trap
1405
            break_o         <= 1'b1;
1406
       default:
1407
          ;
1408
      endcase
1409
   end
1410
end
1411
 
1412
//-----------------------------------------------------------------
1413
// Execute: NOP (simulation) operations
1414
//-----------------------------------------------------------------
1415
`ifdef SIMULATION
1416
    always @ (posedge clk_i or posedge rst_i)
1417
    begin
1418
       if (rst_i == 1'b1)
1419
       begin
1420
    `ifdef SIM_EXT_PUTC
1421
          r_putc                <= 8'b0;
1422
    `endif
1423
       end
1424
       else
1425
       begin
1426
    `ifdef SIM_EXT_PUTC
1427
          r_putc                <= 8'b0;
1428
    `endif
1429
          if (inst_nop_w && state == STATE_EXEC)
1430
          begin
1431
                case (uint16_r)
1432
                // NOP_PUTC
1433
                16'h0004:
1434
                begin
1435
  `ifdef SIM_EXT_PUTC
1436
                  r_putc  <= reg_ra_r[7:0];
1437
  `else
1438
                  $write("%c", reg_ra_r[7:0]);
1439
  `endif
1440
                end
1441
                // NOP
1442
                16'h0000: ;
1443
                endcase
1444
          end
1445
       end
1446
    end
1447
`endif
1448
 
1449
`include "altor32_funcs.v"
1450
 
1451
//-------------------------------------------------------------------
1452
// Hooks for debug
1453
//-------------------------------------------------------------------
1454
`ifdef verilator
1455
   function [31:0] get_opcode_ex;
1456
      // verilator public
1457
      get_opcode_ex = (state == STATE_EXEC) ? r_opcode : `OPCODE_INST_BUBBLE;
1458
   endfunction
1459
   function [31:0] get_pc_ex;
1460
      // verilator public
1461
      get_pc_ex = r_pc;
1462
   endfunction
1463
   function [7:0] get_putc;
1464
      // verilator public
1465
   `ifdef SIM_EXT_PUTC
1466
      get_putc = r_putc;
1467
   `else
1468
      get_putc = 8'b0;
1469
   `endif
1470
   endfunction
1471
   function [0:0] get_reg_valid;
1472
      // verilator public
1473
      get_reg_valid = (state == STATE_EXEC) ? 1'b1 : 1'b0;
1474
   endfunction
1475
   function [4:0] get_reg_ra;
1476
      // verilator public
1477
      get_reg_ra = w_ra;
1478
   endfunction
1479
   function [31:0] get_reg_ra_value;
1480
      // verilator public
1481
      get_reg_ra_value = w_reg_ra;
1482
   endfunction
1483
   function [4:0] get_reg_rb;
1484
      // verilator public
1485
      get_reg_rb = w_rb;
1486
   endfunction
1487
   function [31:0] get_reg_rb_value;
1488
      // verilator public
1489
      get_reg_rb_value = w_reg_rb;
1490
   endfunction
1491
`endif
1492
 
1493
endmodule

powered by: WebSVN 2.1.0

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