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

Subversion Repositories 8051

[/] [8051/] [tags/] [rel_1/] [rtl/] [verilog/] [oc8051_memory_interface.v] - Blame information for rev 186

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 146 simont
// Revision 1.7  2003/05/06 09:39:34  simont
48
// cahnge assigment to pc_wait (remove istb_o)
49
//
50 140 simont
// Revision 1.6  2003/05/05 15:46:37  simont
51
// add aditional alu destination to solve critical path.
52
//
53 139 simont
// Revision 1.5  2003/04/25 17:15:51  simont
54
// change branch instruction execution (reduse needed clock periods).
55
//
56 132 simont
// Revision 1.4  2003/04/16 10:04:09  simont
57
// chance idat_ir to 24 bit wide
58
//
59 128 simont
// Revision 1.3  2003/04/11 10:05:08  simont
60
// Change pc add value from 23'h to 16'h
61
//
62 121 simont
// Revision 1.2  2003/04/09 16:24:03  simont
63
// change wr_sft to 2 bit wire.
64
//
65 118 simont
// Revision 1.1  2003/01/13 14:13:12  simont
66
// initial import
67 81 simont
//
68 118 simont
//
69 81 simont
 
70
// synopsys translate_off
71
`include "oc8051_timescale.v"
72
// synopsys translate_on
73
 
74
`include "oc8051_defines.v"
75
 
76
 
77
module oc8051_memory_interface (clk, rst,
78
//decoder
79
  wr_i, wr_bit_i, rd_sel, wr_sel,
80
  pc_wr_sel, pc_wr, pc, rd,
81
  mem_wait, mem_act, istb,
82
//internal ram
83
  wr_o, wr_bit_o, rd_addr, wr_addr, rd_ind, wr_ind, wr_dat,
84
 
85
  bit_in, in_ram, sfr, sfr_bit, bit_out, iram_out,
86
 
87
//program rom
88
  iadr_o, ea, ea_int,
89
  op1_out, op2_out, op3_out,
90
//internal
91
  op1_i, op2_i, op3_i,
92
//external
93
  iack_i, istb_o, idat_i,
94
 
95
//external data ram
96
  dadr_o, dwe_o, dstb_o, dack_i, ddat_i, ddat_o,
97
//interrupt interface
98
  intr, int_v, int_ack,
99
 
100
//alu
101 139 simont
  des_acc, des1, des2,
102 81 simont
 
103
//sfr's
104 139 simont
  dptr, ri, sp,  sp_w, rn, acc, reti);
105 81 simont
 
106
input bit_in, sfr_bit, dack_i;
107
input [2:0] mem_act;
108
input [7:0] in_ram, sfr, acc, sp_w;
109
input [31:0] idat_i;
110
 
111
output bit_out, mem_wait, reti;
112
output [7:0] iram_out, wr_dat;
113
 
114
reg bit_out, reti;
115
reg [7:0] iram_out, sp_r;
116 139 simont
reg       rd_addr_r;
117 81 simont
input clk, rst, wr_i, wr_bit_i;
118
output wr_o, wr_bit_o;
119
 
120
//????
121
reg dack_ir;
122
reg [7:0] ddat_ir;
123
reg [23:0] idat_ir;
124
 
125
/////////////////////////////
126
//
127
//  rom_addr_sel
128
//
129
/////////////////////////////
130
input iack_i;
131 139 simont
input [7:0] des_acc, des1, des2;
132 81 simont
output [15:0] iadr_o;
133
 
134
wire ea_rom_sel;
135
 
136
/////////////////////////////
137
//
138
// ext_addr_sel
139
//
140
/////////////////////////////
141 139 simont
input [7:0] ri, ddat_i;
142 81 simont
input [15:0] dptr;
143
 
144
output dstb_o, dwe_o;
145
output [7:0] ddat_o;
146
output [15:0] dadr_o;
147
 
148
/////////////////////////////
149
//
150
// ram_adr_sel
151
//
152
/////////////////////////////
153
 
154
input [2:0] rd_sel, wr_sel;
155
input [4:0] rn;
156
input [7:0] sp;
157
 
158
output rd_ind, wr_ind;
159
output [7:0] wr_addr, rd_addr;
160
reg rd_ind, wr_ind;
161
reg [7:0] wr_addr, rd_addr;
162
 
163
reg [4:0] rn_r;
164
reg [7:0] ri_r, imm_r, imm2_r, op1_r;
165
wire [7:0] imm, imm2;
166
 
