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

Subversion Repositories oms8051mini

[/] [oms8051mini/] [trunk/] [rtl/] [8051/] [oc8051_memory_interface.v] - Blame information for rev 25

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

Line No. Rev Author Line
1 2 dinesha
//////////////////////////////////////////////////////////////////////
2
////                                                              ////
3
////  8051 memory interface                                       ////
4
////                                                              ////
5
////  This file is part of the 8051 cores project                 ////
6
////  http://www.opencores.org/cores/oms8051mini/                 ////
7
////                                                              ////
8
////  Description                                                 ////
9
////   comunication betwen cpu and memory                         ////
10
////                                                              ////
11
////  To Do:                                                      ////
12
////   nothing                                                    ////
13
////                                                              ////
14
////  Author(s):                                                  ////
15
////      - Simon Teran, simont@opencores.org                     ////
16
////      - Dinesh Annayya, dinesha@opencores.org                 ////
17
////                                                              ////
18
//////////////////////////////////////////////////////////////////////
19 25 dinesha
////   v0.0 - Dinesh A, 5th Jan 2017
20
////        1. Active edge of reset changed from High to Low
21
//////////////////////////////////////////////////////////////////////
22 2 dinesha
////                                                              ////
23
//// Copyright (C) 2000 Authors and OPENCORES.ORG                 ////
24
////                                                              ////
25
//// This source file may be used and distributed without         ////
26
//// restriction provided that this copyright statement is not    ////
27
//// removed from the file and that any derivative work contains  ////
28
//// the original copyright notice and the associated disclaimer. ////
29
////                                                              ////
30
//// This source file is free software; you can redistribute it   ////
31
//// and/or modify it under the terms of the GNU Lesser General   ////
32
//// Public License as published by the Free Software Foundation; ////
33
//// either version 2.1 of the License, or (at your option) any   ////
34
//// later version.                                               ////
35
////                                                              ////
36
//// This source is distributed in the hope that it will be       ////
37
//// useful, but WITHOUT ANY WARRANTY; without even the implied   ////
38
//// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR      ////
39
//// PURPOSE.  See the GNU Lesser General Public License for more ////
40
//// details.                                                     ////
41
////                                                              ////
42
//// You should have received a copy of the GNU Lesser General    ////
43
//// Public License along with this source; if not, download it   ////
44
//// from http://www.opencores.org/lgpl.shtml                     ////
45
////                                                              ////
46
//////////////////////////////////////////////////////////////////////
47
//
48
// CVS Revision History
49
//
50
// $Log: not supported by cvs2svn $
51
// Revision 1.12  2003/07/01 20:47:39  simont
52
// add /* synopsys xx_case */ to case statments.
53
//
54
// Revision 1.11  2003/06/20 13:35:10  simont
55
// simualtion `ifdef added
56
//
57
// Revision 1.10  2003/06/05 11:15:02  simont
58
// fix bug.
59
//
60
// Revision 1.9  2003/06/03 17:09:57  simont
61
// pipelined acces to axternal instruction interface added.
62
//
63
// Revision 1.8  2003/05/12 16:27:40  simont
64
// fix bug in movc intruction.
65
//
66
// Revision 1.7  2003/05/06 09:39:34  simont
67
// cahnge assigment to pc_wait (remove istb_o)
68
//
69
// Revision 1.6  2003/05/05 15:46:37  simont
70
// add aditional alu destination to solve critical path.
71
//
72
// Revision 1.5  2003/04/25 17:15:51  simont
73
// change branch instruction execution (reduse needed clock periods).
74
//
75
// Revision 1.4  2003/04/16 10:04:09  simont
76
// chance idat_ir to 24 bit wide
77
//
78
// Revision 1.3  2003/04/11 10:05:08  simont
79
// Change pc add value from 23'h to 16'h
80
//
81
// Revision 1.2  2003/04/09 16:24:03  simont
82
// change wr_sft to 2 bit wire.
83
//
84
// Revision 1.1  2003/01/13 14:13:12  simont
85
// initial import
86
//
87
//
88
 
89
 
