idxTmplt[15] = "S1L50k_port2_RTL_VHDL" ; tmplt[15] = [ "-- S1L50000 Sync. 2 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 is changed to X, all written data become X.", "", "-- Ver. 1.0 2007/09/xx Mori, Masaru", "--# Created.", "", "library IEEE ;", "use IEEE.std_logic_1164.all ;", "use IEEE.STD_LOGIC_UNSIGNED.ALL ;", "use IEEE.std_logic_textio.all ;", "use std.textio.all ;", "", "entity %CellName% is", " generic( DEPTH : integer := %Depth% ;", " ADDR_W : integer := %WidthAddr% ; -- Address width", " DATA_W : integer := %WidthData% ); -- Data width", "", " port( FCS, CKA, XWA, CKB, XRB : in std_logic ;", " %EachAddr , AA% : in std_logic ;", " %EachData , D% : in std_logic ;", " %EachAddr , AB% : in std_logic ;", " %EachData , Y% : out std_logic );", "end %CellName% ;", "", "architecture behavior of %CellName% is", "", " subtype WORD is std_logic_vector( DATA_W - 1 downto 0 );", " type MEMORY is array ( 0 to DEPTH - 1 ) of WORD ;", " signal MEM : MEMORY ;", "", " signal ADDR_A, ADDR_B : std_logic_vector( ADDR_W - 1 downto 0 );", " signal REG_A, REG_B : std_logic_vector( ADDR_W - 1 downto 0 );", " signal D_IN, D_OUT : std_logic_vector( DATA_W - 1 downto 0 );", " signal REG_XWA : std_logic ;", " signal READ_OK : boolean ;", "", "begin", " ADDR_A <= %EachAddr & AA% ;", "%OneBitData% D_IN(0) <= D0 ;", "%MulBitData% D_IN <= %EachData & D% ;", " ADDR_B <= %EachAddr & AB% ;", "%LineData% Y%IndexData% <= D_OUT(%IndexData%) when FCS = '1' else 'X' ;", "", " D_OUT <= MEM( conv_integer( REG_B ) ) when READ_OK else ( others => 'X' );", "", " -- Write ------------------------------------------------------------", " WRITE_FUNC : process( CKA )", " variable IDX : integer ; -- Index (Integer of ADDR)", " variable XJUDGE, XJUDGE_R : std_logic ; -- if ADDR include 'X', this is 'X'", " variable WR_LINE : line ; -- to write error message", " begin", " -- Rise --", " if( CKA'event and CKA = '1' )then", "", " REG_XWA <= XWA ;", " REG_A <= ADDR_A ;", "", " -- Check if ADDR_A include 'X' --", " XJUDGE := ADDR_A(0) ;", " for IDX in 1 to ADDR_W - 1 loop", " XJUDGE := XJUDGE xor ADDR_A( IDX );", " end loop ;", "", " -- write --", " if( (XWA = '0') and (FCS = '1') )then", " -- normal Write (ADDR is clean) --", " if( (XJUDGE = '0') or (XJUDGE = '1') )then", " if( conv_integer( ADDR_A ) < DEPTH )then", " MEM( conv_integer( ADDR_A ) ) <= D_IN ;", "", " else", " write( WR_LINE, string'( \"RAM Error(at \" ) );", " write( WR_LINE, now );", " write( WR_LINE, string'( \")! non-existing RAM wr. address is accessed.\" ) );", " writeline( output, WR_LINE );", " end if ;", "", " -- AA include 'X' --", " else", " for I in 0 to DEPTH - 1 loop", " MEM( I ) <= ( others => 'X' );", " end loop ;", " end if ;", "", " -- probably write --", " elsif( (XWA /= '1') and (FCS /= '0') )then", " -- normal Write (ADDR is clean) --", " if( (XJUDGE = '0') or (XJUDGE = '1') )then", " if( conv_integer( ADDR_A ) < DEPTH )then", " MEM( conv_integer( ADDR_A ) ) <= ( others => 'X' );", "", " else", " write( WR_LINE, string'( \"RAM Error(at \" ) );", " write( WR_LINE, now );", " write( WR_LINE, string'( \")! non-existing RAM wr. address is accessed.\" ) );", " writeline( output, WR_LINE );", " end if ;", "", " -- AA include 'X' --", " else", " for I in 0 to DEPTH - 1 loop", " MEM( I ) <= ( others => 'X' );", " end loop ;", " end if ;", " end if ;", "", " -- CKA is X --", " elsif( CKA'event and CKA /= '0' )then", " if( XWA /= REG_XWA )then", " REG_XWA <= 'X' ;", " end if ;", "", " -- Check if ADDR_A include 'X' --", " XJUDGE_R := REG_A(0) ;", " for IDX in 1 to ADDR_W - 1 loop", " XJUDGE_R := XJUDGE_R xor REG_A( IDX );", " end loop ;", "", " if( ( (XJUDGE = '0') or (XJUDGE = '1') )", " and ( (XJUDGE_R = '0') or (XJUDGE_R = '1') ) )then", " if( ADDR_A /= REG_A )then", " REG_A <= ( others => 'X' );", " XJUDGE_R := 'X' ;", " end if ;", " else", " REG_A <= ( others => 'X' );", " XJUDGE_R := 'X' ;", " end if ;", "", " -- probably write --", " if( (XWA /= '1') or (REG_XWA /= '1') )then", "", " -- if AA is clean --", " if( (XJUDGE_R = '0') or (XJUDGE_R = '1') )then", " if( conv_integer( ADDR_A ) < DEPTH )then", " MEM( conv_integer( ADDR_A ) ) <= ( others => 'X' );", "", " else", " write( WR_LINE, string'( \"RAM Error(at \" ) );", " write( WR_LINE, now );", " write( WR_LINE, string'( \")! non-existing RAM wr. address is accessed.\" ) );", " writeline( output, WR_LINE );", " end if ;", "", " else", " for I in 0 to DEPTH - 1 loop", " MEM( I ) <= ( others => 'X' );", " end loop ;", " end if ;", " end if ;", " end if ;", " end process ; -- end of WRITE_FUNC", "", " -- Read -------------------------------------------------------------", " READ_FUNC : process( CKB )", " variable IDX : integer ; -- Index (Integer of ADDR)", " variable XJUDGE : std_logic ; -- if ADDR include 'X', this is 'X'", " variable WR_LINE : line ; -- to write error message", " begin", " if( CKB'event and CKB = '1' )then", "", " -- Check if ADDR_B include 'X' --", " XJUDGE := ADDR_B(0) ;", " for IDX in 1 to ADDR_W - 1 loop", " XJUDGE := XJUDGE xor ADDR_B( IDX );", " end loop ;", "", " REG_B <= ADDR_B ;", "", " if( (XRB = '0') and (FCS = '1') )then", " -- AB is clean --", " if( (XJUDGE = '0') or (XJUDGE = '1') ) then", " if( conv_integer( ADDR_B ) < depth )then", " -- Even if no CKB, read the written data", " READ_OK <= true ;", "", " -- AB is out of range --", " else", " READ_OK <= false ;", " write( WR_LINE, string'( \"RAM Error(at \" ) );", " write( WR_LINE, now );", " write( WR_LINE, string'( \")! non-existing RAM rd. address is accessed.\" ) );", " writeline( output, WR_LINE );", " end if ;", "", " -- AB include 'X' --", " else", " READ_OK <= false ;", " end if ;", "", " -- XRB == 1 or X, or FCS == 0 or X --", " else", " READ_OK <= false ;", " end if ;", "", " -- CKB is X --", " elsif( CKB'event and CKB /= '0' )then", " READ_OK <= false ;", " end if ; -- CKB", " end process ; -- end of READ_FUNC", "end behavior ;" ];