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

Subversion Repositories forwardcom

[/] [forwardcom/] [trunk/] [decoder.sv] - Blame information for rev 23

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 23 Agner
//////////////////////////////////////////////////////////////////////////////////
2
// Engineer: Agner Fog
3
//
4
// Create Date:    2020-05-30
5
// Last modified:  2021-07-11
6
// Module Name:    decoder
7
// Project Name:   ForwardCom soft core
8
// Target Devices: Artix 7
9
// Tool Versions:  Vivado v. 2020.1
10
// License:        CERN-OHL-W v. 2 or later
11
// Description:    Instruction decoder. Identifies instruction category and format,
12
// Loads register parameters. Generates multiple µops for push and pop instructions
13
//
14
//////////////////////////////////////////////////////////////////////////////////
15
`include "defines.vh"
16
 
17
// To do:
18
// Push and pop instructions generate multiple µops in the decoder.
19
 
20
module decoder (
21
    input clock,                            // system clock (100 MHz)
22
    input clock_enable,                     // clock enable. Used when single-stepping
23
    input reset,                            // system reset.
24
    input valid_in,                         // data from fetch module ready
25
    input stall_in,                         // a later stage in pipeline is stalled
26
    input [`CODE_ADDR_WIDTH-1:0] instruction_pointer_in, // address of current instruction
27
    input [95:0] instruction_in,            // current instruction, up to 3 words long
28
    // monitor tags written to register file:
29
    input write_en1,                        // a result is written to writeport1
30
    input [`TAG_WIDTH-1:0] write_tag1,      // tag of result inwriteport1
31
    input write_en2,                        // a result is written to writeport2
32
    input [`TAG_WIDTH-1:0] write_tag2,      // tag of result inwriteport2
33
    output reg        valid_out,            // An instruction is ready for output to next stage
34
    output reg [`CODE_ADDR_WIDTH-1:0] instruction_pointer_out, // address of current instruction
35
    output reg [95:0] instruction_out,      // first word of instruction
36
    output reg        stall_out,            // Not ready to receive next instruction
37
    output reg [5:0]  tag_a_out,            // register number for instruction tag
38
    output reg [`TAG_WIDTH-1:0] tag_val_out,// instruction tag value
39
    output reg        tag_write_out,        // instruction tag write enable
40
    output reg        vector_out,           // this is a vector instruction
41
    output reg [1:0]  category_out,         // 00: multiformat, 01: single format, 10: jump
42
    output reg [1:0]  format_out,           // 00: format A, 01: format E, 10: format B, 11: format C (format D never goes through decoder)
43
    output reg [2:0]  rs_status_out,        // what RS is used for
44
    output reg [2:0]  rt_status_out,        // what RT is used for
45
    output reg [1:0]  ru_status_out,        // what RU is used for
46
    output reg [1:0]  rd_status_out,        // what RD is used for
47
    output reg [1:0]  mask_status_out,      // what the mask register is used for
48
    output reg        mask_options_out,     // mask register may contain option bits
49
    output reg        mask_alternative_out, // mask register and fallback register used for alternative purposes
50
    output reg [2:0]  fallback_use_out,     // 0: no fallback, 1: same as first source operand, 2-4: RU, RS, RT
51
    output reg [1:0]  num_operands_out,     // number of source operands
52
    output reg [1:0]  result_type_out,      // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
53
    output reg [1:0]  offset_field_out,     // address offset. 0: none, 1: 8 bit, possibly scaled, 2: 16 bit, 3: 32 bit
54
    output reg [1:0]  immediate_field_out,  // immediate data field. 0: none, 1: 8 bit, 2: 16 bit, 3: 32 or 64 bit
55
    output reg [1:0]  scale_factor_out,     // 00: index is not scaled, 01: index is scaled by operand size, 10: index is scaled by -1
56
    output reg        index_limit_out,      // The field indicated by offset_field contains a limit to the index
57
    output reg [31:0] debug1_out            // Temporary output for debugging purpose
58
);
59
 
60
logic [1:0]  register_type;                 // 1: general purpose registers, 2: vector registers
61
logic [1:0]  category;                      // 00: multiformat, 01: single format, 10: jump
62
logic [1:0]  format;                        // 00: format A, 01: format E, 10: format B, 11: format C (format D never goes through decoder)
63
 
64
logic [1:0]  num_operands;                  // number of source operands
65
logic [2:0]  rs_status;                     // use of RS register
66
logic [2:0]  rt_status;                     // use of RT register
67
logic [1:0]  ru_status;                     // use of RU register
68
logic [1:0]  rd_status;                     // use of RD register for input
69
logic        mask_used;                     // 1: mask register is used
70
logic        mask_options;                  // mask register may contain options
71
logic [2:0]  fallback_use;                  // 0: no fallback, 1: same as first source operand, 2-4: RU, RS, RT
72
logic [1:0]  scale_factor;                  // 00: index is not scaled, 01: index is scaled by operand size, 10: index is scaled by -1
73
logic [1:0]  offset_field;                  // address offset. 0: none, 1: 8 bit, possibly scaled, 2: 16 bit, 3: 32 bit
74
logic [1:0]  immediate_field;               // immediate data field. 0: none, 1: 8 bit, 2: 16 bit, 3: 32 or 64 bit
75
logic        index_limit;                   // The field indicated by offset_field contains a limit to the index
76
logic        broadcast;                     // Broadcast scalar memory operand or immediate operand
77
logic [1:0]  result_type;                   // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
78
logic        format_error;                  // unknown or unsupported instruction format
79
logic        tag_write;                     // a tag is written
80
logic        tag_error;                     // unpredicted tag error
81
logic [1:0]  il;                            // instruction length
82
logic [2:0]  mode;                          // instruction mode
83
logic [5:0]  op1;                           // OP1 in instruction
84
logic        M;                             // M bit
85
logic [1:0]  op2;                           // OP2 in E format
86
logic [2:0]  mode2;                         // mode2 in E format
87
logic        valid;                         // valid output is ready
88
logic        mask_alternative;              // mask register and fallback register used for alternative purposes
89
integer signed count_inputs;                // calculate whether RD and RU are needed for input operands
90
 
91
reg [`TAG_WIDTH-1:0]      current_tag = 1;  // sequential instruction tags
92
reg [(2**`TAG_WIDTH)-1:0] tag_used = 0;     // remember which tags are in use
93
logic [`TAG_WIDTH-1:0]    next_tag;         // next instruction tags
94
 
95
// analyze instruction
96
always_comb begin
97
    il   = instruction_in[`IL];
98
    mode = instruction_in[`MODE];
99
    op1  = instruction_in[`OP1];
100
    M    = instruction_in[`M];
101
    op2  = instruction_in[`OP2];
