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

Subversion Repositories ao486

[/] [ao486/] [trunk/] [rtl/] [ao486/] [pipeline/] [read_effective_address.v] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 alfik
/*
2
 * Copyright (c) 2014, Aleksander Osman
3
 * All rights reserved.
4
 *
5
 * Redistribution and use in source and binary forms, with or without
6
 * modification, are permitted provided that the following conditions are met:
7
 *
8
 * * Redistributions of source code must retain the above copyright notice, this
9
 *   list of conditions and the following disclaimer.
10
 *
11
 * * Redistributions in binary form must reproduce the above copyright notice,
12
 *   this list of conditions and the following disclaimer in the documentation
13
 *   and/or other materials provided with the distribution.
14
 *
15
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
16
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18
 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
19
 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20
 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
21
 * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
22
 * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
23
 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
24
 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25
 */
26
 
27
`include "defines.v"
28
 
29
module read_effective_address(
30
    input               clk,
31
    input               rst_n,
32
 
33
    input               rd_reset,
34
 
35
    input               rd_address_effective_do,
36
    input               rd_ready,
37
 
38
    //general input
39
    input       [31:0]  eax,
40
    input       [31:0]  ebx,
41
    input       [31:0]  ecx,
42
    input       [31:0]  edx,
43
    input       [31:0]  esp,
44
    input       [31:0]  ebp,
45
    input       [31:0]  esi,
46
    input       [31:0]  edi,
47
 
48
    input       [63:0]  ss_cache,
49
    input       [31:0]  glob_param_3,
50
 
51
    input       [31:0]  wr_esp_prev,
52
 
53
    //rd input
54
    input               rd_address_16bit,
55
    input               rd_address_32bit,
56
    input               rd_operand_16bit,
57
    input               rd_operand_32bit,
58
    input       [87:0]  rd_decoder,
59
    input       [2:0]   rd_modregrm_rm,
60
    input       [2:0]   rd_modregrm_reg,
61
    input       [1:0]   rd_modregrm_mod,
62
    input       [7:0]   rd_sib,
63
 
64
    //address control
65
    input               address_enter_init,
66
    input               address_enter,
67
    input               address_enter_last,
68
    input               address_leave,
69
    input               address_esi,
70
    input               address_edi,
71
    input               address_xlat_transform,
72
    input               address_bits_transform,
73
 
74
    input               address_stack_pop,
75
    input               address_stack_pop_speedup,
76
 
77
    input               address_stack_pop_next,
78
    input               address_stack_pop_esp_prev,
79
    input               address_stack_pop_for_call,
80
    input               address_stack_save,
81
    input               address_stack_add_4_to_saved,
82
 
83
    input               address_stack_for_ret_first,
84
    input               address_stack_for_ret_second,
85
    input               address_stack_for_iret_first,
86
    input               address_stack_for_iret_second,
87
    input               address_stack_for_iret_third,
88
    input               address_stack_for_iret_last,
89
    input               address_stack_for_iret_to_v86,
90
    input               address_stack_for_call_param_first,
91
 
92
    input               address_ea_buffer,
93
    input               address_ea_buffer_plus_2,
94
 
95
    input               address_memoffset,
96
 
97
    //output
98
    output reg          rd_address_effective_ready,
99
    output reg  [31:0]  rd_address_effective
100
);
101
 
102
//------------------------------------------------------------------------------ modregrm
103
 
104
wire [15:0] address_disp16;
105
wire [15:0] base16;
106
wire [15:0] disp16;
107
wire [15:0] base16_plus_disp16;
108
 
109
wire [31:0] address_disp32_no_sib;
110
wire [31:0] address_disp32_sib;
111
wire [31:0] address_disp32;
112
wire [31:0] sib_base32;
113
wire [31:0] sib_index32;
114
wire [31:0] sib_index32_scaled;
115
wire [31:0] sib_base32_plus_index32_scaled;
116
wire [31:0] base32;
117
wire [31:0] disp32;
118
wire [31:0] base32_plus_disp32;
119
 
120
wire [31:0] address_effective_modrm;
121
 
122
//------------------------------------------------------------------------------ modregrm 16-bit
123
 
124
assign address_disp16  = rd_decoder[31:16];
125
 
126
 
127
assign base16 =
128
    (rd_modregrm_rm == 3'b000)?     ebx[15:0] + esi[15:0] :
129
    (rd_modregrm_rm == 3'b001)?     ebx[15:0] + edi[15:0] :
130
    (rd_modregrm_rm == 3'b010)?     ebp[15:0] + esi[15:0] :
131
    (rd_modregrm_rm == 3'b011)?     ebp[15:0] + edi[15:0] :
132
    (rd_modregrm_rm == 3'b100)?     esi[15:0] :
133
    (rd_modregrm_rm == 3'b101)?     edi[15:0] :
134
    (rd_modregrm_rm == 3'b110)?     ebp[15:0] :
135
                                    ebx[15:0];
136
 
137
assign disp16 =
138
    (rd_modregrm_mod == 2'b10)?     address_disp16 :
139
    (rd_modregrm_mod == 2'b01)?     { {8{address_disp16[7]}}, address_disp16[7:0] } :
140
                                    16'd0;
141
 
142
assign base16_plus_disp16 = base16 + disp16;
143
 
144
//------------------------------------------------------------------------------ modregrm 32-bit
145
 
146
assign address_disp32_no_sib = rd_decoder[47:16];
147
assign address_disp32_sib    = rd_decoder[55:24];
148
assign address_disp32        = (rd_modregrm_rm == 3'b100)? address_disp32_sib : address_disp32_no_sib;
149
 
150
assign sib_base32 =
151
    (rd_sib[2:0] == 3'b000)?                               eax :
152
    (rd_sib[2:0] == 3'b001)?                               ecx :
153
    (rd_sib[2:0] == 3'b010)?                               edx :
154
    (rd_sib[2:0] == 3'b011)?                               ebx :
155
    (rd_sib[2:0] == 3'b100)?                               esp :
156
    (rd_sib[2:0] == 3'b101 && rd_modregrm_mod == 2'b00)?   address_disp32_sib :
157
    (rd_sib[2:0] == 3'b101)?                               ebp :
158
    (rd_sib[2:0] == 3'b110)?                               esi :
159
                                                                edi;
160
 
161
assign sib_index32 =
162
    (rd_sib[5:3] == 3'b000)?   eax :
163
    (rd_sib[5:3] == 3'b001)?   ecx :
164
    (rd_sib[5:3] == 3'b010)?   edx :
165
    (rd_sib[5:3] == 3'b011)?   ebx :
166
    (rd_sib[5:3] == 3'b100)?   32'd0 :
167
    (rd_sib[5:3] == 3'b101)?   ebp :
168
    (rd_sib[5:3] == 3'b110)?   esi :
169
                                    edi;
170
 
171
assign sib_index32_scaled =
172
    (rd_sib[7:6] == 2'b00)?      sib_index32 :
173
    (rd_sib[7:6] == 2'b01)?    { sib_index32[30:0], 1'b0 } :
174
    (rd_sib[7:6] == 2'b10)?    { sib_index32[29:0], 2'b0 } :
175
                                    { sib_index32[28:0], 3'b0 };
176
 
177
assign sib_base32_plus_index32_scaled = sib_base32 + sib_index32_scaled;
178
 
179
assign base32 =
180
    (rd_modregrm_rm == 3'b000)?     eax :
181
    (rd_modregrm_rm == 3'b001)?     ecx :
182
    (rd_modregrm_rm == 3'b010)?     edx :
183
    (rd_modregrm_rm == 3'b011)?     ebx :
184
    (rd_modregrm_rm == 3'b100)?     sib_base32_plus_index32_scaled :
185
    (rd_modregrm_rm == 3'b101)?     ebp :
186
    (rd_modregrm_rm == 3'b110)?     esi :
187
                                    edi;
188
 
189
assign disp32 =
190
    (rd_modregrm_mod == 2'b10)?     address_disp32 :
191
    (rd_modregrm_mod == 2'b01)?     { {24{address_disp32[7]}}, address_disp32[7:0] } :
192
                                    32'd0;
193
 
194
assign base32_plus_disp32 = base32 + disp32;
195
 
196
//------------------------------------------------------------------------------ modregrm final
197
 
198
assign address_effective_modrm =
199
    (rd_address_16bit && rd_modregrm_mod == 2'b00 && rd_modregrm_rm == 3'b110)?     { 16'd0, address_disp16 } :
200
    (rd_address_32bit && rd_modregrm_mod == 2'b00 && rd_modregrm_rm == 3'b101)?     address_disp32_no_sib :
201
    (rd_address_16bit)?                                                             { 16'd0, base16_plus_disp16 } :
202
                                                                                    base32_plus_disp32;
203
//------------------------------------------------------------------------------
204
//------------------------------------------------------------------------------
205
//------------------------------------------------------------------------------
206
 
207
//------------------------------------------------------------------------------ string
208
 
209
wire [31:0] esi_offset;
210
wire [31:0] edi_offset;
211
 
212
assign esi_offset = (rd_address_16bit)? { 16'd0, esi[15:0] } : esi;
213
assign edi_offset = (rd_address_16bit)? { 16'd0, edi[15:0] } : edi;
214
 
215
//------------------------------------------------------------------------------ stack pop
216
 
217
wire [31:0] pop_next;
218
wire [31:0] pop_offset_speedup_next;
219
wire [31:0] pop_offset;
220
 
221
reg [31:0]  pop_offset_speedup;
222
 
223
assign pop_next =
224
    (address_stack_pop_speedup && rd_operand_16bit)?    pop_offset_speedup + 32'd2 :
225
    (address_stack_pop_speedup)?                        pop_offset_speedup + 32'd4 :
226
    (rd_operand_16bit)?                                 esp + 32'd2 :
227
                                                        esp + 32'd4;
228
 
229
assign pop_offset_speedup_next = (ss_cache[`DESC_BIT_D_B])? pop_next : { 16'd0, pop_next[15:0] };
230
 
231
always @(posedge clk or negedge rst_n) begin
232
    if(rst_n == 1'b0)   pop_offset_speedup <= 32'd0;
233
    else if(rd_ready)   pop_offset_speedup <= pop_offset_speedup_next;
234
end
235
 
236
assign pop_offset =
237
    (address_stack_pop_speedup)?    pop_offset_speedup :
238
    (ss_cache[`DESC_BIT_D_B])?      esp :
239
                                    { 16'd0, esp[15:0] };
240
 
241
//------------------------------------------------------------------------------ stack pop for ret
242
 
243
wire [31:0] stack_initial;
244
wire [31:0] stack;
245
wire [31:0] stack_for_ret_first;
246
wire [31:0] stack_for_ret_second_imm_offset;
247
wire [31:0] stack_for_ret_second;
248
wire [31:0] stack_for_iret_first;
249
wire [31:0] stack_for_iret_second;
250
wire [31:0] stack_for_iret_third;
251
wire [31:0] stack_for_iret_to_v86;
252
 
253
wire [31:0] stack_for_call_param_first;
254
 
255
wire [31:0] stack_next;
256
 
257
reg  [31:0] stack_saved;
258
 
259
wire [31:0] stack_offset;
260
 
261
wire [4:0]  call_gate_param;
262
 
263
assign stack_initial =
264
    (address_stack_pop_esp_prev)?   wr_esp_prev :
265
                                    esp;
266
 
267
assign stack =
268
    (ss_cache[`DESC_BIT_D_B])?  stack_initial :
269
                                { 16'd0, stack_initial[15:0] };
270
 
271
assign stack_for_ret_first =
272
    (rd_operand_16bit)? stack + 32'd2 :
273
                        stack + 32'd4;
274
 
275
assign stack_for_ret_second_imm_offset =
276
    (rd_decoder[0] == 1'b0)?    { 16'd0, rd_decoder[23:8] } :
277
                                32'd0;
278
 
279
assign stack_for_ret_second =
280
    (rd_operand_16bit)? stack + 32'd6  + stack_for_ret_second_imm_offset :
281
                        stack + 32'd12 + stack_for_ret_second_imm_offset;
282
 
283
assign stack_for_iret_first =
284
    (rd_operand_16bit)? stack + 32'd4 :
285
                        stack + 32'd8;
286
 
287
assign stack_for_iret_second =
288
    (rd_operand_16bit)? stack + 32'd8 :
289
                        stack + 32'd16;
290
 
291
assign stack_for_iret_third =
292
    (rd_operand_16bit)? stack + 32'd6 :
293
                        stack + 32'd12;
294
 
295
assign stack_for_iret_to_v86 = stack + 32'd12;
296
 
297
 
298
assign call_gate_param = glob_param_3[24:20] - 5'd1;
299
 
300
assign stack_for_call_param_first =
301
    (~(glob_param_3[19]))?  stack + { 26'd0, call_gate_param, 1'b0 } :
302
                            stack + { 25'd0, call_gate_param, 2'b0 };
303
 
304
assign stack_next =
305
    (address_stack_pop_for_call && ~(glob_param_3[19]))?    stack_saved - 32'd2 :
306
    (address_stack_pop_for_call)?                           stack_saved - 32'd4 :
307
    (rd_operand_16bit)?                                     stack_saved - 32'd2 :
308
                                                            stack_saved - 32'd4;
309
 
310
always @(posedge clk or negedge rst_n) begin
311
    if(rst_n == 1'b0)                                   stack_saved <= 32'd0;
312
    else if(rd_ready && address_stack_add_4_to_saved)   stack_saved <= stack_saved + 32'd4;
313
    else if(rd_ready)                                   stack_saved <= stack_next;
314
    else if(address_stack_save)                         stack_saved <= stack_offset;
315
end
316
 
317
assign stack_offset =
318
    (address_stack_for_ret_first)?          stack_for_ret_first :
319
    (address_stack_for_ret_second)?         stack_for_ret_second :
320
    (address_stack_for_iret_first)?         stack_for_iret_first :
321
    (address_stack_for_iret_second)?        stack_for_iret_second :
322
    (address_stack_for_iret_third)?         stack_for_iret_third :
323
    (address_stack_for_iret_last)?          stack :
324
    (address_stack_for_iret_to_v86)?        stack_for_iret_to_v86 :
325
    (address_stack_for_call_param_first)?   stack_for_call_param_first :
326
                                            stack_saved;
327
 
328
//------------------------------------------------------------------------------ XLAT
329
 
330
wire [31:0] xlat_offset;
331
 
332
assign xlat_offset = ebx + { 24'b0, eax[7:0] };
333
 
334
//------------------------------------------------------------------------------ LEAVE
335
 
336
wire [31:0] ebp_for_leave_offset;
337
 
338
assign ebp_for_leave_offset = (ss_cache[`DESC_BIT_D_B])? ebp : { 16'd0, ebp[15:0] };
339
 
340
//------------------------------------------------------------------------------ bit operations
341
 
342
wire [31:0] address_bits_transform_reg;
343
wire [31:0] address_bits_transform_sum;
344
 
345
assign address_bits_transform_reg =
346
    (rd_modregrm_reg == 3'b000)?    eax :
347
    (rd_modregrm_reg == 3'b001)?    ecx :
348
    (rd_modregrm_reg == 3'b010)?    edx :
349
    (rd_modregrm_reg == 3'b011)?    ebx :
350
    (rd_modregrm_reg == 3'b100)?    esp :
351
    (rd_modregrm_reg == 3'b101)?    ebp :
352
    (rd_modregrm_reg == 3'b110)?    esi :
353
                                    edi;
354
 
355
assign address_bits_transform_sum =
356
    (rd_operand_32bit)?     address_effective_modrm + { { 3{address_bits_transform_reg[31]}}, address_bits_transform_reg[31:5], 2'b0 } :
357
                            address_effective_modrm + { {19{address_bits_transform_reg[15]}}, address_bits_transform_reg[15:4], 1'b0 };
358
 
359
//------------------------------------------------------------------------------ ENTER
360
 
361
wire [31:0] ebp_for_enter_next;
362
wire [31:0] ebp_for_enter_offset;
363
 
364
reg  [31:0] ebp_for_enter;
365
 
366
wire [31:0] esp_for_enter_next;
367
wire [31:0] esp_for_enter_offset;
368
 
369
 
370
assign ebp_for_enter_next    = (rd_operand_16bit)? ebp_for_enter - 32'd2 : ebp_for_enter - 32'd4;
371
assign ebp_for_enter_offset = (ss_cache[`DESC_BIT_D_B])? ebp_for_enter_next : { 16'd0, ebp_for_enter_next[15:0] };
372
 
373
always @(posedge clk or negedge rst_n) begin
374
    if(rst_n == 1'b0)           ebp_for_enter <= 32'd0;
375
    else if(address_enter_init) ebp_for_enter <= ebp;
376
    else if(rd_ready)           ebp_for_enter <= ebp_for_enter_offset;
377
end
378
 
379
assign esp_for_enter_next    = esp - { 16'd0, rd_decoder[23:8] };
380
assign esp_for_enter_offset = (ss_cache[`DESC_BIT_D_B])? esp_for_enter_next : { 16'd0, esp_for_enter_next[15:0] };
381
 
382
//------------------------------------------------------------------------------ ea buffer
383
 
384
wire [31:0] ea_buffer_sum;
385
wire [31:0] ea_buffer_next;
386
 
387
reg  [31:0] ea_buffer;
388
 
389
assign ea_buffer_sum  =
390
    (rd_operand_16bit || address_ea_buffer_plus_2)? rd_address_effective + 32'd2 :
391
                                                    rd_address_effective + 32'd4;
392
 
393
assign ea_buffer_next = (rd_address_16bit)? { 16'd0, ea_buffer_sum[15:0] } : ea_buffer_sum;
394
 
395
always @(posedge clk or negedge rst_n) begin
396
    if(rst_n == 1'b0)                               ea_buffer <= 32'd0;
397
    else if(rd_ready && rd_address_effective_ready) ea_buffer <= ea_buffer_next;
398
end
399
 
400
//------------------------------------------------------------------------------ final effective address
401
 
402
always @(posedge clk or negedge rst_n) begin
403
    if(rst_n == 1'b0)                   rd_address_effective_ready <= `FALSE;
404
    else if(rd_ready || rd_reset)       rd_address_effective_ready <= `FALSE;
405
    else if(rd_address_effective_do)    rd_address_effective_ready <= `TRUE;
406
end
407
 
408
always @(posedge clk or negedge rst_n) begin
409
    if(rst_n == 1'b0)                               rd_address_effective <= 32'd0;
410
    else if(address_memoffset && rd_address_16bit)  rd_address_effective <= { 16'd0, rd_decoder[23:8] };
411
    else if(address_memoffset && rd_address_32bit)  rd_address_effective <= rd_decoder[39:8];
412
    else if(address_ea_buffer)                      rd_address_effective <= ea_buffer;
413
    else if(address_enter)                          rd_address_effective <= ebp_for_enter_offset;
414
    else if(address_enter_last)                     rd_address_effective <= esp_for_enter_offset;
415
    else if(address_leave)                          rd_address_effective <= ebp_for_leave_offset;
416
    else if(address_esi)                            rd_address_effective <= esi_offset;
417
    else if(address_edi)                            rd_address_effective <= edi_offset;
418
    else if(address_stack_pop)                      rd_address_effective <= pop_offset;
419
    else if(address_stack_pop_next)                 rd_address_effective <= stack_offset;
420
    else if(address_xlat_transform)                 rd_address_effective <= { {16{rd_address_32bit}} & xlat_offset[31:16], xlat_offset[15:0] };
421
    else if(address_bits_transform)                 rd_address_effective <= { {16{rd_address_32bit}} & address_bits_transform_sum[31:16], address_bits_transform_sum[15:0] };
422
    else                                            rd_address_effective <= address_effective_modrm;
423
end
424
 
425
//------------------------------------------------------------------------------
426
 
427
// synthesis translate_off
428
wire _unused_ok = &{ 1'b0, ss_cache[63:55], ss_cache[53:0], glob_param_3[31:25], glob_param_3[18:0], rd_decoder[87:56], rd_decoder[7:1], address_bits_transform_reg[3:0], 1'b0 };
429
// synthesis translate_on
430
 
431
//------------------------------------------------------------------------------
432
 
433
endmodule

powered by: WebSVN 2.1.0

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