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

Subversion Repositories forwardcom

[/] [forwardcom/] [trunk/] [dataread.sv] - Blame information for rev 19

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 19 Agner
//////////////////////////////////////////////////////////////////////////////////
2
// Engineer: Agner Fog
3
//
4
// Create Date:    2020-06-06
5
// Last modified:  2021-07-18
6
// Module Name:    data read
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: Waiting stage after the address generator.
12
// This pipeline stage comes after the address generator.
13
// It waits for a clock cycle while data retrieved from the data cache.
14
// Checks if a memory address is valid.
15
// Converts single format instructions to multiformat instruction code where possible
16
// Dispatches the instruction to the right execution unit.
17
//
18
//////////////////////////////////////////////////////////////////////////////////
19
`include "defines.vh"
20
 
21
 
22
module dataread (
23
    input clock,                            // system clock (100 MHz)
24
    input clock_enable,                     // clock enable. Used when single-stepping
25
    input reset,                            // system reset
26
    input valid_in,                         // data from fetch module ready
27
    input stall_in,                         // a later stage in pipeline is stalled
28
    input [`CODE_ADDR_WIDTH-1:0] instruction_pointer_in, // address of current instruction
29
    input [63:0] instruction_in,            // current instruction, up to 3 words long
30
    input [`TAG_WIDTH-1:0] tag_val_in,      // instruction tag value
31
    input        vector_in,                 // this is a vector instruction
32
    input [1:0]  category_in,               // 00: multiformat, 01: single format, 10: jump
33
    input [1:0]  format_in,                 // 00: format A, 01: format E, 10: format B, 11: format C (format D never goes through decoder)
34
    //input        rs_status_in,              // 1: RS is register operand
35
    //input        rt_status_in,              // 1: RT is register operand
36
    //input        ru_status_in,              // 1: RU is used
37
    //input        rd_status_in,              // 1: RD is used as input
38
    input        mask_status_in,            // 1: mask register used
39
    input        mask_alternative_in,       // mask register and fallback register used for alternative purposes
40
    input [1:0]  num_operands_in,           // number of source operands
41
    input [1:0]  result_type_in,            // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
42
    input [1:0]  immediate_field_in,        // immediate data field. 0: none, 1: 8 bit, 2: 16 bit, 3: 32 or 64 bit
43
    input        memory_operand_in,         // The instruction has a memory operand
44
    input        array_error_in,            // Array index exceeds limit
45
    input        options3_in,               // IM3 containts option bits
46
 
47
    // monitor result buses:
48
    input write_en1,                        // a result is written to writeport1
49
    input [`TAG_WIDTH-1:0] write_tag1_in,   // tag of result inwriteport1
50
    input [`RB1:0] writeport1_in,           // result bus 1
51
    input write_en2,                        // a result is written to writeport2
52
    input [`TAG_WIDTH-1:0] write_tag2_in,   // tag of result inwriteport2
53
    input [`RB1:0] writeport2_in,           // result bus 2
54
    input [`TAG_WIDTH-1:0] predict_tag1_in, // result tag value on writeport1 in next clock cycle
55
    input [`TAG_WIDTH-1:0] predict_tag2_in, // result tag value on writeport2 in next clock cycle
56
 
57
    // Register values sampled from result bus in previous stages
58
    input [`RB:0]  operand1_in,             // value of first operand
59
    input [`RB:0]  operand2_in,             // value of second operand
60
    input [`RB:0]  operand3_in,             // value of last operand
61
    input [`MASKSZ:0] regmask_val_in,          // value of mask register
62
    input [`RB1:0] address_in,              // address of memory operand
63
    input [`RB1:0] ram_data_in,             // memory operand from data cache
64
 
65
    output reg        valid_out,            // An instruction is ready for output to next stage
66
    output reg [`CODE_ADDR_WIDTH-1:0] instruction_pointer_out, // address of current instruction
67
    output reg [31:0] instruction_out,      // first word of instruction
68
    output reg        stall_predict_out,    // predict next stage will stall
69
    output reg [`TAG_WIDTH-1:0] tag_val_out,// instruction tag value
70
    output reg [`RB:0] operand1_out,        // value of first operand for 3-op instructions, bit `RB is 0 if valid
