HierarchyFilesModulesSignalsTasksFunctionsHelp

/******************************************************************************/ 
/*                                                                            */ 
/* Copyright (c) 1999 Sun Microsystems, Inc. All rights reserved.             */ 
/*                                                                            */ 
/* The contents of this file are subject to the current version of the Sun    */ 
/* Community Source License, microSPARCII ("the License"). You may not use    */ 
/* this file except in compliance with the License.  You may obtain a copy    */ 
/* of the License by searching for "Sun Community Source License" on the      */ 
/* World Wide Web at http://www.sun.com. See the License for the rights,      */ 
/* obligations, and limitations governing use of the contents of this file.   */ 
/*                                                                            */ 
/* Sun Microsystems, Inc. has intellectual property rights relating to the    */ 
/* technology embodied in these files. In particular, and without limitation, */ 
/* these intellectual property rights may include one or more U.S. patents,   */ 
/* foreign patents, or pending applications.                                  */ 
/*                                                                            */ 
/* Sun, Sun Microsystems, the Sun logo, all Sun-based trademarks and logos,   */ 
/* Solaris, Java and all Java-based trademarks and logos are trademarks or    */ 
/* registered trademarks of Sun Microsystems, Inc. in the United States and   */ 
/* other countries. microSPARC is a trademark or registered trademark of      */ 
/* SPARC International, Inc. All SPARC trademarks are used under license and  */ 
/* are trademarks or registered trademarks of SPARC International, Inc. in    */ 
/* the United States and other countries. Products bearing SPARC trademarks   */ 
/* are based upon an architecture developed by Sun Microsystems, Inc.         */ 
/*                                                                            */ 
/******************************************************************************/ 

//	afx.v 	- generic afx bus slave
//
//	16 oct 1992	-
//
//	versions:
//
//	0.2	22 oct 92	
//		updated to clean up a few things
//	1.0	26 oct 92	
//		restart, using independant state machines
//	1.1	4 nov 92	
//		added FIFO support
//	1.2	11 nov 92	
//		added sized xfers, programmable latencies
//	1.21	16 nov 92	
//		fix for overlapped writes
//	1.3	17 nov 92	
//		added sparse memory model (swiped from swift team)
//		24 nov 92	
//		fix addresses on afx sparse memory model
//		24 nov 92	
//		fix sizing/port locations
//		2 dec 92	
//		more fixes to sizing
//	2.0	7 dec 92	
//		change over to AFX rev 2
//	2.1	1 mar 1993	
//		changes to match the latest spec (rev. 2.1);
//		timeout and latency checks, new signal names,
//		new latency setup using $GetEnv
//
//		the slave has error messages commented out where they overlap
//		what the monitor should check for.  - changes put in by




  ///////////////////////////////////////////////////////////////////////
 //	module afx_slave	//
/////////////////////////////////
[Up: Msystem Mafx]
module afx_slave(clk, aen, write_l, lo_addr, ab, db, s_reply, p_reply, reset_l);
input clk;
input aen;
input write_l;
input lo_addr;
input [14:0] ab;
inout [63:0] db;
input [1:0] s_reply;
output [1:0] p_reply;
input reset_l;

// parameters & defines	/////////////////////////////////////////////////

parameter VERBOSE = 0;		// if set, will output transfer values

parameter C2Q = 0;		// fake clock-to-Q delay value
parameter CMB = 0;		// combinatorial delay
parameter ADR = 0;		// address delay
parameter DBG = 0;		// debug delay
parameter DAT = 2;		// data delay
parameter ACK = 2;		// write ack delay
parameter INI = 0;		// initialization delay
	
parameter FIFOSIZE = 4;		// depth of the write fifo
parameter FPTRSIZE = 2;		// size of a ptr needed for above fifo
	
parameter MEMSIZE = 'h100000;	// mem depth 1Mb (00000-fffff)
parameter MEMBITS = 20;		// # of addr bits to specify mem
parameter AFXSPACE =8'b00000010; // afx space for sparse memory model

parameter
		READ		= 1'b1,		// address r/w bit
		WRITE		= 1'b0;

parameter [1:0]
		WR_REPLY	= 2'b10,	// reply r/w bits
		RD_REPLY	= 2'b11;

