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

Subversion Repositories zap

[/] [zap/] [trunk/] [src/] [rtl/] [cpu/] [zap_decode_main.v] - Blame information for rev 43

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 module decodes 32-bit ARM instructions into an internal wide       --
25
// -- instruction format that is understood by downstream logic.              --
26
// --                                                                         --
27
// -----------------------------------------------------------------------------
28
 
29
`default_nettype none
30
 
31
module zap_decode_main #(
32
        // Number of architectural registers.
33
        parameter [31:0] ARCH_REGS = 32'd32,
34
 
35
        // Number of arithm. opcodes 
36
        parameter ALU_OPS   = 32,
37
 
38
        // Total shift operations supported.
39
        parameter SHIFT_OPS = 6,
40
 
41
        // Number of physical registers.
42
        parameter PHY_REGS = 46
43
)
44
(
45
        output reg  [64*8-1:0]                  o_decompile, // For debug purposes.
46
 
47
        // -------------------
48
        // Inputs.      
49
        // -------------------
50
 
51
        // Clock and reset.
52
        input   wire                            i_clk,
53
        input   wire                            i_reset,
54
 
55
        // Branch state.
56
        input   wire     [1:0]                  i_taken,
57
 
58
        // Thumb undefined.
59
        input   wire                            i_thumb_und,
60
 
61
        // Force 32-bit
62
        input   wire                            i_force32align,
63
 
64
        // Clear and stall signals. High to low priority.
65
        input wire                              i_clear_from_writeback, // | Priority
66
        input wire                              i_data_stall,           // |
67
        input wire                              i_clear_from_alu,       // |
68
        input wire                              i_stall_from_shifter,   // |
69
        input wire                              i_stall_from_issue,     // V
70
 
71
        // Interrupt events.
72
        input   wire                            i_irq,
73
        input   wire                            i_fiq,
74
        input   wire                            i_abt,
75
 
76
        // PC input.
77
        input wire  [31:0]                      i_pc_ff,
78
        input wire  [31:0]                      i_pc_plus_8_ff,
79
 
80
        // CPU mode. Taken from CPSR.
81
        input   wire    [4:0]                   i_cpsr_ff_mode, // Mode.
82
        input   wire                            i_cpsr_ff_i,    // IRQ state.
83
        input   wire                            i_cpsr_ff_f,    // FIQ state.
84
 
85
        // Instruction input.
86
        input     wire  [35:0]                  i_instruction,
87
        input     wire                          i_instruction_valid,
88
 
89
        // ------------------------
90
        // Outputs.
91
        // ------------------------
92
 
93
        // This signal is used to check the validity of a pipeline stage.
94
        output   reg    [3:0]                   o_condition_code_ff,
95
 
96
        // 
97
        // Where the primary output of the instruction must go to. Make this RAZ
98
        // to throw away the primary output to a void.
99
        //
100
        output   reg    [$clog2(PHY_REGS)-1:0] o_destination_index_ff,
101
 
102
        //
103
        // The ALU source is the source that is fed directly to the ALU without the
104
        // barrel shifter. For multiplication, o_alu_source simply becomes an operand.
105
        // For alu_source_ff, if bit 32 is 1, then [31:0] is a constant else 
106
        // [31:0] is a register index (lower 6-bit effectively).
107
        //
108
        output   reg    [32:0]                  o_alu_source_ff,
109
        output   reg    [$clog2(ALU_OPS)-1:0]   o_alu_operation_ff,
110
 
111
        //
112
        // Stuff related to the shifter. For multiplication, the source and length
113
        // simply become two operands. For shift_source_ff and shift_length_ff,
114
        // bit 32 has the same meaning as for o_alu_source_ff.
115
        //
116
        output   reg    [32:0]                  o_shift_source_ff,
117
        output   reg    [$clog2(SHIFT_OPS)-1:0] o_shift_operation_ff,
118
        output   reg    [32:0]                  o_shift_length_ff,
119
 
120
        //
121
        // Update the flags. Note that writing to CPSR will cause a flag-update (if
122
        // you asked for) even if this is 0.
123
        //
124
        output  reg                             o_flag_update_ff,
125
 
126
        // Things related to memory operations.
127
 
128
        //
129
        // Data register index. Register is read 
130
        // for stores and written for loads.
131
        //
132
        output  reg   [$clog2(PHY_REGS)-1:0]    o_mem_srcdest_index_ff,
133
 
134
        // Load or store.
135
        output  reg                             o_mem_load_ff,
136
        output  reg                             o_mem_store_ff,
137
 
138
        // Indicate pre-ALU tap for address since pre-index.
139
        output  reg                             o_mem_pre_index_ff,
140
 
141
        // Access size and type.
142
 
143
        // Unsigned byte access.
144
        output  reg                             o_mem_unsigned_byte_enable_ff,
145
 
146
        // Signed byte access.
147
        output  reg                             o_mem_signed_byte_enable_ff,
148
 
149
        // Signed halfword access.
150
        output  reg                             o_mem_signed_halfword_enable_ff,
151
 
152
        // Unsigned halfword access.
153
        output  reg                             o_mem_unsigned_halfword_enable_ff,
154
 
155
        // Force user view of memory.
156
        output  reg                             o_mem_translate_ff,
157
 
158
        // PC output. Simply clocked out.
159
        output  reg  [31:0]                     o_pc_plus_8_ff,
160
        output  reg  [31:0]                     o_pc_ff,
161
 
162
        // Switch.
163
        output  reg                             o_switch_ff,
164
 
165
        // Interrupts. 
166
        output  reg                             o_irq_ff, // Goes through mask.
167
        output  reg                             o_fiq_ff, // Goes through mask.
168
        output  reg                             o_abt_ff, // Clocked out.
169
        output  reg                             o_und_ff, // Undefined instr.
170
        output  reg                             o_swi_ff, // SWI encountered.
171
        // EXECUTE tests for condition validity and triggers SWI.
172
 
173
        // Force 32-bit alignment on memory accesses. Simply clocked out.
174
        output reg                              o_force32align_ff,
175
 
176
        // Branch state. Simply clocked out.
177
        output reg    [1:0]                     o_taken_ff
178
);
179
 
180
// ----------------------------------------------------------------------------
181
 
182
`include "zap_defines.vh"
183
`include "zap_localparams.vh"
184
`include "zap_functions.vh"
185
 
