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

Subversion Repositories s80186

[/] [s80186/] [trunk/] [rtl/] [Core.sv] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 jamieiles
// Copyright Jamie Iles, 2017
2
//
3
// This file is part of s80x86.
4
//
5
// s80x86 is free software: you can redistribute it and/or modify
6
// it under the terms of the GNU General Public License as published by
7
// the Free Software Foundation, either version 3 of the License, or
8
// (at your option) any later version.
9
//
10
// s80x86 is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
// GNU General Public License for more details.
14
//
15
// You should have received a copy of the GNU General Public License
16
// along with s80x86.  If not, see .
17
 
18
module Core(input logic clk,
19
            input logic reset,
20
            // Interrupts
21
            input logic nmi,
22
            input logic intr,
23
            input logic [7:0] irq,
24
            output logic inta,
25
            // Instruction bus
26
            output logic [19:1] instr_m_addr,
27
            input logic [15:0] instr_m_data_in,
28
            output logic instr_m_access,
29
            input logic instr_m_ack,
30
            // Data bus
31
            output logic [19:1] data_m_addr,
32
            input logic [15:0] data_m_data_in,
33
            output logic [15:0] data_m_data_out,
34
            output logic data_m_access,
35
            input logic data_m_ack,
36
            output logic data_m_wr_en,
37
            output logic [1:0] data_m_bytesel,
38
            output logic d_io,
39
            output logic lock,
40
            // Debug
41
            output logic debug_stopped,
42
            input logic debug_seize,
43
            input logic [7:0] debug_addr,
44
            input logic debug_run,
45
            output logic [15:0] debug_val,
46
            input logic [15:0] debug_wr_val,
47
            input logic debug_wr_en);
48
 
49
// Internal busses.
50
wire [15:0] a_bus =
51
    a_sel == ADriver_RA ? reg_rd_val[0] :
52
    a_sel == ADriver_IP ? ip_current :
53
    a_sel == ADriver_MAR ? mar : mdr;
54
wire [15:0] b_bus =
55
    b_sel == BDriver_RB ? reg_rd_val[1] :
56
    b_sel == BDriver_IMMEDIATE ? immediate :
57
    b_sel == BDriver_SR ? seg_rd_val : tmp_val;
58
 
59
// Register file.
60
wire reg_is_8_bit = modrm_start & ~modrm_complete ? 1'b0 : is_8_bit;
61
wire [2:0] reg_rd_sel[2];
62
assign reg_rd_sel[0] = modrm_start && ~modrm_complete ? modrm_reg_rd_sel[0] :
63
    ra_modrm_rm_reg ? rm_regnum : microcode_reg_rd_sel[0];
64
assign reg_rd_sel[1] = modrm_start && ~modrm_complete ?
65
    modrm_reg_rd_sel[1] : rb_cl ? CL : regnum;
66
wire [2:0] reg_wr_sel =
67
    rd_sel_source == RDSelSource_MODRM_REG ? regnum :
68
    rd_sel_source == RDSelSource_MODRM_RM_REG ? rm_regnum :
69
    microcode_reg_wr_sel;
70
wire [15:0] reg_wr_val =
71
    reg_wr_source == RegWrSource_Q ? alu_out[15:0] :
72
    reg_wr_source == RegWrSource_QUOTIENT ? quotient : remainder;
