data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v
1: b'%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:2: Cannot find include file: oc8051_timescale.v\n`include "oc8051_timescale.v" \n         ^~~~~~~~~~~~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/505293718/8051/verilog,data/full_repos/permissive/505293718/oc8051_timescale.v\n             data/full_repos/permissive/505293718/8051/verilog,data/full_repos/permissive/505293718/oc8051_timescale.v.v\n             data/full_repos/permissive/505293718/8051/verilog,data/full_repos/permissive/505293718/oc8051_timescale.v.sv\n             oc8051_timescale.v\n             oc8051_timescale.v.v\n             oc8051_timescale.v.sv\n             obj_dir/oc8051_timescale.v\n             obj_dir/oc8051_timescale.v.v\n             obj_dir/oc8051_timescale.v.sv\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:5: Cannot find include file: oc8051_defines.v\n`include "oc8051_defines.v" \n         ^~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:317: Define or directive not defined: \'`OC8051_RRS_RN\'\n    `OC8051_RRS_RN   : rd_addr = {3\'h0, rn};\n    ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:317: syntax error, unexpected \':\', expecting endcase\n    `OC8051_RRS_RN   : rd_addr = {3\'h0, rn};\n                     ^\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:318: Define or directive not defined: \'`OC8051_RRS_I\'\n    `OC8051_RRS_I    : rd_addr = ri;\n    ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:319: Define or directive not defined: \'`OC8051_RRS_D\'\n    `OC8051_RRS_D    : rd_addr = imm;\n    ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:320: Define or directive not defined: \'`OC8051_RRS_SP\'\n    `OC8051_RRS_SP   : rd_addr = sp;\n    ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:322: Define or directive not defined: \'`OC8051_RRS_B\'\n    `OC8051_RRS_B    : rd_addr = `OC8051_SFR_B;\n    ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:322: Define or directive not defined: \'`OC8051_SFR_B\'\n    `OC8051_RRS_B    : rd_addr = `OC8051_SFR_B;\n                                 ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:323: Define or directive not defined: \'`OC8051_RRS_DPTR\'\n    `OC8051_RRS_DPTR : rd_addr = `OC8051_SFR_DPTR_LO;\n    ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:323: Define or directive not defined: \'`OC8051_SFR_DPTR_LO\'\n    `OC8051_RRS_DPTR : rd_addr = `OC8051_SFR_DPTR_LO;\n                                 ^~~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:324: Define or directive not defined: \'`OC8051_RRS_PSW\'\n    `OC8051_RRS_PSW  : rd_addr = `OC8051_SFR_PSW;\n    ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:324: Define or directive not defined: \'`OC8051_SFR_PSW\'\n    `OC8051_RRS_PSW  : rd_addr = `OC8051_SFR_PSW;\n                                 ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:325: Define or directive not defined: \'`OC8051_RRS_ACC\'\n    `OC8051_RRS_ACC  : rd_addr = `OC8051_SFR_ACC;\n    ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:325: Define or directive not defined: \'`OC8051_SFR_ACC\'\n    `OC8051_RRS_ACC  : rd_addr = `OC8051_SFR_ACC;\n                                 ^~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:337: Define or directive not defined: \'`OC8051_RWS_RN\'\n    `OC8051_RWS_RN : wr_addr = {3\'h0, rn_r};\n    ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:338: Define or directive not defined: \'`OC8051_RWS_I\'\n    `OC8051_RWS_I  : wr_addr = ri_r;\n    ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:339: Define or directive not defined: \'`OC8051_RWS_D\'\n    `OC8051_RWS_D  : wr_addr = imm_r;\n    ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:340: Define or directive not defined: \'`OC8051_RWS_SP\'\n    `OC8051_RWS_SP : wr_addr = sp_w;\n    ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:341: Define or directive not defined: \'`OC8051_RWS_D3\'\n    `OC8051_RWS_D3 : wr_addr = imm2_r;\n    ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:342: Define or directive not defined: \'`OC8051_RWS_B\'\n    `OC8051_RWS_B  : wr_addr = `OC8051_SFR_B;\n    ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:342: Define or directive not defined: \'`OC8051_SFR_B\'\n    `OC8051_RWS_B  : wr_addr = `OC8051_SFR_B;\n                               ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:351: Define or directive not defined: \'`OC8051_RRS_I\'\n  else if ((rd_sel==`OC8051_RRS_I) || (rd_sel==`OC8051_RRS_SP))\n                    ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:351: Define or directive not defined: \'`OC8051_RRS_SP\'\n  else if ((rd_sel==`OC8051_RRS_I) || (rd_sel==`OC8051_RRS_SP))\n                                               ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:357: Define or directive not defined: \'`OC8051_RWS_I\'\n  if ((wr_sel==`OC8051_RWS_I) || (wr_sel==`OC8051_RWS_SP))\n               ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:357: Define or directive not defined: \'`OC8051_RWS_SP\'\n  if ((wr_sel==`OC8051_RWS_I) || (wr_sel==`OC8051_RWS_SP))\n                                          ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:376: syntax error, unexpected always\nalways @(posedge clk )\n^~~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:383: syntax error, unexpected else\n  end else if (mem_act==`OC8051_MAS_CODE) begin\n      ^~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:383: Define or directive not defined: \'`OC8051_MAS_CODE\'\n  end else if (mem_act==`OC8051_MAS_CODE) begin\n                        ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:419: Define or directive not defined: \'`OC8051_MAS_DPTR_R\'\n      `OC8051_MAS_DPTR_R: begin   \n      ^~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:419: syntax error, unexpected \':\', expecting endcase\n      `OC8051_MAS_DPTR_R: begin   \n                        ^\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:426: Define or directive not defined: \'`OC8051_MAS_DPTR_W\'\n      `OC8051_MAS_DPTR_W: begin   \n      ^~~~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:426: syntax error, unexpected begin, expecting IDENTIFIER or PACKAGE-IDENTIFIER or TYPE-IDENTIFIER or new\n      `OC8051_MAS_DPTR_W: begin   \n                          ^~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:433: Define or directive not defined: \'`OC8051_MAS_RI_R\'\n      `OC8051_MAS_RI_R:   begin   \n      ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:433: syntax error, unexpected begin, expecting IDENTIFIER or PACKAGE-IDENTIFIER or TYPE-IDENTIFIER or new\n      `OC8051_MAS_RI_R:   begin   \n                          ^~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:440: Define or directive not defined: \'`OC8051_MAS_RI_W\'\n      `OC8051_MAS_RI_W: begin     \n      ^~~~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:440: syntax error, unexpected begin, expecting IDENTIFIER or PACKAGE-IDENTIFIER or TYPE-IDENTIFIER or new\n      `OC8051_MAS_RI_W: begin     \n                        ^~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:447: syntax error, unexpected endcase\n    endcase\n    ^~~~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:464: syntax error, unexpected else\n  end else if ((iack_i | ea_rom_sel) & (inc_pc | pc_wr_r2)) begin\n      ^~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:573: Define or directive not defined: \'`OC8051_LCALL\'\n    op1_o = `OC8051_LCALL;\n            ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:573: syntax error, unexpected \';\', expecting TYPE-IDENTIFIER\n    op1_o = `OC8051_LCALL;\n                         ^\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:587: Define or directive not defined: \'`OC8051_RETI\'\n  else if ((op1_o==`OC8051_RETI) & rd & !mem_wait) reti <= #1 1\'b1;\n                   ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:587: syntax error, unexpected \')\', expecting TYPE-IDENTIFIER\n  else if ((op1_o==`OC8051_RETI) & rd & !mem_wait) reti <= #1 1\'b1;\n                               ^\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:612: Define or directive not defined: \'`OC8051_ACALL\'\n          `OC8051_ACALL :  op_length = 2\'h2;\n          ^~~~~~~~~~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:612: syntax error, unexpected \':\', expecting endcase\n          `OC8051_ACALL :  op_length = 2\'h2;\n                        ^\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:613: Define or directive not defined: \'`OC8051_AJMP\'\n          `OC8051_AJMP :   op_length = 2\'h2;\n          ^~~~~~~~~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:616: Define or directive not defined: \'`OC8051_CJNE_R\'\n          `OC8051_CJNE_R : op_length = 2\'h3;\n          ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:617: Define or directive not defined: \'`OC8051_DJNZ_R\'\n          `OC8051_DJNZ_R : op_length = 2\'h2;\n          ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:618: Define or directive not defined: \'`OC8051_MOV_DR\'\n          `OC8051_MOV_DR : op_length = 2\'h2;\n          ^~~~~~~~~~~~~~\n%Error: data/full_repos/permissive/505293718/8051/verilog/oc8051_memory_interface.v:619: Define or directive not defined: \'`OC8051_MOV_CR\'\n          `OC8051_MOV_CR : op_length = 2\'h2;\n          ^~~~~~~~~~~~~~\n%Error: Exiting due to too many errors encountered; --error-limit=50\n'
module oc8051_memory_interface (clk, rst,


     wr_i,
     wr_bit_i,
     rd_sel,
     wr_sel,
     pc_wr_sel,
     pc_wr,
     pc,
     rd,
     mem_wait,
     mem_act,
     istb,


     wr_o, 
     wr_bit_o, 
     rd_addr, 
     wr_addr, 
     rd_ind, 
     wr_ind, 
     wr_dat,

     bit_in, 
     in_ram, 
     sfr, 
     sfr_bit, 
     bit_out, 
     iram_out,


     iadr_o, 
     ea, 
     ea_int,
     op1_out,  op1,
     op2_out,  op2,
     op3_out,  op3,
     out_of_rst,
     decoder_new_valid_pc,
     pc_log,
     pc_log_prev,


     idat_onchip,


     iack_i, 
     istb_o, 
     idat_i,


     dadr_o, 
     dwe_o, 
     dstb_o, 
     dack_i,
     ddat_i, 
     ddat_o,


     intr, 
     int_v, 
     int_ack,


     des_acc, 
     des1, 
     des2,


     dptr, 
     ri, 
     sp,  
     sp_w, 
     rn, 
     acc, 
     reti
   );


