data/full_repos/permissive/16708890/zybo-test1/zybo-test1.srcs/sources_1/bd/design_1/ip/design_1_processing_system7_0_1/hdl/processing_system7_bfm_v2_0_afi_slave.v
 line:215: before: "integer"
1: b'%Error: data/full_repos/permissive/16708890/zybo-test1/zybo-test1.srcs/sources_1/bd/design_1/ip/design_1_processing_system7_0_1/hdl/processing_system7_bfm_v2_0_afi_slave.v:91: Cannot find include file: processing_system7_bfm_v2_0_local_params.v\n  `include "processing_system7_bfm_v2_0_local_params.v" \n           ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/16708890/zybo-test1/zybo-test1.srcs/sources_1/bd/design_1/ip/design_1_processing_system7_0_1/hdl,data/full_repos/permissive/16708890/processing_system7_bfm_v2_0_local_params.v\n             data/full_repos/permissive/16708890/zybo-test1/zybo-test1.srcs/sources_1/bd/design_1/ip/design_1_processing_system7_0_1/hdl,data/full_repos/permissive/16708890/processing_system7_bfm_v2_0_local_params.v.v\n             data/full_repos/permissive/16708890/zybo-test1/zybo-test1.srcs/sources_1/bd/design_1/ip/design_1_processing_system7_0_1/hdl,data/full_repos/permissive/16708890/processing_system7_bfm_v2_0_local_params.v.sv\n             processing_system7_bfm_v2_0_local_params.v\n             processing_system7_bfm_v2_0_local_params.v.v\n             processing_system7_bfm_v2_0_local_params.v.sv\n             obj_dir/processing_system7_bfm_v2_0_local_params.v\n             obj_dir/processing_system7_bfm_v2_0_local_params.v.v\n             obj_dir/processing_system7_bfm_v2_0_local_params.v.sv\n%Error: data/full_repos/permissive/16708890/zybo-test1/zybo-test1.srcs/sources_1/bd/design_1/ip/design_1_processing_system7_0_1/hdl/processing_system7_bfm_v2_0_afi_slave.v:317: syntax error, unexpected \'@\'\n    @(posedge S_ACLK);\n    ^\n%Error: data/full_repos/permissive/16708890/zybo-test1/zybo-test1.srcs/sources_1/bd/design_1/ip/design_1_processing_system7_0_1/hdl/processing_system7_bfm_v2_0_afi_slave.v:319: syntax error, unexpected \'@\'\n    @(posedge S_ACLK);\n    ^\n%Error: data/full_repos/permissive/16708890/zybo-test1/zybo-test1.srcs/sources_1/bd/design_1/ip/design_1_processing_system7_0_1/hdl/processing_system7_bfm_v2_0_afi_slave.v:327: syntax error, unexpected \'@\'\n     repeat(2) @(posedge S_ACLK);\n               ^\n%Error: Exiting due to 4 error(s)\n'
module processing_system7_bfm_v2_0_afi_slave (
  S_RESETN,

  S_ARREADY,
  S_AWREADY,
  S_BVALID,
  S_RLAST,
  S_RVALID,
  S_WREADY,
  S_BRESP,
  S_RRESP,
  S_RDATA,
  S_BID,
  S_RID,
  S_ACLK,
  S_ARVALID,
  S_AWVALID,
  S_BREADY,
  S_RREADY,
  S_WLAST,
  S_WVALID,
  S_ARBURST,
  S_ARLOCK,
  S_ARSIZE,
  S_AWBURST,
  S_AWLOCK,
  S_AWSIZE,
  S_ARPROT,
  S_AWPROT,
  S_ARADDR,
  S_AWADDR,
  S_WDATA,
  S_ARCACHE,
  S_ARLEN,
  S_AWCACHE,
  S_AWLEN,
  S_WSTRB,
  S_ARID,
  S_AWID,
  S_WID,
  
  S_AWQOS,
  S_ARQOS,

  SW_CLK,
  WR_DATA_ACK_OCM,
  WR_DATA_ACK_DDR,
  WR_ADDR,
  WR_DATA,
  WR_BYTES,
  WR_DATA_VALID_OCM,
  WR_DATA_VALID_DDR,
  WR_QOS,
  
  RD_REQ_DDR,
  RD_REQ_OCM,
  RD_ADDR,
  RD_DATA_OCM,
  RD_DATA_DDR,
  RD_BYTES,
  RD_QOS,
  RD_DATA_VALID_OCM,
  RD_DATA_VALID_DDR,
  S_RDISSUECAP1_EN,
  S_WRISSUECAP1_EN,
  S_RCOUNT,
  S_WCOUNT,
  S_RACOUNT,
  S_WACOUNT

);
  parameter enable_this_port = 0;  
  parameter slave_name = "Slave";
  parameter data_bus_width = 32;
  parameter address_bus_width = 32;
  parameter id_bus_width = 6;
  parameter slave_base_address = 0;
  parameter slave_high_address = 4;
  parameter max_outstanding_transactions = 8;
  parameter exclusive_access_supported = 0;

  `include "processing_system7_bfm_v2_0_local_params.v"



  parameter int_cntr_width = clogb2(max_outstanding_transactions)+1;


  parameter rsp_fifo_bits = axi_rsp_width+id_bus_width; 
  parameter rsp_lsb = 0;
  parameter rsp_msb = axi_rsp_width-1;
  parameter rsp_id_lsb = rsp_msb + 1;  
  parameter rsp_id_msb = rsp_id_lsb + id_bus_width-1;  

  input  S_RESETN;

  output  S_ARREADY;
  output  S_AWREADY;
  output  S_BVALID;
  output  S_RLAST;
  output  S_RVALID;
  output  S_WREADY;
  output  [axi_rsp_width-1:0] S_BRESP;
  output  [axi_rsp_width-1:0] S_RRESP;
  output  [data_bus_width-1:0] S_RDATA;
  output  [id_bus_width-1:0] S_BID;
  output  [id_bus_width-1:0] S_RID;
  input S_ACLK;
  input S_ARVALID;
  input S_AWVALID;
  input S_BREADY;
  input S_RREADY;
  input S_WLAST;
  input S_WVALID;
  input [axi_brst_type_width-1:0] S_ARBURST;
  input [axi_lock_width-1:0] S_ARLOCK;
  input [axi_size_width-1:0] S_ARSIZE;
  input [axi_brst_type_width-1:0] S_AWBURST;
  input [axi_lock_width-1:0] S_AWLOCK;
  input [axi_size_width-1:0] S_AWSIZE;
  input [axi_prot_width-1:0] S_ARPROT;
  input [axi_prot_width-1:0] S_AWPROT;
  input [address_bus_width-1:0] S_ARADDR;
  input [address_bus_width-1:0] S_AWADDR;
  input [data_bus_width-1:0] S_WDATA;
  input [axi_cache_width-1:0] S_ARCACHE;
  input [axi_cache_width-1:0] S_ARLEN;
  
  input [axi_qos_width-1:0] S_ARQOS;
 
  input [axi_cache_width-1:0] S_AWCACHE;
  input [axi_len_width-1:0] S_AWLEN;

  input [axi_qos_width-1:0] S_AWQOS;
  input [(data_bus_width/8)-1:0] S_WSTRB;
  input [id_bus_width-1:0] S_ARID;
  input [id_bus_width-1:0] S_AWID;
  input [id_bus_width-1:0] S_WID;

  input SW_CLK;
  input WR_DATA_ACK_DDR, WR_DATA_ACK_OCM;
  output WR_DATA_VALID_DDR, WR_DATA_VALID_OCM;
  output [max_burst_bits-1:0] WR_DATA;
  output [addr_width-1:0] WR_ADDR;
  output [max_transfer_bytes_width:0] WR_BYTES;
  output reg RD_REQ_OCM, RD_REQ_DDR;
  output reg [addr_width-1:0] RD_ADDR;
  input [max_burst_bits-1:0] RD_DATA_DDR,RD_DATA_OCM;
  output reg[max_transfer_bytes_width:0] RD_BYTES;
  input RD_DATA_VALID_OCM,RD_DATA_VALID_DDR;
  output [axi_qos_width-1:0] WR_QOS;
  output reg [axi_qos_width-1:0] RD_QOS;
 
  input S_RDISSUECAP1_EN;
  input S_WRISSUECAP1_EN;

  output [7:0] S_RCOUNT;
  output [7:0] S_WCOUNT;
  output [2:0] S_RACOUNT;
  output [5:0] S_WACOUNT;

  wire net_ARVALID;
  wire net_AWVALID;
  wire net_WVALID;

  real s_aclk_period;

  cdn_axi3_slave_bfm #(slave_name,
                       data_bus_width,
                       address_bus_width,
                       id_bus_width, 
                       slave_base_address,
                       (slave_high_address- slave_base_address),
                       max_outstanding_transactions,
                       0,
                       exclusive_access_supported)
  slave   (.ACLK    (S_ACLK),
           .ARESETn (S_RESETN),

           .AWID    (S_AWID),
           .AWADDR  (S_AWADDR),
           .AWLEN   (S_AWLEN),
           .AWSIZE  (S_AWSIZE),
           .AWBURST (S_AWBURST),
           .AWLOCK  (S_AWLOCK),
           .AWCACHE (S_AWCACHE),
           .AWPROT  (S_AWPROT),
           .AWVALID (net_AWVALID),
           .AWREADY (S_AWREADY),

           .WID    (S_WID),
           .WDATA  (S_WDATA),
           .WSTRB  (S_WSTRB), 
           .WLAST  (S_WLAST), 
           .WVALID (net_WVALID),
           .WREADY (S_WREADY),

           .BID    (S_BID),
           .BRESP  (S_BRESP),
           .BVALID (S_BVALID),
           .BREADY (S_BREADY),

           .ARID    (S_ARID),
           .ARADDR  (S_ARADDR),
           .ARLEN   (S_ARLEN),
           .ARSIZE  (S_ARSIZE),
           .ARBURST (S_ARBURST),
           .ARLOCK  (S_ARLOCK),
           .ARCACHE (S_ARCACHE),
           .ARPROT  (S_ARPROT),
           .ARVALID (net_ARVALID),
           .ARREADY (S_ARREADY),

           .RID    (S_RID),
           .RDATA  (S_RDATA),
           .RRESP  (S_RRESP),
           .RLAST  (S_RLAST),
           .RVALID (S_RVALID),
           .RREADY (S_RREADY));


  wire wr_intr_fifo_full;
  reg temp_wr_intr_fifo_full; 


  processing_system7_bfm_v2_0_intr_wr_mem wr_intr_fifo(SW_CLK, S_RESETN, wr_intr_fifo_full, WR_DATA_ACK_OCM, WR_DATA_ACK_DDR, WR_ADDR, WR_DATA, WR_BYTES, WR_QOS, WR_DATA_VALID_OCM, WR_DATA_VALID_DDR);


  always@(posedge S_ACLK) temp_wr_intr_fifo_full = wr_intr_fifo_full;


  reg[1:0] latency_type = RANDOM_CASE;
  reg DEBUG_INFO = 1; 
  reg STOP_ON_ERROR = 1'b1; 


  reg [wr_afi_fifo_data_bits-1:0] wr_fifo [0:max_outstanding_transactions-1];
  reg [int_cntr_width-1:0] wr_fifo_wr_ptr = 0, wr_fifo_rd_ptr = 0;
  wire wr_fifo_empty;


  reg [7:0] aw_time_cnt = 0,bresp_time_cnt = 0;
  real awvalid_receive_time[0:max_outstanding_transactions];
  reg  awvalid_flag[0:max_outstanding_transactions];


  reg[int_cntr_width-1:0] aw_cnt = 0;


  reg [axi_size_width-1:0]  awsize [0:max_outstanding_transactions-1];
  reg [axi_prot_width-1:0]  awprot [0:max_outstanding_transactions-1];
  reg [axi_lock_width-1:0]  awlock [0:max_outstanding_transactions-1];
  reg [axi_cache_width-1:0]  awcache [0:max_outstanding_transactions-1];
  reg [axi_brst_type_width-1:0]  awbrst [0:max_outstanding_transactions-1];
  reg [axi_len_width-1:0]  awlen [0:max_outstanding_transactions-1];
  reg aw_flag [0:max_outstanding_transactions-1];
  reg [addr_width-1:0] awaddr [0:max_outstanding_transactions-1];
  reg [id_bus_width-1:0] awid [0:max_outstanding_transactions-1];
  reg [axi_qos_width-1:0]  awqos [0:max_outstanding_transactions-1];
  wire aw_fifo_full;


  reg [(data_bus_width*axi_burst_len)-1:0] burst_data [0:max_outstanding_transactions-1];
  reg [max_burst_bytes_width:0] burst_valid_bytes [0:max_outstanding_transactions-1];
  reg wlast_flag [0:max_outstanding_transactions-1];
  wire wd_fifo_full;


  reg [int_cntr_width-1:0] wd_cnt = 0;
  reg [(data_bus_width*axi_burst_len)-1:0] aligned_wr_data;
  reg [addr_width-1:0] aligned_wr_addr;
  reg [max_burst_bytes_width:0] valid_data_bytes;
  reg [int_cntr_width-1:0] wr_bresp_cnt = 0;
  reg [axi_rsp_width-1:0] bresp;
  reg [rsp_fifo_bits-1:0] fifo_bresp [0:max_outstanding_transactions-1];
  reg enable_write_bresp;
  reg [int_cntr_width-1:0] rd_bresp_cnt = 0;
  integer wr_latency_count;
  reg  wr_delayed;
  wire bresp_fifo_empty;


  reg[7:0] wcount;
  reg[5:0] wacount;


  reg [axi_qos_width-1:0] ar_qos, aw_qos;

  initial begin
   if(DEBUG_INFO) begin
    if(enable_this_port)
     $display("[%0d] : %0s : %0s : Port is ENABLED.",$time, DISP_INFO, slave_name);
    else
     $display("[%0d] : %0s : %0s : Port is DISABLED.",$time, DISP_INFO, slave_name);
   end
  end



          
  always@(S_RESETN)
  begin
   if(S_RESETN) begin
    @(posedge S_ACLK);
    s_aclk_period = $time;
    @(posedge S_ACLK);
    s_aclk_period = $time - s_aclk_period;
   end
  end


  initial slave.set_disable_reset_value_checks(1); 
  initial begin
     repeat(2) @(posedge S_ACLK);
     if(!enable_this_port) begin
        slave.set_channel_level_info(0);
        slave.set_function_level_info(0);
     end 
     slave.RESPONSE_TIMEOUT = 0;
  end



  task set_latency_type;
    input[1:0] lat;
  begin
   if(enable_this_port) 
    latency_type = lat;
   else begin

     $display("[%0d] : %0s : %0s : Port is disabled. 'Latency Profile' will not be set...",$time, DISP_WARN, slave_name);
   end
  end
  endtask


  task set_arqos;
    input[axi_qos_width-1:0] qos;
  begin
   if(enable_this_port) 
    ar_qos = qos;
   else begin
    if(DEBUG_INFO)
     $display("[%0d] : %0s : %0s : Port is disabled. 'ARQOS' will not be set...",$time, DISP_WARN, slave_name);
   end
  end
  endtask



  task set_awqos;
    input[axi_qos_width-1:0] qos;
  begin
   if(enable_this_port) 
    aw_qos = qos;
   else begin
    if(DEBUG_INFO)
     $display("[%0d] : %0s : %0s : Port is disabled. 'AWQOS' will not be set...",$time, DISP_WARN, slave_name);
   end
  end
  endtask



  function [31:0] get_wr_lat_number;
  input dummy;
  reg[1:0] temp;
  begin 
   case(latency_type)
    BEST_CASE   : get_wr_lat_number = afi_wr_min;            
    AVG_CASE    : get_wr_lat_number = afi_wr_avg;            
    WORST_CASE  : get_wr_lat_number = afi_wr_max;            
    default     : begin
                   temp = $random;
                   case(temp) 
                    2'b00   : get_wr_lat_number = ($random()%10+ afi_wr_min); 
                    2'b01   : get_wr_lat_number = ($random()%40+ afi_wr_avg); 
                    default : get_wr_lat_number = ($random()%60+ afi_wr_max); 
                   endcase        
                  end
   endcase
  end
  endfunction



  function [31:0] get_rd_lat_number;
  input dummy;
  reg[1:0] temp;
  begin 
   case(latency_type)
    BEST_CASE   : get_rd_lat_number = afi_rd_min;            
    AVG_CASE    : get_rd_lat_number = afi_rd_avg;            
    WORST_CASE  : get_rd_lat_number = afi_rd_max;            
    default     : begin
                   temp = $random;
                   case(temp) 
                    2'b00   : get_rd_lat_number = ($random()%10+ afi_rd_min); 
                    2'b01   : get_rd_lat_number = ($random()%40+ afi_rd_avg); 
                    default : get_rd_lat_number = ($random()%60+ afi_rd_max); 
                   endcase        
                  end
   endcase
  end
  endfunction


 always@(S_AWVALID or S_WVALID or S_ARVALID)
 begin
  if((S_AWVALID | S_WVALID | S_ARVALID) && !enable_this_port) begin
    $display("[%0d] : %0s : %0s : Port is disabled. AXI transaction is initiated on this port ...\nSimulation will halt ..",$time, DISP_ERR, slave_name);
    $stop;
  end
 end



  assign net_ARVALID = enable_this_port ? S_ARVALID : 1'b0;
  assign net_AWVALID = enable_this_port ? S_AWVALID : 1'b0;
  assign net_WVALID  = enable_this_port ? S_WVALID : 1'b0;

  assign wr_fifo_empty = (wr_fifo_wr_ptr === wr_fifo_rd_ptr)?1'b1: 1'b0;
  assign bresp_fifo_empty = (wr_bresp_cnt === rd_bresp_cnt)?1'b1:1'b0;
  assign bresp_fifo_full  = ((wr_bresp_cnt[int_cntr_width-1] !== rd_bresp_cnt[int_cntr_width-1]) && (wr_bresp_cnt[int_cntr_width-2:0] === rd_bresp_cnt[int_cntr_width-2:0]))?1'b1:1'b0;

  assign S_WCOUNT = wcount;
  assign S_WACOUNT = wacount;


 function automatic wrfifo_full ;
 input [axi_len_width-1:0] fifo_space_exp;
 integer fifo_space_left; 
 begin
   fifo_space_left = afi_fifo_locations - wcount;
   if(fifo_space_left < fifo_space_exp) 
     wrfifo_full = 1;
   else
     wrfifo_full = 0;
 end
 endfunction



 always@(negedge S_RESETN or S_AWID or S_AWADDR or S_AWVALID )
 begin
 if(!S_RESETN)
  aw_time_cnt <= 0;
 else begin
  if(S_AWVALID) begin
    awvalid_receive_time[aw_time_cnt] <= $time;
    awvalid_flag[aw_time_cnt] <= 1'b1;
    aw_time_cnt <= aw_time_cnt + 1;
  end
 end
 end

  always@(posedge S_ACLK)
  begin
  if(net_AWVALID && S_AWREADY) begin
    if(S_AWQOS === 0) awqos[aw_cnt[int_cntr_width-2:0]] = aw_qos; 
    else awqos[aw_cnt[int_cntr_width-2:0]] = S_AWQOS; 
  end
  end


 always@(negedge S_RESETN or posedge S_ACLK)
 begin
 if(!S_RESETN) begin
   aw_cnt <= 0;
   wacount <= 0;
 end else begin
   if(S_AWVALID && !wrfifo_full(S_AWLEN+1)) begin 
       slave.RECEIVE_WRITE_ADDRESS(0,
                                   id_invalid,
                                   awaddr[aw_cnt[int_cntr_width-2:0]],
                                   awlen[aw_cnt[int_cntr_width-2:0]],
                                   awsize[aw_cnt[int_cntr_width-2:0]],
                                   awbrst[aw_cnt[int_cntr_width-2:0]],
                                   awlock[aw_cnt[int_cntr_width-2:0]],
                                   awcache[aw_cnt[int_cntr_width-2:0]],
                                   awprot[aw_cnt[int_cntr_width-2:0]],
                                   awid[aw_cnt[int_cntr_width-2:0]]);
       aw_flag[aw_cnt[int_cntr_width-2:0]] <= 1'b1;
       aw_cnt                              <= aw_cnt + 1;
       wacount                             <= wacount + 1;
   end
 end
 end

 

 always@(negedge S_RESETN or posedge S_ACLK)
 begin
 if(!S_RESETN) begin
  wd_cnt <= 0;
 end else begin
  if(aw_flag[wd_cnt[int_cntr_width-2:0]]) begin
    if(S_WVALID && !wrfifo_full(awlen[wd_cnt[int_cntr_width-2:0]] + 1)) begin
     slave.RECEIVE_WRITE_BURST_NO_CHECKS(S_WID, burst_data[wd_cnt[int_cntr_width-2:0]], burst_valid_bytes[wd_cnt[int_cntr_width-2:0]]); 
     wlast_flag[wd_cnt[int_cntr_width-2:0]] <= 1'b1;
     wd_cnt   <= wd_cnt + 1;
    end  
  end else begin
    if(!wrfifo_full(axi_burst_len) && S_WVALID) begin
      slave.RECEIVE_WRITE_BURST_NO_CHECKS(S_WID, burst_data[wd_cnt[int_cntr_width-2:0]], burst_valid_bytes[wd_cnt[int_cntr_width-2:0]]); 
      wlast_flag[wd_cnt[int_cntr_width-2:0]] <= 1'b1;
      wd_cnt   <= wd_cnt + 1;
    end
  end
 end
 end

 

 task automatic get_wrap_aligned_wr_data;
 output [(data_bus_width*axi_burst_len)-1:0] aligned_data;
 output [addr_width-1:0] start_addr;
 input  [addr_width-1:0] addr;
 input  [(data_bus_width*axi_burst_len)-1:0] b_data;
 input  [max_burst_bytes_width:0] v_bytes;
 reg    [(data_bus_width*axi_burst_len)-1:0] temp_data, wrp_data;
 integer wrp_bytes;
 integer i;
 begin
   start_addr = (addr/v_bytes) * v_bytes;
   wrp_bytes = addr - start_addr;
   wrp_data = b_data;
   temp_data = 0;
   wrp_data = wrp_data << ((data_bus_width*axi_burst_len) - (v_bytes*8));
   while(wrp_bytes > 0) begin
     temp_data = temp_data << 8;
     temp_data[7:0] = wrp_data[(data_bus_width*axi_burst_len)-1 : (data_bus_width*axi_burst_len)-8];
     wrp_data = wrp_data << 8;
     wrp_bytes = wrp_bytes - 1;
   end
   wrp_bytes = addr - start_addr;
   wrp_data = b_data << (wrp_bytes*8);
   
   aligned_data = (temp_data | wrp_data);
 end
 endtask

  

 function [axi_rsp_width-1:0] calculate_resp;
 input [addr_width-1:0] awaddr; 
 input [axi_prot_width-1:0] awprot;
 reg [axi_rsp_width-1:0] rsp;
 begin
   rsp = AXI_OK;

   if(decode_address(awaddr) === INVALID_MEM_TYPE) begin
    rsp = AXI_SLV_ERR;
    $display("[%0d] : %0s : %0s : AXI Access to Invalid location(0x%0h) ",$time, DISP_ERR, slave_name, awaddr);
   end
   else if(decode_address(awaddr) === REG_MEM) begin
    rsp = AXI_SLV_ERR;
    $display("[%0d] : %0s : %0s : AXI Access to Register Map(0x%0h) is not allowed through this port.",$time, DISP_ERR, slave_name, awaddr);
   end
   if(secure_access_enabled && awprot[1])
    rsp = AXI_DEC_ERR;
   calculate_resp = rsp;
 end
 endfunction

 reg[max_burst_bits-1:0] temp_wr_data;

 always@(negedge S_RESETN or posedge S_ACLK)
 begin
 if(!S_RESETN) begin
  wr_fifo_wr_ptr <= 0;
  wcount <= 0;
 end else begin
  enable_write_bresp = aw_flag[wr_fifo_wr_ptr[int_cntr_width-2:0]] && wlast_flag[wr_fifo_wr_ptr[int_cntr_width-2:0]];

  if(enable_write_bresp) begin
    aw_flag[wr_fifo_wr_ptr[int_cntr_width-2:0]]    <= 0;
    wlast_flag[wr_fifo_wr_ptr[int_cntr_width-2:0]] <= 0;
 
    bresp = calculate_resp(awaddr[wr_fifo_wr_ptr[int_cntr_width-2:0]], awprot[wr_fifo_wr_ptr[int_cntr_width-2:0]]);

    if(bresp === AXI_OK ) begin
      if(awbrst[wr_fifo_wr_ptr[int_cntr_width-2:0]]=== AXI_WRAP) begin
        get_wrap_aligned_wr_data(aligned_wr_data, aligned_wr_addr, awaddr[wr_fifo_wr_ptr[int_cntr_width-2:0]], burst_data[wr_fifo_wr_ptr[int_cntr_width-2:0]],burst_valid_bytes[wr_fifo_wr_ptr[int_cntr_width-2:0]]);
      end else begin
        aligned_wr_data = burst_data[wr_fifo_wr_ptr[int_cntr_width-2:0]]; 
        aligned_wr_addr = awaddr[wr_fifo_wr_ptr[int_cntr_width-2:0]] ;
      end
      valid_data_bytes = burst_valid_bytes[wr_fifo_wr_ptr[int_cntr_width-2:0]];
    end else
      valid_data_bytes = 0;
    temp_wr_data = aligned_wr_data;
    wr_fifo[wr_fifo_wr_ptr[int_cntr_width-2:0]] = {awqos[wr_fifo_wr_ptr[int_cntr_width-2:0]], awlen[wr_fifo_wr_ptr[int_cntr_width-2:0]], awid[wr_fifo_wr_ptr[int_cntr_width-2:0]], bresp, temp_wr_data, aligned_wr_addr, valid_data_bytes};
    wcount <= wcount + awlen[wr_fifo_wr_ptr[int_cntr_width-2:0]]+1;
    wr_fifo_wr_ptr <= wr_fifo_wr_ptr + 1;
  end
 end
 end

 

 always@(negedge S_RESETN or posedge S_ACLK)
 begin
 if(!S_RESETN) begin
  rd_bresp_cnt <= 0;
  wr_latency_count = get_wr_lat_number(1);
  wr_delayed = 0;
  bresp_time_cnt <= 0; 
 end else begin
  wr_delayed = 1'b0;
  if(awvalid_flag[bresp_time_cnt] && (($time - awvalid_receive_time[bresp_time_cnt])/s_aclk_period >= wr_latency_count))
    wr_delayed = 1;
  if(!bresp_fifo_empty && wr_delayed) begin
    slave.SEND_WRITE_RESPONSE(fifo_bresp[rd_bresp_cnt[int_cntr_width-2:0]][rsp_id_msb : rsp_id_lsb],
                              fifo_bresp[rd_bresp_cnt[int_cntr_width-2:0]][rsp_msb : rsp_lsb]
                             );
    wr_delayed = 0;
    awvalid_flag[bresp_time_cnt] = 1'b0;
    bresp_time_cnt <= bresp_time_cnt+1;
    rd_bresp_cnt   <= rd_bresp_cnt + 1;
    wr_latency_count = get_wr_lat_number(1);
  end 
 end
 end

 

 reg wr_int_state;

 always@(negedge S_RESETN or posedge S_ACLK) 
 begin
 if(!S_RESETN) begin
  wr_int_state <= 1'b0;
  wr_bresp_cnt <= 0;
  wr_fifo_rd_ptr <= 0;
 end else begin
  case(wr_int_state)
  1'b0 : begin
    wr_int_state <= 1'b0;
    if(!temp_wr_intr_fifo_full && !bresp_fifo_full && !wr_fifo_empty) begin
      wr_intr_fifo.write_mem({wr_fifo[wr_fifo_rd_ptr[int_cntr_width-2:0]][wr_afi_qos_msb:wr_afi_qos_lsb], wr_fifo[wr_fifo_rd_ptr[int_cntr_width-2:0]][wr_afi_data_msb:wr_afi_bytes_lsb]});
      wr_int_state <= 1'b1;

      fifo_bresp[wr_bresp_cnt[int_cntr_width-2:0]] <= wr_fifo[wr_fifo_rd_ptr[int_cntr_width-2:0]][wr_afi_id_msb:wr_afi_rsp_lsb];
      wcount  <= wcount  - (wr_fifo[wr_fifo_rd_ptr[int_cntr_width-2:0]][wr_afi_ln_msb:wr_afi_ln_lsb] + 1);
      wacount <= wacount - 1;
      wr_fifo_rd_ptr <= wr_fifo_rd_ptr + 1;
      wr_bresp_cnt   <= wr_bresp_cnt+1;
    end
  end
  1'b1 : begin
    wr_int_state <= 0;
  end
  endcase
 end
 end


 




  reg [7:0] ar_time_cnt = 0,rresp_time_cnt = 0;
  real arvalid_receive_time[0:max_outstanding_transactions];
  reg arvalid_flag[0:max_outstanding_transactions];
  reg [int_cntr_width-1:0] ar_cnt = 0;


  reg [axi_size_width-1:0]  arsize [0:max_outstanding_transactions-1];
  reg [axi_prot_width-1:0]  arprot [0:max_outstanding_transactions-1];
  reg [axi_brst_type_width-1:0]  arbrst [0:max_outstanding_transactions-1];
  reg [axi_len_width-1:0]  arlen [0:max_outstanding_transactions-1];
  reg [axi_cache_width-1:0]  arcache [0:max_outstanding_transactions-1];
  reg [axi_lock_width-1:0]  arlock [0:max_outstanding_transactions-1];
  reg ar_flag [0:max_outstanding_transactions-1];
  reg [addr_width-1:0] araddr [0:max_outstanding_transactions-1];
  reg [id_bus_width-1:0]  arid [0:max_outstanding_transactions-1];
  reg [axi_qos_width-1:0]  arqos [0:max_outstanding_transactions-1];
  wire ar_fifo_full;

  reg [int_cntr_width-1:0] wr_rresp_cnt = 0;
  reg [axi_rsp_width-1:0] rresp;
  reg [rsp_fifo_bits-1:0] fifo_rresp [0:max_outstanding_transactions-1];
  reg enable_write_rresp;


  integer rd_latency_count;
  reg  rd_delayed;

  reg [rd_afi_fifo_bits-1:0] read_fifo[0:max_outstanding_transactions-1];
  reg [int_cntr_width-1:0] rd_fifo_wr_ptr = 0, rd_fifo_rd_ptr = 0;
  wire read_fifo_full; 

  reg [7:0] rcount;
  reg [2:0] racount;
  
  wire rd_intr_fifo_full, rd_intr_fifo_empty;
  wire read_fifo_empty;


  reg rd_req, invalid_rd_req;
  

  reg [rd_info_bits-1:0] read_control_info;   
  reg [(data_bus_width*axi_burst_len)-1:0] aligned_rd_data;
  reg temp_rd_intr_fifo_empty;

  processing_system7_bfm_v2_0_intr_rd_mem rd_intr_fifo(SW_CLK, S_RESETN, rd_intr_fifo_full, rd_intr_fifo_empty, rd_req, invalid_rd_req, read_control_info , RD_DATA_OCM, RD_DATA_DDR, RD_DATA_VALID_OCM, RD_DATA_VALID_DDR);

  assign read_fifo_empty = (rd_fifo_wr_ptr === rd_fifo_rd_ptr)?1'b1: 1'b0;
  assign S_RCOUNT = rcount;
  assign S_RACOUNT = racount;


  always@(posedge S_ACLK) temp_rd_intr_fifo_empty = rd_intr_fifo_empty;
   

   function automatic rdfifo_full ;
   input [axi_len_width-1:0] fifo_space_exp;
   integer fifo_space_left; 
   begin
     fifo_space_left = afi_fifo_locations - rcount;
     if(fifo_space_left < fifo_space_exp) 
       rdfifo_full = 1;
     else
       rdfifo_full = 0;
   end
   endfunction


  always@(negedge S_RESETN or S_ARID or S_ARADDR or S_ARVALID )
  begin
  if(!S_RESETN)
   ar_time_cnt <= 0;
  else begin
   if(S_ARVALID) begin
     arvalid_receive_time[ar_time_cnt] <= $time;
     arvalid_flag[ar_time_cnt] <= 1'b1;
     ar_time_cnt <= ar_time_cnt + 1;
   end 
  end
  end

  always@(posedge S_ACLK)
  begin
  if(net_ARVALID && S_ARREADY) begin
    if(S_ARQOS === 0) arqos[aw_cnt[int_cntr_width-2:0]] = ar_qos; 
    else arqos[aw_cnt[int_cntr_width-2:0]] = S_ARQOS; 
  end
  end


  always@(negedge S_RESETN or posedge S_ACLK)
  begin
  if(!S_RESETN) begin
    ar_cnt <= 0;
    racount <= 0;
  end else begin
    if(S_ARVALID && !rdfifo_full(S_ARLEN+1)) begin
        slave.RECEIVE_READ_ADDRESS(0,
                                   id_invalid,
                                   araddr[ar_cnt[int_cntr_width-2:0]],
                                   arlen[ar_cnt[int_cntr_width-2:0]],
                                   arsize[ar_cnt[int_cntr_width-2:0]],
                                   arbrst[ar_cnt[int_cntr_width-2:0]],
                                   arlock[ar_cnt[int_cntr_width-2:0]],
                                   arcache[ar_cnt[int_cntr_width-2:0]],
                                   arprot[ar_cnt[int_cntr_width-2:0]],
                                   arid[ar_cnt[int_cntr_width-2:0]]);
        ar_flag[ar_cnt[int_cntr_width-2:0]] <= 1'b1;
        ar_cnt    <= ar_cnt+1;
        racount   <= racount + 1;
    end
  end
  end
  



  task automatic get_wrap_aligned_rd_data;
  output [(data_bus_width*axi_burst_len)-1:0] aligned_data;
  input [addr_width-1:0] addr;
  input [(data_bus_width*axi_burst_len)-1:0] b_data;
  input [max_burst_bytes_width:0] v_bytes;
  reg [addr_width-1:0] start_addr;
  reg [(data_bus_width*axi_burst_len)-1:0] temp_data, wrp_data;
  integer wrp_bytes;
  integer i;
  begin
    start_addr = (addr/v_bytes) * v_bytes;
    wrp_bytes = addr - start_addr;
    wrp_data  = b_data;
    temp_data = 0;
    while(wrp_bytes > 0) begin
     temp_data = temp_data >> 8;
     temp_data[(data_bus_width*axi_burst_len)-1 : (data_bus_width*axi_burst_len)-8] = wrp_data[7:0];
     wrp_data = wrp_data >> 8;
     wrp_bytes = wrp_bytes - 1;
    end
    temp_data = temp_data >> ((data_bus_width*axi_burst_len) - (v_bytes*8));
    wrp_bytes = addr - start_addr;
    wrp_data = b_data >> (wrp_bytes*8);
    
    aligned_data = (temp_data | wrp_data);
  end
  endtask


  parameter RD_DATA_REQ = 1'b0, WAIT_RD_VALID = 1'b1;
  reg rd_fifo_state; 
  reg [addr_width-1:0] temp_read_address;
  reg [max_burst_bytes_width:0] temp_rd_valid_bytes;

  always@(negedge S_RESETN or posedge SW_CLK)
  begin
  if(!S_RESETN)begin
   wr_rresp_cnt <=0;
   rd_fifo_state <= RD_DATA_REQ;
   temp_rd_valid_bytes = 0;
   temp_read_address <= 0;
   RD_REQ_DDR <= 1'b0;
   RD_REQ_OCM <= 1'b0;
   rd_req        <= 0;
   invalid_rd_req<= 0;
   RD_QOS  <= 0;
  end else begin
   case(rd_fifo_state)
   RD_DATA_REQ : begin
     rd_fifo_state <= RD_DATA_REQ;
     RD_REQ_DDR <= 1'b0;
     RD_REQ_OCM <= 1'b0;
     invalid_rd_req <= 0;
     if(ar_flag[wr_rresp_cnt[int_cntr_width-2:0]] && !rd_intr_fifo_full) begin
       ar_flag[wr_rresp_cnt[int_cntr_width-2:0]] <= 0;
       rresp = calculate_resp(araddr[wr_rresp_cnt[int_cntr_width-2:0]],arprot[wr_rresp_cnt[int_cntr_width-2:0]]);
       temp_rd_valid_bytes = (arlen[wr_rresp_cnt[int_cntr_width-2:0]]+1)*(2**arsize[wr_rresp_cnt[int_cntr_width-2:0]]);

       if(arbrst[wr_rresp_cnt[int_cntr_width-2:0]] === AXI_WRAP)
        temp_read_address = (araddr[wr_rresp_cnt[int_cntr_width-2:0]]/temp_rd_valid_bytes) * temp_rd_valid_bytes;
       else 
        temp_read_address = araddr[wr_rresp_cnt[int_cntr_width-2:0]];
       
       if(rresp === AXI_OK) begin 
         case(decode_address(temp_read_address))
          OCM_MEM : RD_REQ_OCM <= 1;
          DDR_MEM : RD_REQ_DDR <= 1;
          default : invalid_rd_req <= 1;
         endcase
       end else
         invalid_rd_req <= 1;
       RD_ADDR    <= temp_read_address;
       RD_BYTES   <= temp_rd_valid_bytes;
       RD_QOS     <= arqos[wr_rresp_cnt[int_cntr_width-2:0]];
       rd_fifo_state <= WAIT_RD_VALID; 
       rd_req     <= 1;
       racount    <= racount - 1;
       read_control_info <= {araddr[wr_rresp_cnt[int_cntr_width-2:0]], arsize[wr_rresp_cnt[int_cntr_width-2:0]], arbrst[wr_rresp_cnt[int_cntr_width-2:0]], arlen[wr_rresp_cnt[int_cntr_width-2:0]], arid[wr_rresp_cnt[int_cntr_width-2:0]], rresp, temp_rd_valid_bytes  };
       wr_rresp_cnt <= wr_rresp_cnt + 1;
     end
   end
   WAIT_RD_VALID : begin    
     rd_fifo_state <= WAIT_RD_VALID;  
     rd_req        <= 0;
     if(RD_DATA_VALID_OCM | RD_DATA_VALID_DDR | invalid_rd_req) begin
       RD_REQ_DDR <= 1'b0;
       RD_REQ_OCM <= 1'b0;
       invalid_rd_req <= 0;
       rd_fifo_state <= RD_DATA_REQ;
     end
   end
   endcase
  end
  end

  

  reg[rd_afi_fifo_bits-1:0] temp_rd_data;
  reg tmp_state; 
  always@(negedge S_RESETN or posedge S_ACLK)
  begin
  if(!S_RESETN)begin
   rd_fifo_wr_ptr <= 0; 
   rcount <= 0;
   tmp_state <= 0;
  end else begin
   case(tmp_state)
   0 : begin 
       tmp_state <= 0;
       if(!temp_rd_intr_fifo_empty) begin
         rd_intr_fifo.read_mem(temp_rd_data);
         tmp_state <= 1;
       end
      end
   1 : begin  
       tmp_state <= 1;
       if(!rdfifo_full(temp_rd_data[rd_afi_ln_msb:rd_afi_ln_lsb]+1)) begin
        read_fifo[rd_fifo_wr_ptr[int_cntr_width-2:0]] = temp_rd_data;
        rd_fifo_wr_ptr = rd_fifo_wr_ptr + 1;
        rcount <= rcount + temp_rd_data[rd_afi_ln_msb:rd_afi_ln_lsb]+1;
        tmp_state <= 0;
       end
      end
    endcase
  end
  end

  
  reg[max_burst_bytes_width:0] rd_v_b;
  reg[rd_afi_fifo_bits-1:0] tmp_fifo_rd;
  reg[(data_bus_width*axi_burst_len)-1:0] temp_read_data;
  reg[(axi_rsp_width*axi_burst_len)-1:0] temp_read_rsp;


  always@(negedge S_RESETN or posedge S_ACLK)
  begin
  if(!S_RESETN)begin
   rd_fifo_rd_ptr <= 0;
   rd_latency_count <= get_rd_lat_number(1);
   rd_delayed = 0;
   rresp_time_cnt <= 0;
   rd_v_b = 0;
  end else begin
     if(arvalid_flag[rresp_time_cnt] && ((($time - arvalid_receive_time[rresp_time_cnt])/s_aclk_period) >= rd_latency_count)) begin
       rd_delayed = 1;
     end
     if(!read_fifo_empty && rd_delayed)begin
       rd_delayed = 0;  
       arvalid_flag[rresp_time_cnt] = 1'b0;
       tmp_fifo_rd =  read_fifo[rd_fifo_rd_ptr[int_cntr_width-2:0]];
       rd_v_b      = (tmp_fifo_rd[rd_afi_ln_msb : rd_afi_ln_lsb]+1)*(2**tmp_fifo_rd[rd_afi_siz_msb : rd_afi_siz_lsb]);
       temp_read_data =  tmp_fifo_rd[rd_afi_data_msb : rd_afi_data_lsb];
       if(tmp_fifo_rd[rd_afi_brst_msb : rd_afi_brst_lsb] === AXI_WRAP) begin
          get_wrap_aligned_rd_data(aligned_rd_data, tmp_fifo_rd[rd_afi_addr_msb : rd_afi_addr_lsb], tmp_fifo_rd[rd_afi_data_msb : rd_afi_data_lsb], rd_v_b);
          temp_read_data = aligned_rd_data;
       end
       temp_read_rsp = 0;
       repeat(axi_burst_len) begin
         temp_read_rsp = temp_read_rsp >> axi_rsp_width;
         temp_read_rsp[(axi_rsp_width*axi_burst_len)-1:(axi_rsp_width*axi_burst_len)-axi_rsp_width] = tmp_fifo_rd[rd_afi_rsp_msb : rd_afi_rsp_lsb];
       end 
       slave.SEND_READ_BURST_RESP_CTRL(tmp_fifo_rd[rd_afi_id_msb : rd_afi_id_lsb],
                                       tmp_fifo_rd[rd_afi_addr_msb : rd_afi_addr_lsb], 
                                       tmp_fifo_rd[rd_afi_ln_msb : rd_afi_ln_lsb], 
                                       tmp_fifo_rd[rd_afi_siz_msb : rd_afi_siz_lsb],
                                       tmp_fifo_rd[rd_afi_brst_msb : rd_afi_brst_lsb], 
                                       temp_read_data,
                                       temp_read_rsp);   
       rcount <= rcount -  (tmp_fifo_rd[rd_afi_ln_msb : rd_afi_ln_lsb]+ 1) ;
       rresp_time_cnt <= rresp_time_cnt+1;
       rd_latency_count <= get_rd_lat_number(1);
       rd_fifo_rd_ptr <= rd_fifo_rd_ptr+1;
     end
  end
  end
endmodule
module processing_system7_bfm_v2_0_afi_slave (
  S_RESETN,

  S_ARREADY,
  S_AWREADY,
  S_BVALID,
  S_RLAST,
  S_RVALID,
  S_WREADY,
  S_BRESP,
  S_RRESP,
  S_RDATA,
  S_BID,
  S_RID,
  S_ACLK,
  S_ARVALID,
  S_AWVALID,
  S_BREADY,
  S_RREADY,
  S_WLAST,
  S_WVALID,
  S_ARBURST,
  S_ARLOCK,
  S_ARSIZE,
  S_AWBURST,
  S_AWLOCK,
  S_AWSIZE,
  S_ARPROT,
  S_AWPROT,
  S_ARADDR,
  S_AWADDR,
  S_WDATA,
  S_ARCACHE,
  S_ARLEN,
  S_AWCACHE,
  S_AWLEN,
  S_WSTRB,
  S_ARID,
  S_AWID,
  S_WID,
  
  S_AWQOS,
  S_ARQOS,

  SW_CLK,
  WR_DATA_ACK_OCM,
  WR_DATA_ACK_DDR,
  WR_ADDR,
  WR_DATA,
  WR_BYTES,
  WR_DATA_VALID_OCM,
  WR_DATA_VALID_DDR,
  WR_QOS,
  
  RD_REQ_DDR,
  RD_REQ_OCM,
  RD_ADDR,
  RD_DATA_OCM,
  RD_DATA_DDR,
  RD_BYTES,
  RD_QOS,
  RD_DATA_VALID_OCM,
  RD_DATA_VALID_DDR,
  S_RDISSUECAP1_EN,
  S_WRISSUECAP1_EN,
  S_RCOUNT,
  S_WCOUNT,
  S_RACOUNT,
  S_WACOUNT

);

  parameter enable_this_port = 0;  
  parameter slave_name = "Slave";
  parameter data_bus_width = 32;
  parameter address_bus_width = 32;
  parameter id_bus_width = 6;
  parameter slave_base_address = 0;
  parameter slave_high_address = 4;
  parameter max_outstanding_transactions = 8;
  parameter exclusive_access_supported = 0;

  `include "processing_system7_bfm_v2_0_local_params.v"



  parameter int_cntr_width = clogb2(max_outstanding_transactions)+1;


  parameter rsp_fifo_bits = axi_rsp_width+id_bus_width; 
  parameter rsp_lsb = 0;
  parameter rsp_msb = axi_rsp_width-1;
  parameter rsp_id_lsb = rsp_msb + 1;  
  parameter rsp_id_msb = rsp_id_lsb + id_bus_width-1;  

  input  S_RESETN;

  output  S_ARREADY;
  output  S_AWREADY;
  output  S_BVALID;
  output  S_RLAST;
  output  S_RVALID;
  output  S_WREADY;
  output  [axi_rsp_width-1:0] S_BRESP;
  output  [axi_rsp_width-1:0] S_RRESP;
  output  [data_bus_width-1:0] S_RDATA;
  output  [id_bus_width-1:0] S_BID;
  output  [id_bus_width-1:0] S_RID;
  input S_ACLK;
  input S_ARVALID;
  input S_AWVALID;
  input S_BREADY;
  input S_RREADY;
  input S_WLAST;
  input S_WVALID;
  input [axi_brst_type_width-1:0] S_ARBURST;
  input [axi_lock_width-1:0] S_ARLOCK;
  input [axi_size_width-1:0] S_ARSIZE;
  input [axi_brst_type_width-1:0] S_AWBURST;
  input [axi_lock_width-1:0] S_AWLOCK;
  input [axi_size_width-1:0] S_AWSIZE;
  input [axi_prot_width-1:0] S_ARPROT;
  input [axi_prot_width-1:0] S_AWPROT;
  input [address_bus_width-1:0] S_ARADDR;
  input [address_bus_width-1:0] S_AWADDR;
  input [data_bus_width-1:0] S_WDATA;
  input [axi_cache_width-1:0] S_ARCACHE;
  input [axi_cache_width-1:0] S_ARLEN;
  
  input [axi_qos_width-1:0] S_ARQOS;
 
  input [axi_cache_width-1:0] S_AWCACHE;
  input [axi_len_width-1:0] S_AWLEN;

  input [axi_qos_width-1:0] S_AWQOS;
  input [(data_bus_width/8)-1:0] S_WSTRB;
  input [id_bus_width-1:0] S_ARID;
  input [id_bus_width-1:0] S_AWID;
  input [id_bus_width-1:0] S_WID;

  input SW_CLK;
  input WR_DATA_ACK_DDR, WR_DATA_ACK_OCM;
  output WR_DATA_VALID_DDR, WR_DATA_VALID_OCM;
  output [max_burst_bits-1:0] WR_DATA;
  output [addr_width-1:0] WR_ADDR;
  output [max_transfer_bytes_width:0] WR_BYTES;
  output reg RD_REQ_OCM, RD_REQ_DDR;
  output reg [addr_width-1:0] RD_ADDR;
  input [max_burst_bits-1:0] RD_DATA_DDR,RD_DATA_OCM;
  output reg[max_transfer_bytes_width:0] RD_BYTES;
  input RD_DATA_VALID_OCM,RD_DATA_VALID_DDR;
  output [axi_qos_width-1:0] WR_QOS;
  output reg [axi_qos_width-1:0] RD_QOS;
 
  input S_RDISSUECAP1_EN;
  input S_WRISSUECAP1_EN;

  output [7:0] S_RCOUNT;
  output [7:0] S_WCOUNT;
  output [2:0] S_RACOUNT;
  output [5:0] S_WACOUNT;

  wire net_ARVALID;
  wire net_AWVALID;
  wire net_WVALID;

  real s_aclk_period;

  cdn_axi3_slave_bfm #(slave_name,
                       data_bus_width,
                       address_bus_width,
                       id_bus_width, 
                       slave_base_address,
                       (slave_high_address- slave_base_address),
                       max_outstanding_transactions,
                       0,
                       exclusive_access_supported)
  slave   (.ACLK    (S_ACLK),
           .ARESETn (S_RESETN),

           .AWID    (S_AWID),
           .AWADDR  (S_AWADDR),
           .AWLEN   (S_AWLEN),
           .AWSIZE  (S_AWSIZE),
           .AWBURST (S_AWBURST),
           .AWLOCK  (S_AWLOCK),
           .AWCACHE (S_AWCACHE),
           .AWPROT  (S_AWPROT),
           .AWVALID (net_AWVALID),
           .AWREADY (S_AWREADY),

           .WID    (S_WID),
           .WDATA  (S_WDATA),
           .WSTRB  (S_WSTRB), 
           .WLAST  (S_WLAST), 
           .WVALID (net_WVALID),
           .WREADY (S_WREADY),

           .BID    (S_BID),
           .BRESP  (S_BRESP),
           .BVALID (S_BVALID),
           .BREADY (S_BREADY),

           .ARID    (S_ARID),
           .ARADDR  (S_ARADDR),
           .ARLEN   (S_ARLEN),
           .ARSIZE  (S_ARSIZE),
           .ARBURST (S_ARBURST),
           .ARLOCK  (S_ARLOCK),
           .ARCACHE (S_ARCACHE),
           .ARPROT  (S_ARPROT),
           .ARVALID (net_ARVALID),
           .ARREADY (S_ARREADY),

           .RID    (S_RID),
           .RDATA  (S_RDATA),
           .RRESP  (S_RRESP),
           .RLAST  (S_RLAST),
           .RVALID (S_RVALID),
           .RREADY (S_RREADY));


  wire wr_intr_fifo_full;
  reg temp_wr_intr_fifo_full; 


  processing_system7_bfm_v2_0_intr_wr_mem wr_intr_fifo(SW_CLK, S_RESETN, wr_intr_fifo_full, WR_DATA_ACK_OCM, WR_DATA_ACK_DDR, WR_ADDR, WR_DATA, WR_BYTES, WR_QOS, WR_DATA_VALID_OCM, WR_DATA_VALID_DDR);


  always@(posedge S_ACLK) temp_wr_intr_fifo_full = wr_intr_fifo_full;


  reg[1:0] latency_type = RANDOM_CASE;
  reg DEBUG_INFO = 1; 
  reg STOP_ON_ERROR = 1'b1; 


  reg [wr_afi_fifo_data_bits-1:0] wr_fifo [0:max_outstanding_transactions-1];
  reg [int_cntr_width-1:0] wr_fifo_wr_ptr = 0, wr_fifo_rd_ptr = 0;
  wire wr_fifo_empty;


  reg [7:0] aw_time_cnt = 0,bresp_time_cnt = 0;
  real awvalid_receive_time[0:max_outstanding_transactions];
  reg  awvalid_flag[0:max_outstanding_transactions];


  reg[int_cntr_width-1:0] aw_cnt = 0;


  reg [axi_size_width-1:0]  awsize [0:max_outstanding_transactions-1];
  reg [axi_prot_width-1:0]  awprot [0:max_outstanding_transactions-1];
  reg [axi_lock_width-1:0]  awlock [0:max_outstanding_transactions-1];
  reg [axi_cache_width-1:0]  awcache [0:max_outstanding_transactions-1];
  reg [axi_brst_type_width-1:0]  awbrst [0:max_outstanding_transactions-1];
  reg [axi_len_width-1:0]  awlen [0:max_outstanding_transactions-1];
  reg aw_flag [0:max_outstanding_transactions-1];
  reg [addr_width-1:0] awaddr [0:max_outstanding_transactions-1];
  reg [id_bus_width-1:0] awid [0:max_outstanding_transactions-1];
  reg [axi_qos_width-1:0]  awqos [0:max_outstanding_transactions-1];
  wire aw_fifo_full;


  reg [(data_bus_width*axi_burst_len)-1:0] burst_data [0:max_outstanding_transactions-1];
  reg [max_burst_bytes_width:0] burst_valid_bytes [0:max_outstanding_transactions-1];
  reg wlast_flag [0:max_outstanding_transactions-1];
  wire wd_fifo_full;


  reg [int_cntr_width-1:0] wd_cnt = 0;
  reg [(data_bus_width*axi_burst_len)-1:0] aligned_wr_data;
  reg [addr_width-1:0] aligned_wr_addr;
  reg [max_burst_bytes_width:0] valid_data_bytes;
  reg [int_cntr_width-1:0] wr_bresp_cnt = 0;
  reg [axi_rsp_width-1:0] bresp;
  reg [rsp_fifo_bits-1:0] fifo_bresp [0:max_outstanding_transactions-1];
  reg enable_write_bresp;
  reg [int_cntr_width-1:0] rd_bresp_cnt = 0;
  integer wr_latency_count;
  reg  wr_delayed;
  wire bresp_fifo_empty;


  reg[7:0] wcount;
  reg[5:0] wacount;


  reg [axi_qos_width-1:0] ar_qos, aw_qos;

  initial begin
   if(DEBUG_INFO) begin
    if(enable_this_port)
     $display("[%0d] : %0s : %0s : Port is ENABLED.",$time, DISP_INFO, slave_name);
    else
     $display("[%0d] : %0s : %0s : Port is DISABLED.",$time, DISP_INFO, slave_name);
   end
  end



          
  always@(S_RESETN)
  begin
   if(S_RESETN) begin
    @(posedge S_ACLK);
    s_aclk_period = $time;
    @(posedge S_ACLK);
    s_aclk_period = $time - s_aclk_period;
   end
  end


  initial slave.set_disable_reset_value_checks(1); 
  initial begin
     repeat(2) @(posedge S_ACLK);
     if(!enable_this_port) begin
        slave.set_channel_level_info(0);
        slave.set_function_level_info(0);
     end 
     slave.RESPONSE_TIMEOUT = 0;
  end



  task set_latency_type;
    input[1:0] lat;
  begin
   if(enable_this_port) 
    latency_type = lat;
   else begin

     $display("[%0d] : %0s : %0s : Port is disabled. 'Latency Profile' will not be set...",$time, DISP_WARN, slave_name);
   end
  end
  endtask


  task set_arqos;
    input[axi_qos_width-1:0] qos;
  begin
   if(enable_this_port) 
    ar_qos = qos;
   else begin
    if(DEBUG_INFO)
     $display("[%0d] : %0s : %0s : Port is disabled. 'ARQOS' will not be set...",$time, DISP_WARN, slave_name);
   end
  end
  endtask



  task set_awqos;
    input[axi_qos_width-1:0] qos;
  begin
   if(enable_this_port) 
    aw_qos = qos;
   else begin
    if(DEBUG_INFO)
     $display("[%0d] : %0s : %0s : Port is disabled. 'AWQOS' will not be set...",$time, DISP_WARN, slave_name);
   end
  end
  endtask



  function [31:0] get_wr_lat_number;
  input dummy;
  reg[1:0] temp;
  begin 
   case(latency_type)
    BEST_CASE   : get_wr_lat_number = afi_wr_min;            
    AVG_CASE    : get_wr_lat_number = afi_wr_avg;            
    WORST_CASE  : get_wr_lat_number = afi_wr_max;            
    default     : begin
                   temp = $random;
                   case(temp) 
                    2'b00   : get_wr_lat_number = ($random()%10+ afi_wr_min); 
                    2'b01   : get_wr_lat_number = ($random()%40+ afi_wr_avg); 
                    default : get_wr_lat_number = ($random()%60+ afi_wr_max); 
                   endcase        
                  end
   endcase
  end
  endfunction



  function [31:0] get_rd_lat_number;
  input dummy;
  reg[1:0] temp;
  begin 
   case(latency_type)
    BEST_CASE   : get_rd_lat_number = afi_rd_min;            
    AVG_CASE    : get_rd_lat_number = afi_rd_avg;            
    WORST_CASE  : get_rd_lat_number = afi_rd_max;            
    default     : begin
                   temp = $random;
                   case(temp) 
                    2'b00   : get_rd_lat_number = ($random()%10+ afi_rd_min); 
                    2'b01   : get_rd_lat_number = ($random()%40+ afi_rd_avg); 
                    default : get_rd_lat_number = ($random()%60+ afi_rd_max); 
                   endcase        
                  end
   endcase
  end
  endfunction


 always@(S_AWVALID or S_WVALID or S_ARVALID)
 begin
  if((S_AWVALID | S_WVALID | S_ARVALID) && !enable_this_port) begin
    $display("[%0d] : %0s : %0s : Port is disabled. AXI transaction is initiated on this port ...\nSimulation will halt ..",$time, DISP_ERR, slave_name);
    $stop;
  end
 end



  assign net_ARVALID = enable_this_port ? S_ARVALID : 1'b0;
  assign net_AWVALID = enable_this_port ? S_AWVALID : 1'b0;
  assign net_WVALID  = enable_this_port ? S_WVALID : 1'b0;

  assign wr_fifo_empty = (wr_fifo_wr_ptr === wr_fifo_rd_ptr)?1'b1: 1'b0;
  assign bresp_fifo_empty = (wr_bresp_cnt === rd_bresp_cnt)?1'b1:1'b0;
  assign bresp_fifo_full  = ((wr_bresp_cnt[int_cntr_width-1] !== rd_bresp_cnt[int_cntr_width-1]) && (wr_bresp_cnt[int_cntr_width-2:0] === rd_bresp_cnt[int_cntr_width-2:0]))?1'b1:1'b0;

  assign S_WCOUNT = wcount;
  assign S_WACOUNT = wacount;


 function automatic wrfifo_full ;
 input [axi_len_width-1:0] fifo_space_exp;
 integer fifo_space_left; 
 begin
   fifo_space_left = afi_fifo_locations - wcount;
   if(fifo_space_left < fifo_space_exp) 
     wrfifo_full = 1;
   else
     wrfifo_full = 0;
 end
 endfunction



 always@(negedge S_RESETN or S_AWID or S_AWADDR or S_AWVALID )
 begin
 if(!S_RESETN)
  aw_time_cnt <= 0;
 else begin
  if(S_AWVALID) begin
    awvalid_receive_time[aw_time_cnt] <= $time;
    awvalid_flag[aw_time_cnt] <= 1'b1;
    aw_time_cnt <= aw_time_cnt + 1;
  end
 end
 end

  always@(posedge S_ACLK)
  begin
  if(net_AWVALID && S_AWREADY) begin
    if(S_AWQOS === 0) awqos[aw_cnt[int_cntr_width-2:0]] = aw_qos; 
    else awqos[aw_cnt[int_cntr_width-2:0]] = S_AWQOS; 
  end
  end


 always@(negedge S_RESETN or posedge S_ACLK)
 begin
 if(!S_RESETN) begin
   aw_cnt <= 0;
   wacount <= 0;
 end else begin
   if(S_AWVALID && !wrfifo_full(S_AWLEN+1)) begin 
       slave.RECEIVE_WRITE_ADDRESS(0,
                                   id_invalid,
                                   awaddr[aw_cnt[int_cntr_width-2:0]],
                                   awlen[aw_cnt[int_cntr_width-2:0]],
                                   awsize[aw_cnt[int_cntr_width-2:0]],
                                   awbrst[aw_cnt[int_cntr_width-2:0]],
                                   awlock[aw_cnt[int_cntr_width-2:0]],
                                   awcache[aw_cnt[int_cntr_width-2:0]],
                                   awprot[aw_cnt[int_cntr_width-2:0]],
                                   awid[aw_cnt[int_cntr_width-2:0]]);
       aw_flag[aw_cnt[int_cntr_width-2:0]] <= 1'b1;
       aw_cnt                              <= aw_cnt + 1;
       wacount                             <= wacount + 1;
   end
 end
 end

 

 always@(negedge S_RESETN or posedge S_ACLK)
 begin
 if(!S_RESETN) begin
  wd_cnt <= 0;
 end else begin
  if(aw_flag[wd_cnt[int_cntr_width-2:0]]) begin
    if(S_WVALID && !wrfifo_full(awlen[wd_cnt[int_cntr_width-2:0]] + 1)) begin
     slave.RECEIVE_WRITE_BURST_NO_CHECKS(S_WID, burst_data[wd_cnt[int_cntr_width-2:0]], burst_valid_bytes[wd_cnt[int_cntr_width-2:0]]); 
     wlast_flag[wd_cnt[int_cntr_width-2:0]] <= 1'b1;
     wd_cnt   <= wd_cnt + 1;
    end  
  end else begin
    if(!wrfifo_full(axi_burst_len) && S_WVALID) begin
      slave.RECEIVE_WRITE_BURST_NO_CHECKS(S_WID, burst_data[wd_cnt[int_cntr_width-2:0]], burst_valid_bytes[wd_cnt[int_cntr_width-2:0]]); 
      wlast_flag[wd_cnt[int_cntr_width-2:0]] <= 1'b1;
      wd_cnt   <= wd_cnt + 1;
    end
  end
 end
 end

 

 task automatic get_wrap_aligned_wr_data;
 output [(data_bus_width*axi_burst_len)-1:0] aligned_data;
 output [addr_width-1:0] start_addr;
 input  [addr_width-1:0] addr;
 input  [(data_bus_width*axi_burst_len)-1:0] b_data;
 input  [max_burst_bytes_width:0] v_bytes;
 reg    [(data_bus_width*axi_burst_len)-1:0] temp_data, wrp_data;
 integer wrp_bytes;
 integer i;
 begin
   start_addr = (addr/v_bytes) * v_bytes;
   wrp_bytes = addr - start_addr;
   wrp_data = b_data;
   temp_data = 0;
   wrp_data = wrp_data << ((data_bus_width*axi_burst_len) - (v_bytes*8));
   while(wrp_bytes > 0) begin
     temp_data = temp_data << 8;
     temp_data[7:0] = wrp_data[(data_bus_width*axi_burst_len)-1 : (data_bus_width*axi_burst_len)-8];
     wrp_data = wrp_data << 8;
     wrp_bytes = wrp_bytes - 1;
   end
   wrp_bytes = addr - start_addr;
   wrp_data = b_data << (wrp_bytes*8);
   
   aligned_data = (temp_data | wrp_data);
 end
 endtask

  

 function [axi_rsp_width-1:0] calculate_resp;
 input [addr_width-1:0] awaddr; 
 input [axi_prot_width-1:0] awprot;
 reg [axi_rsp_width-1:0] rsp;
 begin
   rsp = AXI_OK;

   if(decode_address(awaddr) === INVALID_MEM_TYPE) begin
    rsp = AXI_SLV_ERR;
    $display("[%0d] : %0s : %0s : AXI Access to Invalid location(0x%0h) ",$time, DISP_ERR, slave_name, awaddr);
   end
   else if(decode_address(awaddr) === REG_MEM) begin
    rsp = AXI_SLV_ERR;
    $display("[%0d] : %0s : %0s : AXI Access to Register Map(0x%0h) is not allowed through this port.",$time, DISP_ERR, slave_name, awaddr);
   end
   if(secure_access_enabled && awprot[1])
    rsp = AXI_DEC_ERR;
   calculate_resp = rsp;
 end
 endfunction

 reg[max_burst_bits-1:0] temp_wr_data;

 always@(negedge S_RESETN or posedge S_ACLK)
 begin
 if(!S_RESETN) begin
  wr_fifo_wr_ptr <= 0;
  wcount <= 0;
 end else begin
  enable_write_bresp = aw_flag[wr_fifo_wr_ptr[int_cntr_width-2:0]] && wlast_flag[wr_fifo_wr_ptr[int_cntr_width-2:0]];

  if(enable_write_bresp) begin
    aw_flag[wr_fifo_wr_ptr[int_cntr_width-2:0]]    <= 0;
    wlast_flag[wr_fifo_wr_ptr[int_cntr_width-2:0]] <= 0;
 
    bresp = calculate_resp(awaddr[wr_fifo_wr_ptr[int_cntr_width-2:0]], awprot[wr_fifo_wr_ptr[int_cntr_width-2:0]]);

    if(bresp === AXI_OK ) begin
      if(awbrst[wr_fifo_wr_ptr[int_cntr_width-2:0]]=== AXI_WRAP) begin
        get_wrap_aligned_wr_data(aligned_wr_data, aligned_wr_addr, awaddr[wr_fifo_wr_ptr[int_cntr_width-2:0]], burst_data[wr_fifo_wr_ptr[int_cntr_width-2:0]],burst_valid_bytes[wr_fifo_wr_ptr[int_cntr_width-2:0]]);
      end else begin
        aligned_wr_data = burst_data[wr_fifo_wr_ptr[int_cntr_width-2:0]]; 
        aligned_wr_addr = awaddr[wr_fifo_wr_ptr[int_cntr_width-2:0]] ;
      end
      valid_data_bytes = burst_valid_bytes[wr_fifo_wr_ptr[int_cntr_width-2:0]];
    end else
      valid_data_bytes = 0;
    temp_wr_data = aligned_wr_data;
    wr_fifo[wr_fifo_wr_ptr[int_cntr_width-2:0]] = {awqos[wr_fifo_wr_ptr[int_cntr_width-2:0]], awlen[wr_fifo_wr_ptr[int_cntr_width-2:0]], awid[wr_fifo_wr_ptr[int_cntr_width-2:0]], bresp, temp_wr_data, aligned_wr_addr, valid_data_bytes};
    wcount <= wcount + awlen[wr_fifo_wr_ptr[int_cntr_width-2:0]]+1;
    wr_fifo_wr_ptr <= wr_fifo_wr_ptr + 1;
  end
 end
 end

 

 always@(negedge S_RESETN or posedge S_ACLK)
 begin
 if(!S_RESETN) begin
  rd_bresp_cnt <= 0;
  wr_latency_count = get_wr_lat_number(1);
  wr_delayed = 0;
  bresp_time_cnt <= 0; 
 end else begin
  wr_delayed = 1'b0;
  if(awvalid_flag[bresp_time_cnt] && (($time - awvalid_receive_time[bresp_time_cnt])/s_aclk_period >= wr_latency_count))
    wr_delayed = 1;
  if(!bresp_fifo_empty && wr_delayed) begin
    slave.SEND_WRITE_RESPONSE(fifo_bresp[rd_bresp_cnt[int_cntr_width-2:0]][rsp_id_msb : rsp_id_lsb],
                              fifo_bresp[rd_bresp_cnt[int_cntr_width-2:0]][rsp_msb : rsp_lsb]
                             );
    wr_delayed = 0;
    awvalid_flag[bresp_time_cnt] = 1'b0;
    bresp_time_cnt <= bresp_time_cnt+1;
    rd_bresp_cnt   <= rd_bresp_cnt + 1;
    wr_latency_count = get_wr_lat_number(1);
  end 
 end
 end

 

 reg wr_int_state;

 always@(negedge S_RESETN or posedge S_ACLK) 
 begin
 if(!S_RESETN) begin
  wr_int_state <= 1'b0;
  wr_bresp_cnt <= 0;
  wr_fifo_rd_ptr <= 0;
 end else begin
  case(wr_int_state)
  1'b0 : begin
    wr_int_state <= 1'b0;
    if(!temp_wr_intr_fifo_full && !bresp_fifo_full && !wr_fifo_empty) begin
      wr_intr_fifo.write_mem({wr_fifo[wr_fifo_rd_ptr[int_cntr_width-2:0]][wr_afi_qos_msb:wr_afi_qos_lsb], wr_fifo[wr_fifo_rd_ptr[int_cntr_width-2:0]][wr_afi_data_msb:wr_afi_bytes_lsb]});
      wr_int_state <= 1'b1;

      fifo_bresp[wr_bresp_cnt[int_cntr_width-2:0]] <= wr_fifo[wr_fifo_rd_ptr[int_cntr_width-2:0]][wr_afi_id_msb:wr_afi_rsp_lsb];
      wcount  <= wcount  - (wr_fifo[wr_fifo_rd_ptr[int_cntr_width-2:0]][wr_afi_ln_msb:wr_afi_ln_lsb] + 1);
      wacount <= wacount - 1;
      wr_fifo_rd_ptr <= wr_fifo_rd_ptr + 1;
      wr_bresp_cnt   <= wr_bresp_cnt+1;
    end
  end
  1'b1 : begin
    wr_int_state <= 0;
  end
  endcase
 end
 end


 




  reg [7:0] ar_time_cnt = 0,rresp_time_cnt = 0;
  real arvalid_receive_time[0:max_outstanding_transactions];
  reg arvalid_flag[0:max_outstanding_transactions];
  reg [int_cntr_width-1:0] ar_cnt = 0;


  reg [axi_size_width-1:0]  arsize [0:max_outstanding_transactions-1];
  reg [axi_prot_width-1:0]  arprot [0:max_outstanding_transactions-1];
  reg [axi_brst_type_width-1:0]  arbrst [0:max_outstanding_transactions-1];
  reg [axi_len_width-1:0]  arlen [0:max_outstanding_transactions-1];
  reg [axi_cache_width-1:0]  arcache [0:max_outstanding_transactions-1];
  reg [axi_lock_width-1:0]  arlock [0:max_outstanding_transactions-1];
  reg ar_flag [0:max_outstanding_transactions-1];
  reg [addr_width-1:0] araddr [0:max_outstanding_transactions-1];
  reg [id_bus_width-1:0]  arid [0:max_outstanding_transactions-1];
  reg [axi_qos_width-1:0]  arqos [0:max_outstanding_transactions-1];
  wire ar_fifo_full;

  reg [int_cntr_width-1:0] wr_rresp_cnt = 0;
  reg [axi_rsp_width-1:0] rresp;
  reg [rsp_fifo_bits-1:0] fifo_rresp [0:max_outstanding_transactions-1];
  reg enable_write_rresp;


  integer rd_latency_count;
  reg  rd_delayed;

  reg [rd_afi_fifo_bits-1:0] read_fifo[0:max_outstanding_transactions-1];
  reg [int_cntr_width-1:0] rd_fifo_wr_ptr = 0, rd_fifo_rd_ptr = 0;
  wire read_fifo_full; 

  reg [7:0] rcount;
  reg [2:0] racount;
  
  wire rd_intr_fifo_full, rd_intr_fifo_empty;
  wire read_fifo_empty;


  reg rd_req, invalid_rd_req;
  

  reg [rd_info_bits-1:0] read_control_info;   
  reg [(data_bus_width*axi_burst_len)-1:0] aligned_rd_data;
  reg temp_rd_intr_fifo_empty;

  processing_system7_bfm_v2_0_intr_rd_mem rd_intr_fifo(SW_CLK, S_RESETN, rd_intr_fifo_full, rd_intr_fifo_empty, rd_req, invalid_rd_req, read_control_info , RD_DATA_OCM, RD_DATA_DDR, RD_DATA_VALID_OCM, RD_DATA_VALID_DDR);

  assign read_fifo_empty = (rd_fifo_wr_ptr === rd_fifo_rd_ptr)?1'b1: 1'b0;
  assign S_RCOUNT = rcount;
  assign S_RACOUNT = racount;


  always@(posedge S_ACLK) temp_rd_intr_fifo_empty = rd_intr_fifo_empty;
   

   function automatic rdfifo_full ;
   input [axi_len_width-1:0] fifo_space_exp;
   integer fifo_space_left; 
   begin
     fifo_space_left = afi_fifo_locations - rcount;
     if(fifo_space_left < fifo_space_exp) 
       rdfifo_full = 1;
     else
       rdfifo_full = 0;
   end
   endfunction


  always@(negedge S_RESETN or S_ARID or S_ARADDR or S_ARVALID )
  begin
  if(!S_RESETN)
   ar_time_cnt <= 0;
  else begin
   if(S_ARVALID) begin
     arvalid_receive_time[ar_time_cnt] <= $time;
     arvalid_flag[ar_time_cnt] <= 1'b1;
     ar_time_cnt <= ar_time_cnt + 1;
   end 
  end
  end

  always@(posedge S_ACLK)
  begin
  if(net_ARVALID && S_ARREADY) begin
    if(S_ARQOS === 0) arqos[aw_cnt[int_cntr_width-2:0]] = ar_qos; 
    else arqos[aw_cnt[int_cntr_width-2:0]] = S_ARQOS; 
  end
  end


  always@(negedge S_RESETN or posedge S_ACLK)
  begin
  if(!S_RESETN) begin
    ar_cnt <= 0;
    racount <= 0;
  end else begin
    if(S_ARVALID && !rdfifo_full(S_ARLEN+1)) begin
        slave.RECEIVE_READ_ADDRESS(0,
                                   id_invalid,
                                   araddr[ar_cnt[int_cntr_width-2:0]],
                                   arlen[ar_cnt[int_cntr_width-2:0]],
                                   arsize[ar_cnt[int_cntr_width-2:0]],
                                   arbrst[ar_cnt[int_cntr_width-2:0]],
                                   arlock[ar_cnt[int_cntr_width-2:0]],
                                   arcache[ar_cnt[int_cntr_width-2:0]],
                                   arprot[ar_cnt[int_cntr_width-2:0]],
                                   arid[ar_cnt[int_cntr_width-2:0]]);
        ar_flag[ar_cnt[int_cntr_width-2:0]] <= 1'b1;
        ar_cnt    <= ar_cnt+1;
        racount   <= racount + 1;
    end
  end
  end
  



  task automatic get_wrap_aligned_rd_data;
  output [(data_bus_width*axi_burst_len)-1:0] aligned_data;
  input [addr_width-1:0] addr;
  input [(data_bus_width*axi_burst_len)-1:0] b_data;
  input [max_burst_bytes_width:0] v_bytes;
  reg [addr_width-1:0] start_addr;
  reg [(data_bus_width*axi_burst_len)-1:0] temp_data, wrp_data;
  integer wrp_bytes;
  integer i;
  begin
    start_addr = (addr/v_bytes) * v_bytes;
    wrp_bytes = addr - start_addr;
    wrp_data  = b_data;
    temp_data = 0;
    while(wrp_bytes > 0) begin
     temp_data = temp_data >> 8;
     temp_data[(data_bus_width*axi_burst_len)-1 : (data_bus_width*axi_burst_len)-8] = wrp_data[7:0];
     wrp_data = wrp_data >> 8;
     wrp_bytes = wrp_bytes - 1;
    end
    temp_data = temp_data >> ((data_bus_width*axi_burst_len) - (v_bytes*8));
    wrp_bytes = addr - start_addr;
    wrp_data = b_data >> (wrp_bytes*8);
    
    aligned_data = (temp_data | wrp_data);
  end
  endtask


  parameter RD_DATA_REQ = 1'b0, WAIT_RD_VALID = 1'b1;
  reg rd_fifo_state; 
  reg [addr_width-1:0] temp_read_address;
  reg [max_burst_bytes_width:0] temp_rd_valid_bytes;

  always@(negedge S_RESETN or posedge SW_CLK)
  begin
  if(!S_RESETN)begin
   wr_rresp_cnt <=0;
   rd_fifo_state <= RD_DATA_REQ;
   temp_rd_valid_bytes = 0;
   temp_read_address <= 0;
   RD_REQ_DDR <= 1'b0;
   RD_REQ_OCM <= 1'b0;
   rd_req        <= 0;
   invalid_rd_req<= 0;
   RD_QOS  <= 0;
  end else begin
   case(rd_fifo_state)
   RD_DATA_REQ : begin
     rd_fifo_state <= RD_DATA_REQ;
     RD_REQ_DDR <= 1'b0;
     RD_REQ_OCM <= 1'b0;
     invalid_rd_req <= 0;
     if(ar_flag[wr_rresp_cnt[int_cntr_width-2:0]] && !rd_intr_fifo_full) begin
       ar_flag[wr_rresp_cnt[int_cntr_width-2:0]] <= 0;
       rresp = calculate_resp(araddr[wr_rresp_cnt[int_cntr_width-2:0]],arprot[wr_rresp_cnt[int_cntr_width-2:0]]);
       temp_rd_valid_bytes = (arlen[wr_rresp_cnt[int_cntr_width-2:0]]+1)*(2**arsize[wr_rresp_cnt[int_cntr_width-2:0]]);

       if(arbrst[wr_rresp_cnt[int_cntr_width-2:0]] === AXI_WRAP)
        temp_read_address = (araddr[wr_rresp_cnt[int_cntr_width-2:0]]/temp_rd_valid_bytes) * temp_rd_valid_bytes;
       else 
        temp_read_address = araddr[wr_rresp_cnt[int_cntr_width-2:0]];
       
       if(rresp === AXI_OK) begin 
         case(decode_address(temp_read_address))
          OCM_MEM : RD_REQ_OCM <= 1;
          DDR_MEM : RD_REQ_DDR <= 1;
          default : invalid_rd_req <= 1;
         endcase
       end else
         invalid_rd_req <= 1;
       RD_ADDR    <= temp_read_address;
       RD_BYTES   <= temp_rd_valid_bytes;
       RD_QOS     <= arqos[wr_rresp_cnt[int_cntr_width-2:0]];
       rd_fifo_state <= WAIT_RD_VALID; 
       rd_req     <= 1;
       racount    <= racount - 1;
       read_control_info <= {araddr[wr_rresp_cnt[int_cntr_width-2:0]], arsize[wr_rresp_cnt[int_cntr_width-2:0]], arbrst[wr_rresp_cnt[int_cntr_width-2:0]], arlen[wr_rresp_cnt[int_cntr_width-2:0]], arid[wr_rresp_cnt[int_cntr_width-2:0]], rresp, temp_rd_valid_bytes  };
       wr_rresp_cnt <= wr_rresp_cnt + 1;
     end
   end
   WAIT_RD_VALID : begin    
     rd_fifo_state <= WAIT_RD_VALID;  
     rd_req        <= 0;
     if(RD_DATA_VALID_OCM | RD_DATA_VALID_DDR | invalid_rd_req) begin
       RD_REQ_DDR <= 1'b0;
       RD_REQ_OCM <= 1'b0;
       invalid_rd_req <= 0;
       rd_fifo_state <= RD_DATA_REQ;
     end
   end
   endcase
  end
  end

  

  reg[rd_afi_fifo_bits-1:0] temp_rd_data;
  reg tmp_state; 
  always@(negedge S_RESETN or posedge S_ACLK)
  begin
  if(!S_RESETN)begin
   rd_fifo_wr_ptr <= 0; 
   rcount <= 0;
   tmp_state <= 0;
  end else begin
   case(tmp_state)
   0 : begin 
       tmp_state <= 0;
       if(!temp_rd_intr_fifo_empty) begin
         rd_intr_fifo.read_mem(temp_rd_data);
         tmp_state <= 1;
       end
      end
   1 : begin  
       tmp_state <= 1;
       if(!rdfifo_full(temp_rd_data[rd_afi_ln_msb:rd_afi_ln_lsb]+1)) begin
        read_fifo[rd_fifo_wr_ptr[int_cntr_width-2:0]] = temp_rd_data;
        rd_fifo_wr_ptr = rd_fifo_wr_ptr + 1;
        rcount <= rcount + temp_rd_data[rd_afi_ln_msb:rd_afi_ln_lsb]+1;
        tmp_state <= 0;
       end
      end
    endcase
  end
  end

  
  reg[max_burst_bytes_width:0] rd_v_b;
  reg[rd_afi_fifo_bits-1:0] tmp_fifo_rd;
  reg[(data_bus_width*axi_burst_len)-1:0] temp_read_data;
  reg[(axi_rsp_width*axi_burst_len)-1:0] temp_read_rsp;


  always@(negedge S_RESETN or posedge S_ACLK)
  begin
  if(!S_RESETN)begin
   rd_fifo_rd_ptr <= 0;
   rd_latency_count <= get_rd_lat_number(1);
   rd_delayed = 0;
   rresp_time_cnt <= 0;
   rd_v_b = 0;
  end else begin
     if(arvalid_flag[rresp_time_cnt] && ((($time - arvalid_receive_time[rresp_time_cnt])/s_aclk_period) >= rd_latency_count)) begin
       rd_delayed = 1;
     end
     if(!read_fifo_empty && rd_delayed)begin
       rd_delayed = 0;  
       arvalid_flag[rresp_time_cnt] = 1'b0;
       tmp_fifo_rd =  read_fifo[rd_fifo_rd_ptr[int_cntr_width-2:0]];
       rd_v_b      = (tmp_fifo_rd[rd_afi_ln_msb : rd_afi_ln_lsb]+1)*(2**tmp_fifo_rd[rd_afi_siz_msb : rd_afi_siz_lsb]);
       temp_read_data =  tmp_fifo_rd[rd_afi_data_msb : rd_afi_data_lsb];
       if(tmp_fifo_rd[rd_afi_brst_msb : rd_afi_brst_lsb] === AXI_WRAP) begin
          get_wrap_aligned_rd_data(aligned_rd_data, tmp_fifo_rd[rd_afi_addr_msb : rd_afi_addr_lsb], tmp_fifo_rd[rd_afi_data_msb : rd_afi_data_lsb], rd_v_b);
          temp_read_data = aligned_rd_data;
       end
       temp_read_rsp = 0;
       repeat(axi_burst_len) begin
         temp_read_rsp = temp_read_rsp >> axi_rsp_width;
         temp_read_rsp[(axi_rsp_width*axi_burst_len)-1:(axi_rsp_width*axi_burst_len)-axi_rsp_width] = tmp_fifo_rd[rd_afi_rsp_msb : rd_afi_rsp_lsb];
       end 
       slave.SEND_READ_BURST_RESP_CTRL(tmp_fifo_rd[rd_afi_id_msb : rd_afi_id_lsb],
                                       tmp_fifo_rd[rd_afi_addr_msb : rd_afi_addr_lsb], 
                                       tmp_fifo_rd[rd_afi_ln_msb : rd_afi_ln_lsb], 
                                       tmp_fifo_rd[rd_afi_siz_msb : rd_afi_siz_lsb],
                                       tmp_fifo_rd[rd_afi_brst_msb : rd_afi_brst_lsb], 
                                       temp_read_data,
                                       temp_read_rsp);   
       rcount <= rcount -  (tmp_fifo_rd[rd_afi_ln_msb : rd_afi_ln_lsb]+ 1) ;
       rresp_time_cnt <= rresp_time_cnt+1;
       rd_latency_count <= get_rd_lat_number(1);
       rd_fifo_rd_ptr <= rd_fifo_rd_ptr+1;
     end
  end
  end
endmodule