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

Subversion Repositories zet86

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

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 zeus
`timescale 1ns/10ps
2
 
3
`include "defines.v"
4
 
5
module fetch (
6
    input clk,
7
    input rst,
8
    input [15:0] cs,
9
    input [15:0] ip,
10
    input of,
11
    input zf,
12
    input cx_zero,
13
    input [15:0] data,
14
    output [`IR_SIZE-1:0] ir,
15
    output [15:0] off,
16
    output [15:0] imm,
17
    output [19:0] pc,
18
    output bytefetch,
19
    output fetch_or_exec,
20
    input  mem_rdy
21
  );
22
 
23
  // Registers, nets and parameters
24
  parameter opcod_st = 3'h0;
25
  parameter modrm_st = 3'h1;
26
  parameter offse_st = 3'h2;
27
  parameter immed_st = 3'h3;
28
  parameter execu_st = 3'h4;
29
 
30
  wire [`IR_SIZE-1:0] rom_ir;
31
  wire [7:0] opcode, modrm;
32
  wire exec_st, end_seq;
33
  wire [15:0] imm_d;
34
  wire [2:0] next_state;
35
  wire prefix;
36
  wire next_in_opco, next_in_exec;
37
  wire block;
38
  wire need_modrm, need_off, need_imm, off_size, imm_size;
39
 
40
  reg [2:0] state;
41
  reg [7:0] opcode_l, modrm_l;
42
  reg [15:0] off_l, imm_l;
43
  reg [1:0] pref_l;
44
 
45
  // Module instantiation
46
  decode decode0(opcode, modrm, off_l, imm_l, /* pref_l[1], */ clk, rst, block,
47
                 exec_st, need_modrm, need_off, need_imm, off_size, imm_size,
48
                 rom_ir, off, imm_d, end_seq);
49
  next_or_not nn0(pref_l, opcode[7:1], cx_zero, zf, next_in_opco,
50
                  next_in_exec);
51
  nstate ns0(state, prefix, need_modrm, need_off, need_imm, end_seq,
52
             rom_ir[28:23], of, next_in_opco, next_in_exec, block,
53
             next_state);
54
 
55
  // Assignments
56
  assign pc = (cs << 4) + ip;
57
 
58
  assign ir     = (state == execu_st) ? rom_ir : `ADD_IP;
59
  assign opcode = (state == opcod_st) ? data[7:0] :  opcode_l;
60
  assign modrm  = (state == modrm_st) ? data[7:0] : modrm_l;
61
  assign fetch_or_exec = (state == execu_st);
62
  assign bytefetch = (state == offse_st) ? ~off_size
63
                   : ((state == immed_st) ? ~imm_size : 1'b1);
64
  assign exec_st = (state == execu_st);
65
  assign imm = (state == execu_st) ? imm_d
66
              : ((state == offse_st) & off_size
67
                | (state == immed_st) & imm_size) ? 16'd2
68
              : 16'd1;
69
  assign prefix = (opcode[7:1]==7'b1111_001);
70
  assign block  = ir[`MEM_OP] && !mem_rdy;
71
 
72
  // Behaviour
73
  always @(posedge clk)
74
    if (rst)
75
      begin
76
        state <= execu_st;
