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

Subversion Repositories oms8051mini

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

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

powered by: WebSVN 2.1.0

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