test015.v 5.16 KB
//
// test015	Perform random DMA reads and writes with various modes
//

`define	MAX_TRANSACT	100

integer		test015_address_tab  [0:`MAX_TRANSACT-1];
integer		test015_read_tab     [0:`MAX_TRANSACT-1];
integer		test015_refresh_tab  [0:`MAX_TRANSACT-1];
integer		test015_subblock_tab [0:`MAX_TRANSACT-1];
integer		test015_masked_tab   [0:`MAX_TRANSACT-1];
integer		test015_down_tab     [0:`MAX_TRANSACT-1];
integer		test015_length_tab   [0:`MAX_TRANSACT-1];
integer		test015_delay_tab    [0:`MAX_TRANSACT-1];

task test015;
  begin
    test015_initialize;
    test015_create_tab;
    test015_print_tab;
    fork
      test015_cmd;
      test015_data;
      test015_check;
    join
  end
endtask

task test015_initialize;
  reg		[CBUS_DATA_SIZE-1:0] address;
  reg		[DBUS_DATA_SIZE-1:0] actual_d_data;
  reg		[EBUS_DATA_SIZE-1:0] actual_e_data;
  integer	i, j, k;

  begin
    for (i = 0; i < (`NUM_BANKS * `NUM_RAMS); i = i + 1)
    begin
      for (j = 0; j < `NUM_PAGES; j =  j + 1)
      begin
	address = (i * `BANK_SIZE) + (j * `PAGE_SIZE);
	for (k = 0; k < `MAX_TRANSFER; k = k + 1)
	begin
	  cbus_dma_write(`DMA_UNMASKED, `DMA_UP, address, BUS_DEVICE_MI, -2, 8);
	  dbus_put_data({2{address}}, address[10:3], -2);

	  address = address + 8;
	end
      end
    end
  end
endtask

task test015_create_tab;
  integer	i, address, length, delay;

  begin
    for (i = 0; i < `MAX_TRANSACT; i = i + 1)
    begin
      test015_read_tab[i] = $random & 'b1;
      if (test015_read_tab[i])
      begin 
	test015_subblock_tab[i] = $random & 'b1;
	if (test015_subblock_tab[i])
	  if ($random & 1'b1)
	    length = 2;
	  else
	    length = 4;
	else
	  length = $random & 'hf;
          delay = 3;
      end
      else
      begin
	test015_masked_tab[i] = $random & 'b1;
	if (test015_masked_tab[i])
	  length = $random & 'h7;
	else
	  length = $random & 'hf;
	delay = -2;
      end

      test015_refresh_tab[i] = $random & 'h3;
      test015_delay_tab[i] = delay;

      if (length == 0)
	length = 1;
      test015_length_tab[i] = length; 

      if (test015_subblock_tab[i])
      begin
	test015_down_tab[i] = 0;
	address = ($random & 'h3) * 8;
      end
      else
      begin
        test015_down_tab[i] = $random & 'b1;
	if (test015_down_tab[i])
	  address = (`MAX_TRANSFER - 1) * 8;
	else
	  address = 0;
      end
      address = address + (($random & 'h3) * `BANK_SIZE);
      test015_address_tab[i] = address + (($random & 'h1) * `PAGE_SIZE);
    end
  end
endtask

task test015_print_tab;
  integer	i;

  begin
    for (i = 0; i < `MAX_TRANSACT; i = i + 1)
    begin
      $write("%3d. read %1d refresh %1d address 0x%x\n",
	i, test015_read_tab[i], test015_refresh_tab[i], test015_address_tab[i]);

      $write("     subblock %1d masked %1d down %1d delay %d length 0x%2x\n",
	test015_subblock_tab[i], test015_masked_tab[i],
	test015_down_tab[i], test015_delay_tab[i], test015_length_tab[i]);
    end
  end
endtask

task test015_cmd;
  reg		[CBUS_DATA_SIZE-1:0] address;
  integer	i;

  begin
    address = 0;
    for (i = 0; i < `MAX_TRANSACT; i = i + 1)
    begin
      if (test015_refresh_tab[i] == 0)
	cbus_refresh;

      if (test015_read_tab[i])
        cbus_dma_read(test015_subblock_tab[i], test015_down_tab[i],
		      test015_address_tab[i], BUS_DEVICE_MI,
		      test015_delay_tab[i], test015_length_tab[i] * 8);
      else
        cbus_dma_write(test015_masked_tab[i], test015_down_tab[i],
		       test015_address_tab[i], BUS_DEVICE_MI,
		       test015_delay_tab[i], test015_length_tab[i] * 8);
    end
  end
endtask

task test015_data;
  reg		[CBUS_DATA_SIZE-1:0] address;
  integer	i, j, k, read, masked, subblock, down, delay, length;

  begin
    for (i = 0; i < `MAX_TRANSACT; i = i + 1)
    begin
      address  = test015_address_tab[i];
      read     = test015_read_tab[i];
      masked   = test015_masked_tab[i];
      subblock = test015_subblock_tab[i];
      down     = test015_down_tab[i];
      delay    = test015_delay_tab[i];
      length   = test015_length_tab[i];

      if (test015_refresh_tab[i] == 0)
	check_refresh("test015");

      while (!dma_start)
	@(posedge clock);

      if (read)
	repeat(3-delay)
	  @(posedge clock);
      else
	repeat(-(2+delay))
	  @(posedge clock);

      if (!read && masked)
      begin
	dbus_data_out <= 64'hffffffff_ffffffff;
	ebus_data_out <= 8'hff;
	  @(posedge clock);
      end

      if (subblock)
	k = address / 8;

      for (j = 0; j < length; j = j + 1)
      begin
	if (read)
	begin
	  if (subblock)
	    address = (k^j) *8;
	  check_data("test015", {2{address}}, dbus_data_reg,
				address[10:3], ebus_data_reg);
	end
	else
	begin
	  dbus_data_out <= {2{address}};
	  ebus_data_out <= address[10:3];
	end
	@(posedge clock);
	if (down)
	  address = address - 8;
	else
	  address = address + 8;
      end
    end
  end
endtask

task test015_check;
  integer	i, j, length;

  begin

    for (i = 0; i < `MAX_TRANSACT; i = i + 1)
    begin
      length   = test015_length_tab[i];

      while (!dma_start)
	@(posedge clock);

      for (j = 0; j < (length-1); j = j + 1)
	@(posedge clock);

      if (!dma_last)
      begin
	$write("test015: dma_last expected: %d", 1'b1,
	       " was: %d", dma_last, " at time", $time, "\n");
	errors = errors + 1;
      end
      @(posedge clock);
    end
  end
endtask