102
    mode2 = instruction_in[`MODE2];
103
    num_operands = 2;
104
    ru_status = 0;
105
    rd_status = 0;
106
    mask_used = 0;
107
    mask_options = 0;
108
    mask_alternative = 0;
109
    format_error = 0;
110
    valid = valid_in & !reset;
111
 
112
    // detect instruction format: A, B, C, or E (format D never comes to the decoder)
113
    if (il == 0) begin // format 0.x
114
        if (mode == 1 || mode == 3 || mode == 7) begin
115
            format = `FORMAT_B;        // 0.1, 0.3, 0.7, 0.9
116
        end else begin
117
            format = `FORMAT_A;        // 0.0, 0.2, 0.4, 0.5, 0.6, 0.8
118
        end
119
 
120
    end else if (il == 1) begin        // format 1.x
121
        if (mode == 3 || (mode == 0 && M)) begin
122
            format = `FORMAT_B;        // 1.3, 1.8
123
        end else if (mode == 6) begin  // 1.6 jump instructions
124
            if (op1 == `II_RETURN) format = `FORMAT_C;  // return
125
            else if (op1 >= `II_JUMP_RELATIVE) begin
126
                format = `FORMAT_A;    // relative jump, sys_call
127
            end else format = `FORMAT_B;
128
        end else if (mode == 1 || mode == 4 || mode == 7) begin
129
            format = `FORMAT_C;        //1.1, 1.4, 1.7
130
        end else begin
131
            format = `FORMAT_A;        // 1.0, 1.2
132
        end
133
 
134
    end else if (il == 2) begin        // format 2.x
135
        if ((mode == 0 && M == 0) || mode == 2) begin
136
            format = `FORMAT_E;        // 2.0.x, 2.2.x
137
 
138
        end else if (mode == 5) begin  // format 2.5 mixed
139
            if (op1 == 0)      format = `FORMAT_A; // jump format 2.5.0A
140
            else if (op1 <= 3) format = `FORMAT_B; // jump format 2.5.1B, 2.5.2B
141
            else if (op1 <= 7) format = `FORMAT_C; // jump format 2.5.4C - 2.5.7C
142
            else if (op1 >= `II_25_VECT) format = `FORMAT_A;  // 2.5 32-63 vector instructions
143
            else format = `FORMAT_B;   // other miscellaneous instructions
144
 
145
        end else begin
146
            format = `FORMAT_A;        // other formats 2.x
147
        end
148
 
149
    end else begin // format 3.x
150
        if ((mode == 0 && M == 0) || mode == 2) begin
151
            format = `FORMAT_E;        // 3.0.x, 3.2.x
152
        end else if (mode == 1) begin  // 3.1 mixed
153
            if (op1 > 0 && op1 < 8) begin // jump instructions 3.1.1 - 3.1.7
154
                format = `FORMAT_B;
155
            end else begin
156
                format = `FORMAT_A;
157
            end
158
        end else begin
159
            format = `FORMAT_A;
160
        end
161
    end
162
 
163
    // detect category, 00: multiformat, 01: single format, 10: jump
164
    // (this differs from the category numbers in instruction_list.cvs)
165
    if (il == 0) begin // format 0.x
166
        category = `CAT_MULTI;
167
 
168
    end else if (il == 1) begin             // format 1.x
169
        if (mode == 6 || mode == 7) begin   // format 1.6 and 1.7
170
            category = `CAT_JUMP;
171
        end else begin
172
            category = `CAT_SINGLE;
173
        end
174
 
175
    end else if (il == 2 && ((mode == 0 && !M) || mode == 2) && op2 != 0 && mode2 != 5) begin
176
        // op2 > 0 in format 2.0.x, 2.2.x, except 2.0.5, 2.2.5
177
        category = `CAT_SINGLE;
178
 
179
    end else if (il == 3 && ((mode == 0 && !M) || mode == 2) && op2 != 0) begin
180
        // op2 > 0 in format 3.0.x, 3.2.x
181
        category = `CAT_SINGLE;
182
 
183
    end else if (il == 2) begin             // format 2.x
184
        if (mode == 1 && M) begin           // format 2.9
185
            category = `CAT_SINGLE;
186
        end else if (mode == 6 || mode == 7) begin // format 2.6 - 2.7
187
            category = `CAT_SINGLE;
188
        end else if (mode == 5) begin       // format 2.5
189
            if (op1 < 8) begin
190
                category = `CAT_JUMP;
191
            end else begin
192
                category = `CAT_SINGLE;
193
            end
194
        end else begin
195
            category = `CAT_MULTI;
196
        end
197
 
198
    end else begin                          // format 3.x
199
        if (mode == 1) begin                // format 3.1
200
            if (op1 < 8) begin
201
                category = `CAT_JUMP;
202
            end else begin
203
                category = `CAT_SINGLE;
204
            end
205
        end else begin
206
            category = `CAT_MULTI;
207
        end
208
    end
209
 
210
    // is this a vector instruction?
211
    register_type = `REG_OPERAND;
212
    if (category == `CAT_JUMP) begin
213
        if (M && format != `FORMAT_C) register_type = `REG_VECTOR;
214
    end else if (il == 2 && mode == 5) begin // 2.5 mixed
215
        if (op1 >= `II_25_VECT) register_type = `REG_VECTOR;
216
    end else if (il == 3 && mode == 1) begin // 3.1 mixed
217
        if (op1 >= `II_31_VECT) register_type = `REG_VECTOR;
218
    end else if (mode >= 2) begin
219
        register_type = `REG_VECTOR;
220
    end
221
 
222
    // count number of operands and mask use
223
    if (category == `CAT_MULTI) begin
224
        if (op1 == `II_NOP) num_operands = 0;
225
        else if (op1 <= `II_ONE_OP) num_operands = 1;
226
        else if (op1 >= `II_3OP_FIRST && op1 <= `II_3OP_LAST) begin
227
            num_operands = 3;
228
            // There are currently no g.p. instructions that have option bits in a mask register.
229
            // To do: Set mask_options for relevant floating point instructions
230
            // if (format != `FORMAT_A && format != `FORMAT_E) mask_options = 1;
231
        end
232
        if ((format == `FORMAT_E || format == `FORMAT_A) && (op1 == `II_COMPARE || op1 == `II_TEST_BIT || op1 == `II_TEST_BITS_AND || op1 == `II_TEST_BITS_OR)) begin
233
            mask_alternative = 1; // these instructions allow alternative use of mask register and fallback register
234
        end
235
        /* This is done in address generator:
236
        if (format == `FORMAT_E && op1 >= `II_MUL_ADD_FLOAT16 && op1 <= `II_ADD_ADD) begin
237
            options_im3 = 1;   // IM3 contains option bits, not shift count
238
        end*/
239
    end else if (il == 1 && mode == 1) begin               // format 1.1 C (don't check M because there is no M bit in format C)
240
        if (op1 <= `II_MOVE11_LAST) num_operands = 1;      // move
241
 
242
    end else if (il == 1 && mode == 2) begin               // format 1.2 A
243
        if (op1 <= `II_GETNUM_12) num_operands = 1;
244
        if (op1 == `II_OUTPUT_18) num_operands = 3;        // output instruction
245
 
246
    end else if (il == 1 && mode == 0 && M) begin          // format 1.8
247
        if (op1 == `II_VECTORS_USED) num_operands = 0;     // vectors_used instruction
248
        if (op1 == `II_OUTPUT_18)  num_operands = 3;       // output instruction
249
 
250
    end else if (il == 2 && mode == 6) begin               // format 2.6 A
251
        if (op1 == `II_LOAD_HI_26) num_operands = 1;       // load_hi instruction
252
 
253
    end else if (il == 2 && mode == 1 && M) begin          // format 2.9 A
254
        if (op1 == `II_MOVE_HI_29 || op1 == `II_ADDRESS_29) num_operands = 1; // mov or address instruction
255
 
256
    end else if (il == 2 && (mode == 0 && !M || mode == 2)) begin // format 2.0.x, 2.2.x
257
        if (mode2 == 6 && op1 == `II_TRUTH_TAB3 && op2 == `II2_TRUTH_TAB3) begin
258
            num_operands = 3;                              // truth_tab3. 3 operands
259
        end
260
        if (mode2 == 7 && op1 == `II_MOVE_BITS && op2 == `II2_MOVE_BITS) begin
261
            num_operands = 3;                              // move_bits. 3 operands (Actually 5 operands: IM2 contains two 6-bit constants, IM3 contains the last operand)
262
        end
263
 
264
    end else if (category == `CAT_JUMP) begin
265
        if (il == 1 && mode == 6) begin
266
            if (op1 >> 1 == `IJ_JUMP_INDIRECT_MEM >> 1) num_operands = 1;
267
            else if (op1 >> 1 == `IJ_RETURN >> 1) num_operands = 0;
268
 
269
        end else if (il == 1 && mode == 7) begin
270
            if (op1 >> 1 == `IJ_JUMP_INDIRECT_REG >> 1) num_operands = 1;
271
            else if (op1 == `IJ_SYSRETURN || op1 == `IJ_TRAP) num_operands = 0;
272
 
273
        end else if (il == 2 && mode == 5 && instruction_in[5:1] == 58 >> 1) begin
274
            num_operands = 1;
275
        end
276
        // else if ?
277
 
278
    end
279
 
280
    if (format == `FORMAT_A || format == `FORMAT_E) begin
281
        if (instruction_in[`MASK] != 7) mask_used = 1;     // a mask register is used
282
    end
283
 
284
    // detect use of registers and pointer, index, scale factor, offset, limit, fallback
285
    index_limit = 0;
286
    offset_field = `OFFSET_NONE;
287
    immediate_field = `IMMED_NONE;
288
    rs_status = `REG_UNUSED;
289
    rt_status = `REG_UNUSED;
290
    rd_status = `REG_UNUSED;
291
    scale_factor = `SCALE_UNDEF;
292
    broadcast = 0;
293
    fallback_use = mask_used ? `FALLBACK_SOURCE : `FALLBACK_NONE;
294
 
295
    // detect format
296
    if (il == 0) begin // format 0.x
297
        if ((mode == 0 && !M) || mode == 2) begin
298
            // format 0.0A, 0.2A: RD = f3(RD, RS, RT)
299
            if (num_operands > 0) rt_status = register_type;
300
            if (num_operands > 1 || mask_used) rs_status = register_type;
301
            if (num_operands > 2) rd_status = register_type;
302
            if (mask_used && num_operands == 1) fallback_use = `FALLBACK_RS;
303
        end else if ((mode == 1 && !M) || mode == 3) begin
304
            // format 0.1B, 0.3B: RD = f3(RD, RS, IM1).
305
            if (num_operands > 1) rs_status = register_type;
306
            if (num_operands > 2) rd_status = register_type;
307
            immediate_field = `IMMED_1;
308
        end else if (mode == 4) begin
309
            // format 0.4A: RD = f2(RD, [RS]).
310
            if (num_operands > 1 || mask_used) rd_status = `REG_VECTOR;
311
            if (num_operands > 2) format_error = 1;
312
            rs_status = `REG_POINTER;
313
            rt_status = `REG_LENGTH;
314
        end else if (mode == 5) begin
315
            // format 0.5A: f2(RD, [RS-RT]).
316
            rs_status = `REG_POINTER;
317
            if (instruction_in[`RT] != 5'H1F) rt_status = `REG_INDEX;
318
            scale_factor = `SCALE_MINUS;
319
            if (num_operands > 1 || mask_used) rd_status = `REG_VECTOR;
320
            if (num_operands > 2) format_error = 1;
321
        end else if (mode == 6) begin
322
            // format 0.6A: f2(RD, [RS+RT*OS]). scalar
323
            rs_status = `REG_POINTER;
324
            if (instruction_in[`RT] != 5'H1F) rt_status = `REG_INDEX;
325
            scale_factor = `SCALE_OS;
326
            if (num_operands > 1 || mask_used) rd_status = `REG_VECTOR;
327
            if (num_operands > 2) format_error = 1;
328
        end else if (mode == 7) begin
329
            // format 0.7B: f2(RD, [RS+IM1*OS]). scalar
330
            rs_status = `REG_POINTER;
331
            scale_factor = `SCALE_OS;
332
            offset_field = `OFFSET_1;
333
            if (num_operands > 1) rd_status = `REG_VECTOR;
334
            if (num_operands > 2) format_error = 1;
335
        end else if (mode == 0 && M) begin
336
            // format 0.8A: f2(RD, [RS+RT*OS]).
337
            rs_status = `REG_POINTER;
338
            if (instruction_in[`RT] != 5'H1F) rt_status = `REG_INDEX;
339
            scale_factor = `SCALE_OS;
340
            if (num_operands > 1 || mask_used) rd_status = `REG_OPERAND;
341
            if (num_operands > 2) format_error = 1;
342
        end else if (mode == 1 && M) begin
343
            // format 0.9B: f2(RD, [RS+IM1*OS]).
344
            rs_status = `REG_POINTER;
345
            scale_factor = `SCALE_OS;
346
            offset_field = `OFFSET_1;
347
            if (num_operands > 1) rd_status = `REG_OPERAND;
348
            if (num_operands > 2) format_error = 1;
349
        end
350
 
351
    end else if (il == 1) begin
352
        // format 1.x. no memory operands
353
        if ((mode == 0 && !M) || mode == 2) begin
354
            // format 1.0A, 1.2A: RD = f3(RD, RS, RT).
355
            if (num_operands > 0) rt_status = register_type;
356
            if (num_operands > 1 || mask_used) rs_status = register_type;
357
            if (num_operands > 2) rd_status = register_type;
358
            if (mask_used && num_operands == 1) fallback_use = `FALLBACK_RS;
359
        end else if (mode == 1 || mode == 4) begin
360
            // format 1.1C, 1.4C: RD = f2(RD, IM1-2).
361
            if (num_operands > 1) rd_status = register_type;
362
            if (num_operands > 2) format_error = 1;
363
            immediate_field = `IMMED_2;
364
        end else if (mode == 3 || (mode == 0 & M)) begin
365
            // format 1.3B, 1.8B: RD = f3(RD, RS, IM1).
366
            if (num_operands > 1) rs_status = register_type;
367
            if (num_operands > 2) rd_status = register_type;
368
            if (op1 == `II_READ_SPEC18 && mode[0] == 0) rs_status = `REG_SYSTEM;
369
            immediate_field = `IMMED_1;
370
        end else if (mode == 4) begin
371
            // format 1.4C: RD = f2(RD, IM1-2)
372
            immediate_field = `IMMED_2;
373
            if (num_operands > 1) rd_status = register_type;
374
        end else if (mode == 5) begin
375
            // format 1.5:
376
            format_error = 1;                              // format 1.5 unused
377
        end else if (mode == 6) begin
378
            // format 1.6: jump instructions
379
            if (op1 <= `IJ_LAST_CONDITIONAL) begin
380
                // ordinary conditional jumps
381
                rs_status = register_type;
382
                rd_status = register_type;
383
            end else if (op1[5:1] == (`IJ_JUMP_INDIRECT_MEM >> 1)) begin
384
                // indirect jump to memory address
385
                rs_status = `REG_POINTER;
386
                offset_field = `OFFSET_1;
387
                scale_factor = `SCALE_OS;
388
            end else if (op1[5:1] == (`IJ_JUMP_RELATIVE >> 1)) begin
