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

Subversion Repositories zap

[/] [zap/] [trunk/] [src/] [rtl/] [cpu/] [zap_alu_main.v] - Blame information for rev 37

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

Line No. Rev Author Line
1 26 Revanth
// ---------------------------------------------------------------------------
2
// --                                                                       --
3
// --                   (C) 2016-2018 Revanth Kamaraj.                      --
4
// --                                                                       -- 
5
// -- ------------------------------------------------------------------------
6
// --                                                                       --
7
// -- This program is free software; you can redistribute it and/or         --
8
// -- modify it under the terms of the GNU General Public License           --
9
// -- as published by the Free Software Foundation; either version 2        --
10
// -- of the License, or (at your option) any later version.                --
11
// --                                                                       --
12
// -- This program is distributed in the hope that it will be useful,       --
13
// -- but WITHOUT ANY WARRANTY; without even the implied warranty of        --
14
// -- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         --
15
// -- GNU General Public License for more details.                          --
16
// --                                                                       --
17
// -- You should have received a copy of the GNU General Public License     --
18
// -- along with this program; if not, write to the Free Software           --
19
// -- Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA         --
20
// -- 02110-1301, USA.                                                      --
21
// --                                                                       --
22
// ---------------------------------------------------------------------------
23
// --                                                                       --
24
// -- This is the main ZAP arithmetic and logic unit. Apart from shfits     --
25
// -- and multiplies, all other arithmetic and logic is performed here.     --
26
// -- Also data memory access signals are generated at the end of the clock --
27
// -- cycle.  Instructions that fail condition checks are invalidated here. --
28
// --                                                                       --
29
// ---------------------------------------------------------------------------
30
 
