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

Subversion Repositories zet86

[/] [zet86/] [trunk/] [cores/] [zet/] [rtl/] [fetch.v] - Blame information for rev 55

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 17 zeus
/*
2
 *  Copyright (c) 2008  Zeus Gomez Marmolejo <zeus@opencores.org>
3
 *
4
 *  This file is part of the Zet processor. This processor is free
5
 *  hardware; you can redistribute it and/or modify it under the terms of
6
 *  the GNU General Public License as published by the Free Software
7
 *  Foundation; either version 3, or (at your option) any later version.
8
 *
9 18 zeus
 *  Zet is distrubuted in the hope that it will be useful, but WITHOUT
10
 *  ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
11
 *  or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
12
 *  License for more details.
13 17 zeus
 *
14
 *  You should have received a copy of the GNU General Public License
15 18 zeus
 *  along with Zet; see the file COPYING. If not, see
16 17 zeus
 *  <http://www.gnu.org/licenses/>.
17
 */
18
 
19 2 zeus
`timescale 1ns/10ps
20
 
21
`include "defines.v"
22
 
23
module fetch (
24 21 zeus
`ifdef DEBUG
25
    output reg [2:0] state,
26
    output [2:0] next_state,
27 45 zeus
    output       ext_int,
28
    output       end_seq,
29 21 zeus
`endif
30 40 zeus
    input clk,
31
    input rst,
32
    input [15:0] cs,
33
    input [15:0] ip,
34 2 zeus
    input of,
35
    input zf,
36
    input cx_zero,
37 40 zeus
    input [15:0] data,
38 2 zeus
    output [`IR_SIZE-1:0] ir,
39
    output [15:0] off,
40
    output [15:0] imm,
41
    output [19:0] pc,
42 40 zeus
    output bytefetch,
43 2 zeus
    output fetch_or_exec,
44 35 zeus
    input  block,
45 30 zeus
    input  div_exc,
46 42 zeus
    output wr_ip0,
47
    input  intr,
48 45 zeus
    input  ifl,
49 42 zeus
    output inta
50 2 zeus
  );
51
 
52
  // Registers, nets and parameters
53
  parameter opcod_st = 3'h0;
54
  parameter modrm_st = 3'h1;
55
  parameter offse_st = 3'h2;
56
  parameter immed_st = 3'h3;
57
  parameter execu_st = 3'h4;
58
 
59 21 zeus
`ifndef DEBUG
60 45 zeus
  reg  [2:0] state;
61 21 zeus
  wire [2:0] next_state;
62 45 zeus
  wire       end_seq;
63
  wire       ext_int;
64 21 zeus
`endif
65
 
66 2 zeus
  wire [`IR_SIZE-1:0] rom_ir;
67
  wire [7:0] opcode, modrm;
68 45 zeus
  wire exec_st;
69 2 zeus
  wire [15:0] imm_d;
70 32 zeus
  wire prefix, repz_pr, sovr_pr;
71 2 zeus
  wire next_in_opco, next_in_exec;
72
  wire need_modrm, need_off, need_imm, off_size, imm_size;
73
 
74
  reg [7:0] opcode_l, modrm_l;
75
  reg [15:0] off_l, imm_l;
76
  reg [1:0] pref_l;
77 32 zeus
  reg [2:0] sop_l;
78 2 zeus
 
79
  // Module instantiation
80 30 zeus
  decode decode0(opcode, modrm, off_l, imm_l, pref_l[1], clk, rst, block,
81
                 exec_st, div_exc, need_modrm, need_off, need_imm, off_size,
82 45 zeus
                 imm_size, rom_ir, off, imm_d, end_seq, sop_l, intr, ifl,
83
                 inta, ext_int, pref_l[1]);
84 42 zeus
  next_or_not nn0(pref_l, opcode[7:1], cx_zero, zf, ext_int, next_in_opco,
85 2 zeus
                  next_in_exec);
86
  nstate ns0(state, prefix, need_modrm, need_off, need_imm, end_seq,
87 30 zeus
             rom_ir[28:23], of, next_in_opco, next_in_exec, block, div_exc,
88 45 zeus
             intr, ifl, next_state);
89 2 zeus
 
90
  // Assignments
91
  assign pc = (cs << 4) + ip;
92
 
93
  assign ir     = (state == execu_st) ? rom_ir : `ADD_IP;
94 42 zeus
  assign opcode = (state == opcod_st) ? data[7:0] : opcode_l;
95 2 zeus
  assign modrm  = (state == modrm_st) ? data[7:0] : modrm_l;
96
  assign fetch_or_exec = (state == execu_st);
97 40 zeus
  assign bytefetch = (state == offse_st) ? ~off_size
98
                   : ((state == immed_st) ? ~imm_size : 1'b1);
99 2 zeus
  assign exec_st = (state == execu_st);
100 30 zeus
  assign imm = (state == execu_st) ? imm_d
101 40 zeus
              : (((state == offse_st) & off_size
102 2 zeus
                | (state == immed_st) & imm_size) ? 16'd2
103 30 zeus
              : 16'd1);
104 32 zeus
  assign wr_ip0 = (state == opcod_st) && !pref_l[1] && !sop_l[2];
105 2 zeus
 
106 32 zeus
  assign sovr_pr = (opcode[7:5]==3'b001 && opcode[2:0]==3'b110);
107
  assign repz_pr = (opcode[7:1]==7'b1111_001);
108
  assign prefix  = sovr_pr || repz_pr;
109 30 zeus
 
110 2 zeus
  // Behaviour
111
  always @(posedge clk)
112 40 zeus
    if (rst)
113 2 zeus
      begin
114
        state <= execu_st;
115
        opcode_l <= `OP_NOP;
116
      end
117
    else if (!block)
118
      case (next_state)
119
        default:  // opcode or prefix
120
          begin
121
            case (state)
122 32 zeus
              opcod_st:
123
                begin // There has been a prefix
124
                  pref_l <= repz_pr ? { 1'b1, opcode[0] } : pref_l;
125
                  sop_l  <= sovr_pr ? { 1'b1, opcode[4:3] } : sop_l;
126
                end
127
              default: begin pref_l <= 2'b0; sop_l <= 3'b0; end
128 2 zeus
            endcase
129
            state <= opcod_st;
130
            off_l <= 16'd0;
131 32 zeus
            modrm_l <= 8'b0000_0110;
132 2 zeus
          end
133
 
134
        modrm_st:  // modrm
135
          begin
136
            opcode_l  <= data[7:0];
137
            state <= modrm_st;
138
          end
139
 
140
        offse_st:  // offset
141
          begin
142
            case (state)
143
              opcod_st: opcode_l <= data[7:0];
144
              default: modrm_l <= data[7:0];
145
            endcase
146
            state <= offse_st;
147
          end
148
 
149
        immed_st:  // immediate
150
          begin
151
            case (state)
152
              opcod_st: opcode_l <= data[7:0];
153
              modrm_st: modrm_l <= data[7:0];
154
              default: off_l <= data;
155
            endcase
156
            state <= immed_st;
157
          end
158
 
159
        execu_st:  // execute
160
          begin
161
            case (state)
162
              opcod_st: opcode_l <= data[7:0];
163
              modrm_st: modrm_l <= data[7:0];
164
              offse_st: off_l <= data;
165
              immed_st: imm_l <= data;
166
            endcase
167
            state <= execu_st;
168
          end
169
      endcase
170
endmodule
171
 
172
module nstate (
173
    input [2:0] state,
174
    input prefix,
175
    input need_modrm,
176
    input need_off,
177
    input need_imm,
178
    input end_seq,
179
    input [5:0] ftype,
180
    input of,
181
    input next_in_opco,
182
    input next_in_exec,
183
    input block,
184 30 zeus
    input div_exc,
185 42 zeus
    input intr,
186 45 zeus
    input ifl,
187 2 zeus
    output [2:0] next_state
188
  );
189
 
190
  // Net declarations
191
  parameter opcod_st = 3'h0;
192
  parameter modrm_st = 3'h1;
193
  parameter offse_st = 3'h2;
194
  parameter immed_st = 3'h3;
195
  parameter execu_st = 3'h4;
196
  wire into, end_instr, end_into;
197
  wire [2:0] n_state;
198 45 zeus
  wire       intr_ifl;
199 2 zeus
 
200
  // Assignments
201
  assign into = (ftype==6'b111_010);
202
  assign end_into = into ? ~of : end_seq;
203 45 zeus
  assign end_instr = !div_exc && !intr_ifl && end_into && !next_in_exec;
204
  assign intr_ifl = intr & ifl;
205 2 zeus
 
206 40 zeus
  assign n_state = (state == opcod_st) ? (prefix ? opcod_st
207 2 zeus
                         : (next_in_opco ? opcod_st
208 40 zeus
                         : (need_modrm ? modrm_st
209
                         : (need_off ? offse_st
210 2 zeus
                         : (need_imm ? immed_st : execu_st)))))
211 40 zeus
                     : (state == modrm_st) ? (need_off ? offse_st
212 2 zeus
                                           : (need_imm ? immed_st : execu_st))
213
                     : (state == offse_st) ? (need_imm ? immed_st : execu_st)
214
                     : (state == immed_st) ? (execu_st)
215 42 zeus
   /* state == execu_st */ : (end_instr ? opcod_st : execu_st);
216 2 zeus
 
217
  assign next_state = block ? state : n_state;
218
endmodule
219
 
220
module next_or_not (
221
    input [1:0] prefix,
222
    input [7:1] opcode,
223
    input cx_zero,
224
    input zf,
225 42 zeus
    input ext_int,
226 2 zeus
    output next_in_opco,
227
    output next_in_exec
228
  );
229
 
230
  // Net declarations
231
  wire exit_z, cmp_sca, exit_rep, valid_ops;
232
 
233
  // Assignments
234
  assign cmp_sca = opcode[2] & opcode[1];
235
  assign exit_z = prefix[0] ? /* repz */ (cmp_sca ? ~zf : 1'b0 )
236
                            : /* repnz */ (cmp_sca ? zf : 1'b0 );
237
  assign exit_rep = cx_zero | exit_z;
238
  assign valid_ops = (opcode[7:1]==7'b1010_010   // movs
239 42 zeus
                   || opcode[7:1]==7'b1010_011   // cmps
240
                   || opcode[7:1]==7'b1010_101   // stos
241
                   || opcode[7:1]==7'b1010_110   // lods
242
                   || opcode[7:1]==7'b1010_111); // scas
243
  assign next_in_exec = prefix[1] && valid_ops && !exit_rep && !ext_int;
244 2 zeus
  assign next_in_opco = prefix[1] && valid_ops && cx_zero;
245
endmodule
246
 
247
module decode (
248
    input [7:0] opcode,
249
    input [7:0] modrm,
250
    input [15:0] off_i,
251
    input [15:0] imm_i,
252 15 zeus
    input       rep,
253 2 zeus
    input clk,
254
    input rst,
255
    input block,
256
    input exec_st,
257 30 zeus
    input div_exc,
258 2 zeus
 
259
    output need_modrm,
260
    output need_off,
261
    output need_imm,
262
    output off_size,
263
    output imm_size,
264
 
265
    output [`IR_SIZE-1:0] ir,
266
    output [15:0] off_o,
267
    output [15:0] imm_o,
268 30 zeus
    output end_seq,
269 32 zeus
 
270 42 zeus
    input  [2:0] sop_l,
271
 
272
    input        intr,
273 45 zeus
    input        ifl,
274 42 zeus
    output reg   inta,
275
    output reg   ext_int,
276
    input        repz_pr
277 2 zeus
  );
278
 
279
  // Net declarations
280
  wire [`SEQ_ADDR_WIDTH-1:0] base_addr, seq_addr;
281
  wire [`SEQ_DATA_WIDTH-2:0] micro_addr;
282
  wire [3:0] src, dst, base, index;
283
  wire [1:0] seg;
284
  reg  [`SEQ_ADDR_WIDTH-1:0] seq;
285 37 zeus
  reg  dive;
286 52 zeus
  reg  old_ext_int;
287 2 zeus
 
288
  // Module instantiations
289 40 zeus
  opcode_deco opcode_deco0 (opcode, modrm, rep, sop_l, base_addr, need_modrm,
290
                            need_off, need_imm, off_size, imm_size, src, dst,
291 2 zeus
                            base, index, seg);
292
  seq_rom seq_rom0 (seq_addr, {end_seq, micro_addr});
293
  micro_data mdata0 (micro_addr, off_i, imm_i, src, dst, base, index, seg,
294
                     ir, off_o, imm_o);
295
 
296
  // Assignments
297 42 zeus
  assign seq_addr = (dive ? `INTD
298
    : (ext_int ? (repz_pr ? `EINTP : `EINT) : base_addr)) + seq;
299 2 zeus
 
300
  // Behaviour
301 30 zeus
  // seq
302 2 zeus
  always @(posedge clk)
303
    if (rst) seq <= `SEQ_ADDR_WIDTH'd0;
304
    else if (!block)
305 40 zeus
      seq <= (exec_st && !end_seq && !rst) ? (seq + `SEQ_ADDR_WIDTH'd1)
306 2 zeus
                                : `SEQ_ADDR_WIDTH'd0;
307 30 zeus
  // dive
308
  always @(posedge clk)
309
    if (rst) dive <= 1'b0;
310 42 zeus
    else dive <= block ? dive
311
     : (div_exc ? 1'b1 : (dive ? !end_seq : 1'b0));
312
 
313
  // ext_int
314
  always @(posedge clk)
315
    if (rst) ext_int <= 1'b0;
316
    else ext_int <= block ? ext_int
317 45 zeus
      : ((intr & ifl & exec_st & end_seq) ? 1'b1
318 42 zeus
        : (ext_int ? !end_seq : 1'b0));
319
 
320 52 zeus
  // old_ext_int
321
  always @(posedge clk) old_ext_int <= rst ? 1'b0 : ext_int;
322
 
323 42 zeus
  // inta
324
  always @(posedge clk)
325 52 zeus
    inta <= rst ? 1'b0 : (!old_ext_int & ext_int);
326 42 zeus
 
327 2 zeus
endmodule
328
 
329
module opcode_deco (
330 40 zeus
    input [7:0] op,
331 2 zeus
    input [7:0] modrm,
332 15 zeus
    input       rep,
333 32 zeus
    input [2:0] sovr_pr,
334 2 zeus
 
335
    output reg [`SEQ_ADDR_WIDTH-1:0] seq_addr,
336
    output reg need_modrm,
337
    output reg need_off,
338
    output reg need_imm,
339 40 zeus
    output     off_size,
340 2 zeus
    output reg imm_size,
341
 
342
    output reg [3:0] src,
343
    output reg [3:0] dst,
344
    output [3:0] base,
345
    output [3:0] index,
346
    output [1:0] seg
347
  );
348
 
349
  // Net declarations
350
  wire [1:0] mod;
351
  wire [2:0] regm;
352
  wire [2:0] rm;
353
  wire       d, b, sm, dm;
354
  wire       off_size_mod, need_off_mod;
355
  wire [2:0] srcm, dstm;
356 40 zeus
  wire       off_size_from_mod;
357 2 zeus
 
358
  // Module instantiations
359 32 zeus
  memory_regs mr(rm, mod, sovr_pr, base, index, seg);
360 2 zeus
 
361
  // Assignments
362
  assign mod  = modrm[7:6];
363
  assign regm = modrm[5:3];
364
  assign rm   = modrm[2:0];
365 40 zeus
  assign d    = op[1];
366 2 zeus
  assign dstm = d ? regm : rm;
367
  assign sm   = d & (mod != 2'b11);
368
  assign dm   = ~d & (mod != 2'b11);
369
  assign srcm = d ? rm : regm;
370 40 zeus
  assign b    = ~op[0];
371 2 zeus
  assign off_size_mod = (base == 4'b1100 && index == 4'b1100) ? 1'b1 : mod[1];
372
  assign need_off_mod = (base == 4'b1100 && index == 4'b1100) || ^mod;
373 40 zeus
  assign off_size_from_mod = !op[7] | (!op[5] & !op[4]) | (op[6] & op[4]);
374
  assign off_size = !off_size_from_mod | off_size_mod;
375 2 zeus
 
376
  // Behaviour
377 40 zeus
  always @(op or dm or b or need_off_mod or srcm or sm or dstm
378 45 zeus
           or mod or rm or regm or rep or modrm)
379 40 zeus
    casex (op)
380 27 zeus
      8'b0000_000x: // add r->r, r->m
381
        begin
382
          seq_addr   <= (mod==2'b11) ? (b ? `ADDRRB : `ADDRRW)
383
                                     : (b ? `ADDRMB : `ADDRMW);
384
          need_modrm <= 1'b1;
385
          need_off   <= need_off_mod;
386
          need_imm   <= 1'b0;
387
          imm_size   <= 1'b0;
388
          dst        <= { 1'b0, dstm };
389
          src        <= { 1'b0, srcm };
390
        end
391
 
392
      8'b0000_001x: // add r->r, m->r
393
        begin
394
          seq_addr   <= (mod==2'b11) ? (b ? `ADDRRB : `ADDRRW)
395
                                     : (b ? `ADDMRB : `ADDMRW);
396
          need_modrm <= 1'b1;
397
          need_off   <= need_off_mod;
398
          need_imm   <= 1'b0;
399
          imm_size   <= 1'b0;
400
          dst        <= { 1'b0, dstm };
401
          src        <= { 1'b0, srcm };
402
        end
403
 
404
      8'b0000_010x: // add i->r
405
        begin
406
          seq_addr   <= b ? `ADDIRB : `ADDIRW;
407
          need_modrm <= 1'b0;
408
          need_off   <= 1'b0;
409
          need_imm   <= 1'b1;
410
          imm_size   <= ~b;
411
          dst        <= 4'b0;
412
          src        <= 4'b0;
413
        end
414
 
415 2 zeus
      8'b000x_x110: // push seg
416
        begin
417
          seq_addr <= `PUSHR;
418
          need_modrm <= 1'b0;
419
          need_off <= 1'b0;
420
          need_imm <= 1'b0;
421 21 zeus
          imm_size <= 1'b0;
422 40 zeus
          src <= { 2'b10, op[4:3] };
423 21 zeus
          dst <= 4'b0;
424 2 zeus
        end
425
 
426 19 zeus
      8'b0000_100x: // or r->r, r->m
427
        begin
428
          seq_addr   <= (mod==2'b11) ? (b ? `ORRRB : `ORRRW)
429
                                     : (b ? `ORRMB : `ORRMW);
430
          need_modrm <= 1'b1;
431
          need_off   <= need_off_mod;
432
          need_imm   <= 1'b0;
433
          imm_size   <= 1'b0;
434
          dst        <= { 1'b0, dstm };
435
          src        <= { 1'b0, srcm };
436
        end
437
 
438
      8'b0000_101x: // or r->r, m->r
439
        begin
440
          seq_addr   <= (mod==2'b11) ? (b ? `ORRRB : `ORRRW)
441
                                     : (b ? `ORMRB : `ORMRW);
442
          need_modrm <= 1'b1;
443
          need_off   <= need_off_mod;
444
          need_imm   <= 1'b0;
445
          imm_size   <= 1'b0;
446
          dst        <= { 1'b0, dstm };
447
          src        <= { 1'b0, srcm };
448
        end
449
 
450
      8'b0000_110x: // or i->r
451
        begin
452
          seq_addr   <= b ? `ORIRB : `ORIRW;
453
          need_modrm <= 1'b0;
454
          need_off   <= 1'b0;
455
          need_imm   <= 1'b1;
456
          imm_size   <= ~b;
457
          dst        <= 4'b0;
458
          src        <= 4'b0;
459
        end
460
 
461 2 zeus
      8'b000x_x111: // pop seg
462
        begin
463
          seq_addr <= `POPR;
464
          need_modrm <= 1'b0;
465
          need_off <= 1'b0;
466
          need_imm <= 1'b0;
467 21 zeus
          imm_size <= 1'b0;
468
          src      <= 4'b0;
469 40 zeus
          dst      <= { 2'b10, op[4:3] };
470 2 zeus
        end
471
 
472 27 zeus
      8'b0001_000x: // adc r->r, r->m
473
        begin
474
          seq_addr   <= (mod==2'b11) ? (b ? `ADCRRB : `ADCRRW)
475
                                     : (b ? `ADCRMB : `ADCRMW);
476
          need_modrm <= 1'b1;
477
          need_off   <= need_off_mod;
478
          need_imm   <= 1'b0;
479
          imm_size   <= 1'b0;
480
          dst        <= { 1'b0, dstm };
481
          src        <= { 1'b0, srcm };
482
        end
483
 
484
      8'b0001_001x: // adc r->r, m->r
485
        begin
486
          seq_addr   <= (mod==2'b11) ? (b ? `ADCRRB : `ADCRRW)
487
                                     : (b ? `ADCMRB : `ADCMRW);
488
          need_modrm <= 1'b1;
489
          need_off   <= need_off_mod;
490
          need_imm   <= 1'b0;
491
          imm_size   <= 1'b0;
492
          dst        <= { 1'b0, dstm };
493
          src        <= { 1'b0, srcm };
494
        end
495
 
496
      8'b0001_010x: // adc i->r
497
        begin
498
          seq_addr   <= b ? `ADCIRB : `ADCIRW;
499
          need_modrm <= 1'b0;
500
          need_off   <= 1'b0;
501
          need_imm   <= 1'b1;
502
          imm_size   <= ~b;
503
          dst        <= 4'b0;
504
          src        <= 4'b0;
505
        end
506
 
507
      8'b0001_100x: // sbb r->r, r->m
508
        begin
509
          seq_addr   <= (mod==2'b11) ? (b ? `SBBRRB : `SBBRRW)
510
                                     : (b ? `SBBRMB : `SBBRMW);
511
          need_modrm <= 1'b1;
512
          need_off   <= need_off_mod;
513
          need_imm   <= 1'b0;
514
          imm_size   <= 1'b0;
515
          dst        <= { 1'b0, dstm };
516
          src        <= { 1'b0, srcm };
517
        end
518
 
519
      8'b0001_101x: // sbb r->r, m->r
520
        begin
521
          seq_addr   <= (mod==2'b11) ? (b ? `SBBRRB : `SBBRRW)
522
                                     : (b ? `SBBMRB : `SBBMRW);
523
          need_modrm <= 1'b1;
524
          need_off   <= need_off_mod;
525
          need_imm   <= 1'b0;
526
          imm_size   <= 1'b0;
527
          dst        <= { 1'b0, dstm };
528
          src        <= { 1'b0, srcm };
529
        end
530
 
531
      8'b0001_110x: // sbb i->r
532
        begin
533
          seq_addr   <= b ? `SBBIRB : `SBBIRW;
534
          need_modrm <= 1'b0;
535
          need_off   <= 1'b0;
536
          need_imm   <= 1'b1;
537
          imm_size   <= ~b;
538
          dst        <= 4'b0;
539
          src        <= 4'b0;
540
        end
541
 
542 19 zeus
      8'b0010_000x: // and r->r, r->m
543
        begin
544
          seq_addr   <= (mod==2'b11) ? (b ? `ANDRRB : `ANDRRW)
545
                                     : (b ? `ANDRMB : `ANDRMW);
546
          need_modrm <= 1'b1;
547
          need_off   <= need_off_mod;
548
          need_imm   <= 1'b0;
549
          imm_size   <= 1'b0;
550
          dst        <= { 1'b0, dstm };
551
          src        <= { 1'b0, srcm };
552
        end
553
 
554
      8'b0010_001x: // and r->r, m->r
555
        begin
556
          seq_addr   <= (mod==2'b11) ? (b ? `ANDRRB : `ANDRRW)
557
                                     : (b ? `ANDMRB : `ANDMRW);
558
          need_modrm <= 1'b1;
559
          need_off   <= need_off_mod;
560
          need_imm   <= 1'b0;
561
          imm_size   <= 1'b0;
562
          dst        <= { 1'b0, dstm };
563
          src        <= { 1'b0, srcm };
564
        end
565
 
566
      8'b0010_010x: // and i->r
567
        begin
568
          seq_addr   <= b ? `ANDIRB : `ANDIRW;
569
          need_modrm <= 1'b0;
570
          need_off   <= 1'b0;
571
          need_imm   <= 1'b1;
572
          imm_size   <= ~b;
573
          dst        <= 4'b0;
574
          src        <= 4'b0;
575
        end
576
 
577 26 zeus
      8'b0010_0111: // daa
578
        begin
579
          seq_addr   <= `DAA;
580
          need_modrm <= 1'b0;
581
          need_off   <= 1'b0;
582
          need_imm   <= 1'b0;
583
          imm_size   <= 1'b0;
584
          dst        <= 4'b0;
585
          src        <= 4'b0;
586
        end
587
 
588 27 zeus
      8'b0010_100x: // sub r->r, r->m
589
        begin
590
          seq_addr   <= (mod==2'b11) ? (b ? `SUBRRB : `SUBRRW)
591
                                     : (b ? `SUBRMB : `SUBRMW);
592
          need_modrm <= 1'b1;
593
          need_off   <= need_off_mod;
594
          need_imm   <= 1'b0;
595
          imm_size   <= 1'b0;
596
          dst        <= { 1'b0, dstm };
597
          src        <= { 1'b0, srcm };
598
        end
599
 
600
      8'b0010_101x: // sub r->r, m->r
601
        begin
602
          seq_addr   <= (mod==2'b11) ? (b ? `SUBRRB : `SUBRRW)
603
                                     : (b ? `SUBMRB : `SUBMRW);
604
          need_modrm <= 1'b1;
605
          need_off   <= need_off_mod;
606
          need_imm   <= 1'b0;
607
          imm_size   <= 1'b0;
608
          dst        <= { 1'b0, dstm };
609
          src        <= { 1'b0, srcm };
610
        end
611
 
612
      8'b0010_110x: // sub i->r
613
        begin
614
          seq_addr   <= b ? `SUBIRB : `SUBIRW;
615
          need_modrm <= 1'b0;
616
          need_off   <= 1'b0;
617
          need_imm   <= 1'b1;
618
          imm_size   <= ~b;
619
          dst        <= 4'b0;
620
          src        <= 4'b0;
621
        end
622
 
623 26 zeus
      8'b0010_1111: // das
624
        begin
625
          seq_addr   <= `DAS;
626
          need_modrm <= 1'b0;
627
          need_off   <= 1'b0;
628
          need_imm   <= 1'b0;
629
          imm_size   <= 1'b0;
630
          dst        <= 4'b0;
631
          src        <= 4'b0;
632
        end
633
 
634 19 zeus
      8'b0011_000x: // xor r->r, r->m
635
        begin
636
          seq_addr   <= (mod==2'b11) ? (b ? `XORRRB : `XORRRW)
637
                                     : (b ? `XORRMB : `XORRMW);
638
          need_modrm <= 1'b1;
639
          need_off   <= need_off_mod;
640
          need_imm   <= 1'b0;
641
          imm_size   <= 1'b0;
642
          dst        <= { 1'b0, dstm };
643
          src        <= { 1'b0, srcm };
644
        end
645
 
646
      8'b0011_001x: // xor r->r, m->r
647
        begin
648
          seq_addr   <= (mod==2'b11) ? (b ? `XORRRB : `XORRRW)
649
                                     : (b ? `XORMRB : `XORMRW);
650
          need_modrm <= 1'b1;
651
          need_off   <= need_off_mod;
652
          need_imm   <= 1'b0;
653
          imm_size   <= 1'b0;
654
          dst        <= { 1'b0, dstm };
655
          src        <= { 1'b0, srcm };
656
        end
657
 
658
      8'b0011_010x: // and i->r
659
        begin
660
          seq_addr   <= b ? `XORIRB : `XORIRW;
661
          need_modrm <= 1'b0;
662
          need_off   <= 1'b0;
663
          need_imm   <= 1'b1;
664
          imm_size   <= ~b;
665
          dst        <= 4'b0;
666
          src        <= 4'b0;
667
        end
668
 
669 26 zeus
      8'b0011_0111: // aaa
670
        begin
671
          seq_addr   <= `AAA;
672
          need_modrm <= 1'b0;
673
          need_off   <= 1'b0;
674
          need_imm   <= 1'b0;
675
          imm_size   <= 1'b0;
676
          dst        <= 4'b0;
677
          src        <= 4'b0;
678
        end
679
 
680 28 zeus
      8'b0011_100x: // cmp r->r, r->m
681
        begin
682
          seq_addr   <= (mod==2'b11) ? (b ? `CMPRRB : `CMPRRW)
683
                                     : (b ? `CMPRMB : `CMPRMW);
684
          need_modrm <= 1'b1;
685
          need_off   <= need_off_mod;
686
          need_imm   <= 1'b0;
687
          imm_size   <= 1'b0;
688
          dst        <= { 1'b0, dstm };
689
          src        <= { 1'b0, srcm };
690
        end
691
 
692
      8'b0011_101x: // cmp r->r, m->r
693
        begin
694
          seq_addr   <= (mod==2'b11) ? (b ? `CMPRRB : `CMPRRW)
695
                                     : (b ? `CMPMRB : `CMPMRW);
696
          need_modrm <= 1'b1;
697
          need_off   <= need_off_mod;
698
          need_imm   <= 1'b0;
699
          imm_size   <= 1'b0;
700
          dst        <= { 1'b0, dstm };
701
          src        <= { 1'b0, srcm };
702
        end
703
 
704
      8'b0011_110x: // cmp i->r
705
        begin
706
          seq_addr   <= b ? `CMPIRB : `CMPIRW;
707
          need_modrm <= 1'b0;
708
          need_off   <= 1'b0;
709
          need_imm   <= 1'b1;
710
          imm_size   <= ~b;
711
          dst        <= 4'b0;
712
          src        <= 4'b0;
713
        end
714
 
715 26 zeus
      8'b0011_1111: // aas
716
        begin
717
          seq_addr   <= `AAS;
718
          need_modrm <= 1'b0;
719
          need_off   <= 1'b0;
720
          need_imm   <= 1'b0;
721
          imm_size   <= 1'b0;
722
          dst        <= 4'b0;
723
          src        <= 4'b0;
724
        end
725
 
726 27 zeus
      8'b0100_0xxx: // inc
727
        begin
728
          seq_addr   <= `INCRW;
729
          need_modrm <= 1'b0;
730
          need_off   <= 1'b0;
731
          need_imm   <= 1'b0;
732
          imm_size   <= 1'b0;
733
          dst        <= 4'b0;
734 40 zeus
          src        <= { 1'b0, op[2:0] };
735 27 zeus
        end
736
 
737
      8'b0100_1xxx: // dec
738
        begin
739
          seq_addr   <= `DECRW;
740
          need_modrm <= 1'b0;
741
          need_off   <= 1'b0;
742
          need_imm   <= 1'b0;
743
          imm_size   <= 1'b0;
744
          dst        <= 4'b0;
745 40 zeus
          src        <= { 1'b0, op[2:0] };
746 27 zeus
        end
747
 
748 2 zeus
      8'b0101_0xxx: // push reg
749
        begin
750
          seq_addr <= `PUSHR;
751
          need_modrm <= 1'b0;
752
          need_off <= 1'b0;
753
          need_imm <= 1'b0;
754 21 zeus
          imm_size <= 1'b0;
755 40 zeus
          src <= { 1'b0, op[2:0] };
756 21 zeus
          dst <= 4'b0;
757 2 zeus
        end
758
 
759
      8'b0101_1xxx: // pop reg
760
        begin
761
          seq_addr <= `POPR;
762
          need_modrm <= 1'b0;
763
          need_off <= 1'b0;
764
          need_imm <= 1'b0;
765 21 zeus
          imm_size <= 1'b0;
766
          src <= 4'b0;
767 40 zeus
          dst <= { 1'b0, op[2:0] };
768 2 zeus
        end
769
 
770
      8'b0111_xxxx: // jcc
771
        begin
772
          seq_addr <= `JCC;
773
          need_modrm <= 1'b0;
774
          need_off <= 1'b0;
775
          need_imm <= 1'b1;
776
          imm_size <= 1'b0;
777 40 zeus
          src <= { op[3:0] };
778 21 zeus
          dst <= 4'b0;
779 2 zeus
        end
780
 
781 27 zeus
      8'b1000_00xx: // and, or i->r, i->m
782 19 zeus
        begin
783 28 zeus
          seq_addr   <= regm == 3'b111 ?
784
             ((mod==2'b11) ? (b ? `CMPIRB : `CMPIRW)
785
                           : (b ? `CMPIMB : `CMPIMW))
786
           : (regm == 3'b101 ? ((mod==2'b11) ? (b ? `SUBIRB : `SUBIRW)
787 27 zeus
                          : (b ? `SUBIMB : `SUBIMW))
788
           : (regm == 3'b011 ? ((mod==2'b11) ? (b ? `SBBIRB : `SBBIRW)
789
                          : (b ? `SBBIMB : `SBBIMW))
790
           : (regm == 3'b010 ? ((mod==2'b11) ? (b ? `ADCIRB : `ADCIRW)
791
                          : (b ? `ADCIMB : `ADCIMW))
792
           : (regm == 3'b000 ? ((mod==2'b11) ? (b ? `ADDIRB : `ADDIRW)
793
                          : (b ? `ADDIMB : `ADDIMW))
794
           : (regm == 3'b100 ? ((mod==2'b11) ? (b ? `ANDIRB : `ANDIRW)
795 19 zeus
                             : (b ? `ANDIMB : `ANDIMW))
796
           : (regm == 3'b001 ? ((mod==2'b11) ? (b ? `ORIRB : `ORIRW)
797
                                             : (b ? `ORIMB : `ORIMW))
798
           : ((mod==2'b11) ? (b ? `XORIRB : `XORIRW)
799 28 zeus
                           : (b ? `XORIMB : `XORIMW))))))));
800 19 zeus
          need_modrm <= 1'b1;
801
          need_off   <= need_off_mod;
802
          need_imm   <= 1'b1;
803 45 zeus
          imm_size   <= !op[1] & op[0];
804 27 zeus
          dst        <= { 1'b0, modrm[2:0] };
805 19 zeus
          src        <= 4'b0;
806
        end
807
 
808
      8'b1000_010x: // test r->r, r->m
809
        begin
810
          seq_addr   <= (mod==2'b11) ? (b ? `TSTRRB : `TSTRRW)
811
                                     : (b ? `TSTMRB : `TSTMRW);
812
          need_modrm <= 1'b1;
813
          need_off   <= need_off_mod;
814
          need_imm   <= 1'b0;
815
          imm_size   <= 1'b0;
816
          dst        <= { 1'b0, srcm };
817
          src        <= { 1'b0, dstm };
818
        end
819
 
820 2 zeus
      8'b1000_011x: // xchg
821
        begin
822
          seq_addr <= (mod==2'b11) ? (b ? `XCHRRB : `XCHRRW)
823
                                   : (b ? `XCHRMB : `XCHRMW);
824
          need_modrm <= 1'b1;
825
          need_off <= need_off_mod;
826
          need_imm <= 1'b0;
827 21 zeus
          imm_size <= 1'b0;
828 2 zeus
          dst <= { 1'b0, dstm };
829
          src <= { 1'b0, srcm };
830
        end
831
      8'b1000_10xx: // mov: r->r, r->m, m->r
832
        begin
833
          if (dm)   // r->m
834
            begin
835
              seq_addr <= b ? `MOVRMB : `MOVRMW;
836
              need_off <= need_off_mod;
837
              src <= { 1'b0, srcm };
838
              dst <= 4'b0;
839
            end
840
          else if(sm) // m->r
841
            begin
842
              seq_addr <= b ? `MOVMRB : `MOVMRW;
843
              need_off <= need_off_mod;
844
              src <= 4'b0;
845
              dst <= { 1'b0, dstm };
846
            end
847
          else     // r->r
848
            begin
849
              seq_addr <= b ? `MOVRRB : `MOVRRW;
850
              need_off <= 1'b0;
851
              dst <= { 1'b0, dstm };
852
              src <= { 1'b0, srcm };
853
            end
854
          need_imm <= 1'b0;
855
          need_modrm <= 1'b1;
856
          imm_size <= 1'b0;
857
        end
858
 
859
      8'b1000_1100: // mov: s->m, s->r
860
        begin
861
          if (dm)   // s->m
862
            begin
863
              seq_addr <= `MOVRMW;
864
              need_off <= need_off_mod;
865
              src <= { 1'b1, srcm };
866
              dst <= 4'b0;
867
            end
868
          else     // s->r
869
            begin
870
              seq_addr <= `MOVRRW;
871
              need_off <= 1'b0;
872
              src <= { 1'b1, srcm };
873
              dst <= { 1'b0, dstm };
874
            end
875
          need_imm <= 1'b0;
876
          need_modrm <= 1'b1;
877
          imm_size <= 1'b0;
878
        end
879 15 zeus
 
880 2 zeus
      8'b1000_1101: // lea
881
        begin
882
          seq_addr <= `LEA;
883
          need_modrm <= 1'b1;
884
          need_off <= need_off_mod;
885
          need_imm <= 1'b0;
886 21 zeus
          imm_size <= 1'b0;
887 2 zeus
          src <= { 1'b0, srcm };
888 21 zeus
          dst <= 4'b0;
889 2 zeus
        end
890 15 zeus
 
891 2 zeus
      8'b1000_1110: // mov: m->s, r->s
892
        begin
893
          if (sm)   // m->s
894
            begin
895
              seq_addr <= `MOVMRW;
896
              need_off <= need_off_mod;
897
              src <= 4'b0;
898
              dst <= { 1'b1, dstm };
899
            end
900
          else     // r->s
901
            begin
902
              seq_addr <= `MOVRRW;
903
              need_off <= 1'b0;
904
              src <= { 1'b0, srcm };
905
              dst <= { 1'b1, dstm };
906
            end
907
          need_modrm <= 1'b1;
908
          need_imm <= 1'b0;
909
          imm_size <= 1'b0;
910
        end
911 15 zeus
 
912 2 zeus
      8'b1000_1111: // pop mem or (pop reg non-standard)
913
        begin
914
          seq_addr <= (mod==2'b11) ? `POPR : `POPM;
915
          need_modrm <= 1'b1;
916
          need_off <= need_off_mod;
917
          need_imm <= 1'b0;
918 21 zeus
          imm_size <= 1'b0;
919
          src <= 4'b0;
920 2 zeus
          dst <= { 1'b0, rm };
921
        end
922
 
923 52 zeus
      8'b1001_0xxx: // nop, xchg acum
924 2 zeus
        begin
925
          seq_addr <= `XCHRRW;
926
          need_modrm <= 1'b0;
927
          need_off <= 1'b0;
928
          need_imm <= 1'b0;
929 21 zeus
          imm_size <= 1'b0;
930 2 zeus
          src <= 4'b0000;
931 40 zeus
          dst <= { 1'b0, op[2:0] };
932 2 zeus
        end
933
 
934 26 zeus
      8'b1001_1000: // cbw
935
        begin
936
          seq_addr   <= `CBW;
937
          need_modrm <= 1'b0;
938
          need_off   <= 1'b0;
939
          need_imm   <= 1'b0;
940
          imm_size   <= 1'b0;
941
          dst        <= 4'b0;
942
          src        <= 4'b0;
943
        end
944
 
945
      8'b1001_1001: // cwd
946
        begin
947
          seq_addr   <= `CWD;
948
          need_modrm <= 1'b0;
949
          need_off   <= 1'b0;
950
          need_imm   <= 1'b0;
951
          imm_size   <= 1'b0;
952
          dst        <= 4'b0;
953
          src        <= 4'b0;
954
        end
955
 
956 2 zeus
      8'b1001_1010: // call different seg
957
        begin
958
          seq_addr <= `CALLF;
959
          need_modrm <= 1'b0;
960
          need_off <= 1'b1;
961
          need_imm <= 1'b1;
962
          imm_size <= 1'b1;
963 21 zeus
          src <= 4'b0;
964
          dst <= 4'b0;
965 2 zeus
        end
966 15 zeus
 
967 2 zeus
      8'b1001_1100: // pushf
968
        begin
969
          seq_addr <= `PUSHF;
970
          need_modrm <= 1'b0;
971
          need_off <= 1'b0;
972
          need_imm <= 1'b0;
973
 
974
          imm_size <= 1'b0;
975
 
976
          src <= 4'b0;
977
          dst <= 4'b0;
978
        end
979 15 zeus
 
980 2 zeus
      8'b1001_1101: // popf
981
        begin
982
          seq_addr <= `POPF;
983
          need_modrm <= 1'b0;
984
          need_off <= 1'b0;
985
          need_imm <= 1'b0;
986 21 zeus
          imm_size <= 1'b0;
987
          src <= 4'b0;
988
          dst <= 4'b0;
989 2 zeus
        end
990
 
991
      8'b1001_1110: // sahf
992
        begin
993
          seq_addr <= `SAHF;
994
          need_modrm <= 1'b0;
995
          need_off <= 1'b0;
996
          need_imm <= 1'b0;
997 21 zeus
          imm_size <= 1'b0;
998
          src <= 4'b0;
999
          dst <= 4'b0;
1000
        end
1001 2 zeus
 
1002
      8'b1001_1111: // lahf
1003
        begin
1004
          seq_addr <= `LAHF;
1005
          need_modrm <= 1'b0;
1006
          need_off <= 1'b0;
1007
          need_imm <= 1'b0;
1008 21 zeus
          imm_size <= 1'b0;
1009
          src <= 4'b0;
1010
          dst <= 4'b0;
1011 2 zeus
        end
1012 15 zeus
 
1013 2 zeus
      8'b1010_000x: // mov: m->a
1014
        begin
1015
          seq_addr <= b ? `MOVMAB : `MOVMAW;
1016
          need_modrm <= 1'b0;
1017
          need_off <= 1'b1;
1018
          need_imm <= 1'b0;
1019
          imm_size <= 1'b0;
1020
 
1021
          src <= 4'b0;
1022
          dst <= 4'b0;
1023
        end
1024
 
1025
      8'b1010_001x: // mov: a->m
1026
        begin
1027
          seq_addr <= b ? `MOVAMB : `MOVAMW;
1028
          need_modrm <= 1'b0;
1029
          need_off <= 1'b1;
1030
          need_imm <= 1'b0;
1031
          imm_size <= 1'b0;
1032
 
1033
          src <= 4'b0;
1034
          dst <= 4'b0;
1035
        end
1036 15 zeus
 
1037 2 zeus
      8'b1010_010x: // movs
1038
        begin
1039
          seq_addr <= rep ? (b ? `MOVSBR : `MOVSWR) : (b ? `MOVSB : `MOVSW);
1040
          need_modrm <= 1'b0;
1041
          need_off <= 1'b0;
1042
          need_imm <= 1'b0;
1043 21 zeus
          imm_size <= 1'b0;
1044
          src <= 4'b0;
1045
          dst <= 4'b0;
1046 2 zeus
        end
1047
 
1048
      8'b1010_011x: // cmps
1049
        begin
1050
          seq_addr <= rep ? (b ? `CMPSBR : `CMPSWR) : (b ? `CMPSB : `CMPSW);
1051
          need_modrm <= 1'b0;
1052
          need_off <= 1'b0;
1053
          need_imm <= 1'b0;
1054 21 zeus
          imm_size <= 1'b0;
1055
          src <= 4'b0;
1056
          dst <= 4'b0;
1057 2 zeus
        end
1058
 
1059 19 zeus
      8'b1010_100x: // test i->r
1060
        begin
1061
          seq_addr   <= b ? `TSTIRB : `TSTIRW;
1062
          need_modrm <= 1'b0;
1063
          need_off   <= 1'b0;
1064
          need_imm   <= 1'b1;
1065
          imm_size   <= ~b;
1066
          dst        <= 4'b0;
1067
          src        <= 4'b0;
1068
        end
1069
 
1070 2 zeus
      8'b1010_101x: // stos
1071
        begin
1072
          seq_addr <= rep ? (b ? `STOSBR : `STOSWR) : (b ? `STOSB : `STOSW);
1073
          need_modrm <= 1'b0;
1074
          need_off <= 1'b0;
1075
          need_imm <= 1'b0;
1076 21 zeus
          imm_size <= 1'b0;
1077
          src <= 4'b0;
1078
          dst <= 4'b0;
1079 2 zeus
        end
1080
 
1081
      8'b1010_110x: // lods
1082
        begin
1083
          seq_addr <= rep ? (b ? `LODSBR : `LODSWR) : (b ? `LODSB : `LODSW);
1084
          need_modrm <= 1'b0;
1085
          need_off <= 1'b0;
1086
          need_imm <= 1'b0;
1087 21 zeus
          imm_size <= 1'b0;
1088
          src <= 4'b0;
1089
          dst <= 4'b0;
1090 2 zeus
        end
1091
 
1092
      8'b1010_111x: // scas
1093
        begin
1094
          seq_addr <= rep ? (b ? `SCASBR : `SCASWR) : (b ? `SCASB : `SCASW);
1095
          need_modrm <= 1'b0;
1096
          need_off <= 1'b0;
1097
          need_imm <= 1'b0;
1098 21 zeus
          imm_size <= 1'b0;
1099
          src <= 4'b0;
1100
          dst <= 4'b0;
1101 2 zeus
        end
1102 15 zeus
 
1103 2 zeus
      8'b1011_xxxx: // mov: i->r
1104
        begin
1105 40 zeus
          seq_addr <= op[3] ? `MOVIRW : `MOVIRB;
1106 2 zeus
          need_modrm <= 1'b0;
1107
          need_off <= 1'b0;
1108
          need_imm <= 1'b1;
1109 40 zeus
          imm_size <= op[3];
1110 2 zeus
 
1111
          src <= 4'b0;
1112 40 zeus
          dst <= { 1'b0, op[2:0] };
1113 2 zeus
        end
1114 15 zeus
 
1115 2 zeus
      8'b1100_0010: // ret near with value
1116
        begin
1117
          seq_addr <= `RETNV;
1118
          need_modrm <= 1'b0;
1119
          need_off <= 1'b0;
1120
          need_imm <= 1'b1;
1121
          imm_size <= 1'b1;
1122 21 zeus
          src <= 4'b0;
1123
          dst <= 4'b0;
1124 2 zeus
        end
1125
 
1126
      8'b1100_0011: // ret near
1127
        begin
1128
          seq_addr <= `RETN0;
1129
          need_modrm <= 1'b0;
1130
          need_off <= 1'b0;
1131
          need_imm <= 1'b0;
1132 21 zeus
          imm_size <= 1'b0;
1133
          src <= 4'b0;
1134
          dst <= 4'b0;
1135 2 zeus
        end
1136
 
1137
      8'b1100_0100: // les
1138
        begin
1139
          seq_addr <= `LES;
1140
          need_modrm <= 1'b1;
1141
          need_off <= need_off_mod;
1142
          need_imm <= 1'b0;
1143 21 zeus
          imm_size <= 1'b0;
1144 2 zeus
          src <= { 1'b0, srcm };
1145 21 zeus
          dst <= 4'b0;
1146 2 zeus
        end
1147
 
1148
      8'b1100_0101: // lds
1149
        begin
1150
          seq_addr <= `LDS;
1151
          need_modrm <= 1'b1;
1152
          need_off <= need_off_mod;
1153
          need_imm <= 1'b0;
1154 21 zeus
          imm_size <= 1'b0;
1155 2 zeus
          src <= { 1'b0, srcm };
1156 21 zeus
          dst <= 4'b0;
1157 2 zeus
        end
1158 15 zeus
 
1159 2 zeus
      8'b1100_011x: // mov: i->m (or i->r non-standard)
1160
        begin
1161 40 zeus
          seq_addr <= (mod==2'b11) ? (b ? `MOVIRB : `MOVIRW)
1162 2 zeus
                                   : (b ? `MOVIMB : `MOVIMW);
1163
          need_modrm <= 1'b1;
1164
          need_off <= need_off_mod;
1165
          need_imm <= 1'b1;
1166
          imm_size <= ~b;
1167
 
1168
          src <= 4'b0;
1169
          dst <= { 1'b0, rm };
1170
        end
1171 15 zeus
 
1172 2 zeus
      8'b1100_1010: // ret far with value
1173
        begin
1174
          seq_addr <= `RETFV;
1175
          need_modrm <= 1'b0;
1176
          need_off <= 1'b0;
1177
          need_imm <= 1'b1;
1178
          imm_size <= 1'b1;
1179 21 zeus
          src <= 4'b0;
1180
          dst <= 4'b0;
1181 2 zeus
        end
1182
 
1183
      8'b1100_1011: // ret far
1184
        begin
1185
          seq_addr <= `RETF0;
1186
          need_modrm <= 1'b0;
1187
          need_off <= 1'b0;
1188
          need_imm <= 1'b0;
1189 21 zeus
          imm_size <= 1'b0;
1190
          src <= 4'b0;
1191
          dst <= 4'b0;
1192 2 zeus
        end
1193
 
1194
      8'b1100_1100: // int 3
1195
        begin
1196
          seq_addr <= `INT3;
1197
          need_modrm <= 1'b0;
1198
          need_off <= 1'b0;
1199
          need_imm <= 1'b0;
1200 21 zeus
          imm_size <= 1'b0;
1201
          src <= 4'b0;
1202
          dst <= 4'b0;
1203 2 zeus
        end
1204
 
1205
      8'b1100_1101: // int
1206
        begin
1207
          seq_addr <= `INT;
1208
          need_modrm <= 1'b0;
1209
          need_off <= 1'b0;
1210
          need_imm <= 1'b1;
1211
          imm_size <= 1'b0;
1212 21 zeus
          src <= 4'b0;
1213
          dst <= 4'b0;
1214 2 zeus
        end
1215
 
1216
      8'b1100_1110: // into
1217
        begin
1218
          seq_addr <= `INTO;
1219
          need_modrm <= 1'b0;
1220 40 zeus
          need_off <= 1'b0;
1221 2 zeus
          need_imm <= 1'b0;
1222 21 zeus
          imm_size <= 1'b0;
1223
          src <= 4'b0;
1224
          dst <= 4'b0;
1225 2 zeus
        end
1226
 
1227
      8'b1100_1111: // iret
1228
        begin
1229
          seq_addr <= `IRET;
1230
          need_modrm <= 1'b0;
1231
          need_off <= 1'b0;
1232
          need_imm <= 1'b0;
1233 21 zeus
          imm_size <= 1'b0;
1234
          src <= 4'b0;
1235
          dst <= 4'b0;
1236 2 zeus
        end
1237
 
1238 22 zeus
      8'b1101_00xx: // sal/shl
1239
        begin
1240 24 zeus
          seq_addr <= (regm==3'b010) ? ((mod==2'b11) ?
1241 40 zeus
            (op[1] ? (op[0] ? `RCLCRW : `RCLCRB )
1242
                       : (op[0] ? `RCL1RW : `RCL1RB ))
1243
          : (op[1] ? (op[0] ? `RCLCMW : `RCLCMB )
1244
                       : (op[0] ? `RCL1MW : `RCL1MB )))
1245 24 zeus
         : ((regm==3'b011) ? ((mod==2'b11) ?
1246 40 zeus
            (op[1] ? (op[0] ? `RCRCRW : `RCRCRB )
1247
                       : (op[0] ? `RCR1RW : `RCR1RB ))
1248
          : (op[1] ? (op[0] ? `RCRCMW : `RCRCMB )
1249
                       : (op[0] ? `RCR1MW : `RCR1MB )))
1250 24 zeus
         : ((regm==3'b001) ? ((mod==2'b11) ?
1251 40 zeus
            (op[1] ? (op[0] ? `RORCRW : `RORCRB )
1252
                       : (op[0] ? `ROR1RW : `ROR1RB ))
1253
          : (op[1] ? (op[0] ? `RORCMW : `RORCMB )
1254
                       : (op[0] ? `ROR1MW : `ROR1MB )))
1255 24 zeus
         : ((regm==3'b000) ? ((mod==2'b11) ?
1256 40 zeus
            (op[1] ? (op[0] ? `ROLCRW : `ROLCRB )
1257
                       : (op[0] ? `ROL1RW : `ROL1RB ))
1258
          : (op[1] ? (op[0] ? `ROLCMW : `ROLCMB )
1259
                       : (op[0] ? `ROL1MW : `ROL1MB )))
1260 24 zeus
         : ( (regm==3'b100) ? ((mod==2'b11) ?
1261 40 zeus
            (op[1] ? (op[0] ? `SALCRW : `SALCRB )
1262
                       : (op[0] ? `SAL1RW : `SAL1RB ))
1263
          : (op[1] ? (op[0] ? `SALCMW : `SALCMB )
1264
                       : (op[0] ? `SAL1MW : `SAL1MB )))
1265 22 zeus
         : ( (regm==3'b111) ? ((mod==2'b11) ?
1266 40 zeus
            (op[1] ? (op[0] ? `SARCRW : `SARCRB )
1267
                       : (op[0] ? `SAR1RW : `SAR1RB ))
1268
          : (op[1] ? (op[0] ? `SARCMW : `SARCMB )
1269
                       : (op[0] ? `SAR1MW : `SAR1MB )))
1270 22 zeus
           : ((mod==2'b11) ?
1271 40 zeus
            (op[1] ? (op[0] ? `SHRCRW : `SHRCRB )
1272
                       : (op[0] ? `SHR1RW : `SHR1RB ))
1273
          : (op[1] ? (op[0] ? `SHRCMW : `SHRCMB )
1274
                       : (op[0] ? `SHR1MW : `SHR1MB ))))))));
1275 22 zeus
 
1276
          need_modrm <= 1'b1;
1277
          need_off <= need_off_mod;
1278
          need_imm <= 1'b0;
1279
          imm_size <= 1'b0;
1280
          src <= rm;
1281
          dst <= rm;
1282
        end
1283 31 zeus
 
1284 30 zeus
      8'b1101_0100: // aam
1285
        begin
1286
          seq_addr <= `AAM;
1287
          need_modrm <= 1'b0;
1288
          need_off <= 1'b0;
1289
          need_imm <= 1'b1;
1290
          imm_size <= 1'b0;
1291
          src <= 4'b0;
1292
          dst <= 4'b0;
1293
        end
1294 31 zeus
 
1295 29 zeus
      8'b1101_0101: // aad
1296
        begin
1297
          seq_addr <= `AAD;
1298
          need_modrm <= 1'b0;
1299
          need_off <= 1'b0;
1300
          need_imm <= 1'b1;
1301
          imm_size <= 1'b0;
1302
          src <= 4'b0;
1303
          dst <= 4'b0;
1304
        end
1305
 
1306 2 zeus
      8'b1101_0111: // xlat
1307
        begin
1308
          seq_addr <= `XLAT;
1309
          need_modrm <= 1'b0;
1310
          need_off <= 1'b0;
1311
          need_imm <= 1'b0;
1312 21 zeus
          imm_size <= 1'b0;
1313
          src <= 4'b0;
1314
          dst <= 4'b0;
1315 2 zeus
        end
1316
 
1317
      8'b1110_0000: // loopne
1318
        begin
1319
          seq_addr <= `LOOPNE;
1320
          need_modrm <= 1'b0;
1321
          need_off <= 1'b0;
1322
          need_imm <= 1'b1;
1323
          imm_size <= 1'b0;
1324 21 zeus
          src <= 4'b0;
1325
          dst <= 4'b0;
1326 2 zeus
        end
1327
 
1328
      8'b1110_0001: // loope
1329
        begin
1330
          seq_addr <= `LOOPE;
1331
          need_modrm <= 1'b0;
1332
          need_off <= 1'b0;
1333
          need_imm <= 1'b1;
1334
          imm_size <= 1'b0;
1335 21 zeus
          src <= 4'b0;
1336
          dst <= 4'b0;
1337 2 zeus
        end
1338
 
1339
      8'b1110_0010: // loop
1340
        begin
1341
          seq_addr <= `LOOP;
1342
          need_modrm <= 1'b0;
1343
          need_off <= 1'b0;
1344
          need_imm <= 1'b1;
1345
          imm_size <= 1'b0;
1346 21 zeus
          src <= 4'b0;
1347
          dst <= 4'b0;
1348 2 zeus
        end
1349
 
1350
      8'b1110_0011: // jcxz
1351
        begin
1352
          seq_addr <= `JCXZ;
1353
          need_modrm <= 1'b0;
1354
          need_off <= 1'b0;
1355
          need_imm <= 1'b1;
1356
          imm_size <= 1'b0;
1357 21 zeus
          src <= 4'b0;
1358
          dst <= 4'b0;
1359 2 zeus
        end
1360
 
1361
      8'b1110_010x: // in imm
1362
        begin
1363
          seq_addr <= b ? `INIB : `INIW;
1364
          need_modrm <= 1'b0;
1365
          need_off <= 1'b0;
1366
          need_imm <= 1'b1;
1367
          imm_size <= 1'b0;
1368 21 zeus
          src <= 4'b0;
1369
          dst <= 4'b0;
1370 2 zeus
        end
1371
 
1372
      8'b1110_011x: // out imm
1373
        begin
1374
          seq_addr <= b ? `OUTIB : `OUTIW;
1375
          need_modrm <= 1'b0;
1376
          need_off <= 1'b0;
1377
          need_imm <= 1'b1;
1378
          imm_size <= 1'b0;
1379 21 zeus
          src <= 4'b0;
1380
          dst <= 4'b0;
1381 2 zeus
        end
1382
 
1383
      8'b1110_1000: // call same segment
1384
        begin
1385
          seq_addr <= `CALLN;
1386
          need_modrm <= 1'b0;
1387
          need_off <= 1'b0;
1388
          need_imm <= 1'b1;
1389
          imm_size <= 1'b1;
1390 21 zeus
          src <= 4'b0;
1391
          dst <= 4'b0;
1392 2 zeus
        end
1393 15 zeus
 
1394 2 zeus
      8'b1110_10x1: // jmp direct
1395
        begin
1396
          seq_addr <= `JMPI;
1397
          need_modrm <= 1'b0;
1398
          need_off <= 1'b0;
1399
          need_imm <= 1'b1;
1400 40 zeus
          imm_size <= ~op[1];
1401 2 zeus
 
1402
          src <= 4'b0;
1403
          dst <= 4'b0;
1404
        end
1405
 
1406
      8'b1110_1010: // jmp indirect different segment
1407
        begin
1408
          seq_addr <= `LJMPI;
1409
          need_modrm <= 1'b0;
1410
          need_off <= 1'b1;
1411
          need_imm <= 1'b1;
1412
          imm_size <= 1'b1;
1413
 
1414
          src <= 4'b0;
1415
          dst <= 4'b0;
1416
        end
1417 15 zeus
 
1418 2 zeus
      8'b1110_110x: // in dx
1419
        begin
1420
          seq_addr <= b ? `INRB : `INRW;
1421
          need_modrm <= 1'b0;
1422
          need_off <= 1'b0;
1423
          need_imm <= 1'b0;
1424 21 zeus
          imm_size <= 1'b0;
1425
          src <= 4'b0;
1426
          dst <= 4'b0;
1427 2 zeus
        end
1428
 
1429
      8'b1110_111x: // out dx
1430
        begin
1431
          seq_addr <= b ? `OUTRB : `OUTRW;
1432
          need_modrm <= 1'b0;
1433
          need_off <= 1'b0;
1434
          need_imm <= 1'b0;
1435 21 zeus
          imm_size <= 1'b0;
1436
          src <= 4'b0;
1437
          dst <= 4'b0;
1438 2 zeus
        end
1439 15 zeus
 
1440 2 zeus
      8'b1111_0100: // hlt
1441
        begin
1442
          seq_addr <= `HLT;
1443
          need_modrm <= 1'b0;
1444
          need_off <= 1'b0;
1445
          need_imm <= 1'b0;
1446
          imm_size <= 1'b0;
1447
 
1448
          src <= 4'b0;
1449
          dst <= 4'b0;
1450
        end
1451 15 zeus
 
1452 2 zeus
      8'b1111_0101: // cmc
1453
        begin
1454
          seq_addr <= `CMC;
1455
          need_modrm <= 1'b0;
1456
          need_off <= 1'b0;
1457
          need_imm <= 1'b0;
1458 21 zeus
          imm_size <= 1'b0;
1459
          src <= 4'b0;
1460
          dst <= 4'b0;
1461 2 zeus
        end
1462
 
1463 29 zeus
      8'b1111_011x: // test, not, neg, mul, imul
1464 19 zeus
        begin
1465 29 zeus
          case (regm)
1466
            3'b000: seq_addr <= (mod==2'b11) ?
1467
             (b ? `TSTIRB : `TSTIRW) : (b ? `TSTIMB : `TSTIMW);
1468
            3'b010: seq_addr <= (mod==2'b11) ?
1469
             (b ? `NOTRB : `NOTRW) : (b ? `NOTMB : `NOTMW);
1470
            3'b011: seq_addr <= (mod==2'b11) ?
1471
             (b ? `NEGRB : `NEGRW) : (b ? `NEGMB : `NEGMW);
1472
            3'b100: seq_addr <= (mod==2'b11) ?
1473
             (b ? `MULRB : `MULRW) : (b ? `MULMB : `MULMW);
1474
            3'b101: seq_addr <= (mod==2'b11) ?
1475
             (b ? `IMULRB : `IMULRW) : (b ? `IMULMB : `IMULMW);
1476 30 zeus
            3'b110: seq_addr <= (mod==2'b11) ?
1477
             (b ? `DIVRB : `DIVRW) : (b ? `DIVMB : `DIVMW);
1478
            3'b111: seq_addr <= (mod==2'b11) ?
1479
             (b ? `IDIVRB : `IDIVRW) : (b ? `IDIVMB : `IDIVMW);
1480 29 zeus
            default: seq_addr <= `NOP;
1481
          endcase
1482
 
1483 19 zeus
          need_modrm <= 1'b1;
1484
          need_off   <= need_off_mod;
1485
          need_imm   <= (regm == 3'b000); // imm on test
1486
          imm_size   <= ~b;
1487 29 zeus
          dst        <= { 1'b0, modrm[2:0] };
1488 28 zeus
          src        <= { 1'b0, modrm[2:0] };
1489 19 zeus
        end
1490
 
1491 2 zeus
      8'b1111_1000: // clc
1492
        begin
1493
          seq_addr <= `CLC;
1494
          need_modrm <= 1'b0;
1495
          need_off <= 1'b0;
1496
          need_imm <= 1'b0;
1497 21 zeus
          imm_size <= 1'b0;
1498
          src <= 4'b0;
1499
          dst <= 4'b0;
1500 2 zeus
        end
1501
 
1502
      8'b1111_1001: // stc
1503
        begin
1504
          seq_addr <= `STC;
1505
          need_modrm <= 1'b0;
1506
          need_off <= 1'b0;
1507
          need_imm <= 1'b0;
1508 21 zeus
          imm_size <= 1'b0;
1509
          src <= 4'b0;
1510
          dst <= 4'b0;
1511 2 zeus
        end
1512
 
1513
      8'b1111_1010: // cli
1514
        begin
1515
          seq_addr <= `CLI;
1516
          need_modrm <= 1'b0;
1517
          need_off <= 1'b0;
1518
          need_imm <= 1'b0;
1519 21 zeus
          imm_size <= 1'b0;
1520
          src <= 4'b0;
1521
          dst <= 4'b0;
1522 2 zeus
        end
1523
 
1524
      8'b1111_1011: // sti
1525
        begin
1526
          seq_addr <= `STI;
1527
          need_modrm <= 1'b0;
1528
          need_off <= 1'b0;
1529
          need_imm <= 1'b0;
1530 21 zeus
          imm_size <= 1'b0;
1531
          src <= 4'b0;
1532
          dst <= 4'b0;
1533 2 zeus
        end
1534
 
1535
      8'b1111_1100: // cld
1536
        begin
1537
          seq_addr <= `CLD;
1538
          need_modrm <= 1'b0;
1539
          need_off <= 1'b0;
1540
          need_imm <= 1'b0;
1541 21 zeus
          imm_size <= 1'b0;
1542
          src <= 4'b0;
1543
          dst <= 4'b0;
1544 2 zeus
        end
1545
 
1546
      8'b1111_1101: // std
1547
        begin
1548
          seq_addr <= `STD;
1549
          need_modrm <= 1'b0;
1550
          need_off <= 1'b0;
1551
          need_imm <= 1'b0;
1552 21 zeus
          imm_size <= 1'b0;
1553
          src <= 4'b0;
1554
          dst <= 4'b0;
1555 2 zeus
        end
1556 15 zeus
 
1557 27 zeus
      8'b1111_1110: // inc
1558
        begin
1559
          case (regm)
1560
            3'b000: seq_addr <= (mod==2'b11) ? `INCRB : `INCMB;
1561
            3'b001: seq_addr <= (mod==2'b11) ? `DECRB : `DECMB;
1562
            default: seq_addr <= `NOP;
1563
          endcase
1564
          need_modrm <= 1'b1;
1565
          need_off <= need_off_mod;
1566
          need_imm <= 1'b0;
1567
          imm_size <= 1'b0;
1568
 
1569 40 zeus
          src <= { 1'b0, rm };
1570 27 zeus
          dst <= 4'b0;
1571
        end
1572
 
1573 15 zeus
      8'b1111_1111:
1574 2 zeus
        begin
1575
          case (regm)
1576 27 zeus
            3'b000: seq_addr <= (mod==2'b11) ? `INCRW : `INCMW;
1577
            3'b001: seq_addr <= (mod==2'b11) ? `DECRW : `DECMW;
1578 15 zeus
            3'b010: seq_addr <= (mod==2'b11) ? `CALLNR : `CALLNM;
1579
            3'b011: seq_addr <= `CALLFM;
1580 2 zeus
            3'b100: seq_addr <= (mod==2'b11) ? `JMPR : `JMPM;
1581
            3'b101: seq_addr <= `LJMPM;
1582 15 zeus
            3'b110: seq_addr <= (mod==2'b11) ? `PUSHR : `PUSHM;
1583 2 zeus
            default: seq_addr <= `NOP;
1584
          endcase
1585
          need_modrm <= 1'b1;
1586
          need_off <= need_off_mod;
1587
          need_imm <= 1'b0;
1588
          imm_size <= 1'b0;
1589
 
1590 40 zeus
          src <= { 1'b0, rm };
1591 2 zeus
          dst <= 4'b0;
1592
        end
1593
 
1594 39 zeus
      default: // hlt
1595 2 zeus
        begin
1596 39 zeus
          seq_addr <= `HLT;
1597 2 zeus
          need_modrm <= 1'b0;
1598
          need_off <= 1'b0;
1599
          need_imm <= 1'b0;
1600
          imm_size <= 1'b0;
1601
 
1602
          src <= 4'b0;
1603
          dst <= 4'b0;
1604
        end
1605
 
1606
  endcase
1607
 
1608
endmodule
1609
 
1610
module memory_regs (
1611
    input [2:0] rm,
1612
    input [1:0] mod,
1613 32 zeus
    input [2:0] sovr_pr,
1614
 
1615 2 zeus
    output reg [3:0] base,
1616
    output reg [3:0] index,
1617 32 zeus
    output     [1:0] seg
1618 2 zeus
  );
1619
 
1620 32 zeus
  // Register declaration
1621
  reg [1:0] s;
1622
 
1623
  // Continuous assignments
1624
  assign seg = sovr_pr[2] ? sovr_pr[1:0] : s;
1625
 
1626 2 zeus
  // Behaviour
1627
  always @(rm or mod)
1628
    case (rm)
1629 32 zeus
      3'b000: begin base <= 4'b0011; index <= 4'b0110; s <= 2'b11; end
1630
      3'b001: begin base <= 4'b0011; index <= 4'b0111; s <= 2'b11; end
1631
      3'b010: begin base <= 4'b0101; index <= 4'b0110; s <= 2'b10; end
1632
      3'b011: begin base <= 4'b0101; index <= 4'b0111; s <= 2'b10; end
1633
      3'b100: begin base <= 4'b1100; index <= 4'b0110; s <= 2'b11; end
1634
      3'b101: begin base <= 4'b1100; index <= 4'b0111; s <= 2'b11; end
1635
      3'b110: begin base <= mod ? 4'b0101 : 4'b1100; index <= 4'b1100;
1636
                    s <= mod ? 2'b10 : 2'b11; end
1637
      3'b111: begin base <= 4'b0011; index <= 4'b1100; s <= 2'b11; end
1638 2 zeus
    endcase
1639
endmodule
1640
 
1641
module micro_data (
1642
    input [`MICRO_ADDR_WIDTH-1:0] n_micro,
1643
    input [15:0] off_i,
1644
    input [15:0] imm_i,
1645
    input [3:0] src,
1646
    input [3:0] dst,
1647
    input [3:0] base,
1648
    input [3:0] index,
1649
    input [1:0] seg,
1650
    output [`IR_SIZE-1:0] ir,
1651
    output [15:0] off_o,
1652
    output [15:0] imm_o
1653
  );
1654
 
1655
  // Net declarations
1656
  wire [`MICRO_DATA_WIDTH-1:0] micro_o;
1657 19 zeus
  wire [17:0] high_ir;
1658 2 zeus
  wire var_s, var_off;
1659
  wire [1:0] var_a, var_b, var_c, var_d;
1660
  wire [2:0] var_imm;
1661
 
1662
  wire [3:0] addr_a, addr_b, addr_c, addr_d;
1663
  wire [3:0] micro_a, micro_b, micro_c, micro_d;
1664
  wire [1:0] addr_s, micro_s;
1665
 
1666
  // Module instantiations
1667
  micro_rom m0 (n_micro, micro_o);
1668
 
1669
  // Assignments
1670
  assign micro_s = micro_o[1:0];
1671
  assign micro_a = micro_o[5:2];
1672
  assign micro_b = micro_o[9:6];
1673
  assign micro_c = micro_o[13:10];
1674
  assign micro_d = micro_o[17:14];
1675
  assign high_ir = micro_o[35:18];
1676
  assign var_s   = micro_o[36];
1677
  assign var_a   = micro_o[38:37];
1678
  assign var_b   = micro_o[40:39];
1679
  assign var_c   = micro_o[42:41];
1680
  assign var_d   = micro_o[44:43];
1681
  assign var_off = micro_o[45];
1682
  assign var_imm = micro_o[48:46];
1683
 
1684
  assign imm_o = var_imm == 3'd0 ? (16'h0000)
1685
               : (var_imm == 3'd1 ? (16'h0002)
1686
               : (var_imm == 3'd2 ? (16'h0004)
1687 40 zeus
               : (var_imm == 3'd3 ? off_i
1688
               : (var_imm == 3'd4 ? imm_i
1689
               : (var_imm == 3'd5 ? 16'hffff
1690 2 zeus
               : (var_imm == 3'd6 ? 16'b11 : 16'd1))))));
1691
 
1692
  assign off_o = var_off ? off_i : 16'h0000;
1693
 
1694
  assign addr_a = var_a == 2'd0 ? micro_a
1695 40 zeus
                : (var_a == 2'd1 ? base
1696 2 zeus
                : (var_a == 2'd2 ? dst : src ));
1697
  assign addr_b = var_b == 2'd0 ? micro_b
1698
                : (var_b == 2'd1 ? index : src);
1699
  assign addr_c = var_c == 2'd0 ? micro_c
1700
                : (var_c == 2'd1 ? dst : src);
1701
  assign addr_d = var_d == 2'd0 ? micro_d
1702
                : (var_d == 2'd1 ? dst : src);
1703
  assign addr_s = var_s ? seg : micro_s;
1704
 
1705
  assign ir = { high_ir, addr_d, addr_c, addr_b, addr_a, addr_s };
1706
endmodule
1707
 
1708
module micro_rom (
1709
    input [`MICRO_ADDR_WIDTH-1:0] addr,
1710
    output [`MICRO_DATA_WIDTH-1:0] q
1711
  );
1712
 
1713
  // Registers, nets and parameters
1714
  reg [`MICRO_DATA_WIDTH-1:0] rom[0:2**`MICRO_ADDR_WIDTH-1];
1715
 
1716
  // Assignments
1717
  assign q = rom[addr];
1718
 
1719
  // Behaviour
1720 42 zeus
  initial $readmemb("/home/zeus/zet/rtl-model/micro_rom.dat", rom);
1721 2 zeus
endmodule
1722
 
1723
module seq_rom (
1724
    input [`SEQ_ADDR_WIDTH-1:0] addr,
1725
    output [`SEQ_DATA_WIDTH-1:0] q
1726
  );
1727
 
1728
  // Registers, nets and parameters
1729
  reg [`SEQ_DATA_WIDTH-1:0] rom[0:2**`SEQ_ADDR_WIDTH-1];
1730
 
1731
  // Assignments
1732
  assign q = rom[addr];
1733
 
1734
  // Behaviour
1735 42 zeus
  initial $readmemb("/home/zeus/zet/rtl-model/seq_rom.dat", rom);
1736 2 zeus
endmodule

powered by: WebSVN 2.1.0

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