77
        opcode_l <= `OP_NOP;
78
      end
79
    else if (!block)
80
      case (next_state)
81
        default:  // opcode or prefix
82
          begin
83
            case (state)
84
              opcod_st: pref_l <= prefix ? { 1'b1, opcode[0] } : 2'b0;
85
              default: pref_l <= 2'b0;
86
            endcase
87
            state <= opcod_st;
88
            off_l <= 16'd0;
89
          end
90
 
91
        modrm_st:  // modrm
92
          begin
93
            opcode_l  <= data[7:0];
94
            state <= modrm_st;
95
          end
96
 
97
        offse_st:  // offset
98
          begin
99
            case (state)
100
              opcod_st: opcode_l <= data[7:0];
101
              default: modrm_l <= data[7:0];
102
            endcase
103
            state <= offse_st;
104
          end
105
 
106
        immed_st:  // immediate
107
          begin
108
            case (state)
109
              opcod_st: opcode_l <= data[7:0];
110
              modrm_st: modrm_l <= data[7:0];
111
              default: off_l <= data;
112
            endcase
113
            state <= immed_st;
114
          end
115
 
116
        execu_st:  // execute
117
          begin
118
            case (state)
119
              opcod_st: opcode_l <= data[7:0];
120
              modrm_st: modrm_l <= data[7:0];
121
              offse_st: off_l <= data;
122
              immed_st: imm_l <= data;
123
            endcase
124
            state <= execu_st;
125
          end
126
      endcase
127
endmodule
128
 
129
module nstate (
130
    input [2:0] state,
131
    input prefix,
132
    input need_modrm,
133
    input need_off,
134
    input need_imm,
135
    input end_seq,
136
    input [5:0] ftype,
137
    input of,
138
    input next_in_opco,
139
    input next_in_exec,
140
    input block,
141
    output [2:0] next_state
142
  );
143
 
144
  // Net declarations
145
  parameter opcod_st = 3'h0;
146
  parameter modrm_st = 3'h1;
147
  parameter offse_st = 3'h2;
148
  parameter immed_st = 3'h3;
149
  parameter execu_st = 3'h4;
150
  wire into, end_instr, end_into;
151
  wire [2:0] n_state;
152
 
153
  // Assignments
154
  assign into = (ftype==6'b111_010);
155
  assign end_into = into ? ~of : end_seq;
156
  assign end_instr = end_into && !next_in_exec;
157
 
158
  assign n_state = (state == opcod_st) ? (prefix ? opcod_st
159
                         : (next_in_opco ? opcod_st
160
                         : (need_modrm ? modrm_st
161
                         : (need_off ? offse_st
162
                         : (need_imm ? immed_st : execu_st)))))
163
                     : (state == modrm_st) ? (need_off ? offse_st
164
                                           : (need_imm ? immed_st : execu_st))
165
                     : (state == offse_st) ? (need_imm ? immed_st : execu_st)
166
                     : (state == immed_st) ? (execu_st)
167
                     : (end_instr ? opcod_st : execu_st);
168
 
169
  assign next_state = block ? state : n_state;
170
endmodule
171
 
172
module next_or_not (
173
    input [1:0] prefix,
174
    input [7:1] opcode,
175
    input cx_zero,
176
    input zf,
177
    output next_in_opco,
178
    output next_in_exec
179
  );
180
 
181
  // Net declarations
182
  wire exit_z, cmp_sca, exit_rep, valid_ops;
183
 
184
  // Assignments
185
  assign cmp_sca = opcode[2] & opcode[1];
186
  assign exit_z = prefix[0] ? /* repz */ (cmp_sca ? ~zf : 1'b0 )
187
                            : /* repnz */ (cmp_sca ? zf : 1'b0 );
188
  assign exit_rep = cx_zero | exit_z;
189
  assign valid_ops = (opcode[7:1]==7'b1010_010   // movs
190
                    || opcode[7:1]==7'b1010_011   // cmps
191
                    || opcode[7:1]==7'b1010_101   // stos
192
                    || opcode[7:1]==7'b1010_110   // lods
193
                    || opcode[7:1]==7'b1010_111); // scas
194
  assign next_in_exec = prefix[1] && valid_ops && !exit_rep;
195
  assign next_in_opco = prefix[1] && valid_ops && cx_zero;
196
endmodule
197
 
198
module decode (
199
    input [7:0] opcode,
200
    input [7:0] modrm,
201
    input [15:0] off_i,
202
    input [15:0] imm_i,
203
//    input       rep,
204
    input clk,
205
    input rst,
206
    input block,
207
    input exec_st,
208
 
209
    output need_modrm,
210
    output need_off,
211
    output need_imm,
212
    output off_size,
213
    output imm_size,
214
 
215
    output [`IR_SIZE-1:0] ir,
216
    output [15:0] off_o,
217
    output [15:0] imm_o,
218
    output end_seq
219
  );
220
 
221
  // Net declarations
222
  wire [`SEQ_ADDR_WIDTH-1:0] base_addr, seq_addr;
223
  wire [`SEQ_DATA_WIDTH-2:0] micro_addr;
224
  wire [3:0] src, dst, base, index;
225
  wire [1:0] seg;