// wires & registers		/////////////////////////////////////////

wire clk;
wire aen;
wire write_l;
wire lo_addr;
wire [14:0] ab;
reg [63:0] dbout;		// output register half of the in/out bus
wire [63:0] db = dbout;
wire [1:0] s_reply;
reg [1:0] p_reply;
wire reset_l;
	
reg [27:3] addr;		// address buffer to build into
reg [27:3] tmp_addr;		// temp address
reg [3:0] bm;
//reg [MEMBITS-1:0] wr_addr;	// fully built write address
//reg [MEMBITS-1:0] rd_addr;	// fully built read address

//	As the original sparse memory model was taken from 
//	Viking which supports 36 bits of physical address
//	space the address required to access the sparse
//	memory model is 36 -3 =33 bits. The 3 bit offset
//	is for double words/words/bytes which is the
//	3rd parameter when calling the $mem_write or $mem_read

reg [35:0] wr_addr;		// set to 36 bits for sparse memory stuff
reg [35:0] rd_addr;
reg [7:0] mask;			// memory r/w mask for port positioning

reg [7:0] mem [0:MEMSIZE-1];		// temp memory array
reg [27:3] afifo [0:FIFOSIZE-1];	// address FIFO
reg [3:0] sfifo [0:FIFOSIZE-1];		// byte mask (was size) FIFO
reg [63:0] dfifo [0:FIFOSIZE-1];	// data FIFO
reg [63:0] tmp_data;			// temp data
reg [63:0] read_buf;			// read buffer
reg [7:0] disp_byte;			// used for displaying data
reg [15:0] disp_hword;
reg [31:0] disp_word;

// flags
reg addr_full;			// true (==1) when afifo is full
reg addr_emt;			// true (==1) when afifo is empty
reg data_full;			// true (==1) when dfifo is full
reg data_emt;			// true (==1) when dfifo is empty
reg wdata_pend;			// write data pending (coming in next cycle)
reg rdata_pend;			// read data pending (got addr, go fetch)
reg fifo_busy;			// set when transferring out of the fifo
reg read_busy;			// set when a read is pending (got s_reply)
reg [(FPTRSIZE-1):0] afifo_top;	// pointer to the top of addr/size fifo
reg [(FPTRSIZE-1):0] afifo_btm;	// pointer to the bottom
reg [(FPTRSIZE-1):0] dfifo_top;	// pointer to the top of data fifo
reg [(FPTRSIZE-1):0] dfifo_btm;	// pointer to the bottom
reg [31:0] wlatency;		// write latency value (set by $GetEnv)
reg [31:0] rlatency;		// read latency value (set by $GetEnv)
reg [31:0] wlcount;		// write latency counter
reg [31:0] rlcount;		// read latency counter
reg [7:0] afcount;		// address fifo counter
reg [7:0] dfcount;		// data fifo counter
reg db_en;			// data bus enable (used for afx bus monitor)

reg [7:0] fdbg;			// for debugging
reg [7:0] bdbg;

reg [31:0] afxl;		// for loading latency values thru $GetEnv

reg [31:0] afx_mcd;		// file descriptor for afx trace

reg [31:0] temps;		// general reg used for simulation control

integer i;
integer afxHandle;
integer afx_enable;
	
// initial blocks	/////////////////////////////////////////////////
initial afx_enable = 1;

always @Mclocks.new_working_dir afx_mem_init ;

task afx_mem_init;
	begin
	// initialize sparse memory model
	//$mm_mem_cfree();
	# 0 ;
	afxHandle = $mem_setup();
	$display("afx_slave: doing $afx_setup()...afxHandle: %d", afxHandle);
	
	// initialize local verilog code
//	reset_afx;
	end
endtask

// always blocks	/////////////////////////////////////////////////

// reset
always	@(negedge reset_l) begin
	reset_afx;
end

// address decode
always @(posedge clk && (afx_enable == 1)) begin
    if (aen == 1) begin
	case (lo_addr)
		// load row address
		1'b0: begin
		#DBG	fdbg[3:0] = 4'h1;
		#ADR	addr[27:14] = ab[14:1];
		end
		// load column addr, launch cmd
		1'b1: begin
			case (write_l)
				// write command
				1'b0: begin
				#DBG	fdbg[3:0] = 4'h8;
					if (addr_full == 1) begin