71
    output reg [`RB:0] operand2_out,        // value of second operand, bit `RB is 0 if valid
72
    output reg [`RB:0] operand3_out,        // value of last operand, bit `RB is 0 if valid
73
    output reg [`MASKSZ:0] mask_val_out,    // value of mask, bit 32 is 0 if valid
74
    output reg         opr2_from_ram_out,   // value of operand 2 comes from data cache
75
    output reg         opr3_from_ram_out,   // value of last operand comes from data cache
76
    output reg         vector_out,          // this is a vector instruction
77
    output reg [1:0]   category_out,        // 00: multiformat, 01: single format, 10: jump
78
    output reg [1:0]   format_out,          // 00: format A, 01: format E, 10: format B, 11: format C (format D never goes through decoder)
79
    output reg [1:0]   num_operands_out,    // number of source operands
80
    output reg [1:0]   result_type_out,     // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
81
    output reg         opr1_used_out,       // opr1_val_out is needed
82
    output reg         opr2_used_out,       // opr2_val_out is needed
83
    output reg         opr3_used_out,       // opr3_val_out is needed
84
    output reg         regmask_used_out,    // regmask_val_out is needed
85
    output reg         mask_alternative_out,// mask register and fallback register used for alternative purposes
86
    output reg [3:0]   exe_unit_out,        // each bit enables a particular execution unit:
87
                                            // 1: ALU, 10: MUL, 100: DIV, 1000: IN/OUT
88
    output reg [6:0]   opx_out,             // operation ID in execution unit. This is mostly equal to op1 for multiformat instructions
89
    output reg [5:0]   opj_out,             // operation ID for conditional jump instructions
90
    output reg [2:0]   ot_out,              // operand type
91
    output reg [5:0]   option_bits_out,     // option bits from IM3 or mask
92
    output reg [15:0]  im2_bits_out,        // constant bits from IM2 as extra operand
93
    output reg         trap_out,            // trap instruction detected
94
    output reg         array_error_out,     // array index out of bounds
95
    output reg         read_address_error_out,       // invalid read memory address
96
    output reg         write_address_error_out,      // invalid write memory address
97
    output reg         misaligned_address_error_out, // misaligned read/write memory address
98
    output reg [31:0]  debug_out            // output for debugging
99
);
100
 
101
// instruction components
102
logic [1:0]  il;                            // instruction length
103
logic [2:0]  mode;                          // instruction mode
104
logic [2:0]  mode2;                         // mode2 in format E
105
logic        M;                             // M bit
106
logic [2:0]  otype;                         // operand type in instruction
107
logic [5:0]  op1;                           // OP1 in instruction
108
logic [1:0]  op2;                           // OP2 in instruction
109
logic        is_addr_instr;                 // this is an address instruction
110
logic [5:0]  option_bits;                   // option bits
111
logic [15:0] im2_bits;                      // constant bits from IM2 as extra operand
112
logic [1:0]  last_operand;                  // 0: last operand is a register,
113
                                            // 1: last operand i an immediate constant
114
                                            // 2: last operand is memory
115
                                            // 3: both memory and immediate operands
116
logic        half_precision;                // half precision float
117
logic        swap_operands;                 // swap last two operands
118
logic [3:0]  exe_unit;
119
 
120
// operand values. Extra bit is 1 if not found
121
logic [`RB:0] opr1_val;                     // first operand if 3 operands
122
logic [`RB:0] opr2_val;                     // first operand if 2 operands, second operand if 3 operands
123
logic [`RB:0] opr3_val;                     // last operand
124
logic [`MASKSZ:0] regmask_val;              // value of mask register, bit 32 indicates missing
125
logic        opr2_from_ram;                 // value of operand 2 comes from data ram
126
logic        opr3_from_ram;                 // value of last operand comes from data ram
127
logic        opr1_used;                     // operand 1 is used
128
logic        opr2_used;                     // operand 2 is used
129
logic        opr3_used;                     // operand 3 is used
130
logic        mask_off;                      // mask is zero
131
logic        stall_predict;                 // predict that alu will stall in next clock cycle
132
logic        read_address_error;            // invalid read memory address
133
logic        write_address_error;           // invalid write memory address
134
logic        misaligned_address_error;      // misaligned read/write memory address
135
logic [31:0] jump_offset;                   // relative jump offset
136
 
137
// converted operation id
138
logic [6:0]  opx;                           // operation ID in execution unit. This is mostly equal to op1 for multiformat instructions
139
logic [5:0]  opj;                           // operation ID for conditional jump instructions
140
 
141
// temporary storage of register values if found during stall. High bit is zero if valid
142
reg [`RB:0] opr1_val_temp;                  // value of first  operand, bit `RB indicates missing
143
reg [`RB:0] opr2_val_temp;                  // value of second  operand, bit `RB indicates missing
144
reg [`RB:0] opr3_val_temp;                  // value of last operand, bit `RB indicates missing
145
reg [`MASKSZ:0] regmask_val_temp;           // value of mask register, bit 32 indicates missing
146
reg         last_stall;                     // was stalled in last clock cycle. May obtain register values from the temporary registers
147
reg         last_valid;                     // input was valid in last clock cycle. May obtain memory input
148
 
149
always_comb begin
150
    il   = instruction_in[`IL];             // instruction length
151
    mode = instruction_in[`MODE];           // format mode
152
    mode2 = instruction_in[`MODE2];         // format mode2
153
    M    = instruction_in[`M];              // M bit
154
    op1  = instruction_in[`OP1];            // op1 operation
155
    op2  = instruction_in[`OP2];            // op2 operation
156
    option_bits = 0;                        // option bits from IM3 etc.
157
    opr1_used = 0;                          // operand 1 used
158
    opr2_used = 0;                          // operand 2 used
159
    opr3_used = 0;                          // operand 3 used
160
    half_precision = 0;                     // float16. not implemented yet
161
    swap_operands = 0;                      // swap operands 2 and 3
162
    mask_off = 0;                           // mask known to be zero
163
    stall_predict = 0;                      // predict stall in next clock
164
    read_address_error = 0;                 // read address out of range
165
    write_address_error = 0;                // write address out of range
166
    misaligned_address_error = 0;           // read or write to misaligned address
167
    opr2_from_ram = 0;                      // value of operand 2 comes from data memory
168
    opr3_from_ram = 0;                      // value of last operand comes from data memory
169
    im2_bits = instruction_in[`IM2E];       // IM2 may be used as extra immediate operand
170
    // look for address instruction in format 2.9A:
171
    is_addr_instr = (il == 2 && mode == 1 && M && op1 == `II_ADDRESS_29);
172
 
173
    // Detect operand type
174
    if (format_in == `FORMAT_C) begin
175
        otype = 2;                          // default operand type in format C is int32.
176
        // Exceptions to format C operand type:
177
        if (mode == 1) begin                // format 1.1C.
178
            if (op1[0]) otype = 3;          // optype is int64 when op1 is odd
179
        end
180
        if (mode == 4) begin                // format 1.4C.
181
            if (op1 < 8) begin
182
                otype = 1;                  // optype is int16 when op1 < 8
183
            end else if (op1 < 32) begin
184
                otype = 2 | op1[0];         // optype is int32 for even op1, int64 for odd op1
185
            end else if (op1 < `II_ADD_H14) begin
186
                otype = 5 + op1[0];         // optype is float32 for even op1, float64 for odd op1
187
            end else begin
188
                otype = 1;                  // 16 bits or float16
189
                half_precision = 1;         // half precision single format instructions
190
            end
191
        end
192
        if (mode == 7) begin                // format 1.7C
193
             if ((op1 & -2) == `IJ_SUB_MAXLEN_JPOS) otype = 3; // sub_maxlen/jump instruction has int64
194
        end
195
    end else if (vector_in) begin
196
        otype = instruction_in[`OT];
197
    end else begin
198
        otype = instruction_in[`OT] & 3'b011;
199
    end
200
 
201
    /*
202
    // detect if half precision
203
    if (category_in == `CAT_MULTI && op1 >= `II_ADD_FLOAT16 && op1 <= `II_MUL_ADD_FLOAT16)
204
        half_precision = 1;  // half precision multiformat instructions
205
    if (category_in == `CAT_SINGLE && il == 1 && mode == 4 && op1 >= `II_ADD_H14 && op1 <= `II_MUL_H14)
206
        half_precision = 1;  // half precision single format instructions
207
    */
208
    // detect if last two operands should be swapped
209
    if (category_in == `CAT_MULTI && (op1 == `II_SUB_REV || op1 == `II_DIV_REV || op1 == `II_MUL_ADD2))
210
        swap_operands = 1;
211
 
212
    // look for register values in result buses
213
    if      (last_stall && opr1_val_temp[`RB] == 0) opr1_val = opr1_val_temp;                                                      // obtained during stall
214
    else if (operand1_in[`RB] == 1 && write_en1 && operand1_in[`TAG_WIDTH-1:0] == write_tag1_in) opr1_val = {1'b0, writeport1_in}; // obtained from result bus 1
215
    else if (operand1_in[`RB] == 1 && write_en2 && operand1_in[`TAG_WIDTH-1:0] == write_tag2_in) opr1_val = {1'b0, writeport2_in}; // obtained from result bus 2
216
    else opr1_val = operand1_in;
217
 
218
    if      (last_stall && opr2_val_temp[`RB] == 0) opr2_val = opr2_val_temp;                                                      // obtained during stall
219
    else if (operand2_in[`RB] == 1 && write_en1 && operand2_in[`TAG_WIDTH-1:0] == write_tag1_in) opr2_val = {1'b0, writeport1_in}; // obtained from result bus 1
220
    else if (operand2_in[`RB] == 1 && write_en2 && operand2_in[`TAG_WIDTH-1:0] == write_tag2_in) opr2_val = {1'b0, writeport2_in}; // obtained from result bus 2
221
    else opr2_val = operand2_in;
222
 
223
    if      (operand3_in[`RB] == 1 && write_en1 && operand3_in[`TAG_WIDTH-1:0] == write_tag1_in) opr3_val = {1'b0, writeport1_in}; // obtained from result bus 1
224
    else if (operand3_in[`RB] == 1 && write_en2 && operand3_in[`TAG_WIDTH-1:0] == write_tag2_in) opr3_val = {1'b0, writeport2_in}; // obtained from result bus 2
225
    else if (last_stall && opr3_val_temp[`RB] == 0) opr3_val = opr3_val_temp;                                                      // obtained during stall
226
    else opr3_val = operand3_in;
227
 
228
    if      (last_stall && regmask_val_temp[`MASKSZ] == 0) regmask_val = regmask_val_temp;                                                      // obtained during stall
229
    if      (regmask_val_in[`MASKSZ] == 1 && write_en1 && regmask_val_in[`TAG_WIDTH-1:0] == write_tag1_in) regmask_val = {1'b0, writeport1_in[`MASKSZ-1:0]}; // obtained from result bus 1
230
    else if (regmask_val_in[`MASKSZ] == 1 && write_en2 && regmask_val_in[`TAG_WIDTH-1:0] == write_tag2_in) regmask_val = {1'b0, writeport2_in[`MASKSZ-1:0]}; // obtained from result bus 2
231
    else regmask_val = regmask_val_in;
232
 
233
    // look for memory operand
234
    if (memory_operand_in) begin
235
        if (last_stall && last_valid) begin
236
            // value from data memory is available early because of stall
237
            if (immediate_field_in != `IMMED_NONE) begin
238
                opr2_val = ram_data_in;
239
            end else begin
240
                opr3_val = ram_data_in;
241
            end
242
        end else begin
243
            if (immediate_field_in != `IMMED_NONE) begin
244
                opr2_from_ram = 1;
245
            end else begin
246
                opr3_from_ram = 1;
247
            end
248
        end
249
    end
250
 
251
    // check if memory operand is valid
252
    // (this check is not placed in the address generator stage because of timing constraints)
253
    if (valid_in && memory_operand_in && !is_addr_instr) begin
254
 
255
        // invalid read memory address:
256
        read_address_error = result_type_in != `RESULT_MEM &&
257
            address_in >= 2**`DATA_ADDR_WIDTH; // can read from data only
258
 
259
        // Invalid write memory address:
260
        // To do: fix this when write access to code memory is removed.
261
        // Note: The calculation of write_address_error is not done in the address generator
262
        // stage because of critical timing. It is too late to disable illegal writes in this
263
        // stage. We must find a solution to this in future versions with memory protection.
264
        // For now, we will be satisfied with program halt.
265
        write_address_error = result_type_in == `RESULT_MEM &&
266
            address_in >= 2**`COMMON_ADDR_WIDTH; // can write to data or code
267
 
268
        // misaligned read/write memory address:
269
        case (otype)
270
        0:  // int8
271
            misaligned_address_error = 0;
272
        1:  // int16
273
            misaligned_address_error = address_in[0];
274
        2, 5:  // int32, float32
275
            misaligned_address_error = address_in[1:0] != 0;
276
        3, 6:  // int64, float64
277
            misaligned_address_error = address_in[2:0] != 0;
278
        4, 7:  // int128, float128
279
            misaligned_address_error = address_in[3:0] != 0;
280
        endcase
281
    end
282
 
283
    // find jump offset
284
    jump_offset = 0;
285
 
286
    if (category_in == `CAT_JUMP) begin
287
        if (il == 1 && mode == 6) begin
288
            // 1.6 B: Short jump with two register operands and 8 bit offset (IM1).
289
            jump_offset = {{24{instruction_in[`IM1S]}},instruction_in[`IM1]}; // sign extend
290
 
291
        end else if (il == 1 && mode == 7) begin
292
            // 1.7 C: Short jump with one register operand, an 8-bit immediate constant (IM2) and 8 bit offset (IM1),
293
            jump_offset = {{24{instruction_in[`IM1S]}},instruction_in[`IM1]}; // sign extend
294
 
295
        end else if (il == 2 && mode == 5) begin
296
            if (op1 == 0) begin
297
                // 2.5.0A: Double size jump with three register operands and 24 bit jump offset
298
                jump_offset = {{8{instruction_in[55]}},instruction_in[55:32]}; // sign extend 24 bit offset
299
 
300
            end else if (op1 == 1) begin
301
                // format 2.5.1B: jump with one register, one 16 bit operand, and 16 bit offset
302
                jump_offset = {{16{instruction_in[63]}},instruction_in[63:48]}; // sign extend 16 bit offset
303
 
304
            end else if (op1 == 2) begin
305
                // format 2.5.2B: jump with one register, a memory operand with 16 bit address, and 16 bit offset
306
                jump_offset = {{16{instruction_in[63]}},instruction_in[63:48]}; // sign extend 16 bit offset
307
 
308
            end else if (op1 == 4) begin
309
                // format 2.5.4C: jump with one register, one 8 bit operand, and 32 bit offset
310
                jump_offset = instruction_in[63:32]; // 32 bit offset
311
 
312
            end else if (op1 == 5) begin
313
                // format 2.5.5C: jump with one register, one 32 bit operand, and 8 bit offset
314
                jump_offset = {{24{instruction_in[15]}},instruction_in[15:8]}; // sign extend 8 bit offset
315
 
316
            end
317
 
318
        end else if (il == 3 && mode == 1) begin
319
            if (op1 == 0) begin
320
                // 3.1.0A: Triple size jump with two register operands and 24 bit jump offset and 32 bit address
321
                jump_offset = {{8{instruction_in[55]}},instruction_in[55:32]}; // sign extend 24 bit offset
322
            end else if (op1 == 1) begin
323
                // 3.1.1B: Jump with two registers, a 32 bit operand, and 32 bit jump offset
324
                jump_offset = instruction_in[63:32]; // 32 bit jump offset
325
            end
326
        end
327
    end
328
 
329
    // get condition code for jump instructions
330
    opj = 0;
331
    if (category_in == `CAT_JUMP) begin
332
        if (il == 1) begin
333
            if (mode == 7 && op1 <= `II_UNCOND_JUMP) opj = 0;   // unconditional jump or call handled by fetch unit
334
            else if (op1 == `II_RETURN) opj = 0;                // return handled by fetch unit
335
            else opj = op1;
336
        end else if (il == 2 && mode == 5 && op1 == 0) begin
337
            opj = instruction_in[61:56];                        // format 2.5.0A: opj in upper part of IM2
338
        end else if (il == 2 && mode == 5 && op1 == 7) begin    // system call
339
            opj = `IJ_SYSCALL;
340
        end else if (il == 3 && mode == 1 && op1 == 0) begin
341
            opj = instruction_in[61:56];                        // format 3.1.0A: opj in upper part of IM2
342
        end else if (op1 < 8) begin                             // other jump formats have opj in IM1
343
            opj = instruction_in[5:0];
344
        end else begin
345
            opj = 56;                                           // unknown
346
        end
347
    end
348
 
349
    // get option bits
350
    if (options3_in && format_in == `FORMAT_E) begin
351
        option_bits = instruction_in[`IM3E];                    // option bits in IM3
352
    end else if (category_in == `CAT_JUMP) begin
353
        // imitate compare instruction option bits for compare/jump
354
        case (opj[5:1])
355
        // ignore bit 0 of opj here: it is inserted in the alu stage
356
        `IJ_COMPARE_JEQ>>1: option_bits = 4'b0000;
357
        `IJ_COMPARE_JSB>>1: option_bits = 4'b0010;
358
        `IJ_COMPARE_JSA>>1: option_bits = 4'b0100;
359
        `IJ_COMPARE_JUB>>1: option_bits = 4'b1010;
360
        `IJ_COMPARE_JUA>>1: option_bits = 4'b1100;
361
        endcase
362
    end else if (category_in == `CAT_MULTI && op1 >= `II_MIN && op1 <= `II_MAX_U) begin
363
        // use compare unit to implement max and min
364
        case (op1[1:0])
365
        0: option_bits = 4'b0010;      // min, signed
366
        1: option_bits = 4'b1010;      // min, unsigned
367
        2: option_bits = 4'b0100;      // max, signed
368
        3: option_bits = 4'b1100;      // max, unsigned
369
        endcase
370
    end
371
 
372
    // convert op1 to opx: operation id in execution unit
373
    opx = `IX_UNDEF;                             // default is undefined
374
    if (category_in == `CAT_MULTI) begin
375
        opx = op1;                               // mostly same id for multiformat instructions
376
        if (op1 == `II_SUB_REV) opx = `II_SUB;   // operands have been swapped
377
        if (op1 == `II_DIV_REV) opx = `II_DIV;   // operands have been swapped
378
 
379
    end else if (category_in == `CAT_JUMP) begin
380
        // convert jump instructions to corresponding general ALU instructions
381
        if      (opj <= `IJ_SUB_JBORROW + 1)    opx = `II_SUB;
382
        else if (opj <= `IJ_AND_JZ + 1)         opx = `II_AND;
383
        else if (opj <= `IJ_OR_JZ + 1)          opx = `II_OR;
384
        else if (opj <= `IJ_XOR_JZ + 1)         opx = `II_XOR;
385
        else if (opj <= `IJ_ADD_JCARRY + 1)     opx = `II_ADD;
386
        else if (opj <= `IJ_AND_JZ + 1)         opx = `II_AND;
387
        else if (opj <= `IJ_TEST_BIT_JTRUE + 1) opx = `II_TEST_BIT;
388
        else if (opj <= `IJ_TEST_BITS_AND + 1)  opx = `II_TEST_BITS_AND;
389
        else if (opj <= `IJ_TEST_BITS_OR + 1)   opx = `II_TEST_BITS_OR;
390
        else if (opj <= `IJ_COMPARE_JUA + 1)    opx = `II_COMPARE;
391
        else if ((opj & ~1) == `II_INDIRECT_JUMP) begin // 58
