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

Subversion Repositories amber

[/] [amber/] [trunk/] [hw/] [vlog/] [amber25/] [a25_execute.v] - Blame information for rev 89

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 16 csantifort
//////////////////////////////////////////////////////////////////
2
//                                                              //
3
//  Execute stage of Amber 25 Core                              //
4
//                                                              //
5
//  This file is part of the Amber project                      //
6
//  http://www.opencores.org/project,amber                      //
7
//                                                              //
8
//  Description                                                 //
9
//  Executes instructions. Instantiates the register file, ALU  //
10
//  multiplication unit and barrel shifter. This stage is       //
11
//  relitively simple. All the complex stuff is done in the     //
12
//  decode stage.                                               //
13
//                                                              //
14
//  Author(s):                                                  //
15
//      - Conor Santifort, csantifort.amber@gmail.com           //
16
//                                                              //
17
//////////////////////////////////////////////////////////////////
18
//                                                              //
19
// Copyright (C) 2011 Authors and OPENCORES.ORG                 //
20
//                                                              //
21
// This source file may be used and distributed without         //
22
// restriction provided that this copyright statement is not    //
23
// removed from the file and that any derivative work contains  //
24
// the original copyright notice and the associated disclaimer. //
25
//                                                              //
26
// This source file is free software; you can redistribute it   //
27
// and/or modify it under the terms of the GNU Lesser General   //
28
// Public License as published by the Free Software Foundation; //
29
// either version 2.1 of the License, or (at your option) any   //
30
// later version.                                               //
31
//                                                              //
32
// This source is distributed in the hope that it will be       //
33
// useful, but WITHOUT ANY WARRANTY; without even the implied   //
34
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      //
35
// PURPOSE.  See the GNU Lesser General Public License for more //
36
// details.                                                     //
37
//                                                              //
38
// You should have received a copy of the GNU Lesser General    //
39
// Public License along with this source; if not, download it   //
40
// from http://www.opencores.org/lgpl.shtml                     //
41
//                                                              //
42
//////////////////////////////////////////////////////////////////
43
 
44
 
45
module a25_execute (
46
 
47
input                       i_clk,
48 35 csantifort
input                       i_core_stall,               // stall all stages of the Amber core at the same time
49 16 csantifort
input                       i_mem_stall,                // data memory access stalls
50 35 csantifort
output                      o_exec_stall,               // stall the core pipeline
51 16 csantifort
 
52
input       [31:0]          i_wb_read_data,             // data reads
53
input                       i_wb_read_data_valid,       // read data is valid
54 35 csantifort
input       [10:0]          i_wb_load_rd,               // Rd for data reads
55 16 csantifort
 
56 89 csantifort
input       [31:0]          i_copro_read_data,          // From Co-Processor, to either Register
57 16 csantifort
                                                        // or Memory
58
input                       i_decode_iaccess,           // Indicates an instruction access
59
input                       i_decode_daccess,           // Indicates a data access
60
input       [7:0]           i_decode_load_rd,           // The destination register for a load instruction
61
 
62
output reg  [31:0]          o_copro_write_data = 'd0,
63
output reg  [31:0]          o_write_data = 'd0,
64 89 csantifort
output wire [31:0]          o_iaddress,
65
output      [31:0]          o_iaddress_nxt,             // un-registered version of address to the
66 16 csantifort
                                                        // cache rams address ports
67
output reg                  o_iaddress_valid = 'd0,     // High when instruction address is valid
68
output reg  [31:0]          o_daddress = 32'h0,         // Address to data cache
69 89 csantifort
output      [31:0]          o_daddress_nxt,             // un-registered version of address to the
70 16 csantifort
                                                        // cache rams address ports
71
output reg                  o_daddress_valid = 'd0,     // High when data address is valid
72
output reg                  o_adex = 'd0,               // Address Exception
73
output reg                  o_priviledged = 'd0,        // Priviledged access
74
output reg                  o_exclusive = 'd0,          // swap access
75
output reg                  o_write_enable = 'd0,
76
output reg  [3:0]           o_byte_enable = 'd0,
77 35 csantifort
output reg  [8:0]           o_exec_load_rd = 'd0,       // The destination register for a load instruction
78 16 csantifort
output      [31:0]          o_status_bits,              // Full PC will all status bits, but PC part zero'ed out
79
output                      o_multiply_done,
80
 
81
 
82
// --------------------------------------------------
83
// Control signals from Instruction Decode stage
84
// --------------------------------------------------
85
input      [1:0]            i_status_bits_mode,
86
input                       i_status_bits_irq_mask,
87
input                       i_status_bits_firq_mask,
88
input      [31:0]           i_imm32,
89
input      [4:0]            i_imm_shift_amount,
90
input                       i_shift_imm_zero,
91
input      [3:0]            i_condition,
92
input                       i_decode_exclusive,       // swap access
93
 
94
input      [3:0]            i_rm_sel,
95
input      [3:0]            i_rs_sel,
96
input      [3:0]            i_rn_sel,
97
input      [1:0]            i_barrel_shift_amount_sel,
98
input      [1:0]            i_barrel_shift_data_sel,
99
input      [1:0]            i_barrel_shift_function,
100
input      [8:0]            i_alu_function,
101
input      [1:0]            i_multiply_function,
102
input      [2:0]            i_interrupt_vector_sel,
103
input      [3:0]            i_iaddress_sel,
104
input      [3:0]            i_daddress_sel,
105
input      [2:0]            i_pc_sel,
106
input      [1:0]            i_byte_enable_sel,
107
input      [2:0]            i_status_bits_sel,
108
input      [2:0]            i_reg_write_sel,
109
input                       i_user_mode_regs_store_nxt,
110
input                       i_firq_not_user_mode,
111 83 csantifort
input                       i_use_carry_in,         // e.g. add with carry instruction
112 16 csantifort
 
113
input                       i_write_data_wen,
114 89 csantifort
input                       i_base_address_wen,     // save LDM base address register,
115 16 csantifort
                                                    // in case of data abort
116
input                       i_pc_wen,
117
input      [14:0]           i_reg_bank_wen,
118
input                       i_status_bits_flags_wen,
119
input                       i_status_bits_mode_wen,
120
input                       i_status_bits_irq_mask_wen,
121
input                       i_status_bits_firq_mask_wen,
122
input                       i_copro_write_data_wen,
123 20 csantifort
input                       i_conflict,
124
input                       i_rn_use_read,
125
input                       i_rm_use_read,
126
input                       i_rs_use_read,
127
input                       i_rd_use_read
128 16 csantifort
);
129
 
