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

Subversion Repositories turbo8051

[/] [turbo8051/] [trunk/] [rtl/] [8051/] [oc8051_memory_interface.v] - Blame information for rev 76

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 76 dinesha
//// http://www.opencores.org/cores/turb08051/                    ////
7 2 dinesha
////                                                              ////
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 76 dinesha
////      - Dinesh Annayya, dinesha@opencores.org                 ////
17
////      - 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 76 dinesha
`include "top_defines.v"
89 2 dinesha
 
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
//external
134
     iack_i,
135
     istb_o,
136
     idat_i,
137
 
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
input [31:0]  idat_i;
181
 
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
input         iack_i;
207
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
output        int_ack,
273
              istb_o;
274
 
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
//assign mem_wait   = dmem_wait || imem_wait || pc_wr_r;
360
assign mem_wait   = dmem_wait || imem_wait || pc_wr_r2;
361
//assign mem_wait   = dmem_wait || imem_wait;
362
assign istb_o     = (istb || (istb_t & !iack_i)) && !dstb_o && !ea_rom_sel;
363
 
364
assign pc_wait    = rd && (ea_rom_sel || (!istb_t && iack_i));
365
 
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
always @(rd_sel or sp or ri or rn or imm or dadr_o[15:0] or bank)
404
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
//    default          : rd_addr = 2'bxx;
416
  endcase
417
 
418
end
419
 
420
 
421
//
422
//
423
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
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
//assign iadr_o = (istb_t & !iack_i) ? iadr_t : pc_out;
461
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
  end else if (iack_i) begin
480
    imem_wait <= #1 1'b0;
481
    idat_ir <= #1 idat_i [23:0];
482
  end
483
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
  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
    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
    cdata <= #1 ea_rom_sel ? idat_onchip[7:0] : idat_i[7:0];
566
    cdone <= #1 1'b1;
567
  end else begin
568
    cdone <= #1 1'b0;
569
  end
570
end
571
 
572
always @(op_pos or idat_cur or idat_old)
573
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
/*assign op1 = ea_rom_sel ? idat_onchip[7:0]   : op1_xt;
609
assign op2 = ea_rom_sel ? idat_onchip[15:8]  : op2_xt;
610
assign op3 = ea_rom_sel ? idat_onchip[23:16] : op3_xt;*/
611
 
612
 
613
always @(dack_ir or ddat_ir or op1_o or iram_out or cdone or cdata)
614
  if (dack_ir)
615
    op1_out = ddat_ir;
616
  else if (cdone)
617
    op1_out = cdata;
618
  else
619
    op1_out = op1_o;
620
 
621
assign op3_out = (rd) ? op3_o : op3_buff;
622
assign op2_out = (rd) ? op2_o : op2_buff;
623
 
624
always @(idat_i or iack_i or idat_ir or rd)
625
begin
626
  if (iack_i) begin
627
    op1_xt = idat_i[7:0];
628
    op2_xt = idat_i[15:8];
629
    op3_xt = idat_i[23:16];
630
  end else if (!rd) begin
631
    op1_xt = idat_ir[7:0];
632
    op2_xt = idat_ir[15:8];
633
    op3_xt = idat_ir[23:16];
634
  end else begin
635
    op1_xt = 8'h00;
636
    op2_xt = 8'h00;
637
    op3_xt = 8'h00;
638
  end
639
end
640
 
641
 
642
//
643
// in case of interrupts
644
always @(op1 or op2 or op3 or int_ack_t or int_vec_buff or iack_i or ea_rom_sel)
645
begin
646
  if (int_ack_t && (iack_i || ea_rom_sel)) begin
647
    op1_o = `OC8051_LCALL;
648
    op2_o = 8'h00;
649
    op3_o = int_vec_buff;
650
  end else begin
651
    op1_o = op1;
652
    op2_o = op2;
653
    op3_o = op3;
654
  end
