/******************************************************************************/
/* */
/* 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 //
/////////////////////////////////
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
This page: |
Created: | Thu Aug 19 11:59:25 1999 |
| From: |
../../../sparc_v8/system/rtl/afx.v
|