130 82 csantifort
`include "a25_localparams.vh"
131
`include "a25_functions.vh"
132 16 csantifort
 
133
// ========================================================
134
// Internal signals
135
// ========================================================
136
wire [31:0]         write_data_nxt;
137
wire [3:0]          byte_enable_nxt;
138
wire [31:0]         pc_plus4;
139
wire [31:0]         pc_minus4;
140
wire [31:0]         daddress_plus4;
141
wire [31:0]         alu_plus4;
142
wire [31:0]         rn_plus4;
143
wire [31:0]         alu_out;
144
wire [3:0]          alu_flags;
145
wire [31:0]         rm;
146
wire [31:0]         rs;
147
wire [31:0]         rd;
148
wire [31:0]         rn;
149 20 csantifort
wire [31:0]         reg_bank_rn;
150
wire [31:0]         reg_bank_rm;
151
wire [31:0]         reg_bank_rs;
152
wire [31:0]         reg_bank_rd;
153 16 csantifort
wire [31:0]         pc;
154
wire [31:0]         pc_nxt;
155
wire [31:0]         interrupt_vector;
156
wire [7:0]          shift_amount;
157
wire [31:0]         barrel_shift_in;
158
wire [31:0]         barrel_shift_out;
159
wire                barrel_shift_carry;
160 35 csantifort
wire                barrel_shift_stall;
161 88 csantifort
wire                barrel_shift_carry_alu;
162 16 csantifort
 
163
wire [3:0]          status_bits_flags_nxt;
164
reg  [3:0]          status_bits_flags = 'd0;
165
wire [1:0]          status_bits_mode_nxt;
166
reg  [1:0]          status_bits_mode = SVC;
167
                    // one-hot encoded rs select
168
wire [3:0]          status_bits_mode_rds_oh_nxt;
169
reg  [3:0]          status_bits_mode_rds_oh = 1'd1 << OH_SVC;
170
wire                status_bits_mode_rds_oh_update;
171
wire                status_bits_irq_mask_nxt;
172
reg                 status_bits_irq_mask = 1'd1;
173
wire                status_bits_firq_mask_nxt;
174
reg                 status_bits_firq_mask = 1'd1;
175 35 csantifort
wire [8:0]          exec_load_rd_nxt;
176 16 csantifort
 
177
wire                execute;                    // high when condition execution is true
178
wire [31:0]         reg_write_nxt;
179
wire                pc_wen;
180
wire [14:0]         reg_bank_wen;
181
wire [31:0]         multiply_out;
182
wire [1:0]          multiply_flags;
183 89 csantifort
reg  [31:0]         base_address = 'd0;             // Saves base address during LDM instruction in
184 16 csantifort
                                                    // case of data abort
