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

Subversion Repositories oms8051mini

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

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 dinesha
//////////////////////////////////////////////////////////////////////
18
////   v0.0 - Dinesh A, 17th Dec 2016
19
////        1. External ROM Interface Removed
20 2 dinesha
////                                                              ////
21
//////////////////////////////////////////////////////////////////////
22
////                                                              ////
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
module oc8051_memory_interface (clk, rst,
94
 
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
 
136
//external data ram
137
     dadr_o,
138
     dwe_o,
139
     dstb_o,
140
     dack_i,
141
     ddat_i,
142
     ddat_o,
143
 
144
//interrupt interface
145
     intr,
146
     int_v,
147
     int_ack,
148
 
149
//alu
150
     des_acc,
151
     des1,
152
     des2,
153
 
154
//sfr's
155
     dptr,
156
     ri,
157
     sp,
158
     sp_w,
159
     rn,
160
     acc,
161
     reti
162
   );
163
 
164
 
165
input         clk,
166
              rst,
167
              wr_i,
168
              wr_bit_i;
169
 
170
input         bit_in,
171
              sfr_bit,
172
              dack_i;
173
input [2:0]   mem_act;
174
input [7:0]   in_ram,
175
              sfr,
176
              acc,
177
              sp_w;
178
 
179
output        bit_out,
180
              mem_wait,
181
              reti;
182
output [7:0]  iram_out,
183
              wr_dat;
184
 
185
reg           bit_out,
186
              reti;
187
reg [7:0]     iram_out,
188
              sp_r;
189
reg           rd_addr_r;
190
output        wr_o,
191
              wr_bit_o;
192
 
193
//????
194
reg           dack_ir;
195
reg [7:0]     ddat_ir;
196
reg [23:0]    idat_ir;
197
 
198
/////////////////////////////
199
//
200
//  rom_addr_sel
201
//
202
/////////////////////////////
203
input [7:0]   des_acc,
204
              des1,
205
              des2;
206
output [15:0] iadr_o;
207
 
208
wire          ea_rom_sel;
209
 
210
/////////////////////////////
211
//
212
// ext_addr_sel
213
//
214
/////////////////////////////
215
input [7:0]   ri,
216
              ddat_i;
217
input [15:0]  dptr;
218
 
219
output        dstb_o,
220
              dwe_o;
221
output [7:0]  ddat_o;
222
output [15:0] dadr_o;
223
 
224
/////////////////////////////
225
//
226
// ram_adr_sel
227
//
228
/////////////////////////////
229
 
230
input [2:0]   rd_sel,
231
              wr_sel;
232
input [4:0]   rn;
233
input [7:0]   sp;
234
 
235
output        rd_ind,
236
              wr_ind;
237
output [7:0]  wr_addr,
238
              rd_addr;
239
reg           rd_ind,
240
              wr_ind;
241
reg [7:0]     wr_addr,
242
              rd_addr;
243
 
244
reg [4:0]     rn_r;
245
reg [7:0]     ri_r,
246
              imm_r,
247
              imm2_r,
248
              op1_r;
249
wire [7:0]    imm,
250
              imm2;
251
 
252
/////////////////////////////
253
//
254
// op_select
255
//
256
/////////////////////////////
257
 
258
input         intr,
259
              rd,
260
              ea,
261
              ea_int,
262
              istb;
263
 
264
input  [7:0]  int_v;
265
 
266
input  [31:0] idat_onchip;
267
 
268 18 dinesha
output        int_ack;
269 2 dinesha
 
270
output  [7:0] op1_out,
271
              op3_out,
272
              op2_out;
273
 
274
reg           int_ack_t,
275
              int_ack,
276
              int_ack_buff;
277
 
278
reg [7:0]     int_vec_buff;
279
reg [7:0]     op1_out,
280
              op2_buff,
281
              op3_buff;
282
reg [7:0]     op1_o,
283
              op2_o,
284
              op3_o;
285
 
286
reg [7:0]     op1_xt,
287
              op2_xt,
288
              op3_xt;
