data/full_repos/permissive/142505464/modules/wb_bfm_mod/rtl/verilog/wb_bfm_mod_transactor.v
None: at end of input
1: b'%Error: data/full_repos/permissive/142505464/modules/wb_bfm_mod/rtl/verilog/wb_bfm_mod_transactor.v:61: Cannot find include file: wb_common_params.v\n  `include "wb_common_params.v" \n           ^~~~~~~~~~~~~~~~~~~~\n        ... Looked in:\n             data/full_repos/permissive/142505464/modules/wb_bfm_mod/rtl/verilog,data/full_repos/permissive/142505464/wb_common_params.v\n             data/full_repos/permissive/142505464/modules/wb_bfm_mod/rtl/verilog,data/full_repos/permissive/142505464/wb_common_params.v.v\n             data/full_repos/permissive/142505464/modules/wb_bfm_mod/rtl/verilog,data/full_repos/permissive/142505464/wb_common_params.v.sv\n             wb_common_params.v\n             wb_common_params.v.v\n             wb_common_params.v.sv\n             obj_dir/wb_common_params.v\n             obj_dir/wb_common_params.v.v\n             obj_dir/wb_common_params.v.sv\n%Error: data/full_repos/permissive/142505464/modules/wb_bfm_mod/rtl/verilog/wb_bfm_mod_transactor.v:122: Unsupported: Seeding $random doesn\'t map to C++, use $c("srand")\n          gen_adr = (low + ({$random(SEED)} % (high-low))) &  {{aw-ADR_LSB{1\'b1}},{ADR_LSB{1\'b0}}};\n                             ^~~~~~~\n%Error: Internal Error: data/full_repos/permissive/142505464/modules/wb_bfm_mod/rtl/verilog/wb_bfm_mod_transactor.v:122: ../V3Ast.cpp:358: Null item passed to setOp1p\n          gen_adr = (low + ({$random(SEED)} % (high-low))) &  {{aw-ADR_LSB{1\'b1}},{ADR_LSB{1\'b0}}};\n                            ^\n'
module wb_bfm_mod_transactor # (
    parameter                aw              = 32,
    parameter                dw              = 32,
    parameter                AUTORUN         = 1,
    parameter                MEM_HIGH        = 32'hffffffff,
    parameter                MEM_LOW         = 0,
    parameter                TRANSACTIONS_PARAM    = 1000,
    parameter                SEGMENT_SIZE    = 0,
    parameter                NUM_SEGMENTS    = 0,
    parameter                SUBTRANSACTIONS_PARAM = 100,
    parameter                VERBOSE         = 0,
    parameter                MAX_BURST_LEN   = 32,
    parameter                MAX_WAIT_STATES = 8,
    parameter                CLASSIC_PROB          = 33,
    parameter                CONST_BURST_PROB      = 33,
    parameter                INCR_BURST_PROB       = 34,
    parameter                SEED_PARAM            = 0
  ) (
    input 	      wb_clk_i,
    input 	      wb_rst_i,
    output [aw-1:0]   wb_adr_o,
    output [dw-1:0]   wb_dat_o,
    output [dw/8-1:0] wb_sel_o,
    output 	      wb_we_o,
    output 	      wb_cyc_o,
    output 	      wb_stb_o,
    output [2:0]      wb_cti_o,
    output [1:0]      wb_bte_o,
    input [dw-1:0]    wb_dat_i,
    input 	      wb_ack_i,
    input 	      wb_err_i,
    input 	      wb_rty_i,
    output reg 	      done
  );

  `include "wb_common_params.v"

   parameter ADR_LSB = $clog2(dw/8);

   integer 	      SEED            = SEED_PARAM;
   integer 	      TRANSACTIONS    = TRANSACTIONS_PARAM;
   integer 	      SUBTRANSACTIONS = SUBTRANSACTIONS_PARAM;

   integer cnt_cti_classic = 0;
   integer cnt_cti_const_burst = 0;
   integer cnt_cti_inc_burst = 0;
   integer cnt_cti_invalid = 0;

   integer cnt_bte_linear  = 0;
   integer cnt_bte_wrap_4  = 0;
   integer cnt_bte_wrap_8  = 0;
   integer cnt_bte_wrap_16 = 0;


  initial begin
    if ((CLASSIC_PROB + CONST_BURST_PROB + INCR_BURST_PROB) != 100) begin
      $display("ERROR: Wishbone Cycle Probability values must total 100. Current values total %0d:", (CLASSIC_PROB + CONST_BURST_PROB + INCR_BURST_PROB));
      $display("         Classic Cycle Probability                    : %0d", CLASSIC_PROB);
      $display("         Constant Address Burst Cycle Probability     : %0d", CONST_BURST_PROB);
      $display("         Incrementing Address Burst Cycle Probability : %0d", INCR_BURST_PROB);
      $finish(1);
    end
    if (AUTORUN) begin
       display_settings;
       run;
       display_stats;
       done = 1;
    end
  end

  wb_bfm_mod_master #(
		  .dw (dw),
    .MAX_BURST_LEN           (MAX_BURST_LEN),
    .MAX_WAIT_STATES         (MAX_WAIT_STATES),
    .VERBOSE                 (VERBOSE)
  ) bfm (
    .wb_clk_i                (wb_clk_i),
    .wb_rst_i                (wb_rst_i),
    .wb_adr_o                (wb_adr_o),
    .wb_dat_o                (wb_dat_o),
    .wb_sel_o                (wb_sel_o),
    .wb_we_o                 (wb_we_o),
    .wb_cyc_o                (wb_cyc_o),
    .wb_stb_o                (wb_stb_o),
    .wb_cti_o                (wb_cti_o),
    .wb_bte_o                (wb_bte_o),
    .wb_dat_i                (wb_dat_i),
    .wb_ack_i                (wb_ack_i),
    .wb_err_i                (wb_err_i),
    .wb_rty_i                (wb_rty_i)
  );

   function [aw-1:0] gen_adr;
      input integer low;
      input integer high;
      begin
          gen_adr = (low + ({$random(SEED)} % (high-low))) &  {{aw-ADR_LSB{1'b1}},{ADR_LSB{1'b0}}};
      end
   endfunction

   function [2:0] gen_cycle_type;
      input integer cycle_type_prob;
      begin
         if (cycle_type_prob <= CLASSIC_PROB) begin
            gen_cycle_type                = 3'b000;
         end else if (cycle_type_prob <= (CLASSIC_PROB + CONST_BURST_PROB)) begin
            gen_cycle_type                = CTI_CONST_BURST;
         end else begin
            gen_cycle_type                = CTI_INC_BURST;
         end
      end
   endfunction

   function [aw+3+2+32-1:0] gen_cycle_params;
      input [aw-1:0] adr_min_i;
      input [aw-1:0] adr_max_i;

      reg [aw-1:0]   adr_low;
      reg [aw-1:0]   adr_high;

      reg [aw-1:0]   address;
      reg [2:0]      cycle_type;
      reg [1:0]      burst_type;
      reg [31:0]     burst_length;

      begin
         adr_low  = 0;
         adr_high = 0;

         while((adr_high > adr_max_i) || (adr_low < adr_min_i) || (adr_high == adr_low)) begin
            address                = gen_adr(adr_min_i, adr_max_i);
            cycle_type             = gen_cycle_type({$random(SEED)} % 100);

	    burst_type = (cycle_type === CTI_INC_BURST) ? ({$random(SEED)} % 4) : 0;

	    burst_length = (cycle_type === CTI_CLASSIC) ? 1 :
			   ({$random(SEED)} % MAX_BURST_LEN) + 1;

              {adr_high, adr_low} = adr_range(address, burst_length, cycle_type, burst_type);
         end
	 gen_cycle_params = {address, cycle_type, burst_type, burst_length};
      end
   endfunction

`ifdef BROKEN_CLOG2
function integer clog2;
input integer in;
begin
	in = in - 1;
	for (clog2 = 0; in > 0; clog2=clog2+1)
		in = in >> 1;