389
                // jump to table of relative pointers in memory. format 1.6A
390
                rs_status = `REG_POINTER;
391
                if (instruction_in[`RT] != 5'H1F) rt_status = `REG_INDEX;
392
                rd_status = `REG_OPERAND;
393
                scale_factor = `SCALE_OS;
394
                offset_field = `OFFSET_NONE;
395
                if (instruction_in[`MASK] != 7) format_error = 1; // mask not allowed
396
            end else if (op1 == `IJ_SYSCALL) begin
397
                rs_status = `REG_OPERAND;
398
                rt_status = `REG_OPERAND;
399
                rd_status = `REG_OPERAND;
400
            end
401
        end else if (mode == 7) begin
402
            // format 1.7: jump instructions
403
            if (op1 != `IJ_SYSRETURN && op1 != `IJ_TRAP) begin
404
                rd_status = register_type;
405
            end
406
            if (op1 <= `IJ_LAST_CONDITIONAL) begin
407
                immediate_field = `IMMED_1;                // IM2 = immediate operand
408
            end
409
        end else if (mode == 0 && M) begin
410
            // format 1.8B: RD = f3(RD, RS, IM1).
411
            if (num_operands > 0) rs_status = `REG_OPERAND;
412
            if (num_operands > 1) rd_status = `REG_OPERAND;
413
            if (num_operands > 2) format_error = 1;
414
            immediate_field = `IMMED_1;
415
        end
416
 
417
    end else if (il == 2 && mode == 0 && !M) begin
418
        // format 2.0.x E
419
        if (mode2 == 0) begin
420
            // format 2.0.0: RD = f3(RU, RT, [RS+IM2]).
421
            rs_status = `REG_POINTER;
422
            offset_field = `OFFSET_2;
423
            if (num_operands > 1) rt_status = `REG_OPERAND;
424
            if (num_operands > 2 | mask_used | mask_alternative) ru_status = `REG_OPERAND;
425
            if ((mask_used | mask_alternative) && num_operands < 3) fallback_use = `FALLBACK_RU;
426
        end else if (mode2 == 1) begin
427
            // format 2.0.1: RD = f3(RD, RU, [RS+RT+IM2]).
428
            rs_status = `REG_POINTER;
429
            if (instruction_in[`RT] != 5'H1F) rt_status = `REG_INDEX;
430
            offset_field = `OFFSET_2;
431
            scale_factor = `SCALE_NONE;
432
            if (num_operands > 1 || mask_used) ru_status = `REG_OPERAND;
433
            if (num_operands > 2) rd_status = `REG_OPERAND;
434
            if (mask_used && num_operands == 1) begin
435
                fallback_use = `FALLBACK_RU;  ru_status = `REG_OPERAND;
436
            end
437
        end else if (mode2 == 2) begin
438
            // format 2.0.2: RD = f3(RD, RU, [RS+RT*OS+IM2]).
439
            rs_status = `REG_POINTER;
440
            if (instruction_in[`RT] != 5'H1F) rt_status = `REG_INDEX;