289
 
290
reg [7:0]     op1,
291
              op2,
292
              op3;
293
wire [7:0]    op2_direct;
294
 
295
input [2:0]   pc_wr_sel;
296
 
297
input         pc_wr;
298
output [15:0] pc;
299
 
300
reg [15:0]    pc;
301
 
302
//
303
//pc            program counter register, save current value
304
reg [15:0]    pc_buf;
305
wire [15:0]   alu;
306
 
307
 
308
reg           int_buff,
309
              int_buff1; // interrupt buffer: used to prevent interrupting in the middle of executin instructions
310
 
311
 
312
//
313
//
314
////////////////////////////
315
reg           istb_t,
316
              imem_wait,
317
              dstb_o,
318
              dwe_o;
319
 
320
reg [7:0]     ddat_o;
321
reg [15:0]    iadr_t,
322
              dadr_ot;
323
reg           dmem_wait;
324
wire          pc_wait;
325
wire [1:0]    bank;
326
wire [7:0]    isr_call;
327
 
328
reg [1:0]     op_length;
329
reg [2:0]     op_pos;
330
wire          inc_pc;
331
 
332
reg           pc_wr_r;
333
 
334
wire [15:0]   pc_out;
335
 
336
reg [31:0]    idat_cur,
337
              idat_old;
338
 
339
reg           inc_pc_r,
340
              pc_wr_r2;
341
 
342
reg [7:0]     cdata;
343
reg           cdone;
344
 
345
 
346
assign bank       = rn[4:3];
347
assign imm        = op2_out;
348
assign imm2       = op3_out;
349
assign alu        = {des2, des_acc};
350
assign ea_rom_sel = ea && ea_int;
351
assign wr_o       = wr_i;
352
assign wr_bit_o   = wr_bit_i;
353
 
354
assign mem_wait   = dmem_wait || imem_wait || pc_wr_r2;
355
 
356 18 dinesha
assign pc_wait    = rd ;
357 2 dinesha
 
358
assign wr_dat     = des1;
359
 
360
 
361
`ifdef OC8051_SIMULATION
362
  always @(negedge rst) begin
363
    #5
364
    if (ea_rom_sel)
365
      $display("   progran execution from external rom");
366
    else
367
      $display("   progran execution from internal rom");
368
  end
369
 
370
`endif
371
 
372
 
373
/////////////////////////////
374
//
375
//  ram_select
376
//
377
/////////////////////////////
378
always @(rd_addr_r or in_ram or sfr or bit_in or sfr_bit or rd_ind)
379
begin
380
  if (rd_addr_r && !rd_ind) begin
381
    iram_out = sfr;
382
    bit_out = sfr_bit;
383
  end else begin
384
    iram_out = in_ram;
385
    bit_out = bit_in;
386
  end
387
end
388
 
389
/////////////////////////////
390
//
391
// ram_adr_sel
392
//
393
/////////////////////////////
394
 
395 18 dinesha
always @(*)
396 2 dinesha
begin
397
  case (rd_sel) /* synopsys full_case parallel_case */
398
    `OC8051_RRS_RN   : rd_addr = {3'h0, rn};
399
    `OC8051_RRS_I    : rd_addr = ri;
400
    `OC8051_RRS_D    : rd_addr = imm;
401
    `OC8051_RRS_SP   : rd_addr = sp;
402
 
403
    `OC8051_RRS_B    : rd_addr = `OC8051_SFR_B;
404
    `OC8051_RRS_DPTR : rd_addr = `OC8051_SFR_DPTR_LO;
405
    `OC8051_RRS_PSW  : rd_addr = `OC8051_SFR_PSW;
406
    `OC8051_RRS_ACC  : rd_addr = `OC8051_SFR_ACC;
407
  endcase
408
 
409
end
410
 
411
 
412
//
413
//
414 18 dinesha
always @(*)
415 2 dinesha
begin
416
  case (wr_sel) /* synopsys full_case parallel_case */
417
    `OC8051_RWS_RN : wr_addr = {3'h0, rn_r};
418
    `OC8051_RWS_I  : wr_addr = ri_r;
