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

Subversion Repositories 8051

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

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

powered by: WebSVN 2.1.0

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