input         clk,
              rst,
              wr_i,
              wr_bit_i;

input         bit_in,
              sfr_bit,
              dack_i;
input [2:0]   mem_act;
input [7:0]   in_ram,
              sfr,
              acc,
              sp_w;
input [31:0]  idat_i;

output        bit_out,
              mem_wait,
              reti;
output [7:0]  iram_out,
              wr_dat;
output        out_of_rst;
input         decoder_new_valid_pc;
output [15:0] pc_log;
output [15:0] pc_log_prev;

reg           bit_out,
              reti;
reg [7:0]     iram_out,
              sp_r;
reg           rd_addr_r;
output        wr_o,
              wr_bit_o;


reg           dack_ir;
reg [7:0]     ddat_ir;
reg [23:0]    idat_ir;






input         iack_i;
input [7:0]   des_acc,
              des1,
              des2;
output [15:0] iadr_o;

wire          ea_rom_sel;






input [7:0]   ri,
              ddat_i;
input [15:0]  dptr;

output        dstb_o,
              dwe_o;
output [7:0]  ddat_o;
output [15:0] dadr_o;







input [2:0]   rd_sel,
              wr_sel;
input [4:0]   rn;
input [7:0]   sp;

output        rd_ind,
              wr_ind;
output [7:0]  wr_addr,
              rd_addr;
reg           rd_ind;
reg           wr_ind;
reg [7:0]     wr_addr;
reg [7:0]     rd_addr;

reg [4:0]     rn_r;
reg [7:0]     ri_r,imm_r,imm2_r,op1_r;
wire [7:0]    imm,
              imm2;







input         intr,rd,ea, ea_int, istb;

input  [7:0]  int_v;

input  [31:0] idat_onchip;

output        int_ack,
              istb_o;

output  [7:0] op1_out, op1,
              op3_out, op2,
              op2_out, op3;

reg           int_ack_t,int_ack,int_ack_buff;

reg [7:0]     int_vec_buff;
reg [7:0]     op1_out,op2_buff,op3_buff;
reg [7:0]     op1_o,op2_o,op3_o;

reg [7:0]     op1_xt, 
              op2_xt, 
              op3_xt;

reg [7:0]     op1,op2,op3;
wire [7:0]    op2_direct;

input [2:0]   pc_wr_sel;

input         pc_wr;
output [15:0] pc;

reg [15:0]    pc;



reg [15:0]    pc_buf;
wire [15:0]   alu;


reg           int_buff,
              int_buff1;







reg first_time_done;
wire first_time;
always @(posedge clk) begin
  if (rst) begin
    first_time_done <= 1;
  end else begin
    if ((dack_i == 0) && (dstb_o == 0) && ((mem_act == 0) || (mem_act == 2) || (mem_act == 1) || (mem_act == 3)))
      first_time_done <= 1; 
  end
end
assign first_time = (!first_time_done) && ((dack_i == 0) && (dstb_o == 0) && ((mem_act == 0) || (mem_act == 2) || (mem_act == 1) || (mem_act == 3)));