419
    `OC8051_RWS_D  : wr_addr = imm_r;
420
    `OC8051_RWS_SP : wr_addr = sp_w;
421
    `OC8051_RWS_D3 : wr_addr = imm2_r;
422
    `OC8051_RWS_B  : wr_addr = `OC8051_SFR_B;
423
//    default        : wr_addr = 2'bxx;
424
  endcase
425
end
426
 
427
always @(posedge clk or posedge rst)
428
  if (rst)
429
    rd_ind <= #1 1'b0;
430
  else if ((rd_sel==`OC8051_RRS_I) || (rd_sel==`OC8051_RRS_SP))
431
    rd_ind <= #1 1'b1;
432
  else
433
    rd_ind <= #1 1'b0;
434
 
435
always @(wr_sel)
436
  if ((wr_sel==`OC8051_RWS_I) || (wr_sel==`OC8051_RWS_SP))
437
    wr_ind = 1'b1;
438
  else
439
    wr_ind = 1'b0;
440
 
441
 
442
/////////////////////////////
443
//
444
//  rom_addr_sel
445
//
446
/////////////////////////////
447
//
448
// output address is alu destination
449
// (instructions MOVC)
450
 
451
assign iadr_o = (istb_t) ? iadr_t : pc_out;
452
 
453
 
454
always @(posedge clk or posedge rst)
455
begin
456
  if (rst) begin
457
    iadr_t <= #1 23'h0;
458
    istb_t <= #1 1'b0;
459
    imem_wait <= #1 1'b0;
460
    idat_ir <= #1 24'h0;
461
  end else if (mem_act==`OC8051_MAS_CODE) begin
462
    iadr_t <= #1 alu;
463
    istb_t <= #1 1'b1;
464
    imem_wait <= #1 1'b1;
465
  end else if (ea_rom_sel && imem_wait) begin
466
    imem_wait <= #1 1'b0;
467
  end else if (!imem_wait && istb_t) begin
468
    istb_t <= #1 1'b0;
469 18 dinesha
  end
470 2 dinesha
end
471
 
472
/////////////////////////////
473
//
474
// ext_addr_sel
475
//
476
/////////////////////////////
477
 
478
assign dadr_o = dadr_ot;
479
 
480
always @(posedge clk or posedge rst)
481
begin
482
  if (rst) begin
483
    dwe_o <= #1 1'b0;
484
    dmem_wait <= #1 1'b0;
485
    dstb_o <= #1 1'b0;
486
    ddat_o <= #1 8'h00;
487
    dadr_ot <= #1 23'h0;
488
  end else if (dack_i) begin
489
    dwe_o <= #1 1'b0;
490
    dstb_o <= #1 1'b0;
491
    dmem_wait <= #1 1'b0;
492
  end else begin
493
    case (mem_act) /* synopsys full_case parallel_case */
494
      `OC8051_MAS_DPTR_R: begin  // read from external rom: acc=(dptr)
495
        dwe_o <= #1 1'b0;
496
        dstb_o <= #1 1'b1;
497
        ddat_o <= #1 8'h00;
498
        dadr_ot <= #1 {7'h0, dptr};
499
        dmem_wait <= #1 1'b1;
500
      end
501
      `OC8051_MAS_DPTR_W: begin  // write to external rom: (dptr)=acc
502
        dwe_o <= #1 1'b1;
503
        dstb_o <= #1 1'b1;
504
        ddat_o <= #1 acc;
505
        dadr_ot <= #1 {7'h0, dptr};
506
        dmem_wait <= #1 1'b1;
507
      end
508
      `OC8051_MAS_RI_R:   begin  // read from external rom: acc=(Ri)
509
        dwe_o <= #1 1'b0;
510
        dstb_o <= #1 1'b1;
511
        ddat_o <= #1 8'h00;
512
        dadr_ot <= #1 {15'h0, ri};
513
        dmem_wait <= #1 1'b1;
514
      end
515
      `OC8051_MAS_RI_W: begin    // write to external rom: (Ri)=acc
