sp_tests.v 4.17 KB
// sp_tests.v v1 Frank Berndt
// sp tests;
// :set tabstop=4

`define	SP_NA_DMEM	12		// # of sp dmem address bits;
`define	SP_NA_IMEM	12		// # of sp imem address bits;

// spin on sp io full;

task sp_spin_iofull;
	reg [31:0] rdata;			// read data;
	begin
		sread(`SP_STATUS, `CPU_SIZE_4, rdata);
		while(rdata[4] === 1)
			sread(`SP_STATUS, `CPU_SIZE_4, rdata);
		//XXX timeout;
	end
endtask

// targeted test for single requests to sp memories;

task sp_mem_sglwalk;
	input [31:0] space;			// address space;
	input [5:0] nabits;			// # of address bits;
	input reqspc;				// use random request spacing;
	reg [31:0] addr;			// address;
	reg [31:0] amask;			// address mask;
	reg [31:0] saddr [2:29];	// single address;
	reg [31:0] sdata [2:29];	// single data;
	integer n;
	begin
		// test writes;

		$display("test: %M: space 0x%h, spacing %b", space, reqspc);
		amask = 32'hffff_ffff >> (32 - nabits);
		amask[1:0] = 2'b00;

		// walk one address bit;
		// randomize request spacing and data;

		$display("test: %M: write, addr walking 1");
		for(n = 2; n < nabits; n = n + 1) begin
			addr = space | (1 << n);
			addr[1:0] = 2'b00;
			saddr[n] = addr;
			sdata[n] = $random;
			if(reqspc)
				req_spacing($random);
			swrite(addr, `CPU_SIZE_4, sdata[n]);
			sp_spin_iofull;
		end

		$display("test: %M: write, addr walking 0");
		for(n = 2; n < nabits; n = n + 1) begin
			addr = saddr[n];
			addr = addr ^ amask;
			if(reqspc)
				req_spacing($random);
			swrite(addr, `CPU_SIZE_4, ~sdata[n]);
			sp_spin_iofull;
		end

		// read back single data and check;

		$display("test: %M: compare, addr walking 1");
		for(n = 2; n < nabits; n = n + 1) begin
			addr = saddr[n];
			if(reqspc)
				req_spacing($random);
			sread(addr, `CPU_SIZE_4, data[0]);
			rd_check(0, sdata[n], 32'hffff_ffff, 0);
		end

		$display("test: %M: compare, addr walking 0");
		for(n = 2; n < nabits; n = n + 1) begin
			addr = saddr[n];
			addr = addr ^ amask;
			if(reqspc)
				req_spacing($random);
			sread(addr, `CPU_SIZE_4, data[0]);
			rd_check(0, ~sdata[n], 32'hffff_ffff, 0);
		end
	end
endtask

// fill sp memory with pattern;
// increasing number of 1s in address;

task sp_mem_fill_pat;
	input [31:0] addr;		// address space;
	input [5:0] nabits;		// # of address bits;
	input [31:0] pxor;		// patterrn xor;
	integer n;
	begin
		$display("test: %M: space 0x%h", addr);
		addr = addr & (32'hffff_ffff << nabits);
		for(n = 2; n <= nabits; n = n + 1) begin
			req_spacing($random);
			swrite(addr, `CPU_SIZE_4, addr ^ pxor);
			sp_spin_iofull;
			addr = addr | (1 << n);
			pxor = { pxor[30:0], pxor[31] };
		end
	end
endtask

// compare memory with pattern;
// increasing number of 1s in address;
// read d-cache size with random sub-block order;
// used for touch test;

task sp_mem_cmp_pat;
	input [31:0] addr;		// address space;
	input [5:0] nabits;		// # of address bits;
	input [31:0] pxor;		// patterrn xor;
	reg [31:0] rdata;		// read data;
	integer n;
	begin
		$display("test: %M: space 0x%h", addr);
		addr = addr & (32'hffff_ffff << nabits);
		for(n = 2; n <= nabits; n = n + 1) begin
			req_spacing($random);
			sread(addr, `CPU_SIZE_4, rdata);
			rd_check(0, addr ^ pxor, 32'hffff_ffff, 0);
			addr = addr | (1 << n);
			pxor = { pxor[30:0], pxor[31] };
		end
	end
endtask

// check that memory pattern is 0;
// test dmem;

task sp_dmem;
	begin
		sp_mem_sglwalk(`SP_DMEM, `SP_NA_DMEM, 0);
		sp_mem_sglwalk(`SP_DMEM, `SP_NA_DMEM, 1);
	end
endtask

// test imem;

task sp_imem;
	begin
		sp_mem_sglwalk(`SP_IMEM, `SP_NA_IMEM, 0);
		sp_mem_sglwalk(`SP_IMEM, `SP_NA_IMEM, 1);
	end
endtask

// run all sp tests;

task test_sp;
	reg [31:0] pxor;		// test pattern xor;
	begin
		// run register related tests;
		// XXX

		// test sp internal memories;
		// since they are on the cbus, single requests only;

		sp_dmem;				// test dmem;
		sp_imem;				// test imem;

		// fill all sp internal memories with address pattern;
		// then read all back and compare;
		// this tests read/write interference among those memories;

		pxor = $random;
		sp_mem_fill_pat(`SP_DMEM, `SP_NA_DMEM, pxor);
		sp_mem_fill_pat(`SP_IMEM, `SP_NA_IMEM, pxor);

		sp_mem_cmp_pat(`SP_DMEM, `SP_NA_DMEM, pxor);
		sp_mem_cmp_pat(`SP_IMEM, `SP_NA_IMEM, pxor);

		// XXX need a lot more here;
	end
endtask