73
wire reg_wr_en;
74
wire [15:0] reg_rd_val[2];
75
wire rb_cl;
76
wire [`MC_RDSelSource_t_BITS-1:0] rd_sel_source;
77
 
78
// Segment register file.
79
wire io_operation;
80
assign d_io = io_operation;
81
wire segment_force;
82
assign seg_wr_sel = segment_force ?
83
    microcode_segment : reg_wr_sel[1:0];
84
wire [15:0] seg_rd_val;
85
wire [15:0] seg_wr_val = alu_out[15:0];
86
wire [15:0] cs;
87
wire [1:0] segment;
88
wire segment_override;
89
wire segment_wr_en;
90
 
91
// Prefetch FIFO
92
wire fifo_wr_en;
93
wire fifo_rd_en = modrm_fifo_rd_en | immed_fifo_rd_en | microcode_fifo_rd_en;
94
wire [7:0] fifo_rd_data;
95
wire [7:0] fifo_wr_data;
96
wire fifo_empty;
97
wire fifo_full;
98
wire fifo_reset;
99
 
100
// CS:IP Synchronizer
101
wire cs_updating = seg_wr_sel == CS && segment_wr_en;
102
wire [15:0] prefetch_cs = cs_updating ? seg_wr_val : cs;
103
wire ip_wr_en;
104
wire [15:0] ip_current;
105
wire prefetch_load_new_ip;
106
wire [15:0] prefetch_new_ip;
107
 
108
// Immediate Reader
109
wire immed_start = modrm_immed_start | microcode_immed_start;
110
wire immed_busy;
111
wire immed_complete;
112
wire modrm_immed_is_8bit;
113
wire immed_is_8bit = modrm_immed_start ? modrm_immed_is_8bit : is_8_bit;
114
wire [15:0] immediate_reader_immediate;
115
wire [15:0] immediate = use_microcode_immediate ? microcode_immediate :
116
    immediate_reader_immediate;
117
wire immed_fifo_rd_en;
118
 
119
// ModRM Decoder
120
wire modrm_complete;
121
wire modrm_clear = reset | do_next_instruction;
122
wire [2:0] modrm_reg_rd_sel[2];
123
wire modrm_start;
124
wire modrm_busy;
125
wire modrm_uses_bp_as_base;
126
wire modrm_fifo_rd_en;
127
wire modrm_immed_start;
128
wire [2:0] regnum;
129
wire rm_is_reg;
130
wire [2:0] rm_regnum;
131
wire ra_modrm_rm_reg;
132
 
133
// Flags
134
wire [15:0] flags;
135
wire [8:0] update_flags;
136
 
137
// LoadStore
138
wire [15:0] mar;
139
wire [15:0] mdr;
140
wire microcode_write_mdr;
141
wire write_mdr = microcode_write_mdr | irq_to_mdr;
142
wire [15:0] mdr_in = microcode_write_mdr ? alu_out[15:0] : {8'b0, irq};
143
wire microcode_write_mar;
144
wire write_mar = microcode_write_mar & next_microinstruction;
145
wire mem_read;
146
wire mem_write;
147
wire mar_wr_sel;
148
wire [15:0] mar_wr_val;
149
wire loadstore_start = (mem_read | mem_write) & ~loadstore_complete;
150
wire loadstore_is_store = mem_write;
151
wire loadstore_complete;
152
wire loadstore_busy;
153
assign mar_wr_val = mar_wr_sel == MARWrSel_EA ?
154
    effective_address : alu_out[15:0];
155
 
156
// ALU
157
wire [`MC_ALUOp_t_BITS-1:0] alu_op;
158
wire [31:0] alu_out;
159
wire [15:0] alu_flags_out;
160
wire alu_busy;
161
 
162
// Microcode
163
wire [2:0] microcode_reg_rd_sel[2];
164
wire [2:0] microcode_reg_wr_sel;
165
wire [1:0] reg_wr_source;
166
wire [1:0] seg_wr_sel;
167
wire microcode_fifo_rd_en;
168
wire [1:0] a_sel;
169
wire [1:0] b_sel;
170
wire next_instruction;
171
wire is_8_bit;
172
wire [15:0] effective_address;
173
wire microcode_tmp_wr_en;
174
wire tmp_wr_en = microcode_tmp_wr_en | (debug_wr_en && debug_stopped);
175
wire [15:0] tmp_wr_val = debug_stopped && debug_wr_en ? debug_wr_val :
176
    (tmp_wr_sel == TEMPWrSel_Q_LOW) ?  alu_out[15:0] :
177
    alu_out[31:16];
178
wire tmp_wr_sel;
179
wire [15:0] tmp_val;
180
wire microcode_immed_start;
181
wire [15:0] microcode_immediate;
182
wire use_microcode_immediate;
183
wire [1:0] microcode_segment;
184
wire [7:0] opcode;
185
wire jump_taken;
186
wire multibit_shift;
187
wire rb_zero = ~|reg_rd_val[1];
188
wire nmi_pulse;
189
wire ext_int_yield;
190
wire irq_to_mdr;
191
wire loop_next;
192
wire loop_done;
193
wire is_hlt;
194
wire next_microinstruction;
195
 
196
// Misc control signals
197
wire debug_set_ip = debug_stopped && ip_wr_en;
198
wire do_next_instruction = (next_instruction & ~do_stall) | debug_set_ip;
199
wire do_stall = modrm_busy | immed_busy | loadstore_busy | divide_busy | alu_busy;
200
wire start_interrupt;
201
 
