OpenCores
URL https://opencores.org/ocsvn/mem_ctrl/mem_ctrl/trunk

Subversion Repositories mem_ctrl

[/] [mem_ctrl/] [trunk/] [bench/] [richard/] [verilog/] [models/] [m8kx8.v] - Rev 29

Go to most recent revision | Compare with Previous | Blame | View Log

///////////////////////////////////////////////////////////////////////
////                                                               ////
////  CY7C185 model (Cypress 8kx8 fast asynchronous sram)          ////
////                                                               ////
////                                                               ////
////  Author: Richard Herveille                                    ////
////          richard@asics.ws                                     ////
////          www.asics.ws                                         ////
////                                                               ////
////  Downloaded from: http://www.opencores.org/projects/mem_ctrl  ////
////                                                               ////
///////////////////////////////////////////////////////////////////////
////                                                               ////
//// Copyright (C) 2002 Richard Herveille                          ////
////                    richard@asics.ws                           ////
////                                                               ////
//// This source file may be used and distributed without          ////
//// restriction provided that this copyright statement is not     ////
//// removed from the file and that any derivative work contains   ////
//// the original copyright notice and the associated disclaimer.  ////
////                                                               ////
////     THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY       ////
//// EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED     ////
//// TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS     ////
//// FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR        ////
//// OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,           ////
//// INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES      ////
//// (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE     ////
//// GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR          ////
//// BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF    ////
//// LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT    ////
//// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT    ////
//// OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE           ////
//// POSSIBILITY OF SUCH DAMAGE.                                   ////
////                                                               ////
///////////////////////////////////////////////////////////////////////
 
//  CVS Log
//
//  $Id: m8kx8.v,v 1.1 2002-03-06 15:15:35 rherveille Exp $
//
//  $Date: 2002-03-06 15:15:35 $
//  $Revision: 1.1 $
//  $Author: rherveille $
//  $Locker:  $
//  $State: Exp $
//
//
 
`timescale 1ns/10ps
 
module A8Kx8(Address, dataIO, OEn, CE1n, CE2, WEn);
 
	//
	// parameters
	//
 
	//
	// inputs & outputs
	//
	input [12:0] Address;
	inout [ 7:0] dataIO;
	input        OEn;
	input        CE1n;
	input        CE2;
	input        WEn;
 
	//
	// variables
	//
	reg [ 7:0] mem_array  [8191:0];
 
	reg delayed_WE;
	reg [ 7:0] data_temp, dataIO1;
	reg is_write;
 
	wire CE = !CE1n && CE2;
	reg OE_OEn, OE_CE;
	wire OE = OE_OEn && OE_CE;
 
	reg read_cycle1, read_cycle2;
 
	time Trc;
	time Taa;
	time Toha;
	time Tace;
	time Tdoe;
	time Tlzoe;
	time Thzoe;
	time Tlzce;
	time Thzce;
 
	time Twc;
	time Tsce;
	time Taw;
	time Tpwe;
	time Tsd;
	time Thzwe;
	time Tlzwe;
 
	time CE_start, CE_end;
	time write_WE_start, read_WE_start;
	time dataIO_start;	
	time Address_start;
	time OEn_start,  OEn_end;
 
	initial
		begin
			read_cycle1 = 1'b0;
			read_cycle2 = 1'b0;
 
			// read cycle
			Trc   = 20;
			Taa   = 20;
			Toha  = 5;
			Tace  = 20;
			Tdoe  = 9;
			Tlzoe = 3;
			Thzoe = 8;
			Tlzce = 5; // not completely accurate. Tlzce2 = 3ns
			Thzce = 8;
 
			// write cycle
			Twc   = 20;
			Tsce  = 15;
			Taw   = 15;
			Tpwe  = 15;
			Tsd   = 10;
			Thzwe = 7;
			Tlzwe = 5;
		end
 
	//
	// module body
	//
 
	// assign output
	assign dataIO = (OE && !delayed_WE) ? data_temp : 8'bz;
 
	// assign times
 
	always@(posedge CE)
		begin
			CE_start <= $time;
 
			#Tlzce OE_CE <= CE;
		end
 
	always@(negedge CE)
		begin
			CE_end <= $time;
 
			#Thzce OE_CE <= CE;
		end
 
	always@(dataIO)
		begin
			dataIO_start <= $time;
		end
 
	always@(negedge WEn)
		begin
			write_WE_start <= $time;
 
			# Thzwe delayed_WE <= !WEn;
		end
 
	always@(posedge WEn)
		begin
			read_WE_start <= $time;
 
			#Tlzwe delayed_WE <= !WEn;
		end
 
	always@(Address)
		begin
			Address_start <= $time;
		end
 
	always@(negedge OEn)
		begin
			OEn_start <= $time;
 
			#Tlzoe OE_OEn <= !OEn;
		end
 
	always@(posedge OEn)
		begin
			OEn_end <= $time;
 
			#Thzoe OE_OEn <= !OEn;
		end
	//
	// write cycles
	//
 
	always@(WEn or CE)
		is_write <= !WEn && CE;
 
	// write cycle no.1 & no.3 WE controlled
	always@(posedge WEn or negedge CE)
		begin
			// check if CE asserted ( CE1n == 1'b0 && CE2 == 1'b1)
			if (is_write)
			begin
 
				// check WE valid time
				if ( ($time - write_WE_start) >= Tpwe)
				begin
 
					// check CE valid time
					if ( ($time - CE_start) >= Tsce)
					begin
 
						// check data_in setup-time
						if ( ($time - dataIO_start) >= Tsd)
						begin
 
							// check address valid time
							if ( ($time - Address_start >= Taw) )
								mem_array[Address] <= dataIO;
							else
								$display("Address setup to WE write end violation at time %t", $time);
						end
						else
							$display("Data setup to WE write end violation at time %t", $time);
					end
					else
						$display("CE to WE write end violation at time %t", $time);
				end
				else
					$display("WE pulse width violation at time %t", $time);
			end
		end
 
 
	//
	// Read cycles
	//
 
	always@(Address or WEn or CE or OEn)
		begin
			// check if valid read cycle
			if (CE && WEn)
				begin
					if ( (($time - CE_start) >= Trc) && (CE_start >= CE_end) &&
							(($time - OEn_start) >= Trc) && (OEn_start >= OEn_end) ) // ???
						begin
 
							// check Trc
							if ( ($time - Address_start < Trc) )
							begin
								$display("Read cycle time violation, caused by address change at time %t", $time);
								$display("CE: %t, OEn: %t, Adr: %t", $time - CE_start, $time - OEn_start, $time - Address_start);
							end
 
							// read cycle no.1
							read_cycle1 <= 1'b1;
							read_cycle2 <= 1'b0;
						end
					else
						begin
							// read cycle no.2
							read_cycle1 <= 1'b0;
							read_cycle2 <= 1'b1;
						end
				end
			else
				begin
					read_cycle1 = 1'b0;
					read_cycle2 = 1'b0;
				end
		end
 
 
	// perform actual read
	always
		begin
			#1;
			if (read_cycle1)
				if ( ($time - Address_start) >= Taa)
					data_temp <= mem_array[Address];
				else if ( ($time - Address_start >= Toha) )
					data_temp <= 8'bx;
 
			if (read_cycle2)
				if ( (($time - OEn_start) >= Tdoe) && (($time - CE_start) >= Tace) )
					data_temp <= mem_array[Address];
				else if ( (($time - OEn_start) >= Tlzoe) && (($time - CE_start) >= Tlzce) )
					data_temp <= 8'bx;
		end
 
endmodule
 
 
 
 

Go to most recent revision | Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.