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

Subversion Repositories 8051

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

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

powered by: WebSVN 2.1.0

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