reg           istb_t,imem_wait,dstb_o,dwe_o;

reg [7:0]     ddat_o;
reg [15:0]    iadr_t,
              dadr_ot;
reg           dmem_wait;
wire          pc_wait;
wire [1:0]    bank;
wire [7:0]    isr_call;

reg [1:0]     op_length;
reg [2:0]     op_pos;
wire          inc_pc;

reg           pc_wr_r;

wire [15:0]   pc_out;

reg [31:0]    idat_cur,idat_old;

reg           inc_pc_r,
              pc_wr_r2;

reg [7:0]     cdata;
reg           cdone;


assign bank       = rn[4:3];
assign imm        = op2_out;
assign imm2       = op3_out;
assign alu        = {des2, des_acc};
assign ea_rom_sel = ea && ea_int;
assign wr_o       = wr_i;
assign wr_bit_o   = wr_bit_i;


assign mem_wait   = dmem_wait || imem_wait || pc_wr_r2;

assign istb_o     = (istb || (istb_t & !iack_i)) && !dstb_o && !ea_rom_sel;

assign pc_wait    = rd && (ea_rom_sel || (!istb_t && iack_i));

assign wr_dat     = des1;







always @(rd_addr_r or in_ram or sfr or bit_in or sfr_bit or rd_ind)
begin
  if (rd_addr_r && !rd_ind) begin
    iram_out = sfr;
    bit_out = sfr_bit;
  end else begin
    iram_out = in_ram;
    bit_out = bit_in;
  end
end







always @(rd_sel or sp or ri or rn or imm or dadr_o[15:0] or bank)
begin
  case (rd_sel) 
    `OC8051_RRS_RN   : rd_addr = {3'h0, rn};
    `OC8051_RRS_I    : rd_addr = ri;
    `OC8051_RRS_D    : rd_addr = imm;
    `OC8051_RRS_SP   : rd_addr = sp;

    `OC8051_RRS_B    : rd_addr = `OC8051_SFR_B;
    `OC8051_RRS_DPTR : rd_addr = `OC8051_SFR_DPTR_LO;
    `OC8051_RRS_PSW  : rd_addr = `OC8051_SFR_PSW;
    `OC8051_RRS_ACC  : rd_addr = `OC8051_SFR_ACC;

  endcase

end




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])
begin
  case (wr_sel) 
    `OC8051_RWS_RN : wr_addr = {3'h0, rn_r};
    `OC8051_RWS_I  : wr_addr = ri_r;
    `OC8051_RWS_D  : wr_addr = imm_r;
    `OC8051_RWS_SP : wr_addr = sp_w;
    `OC8051_RWS_D3 : wr_addr = imm2_r;
    `OC8051_RWS_B  : wr_addr = `OC8051_SFR_B;

    default        : wr_addr = 2'bxx;
  endcase
end

always @(posedge clk )
  if (rst)
    rd_ind <= #1 1'b0;
  else if ((rd_sel==`OC8051_RRS_I) || (rd_sel==`OC8051_RRS_SP))
    rd_ind <= #1 1'b1;
  else
    rd_ind <= #1 1'b0;

always @(wr_sel)
  if ((wr_sel==`OC8051_RWS_I) || (wr_sel==`OC8051_RWS_SP))
    wr_ind = 1'b1;
  else
    wr_ind = 1'b0;












assign iadr_o = (istb_t) ? iadr_t : pc_out;


always @(posedge clk )
begin
  if (rst) begin
    iadr_t <= #1 23'h0;
    istb_t <= #1 1'b0;
    imem_wait <= #1 1'b0;
    idat_ir <= #1 24'h0;
  end else if (mem_act==`OC8051_MAS_CODE) begin
    iadr_t <= #1 alu;
    istb_t <= #1 1'b1;
    imem_wait <= #1 1'b1;
  end else if (ea_rom_sel && imem_wait) begin
    imem_wait <= #1 1'b0;
  end else if (!imem_wait && istb_t) begin
    istb_t <= #1 1'b0;
  end else if (iack_i) begin
    imem_wait <= #1 1'b0;
    idat_ir <= #1 idat_i [23:0];
  end
end







assign dadr_o = dadr_ot;

always @(posedge clk )
begin
  if (rst) begin
    dwe_o <= #1 1'b0;
    dmem_wait <= #1 1'b0;
    dstb_o <= #1 1'b0;
    ddat_o <= #1 8'h00;
    dadr_ot <= #1 23'h0;
  end else if (dack_i) begin
    dwe_o <= #1 1'b0;
    dstb_o <= #1 1'b0;
    dmem_wait <= #1 1'b0;
  end else begin
    case (mem_act) 
      `OC8051_MAS_DPTR_R: begin
        dwe_o <= #1 1'b0;
        dstb_o <= #1 1'b1;
        ddat_o <= #1 8'h00;
        dadr_ot <= #1 {7'h0, dptr};
        dmem_wait <= #1 1'b1;
      end
      `OC8051_MAS_DPTR_W: begin
        dwe_o <= #1 1'b1;
        dstb_o <= #1 1'b1;
        ddat_o <= #1 acc;
        dadr_ot <= #1 {7'h0, dptr};
        dmem_wait <= #1 1'b1;
      end
      `OC8051_MAS_RI_R:   begin
        dwe_o <= #1 1'b0;
        dstb_o <= #1 1'b1;
        ddat_o <= #1 8'h00;
        dadr_ot <= #1 {15'h0, ri};
        dmem_wait <= #1 1'b1;
      end
      `OC8051_MAS_RI_W: begin
        dwe_o <= #1 1'b1;
        dstb_o <= #1 1'b1;
        ddat_o <= #1 acc;
        dadr_ot <= #1 {15'h0, ri};
        dmem_wait <= #1 1'b1;
      end
    endcase
  end
end









always @(posedge clk )
begin
  if (rst) begin
    idat_cur            <= #1 32'h0;
    idat_old            <= #1 32'h0;
  end else if ((iack_i | ea_rom_sel) & (inc_pc | pc_wr_r2)) begin
    idat_cur            <= #1 ea_rom_sel ? idat_onchip : idat_i;
    idat_old            <= #1 idat_cur;
  end
end

reg [3:0] out_of_rst_cycles;
reg out_of_rst;

always @(posedge clk )
begin
  if (rst) begin
    out_of_rst         <= 0;
    out_of_rst_cycles   = 0;
  end
  else begin
    out_of_rst_cycles = out_of_rst_cycles < 4'd12 ? out_of_rst_cycles + 1 : out_of_rst_cycles;
    out_of_rst       <= out_of_rst_cycles == 4'd12;
  end 