//						$display("*** afx_slave Error:  overwriting top of address FIFO");
					end
				#ADR	addr[13:3] = ab[10:0];
					bm[3:0] = ab[14:11];
					afifo[afifo_top] = addr;
					sfifo[afifo_top] = bm;
					incr_aptr;
					afcount = afcount + 1'b1;
					if (afcount == FIFOSIZE) begin
						addr_full = 1;
					end
					addr_emt = 0;	// no longer empty
				end
				// read command
				1'b1: begin
				#DBG	fdbg[3:0] = 4'h4;
				#ADR	addr[13:3] = ab[10:0];
					bm[3:0] = ab[14:11];
					if (rdata_pend == 1) begin
//						$display("*** afx_slave Error:  overlapping reads");
					end
					rdata_pend = 1;	// release read cycle
				end
			endcase
		end
	endcase	
    end
end

// fill data fifo
always @(posedge clk && (afx_enable == 1)) begin
	// idle, first cycle to write into data fifo
	if ((s_reply == WR_REPLY) && (wdata_pend == 0)) begin
		fdbg[7:4] = 4'h1;
		wdata_pend = 1;
	end
	// single write
	else if ((s_reply != WR_REPLY) && (wdata_pend == 1)) begin
		fdbg[7:4] = 4'h2;
		if (data_full == 1) begin
//			$display("*** afx_slave Error:  overwriting top of data FIFO");
		end
		dfifo[dfifo_top] = db;	// write data into fifo
		incr_dptr;
		dfcount = dfcount + 1'b1;
		if (dfcount == FIFOSIZE) begin
			data_full = 1;
		end
		wdata_pend = 0;
		data_emt = 0;	// fifo no longer empty
				// (releases back end to write into memory)
	end
	// back-to-back writes
	else if ((s_reply == WR_REPLY) && (wdata_pend == 1)) begin
		fdbg[7:4] = 4'h4;
		if (data_full == 1) begin
//			$display("*** afx_slave Error:  overwriting top of data FIFO");
		end
		dfifo[dfifo_top] = db;	// write data into fifo
		incr_dptr;
		dfcount = dfcount + 1'b1;
		if (dfcount == FIFOSIZE) begin
			data_full = 1;
		end
		data_emt = 0;		// fifo no longer empty (releases
					// back end to write into memory)
	end
end

// write fifo to memory & acknowledge
always @(negedge data_emt && (afx_enable == 1)) begin
#1    	if ((data_emt == 0) && (fifo_busy == 0)) begin
		fifo_busy = 1;	// blocks entrance @ every posedge clock
		while (data_emt == 0) begin
			bdbg[7:4] = 4'h1;
			get_wlatency;	// load write latency counter
			while (wlcount > 0) begin
				@(posedge clk)
				bdbg[7:4] = 4'h2;
				// clear previously launched p_reply
			#ACK	p_reply = 0;
				// count down timer
				wlcount = wlcount - 32'h1;
			end
			do_write;	// actually do the write to memory
		#ACK	p_reply = WR_REPLY;
			if (data_emt == 1) begin	// no more in fifo
				bdbg[7:4] = 4'h4;
				@(posedge clk)
			#ACK	p_reply = 0;
			end
		end
		bdbg[7:4] = 4'h0;
		fdbg[7:4] = 4'h0;
		fifo_busy = 0;
	end
end

// read memory & acknowledge
always @(posedge clk && (afx_enable == 1)) begin
	// hold off until the write fifo has emptied
#1	if ((s_reply[1:0] == RD_REPLY) && (read_busy == 0)) begin
		read_busy = 1;
		if (rdata_pend == 0) begin
//			$display("*** afx_slave Error:  got RD_REPLY without a read address");
		end
		while((addr_emt == 0) || (data_emt == 0)) begin
			@(posedge clk) ;	// wait for write to finish
		end
	
		bdbg[3:0] = 4'h1;
		get_rlatency;
		while (rlcount > 0) begin
			@(posedge clk)
			bdbg[3:0] = 4'h2;
			rlcount = rlcount - 32'h1;
		end
	
		do_read;
	#DAT	db_en = 1;
		rdata_pend = 0;
		read_busy = 0;
	#ACK	p_reply = RD_REPLY;
		
		@(posedge clk)
		bdbg[3:0] = 4'h0;
	#ACK	p_reply = 0;
	#DAT	db_en = 0;
	end
