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

Subversion Repositories forwardcom

[/] [forwardcom/] [trunk/] [addressgenerator.sv] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 Agner
//////////////////////////////////////////////////////////////////////////////////
2
//////////////////////////////////////////////////////////////////////////////////
3
// Engineer: Agner Fog
4
//
5
// Create Date:    2020-06-04
6
// Last modified:  2021-07-17
7
// Module Name:    decoder
8
// Project Name:   ForwardCom soft core
9
// Target Devices: Artix 7
10
// Tool Versions:  Vivado v. 2020.1
11
// License:        CERN-OHL-W v. 2 or later
12
// Description:    Address generator. Calculates address of memory operand
13
//
14
//////////////////////////////////////////////////////////////////////////////////
15
`include "defines.vh"
16
 
17
 
18
module addressgenerator(
19
    input clock,                            // system clock (100 MHz)
20
    input clock_enable,                     // clock enable. Used when single-stepping
21
    input reset,                            // system reset.
22
    input valid_in,                         // data from fetch module ready
23
    input stall_in,                         // a later stage in pipeline is stalled
24
    input [`CODE_ADDR_WIDTH-1:0] instruction_pointer_in, // address of current instruction
25
    input [95:0] instruction_in,            // current instruction, up to 3 words long
26
    input [`TAG_WIDTH-1:0] tag_val_in,      // instruction tag value
27
    input        vector_in,                 // this is a vector instruction
28
    input [1:0]  category_in,               // 00: multiformat, 01: single format, 10: jump
29
    input [1:0]  format_in,                 // 00: format A, 01: format E, 10: format B, 11: format C (format D never goes through decoder)
30
    input [2:0]  rs_status_in,              // 1: RS is register operand, 2: RS is pointer, 3: RS is index, 4: RS is vector length
31
    input [2:0]  rt_status_in,              // 1: RT is register operand, 2: RT is pointer
32
    input [1:0]  ru_status_in,              // 1: RU is used as register operand
33
    input [1:0]  rd_status_in,              // 1: RD is used as input
34
    input [1:0]  mask_status_in,            // 1: mask register used
35
    input        mask_alternative_in,       // mask register and fallback register used for alternative purposes
36
    input [2:0]  fallback_use_in,           // 0: no fallback, 1: same as first source operand, 2-4: RU, RS, RT
37
    input [1:0]  num_operands_in,           // number of source operands
38
    input [1:0]  result_type_in,            // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
39
    input [1:0]  offset_field_in,           // address offset. 0: none, 1: 8 bit, possibly scaled, 2: 16 bit, 3: 32 bit
40
    input [1:0]  immediate_field_in,        // immediate data field. 0: none, 1: 8 bit, 2: 16 bit, 3: 32 or 64 bit
41
    input [1:0]  scale_factor_in,           // 00: index is not scaled, 01: index is scaled by operand size, 10: index is scaled by -1
42
    input        index_limit_in,            // IM2 or IM3 contains a limit to the index
43
    // Register values
44
    input [`RB:0] rd_val_in,                // value of register operand RD, bit `RB indicates missing
