----------------------------------------------------------------- -- uCore 1.90 - functions.vhd -- ----------------------------------------------------------------- -- -- Author: KLAUS SCHLEISIEK -- Last change: KS 07.12.2015 11:31:09 -- -- Do not use this file except in compliance with the License. You may -- obtain a copy of the License at http://www.microcore.org/License/ -- Software distributed under the License is distributed on an "AS IS" basis, -- WITHOUT WARRANTY OF ANY KIND, either express or implied. -- See the License for the specific language governing rights and limitations -- under the License. -- -- The Initial Developer of the Original Code is Klaus.Schleisiek AT microcore.org. -- -- Functions and components which are used throughout uCore. LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_arith.ALL; USE IEEE.STD_LOGIC_signed.ALL; USE STD.TEXTIO.ALL; PACKAGE functions IS CONSTANT async_reset : BOOLEAN := true; -- true = async reset, false = synchronous reset FUNCTION conv_NATURAL(v : IN STD_LOGIC_VECTOR) RETURN NATURAL; FUNCTION to_vec(v : IN INTEGER; s : IN INTEGER ) RETURN STD_LOGIC_VECTOR; FUNCTION slice(v : IN STD_LOGIC; s : IN INTEGER ) RETURN STD_LOGIC_VECTOR; FUNCTION crc(d : IN STD_LOGIC_VECTOR; p : IN STD_LOGIC_VECTOR ) RETURN STD_LOGIC_VECTOR; FUNCTION max(v : IN INTEGER; w : IN INTEGER ) RETURN INTEGER; FUNCTION log2(v : IN INTEGER ) RETURN INTEGER; FUNCTION exp2(v : IN INTEGER ) RETURN INTEGER; FUNCTION ceiling(v : IN INTEGER; w : IN INTEGER ) RETURN INTEGER; FUNCTION next_quad(width : IN NATURAL ) RETURN NATURAL; --pragma translate off PROCEDURE hread(l : INOUT LINE; value : OUT STD_LOGIC_VECTOR); PROCEDURE Char2QuadBits(c : CHARACTER; result : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); good : OUT BOOLEAN; issue_error : IN BOOLEAN); -- pragma translate on COMPONENT synchronise GENERIC (width : INTEGER := 1); PORT (reset : IN STD_LOGIC; clk : IN STD_LOGIC; async : IN STD_LOGIC; sync : OUT STD_LOGIC); END COMPONENT; COMPONENT synchronise_n GENERIC (width : INTEGER := 1); PORT (reset : IN STD_LOGIC; clk : IN STD_LOGIC; async_n : IN STD_LOGIC; sync : OUT STD_LOGIC); END COMPONENT; COMPONENT debounce GENERIC (width : INTEGER := 5); PORT (reset : IN STD_LOGIC; clk : IN STD_LOGIC; clk_en : IN STD_LOGIC; async : IN STD_LOGIC; sync : OUT STD_LOGIC); END COMPONENT; COMPONENT debounce_n GENERIC (width : INTEGER := 5); PORT (reset : IN STD_LOGIC; clk : IN STD_LOGIC; clk_en : IN STD_LOGIC; async : IN STD_LOGIC; sync : OUT STD_LOGIC); END COMPONENT; COMPONENT edge PORT (reset : IN STD_LOGIC; clk : IN STD_LOGIC; i : IN STD_LOGIC; o : OUT STD_LOGIC); END COMPONENT; COMPONENT edge_n PORT (reset : IN STD_LOGIC; clk : IN STD_LOGIC; i : IN STD_LOGIC; o : OUT STD_LOGIC); END COMPONENT; COMPONENT asynch_dpram GENERIC (data_width : INTEGER; addr_width : INTEGER); PORT (clk : IN STD_LOGIC; we : IN STD_LOGIC; waddr : IN STD_LOGIC_VECTOR(addr_width-1 DOWNTO 0); di : IN STD_LOGIC_VECTOR(data_width-1 DOWNTO 0); raddr : IN STD_LOGIC_VECTOR(addr_width-1 DOWNTO 0); do : OUT STD_LOGIC_VECTOR(data_width-1 DOWNTO 0)); END COMPONENT; COMPONENT asynch_ram GENERIC (data_width : INTEGER; addr_width : INTEGER); PORT (clk : IN STD_LOGIC; we : IN STD_LOGIC; addr : IN STD_LOGIC_VECTOR; di : IN STD_LOGIC_VECTOR; do : OUT STD_LOGIC_VECTOR); END COMPONENT; COMPONENT internal_ram GENERIC (data_width : INTEGER; addr_width : INTEGER; init_file : STRING := "none"); PORT (clk : IN STD_LOGIC; en : IN STD_LOGIC; we : IN STD_LOGIC; addr : IN STD_LOGIC_VECTOR; di : IN STD_LOGIC_VECTOR; do : OUT STD_LOGIC_VECTOR); END COMPONENT; COMPONENT internal_dpram GENERIC (data_width : INTEGER; addr_width : INTEGER; init_file : STRING := "none"); PORT (clk : IN STD_LOGIC; ena : IN STD_LOGIC; wea : IN STD_LOGIC; addra : IN STD_LOGIC_VECTOR; dia : IN STD_LOGIC_VECTOR; doa : OUT STD_LOGIC_VECTOR; enb : IN STD_LOGIC; web : IN STD_LOGIC; addrb : IN STD_LOGIC_VECTOR; dib : IN STD_LOGIC_VECTOR; dob : OUT STD_LOGIC_VECTOR); END COMPONENT; COMPONENT external_ram GENERIC (data_width : INTEGER; addr_width : INTEGER; init_file : STRING := "none"); PORT (ce_n : IN STD_LOGIC; oe_n : IN STD_LOGIC; we_n : IN STD_LOGIC; addr : IN STD_LOGIC_VECTOR; data : INOUT STD_LOGIC_VECTOR); END COMPONENT; COMPONENT monoflop GENERIC (ptime : integer); -- Pulsdauer in clk Perioden PORT (clk : IN STD_LOGIC; -- Input Clock reset : IN STD_LOGIC; -- Async. Reset inrt : IN STD_LOGIC; -- retriggerbarer Input pout : OUT STD_LOGIC); -- Output Pulse END COMPONENT; END functions; PACKAGE BODY functions IS ---------------------------------------------------------------- -- conv_NATURAL -- Convert STD_LOGIC_VECTOR to NATURAL number ---------------------------------------------------------------- FUNCTION conv_NATURAL(v : IN STD_LOGIC_VECTOR ) RETURN NATURAL IS VARIABLE temp : NATURAL; BEGIN temp := conv_INTEGER('0' & v); RETURN temp; END; ---------------------------------------------------------------- -- to_vec -- Convert INTEGER number to STD_LOGIC_VECTOR ---------------------------------------------------------------- FUNCTION to_vec(v : IN INTEGER; s : IN INTEGER ) RETURN STD_LOGIC_VECTOR IS VARIABLE temp : STD_LOGIC_VECTOR(s-1 DOWNTO 0); BEGIN temp := conv_STD_LOGIC_VECTOR(v,s); RETURN temp; END; ---------------------------------------------------------------- -- slice -- Return (others => v) within range s-1 to 0 ---------------------------------------------------------------- FUNCTION slice(v : IN STD_LOGIC; s : IN INTEGER ) RETURN STD_LOGIC_VECTOR IS VARIABLE temp : STD_LOGIC_VECTOR (s-1 DOWNTO 0); BEGIN temp := (OTHERS => v); -- synopsys compatibility RETURN temp; END; ---------------------------------------------------------------- -- crc-function (not for synthesis) ---------------------------------------------------------------- FUNCTION crc(d : IN STD_LOGIC_VECTOR; p : IN STD_LOGIC_VECTOR ) RETURN STD_LOGIC_VECTOR IS VARIABLE temp : STD_LOGIC_VECTOR (p'HIGH DOWNTO p'LOW); BEGIN temp := (OTHERS => '0'); FOR I IN d'HIGH DOWNTO d'LOW LOOP IF d(I) = temp(p'HIGH) THEN temp := temp(p'HIGH - 1 DOWNTO p'LOW) & '0'; ELSE temp := temp(p'HIGH - 1 DOWNTO p'LOW) & '0'; temp := temp XOR p; END IF; END LOOP; RETURN temp; END; ---------------------------------------------------------------- -- max -- Return maximum of two INTEGERs w and v ---------------------------------------------------------------- FUNCTION max(v : IN INTEGER; w : IN INTEGER ) RETURN INTEGER IS BEGIN IF (v > w) THEN RETURN v; ELSE RETURN w; END IF; END; ---------------------------------------------------------------- -- logarithm dualis ---------------------------------------------------------------- FUNCTION log2(v : IN INTEGER ) RETURN INTEGER IS VARIABLE temp : INTEGER; BEGIN temp := 0; WHILE 2 ** temp < v LOOP temp := temp + 1; END LOOP; RETURN temp; END; ---------------------------------------------------------------- -- exponentiation dualis ---------------------------------------------------------------- FUNCTION exp2(v : IN INTEGER ) RETURN INTEGER IS VARIABLE temp : INTEGER; BEGIN temp := 1; IF v /= 0 THEN FOR i IN v DOWNTO 1 LOOP temp := temp*2; END LOOP; END IF; RETURN temp; END; ---------------------------------------------------------------- -- ceiling of two number ---------------------------------------------------------------- FUNCTION ceiling(v : IN INTEGER; w : IN INTEGER ) RETURN INTEGER IS VARIABLE temp : INTEGER; BEGIN temp := v/w; IF temp * w < v THEN temp := temp + 1; END IF; RETURN temp; END; ---------------------------------------------------------------- -- next length, which is a multiple of 4 (quad) ---------------------------------------------------------------- FUNCTION next_quad (width : IN NATURAL) RETURN NATURAL IS VARIABLE len : INTEGER := 0; BEGIN len := 0; LOOP len := len + 4; IF len >= width THEN EXIT; END IF; END LOOP; RETURN len; END; ---------------------------------------------------------------- -- read hex number ---------------------------------------------------------------- -- pragma translate off PROCEDURE Char2QuadBits (c : CHARACTER; result : OUT STD_LOGIC_VECTOR(3 DOWNTO 0); good : OUT BOOLEAN; issue_error : IN BOOLEAN) IS BEGIN CASE C IS WHEN '0' => result := x"0"; good := TRUE; WHEN '1' => result := x"1"; good := TRUE; WHEN '2' => result := x"2"; good := TRUE; WHEN '3' => result := x"3"; good := TRUE; WHEN '4' => result := x"4"; good := TRUE; WHEN '5' => result := x"5"; good := TRUE; WHEN '6' => result := x"6"; good := TRUE; WHEN '7' => result := x"7"; good := TRUE; WHEN '8' => result := x"8"; good := TRUE; WHEN '9' => result := x"9"; good := TRUE; WHEN 'A' => result := x"A"; good := TRUE; WHEN 'B' => result := x"B"; good := TRUE; WHEN 'C' => result := x"C"; good := TRUE; WHEN 'D' => result := x"D"; good := TRUE; WHEN 'E' => result := x"E"; good := TRUE; WHEN 'F' => result := x"F"; good := TRUE; WHEN 'a' => result := x"A"; good := TRUE; WHEN 'b' => result := x"B"; good := TRUE; WHEN 'c' => result := x"C"; good := TRUE; WHEN 'd' => result := x"D"; good := TRUE; WHEN 'e' => result := x"E"; good := TRUE; WHEN 'f' => result := x"F"; good := TRUE; WHEN OTHERS => IF issue_error THEN ASSERT FALSE REPORT "HREAD Error: Read a '" & c & "', expected a Hex character (0-F)."; END if; good := FALSE; END CASE; END; PROCEDURE hread (l : INOUT LINE; value : OUT STD_LOGIC_VECTOR) IS VARIABLE ok : BOOLEAN; VARIABLE c : CHARACTER; CONSTANT ne : INTEGER := value'length/4; VARIABLE bv : STD_LOGIC_VECTOR(0 to value'length-1); VARIABLE s : STRING(1 to ne-1); BEGIN IF value'length mod 4 /= 0 THEN ASSERT FALSE REPORT "HREAD Error: Trying to read vector with an odd (non multiple of 4) length"; RETURN; END IF; LOOP -- skip white space and ':' read(l, c); EXIT WHEN ((c /= ' ') AND (c /= CR) AND (c /= HT) AND (c /= ':')); END LOOP; Char2QuadBits(c, bv(0 TO 3), ok, TRUE); IF NOT ok THEN RETURN; END IF; read(l, s, ok); IF NOT ok THEN ASSERT FALSE REPORT "HREAD Error: Failed to read the STRING"; RETURN; END IF; FOR i IN 1 TO ne-1 LOOP Char2QuadBits(s(i), bv(4*i to 4*i+3), ok, TRUE); IF NOT ok THEN RETURN; END IF; END LOOP; value := bv; END hread; -- pragma translate on END functions; ---------------------------------------------------------------- -- synchronising asynchronous input signals ---------------------------------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE work.functions.async_reset; ENTITY synchronise IS GENERIC (width : INTEGER); PORT (reset : IN STD_LOGIC; clk : IN STD_LOGIC; async : IN STD_LOGIC; sync : OUT STD_LOGIC); END synchronise; ARCHITECTURE rtl OF synchronise IS SIGNAL temp : STD_LOGIC_VECTOR(width-1 DOWNTO 0); BEGIN sync <= temp(width-1); synch: PROCESS(clk, reset) BEGIN IF reset = '1' AND async_reset THEN temp <= (OTHERS => '0'); ELSIF rising_edge(clk) THEN IF reset = '1' AND NOT async_reset THEN temp <= (OTHERS => '0'); ELSE IF width = 1 THEN temp(0) <= async; ELSE temp <= temp(width-2 DOWNTO 0) & async; END IF; END IF; END IF; END PROCESS synch; END rtl; ---------------------------------------------------------------- -- synchronising inverted asynchronous input signals ---------------------------------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE work.functions.async_reset; ENTITY synchronise_n IS GENERIC (width : INTEGER); PORT (reset : IN STD_LOGIC; clk : IN STD_LOGIC; async_n : IN STD_LOGIC; sync : OUT STD_LOGIC); END synchronise_n; ARCHITECTURE rtl OF synchronise_n IS SIGNAL temp : STD_LOGIC_VECTOR(width-1 DOWNTO 0); BEGIN sync <= temp(width-1); synch_n: PROCESS(clk, reset) BEGIN IF reset = '1' AND async_reset THEN temp <= (OTHERS => '0'); ELSIF rising_edge(clk) THEN IF reset = '1' AND NOT async_reset THEN temp <= (OTHERS => '0'); ELSE IF width = 1 THEN temp(0) <= NOT async_n; ELSE temp <= temp(width-2 DOWNTO 0) & NOT async_n; END IF; END IF; END IF; END PROCESS synch_n; END rtl; ---------------------------------------------------------------- -- debouncing asynchronous input signals ---------------------------------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE work.functions.async_reset; ENTITY debounce IS GENERIC (width : INTEGER); PORT (reset : IN STD_LOGIC; clk : IN STD_LOGIC; clk_en : IN STD_LOGIC; async : IN STD_LOGIC; sync : OUT STD_LOGIC); END debounce; ARCHITECTURE rtl OF debounce IS SIGNAL temp : STD_LOGIC_VECTOR(width-2 DOWNTO 0); CONSTANT allones : STD_LOGIC_VECTOR(width-1 DOWNTO 0) := (OTHERS => '1'); CONSTANT allzeroes : STD_LOGIC_VECTOR(width-1 DOWNTO 0) := (OTHERS => '0'); BEGIN noglitch: PROCESS(clk, reset) BEGIN IF reset = '1' AND async_reset THEN sync <= '0'; temp <= (OTHERS => '0'); ELSIF rising_edge(clk) THEN IF reset = '1' AND NOT async_reset THEN sync <= '0'; temp <= (OTHERS => '0'); ELSIF clk_en = '1' THEN temp <= temp(temp'high-1 DOWNTO 0) & async; IF (temp&async) = allones THEN sync <= '1'; END IF; IF (temp&async) = allzeroes THEN sync <= '0'; END IF; END IF; END IF; END PROCESS noglitch; END rtl; ---------------------------------------------------------------- -- debouncing inverted asynchronous input signals ---------------------------------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE work.functions.async_reset; ENTITY debounce_n IS GENERIC (width : INTEGER); PORT (reset : IN STD_LOGIC; clk : IN STD_LOGIC; clk_en : IN STD_LOGIC; async : IN STD_LOGIC; sync : OUT STD_LOGIC); END debounce_n; ARCHITECTURE rtl OF debounce_n IS SIGNAL temp : STD_LOGIC_VECTOR(width-2 DOWNTO 0); CONSTANT allones : STD_LOGIC_VECTOR(width-1 DOWNTO 0) := (OTHERS => '1'); CONSTANT allzeroes : STD_LOGIC_VECTOR(width-1 DOWNTO 0) := (OTHERS => '0'); BEGIN noglitch_n: PROCESS(clk, reset) BEGIN IF reset = '1' AND async_reset THEN sync <= '0'; temp <= (OTHERS => '0'); ELSIF rising_edge(clk) THEN IF reset = '1' AND NOT async_reset THEN sync <= '0'; temp <= (OTHERS => '0'); ELSIF clk_en = '1' THEN temp <= temp(temp'high-1 DOWNTO 0) & async; IF (temp&async) = allones THEN sync <= '0'; END IF; IF (temp&async) = allzeroes THEN sync <= '1'; END IF; END IF; END IF; END PROCESS noglitch_n; END rtl; ---------------------------------------------------------------- -- metastable safe positive edge detector ---------------------------------------------------------------- Library IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE work.functions.async_reset; ENTITY edge IS PORT (reset : IN STD_LOGIC; clk : IN STD_LOGIC; i : IN STD_LOGIC; o : OUT STD_LOGIC); END edge; ARCHITECTURE rtl OF edge IS SIGNAL temp : STD_LOGIC; SIGNAL output : STD_LOGIC; BEGIN o <= output; risingedge: PROCESS(reset, clk) BEGIN IF reset = '1' AND async_reset THEN temp <= '0'; -- temp output <= '0'; -- out ELSIF rising_edge(clk) THEN IF reset = '1' AND NOT async_reset THEN temp <= '0'; -- temp output <= '0'; -- out ELSE temp <= i AND (temp OR output); output <= i AND NOT (temp OR output); END IF; END IF; END PROCESS; END rtl; ---------------------------------------------------------------- -- metastable safe negative edge detector ---------------------------------------------------------------- Library IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE work.functions.async_reset; ENTITY edge_n IS PORT (reset : IN STD_LOGIC; clk : IN STD_LOGIC; i : IN STD_LOGIC; o : OUT STD_LOGIC); END edge_n; ARCHITECTURE rtl OF edge_n IS SIGNAL temp : STD_LOGIC; SIGNAL output : STD_LOGIC; BEGIN o <= output; fallingedge: PROCESS(reset, clk) BEGIN IF reset = '1' AND async_reset THEN temp <= '1'; -- temp output <= '0'; -- out ELSIF rising_edge(clk) THEN IF reset = '1' AND NOT async_reset THEN temp <= '1'; -- temp output <= '0'; -- out ELSE temp <= NOT i AND (temp OR output); output <= NOT i AND NOT (temp OR output); END IF; END IF; END PROCESS; END rtl; ----------------------------------------------------------------------- -- internal dual-port asynchronous RAM made of LUTs ----------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_unsigned.ALL; USE work.functions.ALL; ENTITY asynch_dpram IS GENERIC (data_width : INTEGER; addr_width : INTEGER); PORT (clk : IN STD_LOGIC; we : IN STD_LOGIC; waddr : IN STD_LOGIC_VECTOR(addr_width-1 DOWNTO 0); di : IN STD_LOGIC_VECTOR(data_width-1 DOWNTO 0); raddr : IN STD_LOGIC_VECTOR(addr_width-1 DOWNTO 0); do : OUT STD_LOGIC_VECTOR(data_width-1 DOWNTO 0)); END asynch_dpram; ARCHITECTURE inference_model OF asynch_dpram IS TYPE ram_type IS ARRAY (2**addr_width-1 DOWNTO 0) OF STD_LOGIC_VECTOR(data_width-1 DOWNTO 0); SIGNAL ram : ram_type; BEGIN asyn_dpram: PROCESS(clk) BEGIN IF rising_edge(clk) THEN IF we = '1' THEN ram(conv_NATURAL(waddr)) <= di ; END IF; END IF; END PROCESS asyn_dpram; do <= ram(conv_NATURAL(raddr)); END inference_model; ----------------------------------------------------------------------- -- internal asynchronous RAM made of LUTs ----------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_unsigned.ALL; USE work.functions.ALL; ENTITY asynch_ram IS GENERIC (data_width : INTEGER; addr_width : INTEGER); PORT (clk : IN STD_LOGIC; we : IN STD_LOGIC; addr : IN STD_LOGIC_VECTOR(addr_width-1 DOWNTO 0); di : IN STD_LOGIC_VECTOR(data_width-1 DOWNTO 0); do : OUT STD_LOGIC_VECTOR(data_width-1 DOWNTO 0)); END asynch_ram; ARCHITECTURE inference_model OF asynch_ram IS TYPE ram_type IS ARRAY (2**addr_width-1 DOWNTO 0) OF STD_LOGIC_VECTOR(data_width-1 DOWNTO 0); SIGNAL ram : ram_type; BEGIN asyn_ram: PROCESS(clk) BEGIN IF rising_edge(clk) THEN IF we = '1' THEN ram(conv_NATURAL(addr)) <= di ; END IF; END IF; END PROCESS asyn_ram; do <= ram(conv_NATURAL(addr)); END inference_model; ----------------------------------------------------------------------- -- internal_blockRAM: -- Address latched prior to access, input data stored on rising clock edge -- Initialized by an ascii-file of the following format: -- addr 0 1 2 3 -- 0000 : 95930800 00000000 94F4471F 07000000 ----------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_unsigned.ALL; USE STD.TEXTIO.ALL; USE work.functions.ALL; ENTITY internal_ram IS GENERIC (data_width : INTEGER; addr_width : INTEGER; init_file : STRING); PORT (clk : IN STD_LOGIC; en : IN STD_LOGIC; we : IN STD_LOGIC; addr : IN STD_LOGIC_VECTOR(addr_width-1 DOWNTO 0); di : IN STD_LOGIC_VECTOR(data_width-1 DOWNTO 0); do : OUT STD_LOGIC_VECTOR(data_width-1 DOWNTO 0)); ATTRIBUTE ram_style : STRING; ATTRIBUTE ram_style OF internal_ram : ENTITY IS "block"; END internal_ram; ARCHITECTURE inference_model OF internal_ram IS ATTRIBUTE syn_ramstyle : STRING; TYPE ram_type IS ARRAY (2**addr_width-1 DOWNTO 0) OF STD_LOGIC_VECTOR(data_width-1 DOWNTO 0); CONSTANT data_hex : INTEGER := next_quad(data_width); SIGNAL addr_i : STD_LOGIC_VECTOR(addr_width-1 DOWNTO 0); SIGNAL ram : ram_type; ATTRIBUTE syn_ramstyle OF ram : SIGNAL IS "no_rw_check"; BEGIN initialized_ram: PROCESS(clk) FILE tcf : TEXT; VARIABLE first : BOOLEAN := true; VARIABLE l : line; VARIABLE char : character; VARIABLE adr : STD_LOGIC_VECTOR(15 DOWNTO 0); VARIABLE buf : STD_LOGIC_VECTOR(data_hex-1 DOWNTO 0); VARIABLE loc : INTEGER RANGE 0 TO 2**addr_width+1; BEGIN -- pragma translate_off IF first AND init_file /= "none" THEN file_open(tcf, init_file, READ_MODE); l := NEW string'("initializing " & string'(init_file)); writeline(output, l); WHILE NOT ENDFILE(tcf) LOOP readline(tcf, l); IF l'length > 6 THEN hread(l, adr); -- read address loc := conv_NATURAL(adr); LOOP IF l'length < (data_hex / 4) THEN EXIT; END IF; hread(l, buf); -- read 16 bit addresses = 4 hex digits ram(loc) <= buf(data_width-1 DOWNTO 0); loc := loc + 1; IF loc >= (2**addr_width) THEN EXIT; END IF; END LOOP; IF loc >= (2**addr_width) THEN EXIT; END IF; END IF; END LOOP; file_close(tcf); first := false; ELSE -- pragma translate_on IF rising_edge(clk) THEN IF en = '1' THEN addr_i <= addr; IF we = '1' THEN ram(conv_NATURAL(addr)) <= di; END IF; END IF; END IF; -- pragma translate_off END IF; -- pragma translate_on END PROCESS initialized_ram; do <= ram(conv_NATURAL(addr_i)); END inference_model; ----------------------------------------------------------------------- -- internal_dual_port_blockRAM: -- Address latched prior to access, input data stored on rising clock edge -- Initialized by an ascii-file of the following format: -- addr 0 1 2 3 -- 0000 : 95930800 00000000 94F4471F 07000000 ----------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_unsigned.ALL; USE STD.TEXTIO.ALL; USE work.functions.ALL; ENTITY internal_dpram IS GENERIC (data_width : INTEGER; addr_width : INTEGER; init_file : STRING); PORT (clk : IN STD_LOGIC; ena : IN STD_LOGIC; wea : IN STD_LOGIC; addra : IN STD_LOGIC_VECTOR(addr_width-1 DOWNTO 0); dia : IN STD_LOGIC_VECTOR(data_width-1 DOWNTO 0); doa : OUT STD_LOGIC_VECTOR(data_width-1 DOWNTO 0); enb : IN STD_LOGIC; web : IN STD_LOGIC; addrb : IN STD_LOGIC_VECTOR(addr_width-1 DOWNTO 0); dib : IN STD_LOGIC_VECTOR(data_width-1 DOWNTO 0); dob : OUT STD_LOGIC_VECTOR(data_width-1 DOWNTO 0)); ATTRIBUTE ram_style : STRING; ATTRIBUTE ram_style OF internal_dpram : ENTITY IS "block"; END internal_dpram; ARCHITECTURE inference_model OF internal_dpram IS ATTRIBUTE syn_ramstyle : STRING; TYPE ram_type IS ARRAY (2**addr_width-1 DOWNTO 0) OF STD_LOGIC_VECTOR(data_width-1 DOWNTO 0); CONSTANT data_hex : INTEGER := next_quad(data_width); SIGNAL addra_i : STD_LOGIC_VECTOR(addr_width-1 DOWNTO 0); SIGNAL addrb_i : STD_LOGIC_VECTOR(addr_width-1 DOWNTO 0); SIGNAL ram : ram_type; ATTRIBUTE syn_ramstyle OF ram : SIGNAL IS "no_rw_check"; BEGIN initialized_ram: PROCESS(clk) FILE tcf : TEXT; VARIABLE first : BOOLEAN := true; VARIABLE l : line; VARIABLE char : character; VARIABLE adr : STD_LOGIC_VECTOR(15 DOWNTO 0); VARIABLE buf : STD_LOGIC_VECTOR(data_hex-1 DOWNTO 0); VARIABLE loc : INTEGER RANGE 0 TO 2**addr_width+1; BEGIN -- pragma translate_off IF first AND init_file /= "none" THEN file_open(tcf, init_file, READ_MODE); l := NEW string'("initializing " & string'(init_file)); writeline(output, l); WHILE NOT ENDFILE(tcf) LOOP readline(tcf, l); IF l'length > 6 THEN hread(l, adr); -- read address loc := conv_NATURAL(adr); LOOP IF l'length < (data_hex / 4) THEN EXIT; END IF; hread(l, buf); -- read 16 bit addresses = 4 hex digits ram(loc) <= buf(data_width-1 DOWNTO 0); loc := loc + 1; IF loc >= (2**addr_width) THEN EXIT; END IF; END LOOP; IF loc >= (2**addr_width) THEN EXIT; END IF; END IF; END LOOP; file_close(tcf); first := false; ELSE -- pragma translate_on IF rising_edge(clk) THEN IF ena = '1' THEN addra_i <= addra; IF wea = '1' THEN ram(conv_NATURAL(addra)) <= dia; END IF; END IF; IF enb = '1' THEN addrb_i <= addrb; IF web = '1' THEN ram(conv_NATURAL(addrb)) <= dib; END IF; END IF; END IF; -- pragma translate_off END IF; -- pragma translate_on END PROCESS initialized_ram; doa <= ram(conv_NATURAL(addra_i)); dob <= ram(conv_NATURAL(addrb_i)); END inference_model; ----------------------------------------------------------------------- -- external_ram: Input data is stored on falling WRITE edge -- Initialized by an ascii-file of the following format: -- addr 0 1 2 3 -- 0000 : 95930800 00000000 94F4471F 07000000 ----------------------------------------------------------------------- LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.STD_LOGIC_unsigned.ALL; USE STD.TEXTIO.ALL; USE work.functions.ALL; ENTITY external_ram IS GENERIC (data_width : INTEGER; addr_width : INTEGER; init_file : STRING := "none"); PORT (ce_n : IN STD_LOGIC; oe_n : IN STD_LOGIC; we_n : IN STD_LOGIC; addr : IN STD_LOGIC_VECTOR(addr_width-1 DOWNTO 0); data : INOUT STD_LOGIC_VECTOR(data_width-1 DOWNTO 0)); END external_ram; ARCHITECTURE sim_model OF external_ram IS TYPE ram_type IS ARRAY (2**addr_width-1 DOWNTO 0) OF STD_LOGIC_VECTOR(data_width-1 DOWNTO 0); CONSTANT data_hex : INTEGER := next_quad(data_width); SIGNAL addr_i : STD_LOGIC_VECTOR(addr_width-1 DOWNTO 0); SIGNAL ce : STD_LOGIC; SIGNAL din : STD_LOGIC_VECTOR(data_width-1 DOWNTO 0); BEGIN addr_i <= addr AFTER 1 ns; -- delay for the sake of simulation din <= data AFTER 1 ns; -- delay for the sake of simulation ce <= NOT ce_n AFTER 1 ns; initialized_ram: PROCESS(ce, oe_n, we_n, addr_i, din) FILE tcf : TEXT; VARIABLE first : BOOLEAN := true; VARIABLE l : line; VARIABLE char : character; VARIABLE adr : STD_LOGIC_VECTOR(15 DOWNTO 0); VARIABLE buf : STD_LOGIC_VECTOR(data_hex-1 DOWNTO 0); VARIABLE loc : INTEGER RANGE 0 TO 2**addr_width+1; VARIABLE ram : ram_type; BEGIN -- pragma translate_off IF first AND init_file /= "none" THEN file_open(tcf, init_file, READ_MODE); l := NEW string'("initializing " & string'(init_file)); writeline(output, l); WHILE NOT ENDFILE(tcf) LOOP readline(tcf, l); IF l'length > 6 THEN hread(l, adr); -- read address loc := conv_NATURAL(adr); LOOP IF l'length < (data_hex / 4) THEN EXIT; END IF; hread(l, buf); -- read 16 bit addresses = 4 hex digits ram(loc) := buf(data_width-1 DOWNTO 0); loc := loc + 1; IF loc >= (2**addr_width) THEN EXIT; END IF; END LOOP; IF loc >= (2**addr_width) THEN EXIT; END IF; END IF; END LOOP; file_close(tcf); first := false; ELSE -- pragma translate_on data <= (OTHERS => 'Z'); IF ce = '1' THEN IF rising_edge(we_n) THEN ram(conv_NATURAL(addr_i)) := din; END IF; IF we_n = '1' AND oe_n = '0' THEN data <= ram(conv_NATURAL(addr_i)); END IF; END IF; -- pragma translate_off END IF; -- pragma translate_on END PROCESS initialized_ram; END sim_model; ------------------------------------------------------------------------------- -- DONKA - Hardware & VHDL Design -- Monoflop -- Target: independent -- (c) 06/06 Thomas Wendt, DONKA - Hardware & VHDL Design -- V 2.0 ------------------------------------------------------------------------------- -- History -- V1.0 10.08.2006 Erstellung -- V1.1 21.09.2006 durch resetCnt nun retriggerbar -- V2.0 27.02.2009 change to synchronous design LIBRARY IEEE; USE IEEE.STD_LOGIC_1164.ALL; USE IEEE.NUMERIC_STD.ALL; USE work.functions.async_reset; ENTITY monoflop IS GENERIC (ptime : integer := 10000000); -- Pulsdauer in clk Perioden PORT (clk : IN STD_LOGIC; -- Input Clock reset : IN STD_LOGIC; -- Async. Reset inrt : IN STD_LOGIC; -- retriggerbarer Input pout : OUT STD_LOGIC); -- Output Pulse END monoflop; ARCHITECTURE behavior OF monoflop IS SIGNAL pcnt : INTEGER RANGE 1 TO ptime; SIGNAL inrt_L : STD_LOGIC; SIGNAL inrt_LL : STD_LOGIC; SIGNAL inrt_P : STD_LOGIC; BEGIN p_trg_pulse : PROCESS(clk, reset) BEGIN IF reset = '1' AND async_reset THEN inrt_L <= '0'; inrt_LL <= '0'; inrt_P <= '0'; ELSIF rising_edge(clk) THEN IF reset = '1' AND NOT async_reset THEN inrt_L <= '0'; inrt_LL <= '0'; inrt_P <= '0'; ELSE inrt_L <= inrt; inrt_LL <= inrt_L; inrt_P <= inrt_L XOR inrt_LL; END IF; END IF; END PROCESS; p_cnt : PROCESS(clk, reset) BEGIN IF reset = '1' AND async_reset THEN pcnt <= 1; pout <= '1'; ELSIF rising_edge(clk) THEN IF reset = '1' AND NOT async_reset THEN pcnt <= 1; pout <= '1'; ELSE IF inrt_P = '1' THEN pcnt <= 1; pout <= '1'; ELSIF pcnt = ptime THEN pout <= '0'; ELSE pcnt <= pcnt + 1; END IF; END IF; END IF; END PROCESS; END behavior;