167
/////////////////////////////
168
//
169
// op_select
170
//
171
/////////////////////////////
172
 
173
input intr, rd, ea, ea_int, istb;
174
input [7:0] op1_i, op2_i, op3_i, int_v;
175
output int_ack, istb_o;
176
output [7:0] op1_out, op3_out, op2_out;
177
 
178
reg int_ack_t, int_ack, int_ack_buff;
179
reg [7:0] int_vec_buff;
180
reg [7:0] op1_out, op2_buff, op3_buff;
181
reg [7:0] op1_o, op2_o, op3_o;
182
reg [7:0] op1_xt, op2_xt, op3_xt;
183
 
184
wire [7:0] op1, op2, op3, op2_direct;
185
//wire op_sel;
186
 
187
/////////////////////////////
188
//
189
//  pc
190
//
191
/////////////////////////////
192
input [2:0] pc_wr_sel;
193
 
194
input pc_wr;
195
output [15:0] pc;
196
 
197
 
198
reg [15:0] pc;
199
 
200
//
201
//pc            program counter register, save current value
202
reg [15:0] pc_buf;
203
wire [15:0] alu;
204
 
205
//
206
// wr_lo        write low: used in reti instruction, write only low byte of pc
207
// ini_buff     interrupt buffer: used to prevent interrupting in the middle of executin instructions
208
reg int_buff, int_buff1;
209
 
210
 
211
//
212
//
213
////////////////////////////
214
reg istb_t, imem_wait, dstb_o, dwe_o;
215
//reg [3:0] mem_act_r;
216
reg [7:0] ddat_o;
217
reg [15:0] iadr_t, dadr_ot;
218
reg dmem_wait;
219
wire pc_wait;
220
wire [1:0] bank;
221
//wire pis_l;
222
wire [15:0] iadr_ot;
223
wire [7:0] isr_call;
224
 
225
assign bank = rn[4:3];
226
assign imm = op2_out;
227
assign imm2 = op3_out;
228 139 simont
assign alu = {des2, des_acc};
229 81 simont
assign ea_rom_sel = ea && ea_int;
230
assign wr_o = wr_i;
231
assign wr_bit_o = wr_bit_i;
232
 
233
assign mem_wait = dmem_wait || imem_wait;
234 146 simont
assign istb_o = (istb || (istb_t & !iack_i)) && !dstb_o && !ea_rom_sel;
235 81 simont
 
236 140 simont
assign pc_wait = rd && (ea_rom_sel || (!istb_t && iack_i));
237 81 simont
 
238
assign wr_dat = des1;
239
 
240
 
241
/////////////////////////////
242
//
243
//  ram_select
244
//
245 140 simont
/////////////////////////////
246 139 simont
always @(rd_addr_r or in_ram or sfr or bit_in or sfr_bit or rd_ind)
247 81 simont
begin
248 139 simont
  if (rd_addr_r && !rd_ind) begin
249 81 simont
    iram_out = sfr;
250
    bit_out = sfr_bit;
251
  end else begin
252
    iram_out = in_ram;
253
    bit_out = bit_in;
254
  end
255
end
256
 
257
/////////////////////////////
258
//
259
// ram_adr_sel
260
//
261
/////////////////////////////
262
 
263 140 simont
always @(rd_sel or sp or ri or rn or imm or dadr_o[15:0] or bank)
264 81 simont
begin
265 139 simont
  case (rd_sel)
266
    `OC8051_RRS_RN   : rd_addr = {3'h0, rn};
267
    `OC8051_RRS_I    : rd_addr = ri;
268
    `OC8051_RRS_D    : rd_addr = imm;
269
    `OC8051_RRS_SP   : rd_addr = sp;
270 81 simont
 
271 139 simont
    `OC8051_RRS_B    : rd_addr = `OC8051_SFR_B;
272
    `OC8051_RRS_DPTR : rd_addr = `OC8051_SFR_DPTR_LO;
273
    `OC8051_RRS_PSW  : rd_addr = `OC8051_SFR_PSW;
274
    `OC8051_RRS_ACC  : rd_addr = `OC8051_SFR_ACC;
275
    default          : rd_addr = 2'bxx;
276
  endcase
277 81 simont
 
278
end
279
 
280
 
281
//
282
//
283
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])
284
begin
285 139 simont
  case (wr_sel)
286
    `OC8051_RWS_RN : wr_addr = {3'h0, rn_r};
287
    `OC8051_RWS_I  : wr_addr = ri_r;