202
// IP
203
wire ip_inc = fifo_rd_en & ~fifo_empty & ~start_interrupt;
204
wire do_escape_fault;
205
wire ip_rollback = (start_interrupt & ext_int_yield & ~is_hlt) | do_escape_fault;
206
 
207
// Divider
208
wire [31:0] dividend8 = divide_signed ? {{16{tmp_val[15]}}, tmp_val} : {16'b0, tmp_val};
209
wire [31:0] dividend = is_8_bit ? dividend8 : {reg_rd_val[0], tmp_val};
210
wire [15:0] divisor8 = divide_signed ? {{8{mdr[7]}}, mdr[7:0]} : mdr;
211
wire [15:0] divisor = is_8_bit ? divisor8 : mdr;
212
wire [15:0] quotient;
213
wire [15:0] remainder;
214
wire divide_error;
215
wire divide_busy;
216
wire divide = alu_op == ALUOp_DIV || alu_op == ALUOp_IDIV;
217
wire divide_signed = alu_op == ALUOp_IDIV;
218
wire divide_complete;
219
wire do_divide = divide & ~divide_complete;
220
 
221
assign debug_val = tmp_val;
222
 
223
RegisterFile    RegisterFile(.clk(clk),
224
                             .reset(reset),
225
                             .is_8_bit(reg_is_8_bit),
226
                             .rd_sel(reg_rd_sel),
227
                             .rd_val(reg_rd_val),
228
                             .wr_sel(reg_wr_sel),
229
                             .wr_val(reg_wr_val),
230
                             .wr_en(reg_wr_en));
231
 
232
SegmentOverride SegmentOverride(.clk(clk),
233
                                .reset(reset),
234
                                .next_instruction(do_next_instruction),
235
                                .force_segment(segment_force),
236
                                .bp_is_base(modrm_uses_bp_as_base),
237
                                .segment_override(segment_override),
238
                                .microcode_sr_rd_sel(microcode_segment),
239
                                .sr_rd_sel(segment));
240
 
241
SegmentRegisterFile SegmentRegisterFile(.clk(clk),
242
                                        .reset(reset),
243
                                        .rd_sel(segment),
244
                                        .rd_val(seg_rd_val),
245
                                        .wr_en(segment_wr_en),
246
                                        .wr_sel(seg_wr_sel),
247
                                        .wr_val(seg_wr_val),
248
                                        .cs(cs));
249
 
250
Fifo            #(.data_width(8),
251
                  .depth(6))
252
                Fifo(.clk(clk),
253
                     .reset(reset | fifo_reset),
254
                     .wr_en(fifo_wr_en),
255
                     .wr_data(fifo_wr_data),
256
                     .rd_en(fifo_rd_en),
257
                     .rd_data(fifo_rd_data),
258
                     .empty(fifo_empty),
259
                     .nearly_full(fifo_full),
260
                     // verilator lint_off PINCONNECTEMPTY
261
                     .full()
262
                     // verilator lint_on PINCONNECTEMPTY
263
                    );
264
 
265
CSIPSync        CSIPSync(.clk(clk),
266
                         .reset(reset),
267
                         .cs_update(cs_updating),
268
                         .ip_update(ip_wr_en),
269
                         .ip_in(ip_current),
270
                         .new_ip(alu_out[15:0]),
271
                         .propagate(do_next_instruction),
272
                         .ip_out(prefetch_new_ip),
273
                         .update_out(prefetch_load_new_ip));
274
 
275
TempReg         TempReg(.clk(clk),
276
                        .reset(reset),
277
                        .wr_val(tmp_wr_val),
278
                        .wr_en(tmp_wr_en),
279
                        .val(tmp_val));
280
 
281
Prefetch        Prefetch(.clk(clk),
282
                         .reset(reset),
283
                         .new_cs(prefetch_cs),
284
                         .new_ip(prefetch_new_ip),
285
                         .load_new_ip(prefetch_load_new_ip),
286
                         .fifo_wr_en(fifo_wr_en),
287
                         .fifo_wr_data(fifo_wr_data),
288
                         .fifo_reset(fifo_reset),
289
                         .fifo_full(fifo_full),
290
                         .mem_access(instr_m_access),
291
                         .mem_ack(instr_m_ack),
292
                         .mem_address(instr_m_addr),
293
                         .mem_data(instr_m_data_in));
