Writing VHDL for RTL SynthesisStephen A. Edwards, Columbia UniversityJanuary 2011The name VHDL is representative of the language itself: it is a two-level acronymthat stands for VHSIC Hardware Description Language; VHSIC stands for very highspeed integrated circuit. The language is vast, verbose, and was originally designedfor modeling digital systems for simulation. As a result, the full definition of the lan-guage [1] is much larger than what we are concerned with here because many con-structs in the language (e.g., variables, arbitrary events, floating-point types, delays)do not have hardware equivalents and hence not synthesizable.Instead, we focus here on a particular dialect of VHDL dictated in part by theIEEE standard defining RTL synthesis [2]. Even within this standard, there are manyequivalent ways to do essentially the same thing (e.g., define a process representingedge-sensitive logic). This document presents a particular idiom that works; it doesnot try to define all possible synthesizable VHDL specifications.1 StructureMuch like a C program is mainly a series of function definitions, a VHDL specificationis mainly a series of entity/architecture definition pairs. An entity is an object with aseries of input and output ports that represent wires or busses, and an architectureis the “guts” of an entity, comprising concurrent assignment statements, processes,or instantiations of other entities.Concurrent assignment statements that use logical expressions to define the val-ues of signals are one of the most common things in architectures. VHDL supportsthe logical operators and, or, nand, nor, xnor, xnor, and not.library ieee; −− add this to the IEEE libraryuse ieee.std_logic_1164.all; −− in cl udes std_logicentity full_adder isport(a, b, c : in std_logic;sum, carry : out std_logic);end full_adder;architecture imp of full_adder isbeginsum <= (a xor b) xor c; −− combin ation al logiccarry <= (a and b) or (a and c) or (b and c);end imp;11.1 ComponentsOnce you have defined an entity, the next thing is to instantiate it as a componentwithin another entity’s architecture.The interface of the component must be defined in any architecture that instan-tiates it. Then, any number of port map statements create instances of that compo-nent.Here is how to connect two of the full adders to give a two-bit adder:library ieee;use ieee.std_logic_1164.all;use ieee.numeric_std.all; −− includes unsignedentity add2 isport (A, B : in unsigned(1 downto 0);C : out unsigned(2 downto 0));end add2;architecture imp of add2 iscomponent full_adderport (a, b, c : in std_logic;sum, carry : out std_logic);end component;signal carry : std_logic;beginbit0 : full_adder port map (a => A(0),b => B(0),c => ’0’,sum => C(0),carry => carry);bit1 : full_adder port map (a => A(1),b => B(1),c => carry,sum => C(1),carry => C(2));end imp;21.2 MultiplexersThe when...else construct is one way to specify a multiplexer.library ieee;use ieee.std_logic_1164.all;use ieee.numeric_std.all;entity multiplexer_4_1 isport(in0, in1, in2, in3 : in unsigned(15 downto 0);s : in unsigned( 1 downto 0);z : out unsigned(15 downto 0));end multiplexer_4_1;architecture imp of multiplexer_4_1 isbeginz <= in0 when s = "00" elsein1 when s = "01" elsein2 when s = "10" elsein3 when s = "11" else(others => ’X’);end imp;The with...select is another way to describe a multiplexer.library ieee;use ieee.std_logic_1164.all;use ieee.numeric_std.all;entity multiplexer_4_1 isport(in0, in1, in2, in3 : in unsigned(15 downto 0);s0, s1 : in std_logic;z : out unsigned(15 downto 0));end multiplexer_4_1;architecture usewith of multiplexer_4_1 issignal sels : unsigned(1 downto 0); −− Local wiresbeginsels <= s1 & s0; −− vector concatenationwith sels selectz <= in0 when "00",in1 when "01",in2 when "10",in3 when "11",(others => ’X’) when others;end usewith;31.3 DecodersOften, you will want to take a set of bits encoded in one way and represent them inanother. For example, the following one-of-eight decoder takes three bits and usesthem to enable one of eight.library ieee;use ieee.std_logic_1164.all;use ieee.numeric_std.all;entity dec1_8 isport (sel : in unsigned(2 downto 0);res : out unsigned(7 downto 0));end dec1_8;architecture imp of dec1_8 isbeginres <= "00000001" when sel = "000" else"00000010" when sel = "001" else"00000100" when sel = "010" else"00001000" when sel = "011" else"00010000" when sel = "100" else"00100000" when sel = "101" else"01000000" when sel = "110" else"10000000";end imp;1.4 Priority EncodersA priority encoder returns a binary value that indicates the highest set bit amongmany. This implementation says the output when none of the bits are set is a “don’t-care,” meaning the synthesis system is free to generate any output it wants for thiscase.library ieee;use ieee.std_logic_1164.all;use ieee.numeric_std.all;entity priority isport (sel : in unsigned(7 downto 0);code : out unsigned(2 downto 0));end priority;architecture imp of priority isbegincode <= "000" when sel(0) = ’1’ else"001" when sel(1) = ’1’ else"010" when sel(2) = ’1’ else"011" when sel(3) = ’1’ else"100" when sel(4) = ’1’ else"101" when sel(5) = ’1’ else"110" when sel(6) = ’1’ else"111";end imp;41.5 Arithmetic UnitsVHDL has extensive support for arithmetic. Here is an unsigned 8-bit adder withcarry in and out. By default VHDL’s + operator returns a result that is the same widthas its arguments, so it is necessary to zero-extend them to get the ninth (carry) bitout. One way to do this is to convert the arguments to integers, add them, thenconvert them back.library ieee;use ieee.std_logic_1164.all;use ieee.numeric_std.all;entity adder isport (A, B : in unsigned(7 downto 0);CI : in std_logic;SUM : out unsigned(7 downto 0);CO : out std_logic);end adder;architecture imp of adder issignal tmp : unsigned(8 downto 0);begintmp <= A + B + ("0" & CI); −− promote CI to unsignedSUM <= tmp(7 downto 0);CO <= tmp(8);end imp;A very primitive ALU might perform either addition or subtraction:library ieee;use ieee.std_logic_1164.all;use ieee.numeric_std.all;entity alu isport (A, B : in unsigned(7 downto 0);ADD : in std_logic;RES : out unsigned(7 downto 0));end alu;architecture imp of alu isbeginRES <= A + B when ADD = ’1’ elseA − B;end imp;5VHDL provides the usual arithmetic comparison operators. Note that signed andunsigned versions behave differently.library ieee;use ieee.std_logic_1164.all;use
View Full Document