end

always @(posedge clk )
begin
  if (rst) begin
    cdata <= #1 8'h00;
    cdone <= #1 1'b0;
  end else if (istb_t) begin
    cdata <= #1 ea_rom_sel ? idat_onchip[7:0] : idat_i[7:0];
    cdone <= #1 1'b1;
  end else begin
    cdone <= #1 1'b0;
  end
end

always @(op_pos or idat_cur or idat_old)
begin
  case (op_pos)  
    3'b000: begin
       op1 = idat_old[7:0]  ;
       op2 = idat_old[15:8] ;
       op3 = idat_old[23:16];
      end
    3'b001: begin
       op1 = idat_old[15:8] ;
       op2 = idat_old[23:16];
       op3 = idat_old[31:24];
      end
    3'b010: begin
       op1 = idat_old[23:16];
       op2 = idat_old[31:24];
       op3 = idat_cur[7:0]  ;
      end
    3'b011: begin
       op1 = idat_old[31:24];
       op2 = idat_cur[7:0]  ;
       op3 = idat_cur[15:8] ;
      end
    3'b100: begin
       op1 = idat_cur[7:0]  ;
       op2 = idat_cur[15:8] ;
       op3 = idat_cur[23:16];
      end
    default: begin
       op1 = idat_cur[15:8] ;
       op2 = idat_cur[23:16];
       op3 = idat_cur[31:24];
      end
  endcase
end




always @(dack_ir or ddat_ir or op1_o or iram_out or cdone or cdata)
  if (dack_ir)
    op1_out = ddat_ir;
  else if (cdone)
    op1_out = cdata;
  else
    op1_out = op1_o;

assign op3_out = (rd) ? op3_o : op3_buff;
assign op2_out = (rd) ? op2_o : op2_buff;

always @(idat_i or iack_i or idat_ir or rd)
begin
  if (iack_i) begin
    op1_xt = idat_i[7:0];
    op2_xt = idat_i[15:8];
    op3_xt = idat_i[23:16];
  end else if (!rd) begin
    op1_xt = idat_ir[7:0];
    op2_xt = idat_ir[15:8];
    op3_xt = idat_ir[23:16];
  end else begin
    op1_xt = 8'h00;
    op2_xt = 8'h00;
    op3_xt = 8'h00;
  end
end




always @(op1 or op2 or op3 or int_ack_t or int_vec_buff or iack_i or ea_rom_sel)
begin
  if (int_ack_t && (iack_i || ea_rom_sel)) begin
    op1_o = `OC8051_LCALL;
    op2_o = 8'h00;
    op3_o = int_vec_buff;
  end else begin
    op1_o = op1;
    op2_o = op2;
    op3_o = op3;
  end
end



always @(posedge clk )
  if (rst) reti <= #1 1'b0;
  else if ((op1_o==`OC8051_RETI) & rd & !mem_wait) reti <= #1 1'b1;
  else reti <= #1 1'b0;



always @(posedge clk )
begin
  if (rst) begin
    op2_buff <= #1 8'h0;
    op3_buff <= #1 8'h0;
  end else if (rd) begin
    op2_buff <= #1 op2_o;
    op3_buff <= #1 op3_o;
  end
end







always @(op1_out)
begin
        casex (op1_out) 
          `OC8051_ACALL :  op_length = 2'h2;
          `OC8051_AJMP :   op_length = 2'h2;


          `OC8051_CJNE_R : op_length = 2'h3;
          `OC8051_DJNZ_R : op_length = 2'h2;
          `OC8051_MOV_DR : op_length = 2'h2;
          `OC8051_MOV_CR : op_length = 2'h2;
          `OC8051_MOV_RD : op_length = 2'h2;


          `OC8051_CJNE_I : op_length = 2'h3;
          `OC8051_MOV_ID : op_length = 2'h2;
          `OC8051_MOV_DI : op_length = 2'h2;
          `OC8051_MOV_CI : op_length = 2'h2;


          `OC8051_ADD_D :  op_length = 2'h2;
          `OC8051_ADD_C :  op_length = 2'h2;
          `OC8051_ADDC_D : op_length = 2'h2;
          `OC8051_ADDC_C : op_length = 2'h2;
          `OC8051_ANL_D :  op_length = 2'h2;
          `OC8051_ANL_C :  op_length = 2'h2;
          `OC8051_ANL_DD : op_length = 2'h2;
          `OC8051_ANL_DC : op_length = 2'h3;
          `OC8051_ANL_B :  op_length = 2'h2;
          `OC8051_ANL_NB : op_length = 2'h2;
          `OC8051_CJNE_D : op_length = 2'h3;
          `OC8051_CJNE_C : op_length = 2'h3;
          `OC8051_CLR_B :  op_length = 2'h2;
          `OC8051_CPL_B :  op_length = 2'h2;
          `OC8051_DEC_D :  op_length = 2'h2;
          `OC8051_DJNZ_D : op_length = 2'h3;
          `OC8051_INC_D :  op_length = 2'h2;
          `OC8051_JB :     op_length = 2'h3;
          `OC8051_JBC :    op_length = 2'h3;
          `OC8051_JC :     op_length = 2'h2;
          `OC8051_JNB :    op_length = 2'h3;
          `OC8051_JNC :    op_length = 2'h2;
          `OC8051_JNZ :    op_length = 2'h2;
          `OC8051_JZ :     op_length = 2'h2;
          `OC8051_LCALL :  op_length = 2'h3;
          `OC8051_LJMP :   op_length = 2'h3;
          `OC8051_MOV_D :  op_length = 2'h2;
          `OC8051_MOV_C :  op_length = 2'h2;
          `OC8051_MOV_DA : op_length = 2'h2;
          `OC8051_MOV_DD : op_length = 2'h3;
          `OC8051_MOV_CD : op_length = 2'h3;
          `OC8051_MOV_BC : op_length = 2'h2;
          `OC8051_MOV_CB : op_length = 2'h2;
          `OC8051_MOV_DP : op_length = 2'h3;
          `OC8051_ORL_D :  op_length = 2'h2;
          `OC8051_ORL_C :  op_length = 2'h2;
          `OC8051_ORL_AD : op_length = 2'h2;
          `OC8051_ORL_CD : op_length = 2'h3;
          `OC8051_ORL_B :  op_length = 2'h2;
          `OC8051_ORL_NB : op_length = 2'h2;
          `OC8051_POP :    op_length = 2'h2;
          `OC8051_PUSH :   op_length = 2'h2;
          `OC8051_SETB_B : op_length = 2'h2;
          `OC8051_SJMP :   op_length = 2'h2;
          `OC8051_SUBB_D : op_length = 2'h2;
          `OC8051_SUBB_C : op_length = 2'h2;
          `OC8051_XCH_D :  op_length = 2'h2;
          `OC8051_XRL_D :  op_length = 2'h2;
          `OC8051_XRL_C :  op_length = 2'h2;
          `OC8051_XRL_AD : op_length = 2'h2;
          `OC8051_XRL_CD : op_length = 2'h3;
          default:         op_length = 2'h1;
        endcase
