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

Subversion Repositories altor32

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

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

powered by: WebSVN 2.1.0

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