31
`default_nettype none
32
 
33
module zap_alu_main #(
34
 
35
        parameter [31:0] PHY_REGS  = 32'd46, // Number of physical registers.
36
        parameter [31:0] SHIFT_OPS = 32'd5,  // Number of shift operations.
37
        parameter [31:0] ALU_OPS   = 32'd32, // Number of arithmetic operations.
38
        parameter [31:0] FLAG_WDT  = 32'd32  // Width of active CPSR.
39
)
40
(
41
        /**********************************************************************
42
         *
43
         *                              INPUTS
44
         *
45
         *********************************************************************/
46
 
47
 
48
        // ------------------------------------------------------------------
49
        // Decompile Interface. Only for debug.
50
        // ------------------------------------------------------------------
51
 
52
        input wire      [64*8-1:0]              i_decompile,
53
        output reg      [64*8-1:0]              o_decompile,
54
 
55
        // ------------------------------------------------------------------
56
        // ALU Hijack Interface. For Thumb Data Abort address calculation.
57
        // ------------------------------------------------------------------
58
 
59
        input wire                              i_hijack,                    // Enable hijack.
60
        input wire      [31:0]                  i_hijack_op1,                // Hijack operand 1.
61
        input wire      [31:0]                  i_hijack_op2,                // Hijack operand 2.
62
        input wire                              i_hijack_cin,                // Hijack carry in.
63
        output wire     [31:0]                  o_hijack_sum,                // Hijack sum out.
64
 
65
        // ------------------------------------------------------------------
66
        // Clock and reset
67
        // ------------------------------------------------------------------
68
 
69
        input wire                              i_clk,                       // Clock.
70
        input wire                              i_reset,                     // sync active high reset.
71
 
72
        // -------------------------------------------------------------------
73
        // Clear and Stall signals.
74
        // -------------------------------------------------------------------
75
 
76
        input wire                              i_clear_from_writeback,      // Clear unit.
77
        input wire                              i_data_stall,                // DCACHE stall.
78
 
79
        // -------------------------------------------------------------------
80
        // Misc. signals
81
        // -------------------------------------------------------------------
82
 
83
        input wire  [31:0]                      i_cpsr_nxt,                  // From passive CPSR.
84
        input wire                              i_switch_ff,                 // Switch state.
85
        input wire   [1:0]                      i_taken_ff,                  // Branch prediction.
86
        input wire   [31:0]                     i_pc_ff,                     // Addr of instr.
87
        input wire                              i_nozero_ff,                 // Zero flag will not be set.
88
 
89
        // ------------------------------------------------------------------
90
        // Source values
91
        // ------------------------------------------------------------------
92
 
93
        input wire  [31:0]                      i_alu_source_value_ff,       // ALU source value.
94
        input wire  [31:0]                      i_shifted_source_value_ff,   // Shifted source value.
95
        input wire                              i_shift_carry_ff,            // Carry from shifter.        
96
        input wire  [31:0]                      i_pc_plus_8_ff,              // PC + 8 value.
97
 
98
        // ------------------------------------------------------------------
99
        // Interrupt Tagging
100
        // ------------------------------------------------------------------
101
 
102
        input wire                              i_abt_ff,                    // ABT flagged.
103
        input wire                              i_irq_ff,                    // IRQ flagged.
104
        input wire                              i_fiq_ff,                    // FIQ flagged.
105
        input wire                              i_swi_ff,                    // SWI flagged.
106
        input wire                              i_und_ff,                    // Flagged undefined instructions.
107
        input wire                              i_data_mem_fault,            // Flagged Data abort.
108
 
109
        // ------------------------------------------------------------------
110
        // Memory Access Related
111
        // ------------------------------------------------------------------
112
 
113
        input wire  [31:0]                      i_mem_srcdest_value_ff,           // Value to store. 
114
        input wire  [zap_clog2(PHY_REGS)-1:0]   i_mem_srcdest_index_ff,           // LD/ST Memory data register index.    
115
        input wire                              i_mem_load_ff,                    // LD/ST Memory load.
116
        input wire                              i_mem_store_ff,                   // LD/ST Memory store.                    
117
        input wire                              i_mem_pre_index_ff,               // LD/ST Pre/Post index.
118
        input wire                              i_mem_unsigned_byte_enable_ff,    // LD/ST uint8_t  data type.
119
        input wire                              i_mem_signed_byte_enable_ff,      // LD/ST int8_t   data type.
120
        input wire                              i_mem_signed_halfword_enable_ff,  // LD/ST int16_t data type.
121
        input wire                              i_mem_unsigned_halfword_enable_ff,// LD/ST uint16_t  data type.
122
        input wire                              i_mem_translate_ff,               // LD/ST Force user view of memory.
123
        input wire                              i_force32align_ff,                // Force address alignment to 32-bit.
124
 
125
        // -------------------------------------------------------------------
126
        // ALU controls
127
        // -------------------------------------------------------------------
128
 
129
        input wire  [3:0]                       i_condition_code_ff,            // CC associated with instr.
130
        input wire  [zap_clog2(PHY_REGS)-1:0]   i_destination_index_ff,         // Target register index.
131
        input wire  [zap_clog2(ALU_OPS)-1:0]    i_alu_operation_ff,             // Operation to perform.
132
        input wire                              i_flag_update_ff,               // Update flags if 1.
133
 
134
        /**********************************************************************
135
         *
136
         *                              OUTPUTS
137
         *
138
         *********************************************************************/
139
 
140
        // -----------------------------------------------------------------
141
        // ALU result
142
        // -----------------------------------------------------------------
143
 
144
        output reg [31:0]                       o_alu_result_nxt,           // For feedback. ALU result _nxt version.
145
        output reg [31:0]                       o_alu_result_ff,            // ALU result flopped version.
146
        output reg                              o_dav_ff,                   // Instruction valid.
147
        output reg                              o_dav_nxt,                  // Instruction valid _nxt version.
148
        output reg [FLAG_WDT-1:0]               o_flags_ff,                 // Output flags (CPSR).
149
        output reg [FLAG_WDT-1:0]               o_flags_nxt,                // CPSR next.
150
        output reg [zap_clog2(PHY_REGS)-1:0]    o_destination_index_ff,     // Destination register index.
151
 
152
        // -----------------------------------------------------------------
153
        // Interrupt Tagging
154
        // -----------------------------------------------------------------
155
 
156
        output reg                              o_abt_ff,                   // Instruction abort flagged.
157
        output reg                              o_irq_ff,                   // IRQ flagged.
158
        output reg                              o_fiq_ff,                   // FIQ flagged.
159
        output reg                              o_swi_ff,                   // SWI flagged.
160
        output reg                              o_und_ff,                   // Flagged undefined instructions
161
 
162
        // -----------------------------------------------------------------
163
        // Jump Controls, BP Confirm, PC + 8
164
        // -----------------------------------------------------------------
165
 
166
        output reg [31:0]                       o_pc_plus_8_ff,             // Instr address + 8.
167
        output reg                              o_clear_from_alu,           // ALU commands a pipeline clear and a predictor correction.
168
        output reg [31:0]                       o_pc_from_alu,              // Corresponding address to go to is provided here.
169
        output reg                              o_confirm_from_alu,         // Tell branch predictor it was correct.
170
 
171
        // ----------------------------------------------------------------
172
        // Memory access related
173
        // ----------------------------------------------------------------
174
 
175
        output reg  [zap_clog2(PHY_REGS)-1:0]   o_mem_srcdest_index_ff,  // LD/ST data register.
176
        output reg                              o_mem_load_ff,              // LD/ST load indicator.
177
        output reg                              o_mem_store_ff,             // LD/ST store indicator.
178
        output reg [31:0]                       o_mem_address_ff,           // LD/ST address to access.
179
        output reg                              o_mem_unsigned_byte_enable_ff,     // uint8_t
180
        output reg                              o_mem_signed_byte_enable_ff,       // int8_t
181
        output reg                              o_mem_signed_halfword_enable_ff,   // int16_t
182
        output reg                              o_mem_unsigned_halfword_enable_ff, // uint16_t
183
        output reg [31:0]                       o_mem_srcdest_value_ff,     // LD/ST value to store.
184
        output reg                              o_mem_translate_ff,         // LD/ST force user view of memory.
185
        output reg [3:0]                        o_ben_ff,                   // LD/ST byte enables (only for STore instructions).
186
        output reg  [31:0]                      o_address_nxt,              // D pin of address register to drive TAG RAMs.
187
 
188
        // -------------------------------------------------------------
189
        // Wishbone signal outputs.
190
        // -------------------------------------------------------------
191
 
192
        output reg                              o_data_wb_we_nxt,
193
        output reg                              o_data_wb_cyc_nxt,
194
        output reg                              o_data_wb_stb_nxt,
195
        output reg [31:0]                       o_data_wb_dat_nxt,
196
        output reg [3:0]                        o_data_wb_sel_nxt,
197
        output reg                              o_data_wb_we_ff,
198
        output reg                              o_data_wb_cyc_ff,
199
        output reg                              o_data_wb_stb_ff,
200
        output reg [31:0]                       o_data_wb_dat_ff,
201
        output reg [3:0]                        o_data_wb_sel_ff
202
);
203
 
204
// ----------------------------------------------------------------------------
205
 
206
`include "zap_defines.vh"
207
`include "zap_localparams.vh"
208
`include "zap_functions.vh"
209
 