end



assign inc_pc = ((op_pos[2] | (&op_pos[1:0])) & rd) | pc_wr_r2;

always @(posedge clk)
begin
  if (rst) begin
    op_pos <= #1 3'h0;
  end else if (pc_wr_r2) begin
    op_pos <= #1 3'h4;
  end else if (inc_pc & rd) begin
    op_pos[2]   <= #1 op_pos[2] & !op_pos[1] & op_pos[0] & (&op_length);
    op_pos[1:0] <= #1 op_pos[1:0] + op_length;


  end else if (rd) begin
    op_pos <= #1 op_pos + {1'b0, op_length};
  end
end




always @(posedge clk )
 if (rst) begin
   int_ack_t <= #1 1'b0;
   int_vec_buff <= #1 8'h00;
 end else if (intr) begin
   int_ack_t <= #1 1'b1;
   int_vec_buff <= #1 int_v;
 end else if (rd && (ea_rom_sel || iack_i) && !pc_wr_r2) int_ack_t <= #1 1'b0;

always @(posedge clk )
  if (rst) int_ack_buff <= #1 1'b0;
  else int_ack_buff <= #1 int_ack_t;

always @(posedge clk )
  if (rst) int_ack <= #1 1'b0;
  else begin
    if ((int_ack_buff) & !(int_ack_t))
      int_ack <= #1 1'b1;
    else int_ack <= #1 1'b0;
  end




always @(posedge clk )
  if (rst) begin
    int_buff1 <= #1 1'b0;
  end else begin
    int_buff1 <= #1 int_buff;
  end

always @(posedge clk )
  if (rst) begin
    int_buff <= #1 1'b0;
  end else if (intr) begin
    int_buff <= #1 1'b1;
  end else if (pc_wait)
    int_buff <= #1 1'b0;

wire [7:0]  pcs_source;
reg  [15:0] pcs_result;
reg         pcs_cy;

assign pcs_source = pc_wr_sel[0] ? op3_out : op2_out;