441
            offset_field = `OFFSET_2;
442
            scale_factor = `SCALE_OS;
443
            if (num_operands > 1 || mask_used) ru_status = `REG_OPERAND;
444
            if (num_operands > 2) rd_status = `REG_OPERAND;
445
            if (mask_used && num_operands == 1) fallback_use = `FALLBACK_RU;
446
        end else if (mode2 == 3) begin
447
            // format 2.0.3: RD = f3(RD, RU, [RS+RT*OS]).. limit IM2
448
            rs_status = `REG_POINTER;
449
            if (instruction_in[`RT] != 5'H1F) rt_status = `REG_INDEX;
450
            scale_factor = `SCALE_OS;
451
            index_limit = 1;
452
            if (num_operands > 1 || mask_used) ru_status = `REG_OPERAND;
453
            if (num_operands > 2) rd_status = `REG_OPERAND;
454
            if (mask_used && num_operands == 1) fallback_use = `FALLBACK_RU;
455
        end else if (mode2 == 5) begin
456
            // format 2.0.5: RD = f3(RU, [RS+RT*OS+IM2], IM3).
457
            rs_status = `REG_POINTER;
458
            if (instruction_in[`RT] != 5'H1F) rt_status = `REG_INDEX;
459
            scale_factor = `SCALE_OS;
460
            offset_field = `OFFSET_2;
461
            immediate_field = `IMMED_1;                    // immediate field IM3 extended into OP2
462
            if (num_operands > 2 | mask_used | mask_alternative) ru_status = `REG_OPERAND;
463
            if ((mask_used | mask_alternative) && num_operands < 3) fallback_use = `FALLBACK_RU;
464
        end else if (mode2 == 6) begin
465
            offset_field = `OFFSET_NONE;
466
            // format 2.0.6: RD = f3(RU, RS, RT).
467
            rt_status = `REG_OPERAND;
468
            if (num_operands > 1) rs_status = `REG_OPERAND;
469
            if (num_operands > 2 | mask_used | mask_alternative) ru_status = `REG_OPERAND;
470
            if ((mask_used | mask_alternative) && num_operands < 3) fallback_use = `FALLBACK_RU;
471
        end else if (mode2 == 7) begin
472
            immediate_field = `IMMED_2;
473
            // format 2.0.7: RD = f3(RS, RT, IM2 << IM3).
474
            if (num_operands > 1) rt_status = `REG_OPERAND;
475
            if (num_operands > 2) rs_status = `REG_OPERAND;
476
            if ((mask_used | mask_alternative) && num_operands < 3) begin
477
                fallback_use = `FALLBACK_RS;  rs_status = `REG_OPERAND;
478
            end
479
        end else begin
480
            // format 2.0.4 unused
481
            format_error = 1;
482
        end
483
 
484
    end else if (il == 2 && mode == 1 && !M) begin
485
        // format 2.1A. RD = f3(RD, RT, [RS+IM2]).
486
        rs_status = `REG_POINTER;
487
        offset_field = `OFFSET_3;
488
        scale_factor = `SCALE_NONE;
489
        if (num_operands > 1 || mask_used) rt_status = `REG_OPERAND;
490
        if (num_operands > 2) rd_status = `REG_OPERAND;
491
        if (mask_used && num_operands == 1) fallback_use = `FALLBACK_RT;
492
 
493
    end else if (il == 2 && mode == 2) begin
494
        // format 2.2.x E
495
        if (mode2 == 0) begin
496
            // format 2.2.0: RD = f3(RD, RU, [RS+IM2]). broadcast
497
            rs_status = `REG_POINTER;
498
            if (instruction_in[`RT] != 5'H1F) rt_status = `REG_LENGTH;
499
            offset_field = `OFFSET_2;
500
            broadcast = 1;
501
            if (num_operands > 1 || mask_used) ru_status = `REG_VECTOR;
502
            if (num_operands > 2) rd_status = `REG_VECTOR;
503
            if (mask_used && num_operands == 1) fallback_use = `FALLBACK_RU;
504
        end else if (mode2 == 1) begin
505
            // format 2.2.1: RD = f3(RD, RU, [RS+IM2]). length RT
506
            rs_status = `REG_POINTER;
507
            if (instruction_in[`RT] != 5'H1F) rt_status = `REG_LENGTH;
508
            offset_field = `OFFSET_2;
509
            if (num_operands > 1 || mask_used) ru_status = `REG_VECTOR;
510
            if (num_operands > 2) rd_status = `REG_VECTOR;
511
            if (mask_used && num_operands == 1) fallback_use = `FALLBACK_RU;
512
        end else if (mode2 == 2) begin
513
            // format 2.2.2: RD = f3(RD, RU, [RS+RT*OS+IM2]).. scalar
514
            rs_status = `REG_POINTER;
515
            if (instruction_in[`RT] != 5'H1F) rt_status = `REG_INDEX;
516
            offset_field = `OFFSET_2;
517
            scale_factor = `SCALE_OS;
518
            if (num_operands > 1 || mask_used) ru_status = `REG_VECTOR;
519
            if (num_operands > 2) rd_status = `REG_VECTOR;
520
            if (mask_used && num_operands == 1) fallback_use = `FALLBACK_RU;
521
        end else if (mode2 == 3) begin
522
            // format 2.2.3: RD = f3(RD, RU, [RS+RT*OS]).. limit IM2
523
            rs_status = `REG_POINTER;
524
            if (instruction_in[`RT] != 5'H1F) rt_status = `REG_INDEX;
525
            scale_factor = `SCALE_OS;
526
            index_limit = 1;
527
            if (num_operands > 1 || mask_used) ru_status = `REG_VECTOR;
528
            if (num_operands > 2) rd_status = `REG_VECTOR;
529
            if (mask_used && num_operands == 1) fallback_use = `FALLBACK_RU;
530
        end else if (mode2 == 4) begin
531
            // format 2.2.4: RD = f3(RD, RU, [RS-RT+IM2]).
532
            rs_status = `REG_POINTER;
533
            if (instruction_in[`RT] != 5'H1F) rt_status = `REG_INDEX;
534
            scale_factor = `SCALE_MINUS;
535
            offset_field = `OFFSET_2;
536
            if (num_operands > 1 || mask_used) ru_status = `REG_VECTOR;
537
            if (num_operands > 2) rd_status = `REG_VECTOR;
538
            if (mask_used && num_operands == 1) fallback_use = `FALLBACK_RU;
539
        end else if (mode2 == 5) begin
540
            // format 2.2.5: RD = f3(RU, [RS+IM2], IM3).
541
            rs_status = `REG_POINTER;
542
            if (instruction_in[`RT] != 5'H1F) rt_status = `REG_LENGTH;
543
            offset_field = `OFFSET_2;
544
            immediate_field = `IMMED_1;                    // immediate field IM3 extended into OP2
545
            if (num_operands > 2 || mask_used) ru_status = `REG_OPERAND;
546
            if ((mask_used | mask_alternative) && num_operands < 3) begin
547
                fallback_use = `FALLBACK_RU;  ru_status = `REG_VECTOR;
548
            end
549
        end else if (mode2 == 6) begin
550
            // format 2.2.6: RD = f3(RU, RS, RT).
551
            offset_field = `OFFSET_NONE;                   // register operands only
552
            rt_status = `REG_VECTOR;
553
            if (num_operands > 1) rs_status = `REG_VECTOR;
554
            if (num_operands > 2) ru_status = `REG_VECTOR;
555
            if ((mask_used | mask_alternative) && num_operands < 3) begin
556
                fallback_use = `FALLBACK_RU; ru_status = `REG_VECTOR;
557
            end
558
        end else if (mode2 == 7) begin
559
            // format 2.2.7: RD = f3(RS, RT, IM2 << IM3).
560
            immediate_field = `IMMED_2;                    // immediate operand
561
            if (num_operands > 1) rt_status = `REG_VECTOR;
562
            if (num_operands > 2) rs_status = `REG_VECTOR;
563
            if ((mask_used | mask_alternative) && num_operands < 3) begin
564
                fallback_use = `FALLBACK_RS;  rs_status = `REG_VECTOR;
565
            end
566
        end
567
 
568
    end else if (il == 2 && mode == 3) begin
569
        // format 2.3A: RD = f3(RS, RT, IM2).
570
        immediate_field = `IMMED_3;                        // immediate operand
571
        if (num_operands > 1) rt_status = `REG_VECTOR;
572
        if (num_operands > 2 || mask_used) rs_status = `REG_VECTOR;
573
        if (mask_used && num_operands < 3)  fallback_use = `FALLBACK_RS;
574
 
575
    end else if (il == 2 && mode == 4) begin
576
        // format 2.4A: RD = f2(RD, [RS+IM2]). length=RT.
577
        rs_status = `REG_POINTER;
578
        if (instruction_in[`RT] != 5'H1F) rt_status = `REG_LENGTH;
579
        offset_field = `OFFSET_3;
580
        if (num_operands > 1 || mask_used) rd_status = `REG_VECTOR;
581
        if (num_operands > 2) format_error = 1;
582
 
583
    end else if (il == 2 && mode == 5) begin
584
        // format 2.5: jump or mixed
585
        if (op1 < 8) begin                                 // jump instructions. Detect number of operands
586
            if (op1 == 2 && instruction_in[5:1] == `IJ_JUMP_INDIRECT_MEM >> 1) num_operands = 1;
587
        end
588
        if (op1 == 0) begin
589
            // format 2.5.0A: jump with three register operands and 24 bit offset
590
            rs_status = register_type;
591
            rt_status = register_type;
592
        end else if (op1 == 1) begin
593
            // format 2.5.1B: jump with a register source operand and a 16-bit immediate operand
594
            rs_status = register_type;
595
            immediate_field = `IMMED_2;                    // 16 bit in lower half of IM2
596
        end else if (op1 == 2) begin
597
            // format 2.5.2B: jump with register (RD), memory operand w 16 bit address, 16 bit jump offset
598
            rd_status = register_type;
599
            rs_status = `REG_POINTER;
600
            offset_field = `OFFSET_2;
601
            if (instruction_in[5:1] == `IJ_JUMP_INDIRECT_MEM >> 1) offset_field = `OFFSET_3; // format 2.5.2x: 32 bit memory offset
602
        end else if (op1 == 3) begin
603
            // format 2.5.3: unused
604
            format_error = 1;
605
        end else if (op1 == 4) begin
606
            // format 2.5.4: jump with register (RD), one 8-bit immediate constant and 32 bit offset
607
            rd_status = register_type;
608
            immediate_field = `IMMED_1;                    // note: immediate operand in bit 8-15
609
        end else if (op1 == 5) begin
610
            // format 2.5.5: jump with one register operand (RD), an 8-bit offset and a 32-bit immediate constant
611
            rd_status = register_type;
612
            immediate_field = `IMMED_3;
613
        end else if (op1 == 6) begin
614
            // format 2.5.6: unused
615
            format_error = 1;
616
        end else if (op1 == 7) begin
617
            // format 2.5.7: system call, no OPJ, 16 bit constant and 32-bit constant
618
            rd_status = `REG_OPERAND;
619
            immediate_field = `IMMED_3;
620
        end else if (op1 == `II_STOREI) begin              // store constant to memory
621
            rs_status = `REG_POINTER;
622
            offset_field = `OFFSET_1;
623
            immediate_field = `IMMED_3;
624
        end else if (op1 == `II_CMPSWAP) begin             // compare_swap instruction not implemented
625
            rs_status = `REG_POINTER;
626
            rt_status = `REG_OPERAND;
627
            rd_status = `REG_OPERAND;
628
            offset_field = `OFFSET_3;
629
        end else begin                                     // other. mixed format. fallback use unknown
630
            rs_status = `REG_POINTER;
631
            offset_field = `OFFSET_3;
632
            rt_status = register_type;
633
            rd_status = register_type;
634
        end
635
 
636
    end else if (il == 2 && mode == 6) begin
637
        // format 2.6A: RD = f3(RS, RT, IM2).
638
        immediate_field = `IMMED_3;
639
        if (num_operands > 1) rt_status = `REG_VECTOR;
640
        if (num_operands > 2 || mask_used) rs_status = `REG_VECTOR;
641
        if (mask_used && num_operands < 3)  fallback_use = `FALLBACK_RS;
642
 
643
    end else if (il == 2 && mode == 7) begin
644
        // format 2.7: unused
645
        format_error = 1;
646
 
647
    end else if (il == 2 && mode == 0 && M) begin
648
        // format 2.8A: RD = f3(RS, RT, IM2).
649
        immediate_field = `IMMED_3;
650
        if (num_operands > 1) rt_status = `REG_OPERAND;
651
        if (num_operands > 2 || mask_used) rs_status = `REG_OPERAND;
652
        if (mask_used && num_operands < 3) begin
653
            fallback_use = `FALLBACK_RS;
654
        end
655
 
656
    end else if (il == 2 && mode == 1 && M) begin
657
        // format 2.9A: RD = f3(RS, RT, IM2).
658
        if (op1 == `II_ADDRESS_29) begin
659
            offset_field = `OFFSET_3;                      // address instruction
660
            rs_status = `REG_POINTER;
661
            if (mask_used) fallback_use = `FALLBACK_RT;    // can address instruction have mask?
662
            if (mask_used) rt_status = `REG_OPERAND;
663
 
664
        end else begin
665
            immediate_field = `IMMED_3;
666
            if (num_operands > 1) rt_status = `REG_OPERAND;
667
            if (num_operands > 2 || mask_used) rs_status = `REG_OPERAND;
668
            if (mask_used && num_operands < 3) fallback_use = `FALLBACK_RS;
669
        end
670
 
671
    end else if (il == 3 && mode == 0 && !M) begin
672
        // format 3.0.x E
673
        if (mode2 == 0) begin
674
            // format 3.0.0: RD = f3(RU, RS, [RS+IM4]).
675
            rs_status = `REG_POINTER;
676
            offset_field = `OFFSET_3;
677
            if (num_operands > 1) rt_status = `REG_OPERAND;
678
            if (num_operands > 2) ru_status = `REG_OPERAND;
679
            if ((mask_used | mask_alternative) && num_operands < 3) begin
680
                fallback_use = `FALLBACK_RU;  ru_status = `REG_OPERAND;
681
            end
682
        end else if (mode2 == 2) begin
683
            // format 3.0.2: RD = f3(RD, RU, [RS+RT*OS+IM4]).
684
            rs_status = `REG_POINTER;
685
            if (instruction_in[`RT] != 5'H1F) rt_status = `REG_INDEX;
686
            offset_field = `OFFSET_3;
687
            scale_factor = `SCALE_OS;
688
            if (num_operands > 1 || mask_used) ru_status = `REG_OPERAND;
689
            if (num_operands > 2) rd_status = `REG_OPERAND;
690
            if (mask_used && num_operands == 1) begin
691
                fallback_use = `FALLBACK_RU;
692
            end
693
        end else if (mode2 == 3) begin
694
            // format 3.0.3: RD = f3(RD, RU, [RS+RT*OS]).. limit IM4
695
            rs_status = `REG_POINTER;
696
            if (instruction_in[`RT] != 5'H1F) rt_status = `REG_INDEX;
697
            scale_factor = `SCALE_OS;
698
            index_limit = 1;
699
            if (num_operands > 1 || mask_used) ru_status = `REG_OPERAND;
700
            if (num_operands > 2) rd_status = `REG_OPERAND;
701
            if (mask_used && num_operands == 1) begin
702
                fallback_use = `FALLBACK_RU;
703
            end
704
        end else if (mode2 == 5) begin
705
            // format 3.0.5: RD = f3(RU, [RS+RT*OS+IM2], IM4).
706
            rs_status = `REG_POINTER;
707
            if (instruction_in[`RT] != 5'H1F) rt_status = `REG_INDEX;
708
            scale_factor = `SCALE_OS;
709
            offset_field = `OFFSET_2;
710
            immediate_field = `IMMED_3;
711
            if (num_operands > 2) ru_status = `REG_OPERAND;
712
            if ((mask_used | mask_alternative) && num_operands < 3) begin
713
                fallback_use = `FALLBACK_RU; ru_status = `REG_OPERAND;
714
            end
715
        end else if (mode2 == 7) begin
716
            // format 3.0.7: RD = f3(RS, RT, IM4 << IM2).
717
            immediate_field = `IMMED_3;
718
            if (num_operands > 1) rt_status = `REG_OPERAND;
719
            if (num_operands > 2 || mask_used) rs_status = `REG_OPERAND;
720
            if ((mask_used | mask_alternative) && num_operands < 3) begin
721
                fallback_use = `FALLBACK_RS; rs_status = `REG_OPERAND;
722
            end
723
        end else begin
724
            format_error = 1;                              // other formats unused
725
        end
726
 
727
    end else if (il == 3 && mode == 1) begin
728
        // format 3.1: jump or mixed
729
        if (op1 < 8) begin
730
            // jump instructions. Detect number of operands
731
            if (op1 == 1 && instruction_in[5:1] == `IJ_JUMP_DIRECT >> 1) num_operands = 0; // direct jump
732
        end
733
 
734
        if (op1 == 0) begin
735
            // format 3.1.0A jump with two registers, memory operand with 32 bit address, 24 bit jump offset
736
            rs_status = `REG_POINTER;
737
            rt_status = register_type;
738
            offset_field = `OFFSET_3;
739
        end else if (op1 == 1) begin
740
            // format 3.1.1B: jump with 2 registers, 32-bit immediate operand and a 32-bit jump offset
741
            rs_status = register_type;
742
            immediate_field = `IMMED_3;
743
 
744
        end else begin
745
            // single format instructions in format 3.1
746
            immediate_field = `IMMED_3;
747
            if (num_operands > 0) rt_status = register_type;
748
            if (num_operands > 1 || mask_used) rs_status = register_type;
749
            if (num_operands > 2) rd_status = register_type;
750
            // mixed formats. fallback use unknown
751
        end
752
 
753
    end else if (il == 3 && mode == 2) begin
754
        // format 3.2.x E
755
        if (mode2 == 0) begin
756
            // format 3.2.0: RD = f3(RD, RU, [RS+IM4]).. broadcast
757
            rs_status = `REG_POINTER;
758
            if (instruction_in[`RT] != 5'H1F) rt_status = `REG_LENGTH;
759
            offset_field = `OFFSET_3;
760
            broadcast = 1;
761
            if (num_operands > 1 || mask_used) ru_status = `REG_VECTOR;
762
            if (num_operands > 2) rd_status = `REG_VECTOR;
763
            if (mask_used && num_operands == 1) begin
764
                fallback_use = `FALLBACK_RU;
765
            end
766
        end else if (mode2 == 1) begin
767
            // format 3.2.1: RD = f3(RD, RU, [RS+IM4]). Length RT
768
            rs_status = `REG_POINTER;
769
            if (instruction_in[`RT] != 5'H1F) rt_status = `REG_LENGTH;
770
            offset_field = `OFFSET_3;
771
            if (num_operands > 1 || mask_used) ru_status = `REG_VECTOR;
772
            if (num_operands > 2) rd_status = `REG_VECTOR;
773
            if (mask_used && num_operands == 1) begin
774
                fallback_use = `FALLBACK_RU;
775
            end
776
        end else if (mode2 == 2) begin
777
            // format 3.2.2: RD = f3(RD, RU, [RS+RT*OS+IM4]).. scalar
778
            rs_status = `REG_POINTER;
779
            if (instruction_in[`RT] != 5'H1F) rt_status = `REG_INDEX;
780
            offset_field = `OFFSET_3;
781
            scale_factor = `SCALE_OS;
782
            if (num_operands > 1 || mask_used) ru_status = `REG_VECTOR;
783
            if (num_operands > 2) rd_status = `REG_VECTOR;
784
            if (mask_used && num_operands == 1) begin
785
                fallback_use = `FALLBACK_RU;
786
            end
787
        end else if (mode2 == 3) begin
788
            // format 3.2.3: RD = f3(RD, RU, [RS+RT*OS]).. limit IM4
789
            rs_status = `REG_POINTER;
790
            if (instruction_in[`RT] != 5'H1F) rt_status = `REG_INDEX;
791
            scale_factor = `SCALE_OS;
792
            index_limit = 1;
793
            if (num_operands > 1 || mask_used) ru_status = `REG_VECTOR;
794
            if (num_operands > 2) rd_status = `REG_VECTOR;
795
            if (mask_used && num_operands == 1) begin
796
                fallback_use = `FALLBACK_RU;
797
            end
798
        end else if (mode2 == 5) begin
799
            // format 3.2.5: RD = f3(RU, [RS+IM2], IM4). Length=RT.
800
            rs_status = `REG_POINTER;
801
            if (instruction_in[`RT] != 5'H1F) rt_status = `REG_LENGTH;
802
            offset_field = `OFFSET_2;
803
            immediate_field = `IMMED_3;
804
            if (num_operands > 2 || mask_used) ru_status = `REG_VECTOR;
805
            if ((mask_used | mask_alternative) && num_operands < 3) begin
806
                fallback_use = `FALLBACK_RU;  ru_status = `REG_VECTOR;
807
            end
808
        end else if (mode2 == 7) begin
809
            // format 3.2.7: RD = f3(RS, RT, IM4).
810
            immediate_field = `IMMED_3;
811
            if (num_operands > 1) rt_status = `REG_VECTOR;
812
            if (num_operands > 2 || mask_used) rs_status = `REG_VECTOR;
813
            if ((mask_used | mask_alternative) && num_operands < 3) begin
814
                fallback_use = `FALLBACK_RS;  rs_status = `REG_VECTOR;
815
            end
816
        end else begin
817
            // other formats unused
818
            format_error = 1;
819
        end
820
 
821
    end else if (il == 3 && mode == 3) begin
822
        // format 3.3A: RD = f3(RS, RT, IM2-3).
823
        immediate_field = `IMMED_3;
824
        if (num_operands > 1) rt_status = `REG_VECTOR;
825
        if (num_operands > 2 || mask_used) rs_status = `REG_VECTOR;
826
        if (mask_used && num_operands < 3) fallback_use = `FALLBACK_RS;
827
    end else if (il == 3 && mode == 0 && M) begin
828
        // format 3.8A: RD = f3(RS, RT, IM2-3).
829
        immediate_field = `IMMED_3;
830
        if (num_operands > 1) rt_status = `REG_OPERAND;
831
        if (num_operands > 2 || mask_used) rs_status = `REG_OPERAND;
832
        if (mask_used && num_operands < 3) fallback_use = `FALLBACK_RS;
833
    end
834
 
835
 
836
    // detect type of result
837
    result_type = `RESULT_REG;                             // default result type
838
    if (category == `CAT_MULTI && op1 == `II_STORE) begin
839
        result_type = `RESULT_MEM;                         // store instruction
840
        rd_status = `REG_OPERAND;                          // source is rd
841
    end else if (il == 2 && mode == 5 &&
842
        (op1 == `II_STOREI || op1 == `II_FENCE || op1 == `II_CMPSWAP || op1 == `II_XTR_STORE)) begin
843
        result_type = `RESULT_MEM;                         // various complex memory instructions
844
    end else if (il == 1 && mode == 0 && M &&              // format 1.8
845
        (op1 == `II_WR_SPEC || op1 == `II_WR_CAPA)) begin
846
        result_type = `RESULT_SYS;                         // write system registers
847
    end else if (il == 1 && mode == 0 && M && op1 == `II_OUTPUT_18) begin
848
        result_type = `RESULT_NONE;                        // output, format 1.8
849
    end else if (category == `CAT_MULTI && op1 == `II_NOP) begin
850
        result_type = `RESULT_NONE;                        // nop
851
    end else if (il == 1 && mode == 2 && op1 == `II_OUTPUT_18) begin
852
        result_type = `RESULT_NONE;                        // output, format 1.2
853
    end else if (il == 1 && mode == 3 && op1 == `II_CLEAR) begin
854
        result_type = `RESULT_NONE;                        // the clear instruction goes directly to the vector register file, not through the ALU
855
    end else if (category == `CAT_JUMP && il == 1) begin
856
        if ((op1 <= `II_UNCOND_JUMP && mode == 7) || (op1 >= `II_COMPARE_FIRST && op1 <= `II_COMPARE_LAST) || op1 >= `II_INDIRECT_JUMP) result_type = `RESULT_NONE;
857
    end else if (category == `CAT_JUMP && il > 1 && op1 == 0) begin // jump formats 2.5.0A and 3.1.0A have opj in byte 7
858
        if ((instruction_in[61:56] >= `II_COMPARE_FIRST && instruction_in[61:56] <= `II_COMPARE_LAST) || instruction_in[61:56] >= `II_INDIRECT_JUMP) result_type = `RESULT_NONE;
859
    end else if (category == `CAT_JUMP && il > 1) begin    // other jump formats have opj in byte 0
860
        if ((instruction_in[5:0] >= `II_COMPARE_FIRST && instruction_in[5:0] <= `II_COMPARE_LAST) || instruction_in[5:0] >= `II_INDIRECT_JUMP) result_type = `RESULT_NONE;
861
    end
862
end
863
 
864
 
865
// update tags
866
always_comb begin
867
    next_tag = 0;
868
    tag_write = 0;
869
    if (tag_used[current_tag]) begin                       // tag in use should have been predicted
870
        tag_error = 1;
871
    end else begin
872
        tag_error = 0;
873
    end
874
 
875
    // instructions without a result register need a tag in addressgenerator to distinguish instructions
876
    if (valid & !stall_in) begin
877
        // needs a new tag
878
        tag_write = 1;
879
        if (¤t_tag) next_tag = 1;                    // skip value 0
880
        else next_tag = current_tag + 1;
881
    end else begin
882
        next_tag = current_tag;
883
    end
884
end
885
 
886
 
887
// send tag to register file
888
always_ff @(posedge clock) if (clock_enable) begin
889
    if (tag_write && !stall_in) begin
890
        tag_write_out <= result_type == `RESULT_REG || result_type == `RESULT_SYS;
891
        tag_a_out <= {result_type[0], instruction_in[`RD]};
892
        tag_val_out <= current_tag;
893
        current_tag <= next_tag;
894
        if (tag_used[next_tag]) begin
895
            stall_out <= 1;                                // other reasons for stall out?
896
        end else begin
897
            stall_out <= 0;
898
        end
899
    end else begin
900
        tag_write_out <= 0;
901
        stall_out <= 0;
902
    end
903
 
904
    if (reset) current_tag <= 1;
905
end
906
 
907
 
908
// other outputs
909
always_ff @(posedge clock) if (clock_enable) begin
910
    if (reset) valid_out <= 0;
911
    else if (!stall_in) valid_out <= valid_in;
912
 
913
    if (!stall_in) begin
914
        instruction_pointer_out <= instruction_pointer_in;
915
        instruction_out <= instruction_in;
916
        vector_out <= register_type == `REG_VECTOR;
917
        category_out <= category;
918
        format_out <= format;
919
        rs_status_out <= rs_status;
920
        rt_status_out <= rt_status;
921
        ru_status_out <= ru_status;
922
        rd_status_out <= rd_status;
923
        mask_status_out <= (mask_used || mask_options) ? register_type : `REG_UNUSED;
924
        mask_options_out <= mask_options;
925
        mask_alternative_out <= mask_alternative;
926
        fallback_use_out <= fallback_use;
927
        num_operands_out <= num_operands;
928
        result_type_out <= result_type;
929
        offset_field_out <= offset_field;
930
        immediate_field_out <= immediate_field;
931
        scale_factor_out <= scale_factor;
932
        index_limit_out <= index_limit;
933
 
934
        // debug output
935
        debug1_out[1:0]   <= il;
936
        debug1_out[6:4]   <= mode;
937
        debug1_out[8]     <= M;
938
        debug1_out[14:12] <= mode2;
939
        debug1_out[17:16] <= offset_field;
940
        debug1_out[21:20] <= immediate_field;
941
 
942
    end
943
end
944
 
945
 
946
// update list of tags in use
947
genvar i;   // generation loop for all bits in tag_used
948
for (i=0; i < (2**`TAG_WIDTH); i++) begin
949
    always_ff @(posedge clock) if (clock_enable && !stall_in) begin
950
        if (reset) begin
951
            tag_used[i] <= 0;
952
        end else if (i == current_tag) begin
953
            tag_used[i] <= 1;
954
        end else if ((write_en1 && i == write_tag1) || (write_en2 && i == write_tag2)) begin
955
            tag_used[i] <= 0;
956
        end
957
    end
958
end
959
 
960
endmodule

powered by: WebSVN 2.1.0

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