210
wire [31:0] mem_srcdest_value_nxt;
211
wire [3:0] ben_nxt;
212
 
213
// Address about to be output. Used to drive tag RAMs etc.
214
reg [31:0]                      mem_address_nxt;
215
 
216
/*
217
   For memory stores, we must generate correct byte enables. This is done
218
   by examining access type inputs. For loads, always 1111 is generated.
219
   If there is neither a load or a store, the old value is preserved.
220
*/
221
assign ben_nxt = /*i_mem_store_ff ?*/ generate_ben (
222
                                                 i_mem_unsigned_byte_enable_ff,
223
                                                 i_mem_signed_byte_enable_ff,
224
                                                 i_mem_unsigned_halfword_enable_ff,
225
                                                 i_mem_unsigned_halfword_enable_ff,
226
                                                 mem_address_nxt) /*: i_mem_load_ff ? 4'b1111 : o_ben_ff*/;
227
 
228
assign mem_srcdest_value_nxt =  duplicate (
229
                                                 i_mem_unsigned_byte_enable_ff,
230
                                                 i_mem_signed_byte_enable_ff,
231
                                                 i_mem_unsigned_halfword_enable_ff,
232
                                                 i_mem_unsigned_halfword_enable_ff,
233
                                                 i_mem_srcdest_value_ff );
234
 
235
/*
236
   These override global N,Z,C,V definitions which are on CPSR. These params
237
   are localized over the 4-bit flag structure.
238
*/
239
localparam [1:0] _N  = 2'd3;
240
localparam [1:0] _Z  = 2'd2;
241
localparam [1:0] _C  = 2'd1;
242
localparam [1:0] _V  = 2'd0;
243
 
244
// Branch status.
245
localparam [1:0] SNT = 2'd0;
246
localparam [1:0] WNT = 2'd1;
247
localparam [1:0] WT  = 2'd2;
248
localparam [1:0] ST  = 2'd3;
249
 
250
/*
251
   Sleep flop. When 1 unit sleeps i.e., does not produce any output except on
252
   the first clock cycle where LR is calculated using the ALU.
253
*/
254
reg                             sleep_ff, sleep_nxt;
255
 
256
/*
257
   CPSR (Active CPSR). The active CPSR is from the where the CPU flags are
258
   read out and the mode also is. Mode changes via manual writes to CPSR
259
   are first written to the active and they then propagate to the passive CPSR
260
   in the writeback stage. This reduces the pipeline flush penalty.
261
*/
262
reg [31:0]                      flags_ff, flags_nxt;
263
 
264
reg [31:0]                      rm, rn; // RM = shifted source value Rn for
265
                                        // non shifted source value. These are
266
                                        // values and not indices.
267
 
268
 
269 37 Revanth
reg [5:0]                       clz_rm; // Count leading zeros in Rm.
270 26 Revanth
 
271 37 Revanth
always @* // CLZ implementation.
272
begin
273
        casez(rm)
274
        32'b1???????????????????????????????:   clz_rm = 6'd00;
275
        32'b01??????????????????????????????:   clz_rm = 6'd01;
276
        32'b001?????????????????????????????:   clz_rm = 6'd02;
277
        32'b0001????????????????????????????:   clz_rm = 6'd03;
278
        32'b00001???????????????????????????:   clz_rm = 6'd04;
279
        32'b000001??????????????????????????:   clz_rm = 6'd05;
280
        32'b0000001?????????????????????????:   clz_rm = 6'd06;
281
        32'b00000001????????????????????????:   clz_rm = 6'd07;
282
        32'b000000001???????????????????????:   clz_rm = 6'd08;
283
        32'b0000000001??????????????????????:   clz_rm = 6'd09;
284
        32'b00000000001?????????????????????:   clz_rm = 6'd10;
285
        32'b000000000001????????????????????:   clz_rm = 6'd11;
286
        32'b0000000000001???????????????????:   clz_rm = 6'd12;
287
        32'b00000000000001??????????????????:   clz_rm = 6'd13;
288
        32'b000000000000001?????????????????:   clz_rm = 6'd14;
289
        32'b0000000000000001????????????????:   clz_rm = 6'd15;
290
        32'b00000000000000001???????????????:   clz_rm = 6'd16;
291
        32'b000000000000000001??????????????:   clz_rm = 6'd17;
292
        32'b0000000000000000001?????????????:   clz_rm = 6'd18;
293
        32'b00000000000000000001????????????:   clz_rm = 6'd19;
294
        32'b000000000000000000001???????????:   clz_rm = 6'd20;