516
        dwe_o <= #1 1'b1;
517
        dstb_o <= #1 1'b1;
518
        ddat_o <= #1 acc;
519
        dadr_ot <= #1 {15'h0, ri};
520
        dmem_wait <= #1 1'b1;
521
      end
522
    endcase
523
  end
524
end
525
 
526
/////////////////////////////
527
//
528
// op_select
529
//
530
/////////////////////////////
531
 
532
 
533
 
534
always @(posedge clk or posedge rst)
535
begin
536
  if (rst) begin
537
    idat_cur <= #1 32'h0;
538
    idat_old <= #1 32'h0;
539 18 dinesha
  end else if (inc_pc || pc_wr_r2) begin
540
    idat_cur <= #1 idat_onchip;
541 2 dinesha
    idat_old <= #1 idat_cur;
542
  end
543
 
544
end
545
 
546
always @(posedge clk or posedge rst)
547
begin
548
  if (rst) begin
549
    cdata <= #1 8'h00;
550
    cdone <= #1 1'b0;
551
  end else if (istb_t) begin
552 18 dinesha
    cdata <= #1 idat_onchip[7:0] ;
553 2 dinesha
    cdone <= #1 1'b1;
554
  end else begin
555
    cdone <= #1 1'b0;
556
  end
557
end
558
 
559 18 dinesha
always @(*)
560 2 dinesha
begin
561
  case (op_pos)  /* synopsys parallel_case */
562
    3'b000: begin
563
       op1 = idat_old[7:0]  ;
564
       op2 = idat_old[15:8] ;
565
       op3 = idat_old[23:16];
566
      end
567
    3'b001: begin
568
       op1 = idat_old[15:8] ;
569
       op2 = idat_old[23:16];
570
       op3 = idat_old[31:24];
571
      end
572
    3'b010: begin
573
       op1 = idat_old[23:16];
574
       op2 = idat_old[31:24];
575
       op3 = idat_cur[7:0]  ;
576
      end
577
    3'b011: begin
578
       op1 = idat_old[31:24];
579
       op2 = idat_cur[7:0]  ;
580
       op3 = idat_cur[15:8] ;
581
      end
582
    3'b100: begin
583
       op1 = idat_cur[7:0]  ;
584
       op2 = idat_cur[15:8] ;
585
       op3 = idat_cur[23:16];
586
      end
587
    default: begin
588
       op1 = idat_cur[15:8] ;
589
       op2 = idat_cur[23:16];
590
       op3 = idat_cur[31:24];
591
      end
592
  endcase
593
end
594
 
595 18 dinesha
always @(*)
596 2 dinesha
  if (dack_ir)
597
    op1_out = ddat_ir;
598
  else if (cdone)
599
    op1_out = cdata;
600
  else
601
    op1_out = op1_o;
602
 
603
assign op3_out = (rd) ? op3_o : op3_buff;
604
assign op2_out = (rd) ? op2_o : op2_buff;
605
 
606 18 dinesha
always @(*)
607 2 dinesha
begin
608 18 dinesha
  if (!rd) begin
609 2 dinesha
    op1_xt = idat_ir[7:0];
610
    op2_xt = idat_ir[15:8];
611
    op3_xt = idat_ir[23:16];
612
  end else begin
613
    op1_xt = 8'h00;
614
    op2_xt = 8'h00;
615
    op3_xt = 8'h00;
616
  end
617
end
618
 
619
 
620
//
621
// in case of interrupts
622 18 dinesha
always @(*)
623 2 dinesha
begin
624 18 dinesha
  if (int_ack_t) begin
625 2 dinesha
    op1_o = `OC8051_LCALL;
626
    op2_o = 8'h00;
627
    op3_o = int_vec_buff;
628
  end else begin
629
    op1_o = op1;
630
    op2_o = op2;
631
    op3_o = op3;
632
  end
633
end
634
 
635
//
636
//in case of reti
637
always @(posedge clk or posedge rst)
638
  if (rst) reti <= #1 1'b0;
639
  else if ((op1_o==`OC8051_RETI) & rd & !mem_wait) reti <= #1 1'b1;