226
  reg  [`SEQ_ADDR_WIDTH-1:0] seq;
227
 
228
  // Module instantiations
229
  opcode_deco opcode_deco0 (opcode, modrm, /* rep, */ base_addr, need_modrm,
230
                            need_off, need_imm, off_size, imm_size, src, dst,
231
                            base, index, seg);
232
  seq_rom seq_rom0 (seq_addr, {end_seq, micro_addr});
233
  micro_data mdata0 (micro_addr, off_i, imm_i, src, dst, base, index, seg,
234
                     ir, off_o, imm_o);
235
 
236
  // Assignments
237
  assign seq_addr = base_addr + seq;
238
 
239
  // Behaviour
240
  always @(posedge clk)
241
    if (rst) seq <= `SEQ_ADDR_WIDTH'd0;
242
    else if (!block)
243
      seq <= (exec_st && !end_seq && !rst) ? (seq + `SEQ_ADDR_WIDTH'd1)
244
                                : `SEQ_ADDR_WIDTH'd0;
245
 
246
endmodule
247
 
248
module opcode_deco (
249
    input [7:0] opcode,
250
    input [7:0] modrm,
251
//    input       rep,
252
 
253
    output reg [`SEQ_ADDR_WIDTH-1:0] seq_addr,
254
    output reg need_modrm,
255
    output reg need_off,
256
    output reg need_imm,
257
    output reg off_size,
258
    output reg imm_size,
259
 
260
    output reg [3:0] src,
261
    output reg [3:0] dst,
262
    output [3:0] base,
263
    output [3:0] index,
264
    output [1:0] seg
265
  );
266
 
267
  // Net declarations
268
  wire [1:0] mod;
269
  wire [2:0] regm;
270
  wire [2:0] rm;
271
  wire       d, b, sm, dm;
272
  wire       off_size_mod, need_off_mod;
273
  wire [2:0] srcm, dstm;
274
 
275
  // Module instantiations
276
  memory_regs mr(rm, mod, base, index, seg);
277
 
278
  // Assignments
279
  assign mod  = modrm[7:6];
280
  assign regm = modrm[5:3];
281
  assign rm   = modrm[2:0];
282
  assign d    = opcode[1];
283
  assign dstm = d ? regm : rm;
284
  assign sm   = d & (mod != 2'b11);
285
  assign dm   = ~d & (mod != 2'b11);
286
  assign srcm = d ? rm : regm;
287
  assign b    = ~opcode[0];
288
  assign off_size_mod = (base == 4'b1100 && index == 4'b1100) ? 1'b1 : mod[1];
289
  assign need_off_mod = (base == 4'b1100 && index == 4'b1100) || ^mod;
290
 
291
  // Behaviour
292
  always @(opcode or dm or b or need_off_mod or srcm or sm or dstm
293
           or off_size_mod or mod or rm or regm)
294
    casex (opcode)
295
/*
296
      8'b000x_x110: // push seg
297
        begin
298
          seq_addr <= `PUSHR;
299
          need_modrm <= 1'b0;
300
          need_off <= 1'b0;
301
          need_imm <= 1'b0;
302
          src <= { 2'b10, opcode[4:3] };
303
        end
304
 
305
      8'b000x_x111: // pop seg
306
        begin
307
          seq_addr <= `POPR;
308
          need_modrm <= 1'b0;
309
          need_off <= 1'b0;
310
          need_imm <= 1'b0;
311
          dst <= { 2'b10, opcode[4:3] };
312
        end
313
 
314
      8'b0101_0xxx: // push reg
315
        begin
316
          seq_addr <= `PUSHR;
317
          need_modrm <= 1'b0;
318
          need_off <= 1'b0;
319
          need_imm <= 1'b0;
320
          src <= { 1'b0, opcode[2:0] };
321
        end
322
 
323
      8'b0101_1xxx: // pop reg
324
        begin
325
          seq_addr <= `POPR;
326
          need_modrm <= 1'b0;
327
          need_off <= 1'b0;
328
          need_imm <= 1'b0;
329
          dst <= { 1'b0, opcode[2:0] };
330
        end
331
 
332
      8'b0111_xxxx: // jcc
333
        begin
334
          seq_addr <= `JCC;
335
          need_modrm <= 1'b0;
336
          need_off <= 1'b0;
337
          need_imm <= 1'b1;
338
          imm_size <= 1'b0;
339
          src <= { opcode[3:0] };
340
        end
341
 
342
      8'b1000_011x: // xchg
343
        begin
344
          seq_addr <= (mod==2'b11) ? (b ? `XCHRRB : `XCHRRW)
345
                                   : (b ? `XCHRMB : `XCHRMW);
346
          need_modrm <= 1'b1;
347
          need_off <= need_off_mod;
348
          off_size <= off_size_mod;
349
          need_imm <= 1'b0;
350
          dst <= { 1'b0, dstm };
351
          src <= { 1'b0, srcm };
352
        end
353
*/
354
      8'b1000_10xx: // mov: r->r, r->m, m->r
355
        begin
356
          if (dm)   // r->m
357
            begin
358
              seq_addr <= b ? `MOVRMB : `MOVRMW;
359
              need_off <= need_off_mod;
360
              src <= { 1'b0, srcm };
361
              dst <= 4'b0;
362
            end
363
          else if(sm) // m->r
364
            begin
365
              seq_addr <= b ? `MOVMRB : `MOVMRW;
366
              need_off <= need_off_mod;
367
              src <= 4'b0;
368
              dst <= { 1'b0, dstm };
369
            end
370
          else     // r->r
371
            begin
372
              seq_addr <= b ? `MOVRRB : `MOVRRW;
373
              need_off <= 1'b0;
374
              dst <= { 1'b0, dstm };
375
              src <= { 1'b0, srcm };
376
            end
377
          need_imm <= 1'b0;
378
          need_modrm <= 1'b1;
379
          off_size <= off_size_mod;
380
          imm_size <= 1'b0;
381
        end
382
 
383
      8'b1000_1100: // mov: s->m, s->r
384
        begin
385
          if (dm)   // s->m
386
            begin
387
              seq_addr <= `MOVRMW;
388
              need_off <= need_off_mod;
389
              src <= { 1'b1, srcm };
390
              dst <= 4'b0;
391
            end
392
          else     // s->r
393
            begin
394
              seq_addr <= `MOVRRW;
395
              need_off <= 1'b0;
396
              src <= { 1'b1, srcm };
397
              dst <= { 1'b0, dstm };
398
            end
399
          need_imm <= 1'b0;
400
          need_modrm <= 1'b1;
401
          off_size <= off_size_mod;
402
          imm_size <= 1'b0;
403
        end
404
/*
405
      8'b1000_1101: // lea
406
        begin
407
          seq_addr <= `LEA;
408
          need_modrm <= 1'b1;
409
          need_off <= need_off_mod;
410
          off_size <= off_size_mod;
411
          need_imm <= 1'b0;
412
          src <= { 1'b0, srcm };
413
        end
414
*/
415
      8'b1000_1110: // mov: m->s, r->s
416
        begin
417
          if (sm)   // m->s
418
            begin
419
              seq_addr <= `MOVMRW;
420
              need_off <= need_off_mod;
421
              src <= 4'b0;
422
              dst <= { 1'b1, dstm };
423
            end
424
          else     // r->s
425
            begin
426
              seq_addr <= `MOVRRW;
427
              need_off <= 1'b0;
428
              src <= { 1'b0, srcm };
429
              dst <= { 1'b1, dstm };
430
            end
431
          need_modrm <= 1'b1;
432
          off_size <= off_size_mod;
433
          need_imm <= 1'b0;
434
          imm_size <= 1'b0;
435
        end
436
/*
437
      8'b1000_1111: // pop mem or (pop reg non-standard)
438
        begin
439
          seq_addr <= (mod==2'b11) ? `POPR : `POPM;
440
          need_modrm <= 1'b1;
441
          need_off <= need_off_mod;
442
          off_size <= off_size_mod;
443
          need_imm <= 1'b0;
444
          dst <= { 1'b0, rm };
445
        end
446
 
447
      8'b1001_0000: // 90h: nop
448
        begin
449
          seq_addr <= `NOP;
450
          need_modrm <= 1'b0;
451
          need_off <= 1'b0;
452
          need_imm <= 1'b0;
453
        end
454
 
455
      8'b1001_0xxx: // xchg acum
456
        begin
457
          seq_addr <= `XCHRRW;
458
          need_modrm <= 1'b0;
459
          need_off <= 1'b0;
460
          need_imm <= 1'b0;
461
          src <= 4'b0000;
462
          dst <= { 1'b0, opcode[2:0] };
463
        end
464
 
465
      8'b1001_1010: // call different seg
466
        begin
467
          seq_addr <= `CALLF;
468
          need_modrm <= 1'b0;
469
          need_off <= 1'b1;
470
          off_size <= 1'b1;
471
          need_imm <= 1'b1;
472
          imm_size <= 1'b1;
473
        end
474
*/
475
      8'b1001_1100: // pushf
476
        begin
477
          seq_addr <= `PUSHF;
478
          need_modrm <= 1'b0;
479
          need_off <= 1'b0;
480
          need_imm <= 1'b0;
481
 
482
          off_size <= 1'b0;
483
          imm_size <= 1'b0;
484
 
485
          src <= 4'b0;
486
          dst <= 4'b0;
487
        end
488
/*
489
      8'b1001_1101: // popf
490
        begin
491
          seq_addr <= `POPF;
492
          need_modrm <= 1'b0;
493
          need_off <= 1'b0;
494
          need_imm <= 1'b0;
495
        end
496
 
497
      8'b1001_1110: // sahf
498
        begin
499
          seq_addr <= `SAHF;
500
          need_modrm <= 1'b0;
501
          need_off <= 1'b0;
502
          need_imm <= 1'b0;
503
        end
504
 
505
      8'b1001_1111: // lahf
506
        begin
507
          seq_addr <= `LAHF;
508
          need_modrm <= 1'b0;
509
          need_off <= 1'b0;
510
          need_imm <= 1'b0;
511
        end
512
*/
513
      8'b1010_000x: // mov: m->a
514
        begin
515
          seq_addr <= b ? `MOVMAB : `MOVMAW;
516
          need_modrm <= 1'b0;
517
          need_off <= 1'b1;
518
          need_imm <= 1'b0;
519
          off_size <= 1'b1;
520
          imm_size <= 1'b0;
521
 
522
          src <= 4'b0;
523
          dst <= 4'b0;
524
        end
525
 
526
      8'b1010_001x: // mov: a->m
527
        begin
528
          seq_addr <= b ? `MOVAMB : `MOVAMW;
529
          need_modrm <= 1'b0;
530
          need_off <= 1'b1;
531
          need_imm <= 1'b0;
532
          off_size <= 1'b1;
533
          imm_size <= 1'b0;
534
 
535
          src <= 4'b0;
536
          dst <= 4'b0;
537
        end
538
/*
539
      8'b1010_010x: // movs
540
        begin
541
          seq_addr <= rep ? (b ? `MOVSBR : `MOVSWR) : (b ? `MOVSB : `MOVSW);
542
          need_modrm <= 1'b0;
543
          need_off <= 1'b0;
544
          need_imm <= 1'b0;
545
        end
546
 
547
      8'b1010_011x: // cmps
548
        begin
549
          seq_addr <= rep ? (b ? `CMPSBR : `CMPSWR) : (b ? `CMPSB : `CMPSW);
550
          need_modrm <= 1'b0;
551
          need_off <= 1'b0;
552
          need_imm <= 1'b0;
553
        end
554
 
555
      8'b1010_101x: // stos
556
        begin
557
          seq_addr <= rep ? (b ? `STOSBR : `STOSWR) : (b ? `STOSB : `STOSW);
558
          need_modrm <= 1'b0;
559
          need_off <= 1'b0;
560
          need_imm <= 1'b0;
561
        end
562
 
563
      8'b1010_110x: // lods
564
        begin
565
          seq_addr <= rep ? (b ? `LODSBR : `LODSWR) : (b ? `LODSB : `LODSW);
566
          need_modrm <= 1'b0;
567
          need_off <= 1'b0;
568
          need_imm <= 1'b0;
569
        end
570
 
571
      8'b1010_111x: // scas
572
        begin
573
          seq_addr <= rep ? (b ? `SCASBR : `SCASWR) : (b ? `SCASB : `SCASW);
574
          need_modrm <= 1'b0;
575
          need_off <= 1'b0;
576
          need_imm <= 1'b0;
577
        end
578
*/
579
      8'b1011_xxxx: // mov: i->r
580
        begin
581
          seq_addr <= opcode[3] ? `MOVIRW : `MOVIRB;
582
          need_modrm <= 1'b0;
583
          need_off <= 1'b0;
584
          need_imm <= 1'b1;
585
          off_size <= 1'b0;
586
          imm_size <= opcode[3];
587
 
588
          src <= 4'b0;
589
          dst <= { 1'b0, opcode[2:0] };
590
        end
591
/*
592
      8'b1100_0010: // ret near with value
593
        begin
594
          seq_addr <= `RETNV;
595
          need_modrm <= 1'b0;
596
          need_off <= 1'b0;
597
          need_imm <= 1'b1;
598
          imm_size <= 1'b1;
599
        end
600
 
601
      8'b1100_0011: // ret near
602
        begin
603
          seq_addr <= `RETN0;
604
          need_modrm <= 1'b0;
605
          need_off <= 1'b0;
606
          need_imm <= 1'b0;
607
        end
608
 
609
      8'b1100_0100: // les
610
        begin
611
          seq_addr <= `LES;
612
          need_modrm <= 1'b1;
613
          need_off <= need_off_mod;
614
          off_size <= off_size_mod;
615
          need_imm <= 1'b0;
616
          src <= { 1'b0, srcm };
617
        end
618
 
619
      8'b1100_0101: // lds
620
        begin
621
          seq_addr <= `LDS;
622
          need_modrm <= 1'b1;
623
          need_off <= need_off_mod;
624
          off_size <= off_size_mod;
625
          need_imm <= 1'b0;
626
          src <= { 1'b0, srcm };
627
        end
628
*/
629
      8'b1100_011x: // mov: i->m (or i->r non-standard)
630
        begin
631
          seq_addr <= (mod==2'b11) ? (b ? `MOVIRB : `MOVIRW)
632
                                   : (b ? `MOVIMB : `MOVIMW);
633
          need_modrm <= 1'b1;
634
          need_off <= need_off_mod;
635
          off_size <= off_size_mod;
636
          need_imm <= 1'b1;
637
          imm_size <= ~b;
638
 
639
          src <= 4'b0;
640
          dst <= { 1'b0, rm };
641
        end
642
/*
643
      8'b1100_1010: // ret far with value
644
        begin
645
          seq_addr <= `RETFV;
646
          need_modrm <= 1'b0;
647
          need_off <= 1'b0;
648
          need_imm <= 1'b1;
649
          imm_size <= 1'b1;
650
        end
651
 
652
      8'b1100_1011: // ret far
653
        begin
654
          seq_addr <= `RETF0;
655
          need_modrm <= 1'b0;
656
          need_off <= 1'b0;
657
          need_imm <= 1'b0;
658
        end
659
 
660
      8'b1100_1100: // int 3
661
        begin
662
          seq_addr <= `INT3;
663
          need_modrm <= 1'b0;
664
          need_off <= 1'b0;
665
          need_imm <= 1'b0;
666
        end
667
 
668
      8'b1100_1101: // int
669
        begin
670
          seq_addr <= `INT;
671
          need_modrm <= 1'b0;
672
          need_off <= 1'b0;
673
          need_imm <= 1'b1;
674
          imm_size <= 1'b0;
675
        end
676
 
677
      8'b1100_1110: // into
678
        begin
679
          seq_addr <= `INTO;
680
          need_modrm <= 1'b0;
681
          need_off <= 1'b0;
682
          need_imm <= 1'b0;
683
        end
684
 
685
      8'b1100_1111: // iret
686
        begin
687
          seq_addr <= `IRET;
688
          need_modrm <= 1'b0;
689
          need_off <= 1'b0;
690
          need_imm <= 1'b0;
691
        end
692
 
693
      8'b1101_0111: // xlat
694
        begin
695
          seq_addr <= `XLAT;
696
          need_modrm <= 1'b0;
697
          need_off <= 1'b0;
698
          need_imm <= 1'b0;
699
        end
700
 
701
      8'b1110_0000: // loopne
702
        begin
703
          seq_addr <= `LOOPNE;
704
          need_modrm <= 1'b0;
705
          need_off <= 1'b0;
706
          need_imm <= 1'b1;
707
          imm_size <= 1'b0;
708
        end
709
 
710
      8'b1110_0001: // loope
711
        begin
712
          seq_addr <= `LOOPE;
713
          need_modrm <= 1'b0;
714
          need_off <= 1'b0;
715
          need_imm <= 1'b1;
716
          imm_size <= 1'b0;
717
        end
718
 
719
      8'b1110_0010: // loop
720
        begin
721
          seq_addr <= `LOOP;
722
          need_modrm <= 1'b0;
723
          need_off <= 1'b0;
724
          need_imm <= 1'b1;
725
          imm_size <= 1'b0;
726
        end
727
 
728
      8'b1110_0011: // jcxz
729
        begin
730
          seq_addr <= `JCXZ;
731
          need_modrm <= 1'b0;
732
          need_off <= 1'b0;
733
          need_imm <= 1'b1;
734
          imm_size <= 1'b0;
735
        end
736
 
737
      8'b1110_010x: // in imm
738
        begin
739
          seq_addr <= b ? `INIB : `INIW;
740
          need_modrm <= 1'b0;
741
          need_off <= 1'b0;
742
          need_imm <= 1'b1;
743
          imm_size <= 1'b0;
744
        end
745
 
746
      8'b1110_011x: // out imm
747
        begin
748
          seq_addr <= b ? `OUTIB : `OUTIW;
749
          need_modrm <= 1'b0;
750
          need_off <= 1'b0;
751
          need_imm <= 1'b1;
752
          imm_size <= 1'b0;
753
        end
754
 
755
      8'b1110_1000: // call same segment
756
        begin
757
          seq_addr <= `CALLN;
758
          need_modrm <= 1'b0;
759
          need_off <= 1'b0;
760
          need_imm <= 1'b1;
761
          imm_size <= 1'b1;
762
        end
763
*/
764
      8'b1110_10x1: // jmp direct
765
        begin
766
          seq_addr <= `JMPI;
767
          need_modrm <= 1'b0;
768
          need_off <= 1'b0;
769
          need_imm <= 1'b1;
770
          off_size <= 1'b0;
771
          imm_size <= ~opcode[1];
772
 
773
          src <= 4'b0;
774
          dst <= 4'b0;
775
        end
776
 
777
      8'b1110_1010: // jmp indirect different segment
778
        begin
779
          seq_addr <= `LJMPI;
780
          need_modrm <= 1'b0;
781
          need_off <= 1'b1;
782
          off_size <= 1'b1;
783
          need_imm <= 1'b1;
784
          imm_size <= 1'b1;
785
 
786
          src <= 4'b0;
787
          dst <= 4'b0;
788
        end
789
/*
790
      8'b1110_110x: // in dx
791
        begin
792
          seq_addr <= b ? `INRB : `INRW;
793
          need_modrm <= 1'b0;
794
          need_off <= 1'b0;
795
          need_imm <= 1'b0;
796
        end
797
 
798
      8'b1110_111x: // out dx
799
        begin
800
          seq_addr <= b ? `OUTRB : `OUTRW;
801
          need_modrm <= 1'b0;
802
          need_off <= 1'b0;
803
          need_imm <= 1'b0;
804
        end
805
*/
806
      8'b1111_0100: // hlt
807
        begin
808
          seq_addr <= `HLT;
809
          need_modrm <= 1'b0;
810
          need_off <= 1'b0;
811
          need_imm <= 1'b0;
812
          off_size <= 1'b0;
813
          imm_size <= 1'b0;
814
 
815
          src <= 4'b0;
816
          dst <= 4'b0;
817
        end
818
/*
819
      8'b1111_0101: // cmc
820
        begin
821
          seq_addr <= `CMC;
822
          need_modrm <= 1'b0;
823
          need_off <= 1'b0;
824
          need_imm <= 1'b0;
825
        end
826
 
827
      8'b1111_1000: // clc
828
        begin
829
          seq_addr <= `CLC;
830
          need_modrm <= 1'b0;
831
          need_off <= 1'b0;
832
          need_imm <= 1'b0;
833
        end
834
 
835
      8'b1111_1001: // stc
836
        begin
837
          seq_addr <= `STC;
838
          need_modrm <= 1'b0;
839
          need_off <= 1'b0;
840
          need_imm <= 1'b0;
841
        end
842
 
843
      8'b1111_1010: // cli
844
        begin
845
          seq_addr <= `CLI;
846
          need_modrm <= 1'b0;
847
          need_off <= 1'b0;
848
          need_imm <= 1'b0;
849
        end
850
 
851
      8'b1111_1011: // sti
852
        begin
853
          seq_addr <= `STI;
854
          need_modrm <= 1'b0;
855
          need_off <= 1'b0;
856
          need_imm <= 1'b0;
857
        end
858
 
859
      8'b1111_1100: // cld
860
        begin
861
          seq_addr <= `CLD;
862
          need_modrm <= 1'b0;
863
          need_off <= 1'b0;
864
          need_imm <= 1'b0;
865
        end
866
 
867
      8'b1111_1101: // std
868
        begin
869
          seq_addr <= `STD;
870
          need_modrm <= 1'b0;
871
          need_off <= 1'b0;
872
          need_imm <= 1'b0;
873
        end
874
*/
875
      8'b1111_1111:
876
        begin
877
          case (regm)
878
//             3'b010: seq_addr <= (mod==2'b11) ? `CALLNR : `CALLNM;
879
//             3'b011: seq_addr <= `CALLFM;
880
            3'b100: seq_addr <= (mod==2'b11) ? `JMPR : `JMPM;
881
            3'b101: seq_addr <= `LJMPM;
882
//             3'b110: seq_addr <= (mod==2'b11) ? `PUSHR : `PUSHM;
883
            default: seq_addr <= `NOP;
884
          endcase
885
          need_modrm <= 1'b1;
886
          need_off <= need_off_mod;
887
          need_imm <= 1'b0;
888
          off_size <= off_size_mod;
889
          imm_size <= 1'b0;
890
 
891
          src <= { 1'b0, rm };
892
          dst <= 4'b0;
893
        end
894
 
895
      default: // nop
896
        begin
897
          seq_addr <= `NOP;
898
          need_modrm <= 1'b0;
899
          need_off <= 1'b0;
900
          need_imm <= 1'b0;
901
          off_size <= 1'b0;
902
          imm_size <= 1'b0;
903
 
904
          src <= 4'b0;
905
          dst <= 4'b0;
906
        end
907
 
908
  endcase
909
 
910
endmodule
911
 
912
module memory_regs (
913
    input [2:0] rm,
914
    input [1:0] mod,
915
    output reg [3:0] base,
916
    output reg [3:0] index,
917
    output reg [1:0] seg
918
  );
919
 
920
  // Behaviour
921
  always @(rm or mod)
922
    case (rm)
923
      3'b000: begin base <= 4'b0011; index <= 4'b0110; seg <= 2'b11; end
924
      3'b001: begin base <= 4'b0011; index <= 4'b0111; seg <= 2'b11; end
925
      3'b010: begin base <= 4'b0101; index <= 4'b0110; seg <= 2'b10; end
926
      3'b011: begin base <= 4'b0101; index <= 4'b0111; seg <= 2'b10; end
927
      3'b100: begin base <= 4'b1100; index <= 4'b0110; seg <= 2'b11; end
928
      3'b101: begin base <= 4'b1100; index <= 4'b0111; seg <= 2'b11; end
929
      3'b110: begin base <= mod ? 4'b0101 : 4'b1100; index <= 4'b1100;
930
                    seg <= mod ? 2'b10 : 2'b11; end
931
      3'b111: begin base <= 4'b0011; index <= 4'b1100; seg <= 2'b11; end
932
    endcase
933
endmodule
934
 
935
module micro_data (
936
    input [`MICRO_ADDR_WIDTH-1:0] n_micro,
937
    input [15:0] off_i,
938
    input [15:0] imm_i,
939
    input [3:0] src,
940
    input [3:0] dst,
941
    input [3:0] base,
942
    input [3:0] index,
943
    input [1:0] seg,
944
    output [`IR_SIZE-1:0] ir,
945
    output [15:0] off_o,
946
    output [15:0] imm_o
947
  );
948
 
949
  // Net declarations
950
  wire [`MICRO_DATA_WIDTH-1:0] micro_o;
951
  wire [16:0] high_ir;
952
  wire var_s, var_off;
953
  wire [1:0] var_a, var_b, var_c, var_d;
954
  wire [2:0] var_imm;
955
 
956
  wire [3:0] addr_a, addr_b, addr_c, addr_d;
957
  wire [3:0] micro_a, micro_b, micro_c, micro_d;
958
  wire [1:0] addr_s, micro_s;
959
 
960
  // Module instantiations
961
  micro_rom m0 (n_micro, micro_o);
962
 
963
  // Assignments
964
  assign micro_s = micro_o[1:0];
965
  assign micro_a = micro_o[5:2];
966
  assign micro_b = micro_o[9:6];
967
  assign micro_c = micro_o[13:10];
968
  assign micro_d = micro_o[17:14];
969
  assign high_ir = micro_o[35:18];
970
  assign var_s   = micro_o[36];
971
  assign var_a   = micro_o[38:37];
972
  assign var_b   = micro_o[40:39];
973
  assign var_c   = micro_o[42:41];
974
  assign var_d   = micro_o[44:43];
975
  assign var_off = micro_o[45];
976
  assign var_imm = micro_o[48:46];
977
 
978
  assign imm_o = var_imm == 3'd0 ? (16'h0000)
979
               : (var_imm == 3'd1 ? (16'h0002)
980
               : (var_imm == 3'd2 ? (16'h0004)
981
               : (var_imm == 3'd3 ? off_i
982
               : (var_imm == 3'd4 ? imm_i
983
               : (var_imm == 3'd5 ? 16'hffff
984
               : (var_imm == 3'd6 ? 16'b11 : 16'd1))))));
985
 
986
  assign off_o = var_off ? off_i : 16'h0000;
987
 
988
  assign addr_a = var_a == 2'd0 ? micro_a
989
                : (var_a == 2'd1 ? base
990
                : (var_a == 2'd2 ? dst : src ));
991
  assign addr_b = var_b == 2'd0 ? micro_b
992
                : (var_b == 2'd1 ? index : src);
993
  assign addr_c = var_c == 2'd0 ? micro_c
994
                : (var_c == 2'd1 ? dst : src);
995
  assign addr_d = var_d == 2'd0 ? micro_d
996
                : (var_d == 2'd1 ? dst : src);
997
  assign addr_s = var_s ? seg : micro_s;
998
 
999
  assign ir = { high_ir, addr_d, addr_c, addr_b, addr_a, addr_s };
1000
endmodule
1001
 
1002
module micro_rom (
1003
    input [`MICRO_ADDR_WIDTH-1:0] addr,
1004
    output [`MICRO_DATA_WIDTH-1:0] q
1005
  );
1006
 
1007
  // Registers, nets and parameters
1008
  reg [`MICRO_DATA_WIDTH-1:0] rom[0:2**`MICRO_ADDR_WIDTH-1];
1009
 
1010
  // Assignments
1011
  assign q = rom[addr];
1012
 
1013
  // Behaviour
1014
        initial $readmemb("/home/zeus/zet/rtl-model/micro_rom.dat", rom);
1015
endmodule
1016
 
1017
module seq_rom (
1018
    input [`SEQ_ADDR_WIDTH-1:0] addr,
1019
    output [`SEQ_DATA_WIDTH-1:0] q
1020
  );
1021
 
1022
  // Registers, nets and parameters
1023
  reg [`SEQ_DATA_WIDTH-1:0] rom[0:2**`SEQ_ADDR_WIDTH-1];
1024
 
1025
  // Assignments
1026
  assign q = rom[addr];
1027
 
1028
  // Behaviour
1029
        initial $readmemb("/home/zeus/zet/rtl-model/seq_rom.dat", rom);
1030
endmodule

powered by: WebSVN 2.1.0

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