Variables variable variable_name: variable_type variable_name := variable_value Examples: variable x: integer range 0 to 7; Variable count: std_logic_vector(3 downto 0) x := 2; count := “1110”;
Signals vs. variables Signal: Variable: can be used anywhere represents circuit interconnect value is updated at the end of process Variable: only in sequential code (process, function, procedure) Represents local information value is updated immediately
PACKAGES Used for declaring global constants and functions Package must be declared in the include libraries before the entity declaration
PACKAGE EXAMPLE PACKAGE tsu_pkg is CONSTANT word_length: integer := 32; --processor word length CONSTANT thid_length: integer := 16; --thread id length CONSTANT cntx_length: integer := 0; --context length CONSTANT nof_ready_count: integer:= 8; --# ready counts TYPE sync_data_type is ARRAY (nof_ready_count downto 0) of std_logic_vector(word_length-1 downto 0); function LOG (X : integer) return integer; --logarithm base 2 end package;
Using a package Package must be declared in the include libraries before the entity declaration Library work; Use work.tsu_pkg.all; Entity …
Generics An alternative way of declaring parameters, valid only for a single entity. ENTITY counter is GENERIC (wordlength: integer:= 8); PORT (clk, rst_n, en: in std_logic; count: out std_logic_vector(wordlength-1 downto 0) ); END counter;
FUNCTIONS PACKAGE body tsu_pkg is function LOG (X : integer) return integer is variable i: integer range 0 to pe_num; variable modulus, modulus_copy: integer range 0 to pe_num; variable remainder, remainder_detect: integer range 0 to 1; variable result: integer range 0 to 20:=0; begin modulus := X; while modulus > 0 loop modulus_copy := modulus; modulus := modulus/2; remainder := modulus_copy rem 2; if modulus >= 1 then if remainder = 1 then remainder_detect := 1; else remainder_detect := remainder_detect; end if; result := result +1; elsif remainder_detect > 0 then result := result + 1; end loop; return result; end function; end;
Arithmetic conversion functions Need to include std_logic_arith library Conv_integer: converts a std_logic_vector to integer i <= conv_integer(‘0’ & count); Std_logic_vector: converts an integer to std_logic_vector count <= std_logic_vector(i, count’length);
ROM entity entity rominfr is port ( clk : in std_logic; en : in std_logic; addr : in std_logic_vector(4 downto 0); data : out std_logic_vector(3 downto 0)); end rominfr;
ROM architecture architecture syn of rominfr is type rom_type is array (31 downto 0) of std_logic_vector (3 downto 0); constant ROM : rom_type := ("0001","0010","0011","0100","0101","0110","0111","1000","1001“,"1010","1011","1100","1101","1110","1111","0001","0010","0011","0100","0101","0110","0111","1000","1001","1010","1011","1100","1101","1110","1111"); begin process (clk) if (clk’event and clk = ’1’) then if (en = ’1’) then data <= ROM(conv_integer(addr); end if; end process; end syn;
DUAL –PORT RAM ENTITY entity rams_14 is port ( clk : in std_logic; ena : in std_logic; enb : in std_logic; wea : in std_logic; addra : in std_logic_vector(log(ram_depth)-1 downto 0); addrb : in std_logic_vector(log(ram_depth)-1 downto 0); dia : in std_logic_vector(word_length-1 downto 0); doa : out std_logic_vector(word_length-1 downto 0); dob : out std_logic_vector(word_length-1 downto 0)); end rams_14;
DUAL –PORT RAM ARCHITECTURE architecture syn of rams_14 is type ram_type is array (ram_depth-1 downto 0) of std_logic_vector(word_length-1 downto 0); signal RAM : ram_type; signal read_addra : std_logic_vector(log(ram_depth)-1 downto 0); signal read_addrb : std_logic_vector(log(ram_depth)-1 downto 0); begin
DUAL–PORT RAM ARCHITECTURE process (clk) begin if (clk'event and clk = '1') then if (ena = '1') then if (wea = '1') then RAM (conv_integer(addra)) <= dia; end if; read_addra <= addra; if (enb = '1') then read_addrb <= addrb; end process; doa <= RAM(conv_integer(read_addra)); dob <= RAM(conv_integer(read_addrb)); end syn;
Attributes Data attributes(all synthesizable) d’LOW --returns lower index d’HIGH --returns higher index d’LEFT --returns leftmost index d’RIGHT --returns rightmost index d’LENGTH --returns vector size d’RANGE --returns vector range d’REVERSE_RANGE --returns reverse vector range Signal attributes(first two synthesizable) s’EVENT --returns true when event on s s’STABLE --returns true when no event on s s’ACTIVE --returns true when s=‘1’ s’QUIET <time> --returns true when no event on s for specified time s’LAST_EVENT --returns time since last event on s s’LAST_ACTIVE --returns time since s = ‘1’ s’LAST_VALUE --returns value of s before last event
Common VHDL Pitfalls
Name inconsistency Compile: error Severity: Trivial
Reading an output Compile: Error: cannot read output Solution: Use internal signal ENTITY counter is PORT(clk, rst_n: in std_logic; count: out std_logic_vector(3 downto 0)); end counter; Architecture rtl of count is begin PROCESS(clk) if clk’event and clk=‘1’ then if rst_n = ‘0’ then –-synchronous reset count <= (others => ‘0’); else if en = ‘1’ then --count enable count <= count + ‘1’; --cannot read output error end if; end process;
Multiple unconditional concurrent assignments Simulation: ‘X’ value Synthesis: ERROR: signal is multiply driven Severity: Serious Architecture rtl of my_entity is BEGIN output <= a AND b; ... output <= b XOR c; Process (b,c) Begin output <= b OR c; End process; End;
Incomplete sensitivity list Simulation: Unexpected behavior Synthesis: Warning: Incomplete sensitivity list Severity: Serious Solution: complete sensitivity list PROCESS(a, b) BEGIN d <= (a AND b) OR c; --c is missing from sensitivity list!!! END PROCESS;
Not assigning all outputs in combinational process Simulation: Synthesis: Warning: Signal not always assigned, storage may be needed Severity: Serious Solution: assign all signals PROCESS(a, b, c) BEGIN if c = ‘0’ then d <= (a AND b) OR c; --d assigned only first time, else e <= a; --e assigned only second time!!! END PROCESS;
Unassigned signals Simulation: Undefined value (‘U’) Synthesis: Warning: Signal is never used/never assigned a value Severity: Moderate Architecture rtl of my_entity is Signal s: std_logic; Begin Output <= input1 and input2; --s never assigned End;
Output not assigned or not connected Simulation: Undefined Synthesis: Error: All logic removed from the design Severity: Serious ENTITY my_entity IS PORT (input1, input2: in std_logic; output: out std_logic); End my_entity; Architecture rtl of my_entity is Signal s: std_logic; Begin s <= input1 and input2; --output never assigned End;
Using sequential instead of concurrent process Simulation: Unexpectedly delayed signals Synthesis: More FFs than expected