end

// databus drive (this is used by the afx monitor)
always @(db_en && (afx_enable == 1)) begin
	case (db_en)
	0:	dbout = 64'hZ;
	1:	dbout = read_buf;
	endcase
end


// tasks	/////////////////////////////////////////////////////////

task reset_afx;
begin
	i = 0;
#INI	p_reply = 0;
	dbout = 64'hZ;
	wr_addr = 0;
	wr_addr[35:28] = AFXSPACE;
	rd_addr = 0;
	rd_addr[35:28] = AFXSPACE;
	addr_full = 0;
	addr_emt = 1;	
	data_full = 0;
	data_emt = 1;
	afifo_top = 0;
	afifo_btm = 0;
	dfifo_top = 0;
	dfifo_btm = 0;
	dfifo_btm = 0;
	disp_byte = 0;
	disp_hword = 0;
	disp_word = 0;
	afxl = 0;
	wlatency = 0;
	rlatency = 0;
	wlcount = 0;
	rlcount = 0;
	afcount = 0;
	dfcount = 0;
	db_en = 0;
	wdata_pend = 0;
	rdata_pend = 0;
	fifo_busy = 0;
	read_busy = 0;
	fdbg = 8'hff;
	bdbg = 8'hff;

#2	afx_mcd = $fopen({Mclocks.working_dir,"/afx_trace.v"});
	if (!afx_mcd)
                $display( "*** afx_slave Error:  unable to open 'afx_trace.v'") ;

	setlatency;
	
	end
endtask		// reset_afx

// increment the address pointer (roll over if necessary)
task incr_aptr;
begin
	if (afifo_top < (FIFOSIZE-1)) begin
		afifo_top = afifo_top + 1'b1;
	end
	else begin
		afifo_top = 0;
	end
end
endtask		// incr_aptr

// decrement the address pointer (roll over if necessary)
task decr_aptr;
begin
	if (afifo_btm < (FIFOSIZE-1)) begin
		afifo_btm = afifo_btm + 1'b1;
	end
	else begin
		afifo_btm = 0;
	end
end
endtask		// decr_aptr

// increment the data pointer (roll over if necessary)
task incr_dptr;
begin
	if (dfifo_top < (FIFOSIZE-1)) begin
		dfifo_top = dfifo_top + 1'b1;
	end
	else begin
		dfifo_top = 0;
	end
end
endtask		// incr_dptr

// decrement the data pointer (roll over if necessary)
task decr_dptr;
begin
	if (dfifo_btm < (FIFOSIZE-1)) begin
		dfifo_btm = dfifo_btm + 1'b1;
	end
	else begin
		dfifo_btm = 0;
	end
end
endtask		// decr_dptr

// set the write latency counter
task get_wlatency;
begin

	wlcount = wlatency;

end
endtask		// get_wlatency

// set the read latency counter
task get_rlatency;
begin

	rlcount = rlatency;

end
endtask		// get_rlatency

// set the read latency counter
task setlatency;
begin

	$GetEnv("afxlatency", afxl);
	
	case (afxl[31:24])		// look at the select code
		
	// simple fixed latency
		8'h00:	begin		// simple fixed latency
			wlatency[31:24] = 8'h0;
			wlatency[23:0] = afxl[23:0];
			rlatency[31:24] = 8'h0;
			rlatency[23:0] = afxl[23:0];
			$display("afx_slave: setting read/write latencies to %d",
			 	afxl[23:0]);
		end
		
	// split fixed latency
		8'h01:	begin		// split fixed latency
			wlatency[31:12] = 8'h0;
			wlatency[11:0] = afxl[23:12];
			rlatency[31:12] = 8'h0;
			rlatency[11:0] = afxl[11:0];
			$display("afx_slave: setting write latency = %d", 
				afxl[23:12]);
			$display("afx_slave: setting read  latency = %d", 
				afxl[11:0]);
		end

	// address mapped latency
		8'h02:	begin		// address mapped latency
			$display( "*** afx_slave Error:  address mapped latency not working yet");
		end
		
	// random latency
		8'h04:	begin		// random latency
			$display( "*** afx_slave Error:  random latency not working yet");
		end

		8'hff:	begin		// Special code for AFX disable.
			$display( "afx_slave:  AFX Slave is disabled");
			afx_enable = 0;
			end
		
		default	begin
			$display( "*** afx_slave Error:  bad latency value, afxl = 0x%x",
				afxl);
		end
		
	endcase
	
