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

Subversion Repositories 8051

[/] [8051/] [trunk/] [rtl/] [verilog/] [oc8051_memory_interface.v] - Blame information for rev 173

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

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

powered by: WebSVN 2.1.0

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