640
  else reti <= #1 1'b0;
641
 
642
//
643
// remember inputs
644
always @(posedge clk or posedge rst)
645
begin
646
  if (rst) begin
647
    op2_buff <= #1 8'h0;
648
    op3_buff <= #1 8'h0;
649
  end else if (rd) begin
650
    op2_buff <= #1 op2_o;
651
    op3_buff <= #1 op3_o;
652
  end
653
end
654
 
655
/////////////////////////////
656
//
657
//  pc
658
//
659
/////////////////////////////
660
 
661 18 dinesha
always @(*)
662 2 dinesha
begin
663
        casex (op1_out) /* synopsys parallel_case */
664
          `OC8051_ACALL :  op_length = 2'h2;
665
          `OC8051_AJMP :   op_length = 2'h2;
666
 
667
        //op_code [7:3]
668
          `OC8051_CJNE_R : op_length = 2'h3;
669
          `OC8051_DJNZ_R : op_length = 2'h2;
670
          `OC8051_MOV_DR : op_length = 2'h2;
671
          `OC8051_MOV_CR : op_length = 2'h2;
672
          `OC8051_MOV_RD : op_length = 2'h2;
673
 
674
        //op_code [7:1]
675
          `OC8051_CJNE_I : op_length = 2'h3;
676
          `OC8051_MOV_ID : op_length = 2'h2;
677
          `OC8051_MOV_DI : op_length = 2'h2;
678
          `OC8051_MOV_CI : op_length = 2'h2;
679
 
680
        //op_code [7:0]
681
          `OC8051_ADD_D :  op_length = 2'h2;
682
          `OC8051_ADD_C :  op_length = 2'h2;
683
          `OC8051_ADDC_D : op_length = 2'h2;
684
          `OC8051_ADDC_C : op_length = 2'h2;
685
          `OC8051_ANL_D :  op_length = 2'h2;
686
          `OC8051_ANL_C :  op_length = 2'h2;
687
          `OC8051_ANL_DD : op_length = 2'h2;
688
          `OC8051_ANL_DC : op_length = 2'h3;
689
          `OC8051_ANL_B :  op_length = 2'h2;
690
          `OC8051_ANL_NB : op_length = 2'h2;
691
          `OC8051_CJNE_D : op_length = 2'h3;
692
          `OC8051_CJNE_C : op_length = 2'h3;
693
          `OC8051_CLR_B :  op_length = 2'h2;
694
          `OC8051_CPL_B :  op_length = 2'h2;
695
          `OC8051_DEC_D :  op_length = 2'h2;
696
          `OC8051_DJNZ_D : op_length = 2'h3;
697
          `OC8051_INC_D :  op_length = 2'h2;
698
          `OC8051_JB :     op_length = 2'h3;
699
          `OC8051_JBC :    op_length = 2'h3;
700
          `OC8051_JC :     op_length = 2'h2;
701
          `OC8051_JNB :    op_length = 2'h3;
702
          `OC8051_JNC :    op_length = 2'h2;
703
          `OC8051_JNZ :    op_length = 2'h2;
704
          `OC8051_JZ :     op_length = 2'h2;
705
          `OC8051_LCALL :  op_length = 2'h3;
706
          `OC8051_LJMP :   op_length = 2'h3;
707
          `OC8051_MOV_D :  op_length = 2'h2;
708
          `OC8051_MOV_C :  op_length = 2'h2;
709
          `OC8051_MOV_DA : op_length = 2'h2;
710
          `OC8051_MOV_DD : op_length = 2'h3;
711
          `OC8051_MOV_CD : op_length = 2'h3;
712
          `OC8051_MOV_BC : op_length = 2'h2;
713
          `OC8051_MOV_CB : op_length = 2'h2;
714
          `OC8051_MOV_DP : op_length = 2'h3;
715
          `OC8051_ORL_D :  op_length = 2'h2;
