test012.v 7.79 KB
//
// test012	Refresh test
//

// The refresh timing checks wouldn't survive in a rigorous random environment,
// but I've included them here so we can be aware of if it it changes.

`define	CLEAN_REFRESH_COUNT	40
`define	DIRTY_REFRESH_COUNT	42

task test012;
  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;
  reg		[3:0] nibble;
  integer	i, j, k;
  begin

    // Write known data values to all banks, pages
    nibble = 0;
    for (i = 0; i < `NUM_RAMS; i = i + 1)
    begin
      for (j = 0; j < `NUM_BANKS; j = j + 1)
      begin
        for (k = 0; k < `NUM_PAGES; k = k + 1)
	begin
	  address = (i * `RAM_SIZE) + (j * `BANK_SIZE) + (k * `PAGE_SIZE);
	  cbus_dma_write(`DMA_UNMASKED, `DMA_UP, address,
			 BUS_DEVICE_MI, -2, 8);
	  dbus_put_data({16{nibble}}, {2{nibble}}, -2);

	  cbus_dma_read(`DMA_NOSUBBLOCK, `DMA_UP, address,
			BUS_DEVICE_MI, 3, 8);
	  dbus_get_data(actual_d_data, actual_e_data, 3);

	  check_data("test012", {16{nibble}}, actual_d_data,
				{2{nibble}}, actual_e_data);

	  nibble = nibble + 1;
	end
      end
    end

    @(posedge clock);

    fork
      test012_cmd;
      test012_data;
    join
  end
endtask

task test012_cmd;
  reg		[CBUS_DATA_SIZE-1:0] address;
  integer	i, j, k;
  begin

    // Check refreshes on dirty banks

    for (i = 0; i < `NUM_BANKS; i = i + 1)
    begin

      // Write known data values and dirty all banks

      address = 0;
      for (j = 0; j < `NUM_RAMS; j = j + 1)
      begin
	for (k = 0; k < `NUM_BANKS; k = k + 1)
	begin
	  cbus_dma_write(`DMA_UNMASKED, `DMA_UP, address, BUS_DEVICE_MI, -2, 8);
	  address = address + `BANK_SIZE;
	end
      end

      // Refresh on bank i

      cbus_refresh;
      test012_check_refresh_count(`DIRTY_REFRESH_COUNT);

      // Check locations

      address = 0;
      for (j = 0; j < `NUM_RAMS; j = j + 1)
      begin
	for (k = 0; k < `NUM_BANKS; k = k + 1)
	begin
	  cbus_dma_read(`DMA_NOSUBBLOCK, `DMA_UP, address, BUS_DEVICE_MI, 3, 8);
	  address = address + `BANK_SIZE;
	end
      end
    end

    // Clean the banks by reading another page on that bank

    address = 0 + `PAGE_SIZE;
    for (i = 0; i < `NUM_RAMS; i = i + 1)
    begin
      for (j = 0; j < `NUM_BANKS; j = j + 1)
      begin
	  cbus_dma_read(`DMA_NOSUBBLOCK, `DMA_UP, address, BUS_DEVICE_MI, 3, 8);
	  address = address + `BANK_SIZE;
      end
    end

    // Check refreshes on clean banks

    for (i = 0; i < `NUM_BANKS; i = i + 1)
    begin

      // Refresh on bank i

      cbus_refresh;
      test012_check_refresh_count(`CLEAN_REFRESH_COUNT);

      address = 0;
      for (j = 0; j < `NUM_RAMS; j = j + 1)
      begin
	for (k = 0; k < `NUM_BANKS; k = k + 1)
	begin
	  cbus_dma_read(`DMA_NOSUBBLOCK, `DMA_UP, address, BUS_DEVICE_MI, 3, 8);
	  address = address + `BANK_SIZE;
	end
      end
    end

    // Check refreshes on mixed clean/dirty banks

    for (i = 0; i < `NUM_BANKS; i = i + 1)
    begin

      // Dirty bank i

      address = i * `BANK_SIZE;

      for (j = 0; j < `NUM_RAMS; j = j + 1)
      begin
	cbus_dma_write(`DMA_UNMASKED, `DMA_UP, address, BUS_DEVICE_MI, -2, 8);
	cbus_dma_read(`DMA_NOSUBBLOCK, `DMA_UP, address, BUS_DEVICE_MI, 3, 8);
	address = address + `RAM_SIZE;
      end

      //
      // refresh twice; one each time a different bank is clean or dirty.
      // the second time we are overlapping the commands so we see
      // the actual refresh cycle time (thus the addition of 10).
      //

      if (i == 0)
      begin
	cbus_refresh;
	test012_check_refresh_count(`DIRTY_REFRESH_COUNT);
	cbus_refresh;
	test012_check_refresh_count(10 + `CLEAN_REFRESH_COUNT);
      end
      else
      begin
	cbus_refresh;
	test012_check_refresh_count(`CLEAN_REFRESH_COUNT);
	cbus_refresh;
	test012_check_refresh_count(10 + `DIRTY_REFRESH_COUNT);
      end
    end


    // Start a refresh right before writes of varying sizes

    for (i = 0; i < `NUM_BANKS; i = i + 1)
    begin
      address = 0;
      for (j = 1; j <= `MAX_TRANSFER; j = j + 1)
      begin
	cbus_refresh;
	cbus_dma_write(`DMA_UNMASKED, `DMA_UP, address, BUS_DEVICE_MI, -2, j*8);
	address = address + (j*8);
      end

      address = 0;
      for (j = 1; j <= `MAX_TRANSFER; j = j + 1)
      begin
	cbus_dma_read(`DMA_NOSUBBLOCK, `DMA_UP, address, BUS_DEVICE_MI, 3, j*8);
	address = address + (j*8);
      end
      // switch over to bank 1

      if (i == 0)
	cbus_refresh;
    end
  end