186
wire    [3:0]                   o_condition_code_nxt;
187
wire    [$clog2(PHY_REGS )-1:0] o_destination_index_nxt;
188
wire    [32:0]                  o_alu_source_nxt;
189
wire    [$clog2(ALU_OPS)-1:0]   o_alu_operation_nxt;
190
wire    [32:0]                  o_shift_source_nxt;
191
wire    [$clog2(SHIFT_OPS)-1:0] o_shift_operation_nxt;
192
wire    [32:0]                  o_shift_length_nxt;
193
wire                            o_flag_update_nxt;
194
wire   [$clog2(PHY_REGS )-1:0]  o_mem_srcdest_index_nxt; // Data register.
195
wire                            o_mem_load_nxt;          // Type of operation...
196
wire                            o_mem_store_nxt;
197
wire                            o_mem_pre_index_nxt;     // Indicate pre-ALU tap for address.
198
wire                            o_mem_unsigned_byte_enable_nxt;// Byte enable (unsigned).
199
wire                            o_mem_signed_byte_enable_nxt;
200
wire                            o_mem_signed_halfword_enable_nxt;
201
wire                            o_mem_unsigned_halfword_enable_nxt;
202
wire                            o_mem_translate_nxt;    // Force user's view of memory.
203
wire                            o_force_locked_access_nxt;
204
wire                            o_irq_nxt;
205
wire                            o_fiq_nxt;
206
wire                            o_abt_nxt;
207
reg                             o_swi_nxt;
208
wire                            o_und_nxt;
209
wire                            o_switch_nxt;
210
 
211
wire [$clog2(ARCH_REGS)-1:0]    destination_index_nxt;
212
wire [32:0]                     alu_source_nxt;
213
wire [32:0]                     shift_source_nxt;
214
wire [32:0]                     shift_length_nxt;
215
wire [$clog2(ARCH_REGS)-1:0]    mem_srcdest_index_nxt;
216
 