716
          `OC8051_ORL_C :  op_length = 2'h2;
717
          `OC8051_ORL_AD : op_length = 2'h2;
718
          `OC8051_ORL_CD : op_length = 2'h3;
719
          `OC8051_ORL_B :  op_length = 2'h2;
720
          `OC8051_ORL_NB : op_length = 2'h2;
721
          `OC8051_POP :    op_length = 2'h2;
722
          `OC8051_PUSH :   op_length = 2'h2;
723
          `OC8051_SETB_B : op_length = 2'h2;
724
          `OC8051_SJMP :   op_length = 2'h2;
725
          `OC8051_SUBB_D : op_length = 2'h2;
726
          `OC8051_SUBB_C : op_length = 2'h2;
727
          `OC8051_XCH_D :  op_length = 2'h2;
728
          `OC8051_XRL_D :  op_length = 2'h2;
729
          `OC8051_XRL_C :  op_length = 2'h2;
730
          `OC8051_XRL_AD : op_length = 2'h2;
731
          `OC8051_XRL_CD : op_length = 2'h3;
732
          default:         op_length = 2'h1;
733
        endcase
734
end
735
 
736
 
737
assign inc_pc = ((op_pos[2] | (&op_pos[1:0])) & rd) | pc_wr_r2;
738
 
739
always @(posedge rst or posedge clk)
740
begin
741
  if (rst) begin
742
    op_pos <= #1 3'h0;
743
  end else if (pc_wr_r2) begin
744 18 dinesha
    op_pos <= #1 3'h4;
745 2 dinesha
  end else if (inc_pc & rd) begin
746
    op_pos[2]   <= #1 op_pos[2] & !op_pos[1] & op_pos[0] & (&op_length);
747
    op_pos[1:0] <= #1 op_pos[1:0] + op_length;
748
  end else if (rd) begin
749
    op_pos <= #1 op_pos + {1'b0, op_length};
750
  end
751
end
752
 
753
//
754
// remember interrupt
755
// we don't want to interrupt instruction in the middle of execution
756
always @(posedge clk or posedge rst)
757
 if (rst) begin
758
   int_ack_t <= #1 1'b0;
759
   int_vec_buff <= #1 8'h00;
760
 end else if (intr) begin
761
   int_ack_t <= #1 1'b1;
762
   int_vec_buff <= #1 int_v;
763 18 dinesha
 end else if (rd && !pc_wr_r2) int_ack_t <= #1 1'b0;
764 2 dinesha
 
765
always @(posedge clk or posedge rst)
766
  if (rst) int_ack_buff <= #1 1'b0;
767
  else int_ack_buff <= #1 int_ack_t;
768
 
769
always @(posedge clk or posedge rst)
770
  if (rst) int_ack <= #1 1'b0;
771
  else begin
772
    if ((int_ack_buff) & !(int_ack_t))
773
      int_ack <= #1 1'b1;
774
    else int_ack <= #1 1'b0;
775
  end
776
 
777
 
778
//
779
//interrupt buffer
780
always @(posedge clk or posedge rst)
781
  if (rst) begin
782
    int_buff1 <= #1 1'b0;
783
  end else begin
784
    int_buff1 <= #1 int_buff;
785
  end
786
 
787
always @(posedge clk or posedge rst)
788
  if (rst) begin
789
    int_buff <= #1 1'b0;
790
  end else if (intr) begin
791
    int_buff <= #1 1'b1;
792
  end else if (pc_wait)
793
    int_buff <= #1 1'b0;
794
 
795
wire [7:0]  pcs_source;
796
reg  [15:0] pcs_result;
797
reg         pcs_cy;
798
 
799
assign pcs_source = pc_wr_sel[0] ? op3_out : op2_out;
800
 
801
always @(pcs_source or pc or pcs_cy)
802
begin
803
  if (pcs_source[7]) begin
804
    {pcs_cy, pcs_result[7:0]} = {1'b0, pc[7:0]} + {1'b0, pcs_source};