endtask

task test012_data;
  reg		[CBUS_DATA_SIZE-1:0] address;
  reg		[3:0] nibble;
  integer	i, j, k;
  begin

    // Check refreshes on dirty banks

    for (i = 0; i < `NUM_BANKS; i = i + 1)
    begin
      nibble = 0;
      for (j = 0; j < `NUM_RAMS; j = j + 1)
      begin
	for (k = 0; k < `NUM_BANKS; k = k + 1)
	begin
	  while (!dma_start)
	    @(posedge clock);

	  dbus_data_out <= {16{nibble}};
	  ebus_data_out <= {2{nibble}};

	  @(posedge clock);
	  nibble = nibble + `NUM_PAGES;
        end
      end

      check_refresh("test012");

      nibble = 0;
      for (j = 0; j < `NUM_RAMS; j = j + 1)
      begin
	for (k = 0; k < `NUM_BANKS; k = k + 1)
	begin
	  while (!dma_start)
	    @(posedge clock);

	  check_data("test012", {16{nibble}}, dbus_data_reg,
				{2{nibble}},  ebus_data_reg);
	  @(posedge clock);
	  nibble = nibble + `NUM_PAGES;
	end
      end
    end

    // Clean the banks by reading another page on that bank

    address = 0 + `PAGE_SIZE;
    nibble = 1;
    for (i = 0; i < `NUM_RAMS; i = i + 1)
    begin
      for (j = 0; j < `NUM_BANKS; j = j + 1)
      begin
	  while (!dma_start)
	    @(posedge clock);

	  check_data("test012", {16{nibble}}, dbus_data_reg,
				{2{nibble}},  ebus_data_reg);
	  @(posedge clock);
	  nibble = nibble + `NUM_PAGES;
      end
    end

    // Check refreshes on clean banks

    for (i = 0; i < `NUM_BANKS; i = i + 1)
    begin
      check_refresh("test012");

      nibble = 0;
      for (j = 0; j < `NUM_RAMS; j = j + 1)
      begin
	for (k = 0; k < `NUM_BANKS; k = k + 1)
	begin
	  while (!dma_start)
	    @(posedge clock);

	  check_data("test012", {16{nibble}}, dbus_data_reg,
				{2{nibble}},  ebus_data_reg);
	  @(posedge clock);
	  nibble = nibble + `NUM_PAGES;
	end
      end
    end

    // Check refreshes on mixed clean/dirty banks
    for (i = 0; i < `NUM_BANKS; i = i + 1)
    begin

      // Dirty bank i

      nibble = i * `NUM_PAGES;

      for (j = 0; j < `NUM_RAMS; j = j + 1)
      begin
	while (!dma_start)
	  @(posedge clock);

	dbus_data_out <= {16{nibble}};
	ebus_data_out <= {2{nibble}};

	@(posedge clock);

	while (!dma_start)
	  @(posedge clock);

	check_data("test012", {16{nibble}}, dbus_data_reg,
				{2{nibble}},  ebus_data_reg);
	@(posedge clock);

	nibble = nibble + (`NUM_BANKS * `NUM_PAGES);
      end
    end

    // Start a refresh right before writes of varying sizes

    for (i = 0; i < `NUM_BANKS; i = i + 1)
    begin
      address = 0;
      for (j = 1; j <= `MAX_TRANSFER; j = j + 1)
      begin
	check_refresh("test012");

	while (!dma_start)
	  @(posedge clock);

	for (k = 0; k < j; k = k + 1)
	begin
	  dbus_data_out <= {2{address}};
	  ebus_data_out <= address[10:3];
	  @(posedge clock);
	  address = address + 8;
	end
      end

      address = 0;
      for (j = 1; j <= `MAX_TRANSFER; j = j + 1)
      begin
	while (!dma_start)
	  @(posedge clock);

	for (k = 0; k < j; k = k + 1)
	begin
	  check_data("test012", {2{address}}, dbus_data_reg,
				address[10:3], ebus_data_reg);
	  @(posedge clock);
	  address = address + 8;
	end
      end
    end
  end
endtask

task test012_check_refresh_count;
  input	[31:0]	expected_count;
  integer	actual_count;
  begin
    actual_count = 0;
    while (!dma_ready)
    begin
      actual_count = actual_count + 1;
      @(posedge clock);
    end
    if (expected_count !== actual_count)
    begin
      $write("test012: refresh clock count expected: %d was: %d at time %d\n",
	     expected_count, actual_count, $time);
      errors = errors + 1;
    end
  end
endtask