217
// ----------------------------------------------------------------------------
218
 
219
// Abort
220
assign  o_abt_nxt = (i_abt || i_thumb_und) && i_instruction_valid;
221
 
222
// IRQ and FIQ next state.
223
assign  o_irq_nxt = i_irq & !i_cpsr_ff_i; // Pass only when mask is 0.
224
assign  o_fiq_nxt = i_fiq & !i_cpsr_ff_f;  // Pass only when mask is 0.
225
 
226
//
227
// This section translates the indices from the decode stage converts
228
// into a physical index. This is needed because the decode.v module extracts
229
// architectural register numbers.
230
//
231
assign  o_destination_index_nxt = // Always a register so no need for IMMED_EN. 
232
        translate ( destination_index_nxt, i_cpsr_ff_mode );
233
 
234
assign  o_alu_source_nxt =
235
        (alu_source_nxt[32] == IMMED_EN ) ? // Constant...?
236
        alu_source_nxt : // Pass constant on.
237
        translate ( alu_source_nxt, i_cpsr_ff_mode ); // Translate index.
238
 
239
assign  o_shift_source_nxt =
240
        (shift_source_nxt[32] == IMMED_EN ) ? // Constant...?
241
        shift_source_nxt : // Pass constant on.
242
        translate ( shift_source_nxt, i_cpsr_ff_mode ); // Translate index.
243
 
244
assign  o_shift_length_nxt =
245
        (shift_length_nxt[32] == IMMED_EN ) ? // Constant...?
246
        shift_length_nxt : // Pass constant on.
247
        translate ( shift_length_nxt, i_cpsr_ff_mode ); // Translate index.
248
 
249
assign  o_mem_srcdest_index_nxt = // Always a register so no need for IMMED_EN.       
250
        translate ( mem_srcdest_index_nxt, i_cpsr_ff_mode );
251
 
252
 
253
// ----------------------------------------------------------------------------
254
 
255
//
256
// The actual decision whether or not to execute this is taken in EX stage.
257
// At this point, we don't do anything with the SWI except take note.
258
//
259
always @*
260
        o_swi_nxt = &i_instruction[27:24];
261
 
262
// ----------------------------------------------------------------------------
263
 
264
wire [64*8-1:0] decompile_tmp;
265
 
266
// Flop the outputs to break the pipeline at this point.
267
always @ (posedge i_clk)
268
begin
269
        if ( i_reset )
270
        begin
271
                clear;
272
        end
273
        else if ( i_clear_from_writeback )
274
        begin
275
                clear;
276
        end
277
        else if ( i_data_stall )
278
        begin
279
                // Preserve state.
280
        end
281
        else if ( i_clear_from_alu )
282
        begin
283
                clear;
284
        end
285
        else if ( i_stall_from_shifter )
286
        begin
287
                // Preserve state.
288
        end
289
        else if ( i_stall_from_issue )
290
        begin
291
                // Preserve state.
292
        end
293
        // If no stall, only then update...
294
        else
295
        begin
296
                o_irq_ff                                <= o_irq_nxt;
297
                o_fiq_ff                                <= o_fiq_nxt;
298
                o_swi_ff                                <= o_swi_nxt;
299
                o_abt_ff                                <= o_abt_nxt;
300
                o_und_ff                                <= o_und_nxt;
301
                o_condition_code_ff                     <= o_condition_code_nxt;
302
                o_destination_index_ff                  <= o_destination_index_nxt;
303
                o_alu_source_ff                         <= o_alu_source_nxt;
304
                o_alu_operation_ff                      <= o_alu_operation_nxt;
305
                o_shift_source_ff                       <= o_shift_source_nxt;
306
                o_shift_operation_ff                    <= o_shift_operation_nxt;
307
                o_shift_length_ff                       <= o_shift_length_nxt;
308
                o_flag_update_ff                        <= o_flag_update_nxt;
309
                o_mem_srcdest_index_ff                  <= o_mem_srcdest_index_nxt;