always @(pcs_source or pc or pcs_cy)
begin
  if (pcs_source[7]) begin
    {pcs_cy, pcs_result[7:0]} = {1'b0, pc[7:0]} + {1'b0, pcs_source};
    pcs_result[15:8] = pc[15:8] - {7'h0, !pcs_cy};
  end else pcs_result = pc + {8'h00, pcs_source};
end




always @(posedge clk )
  if (rst) begin
    rn_r      <= #1 5'd0;
    ri_r      <= #1 8'h00;
    imm_r     <= #1 8'h00;
    imm2_r    <= #1 8'h00;
    rd_addr_r <= #1 1'b0;
    op1_r     <= #1 8'h0;
    dack_ir   <= #1 1'b0;
    sp_r      <= #1 1'b0;
    pc_wr_r   <= #1 1'b0;
    pc_wr_r2  <= #1 1'b0;
  end else begin
    rn_r      <= #1 rn;
    ri_r      <= #1 ri;
    imm_r     <= #1 imm;
    imm2_r    <= #1 imm2;
    rd_addr_r <= #1 rd_addr[7];
    op1_r     <= #1 op1_out;
    dack_ir   <= #1 dack_i;
    sp_r      <= #1 sp;
    pc_wr_r   <= #1 pc_wr && (pc_wr_sel != `OC8051_PIS_AH);
    pc_wr_r2  <= #1 pc_wr_r;
  end

always @(posedge clk )
  if (rst) begin
    inc_pc_r  <= #1 1'b1;
  end else if (istb) begin
    inc_pc_r  <= #1 inc_pc;
  end

reg [15:0] pc_log;
reg [15:0] pc_log_prev;
always @(posedge clk)
begin
    if (rst) begin
        pc_log      <= 0;
        pc_log_prev <= 0;
    end
    else begin
        if (decoder_new_valid_pc) begin
            pc_log  <= pc;
            pc_log_prev <= pc_log;
        end
    end
end

endmodule
module oc8051_memory_interface (clk, rst,


     wr_i,
     wr_bit_i,
     rd_sel,
     wr_sel,
     pc_wr_sel,
     pc_wr,
     pc,
     rd,
     mem_wait,
     mem_act,
     istb,


     wr_o, 
     wr_bit_o, 
     rd_addr, 
     wr_addr, 
     rd_ind, 
     wr_ind, 
     wr_dat,

     bit_in, 
     in_ram, 
     sfr, 
     sfr_bit, 
     bit_out, 
     iram_out,


     iadr_o, 
     ea, 
     ea_int,
     op1_out,  op1,
     op2_out,  op2,
     op3_out,  op3,
     out_of_rst,
     decoder_new_valid_pc,
     pc_log,
     pc_log_prev,


     idat_onchip,


     iack_i, 
     istb_o, 
     idat_i,


     dadr_o, 
     dwe_o, 
     dstb_o, 
     dack_i,
     ddat_i, 
     ddat_o,


     intr, 
     int_v, 
     int_ack,


     des_acc, 
     des1, 
     des2,


     dptr, 
     ri, 
     sp,  
     sp_w, 
     rn, 
     acc, 
     reti
   );



input         clk,
              rst,
              wr_i,
              wr_bit_i;

input         bit_in,
              sfr_bit,
              dack_i;
input [2:0]   mem_act;
input [7:0]   in_ram,
              sfr,
              acc,
              sp_w;
input [31:0]  idat_i;

output        bit_out,
              mem_wait,
              reti;
output [7:0]  iram_out,
              wr_dat;
output        out_of_rst;
input         decoder_new_valid_pc;
output [15:0] pc_log;
output [15:0] pc_log_prev;

reg           bit_out,
              reti;
reg [7:0]     iram_out,
              sp_r;
reg           rd_addr_r;
output        wr_o,
              wr_bit_o;


reg           dack_ir;
reg [7:0]     ddat_ir;
reg [23:0]    idat_ir;






input         iack_i;
input [7:0]   des_acc,
              des1,
              des2;
output [15:0] iadr_o;

wire          ea_rom_sel;






input [7:0]   ri,
              ddat_i;
input [15:0]  dptr;

output        dstb_o,
              dwe_o;
output [7:0]  ddat_o;
output [15:0] dadr_o;







input [2:0]   rd_sel,
              wr_sel;
input [4:0]   rn;
input [7:0]   sp;

output        rd_ind,
              wr_ind;
output [7:0]  wr_addr,
              rd_addr;
reg           rd_ind;
reg           wr_ind;
reg [7:0]     wr_addr;
reg [7:0]     rd_addr;

reg [4:0]     rn_r;
reg [7:0]     ri_r,imm_r,imm2_r,op1_r;
wire [7:0]    imm,
              imm2;







input         intr,rd,ea, ea_int, istb;

input  [7:0]  int_v;

input  [31:0] idat_onchip;

output        int_ack,
              istb_o;

output  [7:0] op1_out, op1,
              op3_out, op2,
              op2_out, op3;

reg           int_ack_t,int_ack,int_ack_buff;

reg [7:0]     int_vec_buff;
reg [7:0]     op1_out,op2_buff,op3_buff;
reg [7:0]     op1_o,op2_o,op3_o;

reg [7:0]     op1_xt, 
              op2_xt, 
              op3_xt;

reg [7:0]     op1,op2,op3;
wire [7:0]    op2_direct;

input [2:0]   pc_wr_sel;

input         pc_wr;
output [15:0] pc;

reg [15:0]    pc;



reg [15:0]    pc_buf;
wire [15:0]   alu;


reg           int_buff,
              int_buff1;







reg first_time_done;
wire first_time;
always @(posedge clk) begin
  if (rst) begin
    first_time_done <= 1;
  end else begin
    if ((dack_i == 0) && (dstb_o == 0) && ((mem_act == 0) || (mem_act == 2) || (mem_act == 1) || (mem_act == 3)))
      first_time_done <= 1; 
  end
end
assign first_time = (!first_time_done) && ((dack_i == 0) && (dstb_o == 0) && ((mem_act == 0) || (mem_act == 2) || (mem_act == 1) || (mem_act == 3)));




reg           istb_t,imem_wait,dstb_o,dwe_o;

reg [7:0]     ddat_o;
reg [15:0]    iadr_t,
              dadr_ot;
reg           dmem_wait;
wire          pc_wait;
wire [1:0]    bank;
wire [7:0]    isr_call;

reg [1:0]     op_length;
reg [2:0]     op_pos;
wire          inc_pc;

reg           pc_wr_r;

wire [15:0]   pc_out;

reg [31:0]    idat_cur,idat_old;

reg           inc_pc_r,
              pc_wr_r2;

reg [7:0]     cdata;
reg           cdone;


assign bank       = rn[4:3];
assign imm        = op2_out;
assign imm2       = op3_out;
assign alu        = {des2, des_acc};
assign ea_rom_sel = ea && ea_int;
assign wr_o       = wr_i;
assign wr_bit_o   = wr_bit_i;


assign mem_wait   = dmem_wait || imem_wait || pc_wr_r2;

assign istb_o     = (istb || (istb_t & !iack_i)) && !dstb_o && !ea_rom_sel;

assign pc_wait    = rd && (ea_rom_sel || (!istb_t && iack_i));

assign wr_dat     = des1;







always @(rd_addr_r or in_ram or sfr or bit_in or sfr_bit or rd_ind)
begin
  if (rd_addr_r && !rd_ind) begin
    iram_out = sfr;
    bit_out = sfr_bit;
  end else begin
    iram_out = in_ram;
    bit_out = bit_in;
  end
end







always @(rd_sel or sp or ri or rn or imm or dadr_o[15:0] or bank)
begin
  case (rd_sel) 
    `OC8051_RRS_RN   : rd_addr = {3'h0, rn};
    `OC8051_RRS_I    : rd_addr = ri;
    `OC8051_RRS_D    : rd_addr = imm;
    `OC8051_RRS_SP   : rd_addr = sp;

    `OC8051_RRS_B    : rd_addr = `OC8051_SFR_B;
    `OC8051_RRS_DPTR : rd_addr = `OC8051_SFR_DPTR_LO;
    `OC8051_RRS_PSW  : rd_addr = `OC8051_SFR_PSW;
    `OC8051_RRS_ACC  : rd_addr = `OC8051_SFR_ACC;

  endcase

end




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])
begin
  case (wr_sel) 
    `OC8051_RWS_RN : wr_addr = {3'h0, rn_r};
    `OC8051_RWS_I  : wr_addr = ri_r;
    `OC8051_RWS_D  : wr_addr = imm_r;
    `OC8051_RWS_SP : wr_addr = sp_w;
    `OC8051_RWS_D3 : wr_addr = imm2_r;
    `OC8051_RWS_B  : wr_addr = `OC8051_SFR_B;

    default        : wr_addr = 2'bxx;
  endcase
end

always @(posedge clk )
  if (rst)
    rd_ind <= #1 1'b0;
  else if ((rd_sel==`OC8051_RRS_I) || (rd_sel==`OC8051_RRS_SP))
    rd_ind <= #1 1'b1;
  else
    rd_ind <= #1 1'b0;

always @(wr_sel)
  if ((wr_sel==`OC8051_RWS_I) || (wr_sel==`OC8051_RWS_SP))
    wr_ind = 1'b1;
  else
    wr_ind = 1'b0;












assign iadr_o = (istb_t) ? iadr_t : pc_out;


always @(posedge clk )
begin
  if (rst) begin
    iadr_t <= #1 23'h0;
    istb_t <= #1 1'b0;
    imem_wait <= #1 1'b0;
    idat_ir <= #1 24'h0;
  end else if (mem_act==`OC8051_MAS_CODE) begin
    iadr_t <= #1 alu;
    istb_t <= #1 1'b1;
    imem_wait <= #1 1'b1;
  end else if (ea_rom_sel && imem_wait) begin
    imem_wait <= #1 1'b0;
  end else if (!imem_wait && istb_t) begin
    istb_t <= #1 1'b0;
  end else if (iack_i) begin
    imem_wait <= #1 1'b0;
    idat_ir <= #1 idat_i [23:0];
  end
end







assign dadr_o = dadr_ot;