294
 
295
ImmediateReader ImmediateReader(.clk(clk),
296
                                .reset(reset),
297
                                // Control
298
                                .start(immed_start),
299
                                .busy(immed_busy),
300
                                .complete(immed_complete),
301
                                .is_8bit(immed_is_8bit),
302
                                // Result
303
                                .immediate(immediate_reader_immediate),
304
                                // Fifo read port
305
                                .fifo_rd_en(immed_fifo_rd_en),
306
                                .fifo_rd_data(fifo_rd_data),
307
                                .fifo_empty(fifo_empty));
308
 
309
LoopCounter LoopCounter(.clk(clk),
310
                        .count_in(immediate_reader_immediate[4:0]),
311
                        .load(immed_complete),
312
                        .next(loop_next),
313
                        .done(loop_done));
314
 
315
ModRMDecode     ModRMDecode(.clk(clk),
316
                            .reset(reset),
317
                            // Control
318
                            .start(modrm_start),
319
                            .busy(modrm_busy),
320
                            .complete(modrm_complete),
321
                            .clear(modrm_clear),
322
                            // Results
323
                            .effective_address(effective_address),
324
                            .regnum(regnum),
325
                            .rm_is_reg(rm_is_reg),
326
                            .rm_regnum(rm_regnum),
327
                            .bp_as_base(modrm_uses_bp_as_base),
328
                            // Registers
329
                            .reg_sel(modrm_reg_rd_sel),
330
                            .regs(reg_rd_val),
331
                            // Fifo Read Port
332
                            .fifo_rd_en(modrm_fifo_rd_en),
333
                            .fifo_rd_data(fifo_rd_data),
334
                            .fifo_empty(fifo_empty),
335
                            // Immediates
336
                            .immed_start(modrm_immed_start),
337
                            .immed_complete(immed_complete),
338
                            .immed_is_8bit(modrm_immed_is_8bit),
339
                            .immediate(immediate_reader_immediate));
340
 
341
Flags           Flags(.clk(clk),
342
                      .reset(reset),
343
                      .flags_in(alu_flags_out),
344
                      .flags_out(flags),
345
                      .update_flags(update_flags));
346
 
347
JumpTest        JumpTest(.opcode(opcode),
348
                         .flags(flags),
349
                         .taken(jump_taken));
350
 
351
LoadStore       LoadStore(.clk(clk),
352
                          .reset(reset),
353
                          // MAR
354
                          .write_mar(write_mar),
355
                          .segment(seg_rd_val),
356
                          .mar_in(mar_wr_val),
357
                          // MDR
358
                          .mar_out(mar),
359
                          .mdr_out(mdr),
360
                          .write_mdr(write_mdr),
361
                          .mdr_in(mdr_in),
362
                          // Memory bus
363
                          .m_addr(data_m_addr),
364
                          .m_data_in(data_m_data_in),
365
                          .m_data_out(data_m_data_out),
366
                          .m_access(data_m_access),
367
                          .m_ack(data_m_ack),
368
                          .m_wr_en(data_m_wr_en),
369
                          .m_bytesel(data_m_bytesel),
370
                          // Control
371
                          .start(loadstore_start),
372
                          .is_8bit(is_8_bit),
373
                          .wr_en(loadstore_is_store),
374
                          .busy(loadstore_busy),
375
                          .complete(loadstore_complete),
376
                          .io(io_operation));
377
 
378
PosedgeToPulse PosedgeToPulse(.d(nmi),
379
                              .q(nmi_pulse),
380
                              .*);
381
 