295
        32'b0000000000000000000001??????????:   clz_rm = 6'd21;
296
        32'b00000000000000000000001?????????:   clz_rm = 6'd22;
297
        32'b000000000000000000000001????????:   clz_rm = 6'd23;
298
        32'b0000000000000000000000001???????:   clz_rm = 6'd24;
299
        32'b00000000000000000000000001??????:   clz_rm = 6'd25;
300
        32'b000000000000000000000000001?????:   clz_rm = 6'd26;
301
        32'b0000000000000000000000000001????:   clz_rm = 6'd27;
302
        32'b00000000000000000000000000001???:   clz_rm = 6'd28;
303
        32'b000000000000000000000000000001??:   clz_rm = 6'd29;
304
        32'b0000000000000000000000000000001?:   clz_rm = 6'd30;
305
        32'b00000000000000000000000000000001:   clz_rm = 6'd31;
306
        default:                                clz_rm = 6'd32; // All zeros.
307
        endcase
308
end
309
 
310 26 Revanth
// Destination index about to be output.
311
reg [zap_clog2(PHY_REGS)-1:0]      o_destination_index_nxt;
312
 
313
// 1s complement of Rm and Rn.
314
wire [31:0]                     not_rm = ~rm;
315
wire [31:0]                     not_rn = ~rn;
316
 
317
// Wires which connect to an adder.
318
reg [31:0]      op1, op2;
319
reg             cin;
320
 
321
// 32-bit adder with carry input and carry output.
322
wire [32:0]     sum = {1'd0, op1} + {1'd0, op2} + {32'd0, cin};
323
 
324
reg [31:0] tmp_flags, tmp_sum;
325
 
326
// Opcode.
327
wire [zap_clog2(ALU_OPS)-1:0] opcode = i_alu_operation_ff;
328
 
329
/*
330
   Hijack interface. Data aborts use the hijack interface to find return
331
   address. The writeback drives the ALU inputs to find the final output.
332
*/
333
assign o_hijack_sum = sum;
334
 
335
// ----------------------------------------------------------------------------
336
 
337
always @*
338
begin
339
        rm          = i_shifted_source_value_ff;
340
        rn          = i_alu_source_value_ff;
341
        o_flags_ff  = flags_ff;
342
        o_flags_nxt = flags_nxt;
343
end
344
 
345
// Sequential logic.
346
always @ (posedge i_clk)
347
begin
348
        if ( i_reset )
349
        begin
350
                //
351
                // On reset, processor enters supervisory mode with interrupts
352
                // masked.
353
                //
354
                clear ( {1'd1,1'd1,1'd0,SVC} );
355
        end
356
        else if ( i_clear_from_writeback )
357
        begin
358
                // Clear but take CPSR from writeback.
359
                clear ( i_cpsr_nxt );
360
        end
361
        else if ( i_data_stall )
362
        begin
363
                // Preserve values.
364
        end
365
        else if ( i_data_mem_fault || sleep_ff )
366
        begin
367
                // Clear and preserve flags. Keep sleeping.
368
                clear(flags_ff);
369
                sleep_ff                         <= 1'd1;
370
                o_dav_ff                         <= 1'd0; // Don't give any output.
371
        end
372
        else
373
        begin
374
                // Clock out all flops normally.
375
 
376
                o_alu_result_ff                  <= o_alu_result_nxt;
377
                o_dav_ff                         <= o_dav_nxt;
378
                o_pc_plus_8_ff                   <= i_pc_plus_8_ff;
379
                o_destination_index_ff           <= o_destination_index_nxt;
380
                flags_ff                         <= flags_nxt;
381
                o_abt_ff                         <= i_abt_ff;
382
                o_irq_ff                         <= i_irq_ff;
383
                o_fiq_ff                         <= i_fiq_ff;
384
                o_swi_ff                         <= i_swi_ff;
385
                o_mem_srcdest_index_ff           <= i_mem_srcdest_index_ff;
386
                o_mem_srcdest_index_ff           <= i_mem_srcdest_index_ff;
387
 
388
                // Load or store must come up only if an actual LDR/STR is
389
                // detected.
390
                o_mem_load_ff                    <= o_dav_nxt ? i_mem_load_ff : 1'd0;
391
                o_mem_store_ff                   <= o_dav_nxt ? i_mem_store_ff: 1'd0;
392
 
393
                o_mem_unsigned_byte_enable_ff    <= i_mem_unsigned_byte_enable_ff;
394
                o_mem_signed_byte_enable_ff      <= i_mem_signed_byte_enable_ff;
395
                o_mem_signed_halfword_enable_ff  <= i_mem_signed_halfword_enable_ff;
396
                o_mem_unsigned_halfword_enable_ff<= i_mem_unsigned_halfword_enable_ff;
397
                o_mem_translate_ff               <= i_mem_translate_ff;
398
 
399
                //
400
                // The value to store will have to be duplicated for easier
401
                // memory controller design. See the duplicate() function.
402
                //
403
                o_mem_srcdest_value_ff           <= mem_srcdest_value_nxt;
404
 
405
                sleep_ff                         <= sleep_nxt;
406
                o_und_ff                         <= i_und_ff;
407
 
408
                // Generating byte enables based on the data type and address.
409
                o_ben_ff                         <= ben_nxt;
410
 
411
                // For debug
412
                o_decompile                     <= i_decompile;
413
        end
414
end
415
 
416
// ----------------------------------------------------------------------------
417
 
418
always @ (posedge i_clk) // Wishbone flops.
419
begin
420
                // Wishbone updates.    
421
                o_data_wb_cyc_ff                <= o_data_wb_cyc_nxt;
422
                o_data_wb_stb_ff                <= o_data_wb_stb_nxt;
423
                o_data_wb_we_ff                 <= o_data_wb_we_nxt;
424
                o_data_wb_dat_ff                <= o_data_wb_dat_nxt;
425
                o_data_wb_sel_ff                <= o_data_wb_sel_nxt;
426
                o_mem_address_ff                <= o_address_nxt;
427
end
428
 
429
always @* // Wishbone next state logic.
430
begin
431
        // Preserve values.
432
        o_data_wb_cyc_nxt = o_data_wb_cyc_ff;
433
        o_data_wb_stb_nxt = o_data_wb_stb_ff;
434
        o_data_wb_we_nxt  = o_data_wb_we_ff;
435
        o_data_wb_dat_nxt = o_data_wb_dat_ff;
436
        o_data_wb_sel_nxt = o_data_wb_sel_ff;
437
        o_address_nxt     = o_mem_address_ff;
438
 
439
        if ( i_reset )
440
        begin
441
                o_data_wb_cyc_nxt = 1'd0;
442
                o_data_wb_stb_nxt = 1'd0;
443
        end
444
        else if ( i_clear_from_writeback )
445
        begin
446
                o_data_wb_cyc_nxt = 0;
447
                o_data_wb_stb_nxt = 0;
448
        end
449
        else if ( i_data_stall ) begin end
450
        else if ( i_data_mem_fault || sleep_ff )
451
        begin
452
                o_data_wb_cyc_nxt = 0;
453
                o_data_wb_stb_nxt = 0;
454
        end
455
        else
456
        begin
457
                o_data_wb_cyc_nxt = o_dav_nxt ? i_mem_load_ff | i_mem_store_ff : 1'd0;
458
                o_data_wb_stb_nxt = o_dav_nxt ? i_mem_load_ff | i_mem_store_ff : 1'd0;
459
                o_data_wb_we_nxt  = o_dav_nxt ? i_mem_store_ff                 : 1'd0;
460
                o_data_wb_dat_nxt = mem_srcdest_value_nxt;
461
                o_data_wb_sel_nxt = ben_nxt;
462
                o_address_nxt     = mem_address_nxt;
463
        end
464
end
465
 
466
// ----------------------------------------------------------------------------
467
 
468
always @*
469
begin:pre_post_index
470
        // Memory address output based on pre or post index.
471
        if ( i_mem_pre_index_ff == 0 ) // Post-index. Update is done after memory access.
472
                mem_address_nxt = rn;
473
        else                           // Pre-index. Update is done before memory access.
474
                mem_address_nxt = o_alu_result_nxt;
475
 
476
        //
477
        // If a force 32 align is set, make the lower 2 bits as zero.
478
        // Force 32 align is valid for Thumb.
479
        //
480
        if ( i_force32align_ff )
481
                mem_address_nxt[1:0] = 2'b00;
482
 
483
        //
484
        // Do not change address if not needed.
485
        // If not a load OR a store. Preserve this value. Power saving.
486
        //
487
        if (!( (i_mem_load_ff || i_mem_store_ff) && o_dav_nxt ))
488
                mem_address_nxt = o_mem_address_ff;
489
end
490
 
491
// ----------------------------------------------------------------------------
492
 
493
`ifndef SYNTHESIS
494
 
495
reg [64*8-1:0] OPCODE;
496
 
497
always @*
498
case(opcode)
499
AND:begin       OPCODE = "AND";    end
500
EOR:begin       OPCODE = "EOR";    end
501
MOV:begin       OPCODE = "MOV";    end
502
MVN:begin       OPCODE = "MVN";    end
503
BIC:begin       OPCODE = "BIC";    end
504
ORR:begin       OPCODE = "ORR";    end
505
TST:begin       OPCODE = "TST";    end
506
TEQ:begin       OPCODE = "TEQ";    end
507
CLZ:begin       OPCODE = "CLZ";    end
508
FMOV:begin      OPCODE = "FMOV";   end
509
ADD:begin       OPCODE = "ADD";    end
510
ADC:begin       OPCODE = "ADC";    end
511
SUB:begin       OPCODE = "SUB";    end
512
RSB:begin       OPCODE = "RSB";    end
513
SBC:begin       OPCODE = "SBC";    end
514
RSC:begin       OPCODE = "RSC";    end
515
CMP:begin       OPCODE = "CMP";    end
516
CMN:begin       OPCODE = "CMN";    end
517
endcase
518
 
519
`endif
520
 
521
always @*
522
begin: alu_result
523
 
524
        // Default value.
525
        tmp_flags = flags_ff;
526
 
527
        // If it is a logical instruction.
528
        if (            opcode == AND ||
529
                        opcode == EOR ||
530
                        opcode == MOV ||
531
                        opcode == MVN ||
532
                        opcode == BIC ||
533
                        opcode == ORR ||
534
                        opcode == TST ||
535
                        opcode == TEQ ||
536
                        opcode == CLZ
537
                )
538
        begin
539
                // Call the logical processing function.
540
                {tmp_flags[31:28], tmp_sum} = process_logical_instructions (
541
                        rn, rm, flags_ff[31:28],
542
                        opcode, i_flag_update_ff, i_nozero_ff
543
                );
544
        end
545
 
546
        //
547
        // Flag MOV i.e., MOV to CPSR or MMOV.
548
        // FMOV moves to CPSR and flushes the pipeline.
549
        // MMOV moves to SPSR and does not flush the pipeline.
550
        //
551
        else if ( opcode == FMOV || opcode == MMOV )
552
        begin: fmov_mmov
553
                integer i;
554
                reg [31:0] exp_mask;
555
 
556
                // Read entire CPSR or SPSR.
557
                tmp_sum = opcode == FMOV ? flags_ff : i_mem_srcdest_value_ff;
558
 
559
                // Generate a proper mask.
560
                exp_mask = {{8{rn[3]}},{8{rn[2]}},{8{rn[1]}},{8{rn[0]}}};
561
 
562
                // Change only specific bits as specified by the mask.
563
                for ( i=0;i<32;i=i+1 )
564
                begin
565
                        if ( exp_mask[i] )
566
                                tmp_sum[i] = rm[i];
567
                end
568
 
569
                //
570
                // FMOV moves to the CPSR in ALU and writeback. 
571
                // No register is changed. The MSR out of this will have
572
                // a target to CPSR.
573
                //
574
                if ( opcode == FMOV )
575
                begin
576
                        tmp_flags = tmp_sum;
577
                end
578
        end
579
        else
580
        begin: blk3
581
                reg [3:0] flags;
582
                reg [zap_clog2(ALU_OPS)-1:0] op;
583
                reg n,z,c,v;
584
 
585
                op         = opcode;
586
 
587
                // Assign output of adder to flags.
588
                c = sum[32];
589
                z = (sum[31:0] == 0);
590
                n = sum[31];
591
 
592
                // Overflow.
593
                if ( ( op == ADD || op == ADC || op == CMN ) && (rn[31] == rm[31]) && (sum[31] != rn[31]) )
594
                begin
595
                        v = 1;
596
                end
597
                else if ( (op == RSB || op == RSC) && (rm[31] == !rn[31]) && (sum[31] != rm[31] ) )
598
                begin
599
                        v = 1;
600
                end
601
                else if ( (op == SUB || op == SBC || op == CMP) && (rn[31] == !rm[31]) && (sum[31] != rn[31]) )
602
                begin
603
                        v = 1;
604
                end
605
                else
606
                begin
607
                        v = 0;
608
                end
609
 
610
                //       
611
                // If you choose not to update flags, do not change the flags.
612
                // Otherwise, they will contain their newly computed values.
613
                //
614
                if ( i_flag_update_ff )
615
                        tmp_flags[31:28] = {n,z,c,v};
616
 
617
                // Write out the result.
618 37 Revanth
                tmp_sum = op == CLZ ? clz_rm : sum;
619 26 Revanth
        end
620
 
621
        // Drive nxt pin of result register.
622
        o_alu_result_nxt = tmp_sum;
623
end
624
 
625
// ----------------------------------------------------------------------------
626
 
627
always @*
628
begin: flags_bp_feedback
629
 
630
       o_clear_from_alu         = 1'd0;
631
       o_pc_from_alu            = 32'd0;
632
       sleep_nxt                = sleep_ff;
633
       flags_nxt                = tmp_flags;
634
       o_destination_index_nxt  = i_destination_index_ff;
635
       o_confirm_from_alu       = 1'd0;
636
 
637
        // Check if condition is satisfied.
638
       o_dav_nxt = is_cc_satisfied ( i_condition_code_ff, flags_ff[31:28] );
639
 
640
        if ( i_irq_ff || i_fiq_ff || i_abt_ff || i_swi_ff || i_und_ff )
641
        begin
642
                //
643
                // Any sign of an interrupt is present, put unit to sleep.
644
                // The current instruction will not be executed ultimately
645
                // but rather a SUB LR, PC, 4 will be which will be stored in
646
                // the link register.
647
                //
648
                o_dav_nxt = 1'd1;
649
                sleep_nxt = 1'd1;
650
        end
651
        else if ( (opcode == FMOV) && o_dav_nxt ) // Writes to CPSR...
652
        begin
653
                o_clear_from_alu        = 1'd1; // Need to flush everything because we might end up fetching stuff in KERNEL instead of USER mode.
654
                o_pc_from_alu           = sum;  // NOT tmp_sum, that would be loaded into CPSR. 
655
 
656
                // USR cannot change mode. Will silently fail.
657
                flags_nxt[`CPSR_MODE]   = (flags_nxt[`CPSR_MODE] == USR) ? USR : flags_nxt[`CPSR_MODE]; // Security.
658
        end
659
        else if ( i_destination_index_ff == ARCH_PC && (i_condition_code_ff != NV))
660
        begin
661
                if ( i_flag_update_ff && o_dav_nxt )
662
                // PC update with S bit.
663
                // Will restore CPU mode from SPSR. USR no change.
664
                begin
665
                        o_destination_index_nxt = PHY_RAZ_REGISTER;
666
                        o_clear_from_alu        = 1'd1;
667
                        o_pc_from_alu           = tmp_sum;
668
                        flags_nxt               = i_mem_srcdest_value_ff;                                       // Restore CPSR from SPSR.
669
                        flags_nxt[`CPSR_MODE]   = (flags_nxt[`CPSR_MODE] == USR) ? USR : flags_nxt[`CPSR_MODE]; // Security.
670
                end
671
                else if ( o_dav_nxt ) // Branch taken and no flag update.
672
                begin
673
                        if ( i_taken_ff == SNT || i_taken_ff == WNT )
674
                        // Incorrectly predicted as not-taken.
675
                        begin
676
                                // Quick branches - Flush everything before.
677
 
678
                                // Dumping ground since PC change is done.
679
                                o_destination_index_nxt = PHY_RAZ_REGISTER;
680
                                o_clear_from_alu        = 1'd1;
681
                                o_pc_from_alu           = tmp_sum;
682
                                flags_nxt[T]            = i_switch_ff ? tmp_sum[0] : flags_ff[T]; // Thumb/ARM state if i_switch_ff = 1.
683
                        end
684
                        else    // Correctly predicted.
685
                        begin
686
                                // If thumb bit changes, flush everything before
687
                                if ( i_switch_ff )
688
                                begin
689
                                        //
690
                                        // Quick branches! PC goes to RAZ register since
691
                                        // change is done.
692
                                        //
693
                                        o_destination_index_nxt = PHY_RAZ_REGISTER;
694
 
695
                                        o_clear_from_alu        = 1'd1;
696
                                        o_pc_from_alu           = tmp_sum;
697
                                        flags_nxt[T]            = i_switch_ff ? tmp_sum[0] : flags_ff[T];
698
                                        // Thumb/ARM state if i_switch_ff = 1.
699
                                end
700
                                else
701
                                begin
702
                                        //
703
                                        // No mode change, do not change 
704
                                        // anything.
705
                                        //
706
                                        o_destination_index_nxt = PHY_RAZ_REGISTER;
707
                                        o_clear_from_alu = 1'd0;
708
                                        flags_nxt[T]     = i_switch_ff ? tmp_sum[0]: flags_ff[T];
709
 
710
                                        //
711
                                        // Send confirmation message to branch 
712
                                        // predictor.
713
                                        //
714
                                        o_pc_from_alu      = 32'd0;
715
                                        o_confirm_from_alu = 1'd1;
716
                                end
717
                        end
718
                end
719
                else    // Branch not taken
720
                begin
721
                        if ( i_taken_ff == WT || i_taken_ff == ST )
722
                        // Wrong prediction as taken...
723
                        begin
724
                                // Go to the same branch.
725
                                o_clear_from_alu = 1'd1;
726
                                o_pc_from_alu    = i_pc_ff;
727
                        end
728
                        else
729
                        begin
730
                                // Correct prediction.
731
                                o_clear_from_alu = 1'd0;
732
                                o_pc_from_alu    = 32'd0;
733
                        end
734
                end
735
        end
736
        else if ( i_mem_srcdest_index_ff == ARCH_PC && o_dav_nxt && i_mem_load_ff)
737
        begin
738
                // Loads to PC also puts the unit to sleep.
739
                sleep_nxt = 1'd1;
740
        end
741
 
742
        // If the current instruction is invalid, do not update flags.
743
        if ( o_dav_nxt == 1'd0 )
744
                flags_nxt = flags_ff;
745
end
746
 
747
// ----------------------------------------------------------------------------
748
 
749
// These are adder connections. Data processing and FMOV use these.
750
always @*
751
begin: adder_ip_mux
752
        reg [zap_clog2(ALU_OPS)-1:0] op;
753
        reg [31:0] flags;
754
 
755
        flags = flags_ff[31:28];
756
        op    = i_alu_operation_ff;
757
 
758
        if ( i_hijack )
759
        begin
760
                op1 = i_hijack_op1;
761
                op2 = i_hijack_op2;
762
                cin = i_hijack_cin;
763
        end
764
        else
765
        case ( op )
766
       FMOV: begin op1 = i_pc_plus_8_ff ; op2 = ~32'd4 ; cin =   1'd1;      end
767
        ADD: begin op1 = rn             ; op2 = rm     ; cin =   32'd0;     end
768
        ADC: begin op1 = rn             ; op2 = rm     ; cin =   flags[_C]; end
769
        SUB: begin op1 = rn             ; op2 = not_rm ; cin =   32'd1;     end
770
        RSB: begin op1 = rm             ; op2 = not_rn ; cin =   32'd1;     end
771
        SBC: begin op1 = rn             ; op2 = not_rm ; cin =   !flags[_C];end
772
        RSC: begin op1 = rm             ; op2 = not_rn ; cin =   !flags[_C];end
773
 
774
        // Target is not written.
775
        CMP: begin op1 = rn             ; op2 = not_rm ; cin =   32'd1;     end
776
        CMN: begin op1 = rn             ; op2 = rm     ; cin =   32'd0;     end
777
        default:
778
        begin
779
                op1 = 0;
780
                op2 = 0;
781
                cin = 0;
782
        end
783
        endcase
784
end
785
 
786
// ----------------------------------------------------------------------------
787
 
788
// Process logical instructions.
789
function [35:0] process_logical_instructions
790
( input [31:0] rn, rm, input [3:0] flags, input [zap_clog2(ALU_OPS)-1:0] op,
791
  input i_flag_upd, input nozero );
792
begin: blk2
793
        reg [31:0] rd;
794
        reg [3:0] flags_out;
795
 
796
        // Avoid accidental latch inference.
797
        rd        = 0;
798
        flags_out = 0;
799
 
800
        case(op)
801
        AND: rd = rn & rm;
802
        EOR: rd = rn ^ rm;
803
        BIC: rd = rn & ~(rm);
804
        MOV: rd = rm;
805
        MVN: rd = ~rm;
806
        ORR: rd = rn | rm;
807
        TST: rd = rn & rm; // Target is not written.
808
        TEQ: rd = rn ^ rn; // Target is not written.
809
        default:
810
        begin
811
                rd = 0;
812
                $display("*Error: Logic unit got non logic opcode...");
813
                $finish;
814
        end
815
        endcase
816
 
817
        // Suppose flags are not going to change at ALL.
818
        flags_out = flags;
819
 
820
        // Assign values to the flags only if an update is requested. Note that V
821
        // is not touched even if change is requested.
822
        if ( i_flag_upd )
823
        begin
824
                // V is preserved since flags_out = flags assignment.
825
                flags_out[_C] = i_shift_carry_ff;
826
 
827
                if ( nozero )
828
                        //
829
                        // This specifically states that we must NOT set the 
830
                        // ZERO flag under any circumstance. 
831
                        //
832
                        flags_out[_Z] = 1'd0;
833
                else
834
                        flags_out[_Z] = (rd == 0);
835
 
836
                flags_out[_N] = rd[31];
837
        end
838
 
839
        process_logical_instructions = {flags_out, rd};
840
end
841
endfunction
842
 
843
// ----------------------------------------------------------------------------
844
 
845
task clear ( input [31:0] flags );
846
begin
847
                o_dav_ff                         <= 0;
848
                flags_ff                         <= flags;
849
                o_abt_ff                         <= 0;
850
                o_irq_ff                         <= 0;
851
                o_fiq_ff                         <= 0;
852
                o_swi_ff                         <= 0;
853
                o_und_ff                         <= 0;
854
                sleep_ff                         <= 0;
855
                o_mem_load_ff                    <= 0;
856
                o_mem_store_ff                   <= 0;
857
end
858
endtask
859
 
860
// ----------------------------------------------------------------------------
861
 
862
// The reason we use the duplicate function is to copy value over the memory
863
// bus for memory stores. If we have a byte write to address 1, then the
864
// memory controller basically takes address 0 and byte enable 0010 and writes
865
// to address 1. This enables implementation of a 32-bit memory controller
866
// with byte enables to control updates as is common.
867
 
868
function [31:0] duplicate (     input ub, // Unsigned byte. 
869
                                input sb, // Signed byte.
870
                                input uh, // Unsigned halfword.
871
                                input sh, // Signed halfword.
872
                                input [31:0] val        );
873
reg [31:0] x;
874
begin
875
        if ( ub || sb)
876
        begin
877
                // Byte.
878
                x = {val[7:0], val[7:0], val[7:0], val[7:0]};
879
        end
880
        else if (uh || sh)
881
        begin
882
                // Halfword.
883
                x = {val[15:0], val[15:0]};
884
        end
885
        else
886
        begin
887
                x = val;
888
        end
889
 
890
        duplicate = x;
891
end
892
endfunction
893
 
894
// ----------------------------------------------------------------------------
895
 
896
// Generate byte enables based on access mode.
897
function [3:0] generate_ben (   input ub, // Unsigned byte. 
898
                                input sb, // Signed byte.
899
                                input uh, // Unsigned halfword.
900
                                input sh, // Signed halfword.
901
                                input [31:0] addr       );
902
reg [3:0] x;
903
begin
904
        if ( ub || sb ) // Byte oriented.
905
        begin
906
                case ( addr[1:0] ) // Based on address lower 2-bits.
907
                0: x = 1;
908
                1: x = 1 << 1;
909
                2: x = 1 << 2;
910
                3: x = 1 << 3;
911
                endcase
912
        end
913
        else if ( uh || sh ) // Halfword. A word = 2 half words.
914
        begin
915
                case ( addr[1] )
916
                0: x = 4'b0011;
917
                1: x = 4'b1100;
918
                endcase
919
        end
920
        else
921
        begin
922
                x = 4'b1111; // Word oriented.
923
        end
924
 
925
        generate_ben = x;
926
end
927
endfunction // generate_ben
928
 
929
`ifndef SYNTHESIS
930
 
931
        always @*
932
        begin
933
                if ( flags_nxt[`CPSR_MODE] != USR && flags_ff[`CPSR_MODE] == USR )
934
                begin
935
                        $display($time, "Error: %m CPU is changing out of USR mode without an exception...");
936
                        $stop;
937
                end
938
        end
939
 
940
`endif
941
 
942
endmodule // zap_alu_main.v
943
 
944
`default_nettype wire

powered by: WebSVN 2.1.0

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