310
                o_mem_load_ff                           <= o_mem_load_nxt;
311
                o_mem_store_ff                          <= o_mem_store_nxt;
312
                o_mem_pre_index_ff                      <= o_mem_pre_index_nxt;
313
                o_mem_unsigned_byte_enable_ff           <= o_mem_unsigned_byte_enable_nxt;
314
                o_mem_signed_byte_enable_ff             <= o_mem_signed_byte_enable_nxt;
315
                o_mem_signed_halfword_enable_ff         <= o_mem_signed_halfword_enable_nxt;
316
                o_mem_unsigned_halfword_enable_ff       <= o_mem_unsigned_halfword_enable_nxt;
317
                o_mem_translate_ff                      <= o_mem_translate_nxt;
318
                o_pc_plus_8_ff                          <= i_pc_plus_8_ff;
319
                o_pc_ff                                 <= i_pc_ff;
320
                o_switch_ff                             <= o_switch_nxt;
321
                o_force32align_ff                       <= i_force32align;
322
                o_taken_ff                              <= i_taken;
323
 
324
                // For debug
325
                o_decompile                             <= decompile_tmp;
326
        end
327
end
328
 
329
// ----------------------------------------------------------------------------
330
 
331
task clear; // Clear and refresh the unit. Clear everything and a set a dummy
332
            // output to NV acting like a reset.
333
begin
334
                o_irq_ff                                <= 0;
335
                o_fiq_ff                                <= 0;
336
                o_swi_ff                                <= 0;
337
                o_abt_ff                                <= 0;
338
                o_condition_code_ff                     <= NV;
339
                o_und_ff                                <= 0;
340
                o_taken_ff                              <= 0;
341
end
342
endtask
343
 
344
// ----------------------------------------------------------------------------
345
 
346
// Bulk of the decode logic is here.
347
zap_decode #(
348
        .ARCH_REGS      (ARCH_REGS),
349
        .ALU_OPS        (ALU_OPS),
350
        .SHIFT_OPS      (SHIFT_OPS)
351
)
352
u_zap_decode (
353
        .i_irq(i_irq),
354
        .i_fiq(i_fiq),
355
        .i_abt(i_abt),
356
        .i_instruction(i_instruction),
357
        .i_instruction_valid(i_instruction_valid),
358
        .i_cpsr_ff_mode(i_cpsr_ff_mode),
359
        .o_condition_code(o_condition_code_nxt),
360
        .o_destination_index(destination_index_nxt),
361
        .o_alu_source(alu_source_nxt),
362
        .o_alu_operation(o_alu_operation_nxt),
363
        .o_shift_source(shift_source_nxt),
364
        .o_shift_operation(o_shift_operation_nxt),
365
        .o_shift_length(shift_length_nxt),
366
        .o_flag_update(o_flag_update_nxt),
367
        .o_mem_srcdest_index(mem_srcdest_index_nxt),
368
        .o_mem_load(o_mem_load_nxt),
369
        .o_mem_store(o_mem_store_nxt),
370
        .o_mem_pre_index(o_mem_pre_index_nxt),
371
        .o_mem_unsigned_byte_enable(o_mem_unsigned_byte_enable_nxt),
372
        .o_mem_signed_byte_enable(o_mem_signed_byte_enable_nxt),
373
        .o_mem_signed_halfword_enable(o_mem_signed_halfword_enable_nxt),
374
        .o_mem_unsigned_halfword_enable(o_mem_unsigned_halfword_enable_nxt),
375
        .o_mem_translate(o_mem_translate_nxt),
376
        .o_und(o_und_nxt),
377
        .o_switch(o_switch_nxt)
378
);
379
 
380
// -------------------------------------------------------------------------------
381
 
382
// Decompile
383
 
384
 
385
zap_decompile u_zap_decompile (
386
        .i_instruction  (i_instruction),
387
        .i_dav          (i_instruction_valid),
388
        .o_decompile    (decompile_tmp)
389
);
390
 
391
 
392
endmodule // zap_decode_main.v
393
`default_nettype wire

powered by: WebSVN 2.1.0

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