805
    pcs_result[15:8] = pc[15:8] - {7'h0, !pcs_cy};
806
  end else pcs_result = pc + {8'h00, pcs_source};
807
end
808
 
809
always @(posedge clk or posedge rst)
810
begin
811
  if (rst)
812
    pc <= #1 16'h0;
813
  else if (pc_wr_r2)
814
    pc <= #1 pc_buf;
815
  else if (rd & !int_ack_t)
816
    pc <= #1 pc_buf - 16'h8 + {13'h0, op_pos} + {14'h0, op_length};
817
end
818
 
819
 
820
always @(posedge clk or posedge rst)
821
begin
822
  if (rst) begin
823
    pc_buf <= #1 `OC8051_RST_PC;
824
  end else if (pc_wr) begin
825
//
826
//case of writing new value to pc (jupms)
827
      case (pc_wr_sel) /* synopsys full_case parallel_case */
828
        `OC8051_PIS_ALU: pc_buf        <= #1 alu;
829
        `OC8051_PIS_AL:  pc_buf[7:0]   <= #1 alu[7:0];
830
        `OC8051_PIS_AH:  pc_buf[15:8]  <= #1 alu[7:0];
831
        `OC8051_PIS_I11: pc_buf[10:0]  <= #1 {op1_out[7:5], op2_out};
832
        `OC8051_PIS_I16: pc_buf        <= #1 {op2_out, op3_out};
833
        `OC8051_PIS_SO1: pc_buf        <= #1 pcs_result;
834
        `OC8051_PIS_SO2: pc_buf        <= #1 pcs_result;
835
      endcase
836
//  end else if (inc_pc) begin
837
  end else begin
838
//
839
//or just remember current
840
      pc_buf <= #1 pc_out;
841
  end
842
end
843
 
844
 
845
assign pc_out = inc_pc ? pc_buf + 16'h4
846
                       : pc_buf ;
847
 
848
 
849
 
850
 
851
 
852
always @(posedge clk or posedge rst)
853
  if (rst)
854
    ddat_ir <= #1 8'h00;
855
  else if (dack_i)
856
    ddat_ir <= #1 ddat_i;
857
 
858
////////////////////////
859
always @(posedge clk or posedge rst)
860
  if (rst) begin
861
    rn_r      <= #1 5'd0;
862
    ri_r      <= #1 8'h00;
863
    imm_r     <= #1 8'h00;
864
    imm2_r    <= #1 8'h00;
865
    rd_addr_r <= #1 1'b0;
866
    op1_r     <= #1 8'h0;
867
    dack_ir   <= #1 1'b0;
868
    sp_r      <= #1 1'b0;
869
    pc_wr_r   <= #1 1'b0;
870
    pc_wr_r2  <= #1 1'b0;
871
  end else begin
872
    rn_r      <= #1 rn;
873
    ri_r      <= #1 ri;
874
    imm_r     <= #1 imm;
875
    imm2_r    <= #1 imm2;
876
    rd_addr_r <= #1 rd_addr[7];
877
    op1_r     <= #1 op1_out;
878
    dack_ir   <= #1 dack_i;
879
    sp_r      <= #1 sp;
880
    pc_wr_r   <= #1 pc_wr && (pc_wr_sel != `OC8051_PIS_AH);
881
    pc_wr_r2  <= #1 pc_wr_r;
882
  end
883
 
884
always @(posedge clk or posedge rst)
885
  if (rst) begin
886
    inc_pc_r  <= #1 1'b1;
887
  end else if (istb) begin
888
    inc_pc_r  <= #1 inc_pc;
889
  end
890
 
891
`ifdef OC8051_SIMULATION
892
 
893
initial
894
begin
895
  wait (!rst)
896
  if (ea_rom_sel) begin
897
    $display(" ");
898
    $display("\t Program running from internal rom !");
899
    $display(" ");
900
  end else begin
901
    $display(" ");
902
    $display("\t Program running from external rom !");
903
    $display(" ");
904
  end
905
end
906
`endif
907
 
908
 
909
endmodule

powered by: WebSVN 2.1.0

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