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

Subversion Repositories 8051

[/] [8051/] [tags/] [rel_12/] [rtl/] [verilog/] [oc8051_memory_interface.v] - Blame information for rev 149

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

powered by: WebSVN 2.1.0

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