📄 orca_l.vhd
字号:
-- else -- v_MEM(v_OFFSET + k) := 'X'; end if; end loop; v_LINE := v_LINE + 1; v_OFFSET := v_OFFSET + WDATA_WIDTH_A; end loop; end READ_MEM_INIT_FILE;---------------------------------------------------------------------------- Function: Valid_Address -- Description: --------------------------------------------------------------------------function Valid_Address ( IN_ADDR : in std_logic_vector ) return boolean is variable v_Valid_Flag : boolean := TRUE; begin for i in IN_ADDR'high downto IN_ADDR'low loop if (IN_ADDR(i) /= '0' and IN_ADDR(i) /= '1') then v_Valid_Flag := FALSE; end if; end loop; return v_Valid_Flag;end Valid_Address;---------------------------------------------------------------------------- Signal Declaration----------------------------------------------------------------------------------- Local signals used to propagate input wire delay ---------------signal WADA_node : std_logic_vector( WADDR_WIDTH_A -1 downto 0) := (others => '0');signal WEA_node : std_logic := 'X';signal WDA_node : std_logic_vector( WDATA_WIDTH_A -1 downto 0) := (others => 'X');signal RADA_node : std_logic_vector( RADDR_WIDTH_A -1 downto 0) := (others => '0');signal REA_node : std_logic := 'X';signal RDA_node : std_logic_vector( RDATA_WIDTH_A -1 downto 0) := (others => 'X');signal WADB_node : std_logic_vector( WADDR_WIDTH_B -1 downto 0) := (others => '0');signal WEB_node : std_logic := 'X';signal WDB_node : std_logic_vector( WDATA_WIDTH_B -1 downto 0) := (others => 'X');signal RADB_node : std_logic_vector( RADDR_WIDTH_B -1 downto 0) := (others => '0');signal REB_node : std_logic := 'X';signal RDB_node : std_logic_vector( RDATA_WIDTH_B -1 downto 0) := (others => 'X');signal WCLK_node : std_logic := 'X';signal RCLK_node : std_logic := 'X';-- architecturebegin WADA_node <= WADA; WEA_node <= WEA; WDA_node <= WDA; RADA_node <= RADA; REA_node <= REA; RDA <= RDA_node; WADB_node <= WADB; WEB_node <= WEB; WDB_node <= WDB; RADB_node <= RADB; REB_node <= REB; RDB <= RDB_node; WCLK_node <= WCLK; RCLK_node <= RCLK;-------------------------------------------------- Behavior process ------------------------------------------------------ --KERNEL_BEHAV : process( WADA_node, WEA_node, WDA_node, RADA_node, REA_node, WADB_node, WEB_node, WDB_node, RADB_node, REB_node)KERNEL_BEHAV : process( WCLK_node, RCLK_node)--TSPEC: A note about sram initial values and rom mode: -- If the user does not provide any values, ... default 0 -- for all ram locations in JECED variable v_MEM : std_logic_vector(ARRAY_SIZE*WDATA_WIDTH_A - 1 downto 0) := ( others => '0' ); variable v_INI_DONE : boolean := FALSE; variable v_WADDR_A : integer; variable v_RADDR_A : integer; variable v_WADDR_B : integer; variable v_RADDR_B : integer; variable v_WADDRA_Valid_Flag : boolean := TRUE; variable v_WADDRB_Valid_Flag : boolean := TRUE; variable v_RADDRA_Valid_Flag : boolean := TRUE; variable v_RADDRB_Valid_Flag : boolean := TRUE; begin -- Process if( MEM_INIT_FLAG = 1 and v_INI_DONE = FALSE) THEN READ_MEM_INIT_FILE(MEM_INIT_FILE, v_MEM); v_INI_DONE := TRUE; end if; -- Address Check v_WADDRA_Valid_Flag := Valid_Address(WADA_node); v_WADDRB_Valid_Flag := Valid_Address(WADB_node); v_RADDRA_Valid_Flag := Valid_Address(RADA_node); v_RADDRB_Valid_Flag := Valid_Address(RADB_node); if ( v_WADDRA_Valid_Flag = TRUE ) then v_WADDR_A := CONV_INTEGER(WADA_node);-- else -- assert (Now = 0 ps) -- report "Write AddressA of Port contains invalid bit!"-- severity warning; end if; if (v_WADDRB_Valid_Flag = TRUE ) then v_WADDR_B := CONV_INTEGER(WADB_node); else-- assert (Now = 0 ps)-- report "Write AddressB of Port contains invalid bit!"-- severity warning; end if; if (v_RADDRA_Valid_Flag = TRUE ) then v_RADDR_A := CONV_INTEGER(RADA_node);-- else-- assert (Now = 0 ps)-- report "Read AddressA of Port contains invalid bit!"-- severity warning; end if; if (v_RADDRB_Valid_Flag = TRUE ) then v_RADDR_B := CONV_INTEGER(RADB_node);-- else-- assert (Now = 0 ps)-- report "Read AddressB of Port contains invalid bit!"-- severity warning; end if; -- CHECK Operation if (WEA = '1' and WEB = '1' and not( (v_WADDR_A*WDATA_WIDTH_A + WDATA_WIDTH_A -1) < (v_WADDR_B*WDATA_WIDTH_B) or (v_WADDR_B*WDATA_WIDTH_B + WDATA_WIDTH_B -1) < (v_WADDR_A*WDATA_WIDTH_A) ) ) then assert false report " Write collision! Writing in the same memory location using Port A and Port B will cause the memory content invalid." severity warning; end if; -- MEM Operation if (WEA_node = '1' and WCLK_node'event and WCLK_node = '1' ) then v_MEM((v_WADDR_A*WDATA_WIDTH_A + WDATA_WIDTH_A -1) downto (v_WADDR_A*WDATA_WIDTH_A)) := WDA_node; end if; if (WEB_node = '1' and WCLK_node'event and WCLK_node = '1') then v_MEM((v_WADDR_B*WDATA_WIDTH_B + WDATA_WIDTH_B -1) downto (v_WADDR_B*WDATA_WIDTH_B)) := WDB_node; end if; if (REA_node = '1' and RCLK_node'event and RCLK_node = '1') then RDA_node <= v_MEM((v_RADDR_A*RDATA_WIDTH_A + RDATA_WIDTH_A -1) downto (v_RADDR_A*RDATA_WIDTH_A));-- else-- RDA_node <= ( others => 'X'); end if; if (REB_node = '1' and RCLK_node'event and RCLK_node = '1') then RDB_node <= v_MEM((v_RADDR_B*RDATA_WIDTH_B + RDATA_WIDTH_B -1) downto (v_RADDR_B*RDATA_WIDTH_B));-- else-- RDB_node <= ( others => 'X'); end if; end process KERNEL_BEHAV; end LATTICE_BEHAV;library std;use std.textio.all;library ieee, std;use ieee.std_logic_1164.all;use ieee.std_logic_unsigned.all;use std.textio.all;-- ************************************************************************-- Entity definition -- "generic" members -- ************************************************************************entity SC_BRAM_PDP_16K_L is generic ( WADDR_WIDTH_A : integer := 14; RADDR_WIDTH_A : integer := 12; WADDR_WIDTH_B : integer := 14; RADDR_WIDTH_B : integer := 12; WDATA_WIDTH_A : integer := 1; RDATA_WIDTH_A : integer := 4; WDATA_WIDTH_B : integer := 1; RDATA_WIDTH_B : integer := 4; ARRAY_SIZE : integer := 262144; MEM_INIT_FLAG : integer := 0; MEM_INIT_FILE : string := "" ); port ( WADA : in STD_LOGIC_VECTOR (WADDR_WIDTH_A -1 downto 0); WEA : in STD_LOGIC ; WDA : in STD_LOGIC_VECTOR (WDATA_WIDTH_A -1 downto 0); RADA : in STD_LOGIC_VECTOR (RADDR_WIDTH_A -1 downto 0); REA : in STD_LOGIC ; RDA : out STD_LOGIC_VECTOR (RDATA_WIDTH_A -1 downto 0); WADB : in STD_LOGIC_VECTOR (WADDR_WIDTH_B -1 downto 0); WEB : in STD_LOGIC; WDB : in STD_LOGIC_VECTOR (WDATA_WIDTH_B -1 downto 0); RADB : in STD_LOGIC_VECTOR (RADDR_WIDTH_B -1 downto 0); REB : in STD_LOGIC; RDB : out STD_LOGIC_VECTOR (RDATA_WIDTH_B -1 downto 0) ); end SC_BRAM_PDP_16K_L;-- ************************************************************************-- Architecture-- ************************************************************************architecture LATTICE_BEHAV of SC_BRAM_PDP_16K_L isprocedure READ_MEM_INIT_FILE( f_name : IN STRING; v_MEM : OUT STD_LOGIC_VECTOR ) IS file f_INIT_FILE : TEXT is MEM_INIT_FILE; variable v_WORD : line; variable v_GOODFLAG : boolean; variable v_WORD_BIT : string (WDATA_WIDTH_A downto 1) ; variable v_CHAR : character; variable v_OFFSET : integer := 0; variable v_LINE : integer := 0; begin while ( not(endfile(f_INIT_FILE)) and (v_LINE < 2**WADDR_WIDTH_A)) loop readline(f_INIT_FILE, v_WORD); read(v_WORD, v_WORD_BIT, v_GOODFLAG); for k in 0 to WDATA_WIDTH_A - 1 loop v_CHAR := v_WORD_BIT (k + 1); if (v_CHAR = '1') then v_MEM(v_OFFSET + k) := '1'; elsif (v_CHAR = '0') then v_MEM(v_OFFSET + k) := '0';-- else -- v_MEM(v_OFFSET + k) := 'X'; end if; end loop; v_LINE := v_LINE + 1; v_OFFSET := v_OFFSET + WDATA_WIDTH_A; end loop; end READ_MEM_INIT_FILE;---------------------------------------------------------------------------- Function: Valid_Address -- Description: --------------------------------------------------------------------------function Valid_Address ( IN_ADDR : in std_logic_vector ) return boolean is variable v_Valid_Flag : boolean := TRUE; begin for i in IN_ADDR'high downto IN_ADDR'low loop if (IN_ADDR(i) /= '0' and IN_ADDR(i) /= '1') then v_Valid_Flag := FALSE; end if; end loop; return v_Valid_Flag;end Valid_Address;---------------------------------------------------------------------------- Signal Declaration----------------------------------------------------------------------------------- Local signals used to propagate input wire delay ---------------signal WADA_node : std_logic_vector( WADDR_WIDTH_A -1 downto 0) := (others => '0');signal WEA_node : std_logic := 'X';signal WDA_node : std_logic_vector( WDATA_WIDTH_A -1 downto 0) := (others => 'X');signal RADA_node : std_logic_vector( RADDR_WIDTH_A -1 downto 0) := (others => '0');signal REA_node : std_logic := 'X';signal RDA_node : std_logic_vector( RDATA_WIDTH_A -1 downto 0) := (others => 'X');signal WADB_node : std_logic_vector( WADDR_WIDTH_B -1 downto 0) := (others => '0');signal WEB_node : std_logic := 'X';signal WDB_node : std_logic_vector( WDATA_WIDTH_B -1 downto 0) := (others => 'X');signal RADB_node : std_logic_vector( RADDR_WIDTH_B -1 downto 0) := (others => '0');signal REB_node : std_logic := 'X';signal RDB_node : std_logic_vector( RDATA_WIDTH_B -1 downto 0) := (others => 'X');-- architecturebegin WADA_node <= WADA; WEA_node <= WEA; WDA_node <= WDA; RADA_node <= RADA; REA_node <= REA; RDA <= RDA_node; WADB_node <= WADB; WEB_node <= WEB; WDB_node <= WDB; RADB_node <= RADB; REB_node <= REB; RDB <= RDB_node;-------------------------------------------------- Behavior process ------------------------------------------------------ KERNEL_BEHAV : process( WADA_node, WEA_node, WDA_node, RADA_node, REA_node, WADB_node, WEB_node, WDB_node, RADB_node, REB_node)--TSPEC: A note about sram initial values and rom mode: -- If the user does not provide any values, ... default 0 -- for all ram locations in JECED variable v_MEM : std_logic_vector(ARRAY_SIZE - 1 downto 0) := ( others => '0' ); variable v_INI_DONE : boolean := FALSE; variable v_WADDR_A : integer; variable v_RADDR_A : integer; variable v_WADDR_B : integer; variable v_RADDR_B : integer; variable v_WADDRA_Valid_Flag : boolean := TRUE; variable v_WADDRB_Valid_Flag : boolean := TRUE; variable v_RADDRA_Valid_Flag : boolean := TRUE; variable v_RADDRB_Valid_Flag : boolean := TRUE; begin -- Process if( MEM_INIT_FLAG = 1 and v_INI_DONE = FALSE) THEN READ_MEM_INIT_FILE(MEM_INIT_FILE, v_MEM); v_INI_DONE := TRUE; end if; -- Address Check v_WADDRA_Valid_Flag := Valid_Address(WADA_node); v_WADDRB_Valid_Flag := Valid_Address(WADB_node); v_RADDRA_Valid_Flag := Valid_Address(RADA_node); v_RADDRB_Valid_Flag := Valid_Address(RADB_node); if ( v_WADDRA_Valid_Flag = TRUE ) then v_WADDR_A := CONV_INTEGER(WADA_node);-- else -- assert (Now = 0 ps) -- report "Write AddressA of Port contains invalid bit!"-- severity warning; end if; if (v_WADDRB_Valid_Flag = TRUE ) then v_WADDR_B := CONV_INTEGER(WADB_node);-- else-- assert (Now = 0 ps)-- report "Write AddressB of Port contains invalid bit!"-- severity warning; end if; if (v_RADDRA_Valid_Flag = TRUE ) then v_RADDR_A := CONV_INTEGER(RADA_node);-- else-- assert (Now = 0 ps)-- report "Read AddressA of Port contains invalid bit!"-- severity warning; end if; if (v_RADDRB_Valid_Flag = TRUE ) then v_RADDR_B := CONV_INTEGER(RADB_node);-- else-- assert (Now = 0 ps)-- report "Read AddressB of Port contains invalid bit!"-- severity warning; end if; -- CHECK Operation if (WEA = '1' and WEB = '1' and not( (v_WADDR_A*WDATA_WIDTH_A + WDATA_WIDTH_A -1) < (v_WADDR_B*WDATA_WIDTH_B) or (v_WADDR_B*WDATA_WIDTH_B + WDATA_WIDTH_B -1) < (v_WADDR_A*WDATA_WIDTH_A) )
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -