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

Subversion Repositories zap

[/] [zap/] [trunk/] [src/] [rtl/] [cpu/] [zap_shifter_main.v] - Blame information for rev 38

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
// --  The ZAP shift unit. Apart from shift, it does value restoration and
25
// --  multiplication. Value restoration is needed since the ALU (Shift+Op) is
26
// --  pipelined and we want back to back instructions to execute correctly without
27
// --  losing throughput. Note that there are 3 execution pathways in this unit
28
// --  but a given time, only one pathway may be active. The 3 execution pathways
29
// --  are: shifter, multiplier, value feedback network.
30
// -- 
31
// ----------------------------------------------------------------------------
32
 
33
 
34
`default_nettype none
35
module zap_shifter_main
36
#(
37
        parameter PHY_REGS  = 46,
38
        parameter ALU_OPS   = 32,
39
        parameter SHIFT_OPS = 5
40
)
41
(
42
        // For debug
43
        input   wire    [64*8-1:0]              i_decompile,
44
        output  reg     [64*8-1:0]              o_decompile,
45
 
46
        // Clock and reset.
47
        input wire                               i_clk,
48
        input wire                               i_reset,
49
 
50
        // PC
51
        input wire [31:0]                       i_pc_ff,
52
        output reg [31:0]                       o_pc_ff,
53
 
54
        // Taken.
55
        input wire   [1:0]                       i_taken_ff,
56
        output reg   [1:0]                       o_taken_ff,
57
 
58
        // Stall and clear. Hi to low priority.
59
        input wire i_clear_from_writeback, // | High Priority.
60
        input wire i_data_stall,           // |
61
        input wire i_clear_from_alu,       // V Low Priority.
62
 
63
        // Next CPSR and FF CPSR.
64
        input wire [31:0] i_cpsr_nxt, i_cpsr_ff,
65
 
66
        //
67
        // Things from Issue. Please see issue stage for signal details.
68
        //
69
 
70
        input wire       [3:0]                   i_condition_code_ff,
71
        input wire       [$clog2(PHY_REGS )-1:0] i_destination_index_ff,
72
        input wire       [$clog2(ALU_OPS)-1:0]   i_alu_operation_ff,
73
        input wire       [$clog2(SHIFT_OPS)-1:0] i_shift_operation_ff,
74
        input wire                               i_flag_update_ff,
75
 
76
        input wire     [$clog2(PHY_REGS )-1:0]   i_mem_srcdest_index_ff,
77
        input wire                               i_mem_load_ff,
78
        input wire                               i_mem_store_ff,
79
        input wire                               i_mem_pre_index_ff,
80
        input wire                               i_mem_unsigned_byte_enable_ff,
81
        input wire                               i_mem_signed_byte_enable_ff,
82
        input wire                               i_mem_signed_halfword_enable_ff,
83
        input wire                               i_mem_unsigned_halfword_enable_ff,
84
        input wire                               i_mem_translate_ff,
85
 
86
        input wire                               i_irq_ff,
87
        input wire                               i_fiq_ff,
88
        input wire                               i_abt_ff,
89
        input wire                               i_swi_ff,
90
 
91
        // Indices/immediates enter here.
92
        input wire      [32:0]                  i_alu_source_ff,
93
        input wire                              i_alu_dav_nxt,
94
        input wire      [32:0]                  i_shift_source_ff,
95
 
96
        // Values are obtained here.
97
        input wire      [31:0]                  i_alu_source_value_ff,
98
        input wire      [31:0]                  i_shift_source_value_ff,
99
        input wire      [31:0]                  i_shift_length_value_ff,
100
        input wire      [31:0]                  i_mem_srcdest_value_ff, // This too has to be resolved. 
101
                                                // For stores.
102
 
103
        // The PC value.
104
        input wire     [31:0]                   i_pc_plus_8_ff,
105
 
106
        // Shifter disable indicator. In the next stage, the output
107
        // will bypass the shifter. Not actually bypass it but will
108
        // go to the ALU value corrector unit via a MUX.
109
        input wire                              i_disable_shifter_ff,
110
 
111
        // undefined instr.
112
        input wire                         i_und_ff,
113
        output reg                         o_und_ff,
114
 
115
        // Value from ALU for resolver.
116
        input wire   [31:0]                     i_alu_value_nxt,
117
 
118
        // Force 32.
119
        input wire                         i_force32align_ff,
120
        output reg                         o_force32align_ff,
121
 
122
        // ARM <-> Compressed switch indicator.
123
        input wire      i_switch_ff,
124
        output reg      o_switch_ff,
125
 
126
        //
127
        // Outputs.
128
        //
129
 
130
        // Specific to this stage.
131
        output reg      [31:0]                  o_mem_srcdest_value_ff,
132
        output reg      [31:0]                  o_alu_source_value_ff,
133
        output reg      [31:0]                  o_shifted_source_value_ff,
134
        output reg                              o_shift_carry_ff,
135
        output reg                              o_nozero_ff,
136
 
137
        // Send all other outputs.
138
 
139
        // PC+8
140
        output reg      [31:0]                  o_pc_plus_8_ff,
141
 
142
        // Interrupts.
143
        output reg                              o_irq_ff,
144
        output reg                              o_fiq_ff,
145
        output reg                              o_abt_ff,
146
        output reg                              o_swi_ff,
147
 
148
        // Memory related outputs.
149
        output reg [$clog2(PHY_REGS )-1:0]      o_mem_srcdest_index_ff,
150
        output reg                              o_mem_load_ff,
151
        output reg                              o_mem_store_ff,
152
        output reg                              o_mem_pre_index_ff,
153
        output reg                              o_mem_unsigned_byte_enable_ff,
154
        output reg                              o_mem_signed_byte_enable_ff,
155
        output reg                              o_mem_signed_halfword_enable_ff,
156
        output reg                              o_mem_unsigned_halfword_enable_ff,
157
        output reg                              o_mem_translate_ff,
158
 
159
        // Other stuff.
160
        output reg       [3:0]                   o_condition_code_ff,
161
        output reg       [$clog2(PHY_REGS )-1:0] o_destination_index_ff,
162
        output reg       [$clog2(ALU_OPS)-1:0]   o_alu_operation_ff,
163
        output reg                               o_flag_update_ff,
164
 
165
        // Stall from shifter.
166
        output wire                             o_stall_from_shifter
167
);
168
 
169
///////////////////////////////////////////////////////////////////////////////
170
 
171
`include "zap_defines.vh"
172
`include "zap_localparams.vh"
173
`include "zap_functions.vh"
174
 
175
///////////////////////////////////////////////////////////////////////////////
176
 
177
wire nozero_nxt;
178
wire [31:0] shout;
179
wire shcarry;
180
reg [31:0] mem_srcdest_value;
181
reg [31:0] rm, rn;
182
reg shift_carry_nxt;
183
wire shifter_enabled = !i_disable_shifter_ff;
184
 
185
wire [31:0] mult_out;
186
 
187
///////////////////////////////////////////////////////////////////////////////
188
 
189
// The MAC unit.
190
zap_shifter_multiply
191
#(
192
        .PHY_REGS(PHY_REGS),
193
        .ALU_OPS(ALU_OPS)
194
)
195
u_zap_multiply
196
(
197
        .i_clk(i_clk),
198
        .i_reset(i_reset),
199
 
200
        .i_data_stall(i_data_stall),
201
        .i_clear_from_writeback(i_clear_from_writeback),
202
        .i_clear_from_alu(i_clear_from_alu),
203
 
204
        .i_alu_operation_ff(i_alu_operation_ff),
205
 
206
        .i_cc_satisfied (i_condition_code_ff == 4'd15 ? 1'd0 : 1'd1),
207
        // ( is_cc_satisfied ( i_condition_code_ff, i_cpsr_nxt[31:28] ) ) 
208
        // -- Causing timing issues in Xilinx ISE.
209
 
210
        .i_rm(i_alu_source_value_ff),
211
        .i_rn(i_shift_length_value_ff),
212
        .i_rs(i_shift_source_value_ff), // rm.rs + {rh,rn}
213
        .i_rh(i_mem_srcdest_value_ff),
214
 
215
        .o_rd(mult_out),
216
        .o_busy(o_stall_from_shifter),
217
        .o_nozero(nozero_nxt)
218
);
219
 
220
///////////////////////////////////////////////////////////////////////////////
221
 
222
task clear; // Clear the unit out.
223
begin
224
           o_condition_code_ff               <= NV;
225
           o_irq_ff                          <= 0;
226
           o_fiq_ff                          <= 0;
227
           o_abt_ff                          <= 0;
228
           o_swi_ff                          <= 0;
229
           o_und_ff                          <= 0;
230
end
231
endtask
232
 
233
///////////////////////////////////////////////////////////////////////////////
234
 
235
always @ (posedge i_clk)
236
begin
237
        if ( i_reset )
238
        begin
239
                clear;
240
        end
241
        else if ( i_clear_from_writeback )
242
        begin
243
                clear;
244
        end
245
        else if ( i_data_stall )
246
        begin
247
                // Preserve values.
248
        end
249
        else if ( i_clear_from_alu )
250
        begin
251
                clear;
252
        end
253
        else
254
        begin
255
           o_condition_code_ff               <= i_condition_code_ff;
256
           o_destination_index_ff            <= i_destination_index_ff;
257
           o_alu_operation_ff                <= (i_alu_operation_ff == UMLALL ||
258
                                                 i_alu_operation_ff == UMLALH ||
259
                                                 i_alu_operation_ff == SMLALL ||
260
                                                i_alu_operation_ff == SMLALH) ?
261
                                                MOV : i_alu_operation_ff;
262
                                        // Multiplication becomes a MOV for ALU.
263
           o_flag_update_ff                  <= i_flag_update_ff;
264
           o_mem_srcdest_index_ff            <= i_mem_srcdest_index_ff;
265
           o_mem_load_ff                     <= i_mem_load_ff;
266
           o_mem_store_ff                    <= i_mem_store_ff;
267
           o_mem_pre_index_ff                <= i_mem_pre_index_ff;
268
           o_mem_unsigned_byte_enable_ff     <= i_mem_unsigned_byte_enable_ff;
269
           o_mem_signed_byte_enable_ff       <= i_mem_signed_byte_enable_ff;
270
           o_mem_signed_halfword_enable_ff   <= i_mem_signed_halfword_enable_ff;
271
           o_mem_unsigned_halfword_enable_ff <= i_mem_unsigned_halfword_enable_ff;
272
           o_mem_translate_ff                <= i_mem_translate_ff;
273
           o_irq_ff                          <= i_irq_ff;
274
           o_fiq_ff                          <= i_fiq_ff;
275
           o_abt_ff                          <= i_abt_ff;
276
           o_swi_ff                          <= i_swi_ff;
277
           o_pc_plus_8_ff                    <= i_pc_plus_8_ff;
278
           o_mem_srcdest_value_ff            <= mem_srcdest_value;
279
           o_alu_source_value_ff             <= rn;
280
           o_shifted_source_value_ff         <= rm;
281
           o_shift_carry_ff                  <= shift_carry_nxt;
282
           o_switch_ff                       <= i_switch_ff;
283
           o_und_ff                          <= i_und_ff;
284
           o_force32align_ff                 <= i_force32align_ff;
285
           o_taken_ff                        <= i_taken_ff;
286
           o_pc_ff                           <= i_pc_ff;
287
           o_nozero_ff                       <= nozero_nxt;
288
 
289
           // For debug
290
           o_decompile                       <= i_decompile;
291
   end
292
end
293
 
294
///////////////////////////////////////////////////////////////////////////////
295
 
296
// Barrel shifter.
297
zap_shift_shifter  #(
298
        .SHIFT_OPS(SHIFT_OPS)
299
)
300
U_SHIFT
301
(
302
        .i_source       ( i_shift_source_value_ff ),
303
        .i_amount       ( i_shift_length_value_ff[7:0] ),
304
        .i_shift_type   ( i_shift_operation_ff ),
305
        .i_carry        ( i_cpsr_ff[29] ),
306
        .o_result       ( shout ),
307
        .o_carry        ( shcarry )
308
);
309
 
310
///////////////////////////////////////////////////////////////////////////////
311
 
312
// Resolve conflict for ALU source value (rn)
313
always @*
314
begin
315
 
316
                rn = resolve_conflict ( i_alu_source_ff, i_alu_source_value_ff,
317
                                        o_destination_index_ff, i_alu_value_nxt, i_alu_dav_nxt );
318
 
319
 
320
end
321
 
322
///////////////////////////////////////////////////////////////////////////////
323
 
324
// Resolve conflict for shifter source value.
325
always @*
326
begin
327
        // If we issue a multiply.
328
        if ( i_alu_operation_ff == UMLALL || i_alu_operation_ff == UMLALH ||
329
             i_alu_operation_ff == SMLALL || i_alu_operation_ff == SMLALH )
330
        begin
331
                // Get result from multiplier.
332
                rm              = mult_out;
333
 
334
                // Carry is set to a MEANINGLESS value. Zero in this case.
335
                shift_carry_nxt = 1'd0;
336
        end
337
        else if( shifter_enabled ) // Shifter enabled if valid shift is asked for.
338
        begin
339
                // Get result from shifter.
340
                rm              = shout;
341
 
342
                // Get carry from shifter
343
                shift_carry_nxt = shcarry;
344
        end
345
        else
346
        begin