90
`include "top_defines.v"
91
 
92
 
93 25 dinesha
module oc8051_memory_interface (clk, resetn,
94 2 dinesha
 
95
//decoder
96
     wr_i,
97
     wr_bit_i,
98
     rd_sel,
99
     wr_sel,
100
     pc_wr_sel,
101
     pc_wr,
102
     pc,
103
     rd,
104
     mem_wait,
105
     mem_act,
106
     istb,
107
 
108
//internal ram
109
     wr_o,
110
     wr_bit_o,
111
     rd_addr,
112
     wr_addr,
113
     rd_ind,
114
     wr_ind,
115
     wr_dat,
116
 
117
     bit_in,
118
     in_ram,
119
     sfr,
120
     sfr_bit,
121
     bit_out,
122
     iram_out,
123
 
124
//program rom
125
     iadr_o,
126
     ea,
127
     ea_int,
128
     op1_out,
129
     op2_out,
130
     op3_out,
131
 
132
//internal
133
     idat_onchip,
134
 
135 20 dinesha
//external
136
     iack_i,
137
     istb_o,
138
     idat_i,
139 2 dinesha
 
140
//external data ram
141
     dadr_o,
142
     dwe_o,
143
     dstb_o,
144
     dack_i,
145
     ddat_i,
146
     ddat_o,
147
 
148
//interrupt interface
149
     intr,
150
     int_v,
151
     int_ack,
152
 
153
//alu
154
     des_acc,
155
     des1,
156
     des2,
157
 
158
//sfr's
159
     dptr,
160
     ri,
161
     sp,
162
     sp_w,
163
     rn,
164
     acc,
165
     reti
166
   );
167
 
168
 
169
input         clk,
170 25 dinesha
              resetn,
171 2 dinesha
              wr_i,
172
              wr_bit_i;
173
 
174
input         bit_in,
175
              sfr_bit,
176
              dack_i;
177
input [2:0]   mem_act;
178
input [7:0]   in_ram,
179
              sfr,
180
              acc,
181
              sp_w;
182 20 dinesha
input [31:0]  idat_i;
183 2 dinesha
 
184
output        bit_out,
185
              mem_wait,
186
              reti;
187
output [7:0]  iram_out,
188
              wr_dat;
189
 
190
reg           bit_out,
191
              reti;
192
reg [7:0]     iram_out,
193
              sp_r;
194
reg           rd_addr_r;
195
output        wr_o,
196
              wr_bit_o;
197
 
198
//????
199
reg           dack_ir;
200
reg [7:0]     ddat_ir;
201
reg [23:0]    idat_ir;
202
 
203
/////////////////////////////
204
//
205
//  rom_addr_sel
206
//
207
/////////////////////////////
208 20 dinesha
input         iack_i;
209 2 dinesha
input [7:0]   des_acc,
210
              des1,
211
              des2;
212
output [15:0] iadr_o;
213
 
214
wire          ea_rom_sel;
215
 
216
/////////////////////////////
217
//
218
// ext_addr_sel
219
//
220
/////////////////////////////
221
input [7:0]   ri,
222
              ddat_i;
223
input [15:0]  dptr;
224
 
225
output        dstb_o,
226
              dwe_o;
227
output [7:0]  ddat_o;
228
output [15:0] dadr_o;
229
 
230
/////////////////////////////
231
//
232
// ram_adr_sel
233
//
234
/////////////////////////////
235
 
236
input [2:0]   rd_sel,
237
              wr_sel;
238
input [4:0]   rn;
239
input [7:0]   sp;
240
 
241
output        rd_ind,
242
              wr_ind;
243
output [7:0]  wr_addr,
244
              rd_addr;
245
reg           rd_ind,
246
              wr_ind;
247
reg [7:0]     wr_addr,
248
              rd_addr;
249
 
250
reg [4:0]     rn_r;
251
reg [7:0]     ri_r,
252
              imm_r,
253
              imm2_r,
254
              op1_r;
255
wire [7:0]    imm,
256
              imm2;
257
 
258
/////////////////////////////
259
//
260
// op_select
261
//
262
/////////////////////////////
263
 
264
input         intr,
265
              rd,
266
              ea,
267
              ea_int,
268
              istb;
269
 
270
input  [7:0]  int_v;
271
 
272
input  [31:0] idat_onchip;
273
 
274 20 dinesha
output        int_ack,
275
              istb_o;
276 2 dinesha
 
277
output  [7:0] op1_out,
278
              op3_out,
279
              op2_out;
280
 
281
reg           int_ack_t,
282
              int_ack,
283
              int_ack_buff;
284
 
285
reg [7:0]     int_vec_buff;
286
reg [7:0]     op1_out,
287
              op2_buff,
288
              op3_buff;
289
reg [7:0]     op1_o,
290
              op2_o,
291
              op3_o;
292
 
293
reg [7:0]     op1_xt,
294
              op2_xt,
295
              op3_xt;
296
 
297
reg [7:0]     op1,
298
              op2,
299
              op3;
300
wire [7:0]    op2_direct;
301
 
302
input [2:0]   pc_wr_sel;
303
 
304
input         pc_wr;
305
output [15:0] pc;
306
 
307
reg [15:0]    pc;
308
 
309
//
310
//pc            program counter register, save current value
311
reg [15:0]    pc_buf;
312
wire [15:0]   alu;
313
 
314
 
315
reg           int_buff,
316
              int_buff1; // interrupt buffer: used to prevent interrupting in the middle of executin instructions
317
 
318
 
319
//
320
//
321
////////////////////////////
322
reg           istb_t,
323
              imem_wait,
324
              dstb_o,
325
              dwe_o;
326
 
327
reg [7:0]     ddat_o;
328
reg [15:0]    iadr_t,
329
              dadr_ot;
330
reg           dmem_wait;
331
wire          pc_wait;
332
wire [1:0]    bank;
333
wire [7:0]    isr_call;
334
 
335
reg [1:0]     op_length;
336
reg [2:0]     op_pos;
337
wire          inc_pc;
338
 
339
reg           pc_wr_r;
340
 
341
wire [15:0]   pc_out;
342
 
343
reg [31:0]    idat_cur,
344
              idat_old;
345
 
346
reg           inc_pc_r,
347
              pc_wr_r2;
348
 
349
reg [7:0]     cdata;
350
reg           cdone;
351
 
352
 
353
assign bank       = rn[4:3];
354
assign imm        = op2_out;
355
assign imm2       = op3_out;
356
assign alu        = {des2, des_acc};
357
assign ea_rom_sel = ea && ea_int;
358
assign wr_o       = wr_i;
359
assign wr_bit_o   = wr_bit_i;
360
 
361 20 dinesha
//assign mem_wait   = dmem_wait || imem_wait || pc_wr_r;
362 2 dinesha
assign mem_wait   = dmem_wait || imem_wait || pc_wr_r2;
363 20 dinesha
//assign mem_wait   = dmem_wait || imem_wait;
364
assign istb_o     = (istb || (istb_t & !iack_i)) && !dstb_o && !ea_rom_sel;
365 2 dinesha
 
366 20 dinesha
assign pc_wait    = rd && (ea_rom_sel || (!istb_t && iack_i));
367 2 dinesha
 
368
assign wr_dat     = des1;
369
 
370
 
371
`ifdef OC8051_SIMULATION
372 25 dinesha
  always @(negedge resetn) begin