382
Microcode       Microcode(.clk(clk),
383
                          .reset(reset),
384
                          .nmi_pulse(nmi_pulse),
385
                          .intr(intr),
386
                          .inta(inta),
387
                          .irq_to_mdr(irq_to_mdr),
388
                          .start_interrupt(start_interrupt),
389
                          .do_escape_fault(do_escape_fault),
390
                          .stall(do_stall),
391
                          .divide_error(divide_error),
392
                          .modrm_reg(regnum),
393
                          .int_enabled(flags[IF_IDX]),
394
                          .zf(flags[ZF_IDX]),
395
                          .tf(flags[TF_IDX]),
396
                          .microcode_immediate(microcode_immediate),
397
                          .use_microcode_immediate(use_microcode_immediate),
398
                          .opcode(opcode),
399
                          .jump_taken(jump_taken),
400
                          .rb_zero(rb_zero),
401
                          .lock(lock),
402
                          .multibit_shift(multibit_shift),
403
                          .rm_is_reg(rm_is_reg),
404
                          .a_sel(a_sel),
405
                          .alu_op(alu_op),
406
                          .b_sel(b_sel),
407
                          .ext_int_yield(ext_int_yield),
408
                          .io(io_operation),
409
                          .next_instruction(next_instruction),
410
                          .read_immed(microcode_immed_start),
411
                          .load_ip(ip_wr_en),
412
                          .mar_wr_sel(mar_wr_sel),
413
                          .mar_write(microcode_write_mar),
414
                          .mdr_write(microcode_write_mdr),
415
                          .mem_read(mem_read),
416
                          .mem_write(mem_write),
417
                          .modrm_start(modrm_start),
418
                          .ra_modrm_rm_reg(ra_modrm_rm_reg),
419
                          .ra_sel(microcode_reg_rd_sel[0]),
420
                          .rb_cl(rb_cl),
421
                          .rd_sel_source(rd_sel_source),
422
                          .rd_sel(microcode_reg_wr_sel),
423
                          .reg_wr_en(reg_wr_en),
424
                          .reg_wr_source(reg_wr_source),
425
                          .segment(microcode_segment),
426
                          .segment_override(segment_override),
427
                          .segment_force(segment_force),
428
                          .segment_wr_en(segment_wr_en),
429
                          .tmp_wr_en(microcode_tmp_wr_en),
430
                          .tmp_wr_sel(tmp_wr_sel),
431
                          .update_flags(update_flags),
432
                          .width(is_8_bit),
433
                          .fifo_rd_en(microcode_fifo_rd_en),
434
                          .fifo_rd_data(fifo_rd_data),
435
                          .fifo_empty(fifo_empty),
436
                          .fifo_resetting(fifo_reset),
437
                          .loop_next(loop_next),
438
                          .loop_done(loop_done),
439
                          .is_hlt(is_hlt),
440
                          .next_microinstruction(next_microinstruction),
441
                          // Debug
442
                          .debug_stopped(debug_stopped),
443
                          .debug_seize(debug_seize),
444
                          .debug_addr(debug_addr),
445
                          .debug_run(debug_run));
446
 
447
IP              IP(.clk(clk),
448
                   .reset(reset),
449
                   .inc(ip_inc),
450
                   .start_instruction(next_instruction),
451
                   .rollback(ip_rollback),
452
                   .wr_en(prefetch_load_new_ip),
453
                   .wr_val(prefetch_new_ip),
454
                   .val(ip_current));
455
 
456
ALU             ALU(.a(a_bus),
457
                    .b(b_bus),
458
                    .out(alu_out),
459
                    .op(alu_op),
460
                    .is_8_bit(is_8_bit),
461
                    .flags_in(flags),
462
                    .flags_out(alu_flags_out),
463
                    .multibit_shift(multibit_shift),
464
                    .shift_count(tmp_val[4:0]),
465
                    .busy(alu_busy));
466
 
467
Divider         Divider(.clk(clk),
468
                        .reset(reset),
469
                        .start(do_divide),
470
                        .is_8_bit(is_8_bit),
471
                        .is_signed(divide_signed),
472
                        .busy(divide_busy),
473
                        .complete(divide_complete),
474
                        .error(divide_error),
475
                        .dividend(dividend),
476
                        .divisor(divisor),
477
                        .quotient(quotient),
478
                        .remainder(remainder));
479
 
480
`ifdef verilator
481
// verilator lint_off BLKANDNBLK
482
int instr_length;
483
// verilator lint_on BLKANDNBLK
484
 
485
always @(posedge clk)
486
    if (fifo_rd_en & ~fifo_empty)
487
        instr_length <= instr_length + 1;
488
 
489
export "DPI-C" function get_and_clear_instr_length;
490
 
491
function int get_and_clear_instr_length;
492
    get_and_clear_instr_length = instr_length;
493
    instr_length = 0;
494
endfunction
495
 
496
`endif
497
 
498
endmodule

powered by: WebSVN 2.1.0

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