idxTmplt[8] = "S1L50k_port1_RTL_Veri" ; tmplt[8] = [ "// S1L50000 Sync. 1 port RAM RTL Simulation Library", "// * This model does not latch the last data when XCS = 1.", "// * Actual module is soft-macro by using Asynchronous RAM", "// * Function might not correct if FCS is not kept 1.", "", "// Note. If CK become X, all written data are made X.", "", "// SEIKO EPSON", "//#Ver. 1.0 2006/09/xx Mori, Masaru", "//# Created", "//#Ver. 1.1 2006/10/11 Mori, Masaru", "//# Correct the bug of endless loop", "//#Ver. 1.2 2006/10/23 Mori, Masaru", "//# Change \"!=\" to \"!==\"", "//#Ver. 1.3 2006/10/30 Mori, Masaru", "//# Add the function for CK = X", "// Ver. 1.4 2007/08/xx Mori, Masaru", "//# Use new keywords.", "//# Add the checking ADDR < depth at CK is fallen,", "//# and also when FCS != 0(CK is rised).", "", "module %CellName% ( CK, XCS, XWE, FCS,", " %EachAddr , A%,", " %EachData , D%,", " %EachData , Y% );", "", " parameter depth = %Depth% ;", " parameter addr_width = %WidthAddr% ;", " parameter data_width = %WidthData% ;", "", " input CK, XCS, XWE ;", " input FCS ; // Force CS (to turn off asynchronous CS directly)", " input %EachAddr , A% ;", " input %EachData , D% ;", " output %EachData , Y% ;", "", " reg [data_width-1:0] mem [depth-1:0] ;", "", " wire [addr_width-1:0] ADDR ;", " reg [addr_width:0] tmpADDR ; // to write x to all addr. One bit bigger", " wire [data_width-1:0] D_IN ;", " reg [data_width-1:0] D_OUT ;", " reg RegXCS, RegXWE ; // to make write after read function", " reg [addr_width-1:0] RegADDR ; // /", "", " assign ADDR = { %EachAddr , A% };", " assign D_IN = { %EachData , D% };", " assign { %EachData , Y% } = (FCS == 1'b1)? D_OUT : 'bx ;", "", " always @( CK )begin", " if( CK == 1'b1 )begin //--- CK is Risen ---", " RegXCS <= XCS ; // for write after read function at CK falling", " RegXWE <= XWE ; // /", " RegADDR <= ADDR ; // /", "", " //--- XCS is active -----------------------------------------------------", " if( XCS == 1'b0 )begin", " if( (XWE == 1'b0) && (FCS == 1'b1) )begin //--- Write mode (clean) ---", " if( ADDR == ADDR )begin //--- addr. is not x ---", " if( ADDR < depth )begin", " D_OUT = 'hx ;", " mem[ADDR] = D_IN ;", "", " end else begin", " D_OUT = 'hx ;", " $display( \"RAM Error(at %t)! non-existing RAM address is accessed.\", $time );", " end", "", " end else begin //--- if addr. is x, write x to all addr. ---", " D_OUT = 'hx ;", " for( tmpADDR = 0; tmpADDR < depth; tmpADDR = tmpADDR + 1 )begin", " mem[tmpADDR] = 'hx ;", " end", " end", "", " end else if( XWE == 1'b1 )begin //--- Read mode (clean) ---", " if( ADDR < depth )begin", " D_OUT = mem[ADDR] ;", "", " end else begin", " D_OUT = 'hx ;", " $display( \"RAM Error(at %t)! non-existing RAM address is accessed.\", $time );", " end", "", " end else if( FCS !== 1'b0 )begin //--- XWE == x ---", " if( ADDR == ADDR )begin //--- addr. is not x ---", " D_OUT = 'hx ;", " mem[ADDR] <= 'hx ;", "", " end else begin //--- addr. is x ---", " D_OUT = 'hx ;", " for( tmpADDR = 0; tmpADDR < depth; tmpADDR = tmpADDR + 1 )begin", " mem[tmpADDR] = 'hx ;", " end", " end", " end", "", " //--- XCS is 1 ----------------------------------------------------------", " end if( XCS == 1'b1 )begin", " D_OUT = 'hx ;", "", " //--- XCS is x ----------------------------------------------------------", " end if( XCS === 1'bx )begin", " if( (XWE == 1'b0) && (FCS == 1'b1) )begin //--- Write mode (XCS=x) ---", " if( ADDR == ADDR )begin //--- addr. is not x ---", " if( ADDR < depth )begin", " D_OUT = 'hx ;", " mem[ADDR] = 'hx ;", "", " end else begin", " D_OUT = 'hx ;", " $display( \"RAM Error(at %t)! non-existing RAM address is accessed.\", $time );", " end", "", " end else begin //--- addr. is x ---", " D_OUT = 'hx ;", " for( tmpADDR = 0; tmpADDR < depth; tmpADDR = tmpADDR + 1 )begin", " mem[tmpADDR] = 'hx ;", " end", " end", "", " end else if( XWE == 1'b1 )begin //--- Read mode ---", " if( ADDR < depth )begin", " D_OUT = 'hx ;", "", " end else begin", " D_OUT = 'hx ;", " $display( \"RAM Error(at %t)! non-existing RAM address is accessed.\", $time );", " end", "", " end else if( FCS !== 1'b0 )begin //--- XWE == x ---", " if( ADDR == ADDR )begin //--- addr. is not x ---", " D_OUT = 'hx ;", " if( ADDR < depth )begin", " mem[ADDR] <= 'hx ;", " end", "", " end else begin //--- addr. is x ---", " D_OUT = 'hx ;", " for( tmpADDR = 0; tmpADDR < depth; tmpADDR = tmpADDR + 1 )begin", " mem[tmpADDR] = 'hx ;", " end", " end", " end", " end", "", " //--- When CK is fallen, write after read function is occurred ------------", " end else if( CK == 1'b0 )begin", " if( (RegXCS == 1'b0) && (RegXWE == 1'b0) && (RegADDR == RegADDR) )begin", " if( RegADDR < depth )begin", " D_OUT = mem[RegADDR] ;", " end else begin", " D_OUT = 'hx ;", " end", " end", "", " //--- If CK is X, All asynchronous signals are X --------------------------", " end else begin // for safer, do not care FCS", " D_OUT = 'hx ;", " for( tmpADDR = 0; tmpADDR < depth; tmpADDR = tmpADDR + 1 )begin", " mem[tmpADDR] = 'hx ;", " end", " end", " end", "", "endmodule" ];