347
                // Resolve conflict.
348
                rm = resolve_conflict ( i_shift_source_ff, i_shift_source_value_ff,
349
                                        o_destination_index_ff, i_alu_value_nxt, i_alu_dav_nxt );
350
 
351
                // Do not touch the carry. Get from _nxt for back2back execution.
352
                shift_carry_nxt = i_cpsr_nxt[29];
353
        end
354
end
355
 
356
///////////////////////////////////////////////////////////////////////////////
357
 
358
// Mem srcdest index. Used for
359
// stores. Resolve conflict.
360
always @*
361
begin
362
        mem_srcdest_value = resolve_conflict ( i_mem_srcdest_index_ff, i_mem_srcdest_value_ff,
363
                                               o_destination_index_ff, i_alu_value_nxt, i_alu_dav_nxt );
364
end
365
 
366
///////////////////////////////////////////////////////////////////////////////
367
 
368
// This will resolve conflicts for back to back instruction execution.
369
// The function entirely depends only on the inputs to the function.
370
function [31:0] resolve_conflict (
371
        input    [32:0]                  index_from_issue,       // Index from issue stage. Could have immed too.
372
        input    [31:0]                  value_from_issue,       // Issue speculatively read value.
373
        input    [$clog2(PHY_REGS)-1:0]  index_from_this_stage,  // From shift (This) stage output flops.
374
        input    [31:0]                  result_from_alu,        // From ALU output directly.
375
        input                            result_from_alu_valid   // Result from ALU is VALID.
376
);
377
begin
378
`ifdef SH_DEBUG
379
        $display($time, "%m: ================ resolve_conflict ==================");
380
        $display($time, "%m: index from issue = %d value from issue = %d index from this stage = %d result from alu = %d", index_from_issue, value_from_issue, index_from_this_stage, result_from_alu);
381
        $display($time, "%m: ====================================================");
382
`endif
383
 
384
        if ( index_from_issue[32] == IMMED_EN )
385
        begin
386
                resolve_conflict = index_from_issue[31:0];
387
 
388
`ifdef SH_DEBUG
389
                        $display($time, "%m: => It is an immediate value.");
390
`endif
391 38 Revanth
        end
392
        else if ( index_from_issue == PHY_PC )
393
        begin
394
                resolve_conflict = i_pc_plus_8_ff;
395
 
396
`ifdef SH_DEBUG
397
                        $display($time, "%m: => Giving PC");
398
`endif
399 26 Revanth
        end
400
        else if ( index_from_this_stage == index_from_issue[$clog2(PHY_REGS)-1:0] && result_from_alu_valid )
401
        begin
402
                resolve_conflict = result_from_alu;
403
 
404
`ifdef SH_DEBUG
405
                        $display($time, "%m: => Getting result from ALU!");
406
`endif
407
        end
408
        else
409
        begin
410
                resolve_conflict = value_from_issue[31:0];
411
`ifdef SH_DEBUG
412
                        $display($time, "%m: => No changes!");
413
`endif
414
        end
415
 
416
`ifdef SH_DEBUG
417
                $display($time, "%m: ==> Final result is %d", resolve_conflict);
418
`endif
419
end
420
endfunction
421
 
422
///////////////////////////////////////////////////////////////////////////////
423
 
424
endmodule // zap_shifter_main.v
425
`default_nettype wire

powered by: WebSVN 2.1.0

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