655
end
656
 
657
//
658
//in case of reti
659
always @(posedge clk or posedge rst)
660
  if (rst) reti <= #1 1'b0;
661
  else if ((op1_o==`OC8051_RETI) & rd & !mem_wait) reti <= #1 1'b1;
662
  else reti <= #1 1'b0;
663
 
664
//
665
// remember inputs
666
always @(posedge clk or posedge rst)
667
begin
668
  if (rst) begin
669
    op2_buff <= #1 8'h0;
670
    op3_buff <= #1 8'h0;
671
  end else if (rd) begin
672
    op2_buff <= #1 op2_o;
673
    op3_buff <= #1 op3_o;
674
  end
675
end
676
 
677
/////////////////////////////
678
//
679
//  pc
680
//
681
/////////////////////////////
682
 
683
always @(op1_out)
684
begin
685
        casex (op1_out) /* synopsys parallel_case */
686
          `OC8051_ACALL :  op_length = 2'h2;
687
          `OC8051_AJMP :   op_length = 2'h2;
688
 
689
        //op_code [7:3]
690
          `OC8051_CJNE_R : op_length = 2'h3;
691
          `OC8051_DJNZ_R : op_length = 2'h2;
692
          `OC8051_MOV_DR : op_length = 2'h2;
693
          `OC8051_MOV_CR : op_length = 2'h2;
694
          `OC8051_MOV_RD : op_length = 2'h2;
695
 
696
        //op_code [7:1]
697
          `OC8051_CJNE_I : op_length = 2'h3;
698
          `OC8051_MOV_ID : op_length = 2'h2;
699
          `OC8051_MOV_DI : op_length = 2'h2;
700
          `OC8051_MOV_CI : op_length = 2'h2;
701
 
702
        //op_code [7:0]
703
          `OC8051_ADD_D :  op_length = 2'h2;
704
          `OC8051_ADD_C :  op_length = 2'h2;
705
          `OC8051_ADDC_D : op_length = 2'h2;
706
          `OC8051_ADDC_C : op_length = 2'h2;
707
          `OC8051_ANL_D :  op_length = 2'h2;
708
          `OC8051_ANL_C :  op_length = 2'h2;
709
          `OC8051_ANL_DD : op_length = 2'h2;
710
          `OC8051_ANL_DC : op_length = 2'h3;
711
          `OC8051_ANL_B :  op_length = 2'h2;
712
          `OC8051_ANL_NB : op_length = 2'h2;
713
          `OC8051_CJNE_D : op_length = 2'h3;
714
          `OC8051_CJNE_C : op_length = 2'h3;
715
          `OC8051_CLR_B :  op_length = 2'h2;
716
          `OC8051_CPL_B :  op_length = 2'h2;
717
          `OC8051_DEC_D :  op_length = 2'h2;
718
          `OC8051_DJNZ_D : op_length = 2'h3;
719
          `OC8051_INC_D :  op_length = 2'h2;
720
          `OC8051_JB :     op_length = 2'h3;
721
          `OC8051_JBC :    op_length = 2'h3;
722
          `OC8051_JC :     op_length = 2'h2;
723
          `OC8051_JNB :    op_length = 2'h3;
724
          `OC8051_JNC :    op_length = 2'h2;
725
          `OC8051_JNZ :    op_length = 2'h2;
726
          `OC8051_JZ :     op_length = 2'h2;
727
          `OC8051_LCALL :  op_length = 2'h3;
728
          `OC8051_LJMP :   op_length = 2'h3;
729
          `OC8051_MOV_D :  op_length = 2'h2;
730
          `OC8051_MOV_C :  op_length = 2'h2;
731
          `OC8051_MOV_DA : op_length = 2'h2;
732
          `OC8051_MOV_DD : op_length = 2'h3;
733
          `OC8051_MOV_CD : op_length = 2'h3;
734
          `OC8051_MOV_BC : op_length = 2'h2;
735
          `OC8051_MOV_CB : op_length = 2'h2;
736
          `OC8051_MOV_DP : op_length = 2'h3;
737
          `OC8051_ORL_D :  op_length = 2'h2;
738
          `OC8051_ORL_C :  op_length = 2'h2;
739
          `OC8051_ORL_AD : op_length = 2'h2;
740
          `OC8051_ORL_CD : op_length = 2'h3;
741
          `OC8051_ORL_B :  op_length = 2'h2;
742
          `OC8051_ORL_NB : op_length = 2'h2;
743
          `OC8051_POP :    op_length = 2'h2;
744
          `OC8051_PUSH :   op_length = 2'h2;
745
          `OC8051_SETB_B : op_length = 2'h2;
746
          `OC8051_SJMP :   op_length = 2'h2;
747
          `OC8051_SUBB_D : op_length = 2'h2;
748
          `OC8051_SUBB_C : op_length = 2'h2;
749
          `OC8051_XCH_D :  op_length = 2'h2;
750
          `OC8051_XRL_D :  op_length = 2'h2;
751
          `OC8051_XRL_C :  op_length = 2'h2;
752
          `OC8051_XRL_AD : op_length = 2'h2;
753
          `OC8051_XRL_CD : op_length = 2'h3;
754
          default:         op_length = 2'h1;
755
        endcase
756
end
757
 
758
/*
759
always @(posedge clk or posedge rst)
760
begin
761
    if (rst) begin
762
      op_length = 2'h2;
763
//    end else if (pc_wait) begin
764
    end else begin
765
        casex (op1_out)
766
          `OC8051_ACALL :  op_length <= #1 2'h2;
767
          `OC8051_AJMP :   op_length <= #1 2'h2;
768
 
769
        //op_code [7:3]
770
          `OC8051_CJNE_R : op_length <= #1 2'h3;
771
          `OC8051_DJNZ_R : op_length <= #1 2'h2;
772
          `OC8051_MOV_DR : op_length <= #1 2'h2;
773
          `OC8051_MOV_CR : op_length <= #1 2'h2;
774
          `OC8051_MOV_RD : op_length <= #1 2'h2;
775
 
776
        //op_code [7:1]
777
          `OC8051_CJNE_I : op_length <= #1 2'h3;
778
          `OC8051_MOV_ID : op_length <= #1 2'h2;
779
          `OC8051_MOV_DI : op_length <= #1 2'h2;
780
          `OC8051_MOV_CI : op_length <= #1 2'h2;
781
 
782
        //op_code [7:0]
783
          `OC8051_ADD_D :  op_length <= #1 2'h2;
784
          `OC8051_ADD_C :  op_length <= #1 2'h2;
785
          `OC8051_ADDC_D : op_length <= #1 2'h2;
786
          `OC8051_ADDC_C : op_length <= #1 2'h2;
787
          `OC8051_ANL_D :  op_length <= #1 2'h2;
788
          `OC8051_ANL_C :  op_length <= #1 2'h2;
789
          `OC8051_ANL_DD : op_length <= #1 2'h2;
790
          `OC8051_ANL_DC : op_length <= #1 2'h3;
791
          `OC8051_ANL_B :  op_length <= #1 2'h2;
792
          `OC8051_ANL_NB : op_length <= #1 2'h2;
793
          `OC8051_CJNE_D : op_length <= #1 2'h3;
794
          `OC8051_CJNE_C : op_length <= #1 2'h3;
795
          `OC8051_CLR_B :  op_length <= #1 2'h2;
796
          `OC8051_CPL_B :  op_length <= #1 2'h2;
797
          `OC8051_DEC_D :  op_length <= #1 2'h2;
798
          `OC8051_DJNZ_D : op_length <= #1 2'h3;
799
          `OC8051_INC_D :  op_length <= #1 2'h2;
800
          `OC8051_JB :     op_length <= #1 2'h3;
801
          `OC8051_JBC :    op_length <= #1 2'h3;
802
          `OC8051_JC :     op_length <= #1 2'h2;
803
          `OC8051_JNB :    op_length <= #1 2'h3;
804
          `OC8051_JNC :    op_length <= #1 2'h2;
805
          `OC8051_JNZ :    op_length <= #1 2'h2;
806
          `OC8051_JZ :     op_length <= #1 2'h2;
807
          `OC8051_LCALL :  op_length <= #1 2'h3;
808
          `OC8051_LJMP :   op_length <= #1 2'h3;
809
          `OC8051_MOV_D :  op_length <= #1 2'h2;
810
          `OC8051_MOV_C :  op_length <= #1 2'h2;
811
          `OC8051_MOV_DA : op_length <= #1 2'h2;
812
          `OC8051_MOV_DD : op_length <= #1 2'h3;
813
          `OC8051_MOV_CD : op_length <= #1 2'h3;
814
          `OC8051_MOV_BC : op_length <= #1 2'h2;
815
          `OC8051_MOV_CB : op_length <= #1 2'h2;
816
          `OC8051_MOV_DP : op_length <= #1 2'h3;
817
          `OC8051_ORL_D :  op_length <= #1 2'h2;
818
          `OC8051_ORL_C :  op_length <= #1 2'h2;
819
          `OC8051_ORL_AD : op_length <= #1 2'h2;
820
          `OC8051_ORL_CD : op_length <= #1 2'h3;
821
          `OC8051_ORL_B :  op_length <= #1 2'h2;
822
          `OC8051_ORL_NB : op_length <= #1 2'h2;
823
          `OC8051_POP :    op_length <= #1 2'h2;
824
          `OC8051_PUSH :   op_length <= #1 2'h2;
825
          `OC8051_SETB_B : op_length <= #1 2'h2;
826
          `OC8051_SJMP :   op_length <= #1 2'h2;
827
          `OC8051_SUBB_D : op_length <= #1 2'h2;
828
          `OC8051_SUBB_C : op_length <= #1 2'h2;
829
          `OC8051_XCH_D :  op_length <= #1 2'h2;
830
          `OC8051_XRL_D :  op_length <= #1 2'h2;
831
          `OC8051_XRL_C :  op_length <= #1 2'h2;
832
          `OC8051_XRL_AD : op_length <= #1 2'h2;
833
          `OC8051_XRL_CD : op_length <= #1 2'h3;
834
          default:         op_length <= #1 2'h1;
835
        endcase
836
//
837
//in case of instructions that use more than one clock hold current pc
838
//    end else begin
839
//      pc= pc_buf;
840
   end
841
end
842
*/
843
 
844
assign inc_pc = ((op_pos[2] | (&op_pos[1:0])) & rd) | pc_wr_r2;
845
 
846
always @(posedge rst or posedge clk)
847
begin
848
  if (rst) begin
849
    op_pos <= #1 3'h0;
850
  end else if (pc_wr_r2) begin
851
    op_pos <= #1 3'h4;// - op_length;////****??????????
852
/*  end else if (inc_pc & rd) begin
853
    op_pos[2]   <= #1 op_pos[2] & !op_pos[1] & op_pos[0] & (&op_length);
854
    op_pos[1:0] <= #1 op_pos[1:0] + op_length;
855
//    op_pos   <= #1 {1'b0, op_pos[1:0]} + {1'b0, op_length};
856
  end else if (rd) begin
857
    op_pos <= #1 op_pos + {1'b0, op_length};
858
  end*/
859
  end else if (inc_pc & rd) begin
860
    op_pos[2]   <= #1 op_pos[2] & !op_pos[1] & op_pos[0] & (&op_length);
861
    op_pos[1:0] <= #1 op_pos[1:0] + op_length;
862
//    op_pos   <= #1 {1'b0, op_pos[1:0]} + {1'b0, op_length};
863
//  end else if (istb & rd) begin
864
  end else if (rd) begin
865
    op_pos <= #1 op_pos + {1'b0, op_length};
866
  end
867
end
868
 
869
//
870
// remember interrupt
871
// we don't want to interrupt instruction in the middle of execution
872
always @(posedge clk or posedge rst)
873
 if (rst) begin
874
   int_ack_t <= #1 1'b0;
875
   int_vec_buff <= #1 8'h00;
876
 end else if (intr) begin
877
   int_ack_t <= #1 1'b1;
878
   int_vec_buff <= #1 int_v;
879
 end else if (rd && (ea_rom_sel || iack_i) && !pc_wr_r2) int_ack_t <= #1 1'b0;
880
 
881
always @(posedge clk or posedge rst)
882
  if (rst) int_ack_buff <= #1 1'b0;
883
  else int_ack_buff <= #1 int_ack_t;
884
 
885
always @(posedge clk or posedge rst)
886
  if (rst) int_ack <= #1 1'b0;
887
  else begin
888
    if ((int_ack_buff) & !(int_ack_t))
889
      int_ack <= #1 1'b1;
890
    else int_ack <= #1 1'b0;
891
  end
892
 
893
 
894
//
895
//interrupt buffer
896
always @(posedge clk or posedge rst)
897
  if (rst) begin
898
    int_buff1 <= #1 1'b0;
899
  end else begin
900
    int_buff1 <= #1 int_buff;
901
  end
902
 
903
always @(posedge clk or posedge rst)
904
  if (rst) begin
905
    int_buff <= #1 1'b0;
906
  end else if (intr) begin
907
    int_buff <= #1 1'b1;
908
  end else if (pc_wait)
909
    int_buff <= #1 1'b0;
910
 
911
wire [7:0]  pcs_source;
912
reg  [15:0] pcs_result;
913
reg         pcs_cy;
914
 
915
assign pcs_source = pc_wr_sel[0] ? op3_out : op2_out;
916
 
917
always @(pcs_source or pc or pcs_cy)
918
begin
919
  if (pcs_source[7]) begin
920
    {pcs_cy, pcs_result[7:0]} = {1'b0, pc[7:0]} + {1'b0, pcs_source};
921
    pcs_result[15:8] = pc[15:8] - {7'h0, !pcs_cy};
922
  end else pcs_result = pc + {8'h00, pcs_source};
923
end
924
 
925
//assign pc = pc_buf - {13'h0, op_pos[2] | inc_pc_r, op_pos[1:0]}; ////******???
926
//assign pc = pc_buf - 16'h8 + {13'h0, op_pos}; ////******???
927
//assign pc = pc_buf - 16'h8 + {13'h0, op_pos} + {14'h0, op_length};
928
 
929
always @(posedge clk or posedge rst)
930
begin
931
  if (rst)
932
    pc <= #1 16'h0;
933
  else if (pc_wr_r2)
934
    pc <= #1 pc_buf;
935
  else if (rd & !int_ack_t)
936
    pc <= #1 pc_buf - 16'h8 + {13'h0, op_pos} + {14'h0, op_length};
937
end
938
 
939
 
940
always @(posedge clk or posedge rst)
941
begin
942
  if (rst) begin
943
    pc_buf <= #1 `OC8051_RST_PC;
944
  end else if (pc_wr) begin
945
//
946
//case of writing new value to pc (jupms)
947
      case (pc_wr_sel) /* synopsys full_case parallel_case */
948
        `OC8051_PIS_ALU: pc_buf        <= #1 alu;
949
        `OC8051_PIS_AL:  pc_buf[7:0]   <= #1 alu[7:0];
950
        `OC8051_PIS_AH:  pc_buf[15:8]  <= #1 alu[7:0];
951
        `OC8051_PIS_I11: pc_buf[10:0]  <= #1 {op1_out[7:5], op2_out};
952
        `OC8051_PIS_I16: pc_buf        <= #1 {op2_out, op3_out};
953
        `OC8051_PIS_SO1: pc_buf        <= #1 pcs_result;
954
        `OC8051_PIS_SO2: pc_buf        <= #1 pcs_result;
955
      endcase
956
//  end else if (inc_pc) begin
957
  end else begin
958
//
959
//or just remember current
960
      pc_buf <= #1 pc_out;
961
  end
962
end
963
 
964
 
965
assign pc_out = inc_pc ? pc_buf + 16'h4
966
                       : pc_buf ;
967
 
968
 
969
 
970
 
971
 
972
always @(posedge clk or posedge rst)
973
  if (rst)
974
    ddat_ir <= #1 8'h00;
975
  else if (dack_i)
976
    ddat_ir <= #1 ddat_i;
977
 
978
/*
979
 
980
always @(pc_buf or op1_out or pc_wait or int_buff or int_buff1 or ea_rom_sel or iack_i)
981
begin
982
    if (int_buff || int_buff1) begin
983
//
984
//in case of interrupt hold valut, to be written to stack
985
      pc= pc_buf;
986
//    end else if (pis_l) begin
987
//      pc = {pc_buf[22:8], alu[7:0]};
988
    end else if (pc_wait) begin
989
        casex (op1_out)
990
          `OC8051_ACALL :  pc= pc_buf + 16'h2;
991
          `OC8051_AJMP :   pc= pc_buf + 16'h2;
992
 
993
        //op_code [7:3]
994
          `OC8051_CJNE_R : pc= pc_buf + 16'h3;
995
          `OC8051_DJNZ_R : pc= pc_buf + 16'h2;
996
          `OC8051_MOV_DR : pc= pc_buf + 16'h2;
997
          `OC8051_MOV_CR : pc= pc_buf + 16'h2;
998
          `OC8051_MOV_RD : pc= pc_buf + 16'h2;
999
 
1000
        //op_code [7:1]
1001
          `OC8051_CJNE_I : pc= pc_buf + 16'h3;
1002
          `OC8051_MOV_ID : pc= pc_buf + 16'h2;
1003
          `OC8051_MOV_DI : pc= pc_buf + 16'h2;
1004
          `OC8051_MOV_CI : pc= pc_buf + 16'h2;
1005
 
1006
        //op_code [7:0]
1007
          `OC8051_ADD_D :  pc= pc_buf + 16'h2;
1008
          `OC8051_ADD_C :  pc= pc_buf + 16'h2;
1009
          `OC8051_ADDC_D : pc= pc_buf + 16'h2;
1010
          `OC8051_ADDC_C : pc= pc_buf + 16'h2;
1011
          `OC8051_ANL_D :  pc= pc_buf + 16'h2;
1012
          `OC8051_ANL_C :  pc= pc_buf + 16'h2;
1013
          `OC8051_ANL_DD : pc= pc_buf + 16'h2;
1014
          `OC8051_ANL_DC : pc= pc_buf + 16'h3;
1015
          `OC8051_ANL_B :  pc= pc_buf + 16'h2;
1016
          `OC8051_ANL_NB : pc= pc_buf + 16'h2;
1017
          `OC8051_CJNE_D : pc= pc_buf + 16'h3;
1018
          `OC8051_CJNE_C : pc= pc_buf + 16'h3;
1019
          `OC8051_CLR_B :  pc= pc_buf + 16'h2;
1020
          `OC8051_CPL_B :  pc= pc_buf + 16'h2;
1021
          `OC8051_DEC_D :  pc= pc_buf + 16'h2;
1022
          `OC8051_DJNZ_D : pc= pc_buf + 16'h3;
1023
          `OC8051_INC_D :  pc= pc_buf + 16'h2;
1024
          `OC8051_JB :     pc= pc_buf + 16'h3;
1025
          `OC8051_JBC :    pc= pc_buf + 16'h3;
1026
          `OC8051_JC :     pc= pc_buf + 16'h2;
1027
          `OC8051_JNB :    pc= pc_buf + 16'h3;
1028
          `OC8051_JNC :    pc= pc_buf + 16'h2;
1029
          `OC8051_JNZ :    pc= pc_buf + 16'h2;
1030
          `OC8051_JZ :     pc= pc_buf + 16'h2;
1031
          `OC8051_LCALL :  pc= pc_buf + 16'h3;
1032
          `OC8051_LJMP :   pc= pc_buf + 16'h3;
1033
          `OC8051_MOV_D :  pc= pc_buf + 16'h2;
1034
          `OC8051_MOV_C :  pc= pc_buf + 16'h2;
1035
          `OC8051_MOV_DA : pc= pc_buf + 16'h2;
1036
          `OC8051_MOV_DD : pc= pc_buf + 16'h3;
1037
          `OC8051_MOV_CD : pc= pc_buf + 16'h3;
1038
          `OC8051_MOV_BC : pc= pc_buf + 16'h2;
1039
          `OC8051_MOV_CB : pc= pc_buf + 16'h2;
1040
          `OC8051_MOV_DP : pc= pc_buf + 16'h3;
1041
          `OC8051_ORL_D :  pc= pc_buf + 16'h2;
1042
          `OC8051_ORL_C :  pc= pc_buf + 16'h2;
1043
          `OC8051_ORL_AD : pc= pc_buf + 16'h2;
1044
          `OC8051_ORL_CD : pc= pc_buf + 16'h3;
1045
          `OC8051_ORL_B :  pc= pc_buf + 16'h2;
1046
          `OC8051_ORL_NB : pc= pc_buf + 16'h2;
1047
          `OC8051_POP :    pc= pc_buf + 16'h2;
1048
          `OC8051_PUSH :   pc= pc_buf + 16'h2;
1049
          `OC8051_SETB_B : pc= pc_buf + 16'h2;
1050
          `OC8051_SJMP :   pc= pc_buf + 16'h2;
1051
          `OC8051_SUBB_D : pc= pc_buf + 16'h2;
1052
          `OC8051_SUBB_C : pc= pc_buf + 16'h2;
1053
          `OC8051_XCH_D :  pc= pc_buf + 16'h2;
1054
          `OC8051_XRL_D :  pc= pc_buf + 16'h2;
1055
          `OC8051_XRL_C :  pc= pc_buf + 16'h2;
1056
          `OC8051_XRL_AD : pc= pc_buf + 16'h2;
1057
          `OC8051_XRL_CD : pc= pc_buf + 16'h3;
1058
          default:         pc= pc_buf + 16'h1;
1059
        endcase
1060
//
1061
//in case of instructions that use more than one clock hold current pc
1062
    end else begin
1063
      pc= pc_buf;
1064
   end
1065
end
1066
 
1067
 
1068
//
1069
//interrupt buffer
1070
always @(posedge clk or posedge rst)
1071
  if (rst) begin
1072
    int_buff1 <= #1 1'b0;
1073
  end else begin
1074
    int_buff1 <= #1 int_buff;
1075
  end
1076
 
1077
always @(posedge clk or posedge rst)
1078
  if (rst) begin
1079
    int_buff <= #1 1'b0;
1080
  end else if (intr) begin
1081
    int_buff <= #1 1'b1;
1082
  end else if (pc_wait)
1083
    int_buff <= #1 1'b0;
1084
 
1085
wire [7:0]  pcs_source;
1086
reg  [15:0] pcs_result;
1087
reg         pcs_cy;
1088
 
1089
assign pcs_source = pc_wr_sel[0] ? op3_out : op2_out;
1090
 
1091
always @(pcs_source or pc or pcs_cy)
1092
begin
1093
  if (pcs_source[7]) begin
1094
    {pcs_cy, pcs_result[7:0]} = {1'b0, pc[7:0]} + {1'b0, pcs_source};
1095
    pcs_result[15:8] = pc[15:8] - {7'h0, !pcs_cy};
1096
  end else pcs_result = pc + {8'h00, pcs_source};
1097
end
1098
 
1099
 
1100
always @(posedge clk or posedge rst)
1101
begin
1102
  if (rst) begin
1103
    pc_buf <= #1 `OC8051_RST_PC;
1104
  end else begin
1105
    if (pc_wr) begin
1106
//
1107
//case of writing new value to pc (jupms)
1108
      case (pc_wr_sel)
1109
        `OC8051_PIS_ALU: pc_buf        <= #1 alu;
1110
        `OC8051_PIS_AL:  pc_buf[7:0]   <= #1 alu[7:0];
1111
        `OC8051_PIS_AH:  pc_buf[15:8]  <= #1 alu[7:0];
1112
        `OC8051_PIS_I11: pc_buf[10:0]  <= #1 {op1_out[7:5], op2_out};
1113
        `OC8051_PIS_I16: pc_buf        <= #1 {op2_out, op3_out};
1114
        `OC8051_PIS_SO1: pc_buf        <= #1 pcs_result;
1115
        `OC8051_PIS_SO2: pc_buf        <= #1 pcs_result;
1116
      endcase
1117
    end else
1118
//
1119
//or just remember current
1120
      pc_buf <= #1 pc;
1121
  end
1122
end
1123
 
1124
 
1125
always @(posedge clk or posedge rst)
1126
  if (rst)
1127
    ddat_ir <= #1 8'h00;
1128
  else if (dack_i)
1129
    ddat_ir <= #1 ddat_i;
1130
*/
1131
 
1132
////////////////////////
1133
always @(posedge clk or posedge rst)
1134
  if (rst) begin
1135
    rn_r      <= #1 5'd0;
1136
    ri_r      <= #1 8'h00;
1137
    imm_r     <= #1 8'h00;
1138
    imm2_r    <= #1 8'h00;
1139
    rd_addr_r <= #1 1'b0;
1140
    op1_r     <= #1 8'h0;
1141
    dack_ir   <= #1 1'b0;
1142
    sp_r      <= #1 1'b0;
1143
    pc_wr_r   <= #1 1'b0;
1144
    pc_wr_r2  <= #1 1'b0;
1145
  end else begin
1146
    rn_r      <= #1 rn;
1147
    ri_r      <= #1 ri;
1148
    imm_r     <= #1 imm;
1149
    imm2_r    <= #1 imm2;
1150
    rd_addr_r <= #1 rd_addr[7];
1151
    op1_r     <= #1 op1_out;
1152
    dack_ir   <= #1 dack_i;
1153
    sp_r      <= #1 sp;
1154
    pc_wr_r   <= #1 pc_wr && (pc_wr_sel != `OC8051_PIS_AH);
1155
    pc_wr_r2  <= #1 pc_wr_r;
1156
  end
1157
 
1158
always @(posedge clk or posedge rst)
1159
  if (rst) begin
1160
    inc_pc_r  <= #1 1'b1;
1161
  end else if (istb) begin
1162
    inc_pc_r  <= #1 inc_pc;
1163
  end
1164
 
1165
`ifdef OC8051_SIMULATION
1166
 
1167
initial
1168
begin
1169
  wait (!rst)
1170
  if (ea_rom_sel) begin
1171
    $display(" ");
1172
    $display("\t Program running from internal rom !");
1173
    $display(" ");
1174
  end else begin
1175
    $display(" ");
1176
    $display("\t Program running from external rom !");
1177
    $display(" ");
1178
  end
1179
end
1180
`endif
1181
 
1182
 
1183
endmodule

powered by: WebSVN 2.1.0

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