392
            if ((il == 1 && mode == 6) || (il == 2 && mode == 5 && op1[2:0] == 2))
393
                 opx = `IX_INDIRECT_JUMP;  // indirect jump w memory operand, format 1.6 and 2.5.2
394
            else opx = `IX_UNCOND_JUMP;    // unconditional jump format 2.5.4 and 3.1.1
395
        end else if ((opj & ~1) == `II_JUMP_RELATIVE) begin // 60
396
            if (il == 1 && mode == 7) opx = `IX_INDIRECT_JUMP;
397
            else opx = `IX_RELATIVE_JUMP;
398
        end
399
        else opx = 0;
400
 
401
    end else if (il == 1 && mode == 1) begin
402
        // format 1.1 C. single format instructions with 16 bit constant
403
        case (op1[5:1])  // even and odd op1 values treated together, they differ only by operand type
404
        `II_ADD11 >> 1:         opx = `II_ADD;
405
        `II_MUL11 >> 1:         opx = `II_MUL;
406
        `II_ADDSHIFT16_11 >> 1: opx = `II_ADD;
407
        `II_SHIFT_ADD_11 >> 1:  opx = `II_ADD;
408
        `II_SHIFT_AND_11 >> 1:  opx = `II_AND;
409
        `II_SHIFT_OR_11 >> 1:   opx = `II_OR;
410
        `II_SHIFT_XOR_11 >> 1:  opx = `II_XOR;
411
        default:                opx = `IX_UNDEF;
412
        endcase
413
        if (op1 <= `II_MOVE11_LAST) opx = `II_MOVE; // five different move instructions
414
 
415
    end else if (il == 1 && mode == 0 && M) begin
416
        // format 1.8 B. single format instructions with 8 bit constant
417
        case (op1)
418
        `II_SHIFT_ABS18:   opx = `IX_ABS;
419
        `II_BITSCAN_18:    opx = `IX_BIT_SCAN;
420
        `II_ROUNDP2_18:    opx = `IX_ROUNDP2;
421
        `II_POPCOUNT_18:   opx = `IX_POPCOUNT;
422
        `II_READ_SPEC18:   opx = `IX_READ_SPEC;
423
        `II_WRITE_SPEC18:  opx = `IX_WRITE_SPEC;
424
        `II_READ_CAP18:    opx = `IX_READ_CAPABILITIES;
425
        `II_WRITE_CAP18:   opx = `IX_WRITE_CAPABILITIES;
426
        `II_READ_PERF18:   opx = `IX_READ_PERF;
427
        `II_READ_PERFS18:  opx = `IX_READ_PERFS;
428
        `II_READ_SYS18:    opx = `IX_READ_SYS;
429
        `II_WRITE_SYS18:   opx = `IX_WRITE_SYS;
430
        `II_INPUT_18:      opx = `IX_INPUT;
431
        `II_OUTPUT_18:     opx = `IX_OUTPUT;
432
        endcase
433
 
434
    end else if (il == 2 && (mode == 0 && !M || mode == 2) && mode2 == 6) begin // format 2.0.6 and 2.2.6
435
        if (op1 == `II_TRUTH_TAB3 && op2 == `II2_TRUTH_TAB3) opx = `IX_TRUTH_TAB3;
436
 
437
    end else if (il == 2 && (mode == 0 && !M || mode == 2) && mode2 == 7) begin
438
        // format 2.0.7 and 2.2.7 single format
439
        if (op1 == `II_MOVE_BITS && op2 == `II2_MOVE_BITS) begin // move_bits instruction.
440
            // Do calculations on constant operands here to save critical time in the alu stage
441
            logic [5:0] move_from;                 // bit position to move from
442
            logic [5:0] move_to;                   // bit position to move to
443
            logic [5:0] num_bits;                  // number of bits to move
444
            logic [6:0] end_to;                    // end of destination bit field
445
            move_from = instruction_in[37:32];     // low part of im2
446
            move_to   = instruction_in[45:40];     // high part of im2
447
            num_bits  = instruction_in[`IM3E];     // number of bits to move
448
            if (move_from > move_to) begin         // IX_MOVE_BITS2 if shifting right
449
                opx = `IX_MOVE_BITS2;
450
            end else begin
451
                opx = `IX_MOVE_BITS1;              // IX_MOVE_BITS1 if shifting left
452
            end
453
            end_to = {1'b0,move_to} + num_bits - 1;// end of destination bit field.
454
            if (end_to[6]) option_bits[5:0] = 6'b111111; // saturate on overflow
455
            else option_bits = end_to[5:0];
456
            // begin of destination bit field is in im2_bits[13:8]
457
            // end of destination bit field is in option_bits
458
            opr3_val[7:0] = move_from - move_to;   // shift right count, or -(shift left count)
459
        end
460
 
461
    end else if (il == 2 && mode == 5) begin
462
        // format 2.5 B. single format instructions with 32 bit constant
463
        if (op1 == `II_STOREI) opx = `II_STORE;
464
 
465
    end else if (il == 2 && mode == 1 && M) begin
466
        // format 2.9A. single format instructions with 32 bit constant
467
        case (op1)
468
        `II_MOVE_HI_29:    opx = `II_MOVE;  // shifted left by 32 here. just store result
469
        `II_INSERT_HI_29:  opx = `IX_INSERT_HI;
470
        `II_ADDU_29:       opx = `II_ADD;
471
        `II_SUBU_29:       opx = `II_SUB;
472
        `II_ADD_HI_29:     opx = `II_ADD;
473
        `II_AND_HI_29:     opx = `II_SUB;
474
        `II_OR_HI_29:      opx = `II_OR;
475
        `II_XOR_HI_29:     opx = `II_XOR;
476
        `II_ADDRESS_29:    opx = `II_MOVE; // address instruction. resolved in this state. just store result
477
        endcase
478
    end
479
 
480
    // select execution unit
481
    if (opx == `IX_INPUT || opx == `IX_OUTPUT || (opx >= `IX_READ_CAPABILITIES && opx <= `IX_WRITE_SYS+1)) begin
482
        exe_unit = 4'b1000;      // input/output unit. also handles system registers
483
    end else if (opx >= `II_DIV && opx <= `II_REM_U) begin
484
        exe_unit = 4'b0100;      // division unit
485
    end else if ((opx >= `II_MUL && opx <= `II_MUL_HI_U) || opx == `II_MUL_ADD || opx == `II_MUL_ADD2) begin
486
        exe_unit = 4'b0010;      // multiplication unit
487
    end else begin
488
        exe_unit = 4'b0001;      // general ALU unit
489
    end
490
 
491
    // find which operands are used
492
    mask_off = result_type_in != `RESULT_MEM && mask_status_in && regmask_val[`MASKSZ] == 0 && regmask_val[0] == 0 && !mask_alternative_in && !vector_in;
493
 
494
    if (mask_status_in) begin
495
        if (regmask_val[`MASKSZ] == 0) begin
496
            // a mask is used and the value is already available
497
            if (regmask_val[0]) begin
498
                // mask is 1. operands are needed. fallback not needed
499
                if (num_operands_in > 0) opr3_used = 1;
500
                if (num_operands_in > 1) opr2_used = 1;
501
                if (num_operands_in > 2) opr1_used = 1;
502
            end else begin
503
                // mask is 0. operands are not needed. fallback is needed
504
                opr1_used = 1;
505
            end
506
        end else begin
507
            // a mask is used. The value is not available yet. operands and fallback are needed
508
            if (num_operands_in > 0) opr3_used = 1;
509
            if (num_operands_in > 1) opr2_used = 1;
510
            opr1_used = 1;
511
        end
512
    end else begin
513
        // mask not used. fallback not needed
514
        if (num_operands_in > 0) opr3_used = 1;
515
        if (num_operands_in > 1) opr2_used = 1;
516
        if (num_operands_in > 2) opr1_used = 1;
517
    end
518
 
519
    if (mask_alternative_in) opr1_used = 1; // alternative use of fallback register
520
 
521
    // predict stall in ALU
522
    stall_predict =
523
        (opr1_used && opr1_val[`RB] && predict_tag1_in != opr1_val[`TAG_WIDTH-1:0] && predict_tag2_in != opr1_val[`TAG_WIDTH-1:0]) ||
524
        (opr2_used && opr2_val[`RB] && predict_tag1_in != opr2_val[`TAG_WIDTH-1:0] && predict_tag2_in != opr2_val[`TAG_WIDTH-1:0] && !mask_off) ||
525
        (opr3_used && opr3_val[`RB] && predict_tag1_in != opr3_val[`TAG_WIDTH-1:0] && predict_tag2_in != opr3_val[`TAG_WIDTH-1:0] && !mask_off) ||
526
        (mask_status_in && regmask_val[`MASKSZ] && predict_tag1_in != regmask_val[`TAG_WIDTH-1:0] && predict_tag2_in != regmask_val[`TAG_WIDTH-1:0]);
527
end
528
 
529
// save values from result bus during stall
530
always_ff @(posedge clock) if (clock_enable) begin
531
    if (stall_in) begin
532
        opr1_val_temp    <= opr1_val;      // temporary save during stall
533
        opr2_val_temp    <= opr2_val;      // temporary save during stall
534
        opr3_val_temp    <= opr3_val;      // temporary save during stall
535
        regmask_val_temp <= regmask_val;   // temporary save during stall
536
    end else begin
537
        opr1_val_temp    <= {1'b1,`RB'b0}; // reset when not stalled
538
        opr2_val_temp    <= {1'b1,`RB'b0}; // reset when not stalled
539
        opr3_val_temp    <= {1'b1,`RB'b0}; // reset when not stalled
540
        regmask_val_temp <= {1'b1,`MASKSZ'b0}; // reset when not stalled
541
    end
542
end
543
 
544
// output operands
545
always_ff @(posedge clock) if (clock_enable && !stall_in) begin
546
    if (!swap_operands) begin // normal operand order
547
 
548
        // jump instructions
549
        if (category_in == `CAT_JUMP) begin
550
            if (opj < `IJ_JUMP_INDIRECT_MEM || opx == `IX_UNCOND_JUMP) begin
551
                // calculate jump target = ip + il + offset (il cannot be 0 for jump instructions)
552
                operand1_out[`RB1:0] <= instruction_pointer_in + {{32{jump_offset[31]}},jump_offset} + il;
553
                operand1_out[`RB] <= 0;     // indicate not missing
554
            end else begin
555
                // target address not known yet. Make sure we don't accidentally assume no jump
556
                operand1_out <= ~(`RB'b0);  // -1 for unknown target address
557
            end
558
        end else begin
559
            operand1_out <= opr1_val;
560
        end
561
        operand2_out <= opr2_val;
562
        operand3_out <= opr3_val;
563
        opr2_from_ram_out <= opr2_from_ram; // value of operand 2 comes from data cache
564
        opr3_from_ram_out <= opr3_from_ram; // value of last operand comes from data cache
565
        opr1_used_out <= opr1_used;
566
        opr2_used_out <= opr2_used;
567
        opr3_used_out <= opr3_used;
568
        // disable ram input if error (removed because of critical timing):
569
        /*
570
        if (array_error_in || read_address_error) begin
571
            opr2_from_ram_out <= 0;
572
            opr3_from_ram_out <= 0;
573
            if (opr2_from_ram) operand2_out <= 0;
574
            if (opr3_from_ram) operand3_out <= 0;
575
        end*/
576
 
577
    end else begin // swap last two operands
578
        operand1_out <= opr1_val;
579
        operand2_out <= opr3_val;
580
        operand3_out <= opr2_val;
581
        opr2_from_ram_out <= opr3_from_ram; // value of operand 2 comes from data cache
582
        opr3_from_ram_out <= opr2_from_ram; // value of last operand comes from data cache
583
        opr1_used_out <= opr1_used;
584
        opr2_used_out <= opr3_used;
585
        opr3_used_out <= opr2_used;
586
        // disable ram input if error (removed because of critical timing):
587
        /*
588
        if (array_error_in || read_address_error) begin
589
            opr2_from_ram_out <= 0;
590
            opr3_from_ram_out <= 0;
591
            if (opr2_from_ram) operand3_out <= 0;
592
            if (opr3_from_ram) operand2_out <= 0;
593
        end*/
594
    end
595
 
596
    mask_val_out <= regmask_val;
597
 
598
    // other outputs
599
    regmask_used_out <= mask_status_in;
600
    instruction_pointer_out <= instruction_pointer_in; // address of current instruction
601
    instruction_out <= instruction_in[31:0];
602
    tag_val_out <= tag_val_in;              // instruction tag value
603
    vector_out <= vector_in;                // this is a vector instruction
604
    mask_alternative_out <= mask_alternative_in;
605
    opx_out <= opx;                         // operation ID in execution unit. This is mostly equal to op1 for multiformat instructions
606
    opj_out <= opj;                         // operation ID for conditional jump instructions
607
    ot_out <= otype;                        // operand type
608
    option_bits_out <= option_bits;         // option bits in format E
609
    im2_bits_out <= im2_bits;               // constant bits from IM2 as extra operand
610
 
611
    result_type_out <= result_type_in;      // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
612
    num_operands_out <= num_operands_in;    // number of source operands
613
    category_out <= category_in;            // 00: multiformat, 01: single format, 10: jump
614
    format_out <= format_in;                // 00: format A, 01: format E, 10: format B, 11: format C (format D never goes through decoder)
615
 
616
    // choose which execution unit to use
617
    exe_unit_out <= exe_unit;
618
    // detect trap instruction. will enable single step mode in next clock cycle
619
    trap_out <= (il == 1 && mode == 7 && op1 == `IJ_TRAP && valid_in);
620
end
621
 
622
always_ff @(posedge clock) if (clock_enable) begin
623
 
624
    if (reset) valid_out <= 0;
625
    else if (!stall_in) valid_out <= valid_in;
626
 
627
    last_stall <= stall_in & valid_in;
628
    last_valid <= valid_in;
629
    array_error_out <= array_error_in & valid_in;                        // array index out of bounds
630
    read_address_error_out <= read_address_error & valid_in;             // invalid read memory address
631
    write_address_error_out <= write_address_error & valid_in;           // invalid write memory address
632
    misaligned_address_error_out <= misaligned_address_error & valid_in; // misaligned read/write memory address
633
 
634
    // predict stall
635
    if (exe_unit[2] && 0) begin
636
        stall_predict_out <= valid_in; // To do: stall if div unit busy
637
    end else begin
638
        stall_predict_out <= stall_predict && valid_in && !stall_in;     // not all operands and units are ready
639
    end
640
 
641
    // debug output
642
    debug_out <= 0;
643
    debug_out[1:0] <= result_type_in;
644
    debug_out[5:4] <= num_operands_in;
645
    debug_out[9:8] <= mask_status_in;
646
    debug_out[10]  <= mask_alternative_in;
647
    debug_out[11]  <= mask_off;
648
 
649
    debug_out[12]  <= regmask_val[0];
650
    debug_out[15]  <= regmask_val[`MASKSZ];
651
 
652
    debug_out[16]  <= opr1_used;
653
    debug_out[17]  <= opr2_used;
654
    debug_out[18]  <= opr3_used;
655
    debug_out[19]  <= swap_operands;
656
 
657
    debug_out[20]  <= stall_predict;
658
 
659
    debug_out[25:24]  <= il;
660
 
661
 
662
end
663
 
664
endmodule

powered by: WebSVN 2.1.0

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