45
    input [`RB:0] rs_val_in,                // value of register operand RS, bit `RB indicates missing
46
    input [`RB:0] rt_val_in,                // value of register operand RT, bit `RB indicates missing
47
    input [`RB:0] ru_val_in,                // value of register operand RU, bit `RB indicates missing
48
    input [`MASKSZ:0]  regmask_val_in,      // value of mask register, bit 32 indicates missing
49
 
50
    // monitor result buses:
51
    input write_en1,                        // a result is written to writeport1
52
    input [`TAG_WIDTH-1:0] write_tag1_in,   // tag of result inwriteport1
53
    input [`RB1:0] writeport1_in,           // result bus 1
54
    input write_en2,                        // a result is written to writeport2
55
    input [`TAG_WIDTH-1:0] write_tag2_in,   // tag of result inwriteport2
56
    input [`RB1:0] writeport2_in,           // result bus 2
57
    input [`TAG_WIDTH-1:0] predict_tag1_in, // tag on result bus 1 in next clock cycle
58
    input [`TAG_WIDTH-1:0] predict_tag2_in, // tag on result bus 2 in next clock cycle
59
 
60
    // calculated read and write memory addresses go to data cache
61
    output reg [`COMMON_ADDR_WIDTH-1:0] read_write_address_out, // address of memory operand
62
    output reg        read_enable_out,      // read from data cache
63
    output reg [1:0]  read_data_size_out,   // 8, 16, 32, or 64 bits read
64
    output reg [7:0]  write_enable_out,     // write enable for each byte separately
65
    output reg [63:0] write_data_out,       // data to write
66
 
67
    // instruction output to next pipeline stage
68
    output reg        valid_out,            // An instruction is ready for output to next stage
69
    output reg [`CODE_ADDR_WIDTH-1:0] instruction_pointer_out, // address of current instruction
70
    output reg [63:0] instruction_out,      // first word of instruction
71
    output reg        stall_predict_out,    // will be waiting for an operand
72
    output reg [`TAG_WIDTH-1:0] tag_val_out,// instruction tag value
73
 
74
    output reg [`RB:0] operand1_out,        // value of first operand, bit `RB indicates invalid
75
    output reg [`RB:0] operand2_out,        // value of second operand, bit `RB indicates invalid
76
    output reg [`RB:0] operand3_out,        // value of last, bit `RB indicates valid
77
    output reg [`MASKSZ:0]  regmask_val_out,// value of mask register, high bit indicates valid
78
 
79
    output reg        vector_out,           // this is a vector instruction
80
    output reg [1:0]  category_out,         // 00: multiformat, 01: single format, 10: jump
81
    output reg [1:0]  format_out,           // 00: format A, 01: format E, 10: format B, 11: format C (format D never goes through decoder)
82
    output reg        mask_status_out,      // 1: mask register used
83
    output reg        mask_alternative_out, // mask register and fallback register used for alternative purposes
84
    output reg [2:0]  fallback_use_out,     // 0: no fallback, 1: same as first source operand, 2-4: RU, RS, RT
85
    output reg [1:0]  num_operands_out,     // number of source operands
86
    output reg [1:0]  result_type_out,      // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
87
    output reg [1:0]  offset_field_out,     // address offset. 0: none, 1: 8 bit, possibly scaled, 2: 16 bit, 3: 32 bit
88
    output reg [1:0]  immediate_field_out,  // immediate data field. 0: none, 1: 8 bit, 2: 16 bit, 3: 32 or 64 bit
89
    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
90
    output reg        memory_operand_out,   // The instruction has a memory operand
91
    output reg        array_error_out,      // Array index exceeds limit
92
    output reg        options3_out,         // IM3 containts option bits
93
    output reg [31:0] debug1_out,           // Temporary output for debugging purpose
94
    output reg [31:0] debug2_out,           // Temporary output for debugging purpose
95
    output reg [31:0] debug3_out            // Temporary output for debugging purpose
96
);
97
 
98
// instruction components
99
logic [1:0]  il;                            // instruction length
100
logic [2:0]  mode;                          // instruction mode
101
logic        M;                             // M bit
102
logic [5:0]  op1;                           // OP1 in instruction
103
logic [1:0]  op2;                           // OP2 in instruction
104
logic [2:0]  otype;                         // operand type
105
logic [2:0]  mode2;                         // mode2 in format E
106
logic        option_bits_im3;               // IM3 is used for option bits
107
 
108
// synchronization signals
109
logic waiting;                              // waiting for needed register value
110
logic wait_next1;                           // predict that it will also be waiting for reg1 in the next clock cycle
111
logic wait_next2;                           // predict that it will also be waiting for reg2 in the next clock cycle
112
logic wait_next3;                           // predict that it will also be waiting for reg3 in the next clock cycle
113
logic address_instruction;                  // this is an address instruction. no memory access
114
logic mask_off;                             // result is masked off
115
logic new_instruction;                      // instruction is different from last instruction
116
logic array_error;                          // Array index exceeds limit
117
reg   last_stall;                           // was stalled in last clock cycle. May obtain values from the temporary registers
118
reg   last_valid;                           // input was valid in last clock cycle
119
reg [`TAG_WIDTH-1:0] last_tag_val;          // check if instruction tag has changed
120
 
121
// components of address calculation
122
logic [`COMMON_ADDR_WIDTH-1:0] base_pointer;
123
logic [`COMMON_ADDR_WIDTH-1:0] address_index;
124
logic [`COMMON_ADDR_WIDTH-1:0] address_offset; // offset of memory operand
125
logic [`COMMON_ADDR_WIDTH-1:0] address;     // address of memory operand
126
logic [`RB1:0] write_data;                  // data to write
127
 
128
// register values. Extra bit is 1 if not found
129
logic [`RB:0] rs_val;                       // value of first register operand RS, bit `RB indicates missing
130
logic [`RB:0] rt_val;                       // value of second register operand RT, bit `RB indicates missing
131
logic [`RB:0] ru_val;                       // value of third register operand RD or RU, bit `RB indicates missing
132
logic [`RB:0] rd_val;                       // value of third register operand RD or RU, bit `RB indicates missing
133
logic [`MASKSZ:0]  regmask_val;             // value of mask register, bit 32 indicates missing
134
// temporary storage of register values if found during stall. High bit is zero if valid
135
reg [`RB:0] rs_val_temp;                    // value of first register operand RS, bit `RB indicates missing
136
reg [`RB:0] rt_val_temp;                    // value of second register operand RT, bit `RB indicates missing
137
reg [`RB:0] ru_val_temp;                    // value of third register operand RD or RU, bit `RB indicates missing
138
reg [`RB:0] rd_val_temp;                    // value of third register operand RD or RU, bit `RB indicates missing
139
reg [`MASKSZ:0]  regmask_val_temp;          // value of mask register, bit 32 indicates missing
140
 
141
 
142
always_comb begin
143
    // components of format template
144
    il    = instruction_in[`IL];            // instruction length
145
    mode  = instruction_in[`MODE];          // format mode
146
    M     = instruction_in[`M];             // extension to operand type or mode
147
    op1   = instruction_in[`OP1];           // operation code
148
    op2   = instruction_in[`OP2];           // operation code extension
149
    otype = instruction_in[`OT] & {vector_in,2'b11}; // operand type
150
    mode2 = instruction_in[`MODE2];         // format mode extension
151
    // look for address instruction
152
    if (il == 2 && mode == 1 && M && op1 == `II_ADDRESS_29) address_instruction = 1;
153
    else address_instruction = 0;
154
 
155
    // detect use of IM3 as option bits or extra operand
156
    option_bits_im3 = 0;
157
    if (il == 2 && (mode == 0 || mode == 5) && mode2 == 5) begin
158
        option_bits_im3 = 0;                // format 2.0.5 and 2.2.5 are using IM3 for an operand, not for options
159
    end else if (category_in == `CAT_MULTI) begin
160
        if (op1 == `II_SIGN_EXTEND_ADD || op1 == `II_COMPARE
161
         || op1 == `II_DIV || op1 == `II_DIV_REV || op1 == `II_DIV_U
162
         || op1 == `II_TEST_BIT || op1 == `II_TEST_BITS_AND || op1 == `II_TEST_BITS_OR
163
         || op1 == `II_MUL_ADD_FLOAT16 || op1 == `II_MUL_ADD || op1 == `II_MUL_ADD2
164
         || op1 == `II_ADD_ADD) begin
165
            option_bits_im3 = 1;
166
        end
167
    end else if (il == 2) begin
168
        if (((mode == 0 && !M) || mode == 2) && mode2 == 7 && op1 == `II_MOVE_BITS && op2 == `II2_MOVE_BITS)
169
            option_bits_im3 = 1;
170
        if (mode == 2 && mode2 == 7 && op1 == `II_MASK_LENGTH && op2 == `II2_MASK_LENGTH)
171
            option_bits_im3 = 1;
172
        if (((mode == 0 && !M) || mode == 2) && mode2 == 6 && op1 == `II_TRUTH_TAB3 && op2 == `II2_TRUTH_TAB3)
173
            option_bits_im3 = 1;
174
    end
175
 
176
    /* We need to prevent spill-over of values from a preceding stalled instruction
177
    because the address generator can produce pipeline bubbles. The solution used
178
    here is to check if the instruction tag has changed before using the _temp values.
179
    Test case:
180
    int64 sp -= 32
181
    int r8 = 8
182
    int r9 = 9
183
    int32 [sp+0x00] = r8
184
    int32 [sp+0x08] = r9
185
    int32 r2 = r8 + r9
186
    int32 [sp+0x10] = r2
187
    */
188
    // check if current instruction is different from last clock cycle
189
    new_instruction = (tag_val_in != last_tag_val) && valid_in;
190
 
191
    // look at result buses for any missing register values
192
    if      (last_stall && rs_val_temp[`RB] == 0 && last_valid && !new_instruction) rs_val = rs_val_temp; // obtained during stall
193
    else if (rs_val_in[`RB] == 1 && write_en1 && rs_val_in[`TAG_WIDTH-1:0] == write_tag1_in) rs_val = {1'b0, writeport1_in}; // obtained from result bus 1
194
    else if (rs_val_in[`RB] == 1 && write_en2 && rs_val_in[`TAG_WIDTH-1:0] == write_tag2_in) rs_val = {1'b0, writeport2_in}; // obtained from result bus 2
195
    else rs_val = rs_val_in;
196
 
197
    if      (last_stall && rt_val_temp[`RB] == 0 && last_valid && !new_instruction) rt_val = rt_val_temp; // obtained during stall
198
    else if (rt_val_in[`RB] == 1 && write_en1 && rt_val_in[`TAG_WIDTH-1:0] == write_tag1_in) rt_val = {1'b0, writeport1_in}; // obtained from result bus 1
199
    else if (rt_val_in[`RB] == 1 && write_en2 && rt_val_in[`TAG_WIDTH-1:0] == write_tag2_in) rt_val = {1'b0, writeport2_in}; // obtained from result bus 2
200
    else    rt_val = rt_val_in;
201
 
202
    if      (last_stall && ru_val_temp[`RB] == 0 && last_valid && !new_instruction) ru_val = ru_val_temp; // obtained during stall
203
    else if (ru_val_in[`RB] == 1 && write_en1 && ru_val_in[`TAG_WIDTH-1:0] == write_tag1_in) ru_val = {1'b0, writeport1_in}; // obtained from result bus 1
204
    else if (ru_val_in[`RB] == 1 && write_en2 && ru_val_in[`TAG_WIDTH-1:0] == write_tag2_in) ru_val = {1'b0, writeport2_in}; // obtained from result bus 2
205
    else    ru_val = ru_val_in;
206
 
207
    if      (last_stall && rd_val_temp[`RB] == 0 && last_valid && !new_instruction) rd_val = rd_val_temp; // obtained during stall
208
    else if (rd_val_in[`RB] == 1 && write_en1 && rd_val_in[`TAG_WIDTH-1:0] == write_tag1_in) rd_val = {1'b0, writeport1_in}; // obtained from result bus 1
209
    else if (rd_val_in[`RB] == 1 && write_en2 && rd_val_in[`TAG_WIDTH-1:0] == write_tag2_in) rd_val = {1'b0, writeport2_in}; // obtained from result bus 2
210
    else    rd_val = rd_val_in;
211
 
212
    if      (mask_status_in == `REG_UNUSED) regmask_val = 1;        // no mask
213
    else if (last_stall && regmask_val_temp[`MASKSZ] == 0 && last_valid && !new_instruction) regmask_val = regmask_val_temp; // obtained during stall
214
    else 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
215
    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
216
    else    regmask_val = regmask_val_in;
217
end
218
 
219
// save values from result bus during stall
220
always_ff @(posedge clock) if (clock_enable) begin
221
    if ((stall_in || waiting) && valid_in ) begin
222
        rs_val_temp      <= rs_val;              // temporary save during stall
223
        rt_val_temp      <= rt_val;              // temporary save during stall
224
        ru_val_temp      <= ru_val;              // temporary save during stall
225
        rd_val_temp      <= rd_val;              // temporary save during stall
226
        regmask_val_temp <= regmask_val;         // temporary save during stall
227
    end else begin
228
        rs_val_temp      <= {1'b1,`RB'b0};       // reset when not stalled
229
        rt_val_temp      <= {1'b1,`RB'b0};       // reset when not stalled
230
        ru_val_temp      <= {1'b1,`RB'b0};       // reset when not stalled
231
        rd_val_temp      <= {1'b1,`RB'b0};       // reset when not stalled
232
        regmask_val_temp <= {1'b1,`MASKSZ'b0};   // reset when not stalled
233
    end
234
end
235
 
236
 
237
always_comb begin
238
    // Check if result is masked off so that we don't have to wait for operands
239
    mask_off = mask_status_in != `REG_UNUSED && !mask_alternative_in && !vector_in && regmask_val[`MASKSZ] == 0 && regmask_val[0] == 0;
240
    waiting = 0;
241
    wait_next1 = 0; wait_next2 = 0; wait_next3 = 0;
242
    array_error = 0;
243
 
244
    // check if we need to wait for register values
245
    if (rs_val[`RB] && rs_status_in == `REG_POINTER && !mask_off) begin
246
        waiting = 1; // value of RS needed in this stage for address calculation. must stall
247
        // predict if value will arrive in next clock cycle
248
        wait_next1 = predict_tag1_in != rs_val[`TAG_WIDTH-1:0] && predict_tag2_in != rs_val[`TAG_WIDTH-1:0];
249
    end
250
 
251
    if (rt_val[`RB] && rt_status_in >= `REG_INDEX && !mask_off) begin
252
        waiting = 1; // value of RT needed in this stage for address calculation. must stall
253
        // predict if value will arrive in next clock cycle
254
        wait_next2 = predict_tag1_in != rt_val[`TAG_WIDTH-1:0] && predict_tag2_in != rt_val[`TAG_WIDTH-1:0];
255
    end
256
 
257
    if (rd_val[`RB] && rd_status_in != 0 && result_type_in == `RESULT_MEM && !mask_off) begin
258
        waiting = 1; // value of RD needed in this stage for writing. must stall
259
        // predict if value will arrive in next clock cycle
260
        wait_next3 = predict_tag1_in != rd_val[`TAG_WIDTH-1:0] && predict_tag2_in != rd_val[`TAG_WIDTH-1:0];
261
    end
262
 
263
    if (regmask_val[`MASKSZ] && mask_status_in != `REG_UNUSED && result_type_in == `RESULT_MEM) begin
264
        waiting = 1; // value of mask needed before write
265
        // predict if value will arrive in next clock cycle
266
        wait_next3 = predict_tag1_in != regmask_val[`TAG_WIDTH-1:0] && predict_tag2_in != regmask_val[`TAG_WIDTH-1:0];
267
    end
268
 
269
 
270
    ////////////////////////////////////////////////
271
    //             calculate address:             //
272
    ////////////////////////////////////////////////
273
 
274
    // rs is base pointer
275
    base_pointer = rs_val[`RB1:0];
276
 
277
    if (rt_status_in == `REG_INDEX) begin
278
        // rt is scaled index
279
        if (scale_factor_in == `SCALE_OS) begin
280
            case (otype) // operand type
281
            `OT_INT8:                 address_index =  rt_val[`RB-1:0];       // scale factor 1
282
            `OT_INT16:                address_index = {rt_val[`RB-2:0],1'b0}; // scale factor 2
283
            `OT_INT32, `OT_FLOAT32:   address_index = {rt_val[`RB-3:0],2'b0}; // scale factor 4
284
            `OT_INT64, `OT_FLOAT64:   address_index = {rt_val[`RB-4:0],3'b0}; // scale factor 8
285
            `OT_INT128,`OT_FLOAT128:  address_index = {rt_val[`RB-5:0],4'b0}; // scale factor 16
286
            endcase
287
        end else if (scale_factor_in == `SCALE_MINUS) begin
288
            address_index = -rt_val[`RB1:0];          // scale factor -1
289
        end else begin
290
            address_index =  rt_val[`RB1:0];          // no scale factor
291
        end
292
        if (index_limit_in) begin
293
            // check index limit
294
            if (il == 3 && rt_val[`RB1:0] > instruction_in[95:64]
295
            ||  il == 2 && rt_val[`RB1:0] > instruction_in[`IM2E]) array_error = 1;
296
        end
297
 
298
    end else begin
299
        address_index = 0;                            // no index
300
    end
301
 
302
    if (offset_field_in == `OFFSET_NONE) begin        // no offset
303
        address_offset = 0;
304
    end else if (offset_field_in == `OFFSET_1) begin  // 8 bit offset in IM1, scaled by operand size
305
        case (otype) // operand type
306
        `OT_INT8:                 address_offset = {{56{instruction_in[7]}},instruction_in[`IM1]};      // sign extend IM1
307
        `OT_INT16:                address_offset = {{55{instruction_in[7]}},instruction_in[`IM1],1'b0}; // sign extend, scale by 2
308
        `OT_INT32, `OT_FLOAT32:   address_offset = {{54{instruction_in[7]}},instruction_in[`IM1],2'b0}; // sign extend, scale by 4
309
        `OT_INT64, `OT_FLOAT64:   address_offset = {{53{instruction_in[7]}},instruction_in[`IM1],3'b0}; // sign extend, scale by 8
310
        `OT_INT128,`OT_FLOAT128:  address_offset = {{52{instruction_in[7]}},instruction_in[`IM1],4'b0}; // sign extend, scale by 16
311
        endcase
312
    end else if(offset_field_in == `OFFSET_2) begin                        // 16 bit offset in IM2, not scaled
313
        address_offset = {{48{instruction_in[47]}},instruction_in[`IM2E]}; // sign extend IM2;
314
    end else if (il == 2) begin                                            // 32 bit offset in IM2
315
        address_offset = {{32{instruction_in[63]}},instruction_in[63:32]}; // sign extend IM2;
316
    end else if (mode == 1 && op1 == 0) begin                              // format 3.1.0. Jump with memory offest in IM3
317
        address_offset = {{32{instruction_in[95]}},instruction_in[95:64]}; // sign extend IM3;
318
    end else begin                                                         // format 3.x.x, except 3.1.0
319
        address_offset = {{32{instruction_in[95]}},instruction_in[95:64]}; // sign extend IM4;
320
    end
321
 
322
    // calculated address
323
    address = base_pointer + address_index + address_offset;
324
 
325
    // data to write. (mask is handled below)
326
    if (category_in == `CAT_MULTI) begin
327
        write_data <= rd_val;                    // write register
328
    end else begin
329
        write_data <= instruction_in[63:32];     // write constant
330
    end
331
end
332
 
333
 
334
always_ff @(posedge clock) if (clock_enable) begin
335
 
336
    read_enable_out <= 0;
337
    write_enable_out <= 0;
338
 
339
    if (valid_in && !waiting) begin
340
 
341
        // output memory address for data cache read and write
342
        // must have natural alignment
343
        read_write_address_out <= address;
344
 
345
        if (result_type_in == `RESULT_MEM && !mask_off && !array_error) begin
346
 
347
            // memory write
348
            if (otype == `OT_INT8) begin // write 8 bits
349
                case (address[2:0])
350
                0: begin
351
                    write_data_out <= write_data;
352
                    write_enable_out <= 8'b00000001; end
353
                1: begin
354
                    write_data_out <= {write_data[7:0],8'b0};
355
                    write_enable_out <= 8'b00000010; end
356
                2: begin
357
                    write_data_out <= {write_data[7:0],16'b0};
358
                    write_enable_out <= 8'b00000100; end
359
                3: begin
360
                    write_data_out <= {write_data[7:0],24'b0};
361
                    write_enable_out <= 8'b00001000; end
362
                4: begin
363
                    write_data_out <= {write_data[7:0],32'b0};
364
                    write_enable_out <= 8'b00010000; end
365
                5: begin
366
                    write_data_out <= {write_data[7:0],40'b0};
367
                    write_enable_out <= 8'b00100000; end
368
                6: begin
369
                    write_data_out <= {write_data[7:0],48'b0};
370
                    write_enable_out <= 8'b01000000; end
371
                7: begin
372
                    write_data_out <= {write_data[7:0],56'b0};
373
                    write_enable_out <= 8'b10000000; end
374
                endcase
375
 
376
            end else if (otype == `OT_INT16) begin // write 16 bits
377
                case (address[2:1])
378
                0: begin
379
                    write_data_out <= write_data;
380
                    write_enable_out <= 8'b00000011; end
381
                1: begin
382
                    write_data_out <= {write_data[15:0],16'b0};
383
                    write_enable_out <= 8'b00001100; end
384
                2: begin
385
                    write_data_out <= {write_data[15:0],32'b0};
386
                    write_enable_out <= 8'b00110000; end
387
                3: begin
388
                    write_data_out <= {write_data[15:0],48'b0};
389
                    write_enable_out <= 8'b11000000; end
390
                endcase
391
 
392
            end else if (otype == `OT_INT32 || otype == `OT_FLOAT32) begin // write 32 bits
393
                case (address[2])
394
                0: begin
395
                    write_data_out <= write_data;
396
                    write_enable_out <= 8'b00001111; end
397
                1: begin
398
                    write_data_out <= {write_data[31:0],32'b0};
399
                    write_enable_out <= 8'b11110000; end
400
                endcase
401
 
402
            end else begin // write 64 bits (or more)
403
                write_data_out <= write_data;
404
                write_enable_out <= 8'b11111111;
405
            end
406
 
407
        end else if (rs_status_in == `REG_POINTER && !address_instruction) begin
408
 
409
            // memory read. Must have natural alignment
410
            read_enable_out <= valid_in && !mask_off && !array_error;
411
            write_enable_out <= 0;
412
            case (otype)
413
            `OT_INT8:    read_data_size_out <= `OT_INT8;
414
            `OT_INT16:   read_data_size_out <= `OT_INT16;
415
            `OT_INT32,
416
            `OT_FLOAT32: read_data_size_out <= `OT_INT32;
417
            default:     read_data_size_out <= `OT_INT64;
418
            endcase
419
 
420
        end
421
 
422
        // sort operand values, selected by the priority order: immediate, memory, rt, rs, ru, rd
423
        operand1_out <= 0;    // value of first operand,  bit `RB indicates invalid
424
        operand2_out <= 0;    // value of second operand, bit `RB indicates invalid
425
        operand3_out <= 0;    // value of last operand,   bit `RB indicates invalid
426
 
427
        if (immediate_field_in != `IMMED_NONE && rs_status_in == `REG_POINTER) begin
428
            // both memory and immediate operands.
429
            // Last operand is an immediate value calculated below.
430
            // Next to last operand is a memory operand retrieved later.
431
            // Find remaining register operand
432
            if      (rt_status_in == `REG_OPERAND) operand1_out <= rt_val;
433
            else if (ru_status_in == `REG_OPERAND) operand1_out <= ru_val;
434
            else if (rd_status_in == `REG_OPERAND) operand1_out <= rd_val;
435
 
436
        end else if (immediate_field_in != `IMMED_NONE || rs_status_in == `REG_POINTER) begin
437
            // Last operand is an immediate value calculated below or a memory operand retrieved later.
438
            // Find remaining register operands
439
            if  (rt_status_in == `REG_OPERAND) begin
440
                operand2_out <= rt_val;
441
                if      (rs_status_in == `REG_OPERAND) operand1_out <= rs_val;
442
                else if (ru_status_in == `REG_OPERAND) operand1_out <= ru_val;
443
                else if (rd_status_in == `REG_OPERAND) operand1_out <= rd_val;
444
                else operand1_out <= rt_val;  // possible fallback
445
            end else if (rs_status_in == `REG_OPERAND || rs_status_in == `REG_SYSTEM) begin
446
                operand2_out <= rs_val;
447
                if      (ru_status_in == `REG_OPERAND) operand1_out <= ru_val;
448
                else if (rd_status_in == `REG_OPERAND) operand1_out <= rd_val;
449
                else operand1_out <= rs_val; // possible fallback_use_in == `FALLBACK_RS
450
            end else if (ru_status_in == `REG_OPERAND) begin
451
                operand2_out <= ru_val;
452
                if      (rd_status_in == `REG_OPERAND) operand1_out <= rd_val;
453
                else operand1_out <= ru_val;
454
            end else if (rd_status_in == `REG_OPERAND) begin
455
                operand2_out <= rd_val;
456
                operand1_out <= rd_val;
457
            end
458
        end else begin
459
            // last operand is a register
460
            if  (rt_status_in == `REG_OPERAND) begin
461
                operand3_out <= rt_val;
462
                if  (rs_status_in == `REG_OPERAND) begin
463
                    operand2_out <= rs_val;
464
                    if      (ru_status_in == `REG_OPERAND) operand1_out <= ru_val;
465
                    else if (rd_status_in == `REG_OPERAND) operand1_out <= rd_val;
466
                    else operand1_out <= rs_val;
467
                end else if (ru_status_in == `REG_OPERAND) begin
468
                    operand2_out <= ru_val;
469
                    if      (rd_status_in == `REG_OPERAND) operand1_out <= rd_val;
470
                    else operand1_out <= ru_val;
471
                end else if (rd_status_in == `REG_OPERAND) begin
472
                    operand2_out <= rd_val;
473
                    operand1_out <= rd_val;
474
                end
475
            end else if (rs_status_in == `REG_OPERAND) begin
476
                operand3_out <= rs_val;
477
                if  (ru_status_in == `REG_OPERAND) begin
478
                    operand2_out <= ru_val;
479
                    if (rd_status_in == `REG_OPERAND) operand1_out <= rd_val;
480
                    else operand1_out <= ru_val;
481
                end else if (rd_status_in == `REG_OPERAND) begin
482
                    operand2_out <= rd_val;
483
                    operand1_out <= rd_val;
484
                end
485
            end else if (ru_status_in == `REG_OPERAND) begin // should not occur
486
                operand3_out <= ru_val;
487
                if  (rd_status_in == `REG_OPERAND) begin
488
                    operand2_out <= rd_val;
489
                    operand1_out <= rd_val;
490
                end else begin
491
                    operand1_out <= ru_val;
492
                end
493
            end else if (rd_status_in == `REG_OPERAND) begin
494
                operand3_out <= rd_val;
495
                operand1_out <= rd_val;
496
            end
497
        end
498
 
499
        // look for immediate operand, and process it if necessary
500
        if (immediate_field_in != `IMMED_NONE) begin
501
            if (immediate_field_in == `IMMED_1) begin  // sign_extend 8 bit immediate operand
502
                if (format_in == `FORMAT_E) begin
503
                    operand3_out <= {{(`RB-8){instruction_in[`IM3EXS]}},instruction_in[`IM3EX]};
504
                end else if (format_in == `FORMAT_C && category_in == `CAT_JUMP) begin
505
                    // jump in format 1.7C and 2.5.4C
506
                    operand3_out <= {{(`RB-8){instruction_in[15]}},instruction_in[15:8]};
507
                end else begin   // format B
508
                    operand3_out <= {{(`RB-8){instruction_in[`IM1S]}},instruction_in[`IM1]};
509
                end
510
            end
511
            if (immediate_field_in == `IMMED_2) begin // sign_extend 16 bit immediate operand
512
                if (format_in == `FORMAT_C) begin     // format C: sign extend (IM2,IM1)
513
                    operand3_out <= {{(`RB-16){instruction_in[15]}},instruction_in[15:0]};
514
                    // special cases
515
                    if (mode == 1) begin
516
                        if (op1 == `II_MOVEU11) operand3_out <= instruction_in[15:0]; // zero extended
517
                        if (op1 == `II_ADDSHIFT16_11) begin
518
                            `ifdef SUPPORT_64BIT
519
                                operand3_out <= {{(`RB-32){instruction_in[15]}},instruction_in[15:0],16'b0}; // shift left by 16
520
                            `else
521
                                operand3_out <= {instruction_in[15:0],16'b0}; // shift left by 16
522
                            `endif
523
                        end
524
                        if ((op1 & -2) == `II_SHIFT_MOVE_11 || op1 >= `II_SHIFT_ADD_11 && op1 <= `II_SHIFT_XOR_11+1) begin // IM2 << IM1
525
                            if (instruction_in[`IM1] >= 64) operand3_out <= 0;
526
                            else operand3_out <= {{(`RB-8){instruction_in[15]}},instruction_in[15:8]} << instruction_in[5:0];
527
                        end
528
                    end
529
                end else begin
530
                    operand3_out <= {{(`RB-16){instruction_in[`IM2ES]}},instruction_in[`IM2E]};
531
                    // special cases
532
                    if (il == 2 && ((mode == 0 && !M) || mode == 2) && mode2 == 7 && !option_bits_im3) begin
533
                         // format 2.0.7 and 2.2.7 have shift
534
                        operand3_out <= {{(`RB-16){instruction_in[47]}},instruction_in[`IM2E]} << instruction_in[`IM3E];
535
                    end
536
                end
537
            end
538
            if (immediate_field_in == `IMMED_3) begin
539
                `ifdef SUPPORT_64BIT
540
                if (il == 3 && ((mode == 0 && !M) || mode == 2) && mode2 == 7 && otype < `OT_FLOAT32) begin
541
                     // format 3.0.7 and 3.2.7 have shift
542
                    operand3_out <= {{32{instruction_in[95]}},instruction_in[95:64]} << instruction_in[`IM2E];
543
                end else if (il == 3 && format_in == `FORMAT_E) begin
544
                    // other format 3E
545
                    operand3_out <= {{32{instruction_in[95]}},instruction_in[95:64]};
546
                end else if (il == 3 && mode == 0 && M) begin
547
                    // format 3.8
548
                    operand3_out <= instruction_in[95:32];
549
                end else begin
550
                    // format 2.x
551
                    operand3_out <= {{32{instruction_in[63]}},instruction_in[63:32]};
552
                end
553
                `else
554
                if (((mode == 0 && !M) || mode == 2) && mode2 == 7 && otype < `OT_FLOAT32) begin
555
                     // format 3.0.7 and 3.2.7 have shift
556
                    operand3_out <= instruction_in[95:64] << instruction_in[`IM2E];
557
                end else if (il == 3 && format_in == `FORMAT_E) begin
558
                    operand3_out <= instruction_in[95:64];
559
                end else begin
560
                    operand3_out <= instruction_in[63:32];
561
                end
562
                `endif
563
 
564
                // special cases
565
                if (il == 2 && mode == 1 && M) begin
566
                    if (op1 == `II_ADDU_29 || op1 == `II_SUBU_29) begin
567
                        operand3_out <= instruction_in[63:32]; // zero extend
568
                    end
569
                    if (op1 == `II_MOVE_HI_29 || (op1 >= `II_ADD_HI_29 && op1 <= `II_XOR_HI_29)) begin
570
                        // immediate constant is high word of 64 bits
571
                        `ifdef SUPPORT_64BIT
572
                            operand3_out <= {instruction_in[63:32],32'b0}; // high word
573
                        `else
574
                            operand3_out <= 0; // there is no high word
575
                        `endif
576
                    end
577
                end
578
            end
579
            //if (category_in == `CAT_JUMP) begin // unnecessary check
580
            if (il == 2 && mode == 5) begin
581
                // immediate operands in jump instructions 2.5.x
582
                if (op1 == 0) begin
583
                    // format 2.5.0A: jump with three registers, and 24 bit jump offset, no immediate
584
                end else if (op1 == 1) begin
585
                    // format 2.5.1B: jump with one register, one 16 bit operand, and 16 bit jum offset
586
                    operand3_out <= {{48{instruction_in[47]}},instruction_in[47:32]}; // sign extend 16 bit operand
587
                end else if (op1 == 4) begin
588
                    // format 2.5.4C: jump with one register, one 8 bit operand, and 32 bit offset
589
                    operand3_out <= {{56{instruction_in[15]}},instruction_in[15:8]}; // sign extend 8 bit operand
590
                end else if (op1 == 5) begin
591
                    // format 2.5.5: jump with one register, one 32 bit operand, and 8 bit offset
592
                    operand3_out <= {{32{instruction_in[63]}},instruction_in[63:32]}; // sign extend 32 bit operand
593
                end else if (op1 == 7) begin
594
                    // format 2.5.7: system call. 16 bit and 32 bit constants
595
                    operand3_out <= {instruction_in[63:32],16'b0,instruction_in[15:0]}; // 32 bit module ID, 16 bit function ID
596
                end
597
            end
598
            if (il == 3 && mode == 1) begin
599
                // immedate operands in jump instructions 3.1.x
600
                if (op1 == 0) begin
601
                    // format 3.1.0: jump with memory operand and 32 bit offset. no immediate
602
                end else if (op1 == 1) begin // && op1 == `IJ_SYSCALL
603
                    // jump format 3.1.1
604
                    if (instruction_in[5:0] < `IJ_SYSCALL) begin
605
                        operand3_out <= instruction_in[95:64];
606
                    end else begin
607
                        // format 3.1.1: system call with 32 bit module ID and 32 bit function ID
608
                        `ifdef  SUPPORT_64BIT
609
                            operand3_out <= instruction_in[95:32];
610
                        `else
611
                            operand3_out <= {instruction_in[79:64],instruction_in[47:32]};
612
                        `endif
613
                    end
614
                end
615
            end
616
            operand3_out[`RB] <= 0;    // indicate not missing
617
        end
618
 
619
        if (address_instruction) begin
620
            operand3_out <= address;   // address instruction
621
        end
622
 
623
        if (fallback_use_in > `FALLBACK_SOURCE) begin
624
            // separate fallback register. Check if fallback zero
625
            if (fallback_use_in == `FALLBACK_RU && instruction_in[`RU] == 31) operand1_out <= 0;
626
            if (fallback_use_in == `FALLBACK_RS && instruction_in[`RS] == 31) operand1_out <= 0;
627
            if (fallback_use_in == `FALLBACK_RT && instruction_in[`RT] == 31) operand1_out <= 0;
628
        end
629
 
630
        // output everything else
631
        regmask_val_out      <= regmask_val;
632
        instruction_pointer_out <= instruction_pointer_in;    // address of current instruction
633
        instruction_out      <= instruction_in[63:0];         // first two words of instruction
634
        tag_val_out          <= tag_val_in;                   // instruction tag value
635
        vector_out           <= vector_in;                    // this is a vector instruction
636
        category_out         <= category_in;                  // 00: multiformat, 01: single format, 10: jump
637
        format_out           <= format_in;                    // 00: format A, 01: format E, 10: format B, 11: format C (format D never goes through decoder)
638
        mask_status_out      <= mask_status_in == `REG_OPERAND;// mask register is used
639
        mask_alternative_out <= mask_alternative_in;          // mask register and fallback register used for alternative purposes
640
        fallback_use_out     <= fallback_use_in;              // use of fallback register
641
        num_operands_out     <= num_operands_in;              // number of source operands
642
        result_type_out      <= result_type_in;               // type of result: 0: register, 1: system register, 2: memory, 3: other or nothing
643
        offset_field_out     <= offset_field_in;              // address offset. 0: none, 1: 8 bit, possibly scaled, 2: 16 bit, 3: 32 bit
644
        immediate_field_out  <= immediate_field_in;           // immediate data field. 0: none, 1: 8 bit, 2: 16 bit, 3: 32 or 64 bit
645
        scale_factor_out     <= scale_factor_in;              // 00: index is not scaled, 01: index is scaled by operand size, 10: index is scaled by -1
646
        memory_operand_out   <= (rs_status_in >= `REG_POINTER) && !address_instruction; // The instruction has a memory operand
647
        array_error_out      <= array_error;                  // Array index exceeds limit;
648
        options3_out         <= option_bits_im3;              // IM3 used for option bits
649
    end
650
 
651
end
652
 
653
 
654
always_ff @(posedge clock) if (clock_enable) begin
655
    last_stall <= (stall_in || waiting) && valid_in;
656
    last_valid <= valid_in;
657
    stall_predict_out <= (wait_next1 | wait_next2 | wait_next3) && valid_in; // predict stalling in next clock cycle
658
    last_tag_val <= tag_val_in;
659
 
660
    if (reset) begin
661
        valid_out  <= 0;
662
    end else begin
663
        // avoid sending an instruction that is not ready, or an instruction that has already been sent
664
        valid_out  <= valid_in && !waiting && !stall_in && (new_instruction | !valid_out);
665
    end
666
 
667
    // temporary debug outputs
668
    debug1_out <=  {address_offset[7:0], address_index[7:0], base_pointer[15:0]};
669
    debug2_out <=  write_data;
670
 
671
    debug3_out[0] <= waiting;
672
    debug3_out[1] <= stall_in;
673
    debug3_out[2] <= last_stall;
674
 
675
    debug3_out[4] <= wait_next1;
676
    debug3_out[5] <= wait_next2;
677
    debug3_out[6] <= wait_next3;
678
 
679
    debug3_out[8]  <= rs_val[`RB] && (rs_status_in >= `REG_POINTER) && !mask_off;
680
    debug3_out[9]  <= rt_val[`RB] && (rt_status_in >= `REG_INDEX) && !mask_off;
681
    debug3_out[10] <= rd_val[`RB] && (rd_status_in != 0)&& result_type_in == `RESULT_MEM && !mask_off;
682
    debug3_out[11] <= new_instruction;
683
 
684
    debug3_out[12] <= valid_in;
685
    debug3_out[14] <= valid_out; // preceding valid out
686
    debug3_out[15] <= last_valid;
687
 
688
    debug3_out[16] <= rs_val[`RB];
689
    debug3_out[17] <= rt_val[`RB];
690
    debug3_out[18] <= rd_val[`RB];
691
 
692
    debug3_out[20] <= rs_val_temp[`RB];
693
    debug3_out[21] <= rt_val_temp[`RB];
694
    debug3_out[22] <= rd_val_temp[`RB];
695
 
696
    debug3_out[24] <= write_en1 && rt_val_in[`TAG_WIDTH-1:0] == write_tag1_in;
697
    debug3_out[25] <= write_en2 && rt_val_in[`TAG_WIDTH-1:0] == write_tag2_in;
698
    debug3_out[26] <= write_en1 && rd_val_in[`TAG_WIDTH-1:0] == write_tag1_in;
699
    debug3_out[27] <= write_en2 && rd_val_in[`TAG_WIDTH-1:0] == write_tag2_in;
700
 
701
    debug3_out[28] <= option_bits_im3;
702
    debug3_out[31] <= mask_off;
703
 
704
end
705
 
706
endmodule

powered by: WebSVN 2.1.0

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