end
endfunction
`endif

   function [2*aw-1:0] adr_range;
     input [aw-1:0]          adr_i;
     input [$clog2(MAX_BURST_LEN+1):0] len_i;
     input [2:0]             cti_i;
     input [1:0]             bte_i;
     parameter               bpw = dw/8;
     reg [aw-1:0]            adr;
     reg [aw-1:0]            adr_high;
     reg [aw-1:0]            adr_low;
      integer 		     shift;

   begin

`ifdef BROKEN_CLOG2
      shift = clog2(bpw);
`else
      shift = $clog2(bpw);
`endif
       adr                   = adr_i>>shift;
      if (cti_i === CTI_INC_BURST)
       case (bte_i)
         BTE_LINEAR : begin
           adr_high          = adr+len_i;
           adr_low           = adr;
         end
         BTE_WRAP_4   : begin
           adr_high          = adr[aw-1:2]*4+4;
           adr_low           = adr[aw-1:2]*4;
         end
         BTE_WRAP_8   : begin
           adr_high          = adr[aw-1:3]*8+8;
           adr_low           = adr[aw-1:3]*8;
         end
         BTE_WRAP_16  : begin
           adr_high          = adr[aw-1:4]*16+16;
           adr_low           = adr[aw-1:4]*16;
         end
         default : begin
           $display("%d : Illegal burst type (%b)", $time, bte_i);
           adr_range         = {2*aw{1'bx}};
         end
       endcase
      else begin
         adr_high          = adr+1;
         adr_low           = adr;
      end

      adr_high = (adr_high << shift)-1;
      adr_low  = adr_low << shift;
       adr_range             = {adr_high, adr_low};

   end
   endfunction



   task update_stats;
      input [2:0] cti;
      input [1:0] bte;
      input integer burst_length;
      begin
	 case (cti)
	   CTI_CLASSIC:     cnt_cti_classic = cnt_cti_classic + 1;
	   CTI_CONST_BURST: cnt_cti_const_burst = cnt_cti_const_burst + 1;
	   CTI_INC_BURST:   cnt_cti_inc_burst = cnt_cti_inc_burst + 1;
	   default:         cnt_cti_invalid = cnt_cti_invalid + 1;
	 endcase
	 if (cti === CTI_INC_BURST)
	   case (bte)
             BTE_LINEAR  : cnt_bte_linear  = cnt_bte_linear  + 1;
             BTE_WRAP_4  : cnt_bte_wrap_4  = cnt_bte_wrap_4  + 1;
             BTE_WRAP_8  : cnt_bte_wrap_8  = cnt_bte_wrap_8  + 1;
             BTE_WRAP_16 : cnt_bte_wrap_16 = cnt_bte_wrap_16 + 1;
	     default : $display("Invalid BTE %2b", bte);
	   endcase
      end
   endtask

   task display_stats;
      begin
	 $display("#################################");
	 $display("##### Cycle Type Statistics #####");
	 $display("#################################");
	 $display("Invalid cycle types   : %0d", cnt_cti_invalid);
	 $display("Classic cycles        : %0d", cnt_cti_classic);
	 $display("Constant burst cycles : %0d", cnt_cti_const_burst);
	 $display("Increment burst cycles: %0d", cnt_cti_inc_burst);
	 $display("   Linear bursts      : %0d", cnt_bte_linear);
	 $display("   4-beat bursts      : %0d", cnt_bte_wrap_4);
	 $display("   8-beat bursts      : %0d", cnt_bte_wrap_8);
	 $display("  16-beat bursts      : %0d", cnt_bte_wrap_16);
      end
   endtask

   task display_subtransaction;
      input [aw-1:0] address;
      input [2:0]    cycle_type;
      input [1:0]    burst_type;
      input integer  burst_length;
      input 	     wr;

      begin
	 if (VERBOSE > 0) begin
	    $write("  Subtransaction %0d.%0d ", transaction, subtransaction);
	    if (wr)
	      $write("(Write)");
	    else
	      $write("(Read) ");
	    $display(": Start Address: %h, Cycle Type: %b, Burst Type: %b, Burst Length: %0d", address, cycle_type, burst_type, burst_length);
	 end
      end
   endtask

   task set_transactions;
      input integer transactions_i;
      begin
	 TRANSACTIONS = transactions_i;
      end
   endtask

   task set_subtransactions;
      input integer transactions_i;
      begin
	 SUBTRANSACTIONS = transactions_i;
      end
   endtask



   task fill_wdata_array;
     input  [31:0]            burst_length;

     integer 		      word;

     begin

       for(word = 0; word <= burst_length-1; word = word + 1) begin
          bfm.write_data[word] = $random;
       end
     end
   endtask

   task display_settings;
      begin
	 $display("##############################################################");
	 $display("############# Wishbone Master Test Configuration #############");
	 $display("##############################################################");
	 $display("");
	 $display("%m:");
	 if (NUM_SEGMENTS > 0) begin
	    $display("  Number of segments    : %0d", NUM_SEGMENTS);
	    $display("  Segment size          : %h", SEGMENT_SIZE);
	    $display("  Memory High Address   : %h", MEM_LOW+NUM_SEGMENTS*SEGMENT_SIZE-1);
	    $display("  Memory Low Address    : %h", MEM_LOW);
	 end else begin
	    $display("  Memory High Address   : %h", MEM_HIGH);
	    $display("  Memory Low Address    : %h", MEM_LOW);
	 end
	 $display("  Transactions          : %0d", TRANSACTIONS);
	 $display("  Subtransactions       : %0d", SUBTRANSACTIONS);
	 $display("  Max Burst Length      : %0d", MAX_BURST_LEN);
	 $display("  Max Wait States       : %0d", MAX_WAIT_STATES);
	 $display("  Classic Cycle Prob    : %0d", CLASSIC_PROB);
	 $display("  Const Addr Cycle Prob : %0d", CONST_BURST_PROB);
	 $display("  Incr Addr Cycle Prob  : %0d", INCR_BURST_PROB);
	 $display("  Write Data            : Random");
	 $display("  Buffer Data           : Mirrors RAM");
	 $display("  $random Seed          : %0d", SEED);
	 $display("  Verbosity             : %0d", VERBOSE);
	 $display("");
	 $display("############# Starting Wishbone Master Tests...  #############");
	 $display("");
      end
   endtask

   integer                   burst_length;
   reg [1:0]                 burst_type;

   reg [2:0]                 cycle_type;

   integer                   transaction;
   integer                   subtransaction;

   reg                       err;

   reg [aw-1:0]              t_address;
   reg [aw-1:0]              t_adr_high;
   reg [aw-1:0]              t_adr_low;
   reg [aw-1:0]              st_address;
   reg                       st_type;

   integer 		     mem_lo;
   integer 		     mem_hi;
   integer 		     segment;

   task run;
      begin
	 if(TRANSACTIONS < 1) begin
	    $display("%0d transactions requested. Number of transactions must be set to > 0", TRANSACTIONS);
	    $finish;
	 end
      bfm.reset;
      done    = 0;
      st_type = 0;
      err     = 0;

      for(transaction = 1 ; transaction <= TRANSACTIONS; transaction = transaction + 1) begin
        if (VERBOSE>0)
          $display("%m : Transaction: %0d/%0d", transaction, TRANSACTIONS);
        else if(!(transaction%(SUBTRANSACTIONS/10)))
          $display("%m : Transaction: %0d/%0d", transaction, TRANSACTIONS);



        bfm.wait_states                 = {$random(SEED)} % (MAX_WAIT_STATES+1);
        if (VERBOSE>2)
          $display("  Number of Wait States for Transaction %0d is %0d", transaction, bfm.wait_states);


	 if (NUM_SEGMENTS > 0) begin
	    segment = {$random(SEED)} % NUM_SEGMENTS;
	    mem_lo =  MEM_LOW + segment    * SEGMENT_SIZE;
	    mem_hi =  MEM_LOW + (segment+1) * SEGMENT_SIZE - 1;
	 end else begin
	    mem_lo = MEM_LOW;
	    mem_hi = MEM_HIGH;
	 end



         t_adr_high  = 0;
         t_adr_low   = 0;
         while((t_adr_high > mem_hi) || (t_adr_low < mem_lo) || (t_adr_high == t_adr_low)) begin
            t_address                   = gen_adr(mem_lo, mem_hi);
            {t_adr_high,t_adr_low}      = adr_range(t_address, MAX_BURST_LEN, CTI_INC_BURST, BTE_LINEAR);
         end


         if (VERBOSE>0)
           $display("  Transaction %0d Initialisation (Write): Start Address: %h, Burst Length: %0d", transaction, t_address, MAX_BURST_LEN);


         fill_wdata_array(MAX_BURST_LEN);
         bfm.write_burst(t_address, t_address, {dw/8{1'b1}}, CTI_INC_BURST, BTE_LINEAR, MAX_BURST_LEN, err);
         update_stats(cycle_type, burst_type, burst_length);


         if (VERBOSE>0)
           $display("  Transaction %0d Initialisation (Read): Start Address: %h, Burst Length: %0d", transaction, t_address, MAX_BURST_LEN);
         bfm.read_burst_comp(t_address, t_address, {dw/8{1'b1}}, CTI_INC_BURST, BTE_LINEAR, MAX_BURST_LEN, err);
         update_stats(cycle_type, burst_type, burst_length);

         if (VERBOSE>0)
           $display("Transaction %0d initialisation ok (Start Address: %h, Cycle Type: %b, Burst Type: %b, Burst Length: %0d)", transaction, t_address, CTI_INC_BURST, BTE_LINEAR, MAX_BURST_LEN);


         for (subtransaction = 1; subtransaction <= SUBTRANSACTIONS ; subtransaction = subtransaction + 1) begin


            st_type                     = {$random(SEED)} % 2;

            {st_address, cycle_type, burst_type, burst_length} = gen_cycle_params(t_adr_low, t_adr_high);

            display_subtransaction(st_address, cycle_type, burst_type, burst_length, st_type);

            if (~st_type) begin


               bfm.read_burst_comp(t_address, st_address, {dw/8{1'b1}}, cycle_type, burst_type, burst_length, err);

            end else begin


               fill_wdata_array(burst_length);
               bfm.write_burst(t_address, st_address, {dw/8{1'b1}}, cycle_type, burst_type, burst_length, err);

            end
            update_stats(cycle_type, burst_type, burst_length);
         end


         if (VERBOSE>0)
           $display("Transaction %0d Buffer Consistency Check: Start Address: %h, Burst Length: %0d", transaction, t_address, MAX_BURST_LEN);
         bfm.read_burst_comp(t_address, t_address, 4'hf, CTI_INC_BURST, BTE_LINEAR, MAX_BURST_LEN, err);

         if (VERBOSE>0)
           $display("Transaction %0d Completed Successfully", transaction);


         bfm.clear_buffer_data;
      end
      done = 1;
   end
   endtask

endmodule
module wb_bfm_mod_transactor # (
    parameter                aw              = 32,
    parameter                dw              = 32,
    parameter                AUTORUN         = 1,
    parameter                MEM_HIGH        = 32'hffffffff,
    parameter                MEM_LOW         = 0,
    parameter                TRANSACTIONS_PARAM    = 1000,
    parameter                SEGMENT_SIZE    = 0,
    parameter                NUM_SEGMENTS    = 0,
    parameter                SUBTRANSACTIONS_PARAM = 100,
    parameter                VERBOSE         = 0,
    parameter                MAX_BURST_LEN   = 32,
    parameter                MAX_WAIT_STATES = 8,
    parameter                CLASSIC_PROB          = 33,
    parameter                CONST_BURST_PROB      = 33,
    parameter                INCR_BURST_PROB       = 34,
    parameter                SEED_PARAM            = 0
  ) (
    input 	      wb_clk_i,
    input 	      wb_rst_i,
    output [aw-1:0]   wb_adr_o,
    output [dw-1:0]   wb_dat_o,
    output [dw/8-1:0] wb_sel_o,
    output 	      wb_we_o,
    output 	      wb_cyc_o,
    output 	      wb_stb_o,
    output [2:0]      wb_cti_o,
    output [1:0]      wb_bte_o,
    input [dw-1:0]    wb_dat_i,
    input 	      wb_ack_i,
    input 	      wb_err_i,
    input 	      wb_rty_i,
    output reg 	      done
  );


  `include "wb_common_params.v"

   parameter ADR_LSB = $clog2(dw/8);

   integer 	      SEED            = SEED_PARAM;
   integer 	      TRANSACTIONS    = TRANSACTIONS_PARAM;
   integer 	      SUBTRANSACTIONS = SUBTRANSACTIONS_PARAM;

   integer cnt_cti_classic = 0;
   integer cnt_cti_const_burst = 0;
   integer cnt_cti_inc_burst = 0;
   integer cnt_cti_invalid = 0;

   integer cnt_bte_linear  = 0;
   integer cnt_bte_wrap_4  = 0;
   integer cnt_bte_wrap_8  = 0;
   integer cnt_bte_wrap_16 = 0;


  initial begin
    if ((CLASSIC_PROB + CONST_BURST_PROB + INCR_BURST_PROB) != 100) begin
      $display("ERROR: Wishbone Cycle Probability values must total 100. Current values total %0d:", (CLASSIC_PROB + CONST_BURST_PROB + INCR_BURST_PROB));
      $display("         Classic Cycle Probability                    : %0d", CLASSIC_PROB);
      $display("         Constant Address Burst Cycle Probability     : %0d", CONST_BURST_PROB);
      $display("         Incrementing Address Burst Cycle Probability : %0d", INCR_BURST_PROB);
      $finish(1);
    end
    if (AUTORUN) begin
       display_settings;
       run;
       display_stats;
       done = 1;
    end
  end

  wb_bfm_mod_master #(
		  .dw (dw),
    .MAX_BURST_LEN           (MAX_BURST_LEN),
    .MAX_WAIT_STATES         (MAX_WAIT_STATES),
    .VERBOSE                 (VERBOSE)
  ) bfm (
    .wb_clk_i                (wb_clk_i),
    .wb_rst_i                (wb_rst_i),
    .wb_adr_o                (wb_adr_o),
    .wb_dat_o                (wb_dat_o),
    .wb_sel_o                (wb_sel_o),
    .wb_we_o                 (wb_we_o),
    .wb_cyc_o                (wb_cyc_o),
    .wb_stb_o                (wb_stb_o),
    .wb_cti_o                (wb_cti_o),
    .wb_bte_o                (wb_bte_o),
    .wb_dat_i                (wb_dat_i),
    .wb_ack_i                (wb_ack_i),
    .wb_err_i                (wb_err_i),
    .wb_rty_i                (wb_rty_i)
  );

   function [aw-1:0] gen_adr;
      input integer low;
      input integer high;
      begin
          gen_adr = (low + ({$random(SEED)} % (high-low))) &  {{aw-ADR_LSB{1'b1}},{ADR_LSB{1'b0}}};
      end
   endfunction

   function [2:0] gen_cycle_type;
      input integer cycle_type_prob;
      begin
         if (cycle_type_prob <= CLASSIC_PROB) begin
            gen_cycle_type                = 3'b000;
         end else if (cycle_type_prob <= (CLASSIC_PROB + CONST_BURST_PROB)) begin
            gen_cycle_type                = CTI_CONST_BURST;
         end else begin
            gen_cycle_type                = CTI_INC_BURST;
         end
      end
   endfunction

   function [aw+3+2+32-1:0] gen_cycle_params;
      input [aw-1:0] adr_min_i;
      input [aw-1:0] adr_max_i;

      reg [aw-1:0]   adr_low;
      reg [aw-1:0]   adr_high;

      reg [aw-1:0]   address;
      reg [2:0]      cycle_type;
      reg [1:0]      burst_type;
      reg [31:0]     burst_length;

      begin
         adr_low  = 0;
         adr_high = 0;

         while((adr_high > adr_max_i) || (adr_low < adr_min_i) || (adr_high == adr_low)) begin
            address                = gen_adr(adr_min_i, adr_max_i);
            cycle_type             = gen_cycle_type({$random(SEED)} % 100);

	    burst_type = (cycle_type === CTI_INC_BURST) ? ({$random(SEED)} % 4) : 0;

	    burst_length = (cycle_type === CTI_CLASSIC) ? 1 :
			   ({$random(SEED)} % MAX_BURST_LEN) + 1;

              {adr_high, adr_low} = adr_range(address, burst_length, cycle_type, burst_type);
         end
	 gen_cycle_params = {address, cycle_type, burst_type, burst_length};
      end
   endfunction

`ifdef BROKEN_CLOG2
function integer clog2;
input integer in;
begin
	in = in - 1;
	for (clog2 = 0; in > 0; clog2=clog2+1)
		in = in >> 1;
end
endfunction
`endif

   function [2*aw-1:0] adr_range;
     input [aw-1:0]          adr_i;
     input [$clog2(MAX_BURST_LEN+1):0] len_i;
     input [2:0]             cti_i;
     input [1:0]             bte_i;
     parameter               bpw = dw/8;
     reg [aw-1:0]            adr;
     reg [aw-1:0]            adr_high;
     reg [aw-1:0]            adr_low;
      integer 		     shift;

   begin

`ifdef BROKEN_CLOG2
      shift = clog2(bpw);
`else
      shift = $clog2(bpw);
`endif
       adr                   = adr_i>>shift;
      if (cti_i === CTI_INC_BURST)
       case (bte_i)
         BTE_LINEAR : begin
           adr_high          = adr+len_i;
           adr_low           = adr;
         end
         BTE_WRAP_4   : begin
           adr_high          = adr[aw-1:2]*4+4;
           adr_low           = adr[aw-1:2]*4;
         end
         BTE_WRAP_8   : begin
           adr_high          = adr[aw-1:3]*8+8;
           adr_low           = adr[aw-1:3]*8;
         end
         BTE_WRAP_16  : begin
           adr_high          = adr[aw-1:4]*16+16;
           adr_low           = adr[aw-1:4]*16;
         end
         default : begin
           $display("%d : Illegal burst type (%b)", $time, bte_i);
           adr_range         = {2*aw{1'bx}};
         end
       endcase
      else begin
         adr_high          = adr+1;
         adr_low           = adr;
      end

      adr_high = (adr_high << shift)-1;
      adr_low  = adr_low << shift;
       adr_range             = {adr_high, adr_low};

   end
   endfunction



   task update_stats;
      input [2:0] cti;
      input [1:0] bte;
      input integer burst_length;
      begin
	 case (cti)
	   CTI_CLASSIC:     cnt_cti_classic = cnt_cti_classic + 1;
	   CTI_CONST_BURST: cnt_cti_const_burst = cnt_cti_const_burst + 1;
	   CTI_INC_BURST:   cnt_cti_inc_burst = cnt_cti_inc_burst + 1;
	   default:         cnt_cti_invalid = cnt_cti_invalid + 1;
	 endcase
	 if (cti === CTI_INC_BURST)
	   case (bte)
             BTE_LINEAR  : cnt_bte_linear  = cnt_bte_linear  + 1;
             BTE_WRAP_4  : cnt_bte_wrap_4  = cnt_bte_wrap_4  + 1;
             BTE_WRAP_8  : cnt_bte_wrap_8  = cnt_bte_wrap_8  + 1;
             BTE_WRAP_16 : cnt_bte_wrap_16 = cnt_bte_wrap_16 + 1;
	     default : $display("Invalid BTE %2b", bte);
	   endcase
      end
   endtask

   task display_stats;
      begin
	 $display("#################################");
	 $display("##### Cycle Type Statistics #####");
	 $display("#################################");
	 $display("Invalid cycle types   : %0d", cnt_cti_invalid);
	 $display("Classic cycles        : %0d", cnt_cti_classic);
	 $display("Constant burst cycles : %0d", cnt_cti_const_burst);
	 $display("Increment burst cycles: %0d", cnt_cti_inc_burst);
	 $display("   Linear bursts      : %0d", cnt_bte_linear);
	 $display("   4-beat bursts      : %0d", cnt_bte_wrap_4);
	 $display("   8-beat bursts      : %0d", cnt_bte_wrap_8);
	 $display("  16-beat bursts      : %0d", cnt_bte_wrap_16);
      end
   endtask

   task display_subtransaction;
      input [aw-1:0] address;
      input [2:0]    cycle_type;
      input [1:0]    burst_type;
      input integer  burst_length;
      input 	     wr;

      begin
	 if (VERBOSE > 0) begin
	    $write("  Subtransaction %0d.%0d ", transaction, subtransaction);
	    if (wr)
	      $write("(Write)");
	    else
	      $write("(Read) ");
	    $display(": Start Address: %h, Cycle Type: %b, Burst Type: %b, Burst Length: %0d", address, cycle_type, burst_type, burst_length);
	 end
      end
   endtask

   task set_transactions;
      input integer transactions_i;
      begin
	 TRANSACTIONS = transactions_i;
      end
   endtask

   task set_subtransactions;
      input integer transactions_i;
      begin
	 SUBTRANSACTIONS = transactions_i;
      end
   endtask



   task fill_wdata_array;
     input  [31:0]            burst_length;

     integer 		      word;

     begin

       for(word = 0; word <= burst_length-1; word = word + 1) begin
          bfm.write_data[word] = $random;
       end
     end
   endtask

   task display_settings;
      begin
	 $display("##############################################################");
	 $display("############# Wishbone Master Test Configuration #############");
	 $display("##############################################################");
	 $display("");
	 $display("%m:");
	 if (NUM_SEGMENTS > 0) begin
	    $display("  Number of segments    : %0d", NUM_SEGMENTS);
	    $display("  Segment size          : %h", SEGMENT_SIZE);
	    $display("  Memory High Address   : %h", MEM_LOW+NUM_SEGMENTS*SEGMENT_SIZE-1);
	    $display("  Memory Low Address    : %h", MEM_LOW);
	 end else begin
	    $display("  Memory High Address   : %h", MEM_HIGH);
	    $display("  Memory Low Address    : %h", MEM_LOW);
	 end
	 $display("  Transactions          : %0d", TRANSACTIONS);
	 $display("  Subtransactions       : %0d", SUBTRANSACTIONS);
	 $display("  Max Burst Length      : %0d", MAX_BURST_LEN);
	 $display("  Max Wait States       : %0d", MAX_WAIT_STATES);
	 $display("  Classic Cycle Prob    : %0d", CLASSIC_PROB);
	 $display("  Const Addr Cycle Prob : %0d", CONST_BURST_PROB);
	 $display("  Incr Addr Cycle Prob  : %0d", INCR_BURST_PROB);
	 $display("  Write Data            : Random");
	 $display("  Buffer Data           : Mirrors RAM");
	 $display("  $random Seed          : %0d", SEED);
	 $display("  Verbosity             : %0d", VERBOSE);
	 $display("");
	 $display("############# Starting Wishbone Master Tests...  #############");
	 $display("");
      end
   endtask

   integer                   burst_length;
   reg [1:0]                 burst_type;

   reg [2:0]                 cycle_type;

   integer                   transaction;
   integer                   subtransaction;

   reg                       err;

   reg [aw-1:0]              t_address;
   reg [aw-1:0]              t_adr_high;
   reg [aw-1:0]              t_adr_low;
   reg [aw-1:0]              st_address;
   reg                       st_type;

   integer 		     mem_lo;
   integer 		     mem_hi;
   integer 		     segment;

   task run;
      begin
	 if(TRANSACTIONS < 1) begin
	    $display("%0d transactions requested. Number of transactions must be set to > 0", TRANSACTIONS);
	    $finish;
	 end
      bfm.reset;
      done    = 0;
      st_type = 0;
      err     = 0;

      for(transaction = 1 ; transaction <= TRANSACTIONS; transaction = transaction + 1) begin
        if (VERBOSE>0)
          $display("%m : Transaction: %0d/%0d", transaction, TRANSACTIONS);
        else if(!(transaction%(SUBTRANSACTIONS/10)))
          $display("%m : Transaction: %0d/%0d", transaction, TRANSACTIONS);



        bfm.wait_states                 = {$random(SEED)} % (MAX_WAIT_STATES+1);
        if (VERBOSE>2)
          $display("  Number of Wait States for Transaction %0d is %0d", transaction, bfm.wait_states);


	 if (NUM_SEGMENTS > 0) begin
	    segment = {$random(SEED)} % NUM_SEGMENTS;
	    mem_lo =  MEM_LOW + segment    * SEGMENT_SIZE;
	    mem_hi =  MEM_LOW + (segment+1) * SEGMENT_SIZE - 1;
	 end else begin
	    mem_lo = MEM_LOW;
	    mem_hi = MEM_HIGH;
	 end



         t_adr_high  = 0;
         t_adr_low   = 0;
         while((t_adr_high > mem_hi) || (t_adr_low < mem_lo) || (t_adr_high == t_adr_low)) begin
            t_address                   = gen_adr(mem_lo, mem_hi);
            {t_adr_high,t_adr_low}      = adr_range(t_address, MAX_BURST_LEN, CTI_INC_BURST, BTE_LINEAR);
         end


         if (VERBOSE>0)
           $display("  Transaction %0d Initialisation (Write): Start Address: %h, Burst Length: %0d", transaction, t_address, MAX_BURST_LEN);


         fill_wdata_array(MAX_BURST_LEN);
         bfm.write_burst(t_address, t_address, {dw/8{1'b1}}, CTI_INC_BURST, BTE_LINEAR, MAX_BURST_LEN, err);
         update_stats(cycle_type, burst_type, burst_length);


         if (VERBOSE>0)
           $display("  Transaction %0d Initialisation (Read): Start Address: %h, Burst Length: %0d", transaction, t_address, MAX_BURST_LEN);
         bfm.read_burst_comp(t_address, t_address, {dw/8{1'b1}}, CTI_INC_BURST, BTE_LINEAR, MAX_BURST_LEN, err);
         update_stats(cycle_type, burst_type, burst_length);

         if (VERBOSE>0)
           $display("Transaction %0d initialisation ok (Start Address: %h, Cycle Type: %b, Burst Type: %b, Burst Length: %0d)", transaction, t_address, CTI_INC_BURST, BTE_LINEAR, MAX_BURST_LEN);


         for (subtransaction = 1; subtransaction <= SUBTRANSACTIONS ; subtransaction = subtransaction + 1) begin


            st_type                     = {$random(SEED)} % 2;

            {st_address, cycle_type, burst_type, burst_length} = gen_cycle_params(t_adr_low, t_adr_high);

            display_subtransaction(st_address, cycle_type, burst_type, burst_length, st_type);

            if (~st_type) begin


               bfm.read_burst_comp(t_address, st_address, {dw/8{1'b1}}, cycle_type, burst_type, burst_length, err);

            end else begin


               fill_wdata_array(burst_length);
               bfm.write_burst(t_address, st_address, {dw/8{1'b1}}, cycle_type, burst_type, burst_length, err);

            end
            update_stats(cycle_type, burst_type, burst_length);
         end


         if (VERBOSE>0)
           $display("Transaction %0d Buffer Consistency Check: Start Address: %h, Burst Length: %0d", transaction, t_address, MAX_BURST_LEN);
         bfm.read_burst_comp(t_address, t_address, 4'hf, CTI_INC_BURST, BTE_LINEAR, MAX_BURST_LEN, err);

         if (VERBOSE>0)
           $display("Transaction %0d Completed Successfully", transaction);


         bfm.clear_buffer_data;
      end
      done = 1;
   end
   endtask

endmodule