Open main menu
Home
Random
Recent changes
Special pages
Community portal
Preferences
About Wikipedia
Disclaimers
Incubator escapee wiki
Search
User menu
Talk
Dark mode
Contributions
Create account
Log in
Editing
VHDL
(section)
Warning:
You are not logged in. Your IP address will be publicly visible if you make any edits. If you
log in
or
create an account
, your edits will be attributed to your username, along with other benefits.
Anti-spam check. Do
not
fill this in!
==Design examples== {{how-to|section|date=January 2013}} In VHDL, a design consists at a minimum of an ''entity'' which describes the interface and an ''architecture'' which contains the actual implementation. In addition, most designs import library modules. Some designs also contain multiple architectures and ''configurations''. A simple [[Logic gate|AND gate]] in VHDL would look something like: <syntaxhighlight lang="vhdl"> -- (this is a VHDL comment) /* this is a block comment (VHDL-2008) */ -- import std_logic from the IEEE library library IEEE; use IEEE.std_logic_1164.all; -- this is the entity entity ANDGATE is port ( I1 : in std_logic; I2 : in std_logic; O : out std_logic); end entity ANDGATE; -- this is the architecture architecture RTL of ANDGATE is begin O <= I1 and I2; end architecture RTL; </syntaxhighlight> (Notice that <code>RTL</code> stands for ''[[Register transfer level]]'' design.) While the example above may seem verbose to HDL beginners, many parts are either optional or need to be written only once. Generally, simple functions like this are part of a larger behavioral module, instead of having a separate module for something so simple. In addition, use of elements such as the <code>std_logic</code> type might at first seem to be an overkill. One could easily use the built-in <code>bit</code> type and avoid the library import in the beginning. However, using a form of [[many-valued logic]], specifically [[IEEE 1164|9-valued logic]] (<code>U</code>,<code>X</code>,<code>0</code>,<code>1</code>,<code>Z</code>,<code>W</code>,<code>H</code>,<code>L</code>,<code>-</code>), instead of simple bits (0,1) offers a very powerful simulation and debugging tool to the designer which currently does not exist in any other HDL. In the examples that follow, one will see that VHDL code can be written in a very compact form. However, more experienced designers usually avoid these compact forms and use a more verbose coding style for the sake of readability and maintainability. ===Synthesizable constructs and VHDL templates=== VHDL is frequently used for two different goals: simulation of electronic designs and synthesis of such designs. Synthesis is a process where a VHDL is compiled and mapped into an implementation technology such as an FPGA or an ASIC. Not all constructs in VHDL are suitable for synthesis. For example, most constructs that explicitly deal with timing such as <code>wait for 10 ns;</code> are not synthesizable despite being valid for simulation. While different synthesis tools have different capabilities, there exists a common ''synthesizable subset'' of VHDL that defines what language constructs and idioms map into common hardware for many synthesis tools. IEEE 1076.6 defines a subset of the language that is considered the official synthesis subset. It is generally considered a "best practice" to write very idiomatic code for synthesis as results can be incorrect or suboptimal for non-standard constructs. ===MUX template=== The [[multiplexer]], or 'MUX' as it is usually called, is a simple construct very common in hardware design. The example below demonstrates a simple two to one MUX, with inputs <code>A</code> and <code>B</code>, selector <code>S</code> and output <code>X</code>. Note that there are many other ways to express the same MUX in VHDL.<ref>{{cite web |url=https://www.fpgatutorial.com/vhdl-logical-operators-and-signal-assignments-for-combinatorial-logic/#vhdl-mux |title=VHDL Logical Operators and Signal Assignments for Combinatorial Logic |website=FPGAtutorial |date=16 May 2020 |access-date=2020-08-23}}</ref> <syntaxhighlight lang="VHDL">X <= A when S = '1' else B;</syntaxhighlight> A more complex example of a MUX with 4Γ3 inputs and a 2-bit selector: <syntaxhighlight lang="vhdl"> library IEEE; use IEEE.std_logic_1164.all; entity mux4 is port( a1 : in std_logic_vector(2 downto 0); a2 : in std_logic_vector(2 downto 0); a3 : in std_logic_vector(2 downto 0); a4 : in std_logic_vector(2 downto 0); sel : in std_logic_vector(1 downto 0); b : out std_logic_vector(2 downto 0) ); end mux4; architecture rtl of mux4 is -- declarative part: empty begin p_mux : process(a1,a2,a3,a4,sel) begin case sel is when "00" => b <= a1 ; when "01" => b <= a2 ; when "10" => b <= a3 ; when others => b <= a4 ; end case; end process p_mux; end rtl; </syntaxhighlight> ===Latch template=== A [[transparent latch]] is basically one bit of memory which is updated when an enable signal is raised. Again, there are many other ways this can be expressed in VHDL. <syntaxhighlight lang="vhdl"> -- latch template 1: Q <= D when Enable = '1' else Q; -- latch template 2: process(all) begin Q <= D when(Enable); end process; </syntaxhighlight> ===D-type flip-flops=== The D-type [[Flip-flop (electronics)|flip-flop]] samples an incoming signal at the rising (or falling) edge of a clock. This example has an asynchronous, active-high reset, and samples at the rising clock edge. <syntaxhighlight lang="vhdl"> DFF : process(all) is begin if RST then Q <= '0'; elsif rising_edge(CLK) then Q <= D; end if; end process DFF; </syntaxhighlight> Another common way to write edge-triggered behavior in VHDL is with the 'event' signal attribute. A single apostrophe has to be written between the signal name and the name of the attribute. <syntaxhighlight lang="vhdl"> DFF : process(RST, CLK) is begin if RST then Q <= '0'; elsif CLK'event and CLK = '1' then Q <= D; end if; end process DFF; </syntaxhighlight> VHDL also lends itself to "one-liners" such as: <syntaxhighlight lang="VHDL"> DFF : Q <= '0' when RST = '1' else D when rising_edge(clk); </syntaxhighlight> or: <syntaxhighlight lang="vhdl"> DFF : process(all) is begin if rising_edge(CLK) then Q <= D; end if; if RST then Q <= '0'; end if; end process DFF; </syntaxhighlight> or:<syntaxhighlight lang="vhdl"> Library IEEE; USE IEEE.Std_logic_1164.all; entity RisingEdge_DFlipFlop_SyncReset is port( Q : out std_logic; Clk : in std_logic; sync_reset : in std_logic; D : in std_logic ); end RisingEdge_DFlipFlop_SyncReset; architecture Behavioral of RisingEdge_DFlipFlop_SyncReset is begin process(Clk) begin if (rising_edge(Clk)) then if (sync_reset='1') then Q <= '0'; else Q <= D; end if; end if; end process; end Behavioral; </syntaxhighlight>Which can be useful if not all signals (registers) driven by this process should be reset. ===Example: a counter=== The following example is an up-counter with asynchronous reset, parallel load and configurable width. It demonstrates the use of the 'unsigned' type, type conversions between 'unsigned' and 'std_logic_vector' and VHDL ''generics''. The generics are very close to arguments or templates in other traditional programming languages like C++. The example is in VHDL 2008 language. <syntaxhighlight lang="vhdl"> library IEEE; use IEEE.std_logic_1164.all; use IEEE.numeric_std.all; -- for the unsigned type entity COUNTER is generic ( WIDTH : in natural := 32); port ( RST : in std_logic; CLK : in std_logic; LOAD : in std_logic; DATA : in std_logic_vector(WIDTH-1 downto 0); Q : out std_logic_vector(WIDTH-1 downto 0)); end entity COUNTER; architecture RTL of COUNTER is begin process(all) is begin if RST then Q <= (others => '0'); elsif rising_edge(CLK) then if LOAD='1' then Q <= DATA; else Q <= std_logic_vector(unsigned(Q) + 1); end if; end if; end process; end architecture RTL; </syntaxhighlight> More complex counters may add if/then/else statements within the <code>rising_edge(CLK) elsif</code> to add other functions, such as count enables, stopping or rolling over at some count value, and generating output signals like terminal count signals. Care must be taken with the ordering and nesting of such controls if used together, in order to produce the desired priorities and minimize the number of logic levels needed. ===Simulation-only constructs=== A large subset of VHDL cannot be translated into hardware. This subset is known as the non-synthesizable or the simulation-only subset of VHDL and can only be used for prototyping, simulation and debugging. For example, the following code will generate a clock with a frequency of 50 MHz. It can, for example, be used to drive a clock input in a design during simulation. It is, however, a simulation-only construct and cannot be implemented in hardware. In actual hardware, the clock is generated externally; it can be scaled down internally by user logic or dedicated hardware. <syntaxhighlight Lang="VHDL"> process begin CLK <= '1'; wait for 10 NS; CLK <= '0'; wait for 10 NS; end process; </syntaxhighlight> The simulation-only constructs can be used to build complex waveforms in a very short time. Such waveforms can be used, for example, as test vectors for a complex design or as a prototype of some synthesizer logic that will be implemented in the future. <syntaxhighlight Lang="VHDL"> process begin wait until START = '1'; -- wait until START is high for i in 1 to 10 loop -- then wait for a few clock periods... wait until rising_edge(CLK); end loop; for i in 1 to 10 loop -- write numbers 1 to 10 to DATA, 1 every cycle DATA <= to_unsigned(i, 8); wait until rising_edge(CLK); end loop; -- wait until the output changes wait on RESULT; -- now raise ACK for clock period ACK <= '1'; wait until rising_edge(CLK); ACK <= '0'; -- and so on... end process; </syntaxhighlight>
Edit summary
(Briefly describe your changes)
By publishing changes, you agree to the
Terms of Use
, and you irrevocably agree to release your contribution under the
CC BY-SA 4.0 License
and the
GFDL
. You agree that a hyperlink or URL is sufficient attribution under the Creative Commons license.
Cancel
Editing help
(opens in new window)