185
wire [31:0]         read_data_filtered1;
186
wire [31:0]         read_data_filtered;
187 20 csantifort
wire [31:0]         read_data_filtered_c;
188
reg  [31:0]         read_data_filtered_r = 'd0;
189 86 csantifort
reg  [5:0]          load_rd_r = 'd0;
190
wire [5:0]          load_rd_c;
191 16 csantifort
 
192
wire                write_enable_nxt;
193
wire                daddress_valid_nxt;
194
wire                iaddress_valid_nxt;
195 89 csantifort
wire                priviledged_nxt;
196 16 csantifort
wire                priviledged_update;
197
wire                iaddress_update;
198
wire                daddress_update;
199
wire                base_address_update;
200
wire                write_data_update;
201
wire                copro_write_data_update;
202
wire                byte_enable_update;
203
wire                exec_load_rd_update;
204
wire                write_enable_update;
205
wire                exclusive_update;
206
wire                status_bits_flags_update;
207
wire                status_bits_mode_update;
208
wire                status_bits_irq_mask_update;
209
wire                status_bits_firq_mask_update;
210
 
211
wire [31:0]         alu_out_pc_filtered;
212
wire                adex_nxt;
213
wire [31:0]         save_int_pc;
214
wire [31:0]         save_int_pc_m4;
215
wire                ldm_flags;
216
wire                ldm_status_bits;
217
 
218 83 csantifort
wire                carry_in;
219
 
220 89 csantifort
reg   [31:0]        iaddress_r = 32'hdead_dead;
221 83 csantifort
 
222 89 csantifort
 