288
    `OC8051_RWS_D  : wr_addr = imm_r;
289
    `OC8051_RWS_SP : wr_addr = sp_w;
290
    `OC8051_RWS_D3 : wr_addr = imm2_r;
291
    `OC8051_RWS_B  : wr_addr = `OC8051_SFR_B;
292
    default        : wr_addr = 2'bxx;
293
  endcase
294 81 simont
end
295
 
296
always @(posedge clk or posedge rst)
297
  if (rst)
298
    rd_ind <= #1 1'b0;
299
  else if ((rd_sel==`OC8051_RRS_I) || (rd_sel==`OC8051_RRS_SP))
300
    rd_ind <= #1 1'b1;
301
  else
302
    rd_ind <= #1 1'b0;
303
 
304
always @(wr_sel)
305
  if ((wr_sel==`OC8051_RWS_I) || (wr_sel==`OC8051_RWS_SP))
306
    wr_ind = 1'b1;
307
  else
308
    wr_ind = 1'b0;
309
 
310
 
311
/////////////////////////////
312
//
313
//  rom_addr_sel
314
//
315
/////////////////////////////
316
//
317
// output address is alu destination
318
// (instructions MOVC)
319
 
320 139 simont
assign iadr_ot = (istb_t & !iack_i) ? iadr_t : pc;
321 81 simont
assign iadr_o = iadr_ot;
322
 
323
 
324
always @(posedge clk or posedge rst)
325
begin
326
  if (rst) begin
327
    iadr_t <= #1 23'h0;
328
    istb_t <= #1 1'b0;
329
    imem_wait <= #1 1'b0;
330
    idat_ir <= #1 24'h0;
331
  end else if (iack_i) begin
332
    istb_t <= #1 1'b0;
333
    imem_wait <= #1 1'b0;
334 128 simont
    idat_ir <= #1 idat_i [23:0];
335 81 simont
  end else if (ea_rom_sel && imem_wait) begin
336
    imem_wait <= #1 1'b0;
337
  end else if (ea_rom_sel && !imem_wait && istb_t) begin
338
    istb_t <= #1 1'b0;
339
  end else if (mem_act==`OC8051_MAS_CODE) begin
340 139 simont
    iadr_t <= #1 alu;
341 81 simont
    istb_t <= #1 1'b1;
342
    imem_wait <= #1 1'b1;
343
  end
344
end
345
 
346
/////////////////////////////
347
//
348
// ext_addr_sel
349
//
350
/////////////////////////////
351
 
352
assign dadr_o = dadr_ot;
353
 
354
always @(posedge clk or posedge rst)
355
begin
356
  if (rst) begin
357
    dwe_o <= #1 1'b0;
358
    dmem_wait <= #1 1'b0;
359
    dstb_o <= #1 1'b0;
360
    ddat_o <= #1 8'h00;
361
    dadr_ot <= #1 23'h0;
362
  end else if (dack_i) begin
363
    dwe_o <= #1 1'b0;
364
    dstb_o <= #1 1'b0;
365
    dmem_wait <= #1 1'b0;
366
  end else begin
367
    case (mem_act)
368
      `OC8051_MAS_DPTR_R: begin  // read from external rom: acc=(dptr)
369
        dwe_o <= #1 1'b0;
370
        dstb_o <= #1 1'b1;
371
        ddat_o <= #1 8'h00;
372
        dadr_ot <= #1 {7'h0, dptr};
373
        dmem_wait <= #1 1'b1;
374
      end
375
      `OC8051_MAS_DPTR_W: begin  // write to external rom: (dptr)=acc
376
        dwe_o <= #1 1'b1;
377
        dstb_o <= #1 1'b1;
378
        ddat_o <= #1 acc;
379
        dadr_ot <= #1 {7'h0, dptr};
380
        dmem_wait <= #1 1'b1;
381
      end
382
      `OC8051_MAS_RI_R:   begin  // read from external rom: acc=(Ri)
383
        dwe_o <= #1 1'b0;
384
        dstb_o <= #1 1'b1;
385
        ddat_o <= #1 8'h00;
386
        dadr_ot <= #1 {15'h0, ri};
387
        dmem_wait <= #1 1'b1;
388
      end
389
      `OC8051_MAS_RI_W: begin    // write to external rom: (Ri)=acc
390
        dwe_o <= #1 1'b1;
391
        dstb_o <= #1 1'b1;
392
        ddat_o <= #1 acc;