end
endtask		// setlatency

// write top of data fifo to memory
task do_write;
begin
    wr_addr[27:3] = afifo[afifo_btm];
    tmp_data = dfifo[dfifo_btm];
    case (sfifo[afifo_btm])
    	// byte writes ///////////////////////////////////////////////////////
    	4'b0000: begin
		wr_addr[2:0] = 3'b000;
		disp_byte = tmp_data[63:56];
		mask = 8'b10000000;
		$mem_write(afxHandle, wr_addr[35:3], mask, tmp_data);
		$fdisplay(afx_mcd, "0x%h	0x%h	%d", 
			  wr_addr[31:0], disp_byte, Mclocks.cycle_count);
		if (VERBOSE)
		    $display("afx_slave: writing byte data=0x%h to addr=0x%h",
			   disp_byte, wr_addr[31:0]);
	end
	4'b0001: begin
		wr_addr[2:0] = 3'b001;
		disp_byte = tmp_data[55:48];
		mask = 8'b01000000;
		$mem_write(afxHandle, wr_addr[35:3], mask, tmp_data);
		$fdisplay(afx_mcd, "0x%h	0x%h	%d", 
			  wr_addr[31:0], disp_byte, Mclocks.cycle_count);
		if (VERBOSE)
		    $display("afx_slave: writing byte data=0x%h to addr=0x%h",
			   disp_byte, wr_addr[31:0]);
	end
	4'b0010: begin
		wr_addr[2:0] = 3'b010;
		disp_byte = tmp_data[47:40];
		mask = 8'b00100000;
		$mem_write(afxHandle, wr_addr[35:3], mask, tmp_data);
		$fdisplay(afx_mcd, "0x%h	0x%h	%d", 
			  wr_addr[31:0], disp_byte, Mclocks.cycle_count);
		if (VERBOSE)
		    $display("afx_slave: writing byte data=0x%h to addr=0x%h",
			   disp_byte, wr_addr[31:0]);
	end
	4'b0011: begin
		wr_addr[2:0] = 3'b011;
		disp_byte = tmp_data[41:32];
		mask = 8'b00010000;
		$mem_write(afxHandle, wr_addr[35:3], mask, tmp_data);
		$fdisplay(afx_mcd, "0x%h	0x%h	%d", 
			  wr_addr[31:0], disp_byte, Mclocks.cycle_count);
		if (VERBOSE)
		    $display("afx_slave: writing byte data=0x%h to addr=0x%h",
			   disp_byte, wr_addr[31:0]);
	end
	4'b0100: begin
		wr_addr[2:0] = 3'b100;
		disp_byte = tmp_data[31:24];
		mask = 8'b00001000;
		$mem_write(afxHandle, wr_addr[35:3], mask, tmp_data);
		$fdisplay(afx_mcd, "0x%h	0x%h	%d", 
			  wr_addr[31:0], disp_byte, Mclocks.cycle_count);
		if (VERBOSE)
		    $display("afx_slave: writing byte data=0x%h to addr=0x%h",
			   disp_byte, wr_addr[31:0]);
	end
	4'b0101: begin
		wr_addr[2:0] = 3'b101;
		disp_byte = tmp_data[23:16];
		mask = 8'b00000100;
		$mem_write(afxHandle, wr_addr[35:3], mask, tmp_data);
		$fdisplay(afx_mcd, "0x%h	0x%h	%d", 
			  wr_addr[31:0], disp_byte, Mclocks.cycle_count);
		if (VERBOSE)
		    $display("afx_slave: writing byte data=0x%h to addr=0x%h",
			   disp_byte, wr_addr[31:0]);
	end
	4'b0110: begin
		wr_addr[2:0] = 3'b110;
		disp_byte = tmp_data[15:8];
		mask = 8'b00000010;
		$mem_write(afxHandle, wr_addr[35:3], mask, tmp_data);
		$fdisplay(afx_mcd, "0x%h	0x%h	%d", 
			  wr_addr[31:0], disp_byte, Mclocks.cycle_count);
		if (VERBOSE)
		    $display("afx_slave: writing byte data=0x%h to addr=0x%h",
			   disp_byte, wr_addr[31:0]);
	end
	4'b0111: begin
		wr_addr[2:0] = 3'b111;
		disp_byte = tmp_data[7:0];
		mask = 8'b00000001;
		$mem_write(afxHandle, wr_addr[35:3], mask, tmp_data);
		$fdisplay(afx_mcd, "0x%h	0x%h	%d", 
			  wr_addr[31:0], disp_byte, Mclocks.cycle_count);
		if (VERBOSE)
		    $display("afx_slave: writing byte data=0x%h to addr=0x%h",
			   disp_byte, wr_addr[31:0]);
	end
	// half-word writes //////////////////////////////////////////////////
    	4'b1000: begin
		wr_addr[2:0] = 3'b000;
		disp_hword = tmp_data[63:48];
		mask = 8'b11000000;
		$mem_write(afxHandle, wr_addr[35:3], mask, tmp_data);
		$fdisplay(afx_mcd, "0x%h	0x%h	%d", 
			  wr_addr[31:0], disp_hword, Mclocks.cycle_count);
		if (VERBOSE)
		    $display("afx_slave: writing byte data=0x%h to addr=0x%h",
			   disp_hword, wr_addr[31:0]);
	end
	4'b1010: begin
		wr_addr[2:0] = 3'b010;
		disp_hword = tmp_data[47:32];
		mask = 8'b00110000;
		$mem_write(afxHandle, wr_addr[35:3], mask, tmp_data);
		$fdisplay(afx_mcd, "0x%h	0x%h	%d", 
			  wr_addr[31:0], disp_hword, Mclocks.cycle_count);
		if (VERBOSE)
		    $display("afx_slave: writing byte data=0x%h to addr=0x%h",
			   disp_hword, wr_addr[31:0]);
	end
	4'b1100: begin
		wr_addr[2:0] = 3'b100;
		disp_hword = tmp_data[31:16];
		mask = 8'b00001100;
		$mem_write(afxHandle, wr_addr[35:3], mask, tmp_data);
		$fdisplay(afx_mcd, "0x%h	0x%h	%d", 
			  wr_addr[31:0], disp_hword, Mclocks.cycle_count);
		if (VERBOSE)
		    $display("afx_slave: writing byte data=0x%h to addr=0x%h",
			   disp_hword, wr_addr[31:0]);
	end
	4'b1110: begin
		wr_addr[2:0] = 3'b110;
		disp_hword = tmp_data[15:0];
		mask = 8'b00000011;
		$mem_write(afxHandle, wr_addr[35:3], mask, tmp_data);
		$fdisplay(afx_mcd, "0x%h	0x%h	%d", 
			  wr_addr[31:0], disp_hword, Mclocks.cycle_count);
		if (VERBOSE)
		    $display("afx_slave: writing halfword data=0x%h to addr=0x%h",
			   disp_hword, wr_addr[31:0]);
	end
	// word writes ///////////////////////////////////////////////////////
    	4'b1001: begin
		wr_addr[2:0] = 3'b000;
		disp_word = tmp_data[63:32];
		mask = 8'b11110000;
		$mem_write(afxHandle, wr_addr[35:3], mask, tmp_data);
		$fdisplay(afx_mcd, "0x%h	0x%h	%d", 
			  wr_addr[31:0], disp_word, Mclocks.cycle_count);
		if (VERBOSE)
		    $display("afx_slave: writing word data=0x%h to addr=0x%h",
			   disp_word, wr_addr[31:0]);
	end
	4'b1101: begin
		wr_addr[2:0] = 3'b100;
		disp_word = tmp_data[31:0];
		mask = 8'b00001111;
		$mem_write(afxHandle, wr_addr[35:3], mask, tmp_data);
		$fdisplay(afx_mcd, "0x%h	0x%h	%d", 
			  wr_addr[31:0], disp_word, Mclocks.cycle_count);
		if (VERBOSE)
		    $display("afx_slave: writing word data=0x%h to addr=0x%h",
			   disp_word, wr_addr[31:0]);
	end
	// doubleword writes /////////////////////////////////////////////////
    	4'b1011: begin
		wr_addr[2:0] = 3'b000;
		mask = 8'b11111111;
		$mem_write(afxHandle, wr_addr[35:3], mask, tmp_data);
		$fdisplay(afx_mcd, "0x%h	0x%h	%d", 
			  wr_addr[31:0], tmp_data, Mclocks.cycle_count);
		if (VERBOSE)
		    $display("afx_slave: writing doubleword data=0x%h to addr=0x%h",
			   tmp_data, wr_addr[31:0]);
	end
	// reserved byte mask code! //////////////////////////////////////////
    	4'b1111: begin
		if (VERBOSE)
		    $display("afx_slave Error: writing to reserved byte mask code = 11111");
	end
    endcase

    // finish up w/ setting counter & flags
    decr_aptr;
    afcount = afcount - 1'b1;
    if (afcount == 0) begin
	addr_emt = 1;
    end
    addr_full = 0;	// no longer full

    decr_dptr;
    dfcount = dfcount - 1'b1;
    data_full = 0;	// no longer full
    if (dfcount == 0) begin
	data_emt = 1;
    end