223 16 csantifort
// ========================================================
224
// Status Bits in PC register
225
// ========================================================
226 54 csantifort
wire [1:0] status_bits_mode_out;
227 89 csantifort
assign status_bits_mode_out = (i_status_bits_mode_wen && i_status_bits_sel == 3'd1 && !ldm_status_bits) ?
228 54 csantifort
                                    alu_out[1:0] : status_bits_mode ;
229
 
230 16 csantifort
assign o_status_bits = {   status_bits_flags,           // 31:28
231
                           status_bits_irq_mask,        // 7
232
                           status_bits_firq_mask,       // 6
233
                           24'd0,
234 54 csantifort
                           status_bits_mode_out };      // 1:0 = mode
235 16 csantifort
 
236
 
237
// ========================================================
238
// Status Bits Select
239
// ========================================================
240 35 csantifort
assign ldm_flags                 = i_wb_read_data_valid & ~i_mem_stall & i_wb_load_rd[8];
241
assign ldm_status_bits           = i_wb_read_data_valid & ~i_mem_stall & i_wb_load_rd[7];
242 16 csantifort
 
243
 
244
assign status_bits_flags_nxt     = ldm_flags                 ? read_data_filtered[31:28]           :
245
                                   i_status_bits_sel == 3'd0 ? alu_flags                           :
246
                                   i_status_bits_sel == 3'd1 ? alu_out          [31:28]            :
247
                                   i_status_bits_sel == 3'd3 ? i_copro_read_data[31:28]            :
248
                                   // 4 = update flags after a multiply operation
249 82 csantifort
                                   i_status_bits_sel == 3'd4 ? { multiply_flags, status_bits_flags[1:0] } :
250
                                   // regops that do not change the overflow flag
251 89 csantifort
                                   i_status_bits_sel == 3'd5 ? { alu_flags[3:1], status_bits_flags[0] } :
252 82 csantifort
                                                               4'b1111 ;
253 16 csantifort
 
254
assign status_bits_mode_nxt      = ldm_status_bits           ? read_data_filtered [1:0] :
255
                                   i_status_bits_sel == 3'd0 ? i_status_bits_mode       :
256 82 csantifort
                                   i_status_bits_sel == 3'd5 ? i_status_bits_mode       :
257 16 csantifort
                                   i_status_bits_sel == 3'd1 ? alu_out            [1:0] :
258
                                                               i_copro_read_data  [1:0] ;
259
 
260
 
261
// Used for the Rds output of register_bank - this special version of
262
// status_bits_mode speeds up the critical path from status_bits_mode through the
263
// register_bank, barrel_shifter and alu. It moves a mux needed for the
264
// i_user_mode_regs_store_nxt signal back into the previous stage -
265
// so its really part of the decode stage even though the logic is right here
266
// In addition the signal is one-hot encoded to further speed up the logic
267
 
268
assign status_bits_mode_rds_oh_nxt    = i_user_mode_regs_store_nxt ? 1'd1 << OH_USR                            :
269
                                        status_bits_mode_update    ? oh_status_bits_mode(status_bits_mode_nxt) :
270
                                                                     oh_status_bits_mode(status_bits_mode)     ;
271
 
272 89 csantifort
 
273 16 csantifort
assign status_bits_irq_mask_nxt  = ldm_status_bits           ? read_data_filtered     [27] :
274
                                   i_status_bits_sel == 3'd0 ? i_status_bits_irq_mask      :
275 82 csantifort
                                   i_status_bits_sel == 3'd5 ? i_status_bits_irq_mask      :
276 16 csantifort
                                   i_status_bits_sel == 3'd1 ? alu_out                [27] :
277
                                                               i_copro_read_data      [27] ;
278 89 csantifort
 
279 16 csantifort
assign status_bits_firq_mask_nxt = ldm_status_bits           ? read_data_filtered     [26] :
280
                                   i_status_bits_sel == 3'd0 ? i_status_bits_firq_mask     :
281 82 csantifort
                                   i_status_bits_sel == 3'd5 ? i_status_bits_firq_mask     :
282 16 csantifort
                                   i_status_bits_sel == 3'd1 ? alu_out                [26] :
283
                                                               i_copro_read_data      [26] ;
284
 
285
 
286
 
287
// ========================================================
288
// Adders
289
// ========================================================
290
assign pc_plus4       = pc         + 32'd4;
291
assign pc_minus4      = pc         - 32'd4;
292
assign daddress_plus4 = o_daddress + 32'd4;
293
assign alu_plus4      = alu_out    + 32'd4;
294
assign rn_plus4       = rn         + 32'd4;
295
 
296
// ========================================================
297
// Barrel Shift Amount Select
298
// ========================================================
299
// An immediate shift value of 0 is translated into 32
300
assign shift_amount = i_barrel_shift_amount_sel == 2'd0 ? 8'd0                         :
301
                      i_barrel_shift_amount_sel == 2'd1 ? rs[7:0]                      :
302
                                                          {3'd0, i_imm_shift_amount  } ;
303
 
304
 
305
// ========================================================
306
// Barrel Shift Data Select
307
// ========================================================
308
assign barrel_shift_in = i_barrel_shift_data_sel == 2'd0 ? i_imm32 : rm ;
309
 
310
 
311
// ========================================================
312
// Interrupt vector Select
313
// ========================================================
314
 
315
assign interrupt_vector = // Reset vector
316 89 csantifort
                          (i_interrupt_vector_sel == 3'd0) ? 32'h00000000 :
317
                          // Data abort interrupt vector
318 16 csantifort
                          (i_interrupt_vector_sel == 3'd1) ? 32'h00000010 :
319 89 csantifort
                          // Fast interrupt vector
320 16 csantifort
                          (i_interrupt_vector_sel == 3'd2) ? 32'h0000001c :
321
                          // Regular interrupt vector
322
                          (i_interrupt_vector_sel == 3'd3) ? 32'h00000018 :
323
                          // Prefetch abort interrupt vector
324
                          (i_interrupt_vector_sel == 3'd5) ? 32'h0000000c :
325
                          // Undefined instruction interrupt vector
326
                          (i_interrupt_vector_sel == 3'd6) ? 32'h00000004 :
327
                          // Software (SWI) interrupt vector
328
                          (i_interrupt_vector_sel == 3'd7) ? 32'h00000008 :
329
                          // Default is the address exception interrupt
330
                                                             32'h00000014 ;
331
 
332
 
333
// ========================================================
334
// Address Select
335
// ========================================================
336
assign pc_dmem_wen    = i_wb_read_data_valid & ~i_mem_stall & i_wb_load_rd[3:0] == 4'd15;
337
 
338
// If rd is the pc, then seperate the address bits from the status bits for
339
// generating the next address to fetch
340
assign alu_out_pc_filtered = pc_wen && i_pc_sel == 3'd1 ? pcf(alu_out) : alu_out;
341
 
342
// if current instruction does not execute because it does not meet the condition
343
// then address advances to next instruction
344
assign o_iaddress_nxt = (pc_dmem_wen)            ? pcf(read_data_filtered) :
345 89 csantifort
                        (!execute)               ? pc_plus4                :
346 16 csantifort
                        (i_iaddress_sel == 4'd0) ? pc_plus4                :
347
                        (i_iaddress_sel == 4'd1) ? alu_out_pc_filtered     :
348
                        (i_iaddress_sel == 4'd2) ? interrupt_vector        :
349
                                                   pc                      ;
350
 
351
 
352
 
353
// if current instruction does not execute because it does not meet the condition
354
// then address advances to next instruction
355
assign o_daddress_nxt = (i_daddress_sel == 4'd1) ? alu_out_pc_filtered   :
356
                        (i_daddress_sel == 4'd2) ? interrupt_vector      :
357
                        (i_daddress_sel == 4'd4) ? rn                    :
358
                        (i_daddress_sel == 4'd5) ? daddress_plus4        :  // MTRANS address incrementer
359
                        (i_daddress_sel == 4'd6) ? alu_plus4             :  // MTRANS decrement after
360
                                                   rn_plus4              ;  // MTRANS increment before
361
 
362
// Data accesses use 32-bit address space, but instruction
363
// accesses are restricted to 26 bit space
364
assign adex_nxt      = |o_iaddress_nxt[31:26] && i_decode_iaccess;
365
 
366
 
367
// ========================================================
368
// Filter Read Data
369
// ========================================================
370 35 csantifort
// mem_load_rd[10:9]-> shift ROR bytes
371
// mem_load_rd[8]   -> load flags with PC
372
// mem_load_rd[7]   -> load status bits with PC
373
// mem_load_rd[6:5] -> Write into this Mode registers
374 16 csantifort
// mem_load_rd[4]   -> zero_extend byte
375 89 csantifort
// mem_load_rd[3:0] -> Destination Register
376 53 csantifort
assign read_data_filtered1 = i_wb_load_rd[10:9] == 2'd0 ? i_wb_read_data                                :
377
                             i_wb_load_rd[10:9] == 2'd1 ? {i_wb_read_data[7:0],  i_wb_read_data[31:8]}  :
378
                             i_wb_load_rd[10:9] == 2'd2 ? {i_wb_read_data[15:0], i_wb_read_data[31:16]} :
379
                                                          {i_wb_read_data[23:0], i_wb_read_data[31:24]} ;
380 16 csantifort
 
381 89 csantifort
assign read_data_filtered  = i_wb_load_rd[4] ? {24'd0, read_data_filtered1[7:0]} : read_data_filtered1 ;
382 16 csantifort
 
383
 
384
// ========================================================
385
// Program Counter Select
386
// ========================================================
387
// If current instruction does not execute because it does not meet the condition
388
// then PC advances to next instruction
389
assign pc_nxt = (!execute)       ? pc_plus4                :
390
                i_pc_sel == 3'd0 ? pc_plus4                :
391
                i_pc_sel == 3'd1 ? alu_out                 :
392
                i_pc_sel == 3'd2 ? interrupt_vector        :
393
                i_pc_sel == 3'd3 ? pcf(read_data_filtered) :
394
                                   pc_minus4               ;
395
 
396
 
397
// ========================================================
398
// Register Write Select
399
// ========================================================
400
 
401 89 csantifort
assign save_int_pc    = { status_bits_flags,
402
                          status_bits_irq_mask,
403
                          status_bits_firq_mask,
404
                          pc[25:2],
405 16 csantifort
                          status_bits_mode      };
406
 
407
 
408 89 csantifort
assign save_int_pc_m4 = { status_bits_flags,
409
                          status_bits_irq_mask,
410
                          status_bits_firq_mask,
411
                          pc_minus4[25:2],
412 16 csantifort
                          status_bits_mode      };
413
 
414
 
415
assign reg_write_nxt = i_reg_write_sel == 3'd0 ? alu_out               :
416 89 csantifort
                       // save pc to lr on an interrupt
417 16 csantifort
                       i_reg_write_sel == 3'd1 ? save_int_pc_m4        :
418
                       // to update Rd at the end of Multiplication
419
                       i_reg_write_sel == 3'd2 ? multiply_out          :
420
                       i_reg_write_sel == 3'd3 ? o_status_bits         :
421
                       i_reg_write_sel == 3'd5 ? i_copro_read_data     :  // mrc
422
                       i_reg_write_sel == 3'd6 ? base_address          :
423 89 csantifort
                                                 save_int_pc           ;
424 16 csantifort
 
425
 
426
// ========================================================
427
// Byte Enable Select
428
// ========================================================
429
assign byte_enable_nxt = i_byte_enable_sel == 2'd0   ? 4'b1111 :  // word write
430
                         i_byte_enable_sel == 2'd2   ?            // halfword write
431 89 csantifort
                         ( o_daddress_nxt[1] == 1'd0 ? 4'b0011 :
432 16 csantifort
                                                       4'b1100  ) :
433 89 csantifort
 
434 16 csantifort
                         o_daddress_nxt[1:0] == 2'd0 ? 4'b0001 :  // byte write
435
                         o_daddress_nxt[1:0] == 2'd1 ? 4'b0010 :
436
                         o_daddress_nxt[1:0] == 2'd2 ? 4'b0100 :
437
                                                       4'b1000 ;
438
 
439
 
440
// ========================================================
441
// Write Data Select
442
// ========================================================
443
assign write_data_nxt = i_byte_enable_sel == 2'd0 ? rd            :
444
                                                    {4{rd[ 7:0]}} ;
445
 
446
 
447
// ========================================================
448
// Conditional Execution
449
// ========================================================
450
assign execute = conditional_execute ( i_condition, status_bits_flags );
451 89 csantifort
 
452 16 csantifort
// allow the PC to increment to the next instruction when current
453
// instruction does not execute
454
assign pc_wen       = (i_pc_wen || !execute) && !i_conflict;
455
 
456
// only update register bank if current instruction executes
457
assign reg_bank_wen = {{15{execute}} & i_reg_bank_wen};
458
 
459
 
460
// ========================================================
461
// Priviledged output flag
462
// ========================================================
463
// Need to look at status_bits_mode_nxt so switch to priviledged mode
464
// at the same time as assert interrupt vector address
465
assign priviledged_nxt  = ( i_status_bits_mode_wen ? status_bits_mode_nxt : status_bits_mode ) != USR ;
466
 
467
 
468
// ========================================================
469
// Write Enable
470
// ========================================================
471
// This must be de-asserted when execute is fault
472
assign write_enable_nxt = execute && i_write_data_wen;
473
 
474
 
475
// ========================================================
476
// Address Valid
477
// ========================================================
478 35 csantifort
assign daddress_valid_nxt = execute && i_decode_daccess && !i_core_stall;
479 16 csantifort
 
480 20 csantifort
// For some multi-cycle instructions, the stream of instrution
481
// reads can be paused. However if the instruction does not execute
482
// then the read stream must not be interrupted.
483
assign iaddress_valid_nxt = i_decode_iaccess || !execute;
484 16 csantifort
 
485 20 csantifort
 
486 16 csantifort
// ========================================================
487 20 csantifort
// Use read value from data memory instead of from register
488
// ========================================================
489 86 csantifort
assign rn = i_rn_use_read && i_rn_sel == load_rd_c[3:0] && status_bits_mode == load_rd_c[5:4] ? read_data_filtered_c : reg_bank_rn;
490
assign rm = i_rm_use_read && i_rm_sel == load_rd_c[3:0] && status_bits_mode == load_rd_c[5:4] ? read_data_filtered_c : reg_bank_rm;
491
assign rs = i_rs_use_read && i_rs_sel == load_rd_c[3:0] && status_bits_mode == load_rd_c[5:4] ? read_data_filtered_c : reg_bank_rs;
492
assign rd = i_rd_use_read && i_rs_sel == load_rd_c[3:0] && status_bits_mode == load_rd_c[5:4] ? read_data_filtered_c : reg_bank_rd;
493 20 csantifort
 
494
 
495
always@( posedge i_clk )
496
    if ( i_wb_read_data_valid )
497
        begin
498
        read_data_filtered_r <= read_data_filtered;
499 86 csantifort
        load_rd_r            <= {i_wb_load_rd[6:5], i_wb_load_rd[3:0]};
500 20 csantifort
        end
501
 
502
assign read_data_filtered_c = i_wb_read_data_valid ? read_data_filtered : read_data_filtered_r;
503
 
504 86 csantifort
// the register number and the mode
505
assign load_rd_c            = i_wb_read_data_valid ? {i_wb_load_rd[6:5], i_wb_load_rd[3:0]}  : load_rd_r;
506 20 csantifort
 
507 86 csantifort
 
508 20 csantifort
// ========================================================
509 35 csantifort
// Set mode for the destination registers of a mem read
510
// ========================================================
511
// The mode is either user mode, or the current mode
512 89 csantifort
assign  exec_load_rd_nxt   = { i_decode_load_rd[7:6],
513 35 csantifort
                               i_decode_load_rd[5] ? USR : status_bits_mode,  // 1 bit -> 2 bits
514
                               i_decode_load_rd[4:0] };
515
 
516 89 csantifort
 
517 35 csantifort
// ========================================================
518 16 csantifort
// Register Update
519
// ========================================================
520 35 csantifort
assign o_exec_stall                    = barrel_shift_stall;
521 16 csantifort
 
522 35 csantifort
assign daddress_update                 = !i_core_stall;
523
assign exec_load_rd_update             = !i_core_stall && execute;
524 89 csantifort
assign priviledged_update              = !i_core_stall;
525 35 csantifort
assign exclusive_update                = !i_core_stall && execute;
526
assign write_enable_update             = !i_core_stall;
527
assign write_data_update               = !i_core_stall && execute && i_write_data_wen;
528
assign byte_enable_update              = !i_core_stall && execute && i_write_data_wen;
529 16 csantifort
 
530 35 csantifort
assign iaddress_update                 = pc_dmem_wen || (!i_core_stall && !i_conflict);
531
assign copro_write_data_update         = !i_core_stall && execute && i_copro_write_data_wen;
532 16 csantifort
 
533 89 csantifort
assign base_address_update             = !i_core_stall && execute && i_base_address_wen;
534 35 csantifort
assign status_bits_flags_update        = ldm_flags       || (!i_core_stall && execute && i_status_bits_flags_wen);
535
assign status_bits_mode_update         = ldm_status_bits || (!i_core_stall && execute && i_status_bits_mode_wen);
536
assign status_bits_mode_rds_oh_update  = !i_core_stall;
537
assign status_bits_irq_mask_update     = ldm_status_bits || (!i_core_stall && execute && i_status_bits_irq_mask_wen);
538
assign status_bits_firq_mask_update    = ldm_status_bits || (!i_core_stall && execute && i_status_bits_firq_mask_wen);
539 16 csantifort
 
540
 
541
always @( posedge i_clk )
542 89 csantifort
    begin
543
    o_daddress              <= daddress_update                ? o_daddress_nxt               : o_daddress;
544 16 csantifort
    o_daddress_valid        <= daddress_update                ? daddress_valid_nxt           : o_daddress_valid;
545 35 csantifort
    o_exec_load_rd          <= exec_load_rd_update            ? exec_load_rd_nxt             : o_exec_load_rd;
546 16 csantifort
    o_priviledged           <= priviledged_update             ? priviledged_nxt              : o_priviledged;
547
    o_exclusive             <= exclusive_update               ? i_decode_exclusive           : o_exclusive;
548
    o_write_enable          <= write_enable_update            ? write_enable_nxt             : o_write_enable;
549 89 csantifort
    o_write_data            <= write_data_update              ? write_data_nxt               : o_write_data;
550 16 csantifort
    o_byte_enable           <= byte_enable_update             ? byte_enable_nxt              : o_byte_enable;
551 89 csantifort
    iaddress_r              <= iaddress_update                ? o_iaddress_nxt               : iaddress_r;
552 16 csantifort
    o_iaddress_valid        <= iaddress_update                ? iaddress_valid_nxt           : o_iaddress_valid;
553 89 csantifort
    o_adex                  <= iaddress_update                ? adex_nxt                     : o_adex;
554
    o_copro_write_data      <= copro_write_data_update        ? write_data_nxt               : o_copro_write_data;
555 16 csantifort
 
556 89 csantifort
    base_address            <= base_address_update            ? rn                           : base_address;
557 16 csantifort
 
558
    status_bits_flags       <= status_bits_flags_update       ? status_bits_flags_nxt        : status_bits_flags;
559
    status_bits_mode        <= status_bits_mode_update        ? status_bits_mode_nxt         : status_bits_mode;
560
    status_bits_mode_rds_oh <= status_bits_mode_rds_oh_update ? status_bits_mode_rds_oh_nxt  : status_bits_mode_rds_oh;
561
    status_bits_irq_mask    <= status_bits_irq_mask_update    ? status_bits_irq_mask_nxt     : status_bits_irq_mask;
562
    status_bits_firq_mask   <= status_bits_firq_mask_update   ? status_bits_firq_mask_nxt    : status_bits_firq_mask;
563
    end
564
 
565 89 csantifort
assign o_iaddress = iaddress_r;
566
 
567
 
568 16 csantifort
// ========================================================
569
// Instantiate Barrel Shift
570
// ========================================================
571 83 csantifort
assign carry_in = i_use_carry_in ? status_bits_flags[1] : 1'd0;
572
 
573 16 csantifort
a25_barrel_shift u_barrel_shift  (
574 35 csantifort
    .i_clk            ( i_clk                     ),
575 16 csantifort
    .i_in             ( barrel_shift_in           ),
576 83 csantifort
    .i_carry_in       ( carry_in                  ),
577 16 csantifort
    .i_shift_amount   ( shift_amount              ),
578
    .i_shift_imm_zero ( i_shift_imm_zero          ),
579
    .i_function       ( i_barrel_shift_function   ),
580
 
581
    .o_out            ( barrel_shift_out          ),
582 35 csantifort
    .o_carry_out      ( barrel_shift_carry        ),
583 88 csantifort
    .o_stall          ( barrel_shift_stall        ));
584 16 csantifort
 
585
 
586
// ========================================================
587
// Instantiate ALU
588
// ========================================================
589 89 csantifort
assign barrel_shift_carry_alu =  i_barrel_shift_data_sel == 2'd0 ?
590
                                  (i_imm_shift_amount[4:1] == 0 ? status_bits_flags[1] : i_imm32[31]) :
591 88 csantifort
                                   barrel_shift_carry;
592 89 csantifort
 
593 16 csantifort
a25_alu u_alu (
594 88 csantifort
    .i_a_in                 ( rn                      ),
595
    .i_b_in                 ( barrel_shift_out        ),
596
    .i_barrel_shift_carry   ( barrel_shift_carry_alu  ),
597
    .i_status_bits_carry    ( status_bits_flags[1]    ),
598
    .i_function             ( i_alu_function          ),
599 16 csantifort
 
600 88 csantifort
    .o_out                  ( alu_out                 ),
601
    .o_flags                ( alu_flags               ));
602 16 csantifort
 
603
 
604 88 csantifort
 
605 16 csantifort
// ========================================================
606
// Instantiate Booth 64-bit Multiplier-Accumulator
607
// ========================================================
608
a25_multiply u_multiply (
609
    .i_clk          ( i_clk                 ),
610 35 csantifort
    .i_core_stall   ( i_core_stall          ),
611 16 csantifort
    .i_a_in         ( rs                    ),
612
    .i_b_in         ( rm                    ),
613
    .i_function     ( i_multiply_function   ),
614
    .i_execute      ( execute               ),
615
    .o_out          ( multiply_out          ),
616
    .o_flags        ( multiply_flags        ),  // [1] = N, [0] = Z
617 89 csantifort
    .o_done         ( o_multiply_done       )
618 16 csantifort
);
619
 
620
 
621
// ========================================================
622
// Instantiate Register Bank
623
// ========================================================
624
a25_register_bank u_register_bank(
625
    .i_clk                   ( i_clk                     ),
626 35 csantifort
    .i_core_stall            ( i_core_stall              ),
627 16 csantifort
    .i_mem_stall             ( i_mem_stall               ),
628
    .i_rm_sel                ( i_rm_sel                  ),
629
    .i_rs_sel                ( i_rs_sel                  ),
630
    .i_rn_sel                ( i_rn_sel                  ),
631
    .i_pc_wen                ( pc_wen                    ),
632
    .i_reg_bank_wen          ( reg_bank_wen              ),
633
    .i_pc                    ( pc_nxt[25:2]              ),
634
    .i_reg                   ( reg_write_nxt             ),
635
    .i_mode_idec             ( i_status_bits_mode        ),
636
    .i_mode_exec             ( status_bits_mode          ),
637
 
638
    .i_wb_read_data          ( read_data_filtered        ),
639
    .i_wb_read_data_valid    ( i_wb_read_data_valid      ),
640
    .i_wb_read_data_rd       ( i_wb_load_rd[3:0]         ),
641 35 csantifort
    .i_wb_mode               ( i_wb_load_rd[6:5]         ),
642 16 csantifort
 
643
    .i_status_bits_flags     ( status_bits_flags         ),
644
    .i_status_bits_irq_mask  ( status_bits_irq_mask      ),
645
    .i_status_bits_firq_mask ( status_bits_firq_mask     ),
646
 
647
    // pre-encoded in decode stage to speed up long path
648
    .i_firq_not_user_mode    ( i_firq_not_user_mode      ),
649 89 csantifort
 
650 16 csantifort
    // use one-hot version for speed, combine with i_user_mode_regs_store
651 89 csantifort
    .i_mode_rds_exec         ( status_bits_mode_rds_oh   ),
652
 
653 20 csantifort
    .o_rm                    ( reg_bank_rm               ),
654
    .o_rs                    ( reg_bank_rs               ),
655
    .o_rd                    ( reg_bank_rd               ),
656
    .o_rn                    ( reg_bank_rn               ),
657 16 csantifort
    .o_pc                    ( pc                        )
658
);
659
 
660
 
661 20 csantifort
 
662 16 csantifort
// ========================================================
663
// Debug - non-synthesizable code
664
// ========================================================
665
//synopsys translate_off
666
 
667
wire    [(2*8)-1:0]    xCONDITION;
668
wire    [(4*8)-1:0]    xMODE;
669
 
670
assign  xCONDITION           = i_condition == EQ ? "EQ"  :
671
                               i_condition == NE ? "NE"  :
672
                               i_condition == CS ? "CS"  :
673
                               i_condition == CC ? "CC"  :
674
                               i_condition == MI ? "MI"  :
675
                               i_condition == PL ? "PL"  :
676
                               i_condition == VS ? "VS"  :
677
                               i_condition == VC ? "VC"  :
678
                               i_condition == HI ? "HI"  :
679
                               i_condition == LS ? "LS"  :
680
                               i_condition == GE ? "GE"  :
681
                               i_condition == LT ? "LT"  :
682
                               i_condition == GT ? "GT"  :
683
                               i_condition == LE ? "LE"  :
684
                               i_condition == AL ? "AL"  :
685
                                                   "NV " ;
686
 
687
assign  xMODE  =  status_bits_mode == SVC  ? "SVC"  :
688
                  status_bits_mode == IRQ  ? "IRQ"  :
689
                  status_bits_mode == FIRQ ? "FIRQ" :
690
                  status_bits_mode == USR  ? "USR"  :
691
                                             "XXX"  ;
692
 
693 89 csantifort
 
694 16 csantifort
//synopsys translate_on
695
 
696
endmodule
697
 
698
 

powered by: WebSVN 2.1.0

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