373 2 dinesha
    #5
374
    if (ea_rom_sel)
375
      $display("   progran execution from external rom");
376
    else
377
      $display("   progran execution from internal rom");
378
  end
379
 
380
`endif
381
 
382
 
383
/////////////////////////////
384
//
385
//  ram_select
386
//
387
/////////////////////////////
388
always @(rd_addr_r or in_ram or sfr or bit_in or sfr_bit or rd_ind)
389
begin
390
  if (rd_addr_r && !rd_ind) begin
391
    iram_out = sfr;
392
    bit_out = sfr_bit;
393
  end else begin
394
    iram_out = in_ram;
395
    bit_out = bit_in;
396
  end
397
end
398
 
399
/////////////////////////////
400
//
401
// ram_adr_sel
402
//
403
/////////////////////////////
404
 
405 20 dinesha
always @(rd_sel or sp or ri or rn or imm or dadr_o[15:0] or bank)
406 2 dinesha
begin
407
  case (rd_sel) /* synopsys full_case parallel_case */
408
    `OC8051_RRS_RN   : rd_addr = {3'h0, rn};
409
    `OC8051_RRS_I    : rd_addr = ri;
410
    `OC8051_RRS_D    : rd_addr = imm;
411
    `OC8051_RRS_SP   : rd_addr = sp;
412
 
413
    `OC8051_RRS_B    : rd_addr = `OC8051_SFR_B;
414
    `OC8051_RRS_DPTR : rd_addr = `OC8051_SFR_DPTR_LO;
415
    `OC8051_RRS_PSW  : rd_addr = `OC8051_SFR_PSW;
416
    `OC8051_RRS_ACC  : rd_addr = `OC8051_SFR_ACC;
417 20 dinesha
//    default          : rd_addr = 2'bxx;
418 2 dinesha
  endcase
419
 
420
end
421
 
422
 
423
//
424
//
425 20 dinesha
always @(wr_sel or sp_w or rn_r or imm_r or ri_r or imm2_r or op1_r or dadr_o[15:0])
426 2 dinesha
begin
427
  case (wr_sel) /* synopsys full_case parallel_case */
428
    `OC8051_RWS_RN : wr_addr = {3'h0, rn_r};
429
    `OC8051_RWS_I  : wr_addr = ri_r;
430
    `OC8051_RWS_D  : wr_addr = imm_r;
431
    `OC8051_RWS_SP : wr_addr = sp_w;
432
    `OC8051_RWS_D3 : wr_addr = imm2_r;
433
    `OC8051_RWS_B  : wr_addr = `OC8051_SFR_B;
434
//    default        : wr_addr = 2'bxx;
435
  endcase
436
end
437
 
438 25 dinesha
always @(posedge clk or negedge resetn)
439
  if (resetn == 1'b0)
440 2 dinesha
    rd_ind <= #1 1'b0;
441
  else if ((rd_sel==`OC8051_RRS_I) || (rd_sel==`OC8051_RRS_SP))
442
    rd_ind <= #1 1'b1;
443
  else
444
    rd_ind <= #1 1'b0;
445
 
446
always @(wr_sel)
447
  if ((wr_sel==`OC8051_RWS_I) || (wr_sel==`OC8051_RWS_SP))
448
    wr_ind = 1'b1;
449
  else
450
    wr_ind = 1'b0;
451
 
452
 
453
/////////////////////////////
454
//
455
//  rom_addr_sel
456
//
457
/////////////////////////////
458
//
459
// output address is alu destination
460
// (instructions MOVC)
461
 
462 20 dinesha
//assign iadr_o = (istb_t & !iack_i) ? iadr_t : pc_out;
463 2 dinesha
assign iadr_o = (istb_t) ? iadr_t : pc_out;
464
 
465
 
466 25 dinesha
always @(posedge clk or negedge resetn)
467 2 dinesha
begin
468 25 dinesha
  if (resetn == 1'b0) begin
469 2 dinesha
    iadr_t <= #1 23'h0;
470
    istb_t <= #1 1'b0;
471
    imem_wait <= #1 1'b0;
472
    idat_ir <= #1 24'h0;
473
  end else if (mem_act==`OC8051_MAS_CODE) begin
474
    iadr_t <= #1 alu;
475
    istb_t <= #1 1'b1;
476
    imem_wait <= #1 1'b1;
477
  end else if (ea_rom_sel && imem_wait) begin
478
    imem_wait <= #1 1'b0;
479
  end else if (!imem_wait && istb_t) begin
480
    istb_t <= #1 1'b0;
481 20 dinesha
  end else if (iack_i) begin
482
    imem_wait <= #1 1'b0;
483
    idat_ir <= #1 idat_i [23:0];
484
  end
485 2 dinesha
end
486
 
487
/////////////////////////////
488
//
489
// ext_addr_sel
490
//
491
/////////////////////////////
492
 
493
assign dadr_o = dadr_ot;
494
 
495 25 dinesha
always @(posedge clk or negedge resetn)
496 2 dinesha
begin
497 25 dinesha
  if (resetn == 1'b0) begin
498 2 dinesha
    dwe_o <= #1 1'b0;
499
    dmem_wait <= #1 1'b0;
500
    dstb_o <= #1 1'b0;
501
    ddat_o <= #1 8'h00;
502
    dadr_ot <= #1 23'h0;
503
  end else if (dack_i) begin
504
    dwe_o <= #1 1'b0;
505
    dstb_o <= #1 1'b0;
506
    dmem_wait <= #1 1'b0;
507
  end else begin
508
    case (mem_act) /* synopsys full_case parallel_case */
509
      `OC8051_MAS_DPTR_R: begin  // read from external rom: acc=(dptr)
510
        dwe_o <= #1 1'b0;
511
        dstb_o <= #1 1'b1;
512
        ddat_o <= #1 8'h00;
513
        dadr_ot <= #1 {7'h0, dptr};
514
        dmem_wait <= #1 1'b1;
515
      end
516
      `OC8051_MAS_DPTR_W: begin  // write to external rom: (dptr)=acc
517
        dwe_o <= #1 1'b1;
518
        dstb_o <= #1 1'b1;
519
        ddat_o <= #1 acc;
520
        dadr_ot <= #1 {7'h0, dptr};
521
        dmem_wait <= #1 1'b1;
522
      end
523
      `OC8051_MAS_RI_R:   begin  // read from external rom: acc=(Ri)
524
        dwe_o <= #1 1'b0;
525
        dstb_o <= #1 1'b1;
526
        ddat_o <= #1 8'h00;
527
        dadr_ot <= #1 {15'h0, ri};
528
        dmem_wait <= #1 1'b1;
529
      end
530
      `OC8051_MAS_RI_W: begin    // write to external rom: (Ri)=acc
531
        dwe_o <= #1 1'b1;
532
        dstb_o <= #1 1'b1;
533
        ddat_o <= #1 acc;
534
        dadr_ot <= #1 {15'h0, ri};
535
        dmem_wait <= #1 1'b1;
536
      end
537
    endcase
538
  end
539
end
540
 
541
/////////////////////////////
542
//
543
// op_select
544
//
545
/////////////////////////////
546
 
547
 
548
 
549 25 dinesha
always @(posedge clk or negedge resetn)
550 2 dinesha
begin
551 25 dinesha
  if (resetn == 1'b0) begin
552 2 dinesha
    idat_cur <= #1 32'h0;
553
    idat_old <= #1 32'h0;
554 20 dinesha
  end else if ((iack_i | ea_rom_sel) & (inc_pc | pc_wr_r2)) begin
555
    idat_cur <= #1 ea_rom_sel ? idat_onchip : idat_i;
556 2 dinesha
    idat_old <= #1 idat_cur;
557
  end
558
 
559
end
560
 
561 25 dinesha
always @(posedge clk or negedge resetn)
562 2 dinesha
begin
563 25 dinesha
  if (resetn == 1'b0) begin
564 2 dinesha
    cdata <= #1 8'h00;
565
    cdone <= #1 1'b0;
566
  end else if (istb_t) begin
567 20 dinesha
    cdata <= #1 ea_rom_sel ? idat_onchip[7:0] : idat_i[7:0];
568 2 dinesha
    cdone <= #1 1'b1;
569
  end else begin
570
    cdone <= #1 1'b0;
571
  end
572
end
573
 
574 20 dinesha
always @(op_pos or idat_cur or idat_old)
575 2 dinesha
begin
576
  case (op_pos)  /* synopsys parallel_case */
577
    3'b000: begin
578
       op1 = idat_old[7:0]  ;
579
       op2 = idat_old[15:8] ;
580
       op3 = idat_old[23:16];
581
      end
582
    3'b001: begin
583
       op1 = idat_old[15:8] ;
584
       op2 = idat_old[23:16];
585
       op3 = idat_old[31:24];
586
      end
587
    3'b010: begin
588
       op1 = idat_old[23:16];
589
       op2 = idat_old[31:24];
590
       op3 = idat_cur[7:0]  ;
591
      end
592
    3'b011: begin
593
       op1 = idat_old[31:24];
594
       op2 = idat_cur[7:0]  ;
595
       op3 = idat_cur[15:8] ;
596
      end
597
    3'b100: begin
598
       op1 = idat_cur[7:0]  ;
599
       op2 = idat_cur[15:8] ;
600
       op3 = idat_cur[23:16];
601
      end
602
    default: begin
603
       op1 = idat_cur[15:8] ;
604
       op2 = idat_cur[23:16];
605
       op3 = idat_cur[31:24];
606
      end
607
  endcase
608
end
609
 
610 20 dinesha
 
611
always @(dack_ir or ddat_ir or op1_o or iram_out or cdone or cdata)
612 2 dinesha
  if (dack_ir)
613
    op1_out = ddat_ir;
614
  else if (cdone)
615
    op1_out = cdata;
616
  else
617
    op1_out = op1_o;
618
 
619
assign op3_out = (rd) ? op3_o : op3_buff;
620
assign op2_out = (rd) ? op2_o : op2_buff;
621
 
622 20 dinesha
always @(idat_i or iack_i or idat_ir or rd)
623 2 dinesha
begin
624 20 dinesha
  if (iack_i) begin
625
    op1_xt = idat_i[7:0];
626
    op2_xt = idat_i[15:8];
627
    op3_xt = idat_i[23:16];
628
  end else if (!rd) begin
629 2 dinesha
    op1_xt = idat_ir[7:0];
630
    op2_xt = idat_ir[15:8];
631
    op3_xt = idat_ir[23:16];
632
  end else begin
633
    op1_xt = 8'h00;
634
    op2_xt = 8'h00;
635
    op3_xt = 8'h00;
636
  end
637
end
638
 
639
 
640
//
641
// in case of interrupts
642 20 dinesha
always @(op1 or op2 or op3 or int_ack_t or int_vec_buff or iack_i or ea_rom_sel)
643 2 dinesha
begin
644 20 dinesha
  if (int_ack_t && (iack_i || ea_rom_sel)) begin
645 2 dinesha
    op1_o = `OC8051_LCALL;
646
    op2_o = 8'h00;
647
    op3_o = int_vec_buff;
648
  end else begin
649
    op1_o = op1;
650
    op2_o = op2;
651
    op3_o = op3;
652
  end
653
end
654
 
655
//
656
//in case of reti
657 25 dinesha
always @(posedge clk or negedge resetn)
658
  if (resetn == 1'b0) reti <= #1 1'b0;
659 2 dinesha
  else if ((op1_o==`OC8051_RETI) & rd & !mem_wait) reti <= #1 1'b1;
660
  else reti <= #1 1'b0;
661
 
662
//
663
// remember inputs
664 25 dinesha
always @(posedge clk or negedge resetn)
665 2 dinesha
begin
666 25 dinesha
  if (resetn == 1'b0) begin
667 2 dinesha
    op2_buff <= #1 8'h0;
668
    op3_buff <= #1 8'h0;
669
  end else if (rd) begin
670
    op2_buff <= #1 op2_o;
671
    op3_buff <= #1 op3_o;
672
  end
673
end
674
 
675
/////////////////////////////
676
//
677
//  pc
678
//
679
/////////////////////////////
680
 
681 20 dinesha
always @(op1_out)
682 2 dinesha
begin
683
        casex (op1_out) /* synopsys parallel_case */
684
          `OC8051_ACALL :  op_length = 2'h2;
685
          `OC8051_AJMP :   op_length = 2'h2;
686
 
687
        //op_code [7:3]
688
          `OC8051_CJNE_R : op_length = 2'h3;
689
          `OC8051_DJNZ_R : op_length = 2'h2;
690
          `OC8051_MOV_DR : op_length = 2'h2;
691
          `OC8051_MOV_CR : op_length = 2'h2;
692
          `OC8051_MOV_RD : op_length = 2'h2;
693
 
694
        //op_code [7:1]
695
          `OC8051_CJNE_I : op_length = 2'h3;
696
          `OC8051_MOV_ID : op_length = 2'h2;
697
          `OC8051_MOV_DI : op_length = 2'h2;
698
          `OC8051_MOV_CI : op_length = 2'h2;
699
 
700
        //op_code [7:0]
701
          `OC8051_ADD_D :  op_length = 2'h2;
702
          `OC8051_ADD_C :  op_length = 2'h2;
703
          `OC8051_ADDC_D : op_length = 2'h2;
704
          `OC8051_ADDC_C : op_length = 2'h2;
705
          `OC8051_ANL_D :  op_length = 2'h2;
706
          `OC8051_ANL_C :  op_length = 2'h2;
707
          `OC8051_ANL_DD : op_length = 2'h2;
708
          `OC8051_ANL_DC : op_length = 2'h3;
709
          `OC8051_ANL_B :  op_length = 2'h2;
710
          `OC8051_ANL_NB : op_length = 2'h2;
711
          `OC8051_CJNE_D : op_length = 2'h3;
712
          `OC8051_CJNE_C : op_length = 2'h3;
713
          `OC8051_CLR_B :  op_length = 2'h2;
714
          `OC8051_CPL_B :  op_length = 2'h2;
715
          `OC8051_DEC_D :  op_length = 2'h2;
716
          `OC8051_DJNZ_D : op_length = 2'h3;
717
          `OC8051_INC_D :  op_length = 2'h2;
718
          `OC8051_JB :     op_length = 2'h3;
719
          `OC8051_JBC :    op_length = 2'h3;
720
          `OC8051_JC :     op_length = 2'h2;
721
          `OC8051_JNB :    op_length = 2'h3;
722
          `OC8051_JNC :    op_length = 2'h2;
723
          `OC8051_JNZ :    op_length = 2'h2;
724
          `OC8051_JZ :     op_length = 2'h2;
725
          `OC8051_LCALL :  op_length = 2'h3;
726
          `OC8051_LJMP :   op_length = 2'h3;
727
          `OC8051_MOV_D :  op_length = 2'h2;
728
          `OC8051_MOV_C :  op_length = 2'h2;
729
          `OC8051_MOV_DA : op_length = 2'h2;
730
          `OC8051_MOV_DD : op_length = 2'h3;
731
          `OC8051_MOV_CD : op_length = 2'h3;
732
          `OC8051_MOV_BC : op_length = 2'h2;
733
          `OC8051_MOV_CB : op_length = 2'h2;
734
          `OC8051_MOV_DP : op_length = 2'h3;
735
          `OC8051_ORL_D :  op_length = 2'h2;
736
          `OC8051_ORL_C :  op_length = 2'h2;
737
          `OC8051_ORL_AD : op_length = 2'h2;
738
          `OC8051_ORL_CD : op_length = 2'h3;
739
          `OC8051_ORL_B :  op_length = 2'h2;
740
          `OC8051_ORL_NB : op_length = 2'h2;
741
          `OC8051_POP :    op_length = 2'h2;
742
          `OC8051_PUSH :   op_length = 2'h2;
743
          `OC8051_SETB_B : op_length = 2'h2;
744
          `OC8051_SJMP :   op_length = 2'h2;
745
          `OC8051_SUBB_D : op_length = 2'h2;
746
          `OC8051_SUBB_C : op_length = 2'h2;
747
          `OC8051_XCH_D :  op_length = 2'h2;
748
          `OC8051_XRL_D :  op_length = 2'h2;
749
          `OC8051_XRL_C :  op_length = 2'h2;
750
          `OC8051_XRL_AD : op_length = 2'h2;
751
          `OC8051_XRL_CD : op_length = 2'h3;
752
          default:         op_length = 2'h1;
753
        endcase
754
end
755
 
756
 
757
assign inc_pc = ((op_pos[2] | (&op_pos[1:0])) & rd) | pc_wr_r2;
758
 
759 25 dinesha
always @(posedge clk or negedge resetn)
760 2 dinesha
begin
761 25 dinesha
  if (resetn == 1'b0) begin
762 2 dinesha
    op_pos <= #1 3'h0;
763
  end else if (pc_wr_r2) begin
764 20 dinesha
    op_pos <= #1 3'h4;// - op_length;////****??????????
765 2 dinesha
  end else if (inc_pc & rd) begin
766
    op_pos[2]   <= #1 op_pos[2] & !op_pos[1] & op_pos[0] & (&op_length);
767
    op_pos[1:0] <= #1 op_pos[1:0] + op_length;
768
  end else if (rd) begin
769
    op_pos <= #1 op_pos + {1'b0, op_length};
770
  end
771
end
772
 
773
//
774
// remember interrupt
775
// we don't want to interrupt instruction in the middle of execution
776 25 dinesha
always @(posedge clk or negedge resetn)
777
 if (resetn == 1'b0) begin
778 2 dinesha
   int_ack_t <= #1 1'b0;
779
   int_vec_buff <= #1 8'h00;
780
 end else if (intr) begin
781
   int_ack_t <= #1 1'b1;
782
   int_vec_buff <= #1 int_v;
783 20 dinesha
 end else if (rd && (ea_rom_sel || iack_i) && !pc_wr_r2) int_ack_t <= #1 1'b0;
784 2 dinesha
 
785 25 dinesha
always @(posedge clk or negedge resetn)
786
  if (resetn == 1'b0) int_ack_buff <= #1 1'b0;
787 2 dinesha
  else int_ack_buff <= #1 int_ack_t;
788
 
789 25 dinesha
always @(posedge clk or negedge resetn)
790
  if (resetn == 1'b0) int_ack <= #1 1'b0;
791 2 dinesha
  else begin
792
    if ((int_ack_buff) & !(int_ack_t))
793
      int_ack <= #1 1'b1;
794
    else int_ack <= #1 1'b0;
795
  end
796
 
797
 
798
//
799
//interrupt buffer
800 25 dinesha
always @(posedge clk or negedge resetn)
801
  if (resetn == 1'b0) begin
802 2 dinesha
    int_buff1 <= #1 1'b0;
803
  end else begin
804
    int_buff1 <= #1 int_buff;
805
  end
806
 
807 25 dinesha
always @(posedge clk or negedge resetn)
808
  if (resetn == 1'b0) begin
809 2 dinesha
    int_buff <= #1 1'b0;
810
  end else if (intr) begin
811
    int_buff <= #1 1'b1;
812
  end else if (pc_wait)
813
    int_buff <= #1 1'b0;
814
 
815
wire [7:0]  pcs_source;
816
reg  [15:0] pcs_result;
817
reg         pcs_cy;
818
 
819
assign pcs_source = pc_wr_sel[0] ? op3_out : op2_out;
820
 
821
always @(pcs_source or pc or pcs_cy)
822
begin
823
  if (pcs_source[7]) begin
824
    {pcs_cy, pcs_result[7:0]} = {1'b0, pc[7:0]} + {1'b0, pcs_source};
825
    pcs_result[15:8] = pc[15:8] - {7'h0, !pcs_cy};
826
  end else pcs_result = pc + {8'h00, pcs_source};
827
end
828
 
829 20 dinesha
 
830 25 dinesha
always @(posedge clk or negedge resetn)
831 2 dinesha
begin
832 25 dinesha
  if (resetn == 1'b0)
833 2 dinesha
    pc <= #1 16'h0;
834
  else if (pc_wr_r2)
835
    pc <= #1 pc_buf;
836
  else if (rd & !int_ack_t)
837
    pc <= #1 pc_buf - 16'h8 + {13'h0, op_pos} + {14'h0, op_length};
838
end
839
 
840
 
841 25 dinesha
always @(posedge clk or negedge resetn)
842 2 dinesha
begin
843 25 dinesha
  if (resetn == 1'b0) begin
844 2 dinesha
    pc_buf <= #1 `OC8051_RST_PC;
845
  end else if (pc_wr) begin
846
//
847
//case of writing new value to pc (jupms)
848
      case (pc_wr_sel) /* synopsys full_case parallel_case */
849
        `OC8051_PIS_ALU: pc_buf        <= #1 alu;
850
        `OC8051_PIS_AL:  pc_buf[7:0]   <= #1 alu[7:0];
851
        `OC8051_PIS_AH:  pc_buf[15:8]  <= #1 alu[7:0];
852
        `OC8051_PIS_I11: pc_buf[10:0]  <= #1 {op1_out[7:5], op2_out};
853
        `OC8051_PIS_I16: pc_buf        <= #1 {op2_out, op3_out};
854
        `OC8051_PIS_SO1: pc_buf        <= #1 pcs_result;
855
        `OC8051_PIS_SO2: pc_buf        <= #1 pcs_result;
856
      endcase
857
//  end else if (inc_pc) begin
858
  end else begin
859
//
860
//or just remember current
861
      pc_buf <= #1 pc_out;
862
  end
863
end
864
 
865
 
866
assign pc_out = inc_pc ? pc_buf + 16'h4
867
                       : pc_buf ;
868
 
869
 
870
 
871
 
872
 
873 25 dinesha
always @(posedge clk or negedge resetn)
874
  if (resetn == 1'b0)
875 2 dinesha
    ddat_ir <= #1 8'h00;
876
  else if (dack_i)
877
    ddat_ir <= #1 ddat_i;
878
 
879 20 dinesha
 
880 2 dinesha
////////////////////////
881 25 dinesha
always @(posedge clk or negedge resetn)
882
  if (resetn == 1'b0) begin
883 2 dinesha
    rn_r      <= #1 5'd0;
884
    ri_r      <= #1 8'h00;
885
    imm_r     <= #1 8'h00;
886
    imm2_r    <= #1 8'h00;
887
    rd_addr_r <= #1 1'b0;
888
    op1_r     <= #1 8'h0;
889
    dack_ir   <= #1 1'b0;
890
    sp_r      <= #1 1'b0;
891
    pc_wr_r   <= #1 1'b0;
892
    pc_wr_r2  <= #1 1'b0;
893
  end else begin
894
    rn_r      <= #1 rn;
895
    ri_r      <= #1 ri;
896
    imm_r     <= #1 imm;
897
    imm2_r    <= #1 imm2;
898
    rd_addr_r <= #1 rd_addr[7];
899
    op1_r     <= #1 op1_out;
900
    dack_ir   <= #1 dack_i;
901
    sp_r      <= #1 sp;
902
    pc_wr_r   <= #1 pc_wr && (pc_wr_sel != `OC8051_PIS_AH);
903
    pc_wr_r2  <= #1 pc_wr_r;
904
  end
905
 
906 25 dinesha
always @(posedge clk or negedge resetn)
907
  if (resetn == 1'b0) begin
908 2 dinesha
    inc_pc_r  <= #1 1'b1;
909
  end else if (istb) begin
910
    inc_pc_r  <= #1 inc_pc;
911
  end
912
 
913
`ifdef OC8051_SIMULATION
914
 
915
initial
916
begin
917 25 dinesha
  wait (!resetn)
918 2 dinesha
  if (ea_rom_sel) begin
919
    $display(" ");
920
    $display("\t Program running from internal rom !");
921
    $display(" ");
922
  end else begin
923
    $display(" ");
924
    $display("\t Program running from external rom !");
925
    $display(" ");
926
  end
927
end
928
`endif
929
 
930
 
931
endmodule

powered by: WebSVN 2.1.0

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