510 likes | 618 Views
ECE 545 Lecture 7. Variables, Functions, Memory, File I/O. Variables. Variable – Example (1). LIBRARY ieee ; USE ieee.std_logic_1164.all ; ENTITY Numbits IS PORT ( X : IN STD_LOGIC_VECTOR(1 TO 3) ; Count : OUT INTEGER RANGE 0 TO 3) ; END Numbits ;.
E N D
ECE 545 Lecture 7 Variables, Functions, Memory, File I/O ECE 545 – Introduction to VHDL
Variables ECE 545 – Introduction to VHDL
Variable – Example (1) LIBRARY ieee ; USE ieee.std_logic_1164.all ; ENTITY Numbits IS PORT ( X : IN STD_LOGIC_VECTOR(1 TO 3) ; Count : OUT INTEGER RANGE 0 TO 3) ; END Numbits ; ECE 545 – Introduction to VHDL
Variable – Example (2) ARCHITECTURE Behavior OF Numbits IS BEGIN PROCESS(X) – count the number of bits in X equal to 1 VARIABLE Tmp: INTEGER; BEGIN Tmp := 0; FOR i IN 1 TO 3 LOOP IF X(i) = ‘1’ THEN Tmp := Tmp + 1; END IF; END LOOP; Count <= Tmp; END PROCESS; END Behavior ; ECE 545 – Introduction to VHDL
Variables - features • Can only be declared within processes and subprograms (functions & procedures) • Initial value can be explicitly specified in the declaration • When assigned take an assigned value immediately • Variable assignments represent the desired behavior, not the structure of the circuit • Should be avoided, or at least used with caution in a synthesizable code ECE 545 – Introduction to VHDL
Variables vs. Signals ECE 545 – Introduction to VHDL
Variable – Example ARCHITECTURE Behavior OF Numbits IS BEGIN PROCESS(X) – count the number of bits in X equal to 1 VARIABLE Tmp: INTEGER; BEGIN Tmp := 0; FOR i IN 1 TO 3 LOOP IF X(i) = ‘1’ THEN Tmp := Tmp + 1; END IF; END LOOP; Count <= Tmp; END PROCESS; END Behavior ; ECE 545 – Introduction to VHDL
Incorrect Code using Signals ARCHITECTURE Behavior OF Numbits IS SIGNAL Tmp : INTEGER RANGE 0 TO 3 ; BEGIN PROCESS(X) – count the number of bits in X equal to 1 BEGIN Tmp <= 0; FOR i IN 1 TO 3 LOOP IF X(i) = ‘1’ THEN Tmp <= Tmp + 1; END IF; END LOOP; Count <= Tmp; END PROCESS; END Behavior ; ECE 545 – Introduction to VHDL
Parity generator entity library ieee; use ieee.std_logic_1164.all; entity oddParityLoop is generic ( width : integer := 8 ); port (ad: in std_logic_vector (width - 1 downto 0); oddParity : out std_logic ) ; end oddParityLoop ; ECE 545 – Introduction to VHDL
Parity generator architecture using variables architecture behavioral of oddParityLoop is begin process (ad) variable loopXor: std_logic; begin loopXor := '0'; for i in 0 to width -1 loop loopXor := loopXor xor ad( i ) ; end loop ; oddParity <= loopXor ; end process; end behavioral ; ECE 545 – Introduction to VHDL
Parity generator architecture using signals architecture dataflow of oddParityGen is signal genXor: std_logic_vector(width downto 0); begin genXor(0) <= '0'; parTree: for i in 1 to width generate genXor(i) <= genXor(i - 1) XOR ad(i - 1); end generate; oddParity <= genXor(width) ; end dataflow ; ECE 545 – Introduction to VHDL
N-bit NAND library ieee; use ieee.std_logic_1164.all; ENTITY NANDn IS GENERIC (n: INTEGER := 4) PORT ( X : IN STD_LOGIC_VECTOR(1 TO n); Y : OUT STD_LOGIC); END NANDn; ECE 545 – Introduction to VHDL
N-bit NAND architecture using variables ARCHITECTUREbehavioral1OFNANDnIS BEGIN PROCESS (X) VARIABLETmp: STD_LOGIC; BEGIN Tmp := X(1); AND_bits: FOR i IN2TO nLOOP Tmp := TmpANDX( i ) ; END LOOP AND_bits ; Y <= NOT Tmp ; END PROCESS; ENDbehavioral1 ; ECE 545 – Introduction to VHDL
Incorrect N-bit NAND architecture using signals ARCHITECTUREbehavioral2OFNANDnIS SIGNALTmp: STD_LOGIC; BEGIN PROCESS (X) BEGIN Tmp<= X(1); AND_bits: FOR i IN2TO nLOOP Tmp<= TmpANDX( i ) ; END LOOP AND_bits ; Y <= NOT Tmp ; END PROCESS; ENDbehavioral2 ; ECE 545 – Introduction to VHDL
Correct N-bit NAND architecture using signals ARCHITECTUREdataflow1 OFNANDnIS SIGNALTmp: STD_LOGIC_VECTOR(1 TO n); BEGIN Tmp(1)<= X(1); AND_bits: FOR i IN2TO nLOOP Tmp(i)<= Tmp(i-1)ANDX( i ) ; END LOOP AND_bits ; Y <= NOT Tmp(n) ; ENDdataflow1 ; ECE 545 – Introduction to VHDL
Correct N-bit NAND architecture using signals ARCHITECTUREdataflow2OFNANDnIS SIGNALTmp: STD_LOGIC_VECTOR(1 TO n); BEGIN Tmp <= (OTHERS => 1); Y <= ‘0’ WHEN X = Tmp ELSE ‘1’; ENDdataflow2 ; ECE 545 – Introduction to VHDL
Functions ECE 545 – Introduction to VHDL
Functions – basic features Functions • never modify parameters passed to them • always return a single value as a result • are always used in some expression, and not called on their own ECE 545 – Introduction to VHDL
User-defined Functions ECE 545 – Introduction to VHDL
Function – example (1) library IEEE; use IEEE.std_logic_1164.all; ENTITY powerOfFour IS PORT( X : IN INTEGER; Y : OUT INTEGER; ); END powerOfFour; ECE 545 – Introduction to VHDL
Function – example (2) ARCHITECTURE behavioral OF powerOfFour IS FUNCTION Pow( N, Exp : INTEGER) RETURNINTEGERIS VARIABLE Result : INTEGER := 1; BEGIN FOR i IN 1 TO Exp LOOP Result := Result * N; END LOOP; RETURN( Result ); END Pow; BEGIN Y <= Pow(X, 4); END behavioral; ECE 545 – Introduction to VHDL
User-defined Functions – basic features User-defined Functions • are declared between the architecture declaration statement and the BEGIN statement of that architecture, just like components • are called using formal and actual parameters the same way as components • may be defined in package bodies ECE 545 – Introduction to VHDL
Package containing a function (1) LIBRARY IEEE; USE IEEE.std_logic_1164.all; PACKAGE specialFunctions IS FUNCTION Pow( N, Exp : INTEGER) RETURNINTEGER; END specialFunctions ECE 545 – Introduction to VHDL
Package containing a function (2) PACKAGE BODY specialFunctions IS FUNCTION Pow( N, Exp : INTEGER) RETURNINTEGERIS VARIABLE Result : INTEGER := 1; BEGIN FOR i IN 1 TO Exp LOOP Result := Result * N; END LOOP; RETURN( Result ); END Pow; END specialFunctions ECE 545 – Introduction to VHDL
User-defined Procedures ECE 545 – Introduction to VHDL
Procedure – example (1) library IEEE; use IEEE.std_logic_1164.all; use work.decProcs.all; entity decoder is port ( decIn: in std_logic_vector(1 downto 0); decOut: out std_logic_vector(3 downto 0) ); end decoder; ECE 545 – Introduction to VHDL
Procedure – example (2) architecture simple of decoder is procedure DEC2x4 (inputs : in std_logic_vector(1 downto 0); decode: out std_logic_vector(3 downto 0) ) is begin case inputs is when "11" => decode := "1000"; when "10" => decode := "0100"; when "01" => decode := "0010"; when "00" => decode := "0001"; when others => decode := "0001"; end case; end DEC2x4; begin DEC2x4(decIn,decOut); end simple; ECE 545 – Introduction to VHDL
Memories ECE 545 – Introduction to VHDL
Distributed RAM RAM16X1S D WE WCLK = O A0 A1 A2 A3 LUT LUT LUT RAM32X1S D WE WCLK A0 O A1 A2 A3 A4 or RAM16X2S D0 D1 WE = WCLK O0 A0 O1 RAM16X1D A1 A2 D A3 WE or WCLK A0 SPO A1 A2 A3 DPRA0 DPO DPRA1 DPRA2 DPRA3 • CLB LUT configurable as Distributed RAM • A LUT equals 16x1 RAM • Implements Single and Dual-Ports • Cascade LUTs to increase RAM size • Synchronous write • Synchronous/Asynchronous read • Accompanying flip-flops used for synchronous read ECE 545 – Introduction to VHDL
RAM 16x1 (1) library IEEE; use IEEE.STD_LOGIC_1164.all; library UNISIM; use UNISIM.all; entity RAM_16X1_DISTRIBUTED is port( CLK : in STD_LOGIC; WE : in STD_LOGIC; ADDR : in STD_LOGIC_VECTOR(3 downto 0); DATA_IN : in STD_LOGIC; DATA_OUT : out STD_LOGIC ); end RAM_16X1_DISTRIBUTED; ECE 545 – Introduction to VHDL
RAM 16x1 (2) architecture RAM_16X1_DISTRIBUTED_STRUCTURAL of RAM_16X1_DISTRIBUTED is attribute INIT : string; attribute INIT of RAM16X1_S_1: label is "F0C1"; -- Component declaration of the "ram16x1s(ram16x1s_v)" unit -- File name contains "ram16x1s" entity: ./src/unisim_vital.vhd component ram16x1s generic( INIT : BIT_VECTOR(15 downto 0) := X"0000"); port( O : out std_ulogic; A0 : in std_ulogic; A1 : in std_ulogic; A2 : in std_ulogic; A3 : in std_ulogic; D : in std_ulogic; WCLK : in std_ulogic; WE : in std_ulogic); end component; ECE 545 – Introduction to VHDL
RAM 16x1 (3) begin RAM_16X1_S_1: ram16x1s generic map (INIT => X"F0C1") port map (O=>DATA_OUT, A0=>ADDR(0), A1=>ADDR(1), A2=>ADDR(2), A3=>ADDR(3), D=>DATA_IN, WCLK=>CLK, WE=>WE ); end RAM_16X1_DISTRIBUTED_STRUCTURAL; ECE 545 – Introduction to VHDL
RAM 16x8 (1) library IEEE; use IEEE.STD_LOGIC_1164.all; library UNISIM; use UNISIM.all; entity RAM_16X8_DISTRIBUTED is port( CLK : in STD_LOGIC; WE : in STD_LOGIC; ADDR : in STD_LOGIC_VECTOR(3 downto 0); DATA_IN : in STD_LOGIC_VECTOR(7 downto 0); DATA_OUT : out STD_LOGIC_VECTOR(7 downto 0) ); end RAM_16X8_DISTRIBUTED; ECE 545 – Introduction to VHDL
RAM 16x8 (2) architecture RAM_16X8_DISTRIBUTED_STRUCTURAL of RAM_16X8_DISTRIBUTED is attribute INIT : string; attribute INIT of RAM16X1_S_1: label is "0000"; -- Component declaration of the "ram16x1s(ram16x1s_v)" unit -- File name contains "ram16x1s" entity: ./src/unisim_vital.vhd component ram16x1s generic( INIT : BIT_VECTOR(15 downto 0) := X"0000"); port( O : out std_ulogic; A0 : in std_ulogic; A1 : in std_ulogic; A2 : in std_ulogic; A3 : in std_ulogic; D : in std_ulogic; WCLK : in std_ulogic; WE : in std_ulogic); end component; ECE 545 – Introduction to VHDL
RAM 16x8 (3) begin GENERATE_MEMORY: for I in 0 to 7 generate RAM_16X1_S_1: ram16x1s generic map (INIT => X"0000") port map (O=>DATA_OUT(I), A0=>ADDR(0), A1=>ADDR(1), A2=>ADDR(2), A3=>ADDR(3), D=>DATA_IN(I), WCLK=>CLK, WE=>WE ); end generate; end RAM_16X8_DISTRIBUTED_STRUCTURAL; ECE 545 – Introduction to VHDL
ROM 16x1 (1) library IEEE; use IEEE.STD_LOGIC_1164.all; library UNISIM; use UNISIM.all; entity ROM_16X1_DISTRIBUTED is port( ADDR : in STD_LOGIC_VECTOR(3 downto 0); DATA_OUT : out STD_LOGIC ); end ROM_16X1_DISTRIBUTED; ECE 545 – Introduction to VHDL
ROM 16x1 (2) architecture ROM_16X1_DISTRIBUTED_STRUCTURAL of ROM_16X1_DISTRIBUTED is attribute INIT : string; attribute INIT of ROM16X1_S_1: label is "F0C1"; component ram16x1s generic( INIT : BIT_VECTOR(15 downto 0) := X"0000"); port( O : out std_ulogic; A0 : in std_ulogic; A1 : in std_ulogic; A2 : in std_ulogic; A3 : in std_ulogic; D : in std_ulogic; WCLK : in std_ulogic; WE : in std_ulogic); end component; signal Low : std_ulogic := ‘0’; ECE 545 – Introduction to VHDL
ROM 16x1 (3) begin ROM_16X1_S_1: ram16x1s generic map (INIT => X"F0C1") port map (O=>DATA_OUT, A0=>ADDR(0), A1=>ADDR(1), A2=>ADDR(2), A3=>ADDR(3), D=>Low, WCLK=>Low, WE=>Low ); end ROM_16X1_DISTRIBUTED_STRUCTURAL; ECE 545 – Introduction to VHDL
File I/O ECE 545 – Introduction to VHDL
Design Under Test (1) library IEEE; use IEEE.std_logic_1164.all; use IEEE.std_logic_unsigned.all; entity loadCnt is port ( data: in std_logic_vector (7 downto 0); load: in std_logic; clk: in std_logic; rst: in std_logic; q: out std_logic_vector (7 downto 0) ); end loadCnt; ECE 545 – Introduction to VHDL
Design Under Test (2) architecture rtl of loadCnt is signal cnt: std_logic_vector (7 downto 0); begin counter: process (clk, rst) begin if (rst = '1') then cnt <= (others => '0'); elsif (clk'event and clk = '1') then if (load = '1') then cnt <= data; else cnt <= cnt + 1; end if; end if; end process; q <= cnt; end rtl; ECE 545 – Introduction to VHDL
Test vector file (1) #Format is Rst, Load, Data, Q #load the counter to all 1s 011111111111111111 #reset the counter 101010101000000000 #now perform load/increment for each bit 011111111011111110 001111111011111111 # 011111110111111101 001111110111111110 # 011111101111111011 001111101111111100 # 011111011111110111 001111011111111000 ECE 545 – Introduction to VHDL
Test vector file (2) # 011110111111101111 001110111111110000 # 011101111111011111 001101111111100000 # 011011111110111111 001011111111000000 # 010111111101111111 00 0111111110000000 # #check roll-over case 011111111111111111 001111111100000000 # # End vectors ECE 545 – Introduction to VHDL
Testbench (1) library IEEE; use IEEE.std_logic_1164.all; use ieee.STD_LOGIC_TEXTIO.all; use std.textio.all; entity loadCntTB is end loadCntTB; ECE 545 – Introduction to VHDL
Testbench (2) architecture testbench of loadCntTB is component loadCnt port ( data: in std_logic_vector (7 downto 0); load: in std_logic; clk: in std_logic; rst: in std_logic; q: out std_logic_vector (7 downto 0) ); end component; ECE 545 – Introduction to VHDL
Testbench (3) file vectorFile: text is in "vectorfile"; type vectorType is record data: std_logic_vector(7 downto 0); load: std_logic; rst: std_logic; q: std_logic_vector(7 downto 0); end record; signal testVector: vectorType; signal TestClk: std_logic := '0'; signal Qout: std_logic_vector(7 downto 0); ECE 545 – Introduction to VHDL
Testbench (4) constant ClkPeriod: time := 100 ns; begin -- File reading and stimulus application readVec: process variable VectorLine: line; variable VectorValid: boolean; variable vRst: std_logic; variable vLoad: std_logic; variable vData: std_logic_vector(7 downto 0); variable vQ: std_logic_vector(7 downto 0); ECE 545 – Introduction to VHDL
Testbench (5) begin while not endfile (vectorFile) loop readline(vectorFile, VectorLine); read(VectorLine, vRst, good => VectorValid); next when not VectorValid; read(VectorLine, vLoad); read(VectorLine, vData); read(VectorLine, vQ); wait for ClkPeriod/4; testVector.Rst <= vRst; testVector.Load <= vLoad; testVector.Data <= vData; testVector.Q <= vQ; wait for (ClkPeriod/4) * 3; end loop; ECE 545 – Introduction to VHDL
Testbench (6) assert false report "Simulation complete" severity note; wait; end process; -- Free running test clock TestClk <= not TestClk after ClkPeriod/2; -- Instance of design being tested u1: loadCnt port map (Data => testVector.Data, load => testVector.Load, clk => TestClk, rst => testVector.Rst, q => Qout ); ECE 545 – Introduction to VHDL
Testbench (7) -- Process to verify outputs verify: process (TestClk) variable ErrorMsg: line; begin if (TestClk'event and TestClk = '0') then if Qout /= testVector.Q then write(ErrorMsg, string'("Vector failed ")); write(ErrorMsg, now); writeline(output, ErrorMsg); end if; end if; end process; end testbench; ECE 545 – Introduction to VHDL