393
        dadr_ot <= #1 {15'h0, ri};
394
        dmem_wait <= #1 1'b1;
395
      end
396
    endcase
397
  end
398
end
399
 
400
/////////////////////////////
401
//
402
// op_select
403
//
404
/////////////////////////////
405
 
406
 
407
assign op1 = ea_rom_sel ? op1_i: op1_xt;
408
assign op2 = ea_rom_sel ? op2_i: op2_xt;
409
assign op3 = ea_rom_sel ? op3_i: op3_xt;
410
 
411
 
412
always @(dack_ir or ddat_ir or op1_o or iram_out)
413
  if (dack_ir)
414
    op1_out = ddat_ir;
415
  else
416
    op1_out = op1_o;
417
 
418
assign op3_out = (rd) ? op3_o : op3_buff;
419
assign op2_out = (rd) ? op2_o : op2_buff;
420
 
421
always @(idat_i or iack_i or idat_ir or rd)
422
begin
423
  if (iack_i) begin
424 128 simont
    op1_xt = idat_i[7:0];
425
    op2_xt = idat_i[15:8];
426
    op3_xt = idat_i[23:16];
427 81 simont
  end else if (!rd) begin
428 128 simont
    op1_xt = idat_ir[7:0];
429 81 simont
    op2_xt = idat_ir[15:8];
430 128 simont
    op3_xt = idat_ir[23:16];
431 81 simont
  end else begin
432
    op1_xt = 8'h00;
433
    op2_xt = 8'h00;
434
    op3_xt = 8'h00;
435
  end
436
end
437
 
438
 
439
//
440
// in case of interrupts
441
always @(op1 or op2 or op3 or int_ack_t or int_vec_buff or iack_i or ea_rom_sel)
442
begin
443
  if (int_ack_t && (iack_i || ea_rom_sel)) begin
444
    op1_o = `OC8051_LCALL;
445
    op2_o = 8'h00;
446
    op3_o = int_vec_buff;
447
  end else begin
448
    op1_o = op1;
449
    op2_o = op2;
450
    op3_o = op3;
451
  end
452
end
453
 
454
//
455
//in case of reti
456
always @(posedge clk or posedge rst)
457
  if (rst) reti <= #1 1'b0;
458
  else if ((op1_o==`OC8051_RETI) & rd) reti <= #1 1'b1;
459
  else reti <= #1 1'b0;
460
 
461
//
462
// remember inputs
463
always @(posedge clk or posedge rst)
464
begin
465
  if (rst) begin
466
    op2_buff <= #1 8'h0;
467
    op3_buff <= #1 8'h0;
468
  end else if (rd) begin
469
    op2_buff <= #1 op2_o;
470
    op3_buff <= #1 op3_o;
471
  end
472
end
473
 
474
//
475
// remember interrupt
476
// we don't want to interrupt instruction in the middle of execution
477
always @(posedge clk or posedge rst)
478
 if (rst) begin
479
   int_ack_t <= #1 1'b0;
480
   int_vec_buff <= #1 8'h00;
481
 end else if (intr) begin
482
   int_ack_t <= #1 1'b1;
483
   int_vec_buff <= #1 int_v;
484
 end else if (rd && (ea_rom_sel || iack_i)) int_ack_t <= #1 1'b0;
485
 
486
always @(posedge clk or posedge rst)
487
  if (rst) int_ack_buff <= #1 1'b0;
488
  else int_ack_buff <= #1 int_ack_t;
489
 
490
always @(posedge clk or posedge rst)
491
  if (rst) int_ack <= #1 1'b0;
492
  else begin
493
    if ((int_ack_buff) & !(int_ack_t))
494
      int_ack <= #1 1'b1;
495
    else int_ack <= #1 1'b0;
496
  end
497
 
498
 
499
/////////////////////////////
500
//
501
//  pc
502
//
503
/////////////////////////////
504
 
505 139 simont
always @(pc_buf or op1_out or pc_wait or int_buff or int_buff1 or ea_rom_sel or iack_i)
506 81 simont
begin
507
    if (int_buff || int_buff1) begin
508
//
509
//in case of interrupt hold valut, to be written to stack
510
      pc= pc_buf;
511
//    end else if (pis_l) begin
512
//      pc = {pc_buf[22:8], alu[7:0]};
513
    end else if (pc_wait) begin
514
        casex (op1_out)
515 121 simont
          `OC8051_ACALL :  pc= pc_buf + 16'h2;
516
          `OC8051_AJMP :   pc= pc_buf + 16'h2;
