HierarchyFilesModulesSignalsTasksFunctionsHelp
1234

/******************************************************************************/ 
/*                                                                            */ 
/* 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.         */ 
/*                                                                            */ 
/******************************************************************************/ 

/****************************************************************************
 * 64-bit DRAM module 
 ***************************************************************************/
[Up: Msystem TheRam]
module RAM64  ( mem_size, b_memdata, b_mempar,
                memaddr, ras_l, cas_l, moe_l, mwe_l, ram_output, simm32_sel
              );
    output  [63:00]     mem_size; /* Return `SIZE to top module as 63-bit.*/
    output  		ram_output;	// ram output enable signal for tri-state driver check

    inout   [63:00]     b_memdata; // 64-bit bi-dir data bus
    inout   [01:00]     b_mempar ; // 2-bit bi-dir parity bus

    input   [10:00]     memaddr;
    input   [07:00]     ras_l;
    input   [03:00]     cas_l;
    input               moe_l;
    input               mwe_l;
    input               simm32_sel;

    wire [63:00] FPM_mem_size;
    wire [63:00] EDO_mem_size;
    wire	 FPM_ram_output;
    wire 	 EDO_ram_output;
    wire [63:00] FPM_rd_data;
    wire [63:00] EDO_rd_data;
    wire [01:00] FPM_rd_par;
    tri [01:00] EDO_rd_par_tmp;		//rdv
    tri [01:00] FPM_rd_par_tmp;		//rdv
    wire        par_addr_ok;			//rdv
    wire [01:00] EDO_rd_par;
    wire [63:00] BOTH_wr_data;
    wire [01:00] BOTH_wr_par;
    wire [07:00] FPM_ras_l;
    wire [07:00] EDO_ras_l;
    wire [03:00] FPM_cas_l;
    wire [03:00] EDO_cas_l;
    wire [10:00] FPM_memaddr;
    wire [10:00] EDO_memaddr;
    wire	 FPM_moe_l;
    wire	 EDO_moe_l;
    wire	 FPM_mwe_l;
    wire	 EDO_mwe_l;

    integer memHandle, parHandle;



/****************************************************************************
 * Init sparse memory model
 *
 * In sunergy, the vfront command 'start_test', among other things, changes
 * the current working directory and sets the signal '.new_working_dir'.
 * this triggers the following task which frees up any previously allocated
 * sparse memory data structures and sets up the new ones.
 *
 ***************************************************************************/

//Add parity testing hooks (via run -testpar option) -rdv
reg testpar;
initial begin
   $GetEnv("testpar",testpar);

end

always @Mclocks.new_working_dir sparse_mem_init ;
task sparse_mem_init;
	begin
	$mm_mem_cfree ();
	memHandle = $mem_setup();
	$display("doing $mem_setup()...memHandle: %g", memHandle);
	parHandle = $mem_setup();
	$display("doing $mem_setup()...parHandle: %g", parHandle);
	end
