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

Subversion Repositories altor32

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

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

powered by: WebSVN 2.1.0

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