517 81 simont
 
518
        //op_code [7:3]
519 121 simont
          `OC8051_CJNE_R : pc= pc_buf + 16'h3;
520
          `OC8051_DJNZ_R : pc= pc_buf + 16'h2;
521
          `OC8051_MOV_DR : pc= pc_buf + 16'h2;
522
          `OC8051_MOV_CR : pc= pc_buf + 16'h2;
523
          `OC8051_MOV_RD : pc= pc_buf + 16'h2;
524 81 simont
 
525
        //op_code [7:1]
526 121 simont
          `OC8051_CJNE_I : pc= pc_buf + 16'h3;
527
          `OC8051_MOV_ID : pc= pc_buf + 16'h2;
528
          `OC8051_MOV_DI : pc= pc_buf + 16'h2;
529
          `OC8051_MOV_CI : pc= pc_buf + 16'h2;
530 81 simont
 
531
        //op_code [7:0]
532 121 simont
          `OC8051_ADD_D :  pc= pc_buf + 16'h2;
533
          `OC8051_ADD_C :  pc= pc_buf + 16'h2;
534
          `OC8051_ADDC_D : pc= pc_buf + 16'h2;
535
          `OC8051_ADDC_C : pc= pc_buf + 16'h2;
536
          `OC8051_ANL_D :  pc= pc_buf + 16'h2;
537
          `OC8051_ANL_C :  pc= pc_buf + 16'h2;
538
          `OC8051_ANL_DD : pc= pc_buf + 16'h2;
539
          `OC8051_ANL_DC : pc= pc_buf + 16'h3;
540
          `OC8051_ANL_B :  pc= pc_buf + 16'h2;
541
          `OC8051_ANL_NB : pc= pc_buf + 16'h2;
542
          `OC8051_CJNE_D : pc= pc_buf + 16'h3;
543
          `OC8051_CJNE_C : pc= pc_buf + 16'h3;
544
          `OC8051_CLR_B :  pc= pc_buf + 16'h2;
545
          `OC8051_CPL_B :  pc= pc_buf + 16'h2;
546
          `OC8051_DEC_D :  pc= pc_buf + 16'h2;
547
          `OC8051_DJNZ_D : pc= pc_buf + 16'h3;
548
          `OC8051_INC_D :  pc= pc_buf + 16'h2;
549
          `OC8051_JB :     pc= pc_buf + 16'h3;
550
          `OC8051_JBC :    pc= pc_buf + 16'h3;
551
          `OC8051_JC :     pc= pc_buf + 16'h2;
552
          `OC8051_JNB :    pc= pc_buf + 16'h3;
553
          `OC8051_JNC :    pc= pc_buf + 16'h2;
554
          `OC8051_JNZ :    pc= pc_buf + 16'h2;
555
          `OC8051_JZ :     pc= pc_buf + 16'h2;
556
          `OC8051_LCALL :  pc= pc_buf + 16'h3;
557
          `OC8051_LJMP :   pc= pc_buf + 16'h3;
558
          `OC8051_MOV_D :  pc= pc_buf + 16'h2;
559
          `OC8051_MOV_C :  pc= pc_buf + 16'h2;
560
          `OC8051_MOV_DA : pc= pc_buf + 16'h2;
561
          `OC8051_MOV_DD : pc= pc_buf + 16'h3;
562
          `OC8051_MOV_CD : pc= pc_buf + 16'h3;
563
          `OC8051_MOV_BC : pc= pc_buf + 16'h2;
564
          `OC8051_MOV_CB : pc= pc_buf + 16'h2;
565
          `OC8051_MOV_DP : pc= pc_buf + 16'h3;
566
          `OC8051_ORL_D :  pc= pc_buf + 16'h2;
567
          `OC8051_ORL_C :  pc= pc_buf + 16'h2;
568
          `OC8051_ORL_AD : pc= pc_buf + 16'h2;
569
          `OC8051_ORL_CD : pc= pc_buf + 16'h3;
570
          `OC8051_ORL_B :  pc= pc_buf + 16'h2;
571
          `OC8051_ORL_NB : pc= pc_buf + 16'h2;
572
          `OC8051_POP :    pc= pc_buf + 16'h2;
573
          `OC8051_PUSH :   pc= pc_buf + 16'h2;
574
          `OC8051_SETB_B : pc= pc_buf + 16'h2;