always @(posedge clk )
begin
  if (rst) begin
    dwe_o <= #1 1'b0;
    dmem_wait <= #1 1'b0;
    dstb_o <= #1 1'b0;
    ddat_o <= #1 8'h00;
    dadr_ot <= #1 23'h0;
  end else if (dack_i) begin
    dwe_o <= #1 1'b0;
    dstb_o <= #1 1'b0;
    dmem_wait <= #1 1'b0;
  end else begin
    case (mem_act) 
      `OC8051_MAS_DPTR_R: begin
        dwe_o <= #1 1'b0;
        dstb_o <= #1 1'b1;
        ddat_o <= #1 8'h00;
        dadr_ot <= #1 {7'h0, dptr};
        dmem_wait <= #1 1'b1;
      end
      `OC8051_MAS_DPTR_W: begin
        dwe_o <= #1 1'b1;
        dstb_o <= #1 1'b1;
        ddat_o <= #1 acc;
        dadr_ot <= #1 {7'h0, dptr};
        dmem_wait <= #1 1'b1;
      end
      `OC8051_MAS_RI_R:   begin
        dwe_o <= #1 1'b0;
        dstb_o <= #1 1'b1;
        ddat_o <= #1 8'h00;
        dadr_ot <= #1 {15'h0, ri};
        dmem_wait <= #1 1'b1;
      end
      `OC8051_MAS_RI_W: begin
        dwe_o <= #1 1'b1;
        dstb_o <= #1 1'b1;
        ddat_o <= #1 acc;
        dadr_ot <= #1 {15'h0, ri};
        dmem_wait <= #1 1'b1;
      end
    endcase
  end
end









always @(posedge clk )
begin
  if (rst) begin
    idat_cur            <= #1 32'h0;
    idat_old            <= #1 32'h0;
  end else if ((iack_i | ea_rom_sel) & (inc_pc | pc_wr_r2)) begin
    idat_cur            <= #1 ea_rom_sel ? idat_onchip : idat_i;
    idat_old            <= #1 idat_cur;
  end
end

reg [3:0] out_of_rst_cycles;
reg out_of_rst;

always @(posedge clk )
begin
  if (rst) begin
    out_of_rst         <= 0;
    out_of_rst_cycles   = 0;
  end
  else begin
    out_of_rst_cycles = out_of_rst_cycles < 4'd12 ? out_of_rst_cycles + 1 : out_of_rst_cycles;
    out_of_rst       <= out_of_rst_cycles == 4'd12;
  end 
end

always @(posedge clk )
begin
  if (rst) begin
    cdata <= #1 8'h00;
    cdone <= #1 1'b0;
  end else if (istb_t) begin
    cdata <= #1 ea_rom_sel ? idat_onchip[7:0] : idat_i[7:0];
    cdone <= #1 1'b1;
  end else begin
    cdone <= #1 1'b0;
  end
end

always @(op_pos or idat_cur or idat_old)
begin
  case (op_pos)  
    3'b000: begin
       op1 = idat_old[7:0]  ;
       op2 = idat_old[15:8] ;
       op3 = idat_old[23:16];
      end
    3'b001: begin
       op1 = idat_old[15:8] ;
       op2 = idat_old[23:16];
       op3 = idat_old[31:24];
      end
    3'b010: begin
       op1 = idat_old[23:16];
       op2 = idat_old[31:24];
       op3 = idat_cur[7:0]  ;
      end
    3'b011: begin
       op1 = idat_old[31:24];
       op2 = idat_cur[7:0]  ;
       op3 = idat_cur[15:8] ;
      end
    3'b100: begin
       op1 = idat_cur[7:0]  ;
       op2 = idat_cur[15:8] ;
       op3 = idat_cur[23:16];
      end
    default: begin
       op1 = idat_cur[15:8] ;
       op2 = idat_cur[23:16];
       op3 = idat_cur[31:24];
      end
  endcase
end




always @(dack_ir or ddat_ir or op1_o or iram_out or cdone or cdata)
  if (dack_ir)
    op1_out = ddat_ir;
  else if (cdone)
    op1_out = cdata;
  else
    op1_out = op1_o;

assign op3_out = (rd) ? op3_o : op3_buff;
assign op2_out = (rd) ? op2_o : op2_buff;

always @(idat_i or iack_i or idat_ir or rd)
begin
  if (iack_i) begin
    op1_xt = idat_i[7:0];
    op2_xt = idat_i[15:8];
    op3_xt = idat_i[23:16];
  end else if (!rd) begin
    op1_xt = idat_ir[7:0];
    op2_xt = idat_ir[15:8];
    op3_xt = idat_ir[23:16];
  end else begin
    op1_xt = 8'h00;
    op2_xt = 8'h00;
    op3_xt = 8'h00;
  end
end




always @(op1 or op2 or op3 or int_ack_t or int_vec_buff or iack_i or ea_rom_sel)
begin
  if (int_ack_t && (iack_i || ea_rom_sel)) begin
    op1_o = `OC8051_LCALL;
    op2_o = 8'h00;
    op3_o = int_vec_buff;
  end else begin
    op1_o = op1;
    op2_o = op2;
    op3_o = op3;
  end
end



always @(posedge clk )
  if (rst) reti <= #1 1'b0;
  else if ((op1_o==`OC8051_RETI) & rd & !mem_wait) reti <= #1 1'b1;
  else reti <= #1 1'b0;



always @(posedge clk )
begin
  if (rst) begin
    op2_buff <= #1 8'h0;
    op3_buff <= #1 8'h0;
  end else if (rd) begin
    op2_buff <= #1 op2_o;
    op3_buff <= #1 op3_o;
  end
end