endtask

	RAM   RamWord1   ( FPM_mem_size, , , FPM_rd_data, BOTH_wr_data, FPM_rd_par, BOTH_wr_par,
                          FPM_memaddr, FPM_ras_l, FPM_cas_l, FPM_moe_l, FPM_mwe_l, FPM_ram_output, 
				simm32_sel);

        EDO_DRAM RamWord2 (EDO_mem_size, EDO_rd_data, BOTH_wr_data, EDO_rd_par, BOTH_wr_par, 
				EDO_memaddr, EDO_ras_l, EDO_cas_l, EDO_moe_l, EDO_mwe_l, EDO_ram_output);

	assign mem_size = (simm32_sel) ? EDO_mem_size : FPM_mem_size;
	assign ram_output = (simm32_sel) ? EDO_ram_output : FPM_ram_output;
	assign b_memdata = (simm32_sel) ? EDO_rd_data : FPM_rd_data;

	//add par_addr_ok flag (must use with run -testpar switch
        //with PA[31:4]=F400000x to cause parity error) -rdv
	assign par_addr_ok = ram_output ? (simm32_sel ?
			(RamWord2.Addr[27:4]==24'h400000) :
			(RamWord1.Addr[27:4]==24'h400000)) : 1'b0 ;

	//add testpar mux (must use with run -testpar switch
        //with PA[31:4]=F400000x to cause parity error) -rdv
	assign EDO_rd_par_tmp = (testpar & par_addr_ok) ? ~EDO_rd_par : EDO_rd_par;
	assign FPM_rd_par_tmp = (testpar & par_addr_ok) ? ~FPM_rd_par : FPM_rd_par;

	//assign b_mempar = (simm32_sel) ? EDO_rd_par : FPM_rd_par;
	assign b_mempar = (simm32_sel) ? EDO_rd_par_tmp : FPM_rd_par_tmp;
	assign BOTH_wr_data = b_memdata;
	assign BOTH_wr_par = b_mempar;
	assign FPM_ras_l = (simm32_sel) ? 1 : ras_l;
	assign EDO_ras_l = (simm32_sel) ? ras_l : 1;
	assign FPM_cas_l = (simm32_sel) ? 1 : cas_l;
	assign EDO_cas_l = (simm32_sel) ? cas_l : 1;
	assign FPM_memaddr = (simm32_sel) ? 11'b0 : memaddr;
	assign EDO_memaddr = (simm32_sel) ? memaddr : 11'b0;
	assign FPM_moe_l = (simm32_sel) ? 1 : moe_l;
	assign EDO_moe_l = (simm32_sel) ? moe_l : 1;
	assign FPM_mwe_l = (simm32_sel) ? 1 : mwe_l;
	assign EDO_mwe_l = (simm32_sel) ? mwe_l : 1;

endmodule

/*=======================================================================*/

`define tRC             110		// random read or write cycle time
`define tRAC		75		// Access time from RAS
`define tCAC		30		// Access time from CAS
`define	tAA		45		// Access time from column address
// tCEZ monitors not required,because RAS turns off after CAS tREZ is the 
// data turn off parameter.
`define tCEZ_MIN	15		// Output buffer turn off delay from CAS
`define tCEZ_MAX	30		// Output buffer turn off delay from CAS
`define tT_MIN          2		// CHECK Transition time (rise and fall)
`define tT_MAX		50		// CHECK Transition time (rise and fall)
`define tRP		40		// RAS precharge time
`define tRAS_MIN	60		// RAS pulse width
`define	tRAS_MAX	10000		// RAS pulse width
`define tRSH		17		// RAS hold time
`define tCSH		50		// CAS hold time
`define	tCAS_MIN	10		// CAS pulse width
`define	tCAS_MAX	10000		// CAS pulse width
`define tRCD_MIN	20		// RAS to CAS delay time
`define tRCD_MAX	45		// RAS to CAS delay time
`define tRAD_MIN	15		// RAS to column address delay time
`define tRAD_MAX	30		// RAS to column address delay time
`define tCRP		5		// CAS to RAS precharge time
`define tASR		0		// Row address set up time
`define tRAH		10		// Row address hold time
`define	tASC		0		// Column address set up time
`define	tCAH		10		// Column address hold time
`define tRAL		30		// Column address to RAS lead time
`define tRCS		5		// Read command set_up time
`define tRCH		5		// Read command hold time referenced to CAS
`define tRRH		5		// Read command hold time referenced to RAS
`define tWCH		10		// Write command hold time
`define tWP		10		// Write command pulse width
`define tRWL            15		// Write command to RAS lead time
`define tCWL		10		// Write command to CAS lead time
`define tDS             0		// Data set_up time
`define tDH             10		// Data hold time
`define tREF_MAX       	64 		// CHECK Refresh period
`define tWCS		0		// Write command set up time
`define tCPWD		60		// CHECK CAS precharge to W delay time
`define tCSR		10		// CAS set up time (CAS_Before_RAS refresh)
`define tCHR		10		// CAS hold time (CAS_Before_RAS refresh)
`define tRPC		5		// ADD MONITOR RAS to CAS precharge time
`define tCPA		39		// Access time from CAS precharge
`define tHPC		25		// same as tPC of Micron data sheet Hyper page cycle time
`define tCP		10		// CAS precharge time (Hyper page cycle)
`define tRASP_MAX	100000		// RAS pulse width (Hyper page cycle)
`define tRASP_MIN       60		// RAS pulse width (Hyper page cycle)
`define tRHCP		35		// ADD to EDO.SIMM.v {tCP + tRSH} RAS hold time from CAS precharge
`define tOED		15		// OE to data delay
`define tOEH		15		// OE command hold time
`define tWRP		10		// W to RAS precharge time
`define tWRH		10		// W to RAS hold time (C-B-R refresh)
`define tDOH		9		// same as tCOH of Micron data sheet Output data hold time
`define tREZ_MIN        18		// same as tOFF Output buffer turn off delay from RAS
`define tREZ_MAX        30		// same as tOFF Output buffer turn off delay from RAS
`define tOEP        	5		// OE precharge time

`define tWEZ_MIN	0		// only for read/write mixed cycle Output buffer turn off delay from W
`define tWEZ_MAX	15		// only for read/write mixed cycle Output buffer turn off delay from W
`define tOCH		5		// OE to CAS hold time
`define tCHO		5		// CAS hold time to OE
`define tWPE		10		// applicable only for read/write mixed cycle W pulse width (Hyper Page cycle
`define tOEA		30		// OE is permanently tied to gnd OE access time
`define	tOEZ_MAX	30		// OE is permanently tied to gnd Output buffer turn off delay time from OE
`define	tOEZ_MIN	15		// OE is permanently tied to gnd Output buffer turn off delay time from OE
`define tCWD		40		// since we don't do rmw at dram CAS to W delay time
`define tRWD		85		// since we don't do rmw at dram RAS to W delay time
`define tAWD		55		// since we don't do rmw at dram Column address to W delay time
`define tCLZ		0		// CAS to output in Low-z
`define tOLZ		0		// OE to output in Low-z
`define tHPRWC          79              // Hyper page mode read-modify-write cycle time, not required
`define tRWC		155		// read-modify-write cycle time, not required because
					// we don't do rmw at dram
					



// From Micron's data sheet
//`define tACH		15		
//`define tCHD		10
//`define tDHR		45
//`define tORD		0
//`define tPRWC		75
//`define tRASS		100
//`define tREFs		128
//`define tREF		32
//`define tRPS		110
//`define tWCR		45
//`define tWPZ		10


/***************************************************************************
*               File name:      EDO_DRAM.v
*
*               Description:    Eagel dram model
*
*               based on Sabre SIMM model
*
***************************************************************************/

[Up: RAM64 RamWord2]
module EDO_DRAM(EDO_mem_size, EDO_rd_data, EDO_wr_data, EDO_rd_par, EDO_wr_par, EDO_memaddr, EDO_ras_l, EDO_cas_l, EDO_moe_l, EDO_mwe_l, EDO_ram_output);

//`include "quit.h"
//`include "monitor.h"

output EDO_mem_size;
output EDO_ram_output;

output	[63:00]	EDO_rd_data;
output	[01:00] EDO_rd_par;
input	[63:00]	EDO_wr_data;
input	[01:00] EDO_wr_par;
input	[10:00] EDO_memaddr;
input 	[07:00]	EDO_ras_l;
input	[03:00] EDO_cas_l;
input		EDO_moe_l;
input		EDO_mwe_l;

`define     ASSERTED    1
`define     NEGATED     0

wire	[3:0]	rasb_l;
wire	[3:0]	rast_l;
wire	[63:00]	EDO_mem_size;
reg	EDO_ram_output;

parameter RAM_DELAY_EDO = 25;
integer		ParUpdateFlag;

assign rasb_l = { EDO_ras_l[6], EDO_ras_l[4], EDO_ras_l[2], EDO_ras_l[0] };	// Used for even bank YS
assign rast_l = { EDO_ras_l[7], EDO_ras_l[5], EDO_ras_l[3], EDO_ras_l[1] };	// Used for odd bank YS
assign EDO_mem_size = 64'b0;

reg                 mem_trace;      // enable or disable mem traces
reg     [31:0]      mem_mcd;        // file descriptor for mem trace
reg     [27:03]     Addr;           // used for forming the address.
reg	[32:00]		Index;		// 33 bits for sparse memory requirement

reg 		address_done;

reg [31:0] 	full_address;
reg [31:0] 	full_address2;

//----------------------------------------
task gen_full_addrs;
 
input [31:0] row;
input [31:0] colm;
output [31:0] faddrs;
 
reg [31:0] ffaddrs;
 
begin
 
    ffaddrs = 32'b0;
 
     begin
        {ffaddrs[24], ffaddrs[22], ffaddrs[20:12]} = row[10:0];
        {ffaddrs[23], ffaddrs[21], ffaddrs[11:03]} = colm[10:0];
     end 
 
    faddrs = ffaddrs;
 
end
 
endtask

initial begin

	address_done = 1'b0;
        ParUpdateFlag   = `NEGATED ;
        EDO_ram_output      =  1'b0 ;

	$display ("\nModule EDO_dram.v - RAM initial block\n");
	mem_trace = 0;
	// Wait for working dir, etc., to be initialized before opening
	// the trace file.
	#1;
	mem_mcd = $fopen({Mclocks.working_dir,"/mem_trace.v"});
	if (!mem_mcd)
	    $display ("EDO_dram: unable to open 'mem_trace.v'");
end


// When is the time to read.
always @(posedge simm0.start_read)
 begin

	full_address = 32'b0;
	gen_full_addrs(simm0.row_addrs, simm0.colm_addrs, full_address);

	if ((rasb_l[0] == 1'b0) && (rast_l[0] == 1'b0))
	 begin
	   $display("\nDRAM Error:[%h]\n", $stime);
	   $display("\nBoth rasb_l[0] and rast_l[0] can't be asserted at the same time.\n");
	 end

	 if (rasb_l[0] == 1'b0)
	 	full_address[27:25]	= 3'b000;

	 if (rast_l[0] == 1'b0)
	 	full_address[27:25]	= 3'b001;
	Index = {7'b0, full_address[27:03]};
	Addr[27:03] = full_address[27:03];

	$display("\nDRAM INFO: Read, Addrs=%h\n", full_address);

	$mem_read(Msystem.TheRam.memHandle, Index, 8'b11111111, simm0.rd_data);
	$mem_read(Msystem.TheRam.parHandle, Index, 8'b00000011, simm0.rd_parity);
	$display("\nDRAM INFO:data Read=%h[%h]\n", simm0.rd_data, simm0.rd_parity);
                ParUpdateFlag = `NEGATED;
                if (simm0.rd_parity[1] == 1'b0) begin
                        simm0.rd_parity[1] = 1'b1;
                        simm0.rd_parity[0] = ^simm0.rd_data[31:0];
                        ParUpdateFlag = `ASSERTED;
                        end
                if (simm0.rd_parity[9] == 1'b0) begin
                        simm0.rd_parity[9] = 1'b1;
                        simm0.rd_parity[8] = ^simm0.rd_data[63:32];
                        ParUpdateFlag = `ASSERTED;
                        end
                if (ParUpdateFlag == `ASSERTED) begin
                        $mem_write(Msystem.TheRam.parHandle, Index, 8'b00000011, simm0.rd_parity);
                        end


        address_done = 1'b1;

`ifdef DEBUG

	$display("TIME=%t, SIMM0, Full address=%h, Data0=%h\n",$stime,   full_address, simm0.rd_data);
	$display("============================================\n");

`endif

	simm0.start_read	<= #1 1'b0;			// Reset for next time.
	simm0.tAA_met		<= #1 0;
	simm0.tAA_done		<= #1 1;
	simm0.tCPA_met		<= #1 0;
	simm0.tCAC_met		<= #1 0;
	simm0.cac_met		<= #1 0;
	simm0.cpa_met		<= #1 0;
	simm0.colm_addrs	 = 32'hFFFF;
        address_done		<= #1 1'b0;
 end

// When is the time to read.
always @(posedge simm1.start_read)
 begin

	full_address = 32'b0;
	gen_full_addrs(simm1.row_addrs, simm1.colm_addrs, full_address);

	if ((rasb_l[1] == 1'b0) && (rast_l[1] == 1'b0))
	 begin
	   $display("\nDRAM Error:[%h]\n", $stime);
	   $display("\nBoth rasb_l[1] and rast_l[1] can't be asserted at the same time.\n");
	 end

	 if (rasb_l[1] == 1'b0)
	 	full_address[27:25]	= 3'b010;

	 if (rast_l[1] == 1'b0)
	 	full_address[27:25]	= 3'b011;

	Index = {7'b0, full_address[27:03]};
	Addr[27:03] = full_address[27:03];

	$display("\nDRAM INFO: Read, Addrs=%h\n", full_address);

        $mem_read(Msystem.TheRam.memHandle, Index, 8'b11111111, simm1.rd_data);
        $mem_read(Msystem.TheRam.parHandle, Index, 8'b00000011, simm1.rd_parity);
        $display("\nDRAM INFO:data Read=%h[%h]\n", simm1.rd_data, simm1.rd_parity);

                ParUpdateFlag = `NEGATED;
                if (simm1.rd_parity[1] == 1'b0) begin
                        simm1.rd_parity[1] = 1'b1;
                        simm1.rd_parity[0] = ^simm1.rd_data[31:0];
                        ParUpdateFlag = `ASSERTED;
                        end
                if (simm1.rd_parity[9] == 1'b0) begin
                        simm1.rd_parity[9] = 1'b1;
                        simm1.rd_parity[8] = ^simm1.rd_data[63:32];
                        ParUpdateFlag = `ASSERTED;
                        end
                if (ParUpdateFlag == `ASSERTED) begin
                        $mem_write(Msystem.TheRam.parHandle, Index, 8'b00000011, simm1.rd_parity);
                        end

        address_done = 1'b1;

	$display("\nDRAM INFO:data Read=%h[%h]\n", simm1.rd_data, simm1.rd_parity);

`ifdef DEBUG

	$display("TIME=%t, SIMM2, Full address=%h, Data0=%h\n",$stime,   full_address, simm1.rd_data);
	$display("============================================\n");

`endif

	simm1.start_read	<= #1 1'b0;			// Reset for next time.
	simm1.tAA_met		<= #1 0;
	simm1.tAA_done		<= #1 1;
        simm1.tCPA_met		<= #1 0;
        simm1.tCAC_met		<= #1 0;
        simm1.cac_met		<= #1 0;
        simm1.cpa_met		<= #1 0;
	simm1.colm_addrs	 = 32'hFFFF;
        address_done		<= #1 1'b0;
 end

// When is the time to read.
always @(posedge simm2.start_read)
 begin

	full_address = 32'b0;
	gen_full_addrs(simm2.row_addrs, simm2.colm_addrs, full_address);

	if ((rasb_l[2] == 1'b0) && (rast_l[2] == 1'b0))
	 begin
	   $display("\nDRAM Error:[%h]\n", $stime);
	   $display("\nBoth rasb_l[2] and rast_l[2] can't be asserted at the same time.\n");
	 end

	 if (rasb_l[2] == 1'b0)
	 	full_address[27:25]	= 3'b100;

	 if (rast_l[2] == 1'b0)
	 	full_address[27:25]	= 3'b101;

	$display("\nDRAM INFO: Read, Addrs=%h\n", full_address);

	Index = {7'b0, full_address[27:03]};
	Addr[27:03] = full_address[27:03];

        $mem_read(Msystem.TheRam.memHandle, Index, 8'b11111111, simm2.rd_data);
        $mem_read(Msystem.TheRam.parHandle, Index, 8'b00000011, simm2.rd_parity);
        $display("\nDRAM INFO:data Read=%h[%h]\n", simm2.rd_data, simm2.rd_parity);

                ParUpdateFlag = `NEGATED;
                if (simm2.rd_parity[1] == 1'b0) begin
                        simm2.rd_parity[1] = 1'b1;
                        simm2.rd_parity[0] = ^simm2.rd_data[31:0];
                        ParUpdateFlag = `ASSERTED;
                        end
                if (simm2.rd_parity[9] == 1'b0) begin
                        simm2.rd_parity[9] = 1'b1;
                        simm2.rd_parity[8] = ^simm2.rd_data[63:32];
                        ParUpdateFlag = `ASSERTED;
                        end
                if (ParUpdateFlag == `ASSERTED) begin
                        $mem_write(Msystem.TheRam.parHandle, Index, 8'b00000011, simm2.rd_parity);
                        end

        address_done = 1'b1;

	$display("\nDRAM INFO:data Read=%h[%h]\n", simm2.rd_data, simm2.rd_parity);

`ifdef DEBUG

	$display("TIME=%t, SIMM4, Full address=%h, Data0=%h\n",$stime,   full_address, simm2.rd_data);
	$display("============================================\n");

`endif

	simm2.start_read	<= #1 1'b0;			// Reset for next time.
	simm2.tAA_met		<= #1 0;
	simm2.tAA_done		<= #1 1;
        simm2.tCPA_met		<= #1 0;
        simm2.tCAC_met		<= #1 0;
        simm2.cac_met		<= #1 0;
        simm2.cpa_met		<= #1 0;
	simm2.colm_addrs	 = 32'hFFFF;
        address_done		<= #1 1'b0;

 end


// When is the time to read.
always @(posedge simm3.start_read)
 begin

	full_address = 32'b0;
	gen_full_addrs(simm3.row_addrs, simm3.colm_addrs, full_address);

	if ((rasb_l[3] == 1'b0) && (rast_l[3] == 1'b0))
	 begin
	   $display("\nDRAM Error:[%h]\n", $stime);
	   $display("\nBoth rasb_l[3] and rast_l[3] can't be asserted at the same time.\n");
	 end

	 if (rasb_l[3] == 1'b0)
	 	full_address[27:25]	= 3'b110;

	 if (rast_l[3] == 1'b0)
	 	full_address[27:25]	= 3'b111;

	Index = {7'b0, full_address[27:03]};
	Addr[27:03] = full_address[27:03];

        $mem_read(Msystem.TheRam.memHandle, Index, 8'b11111111, simm3.rd_data);
        $mem_read(Msystem.TheRam.parHandle, Index, 8'b00000011, simm3.rd_parity);
        $display("\nDRAM INFO:data Read=%h[%h]\n", simm3.rd_data, simm3.rd_parity);

                ParUpdateFlag = `NEGATED;
                if (simm3.rd_parity[1] == 1'b0) begin
                        simm3.rd_parity[1] = 1'b1;
                        simm3.rd_parity[0] = ^simm3.rd_data[31:0];
                        ParUpdateFlag = `ASSERTED;
                        end
                if (simm3.rd_parity[9] == 1'b0) begin
                        simm3.rd_parity[9] = 1'b1;
                        simm3.rd_parity[8] = ^simm3.rd_data[63:32];
                        ParUpdateFlag = `ASSERTED;
                        end
                if (ParUpdateFlag == `ASSERTED) begin
                        $mem_write(Msystem.TheRam.parHandle, Index, 8'b00000011, simm3.rd_parity);
                        end

        address_done = 1'b1;

`ifdef DEBUG

	$display("TIME=%t, SIMM6, Full address=%h, Data0=%h\n",$stime,   full_address, simm6.rd_data);
	$display("============================================\n");

`endif

	simm3.start_read	<= #1 1'b0;			// Reset for next time.
	simm3.tAA_met		<= #1 0;
	simm3.tAA_done		<= #1 1;
        simm3.tCPA_met		<= #1 0;
        simm3.tCAC_met		<= #1 0;
        simm3.cac_met		<= #1 0;
        simm3.cpa_met		<= #1 0;
	simm3.colm_addrs	 = 32'hFFFF;
        address_done		<= #1 1'b0;
 end

// Start writes now.
always @(posedge simm0.start_write)
 begin

	full_address2 = 32'b0;
	gen_full_addrs(simm0.row_addr, simm0.colm_addrs, full_address2);

	if ((rasb_l[0] == 1'b0) && (rast_l[0] == 1'b0))
	 begin
	   $display("\nDRAM Error:[%h]\n", $stime);
	   $display("\nBoth rasb_l[0]&rast_l[0] can't be asserted at the same time.\n");
	 end

	 if (rasb_l[0] == 1'b0)
	 	full_address2[27:25]	= 3'b000;

	 if (rast_l[0] == 1'b0)
	 	full_address2[27:25]	= 3'b001;

	Index = {7'b0, full_address2[27:03]};
	Addr[27:03] = full_address2[27:03];

         if ((EDO_cas_l[0] === 1'b0 ) || (EDO_cas_l[2] === 1'b0)) begin
                 $mem_write(Msystem.TheRam.memHandle, Index, 8'b11110000, simm0.wr_data);
                 mem_dump(full_address2[27:03],simm0.wr_data[63:32],0);
                 simm0.wr_parity[9] = 1'b1;   // valid bit for bank 0 (63:32) is 9
                 $mem_write(Msystem.TheRam.parHandle, Index, 8'b00000010, simm0.wr_parity);
                 end
         if ((EDO_cas_l[1] === 1'b0)|| (EDO_cas_l[3] === 1'b0))  begin
                 $mem_write(Msystem.TheRam.memHandle, Index, 8'b00001111, simm0.wr_data);
                 mem_dump(full_address2[27:03],simm0.wr_data[31:0],1);
                 simm0.wr_parity[1] = 1'b1;   // valid bit for bank 1 (31:0) is 1
                 $mem_write(Msystem.TheRam.parHandle, Index, 8'b00000001, simm0.wr_parity);
                 end

	$display("\nDRAM INFO:Write DATA=%h[%h]\n", simm0.wr_data, simm0.wr_parity);

`ifdef DEBUG

	$display("TIME=%t, SIMM0, Write, Full addr=%h, data0=%h\n",$stime,full_address2, simm0.wr_data);
	$display("============================================\n");

`endif

	simm0.start_write	<= #1 1'b0;
	simm0.colm_addrs	 = 32'hFFFF;
 end

always @(posedge simm1.start_write)
 begin

	full_address2 = 32'b0; 
	gen_full_addrs(simm1.row_addr, simm1.colm_addrs, full_address2);

	if ((rasb_l[1] == 1'b0) && (rast_l[1] == 1'b0))
	 begin
	   $display("\nDRAM Error:[%h]\n", $stime);
	   $display("\nBoth rasb_l[1]&rast_l[1] can't be asserted at the same time.\n");
	 end

	 if (rasb_l[1] == 1'b0)
	 	full_address2[27:25]	= 3'b010;

	 if (rast_l[1] == 1'b0)
	 	full_address2[27:25]	= 3'b011;

	Index = {7'b0, full_address2[27:03]};
	Addr[27:03] = full_address2[27:03];

         if ((EDO_cas_l[0] === 1'b0 ) || (EDO_cas_l[2] === 1'b0)) begin
                 $mem_write(Msystem.TheRam.memHandle, Index, 8'b11110000, simm1.wr_data);
                 mem_dump(full_address2[27:03],simm1.wr_data[63:32],0);
                 simm1.wr_parity[9] = 1'b1;   // valid bit for bank 0 (63:32) is 9
                 $mem_write(Msystem.TheRam.parHandle, Index, 8'b00000010, simm1.wr_parity);
                 end
         if ((EDO_cas_l[1] === 1'b0)|| (EDO_cas_l[3] === 1'b0))  begin
                 $mem_write(Msystem.TheRam.memHandle, Index, 8'b00001111, simm1.wr_data);
                 mem_dump(full_address2[27:03],simm1.wr_data[31:0],1);
                 simm1.wr_parity[1] = 1'b1;   // valid bit for bank 1 (31:0) is 1
                 $mem_write(Msystem.TheRam.parHandle, Index, 8'b00000001, simm1.wr_parity);
                 end

        $display("\nDRAM INFO:Write DATA=%h[%h]\n", simm1.wr_data, simm1.wr_parity);

`ifdef DEBUG

	$display("TIME=%t, SIMM2, Write, Full addr=%h, data0=%h\n",$stime,full_address2, simm1.wr_data);
	$display("============================================\n");

`endif

	simm1.start_write	<= #1 1'b0;
	simm1.colm_addrs	 = 32'hFFFF;
 end

always @(posedge simm2.start_write)
 begin

	full_address2 = 32'b0; 
	gen_full_addrs(simm2.row_addr, simm2.colm_addrs, full_address2);

	if ((rasb_l[2] == 1'b0) && (rast_l[2] == 1'b0))
	 begin
	   $display("\nDRAM Error:[%h]\n", $stime);
	   $display("\nBoth rasb_l[2]&rast_l[2] can't be asserted at the same time.\n");
	 end

	 if (rasb_l[2] == 1'b0)
	 	full_address2[27:25]	= 3'b100;

	 if (rast_l[2] == 1'b0)
	 	full_address2[27:25]	= 3'b101;

	Index = {7'b0, full_address2[27:03]};
	Addr[27:03] = full_address2[27:03];

         if ((EDO_cas_l[0] === 1'b0 ) || (EDO_cas_l[2] === 1'b0)) begin
                 $mem_write(Msystem.TheRam.memHandle, Index, 8'b11110000, simm2.wr_data);
                 mem_dump(full_address2[27:03],simm2.wr_data[63:32],0);
                 simm2.wr_parity[9] = 1'b1;   // valid bit for bank 0 (63:32) is 9
                 $mem_write(Msystem.TheRam.parHandle, Index, 8'b00000010, simm2.wr_parity);
                 end
         if ((EDO_cas_l[1] === 1'b0)|| (EDO_cas_l[3] === 1'b0))  begin
                 $mem_write(Msystem.TheRam.memHandle, Index, 8'b00001111, simm2.wr_data);
                 mem_dump(full_address2[27:03],simm2.wr_data[31:0],1);
                 simm2.wr_parity[1] = 1'b1;   // valid bit for bank 1 (31:0) is 1
                 $mem_write(Msystem.TheRam.parHandle, Index, 8'b00000001, simm2.wr_parity);
                 end

        $display("\nDRAM INFO:Write DATA=%h[%h]\n", simm2.wr_data, simm2.wr_parity);

`ifdef DEBUG

	$display("TIME=%t, SIMM2, Write, Full addr=%h, data0=%h\n",$stime,full_address2, simm2.wr_data);
	$display("============================================\n");

`endif

	simm2.start_write	<= #1 1'b0;
	simm2.colm_addrs	 = 32'hFFFF;
 end

always @(posedge simm3.start_write)
 begin

	full_address2 = 32'b0; 
	gen_full_addrs(simm3.row_addr, simm3.colm_addrs, full_address2);

	if ((rasb_l[3] == 1'b0) && (rast_l[3] == 1'b0))
	 begin
	   $display("\nDRAM Error:[%h]\n", $stime);
	   $display("\nBoth rasb_l[3] & rast_l[3] can't be asserted at the same time.\n");
	 end

	 if (rasb_l[3] == 1'b0)
	 	full_address2[27:25]	= 3'b110;

	 if (rast_l[3] == 1'b0)
	 	full_address2[27:25]	= 3'b111;

	Index = {7'b0, full_address2[27:03]};
	Addr[27:03] = full_address2[27:03];

         if ((EDO_cas_l[0] === 1'b0 ) || (EDO_cas_l[2] === 1'b0)) begin
                 $mem_write(Msystem.TheRam.memHandle, Index, 8'b11110000, simm3.wr_data);
                 mem_dump(full_address2[27:03],simm3.wr_data[63:32],0);
                 simm3.wr_parity[9] = 1'b1;   // valid bit for bank 0 (63:32) is 9
                 $mem_write(Msystem.TheRam.parHandle, Index, 8'b00000010, simm3.wr_parity);
                 end
         if ((EDO_cas_l[1] === 1'b0)|| (EDO_cas_l[3] === 1'b0))  begin
                 $mem_write(Msystem.TheRam.memHandle, Index, 8'b00001111, simm3.wr_data);
                 mem_dump(full_address2[27:03],simm3.wr_data[31:0],1);
                 simm3.wr_parity[1] = 1'b1;   // valid bit for bank 1 (31:0) is 1
                 $mem_write(Msystem.TheRam.parHandle, Index, 8'b00000001, simm3.wr_parity);
                 end

        $display("\nDRAM INFO:Write DATA=%h[%h]\n", simm3.wr_data, simm3.wr_parity);

`ifdef DEBUG

	$display("TIME=%t, SIMM3, Write, Full addr=%h, data0=%h\n",$stime,full_address2, simm3.wr_data);
	$display("============================================\n");

`endif

	simm3.start_write	<= #1 1'b0;
	simm3.colm_addrs	= 32'hFFFF;

 end

always @(negedge EDO_cas_l[0] or negedge EDO_cas_l[1] or negedge EDO_cas_l[2] or negedge EDO_cas_l[3]) begin
        if ((EDO_ras_l != 8'hff) && EDO_mwe_l) begin
                EDO_ram_output = 1'b1;
        end
end
 
always @(posedge EDO_cas_l[0] or posedge EDO_cas_l[1] or posedge EDO_cas_l[2] or posedge EDO_cas_l[3]) begin
        if (EDO_ram_output) begin
                EDO_ram_output = # RAM_DELAY_EDO 1'b0 ;
        end
end

simm	simm0(
		.data_out		(EDO_rd_data[63:0]), 
		.data_in		(EDO_wr_data[63:0]), 
		.parity_out		(EDO_rd_par[1:0]),
		.parity_in		(EDO_wr_par[1:0]),
		//.data           (b_memdata[63:0]), 
                //.parity         (b_mempar[1:0]),
		.simm_address	(EDO_memaddr[10:0]),
		.rast_l		(rast_l[0]), 
		.rasb_l		(rasb_l[0]), 
		.cas0_l		(EDO_cas_l[0]),
		.cas1_l		(EDO_cas_l[1]),
		.oe_l		(EDO_moe_l), 
                .we_l           (EDO_mwe_l)   
);

simm    simm1(
		.data_out		(EDO_rd_data[63:0]), 
		.data_in		(EDO_wr_data[63:0]), 
		.parity_out		(EDO_rd_par[1:0]),
		.parity_in		(EDO_wr_par[1:0]),
		//.data           (b_memdata[63:0]), 
                //.parity         (b_mempar[1:0]),
                .simm_address   (EDO_memaddr[10:0]),
                .rast_l         (rast_l[1]),
		.rasb_l         (rasb_l[1]), 
		.cas0_l         (EDO_cas_l[0]),
                .cas1_l         (EDO_cas_l[1]),
                .oe_l           (EDO_moe_l), 
                .we_l           (EDO_mwe_l)   
);

simm    simm2(
		.data_out		(EDO_rd_data[63:0]), 
		.data_in		(EDO_wr_data[63:0]), 
		.parity_out		(EDO_rd_par[1:0]),
		.parity_in		(EDO_wr_par[1:0]),
		//.data           (b_memdata[63:0]),  
                //.parity         (b_mempar[1:0]), 
                .simm_address   (EDO_memaddr[10:0]), 
                .rast_l         (rast_l[2]),
		.rasb_l         (rasb_l[2]),
		.cas0_l         (EDO_cas_l[0]),
                .cas1_l         (EDO_cas_l[1]),
                .oe_l           (EDO_moe_l),   
                .we_l           (EDO_mwe_l)  
);

simm	simm3(
		.data_out		(EDO_rd_data[63:0]), 
		.data_in		(EDO_wr_data[63:0]), 
		.parity_out		(EDO_rd_par[1:0]),
		.parity_in		(EDO_wr_par[1:0]),
		//.data           (b_memdata[63:0]),   
                //.parity         (b_mempar[1:0]),  
                .simm_address   (EDO_memaddr[10:0]),  
                .rast_l         (rast_l[3]),
		.rasb_l         (rasb_l[3]), 
		.cas0_l         (EDO_cas_l[0]),
                .cas1_l         (EDO_cas_l[1]),
                .oe_l           (EDO_moe_l),   
                .we_l           (EDO_mwe_l)   
);

task mem_dump;
        input [27:3] addr;
        input [31:0] data;
        input   odd_word;
        begin
                if (~mem_trace) begin
                        if (mem_mcd != 0) begin
                                $fclose(mem_mcd);
                                mem_mcd = 0;
                        end
                end
                else begin
                        if (mem_mcd == 0)
                                mem_mcd = $fopen({Mclocks.working_dir,"/mem_trace.v"});
                        if (mem_mcd != 0) begin
                                if (odd_word)
                                        $fdisplay(mem_mcd, "0x%h        0x%h    %g",{4'b0, addr[27:03],3'b100},data,Mclocks.cycle_count);
                                else
                                        $fdisplay(mem_mcd, "0x%h        0x%h    %g",{4'b0, addr[27:03],3'b000},data,Mclocks.cycle_count);
                        end
                        else $display( "dram: unable to open 'mem_trace.v'") ;
                end
        end
endtask
endmodule


/***********************************************************************************************************************************************
*		File name:	simm.v
*
*		Description:	Sabre simm model
*
*
*	Sun Proprietary!!
*
************************************************************************************************************************************************/

[Up: EDO_DRAM simm0][Up: EDO_DRAM simm1][Up: EDO_DRAM simm2][Up: EDO_DRAM simm3]
module simm (
		 data_out,
		 data_in,
		 parity_out,
		 parity_in,
		 simm_address,
		 rast_l,
		 rasb_l,
		 cas0_l,
		 cas1_l,
		 oe_l,			// YS
		 we_l
);



parameter 	
	//asize = 13,
	capacity  = 128;
	
	
output	[63:0]	data_out;					// data out of each simm is only 64 bits.
output	[1:0]  parity_out;					// 2 parity bits
input	[63:0]	data_in;					// data out of each simm is only 64 bits.
input	[1:0]  parity_in;					// 2 parity bits
input	[10:0]	simm_address;			// address to Dram.	
input	rasb_l;						// ras for bottom stack
input	rast_l; 					// ras for top stack
input	cas0_l; 					
input	cas1_l; 
input	oe_l;						// output enable. YS
input	we_l;						// write enable.
							// rasb_l and rast_l are needed for stacked simms which need
                                                        // special DRAMS which have 2 die in a single package or maybe
                                                        // two packages glued together.
                                                        // rasb_l selects bottom stack, rast_ selects top stack.


reg	[63:0]	rd_data;				// data from a read 
reg	[63:0]	rd_parity;				// parity from a read 
reg	[63:0]  wr_data;				// write data
reg	[63:0]  wr_parity;				// write parity
reg	[31:0]	row_addr;   
reg	[31:0]	first_col_addr;	
reg	[31:0]	prev_simm_addr;	
reg	[31:0]	curr_simm_addr;	

wire	cas_l = cas1_l & cas0_l;			// multiple copies of the same cas_l 

reg 		write_done;				// tells you when write completed
reg 		data_turn_off;				// tells you when to trigger tREZ monitor
reg		tRAC_met; 				// indicates when tRAC is met(RAS low to DATA)
reg		rac_met;
reg		tCAC_met;				// indicates when tCAC is met(Cas low to DATA) 
reg		cac_met;
reg		tAA_met;				// indicates first_access time is met 
reg		tAA_start;				// indicates first_access time is met 
reg		tAA_done;
reg		tCPA_met;				// indicates first_access time from cas precharge is met 
reg		cpa_met;
reg		first_access;			
reg		data_valid;				// to keep data on o/p port for tDOH after cas low.
reg	[2:0]	type_op;				// write operation if a 001, read if 010, refresh if 100. 

reg		tOEA_met;				// indicates when tOEA met (Oe_l low to DATA) YS
reg		oea_met;				// YS
reg		oez_min_met;				// indicates when tOEZ_MIN (oe_l high to DATA OFF min time) YS
reg		oez_max_met;				// indicates when tOEZ_MIN (oe_l high to DATA OFF max time) YS
reg		oez_met;				// any time between tOEZ min and max to turn data off YS
reg	[31:0]	rand;					// random value generated for oez_met YS

reg	[1:0]	whichRASprevAsserted;

reg		tRAD_max_rasb_chk_done;			// needed because tRAD check is a one time check after ras goes low
							// set this flag as soon as its checked once
reg		tRAD_min_rasb_chk_done;			// needed because tRAD min check is one time check	
reg		tRAD_min_rast_chk_done;
reg		tRAD_max_rast_chk_done;
reg		tRCD_chkd;
reg		tRAC_chkd;
reg		tRAH_chkd;
reg		tRP_chkd;
reg		tCSH_chkd;

reg		twrh_chk;				// required because twrh is a one time check

reg		row_address;				// tells you whether the address is row or column

reg  [31:0]	row_addrs;
reg  [31:0]	colm_addrs;

// YS  wire		oe_l = 0;				// output enable  tied to ground

integer		size8; 					// indicates # of bytes of data 			
integer		size1;					// indicates # of bytes of parity 
integer		n;				 
real	ticks_per_ns;
	initial
	begin
	ticks_per_ns = 1.4;				// simulation ticks per nanosec
	end

reg		start_write, start_read;

integer		oe_high_cycle; 				// record cycle# @ posedge of oe_l 
integer		oe_low_cycle;				// record cycle# @ negedge of oe_l 
integer		we_high_cycle; 				// record cycle# @ posedge of we_l 
integer		we_low_cycle;				// record cycle# @ negedge of we_l 
integer         tRP;
integer         tRAS;
integer		cas_high_cycle;				// record cycle#  @ posedge of cas_l 
integer		cas_low_cycle; 				// record cycle#  @ negedge of cas_l 
integer		cas_prev_low_cycle;			// required in cases where data and subsequent cas low happen
integer		cas_prev_high_cycle;			// required to monitor tHPC.
Next1234
HierarchyFilesModulesSignalsTasksFunctionsHelp

This page: Created:Thu Aug 19 12:01:39 1999
From: ../../../sparc_v8/system/rtl/dram.v

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