575
          `OC8051_SJMP :   pc= pc_buf + 16'h2;
576
          `OC8051_SUBB_D : pc= pc_buf + 16'h2;
577
          `OC8051_SUBB_C : pc= pc_buf + 16'h2;
578
          `OC8051_XCH_D :  pc= pc_buf + 16'h2;
579
          `OC8051_XRL_D :  pc= pc_buf + 16'h2;
580
          `OC8051_XRL_C :  pc= pc_buf + 16'h2;
581
          `OC8051_XRL_AD : pc= pc_buf + 16'h2;
582
          `OC8051_XRL_CD : pc= pc_buf + 16'h3;
583
          default:         pc= pc_buf + 16'h1;
584 81 simont
        endcase
585
//
586
//in case of instructions that use more than one clock hold current pc
587
    end else begin
588
      pc= pc_buf;
589
   end
590
end
591
 
592
 
593
//
594
//interrupt buffer
595
always @(posedge clk or posedge rst)
596
  if (rst) begin
597
    int_buff1 <= #1 1'b0;
598
  end else begin
599
    int_buff1 <= #1 int_buff;
600
  end
601
 
602
always @(posedge clk or posedge rst)
603
  if (rst) begin
604
    int_buff <= #1 1'b0;
605
  end else if (intr) begin
606
    int_buff <= #1 1'b1;
607
  end else if (pc_wait)
608
    int_buff <= #1 1'b0;
609
 
610 132 simont
wire [7:0]  pcs_source;
611
reg  [15:0] pcs_result;
612
reg         pcs_cy;
613 81 simont
 
614 132 simont
assign pcs_source = pc_wr_sel[0] ? op3_out : op2_out;
615
 
616
always @(pcs_source or pc or pcs_cy)
617
begin
618
  if (pcs_source[7]) begin
619
    {pcs_cy, pcs_result[7:0]} = {1'b0, pc[7:0]} + {1'b0, pcs_source};
620
    pcs_result[15:8] = pc[15:8] - {7'h0, !pcs_cy};
621
  end else pcs_result = pc + {8'h00, pcs_source};
622
end
623
 
624
 
625 81 simont
always @(posedge clk or posedge rst)
626
begin
627
  if (rst) begin
628
    pc_buf <= #1 `OC8051_RST_PC;
629
  end else begin
630
    if (pc_wr) begin
631
//
632
//case of writing new value to pc (jupms)
633
      case (pc_wr_sel)
634
        `OC8051_PIS_ALU: pc_buf        <= #1 alu;
635
        `OC8051_PIS_AL:  pc_buf[7:0]   <= #1 alu[7:0];
636
        `OC8051_PIS_AH:  pc_buf[15:8]  <= #1 alu[7:0];
637
        `OC8051_PIS_I11: pc_buf[10:0]  <= #1 {op1_out[7:5], op2_out};
638
        `OC8051_PIS_I16: pc_buf        <= #1 {op2_out, op3_out};
639 132 simont
        `OC8051_PIS_SO1: pc_buf        <= #1 pcs_result;
640
        `OC8051_PIS_SO2: pc_buf        <= #1 pcs_result;
641 81 simont
      endcase
642
    end else
643
//
644
//or just remember current
645
      pc_buf <= #1 pc;
646
  end
647
end
648
 
649
 
650
always @(posedge clk or posedge rst)
651
  if (rst)
652
    ddat_ir <= #1 8'h00;
653
  else if (dack_i)
654
    ddat_ir <= #1 ddat_i;
655
 
656
////////////////////////
657
always @(posedge clk or posedge rst)
658
  if (rst) begin
659
    rn_r <= #1 5'd0;
660
    ri_r <= #1 8'h00;
661
    imm_r <= #1 8'h00;
662
    imm2_r <= #1 8'h00;
663 139 simont
    rd_addr_r <= #1 1'b0;
664 81 simont
    op1_r <= #1 8'h0;
665
    dack_ir <= #1 1'b0;
666
    sp_r <= #1 1'b0;
667
  end else begin
668
    rn_r <= #1 rn;
669
    ri_r <= #1 ri;
670
    imm_r <= #1 imm;
671
    imm2_r <= #1 imm2;
672 139 simont
    rd_addr_r <= #1 rd_addr[7];
673 81 simont
    op1_r <= #1 op1_out;
674
    dack_ir <= #1 dack_i;
675
    sp_r <= #1 sp;
676
  end
677
 
678
 
679
endmodule

powered by: WebSVN 2.1.0

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