always @(op1_out)
begin
        casex (op1_out) 
          `OC8051_ACALL :  op_length = 2'h2;
          `OC8051_AJMP :   op_length = 2'h2;


          `OC8051_CJNE_R : op_length = 2'h3;
          `OC8051_DJNZ_R : op_length = 2'h2;
          `OC8051_MOV_DR : op_length = 2'h2;
          `OC8051_MOV_CR : op_length = 2'h2;
          `OC8051_MOV_RD : op_length = 2'h2;


          `OC8051_CJNE_I : op_length = 2'h3;
          `OC8051_MOV_ID : op_length = 2'h2;
          `OC8051_MOV_DI : op_length = 2'h2;
          `OC8051_MOV_CI : op_length = 2'h2;


          `OC8051_ADD_D :  op_length = 2'h2;
          `OC8051_ADD_C :  op_length = 2'h2;
          `OC8051_ADDC_D : op_length = 2'h2;
          `OC8051_ADDC_C : op_length = 2'h2;
          `OC8051_ANL_D :  op_length = 2'h2;
          `OC8051_ANL_C :  op_length = 2'h2;
          `OC8051_ANL_DD : op_length = 2'h2;
          `OC8051_ANL_DC : op_length = 2'h3;
          `OC8051_ANL_B :  op_length = 2'h2;
          `OC8051_ANL_NB : op_length = 2'h2;
          `OC8051_CJNE_D : op_length = 2'h3;
          `OC8051_CJNE_C : op_length = 2'h3;
          `OC8051_CLR_B :  op_length = 2'h2;
          `OC8051_CPL_B :  op_length = 2'h2;
          `OC8051_DEC_D :  op_length = 2'h2;
          `OC8051_DJNZ_D : op_length = 2'h3;
          `OC8051_INC_D :  op_length = 2'h2;
          `OC8051_JB :     op_length = 2'h3;
          `OC8051_JBC :    op_length = 2'h3;
          `OC8051_JC :     op_length = 2'h2;
          `OC8051_JNB :    op_length = 2'h3;
          `OC8051_JNC :    op_length = 2'h2;
          `OC8051_JNZ :    op_length = 2'h2;
          `OC8051_JZ :     op_length = 2'h2;
          `OC8051_LCALL :  op_length = 2'h3;
          `OC8051_LJMP :   op_length = 2'h3;
          `OC8051_MOV_D :  op_length = 2'h2;
          `OC8051_MOV_C :  op_length = 2'h2;
          `OC8051_MOV_DA : op_length = 2'h2;
          `OC8051_MOV_DD : op_length = 2'h3;
          `OC8051_MOV_CD : op_length = 2'h3;
          `OC8051_MOV_BC : op_length = 2'h2;
          `OC8051_MOV_CB : op_length = 2'h2;
          `OC8051_MOV_DP : op_length = 2'h3;
          `OC8051_ORL_D :  op_length = 2'h2;
          `OC8051_ORL_C :  op_length = 2'h2;
          `OC8051_ORL_AD : op_length = 2'h2;
          `OC8051_ORL_CD : op_length = 2'h3;
          `OC8051_ORL_B :  op_length = 2'h2;
          `OC8051_ORL_NB : op_length = 2'h2;
          `OC8051_POP :    op_length = 2'h2;
          `OC8051_PUSH :   op_length = 2'h2;
          `OC8051_SETB_B : op_length = 2'h2;
          `OC8051_SJMP :   op_length = 2'h2;
          `OC8051_SUBB_D : op_length = 2'h2;
          `OC8051_SUBB_C : op_length = 2'h2;
          `OC8051_XCH_D :  op_length = 2'h2;
          `OC8051_XRL_D :  op_length = 2'h2;
          `OC8051_XRL_C :  op_length = 2'h2;
          `OC8051_XRL_AD : op_length = 2'h2;
          `OC8051_XRL_CD : op_length = 2'h3;
          default:         op_length = 2'h1;
        endcase
end



assign inc_pc = ((op_pos[2] | (&op_pos[1:0])) & rd) | pc_wr_r2;

always @(posedge clk)
begin
  if (rst) begin
    op_pos <= #1 3'h0;
  end else if (pc_wr_r2) begin
    op_pos <= #1 3'h4;
  end else if (inc_pc & rd) begin
    op_pos[2]   <= #1 op_pos[2] & !op_pos[1] & op_pos[0] & (&op_length);
    op_pos[1:0] <= #1 op_pos[1:0] + op_length;


  end else if (rd) begin
    op_pos <= #1 op_pos + {1'b0, op_length};
  end
end




always @(posedge clk )
 if (rst) begin
   int_ack_t <= #1 1'b0;
   int_vec_buff <= #1 8'h00;
 end else if (intr) begin
   int_ack_t <= #1 1'b1;
   int_vec_buff <= #1 int_v;
 end else if (rd && (ea_rom_sel || iack_i) && !pc_wr_r2) int_ack_t <= #1 1'b0;

always @(posedge clk )
  if (rst) int_ack_buff <= #1 1'b0;
  else int_ack_buff <= #1 int_ack_t;

always @(posedge clk )
  if (rst) int_ack <= #1 1'b0;
  else begin
    if ((int_ack_buff) & !(int_ack_t))
      int_ack <= #1 1'b1;
    else int_ack <= #1 1'b0;
  end




always @(posedge clk )
  if (rst) begin
    int_buff1 <= #1 1'b0;
  end else begin
    int_buff1 <= #1 int_buff;
  end

always @(posedge clk )
  if (rst) begin
    int_buff <= #1 1'b0;
  end else if (intr) begin
    int_buff <= #1 1'b1;
  end else if (pc_wait)
    int_buff <= #1 1'b0;

wire [7:0]  pcs_source;
reg  [15:0] pcs_result;
reg         pcs_cy;

assign pcs_source = pc_wr_sel[0] ? op3_out : op2_out;

always @(pcs_source or pc or pcs_cy)
begin
  if (pcs_source[7]) begin
    {pcs_cy, pcs_result[7:0]} = {1'b0, pc[7:0]} + {1'b0, pcs_source};
    pcs_result[15:8] = pc[15:8] - {7'h0, !pcs_cy};
  end else pcs_result = pc + {8'h00, pcs_source};
end




always @(posedge clk )
  if (rst) begin
    rn_r      <= #1 5'd0;
    ri_r      <= #1 8'h00;
    imm_r     <= #1 8'h00;
    imm2_r    <= #1 8'h00;
    rd_addr_r <= #1 1'b0;
    op1_r     <= #1 8'h0;
    dack_ir   <= #1 1'b0;
    sp_r      <= #1 1'b0;
    pc_wr_r   <= #1 1'b0;
    pc_wr_r2  <= #1 1'b0;
  end else begin
    rn_r      <= #1 rn;
    ri_r      <= #1 ri;
    imm_r     <= #1 imm;
    imm2_r    <= #1 imm2;
    rd_addr_r <= #1 rd_addr[7];
    op1_r     <= #1 op1_out;
    dack_ir   <= #1 dack_i;
    sp_r      <= #1 sp;
    pc_wr_r   <= #1 pc_wr && (pc_wr_sel != `OC8051_PIS_AH);
    pc_wr_r2  <= #1 pc_wr_r;
  end

always @(posedge clk )
  if (rst) begin
    inc_pc_r  <= #1 1'b1;
  end else if (istb) begin
    inc_pc_r  <= #1 inc_pc;
  end

reg [15:0] pc_log;
reg [15:0] pc_log_prev;
always @(posedge clk)
begin
    if (rst) begin
        pc_log      <= 0;
        pc_log_prev <= 0;
    end
    else begin
        if (decoder_new_valid_pc) begin
            pc_log  <= pc;
            pc_log_prev <= pc_log;
        end
    end
end

endmodule