end
endtask		// do_write

// read from memory
task do_read;
begin
    read_buf = 64'h0;	// safe model
    //read_buf = 64'hX;	// pessimistic model
    rd_addr[27:3] = addr;
    case (bm[3:0])
	// byte reads ////////////////////////////////////////////////////////
    	4'b0000: begin
		rd_addr[2:0] = 3'b000;
		mask = 8'b10000000;
		$mem_read(afxHandle, rd_addr[35:3], mask, read_buf);
		disp_byte = read_buf[63:56];
		if (VERBOSE)
		    $display("afx_slave: reading byte data=0x%h from addr=0x%h",
			   disp_byte, rd_addr[31:0]);
	end
	4'b0001: begin
		rd_addr[2:0] = 3'b001;
		mask = 8'b01000000;
		$mem_read(afxHandle, rd_addr[35:3], mask, read_buf);
		disp_byte = read_buf[55:48];
		if (VERBOSE)
		    $display("afx_slave: reading byte data=0x%h from addr=0x%h",
			   disp_byte, rd_addr[31:0]);
	end
	4'b0010: begin
		rd_addr[2:0] = 3'b010;
		mask = 8'b00100000;
		$mem_read(afxHandle, rd_addr[35:3], mask, read_buf);
		disp_byte = read_buf[47:40];
		if (VERBOSE)
		    $display("afx_slave: reading byte data=0x%h from addr=0x%h",
			   disp_byte, rd_addr[31:0]);
	end
	4'b0011: begin
		rd_addr[2:0] = 3'b011;
		mask = 8'b00010000;
		$mem_read(afxHandle, rd_addr[35:3], mask, read_buf);
		disp_byte = read_buf[41:32];
		if (VERBOSE)
		    $display("afx_slave: reading byte data=0x%h from addr=0x%h",
			   disp_byte, rd_addr[31:0]);
	end
	4'b0100: begin
		rd_addr[2:0] = 3'b100;
		mask = 8'b00001000;
		$mem_read(afxHandle, rd_addr[35:3], mask, read_buf);
		disp_byte = read_buf[31:24];
		if (VERBOSE)
		    $display("afx_slave: reading byte data=0x%h from addr=0x%h",
			   disp_byte, rd_addr[31:0]);
	end
	4'b0101: begin
		rd_addr[2:0] = 3'b101;
		mask = 8'b00000100;
		$mem_read(afxHandle, rd_addr[35:3], mask, read_buf);
		disp_byte = read_buf[23:16];
		if (VERBOSE)
		    $display("afx_slave: reading byte data=0x%h from addr=0x%h",
			   disp_byte, rd_addr[31:0]);
	end
	4'b0110: begin
		rd_addr[2:0] = 3'b110;
		mask = 8'b00000010;
		$mem_read(afxHandle, rd_addr[35:3], mask, read_buf);
		disp_byte = read_buf[15:8];
		if (VERBOSE)
		    $display("afx_slave: reading byte data=0x%h from addr=0x%h",
			   disp_byte, rd_addr[31:0]);
	end
	4'b0111: begin
		rd_addr[2:0] = 3'b111;
		mask = 8'b00000001;
		$mem_read(afxHandle, rd_addr[35:3], mask, read_buf);
		disp_byte = read_buf[7:0];
		if (VERBOSE)
		    $display("afx_slave: reading byte data=0x%h from addr=0x%h",
			   disp_byte, rd_addr[31:0]);
	end
	// half-word reads ///////////////////////////////////////////////////
    	4'b1000: begin
		rd_addr[2:0] = 3'b000;
		mask = 8'b11000000;
		$mem_read(afxHandle, rd_addr[35:3], mask, read_buf);
		disp_hword = read_buf[63:48];
		if (VERBOSE)
		    $display("afx_slave: reading halfword data=0x%h from addr=0x%h",
			   disp_hword, rd_addr[31:0]);
	end
	4'b1010: begin
		rd_addr[2:0] = 3'b010;
		mask = 8'b00110000;
		$mem_read(afxHandle, rd_addr[35:3], mask, read_buf);
		disp_hword = read_buf[47:32];
		if (VERBOSE)
		    $display("afx_slave: reading halfword data=0x%h from addr=0x%h",
			   disp_hword, rd_addr[31:0]);
	end
	4'b1100: begin
		rd_addr[2:0] = 3'b100;
		mask = 8'b00001100;
		$mem_read(afxHandle, rd_addr[35:3], mask, read_buf);
		disp_hword = read_buf[31:16];
		if (VERBOSE)
		    $display("afx_slave: reading halfword data=0x%h from addr=0x%h",
			   disp_hword, rd_addr[31:0]);
	end
	4'b1110: begin
		rd_addr[2:0] = 3'b110;
		mask = 8'b00000011;
		$mem_read(afxHandle, rd_addr[35:3], mask, read_buf);
		disp_hword = read_buf[15:0];
		if (VERBOSE)
		    $display("afx_slave: reading halfword data=0x%h from addr=0x%h",
			   disp_hword, rd_addr[31:0]);
	end
	// word reads ////////////////////////////////////////////////////////
    	4'b1001: begin
		rd_addr[2:0] = 3'b000;
		mask = 8'b11110000;
		$mem_read(afxHandle, rd_addr[35:3], mask, read_buf);
		disp_word = read_buf[63:32];
		if (VERBOSE)
		    $display("afx_slave: reading word data=0x%h from addr=0x%h",
			   disp_word, rd_addr[31:0]);
	end
	4'b1101: begin
		rd_addr[2:0] = 3'b100;
		mask = 8'b00001111;
		$mem_read(afxHandle, rd_addr[35:3], mask, read_buf);
		disp_word = read_buf[31:0];
		if (VERBOSE)
		    $display("afx_slave: reading word data=0x%h from addr=0x%h",
			   disp_word, rd_addr[31:0]);
	end
	// doubleword reads //////////////////////////////////////////////////
    	4'b1011: begin
		rd_addr[2:0] = 3'b000;
		mask = 8'b11111111;
		$mem_read(afxHandle, rd_addr[35:3], mask, read_buf);
		if (VERBOSE)
		    $display("afx_slave: reading doubleword data=0x%h from addr=0x%h",
			   read_buf, rd_addr[31:0]);
	end
	// reserved byte mask code! //////////////////////////////////////////
    	4'b1111: begin
		if (VERBOSE)
		    $display("afx_slave Error: reading from reserved byte mask code = 11111");
	end
    endcase
end
endtask		// do_read

endmodule	// afx_slave

HierarchyFilesModulesSignalsTasksFunctionsHelp

This page: Created:Thu Aug 19 11:59:25 1999
From: ../../../sparc_v8/system/rtl/afx.v

Verilog converted to html by v2html 5.0 (written by Costas Calamvokis).Help