Return to HDL info page. | VHDL Coding Guidelines | (last edit: 7. June 2022) |
Introduction | ||
This document was created to provide VHDL users with a guideline for producing fast, reliable and reusable HDL code. Some of the main issues when writing VHDL code is: |
entity mux2to1 is port ( a : in std_logic_vector(1 downto 0); sel : in std_logic; muxed : out std_logic ); end mux2to1; architecture rtl of mux2to1 is begin muxed <= a(1) when sel = '1' else a(0); end rtl; |
entity mux4to1 is port ( input : in std_logic_vector(3 downto 0); |
architecture structural of mux4to1 is ... begin mux2to1_1_0: mux2to1 port map ( a => input(1 downto 0), sel => sel(0), muxed => muxed_mid(0) ); ... end mux4to1; |
--------------------------------------------------------------------------------------------------- -- Author: John Q. Smith Copyright Xilinx, 2001 -- Xilinx FPGA - VirtexII -- Begin Date: 1/10/01 -- Revision History Date Author Comments -- 1/10/01 John Smith Created -- 1/14/01 John Smith changed entity port address & data to addr & dat --------------------------------------------------------------------------------------------------- --Purpose: -- This entity/architecture pair is a block level with 4 sub-blocks. This is the processor control -- interface for the block level |
--------------------------------------------------------------------------------------------------- -- demux_proc: this process dumultiplexes the inputs and registers the -- demultiplexed signals --------------------------------------------------------------------------------------------------- demux_proc : process(clk, reset) begin ... |
--------------------------------------------------------------------------------------------------- -- demux_proc: this process dumultiplexes the inputs and registers the -- demultiplexed signals --------------------------------------------------------------------------------------------------- demux_proc : process(clk, reset) begin ... if reset = '1' then demux <= (others => '0'); elsif rising_edge(clk) then -- demultiplex input onto the signal demux case (sel) is when '0' => demux(0) <= input; when '1' => demux(1) <= input; when others => demux <= (others => '0'); end case; end if; end process; |
-- purpose: to show proper indentation sample_proc : process (clk, reset) variable muxed_data_v : std_logic_vector (1 downto 0); --_v denotes a variable begin -- process sample_proc if reset = '0' then for i in data'range loop data(i) <= (others => '0'); -- data is a 4x2 array end loop; --i muxed_data <= '0' elsif clk'event and clk = '1' then muxed_data_v := data(conv_integer(addr)); case sel is when '0' => muxed_data <= mux_data_v(0); when '1' => muxed_data <= mux_data_v(1); end case; -- case sel is end if; -- if reset = '0'... end process sample_proc; |
entity in_out is port ( data_in : in std_logic_vector (31 downto 0); data_out : out std_logic_vector(31 downto 0) ); end entity in_out; ... in_out_inst: in_out port map ( data_in => ram_data_out, data_out => ram_data_in ); |
count <= count_i; process (clk, reset) begin if reset = '1' then count_i <= (others => '0'); elsif rising_edge(clk) then count_i <= count_i + 1; end if; end process; |
process (clk, reset) variable correct_v : std_logic; begin if reset = '1' then a <= '0'; b <= '0'; elsif rising_edge(clk) then correct_v := c and d; a <= e or correct_v; b <= f or correct_v; end if; end process; |
process (clk, reset) variable incorrect_v : std_logic; begin if reset = '1' then a <= '0'; b <= '0'; elsif rising_edge(clk) then a <= e or incorrect_v; b <= f or incorrect_v; incorrect_v := c and d; end if; end process; |
--within a package constant asic : boolean := True; ... -- within an architecture generate_asic : if asic = true then mux_proc : process (addr, sel, data) ... generate_fpga : if asic = false then tri_state_proc : process (addr, sel, data) ... |
--within the package pack_ase_fpga constant addrw : integer := 18; use work.pack_ase_fpga.all; entity profound is port ( addr : in std_logic_vector (addrw-1 downto 0); ... |
function parity (vec : input std_logic_vector) return std_logic is variable temp_parity : std_logic := '0'; begin for i in vec'range loop temp_parity := temp_parity xor vec(i); end loop; return temp_parity; end function; |
package alias_use is type opcode is record parity : std_logic; address : std_logic_vector(7 downto 0); data : std_logic_vector(7 downto 0); stop_bits : std_logic_vector(2 downto 0); end record; type data_array_type is array (0 to 3) of std_logic_vector (31 downto 0); end package; architecture rtl of alias_use is signal addr : std_logic_vector (11 downto 0); signal data_array : data_array_type; alias data_when_addr0 : std_logic_vector(31 downto 0) is data_array(0); signal rx_packet : opcode; alias rx_parity is rx_packet.parity; alias rx_addr is rx_packet.address; alias rx_data is rx_packet.data; alias rx_stop is rx_packet.stop_bits; begin data_when_addr0 <= data when addr = x"000" else (others => '0'); rx_data <= data_when_addr0; ... |
process (r1w0, addr_integer, data_regs1) begin -- process for i in 0 to 3 loop -- three-state the signal data_tri(i) <= (others => 'Z'); end loop; --i if r1w0 = '1' then case addr_integer is when 0 to 3 => data_tri(0) <= data_regs1(0); when 4 to 7 => data_tri(1) <= data_regs1(1); when 8 to 11 => data_tri(2) <= data_regs1(2); when 12 to 15 => data_tri(3) <= data_regs1(3); end case; end if; end process; -- concurrent assignments to data data <= data_tri(0); data <= data_tri(1); data <= data_tri(2); data <= data_tri(3); |
type ram_array is array (0 to 15) of std_logic_vector (5 downto 0); signal ram_data : ram_array; ... begin process(clk) --synchronous write begin if clk'event and clk = '1' then if we = '1' then ram_data(conv_integer(addr_sp)) <= data_to_ram; end if; end if; end process; --for single port, use the same address as -- is used for the write -- asynchronous read - dual port ram_data_dp <=ram_data(conv_integer(addr_dp)); end; |
type rom is arrary (0 to15) of std_logic_vector (3 downto 0); -- 16x4 ROM in Xilinx LUT's constant rom_data : rom := (x"F", x"A", x"7", x"0", x"1", x"5", x"C", x"D", x"9", x"4", x"8", x"2", x"6, x"3", x"B", x"E"); ... begin -- ROM read data_from_rom <= rom_data(conv_integer(addr)); ... end; |
type ram_array is array (0 to 127) of std_logic_vector (7 downto 0); signal ram_data : ram_array; ... begin process(clk) --synchronous write begin if clk'event and clk = '1' then addr_q0 <= addr; -- registered address/pipelined address if we = '1' then ram_data(conv_integer(addr)) <= data_to_ram; end if; end if; end process; data_from_ram <= ram_data(conv_integer(addr_q0)); ... end; |
process (clk) -- Explicit inference of a clock enable begin -- process if rising_edge(clk) then if tc = '1' then cnt <= cnt + '1'; end if; end if; end process; process (clk, reset) -- Implicit inference of a clock enable begin -- process if reset = '1' then state <= (others => '0'); cs <= "00"; elsif rising_edge(clk) then case (state) is when init => -- inference of a clock enable for signal cs state <= load; when fetch => if (a = '1' and b = '1') then -- inference of a clock enable for signal state state <= init; end if; cs <= "11"; when others => null; end case; end if; end process; |
library ieee ; use ieee.std_logic_1164.all; entity srltest is port( clk, en : in std_logic; din : in std_logic_vector(3 downto 0); dout : out std_logic_vector(3 downto 0) ); end srltest; architecture rtl of srltest is type srl_16x4_array is array (15 downto 0) of std_logic_vector(3 downto 0); signal sreg : srl_16x4_array; begin dout <= sreg(15) ; -- read from constant location srl_proc : process (clk, en) begin if rising_edge(clk) then if (en = '1') then sreg <= sreg(14 downto 0) & din ; -- shift the data -- Current Value sreg (15:1) sreg(0) -- Next Value sreg (14:0) din end if; end if; end process; end rtl; |
-- Asynchronous local reset and internally generated clock process (clk, reset, cnt_reset) begin -- process -- global and local async. reset if (reset = '1' or cnt_reset = '1') then tc <= '0'; cnt <= "0000"; elsif rising_edge(clk) then if cnt = "1110" then cnt_reset <= '1'; tc <= '1'; else cnt <= cnt + 1; tc <= '0'; cnt_reset <= '0'; end if; end if; end process; -- internally generated clock -tc process (tc, reset) begin -- process if reset = '1' then data_en <= (others => '0'); elsif rising_edge(tc) then data_en <= data; end if; end process; |
-- Synchronous Local reset and clock enable use process (clk, reset) variable tc : std_logic := '0'; begin -- process if reset = '1' then -- global asynchronous reset cnt <= "0000"; data_en <= (others => '0'); elsif rising_edge(clk) then if cnt = "1110" then cnt <= "0000"; --local synchronous reset data_en <= data; --terminal count clock enable else cnt <= cnt + '1'; tc := '0'; end if; end if; end process; |
process (clk)Figure 24: Priority Encoded Logic
begin if rising_edge(clk) then if data(2 downto 0) = "110" then if cs = '1' then if en = '1' then data_q <= data + 1; end if; -- if en = '1'... end if; -- if cs = '1' ... end if; -- if data(2 downto 0)... end if;-- if rising_edge(clk)... end process; -- should be replaced with... process (clk) begin if rising_edge(clk) then if data(2 downto 0) = "110" and cs = '1' and en = '1' then data_q <= data + 1; end if; end if; end process;
process (data_vec) variable parity_v : std_logic; begin parity_v := '0'; for i in data_vec'range loop parity_v := parity_v xor data_vec(i); end loop; parity <= parity_v; end process; |
--(1) Did not specify each possible state process (state) begin if state = "001" then cs <= "01"; elsif state = "010" then cs <= "10"; elsif state = "100" then cs <= "11"; end if; end process; |
--(2) Did not specify all possible -- outputs for each state process (state) begin case (state) is when "001" => cs(0) <= '1'; when "010" => cs(1) <= '1'; when "100" => cs(1 downto 0) <= "11"; when others => cs(1 downto 0) <= "00"; end case; end process; |
-- (1) Fixed Case implementation process (state) begin cs <= "00"; case (state) is when "001" => cs(0) <= '1'; when "010" => cs(1) <= '1'; when "100" => cs <= "11"; when others => cs <= "00"; end case; end process; |
--(2) Fixed if-then-else implementation process (state) begin if state = "001" then cs <= "01"; elsif state = "010" then cs <= "10"; elsif state = "100" then cs <= "11"; else cs <= "00"; end if; end process; |