Differences
This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
dt-code [2011/04/07 11:54] beckmanf with select repariert |
dt-code [2025/04/10 16:09] (current) beckmanf bilder in dokuwiki |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | === VHDL Code Beispiele === | + | ===== VHDL Entity and Architecture ===== |
- | == Entity and Architecture == | + | VHDL splits interface (entity) and implementation (architecture). The interface of a circuit is defined in the entity. The implementation is defined in the architecture. |
<code vhdl> | <code vhdl> | ||
Line 11: | Line 11: | ||
a_i : in std_ulogic; | a_i : in std_ulogic; | ||
b_i : in std_ulogic; | b_i : in std_ulogic; | ||
- | y_i : out std_ulogic); | + | y_o : out std_ulogic); |
- | end first; | + | end and_gate; |
architecture rtl of and_gate is | architecture rtl of and_gate is | ||
begin | begin | ||
y_o <= a_i and b_i; | y_o <= a_i and b_i; | ||
- | end rtl; | + | end architecture rtl; |
- | | + | |
</code> | </code> | ||
+ | Listing 1: Entity and Architecture for and_gate | ||
+ | |||
+ | The code in listing 1 describes the full code for a circuit called "and_gate". The entity with the name "and_gate" describes two input ports "a_i" and "b_i" and an output port "y_o". All ports here have the type "std_ulogic" which defines that those ports basically can have a logic 1 or 0 value. (Some other values for simulation purposes are left for now). An entity can have an arbitrary number of inputs and outputs. Each input and output can have a different type. | ||
+ | |||
+ | {{ :public:praktikum_digitaltechnik:and_gate.svg?width=300 |AND Gate Block}} | ||
+ | |||
+ | {{ :public:praktikum_digitaltechnik:and_gate.svg?linkonly |Figure 1}}: Block and_gate with a_i and b_i as inputs and y_o as output | ||
- | == Strukturelle Beschreibung von Schaltungen == | + | Figure 1 shows the block "and_gate" with the inputs and outputs. This represents the entity. The entity code does not imply any functionality. The name "and_gate" is an identifier, i.e. it does not imply that this block actually works as an and gate. |
+ | |||
+ | {{ :public:praktikum_digitaltechnik:and_gate_arch.svg?width=300 |}} | ||
+ | |||
+ | {{ :public:praktikum_digitaltechnik:and_gate_arch.svg?linkonly |Figure 2}}: Architecture of "and_gate" which just contains an AND gate. | ||
+ | |||
+ | The architecture with the name "rtl" describes the implementation. Here it is a signal assignment with a boolean expression using the and function. This makes this circuit behave like an AND gate. Figure 2 shows the schematic with the AND gate. As the AND function can be described in one line of code, this block "and_gate" does not make too much sense, but it explains the idea of entity and architecture. | ||
+ | |||
+ | ===== Instantiation and hierarchical design ===== | ||
+ | |||
+ | Circuits are very often composed of subcircuits. And the subcircuits can themself be composed of subcircuits. This is called hierarchical design. The following example shows a block "mux". | ||
+ | |||
+ | {{ :public:praktikum_digitaltechnik:mux.svg?width=200 | Multipexer block}} | ||
+ | |||
+ | {{ :public:praktikum_digitaltechnik:mux.svg?linkonly |Figure 3}}: "mux" block with a_i, b_i and s_i inputs and y_o output | ||
+ | |||
+ | Figure 3 shows the block interface of a circuit "mux" which has three inputs a_i, b_i and s_i and an output y_o. | ||
+ | |||
+ | This "mux" is composed of two instances of "and_gate", an "or_gate" and an "inv_gate". | ||
+ | Assume that we have defined not only the "and_gate" but also an "or_gate" and an "inv_gate". The mux circuit shall be composed of the xxx_gate subcircuits as shown in figure 4. | ||
+ | |||
+ | {{ :public:praktikum_digitaltechnik:mux-vhdl.svg?width=800 | Mux Schematic}} | ||
+ | |||
+ | {{ :public:praktikum_digitaltechnik:mux-vhdl.svg?linkonly |Figure 4}}: Schematic of "mux" | ||
+ | |||
+ | Figure 4 shows a schematic of a multiplexer using and_gate, or_gate and the inv_gate. The corresponding VHDL code is shown in listing 2. | ||
<code vhdl> | <code vhdl> | ||
Line 35: | Line 66: | ||
end mux; | end mux; | ||
- | architecture structure of mux is | + | architecture structure of mux is |
- | + | ||
- | component and_gate | + | |
- | port( | + | |
- | a_i : in std_ulogic; | + | |
- | b_i : in std_ulogic; | + | |
- | y_o : out std_ulogic); | + | |
- | end component; | + | |
- | + | ||
- | component or_gate | + | |
- | port( | + | |
- | a_i : in std_ulogic; | + | |
- | b_i : in std_ulogic; | + | |
- | y_o : out std_ulogic); | + | |
- | end component; | + | |
- | + | ||
- | component inv_gate | + | |
- | port( | + | |
- | a_i : in std_ulogic; | + | |
- | y_o : out std_ulogic); | + | |
- | end component; | + | |
- | | + | |
signal s1 : std_ulogic; | signal s1 : std_ulogic; | ||
signal s2 : std_ulogic; | signal s2 : std_ulogic; | ||
signal s3 : std_ulogic; | signal s3 : std_ulogic; | ||
- | | ||
begin | begin | ||
- | inv_gate_i0 : inv_gate | + | inv_gate_i0 : work.inv_gate |
port map( | port map( | ||
a_i => s_i, | a_i => s_i, | ||
y_o => s1); | y_o => s1); | ||
| | ||
- | and_gate_i0 : and_gate | + | and_gate_i0 : work.and_gate |
port map( | port map( | ||
a_i => s1, | a_i => s1, | ||
Line 74: | Line 83: | ||
y_o => s2); | y_o => s2); | ||
| | ||
- | and_gate_i1 : and_gate | + | and_gate_i1 : work.and_gate |
port map( | port map( | ||
a_i => s_i, | a_i => s_i, | ||
Line 80: | Line 89: | ||
y_o => s3); | y_o => s3); | ||
| | ||
- | or_gate_i0 : or_gate | + | or_gate_i0 : work.or_gate |
port map( | port map( | ||
a_i => s2, | a_i => s2, | ||
Line 86: | Line 95: | ||
y_o => y_o); | y_o => y_o); | ||
- | end mux; | + | end architecture structure; |
</code> | </code> | ||
- | == Funktionale Beschreibung mit Concurrent Signal Assignments == | + | Listing 2: Structural VHDL code that instantiates and_gate, or_gate and inv_gate |
- | Eine alternative Beschreibung des Multiplexers mit Funktionen und | + | The instantiation code introduces the name of the instance. In this example the names of the "and_gate" instances are "and_gate_i0" and "and_gate_i1". The instantiation code instantiates "work.and_gate" which means that there is a component "and_gate" assumed to be in library "work". The "and_gate" component is created in the work library when the corresponding vhdl code that defines the "and_gate" is compiled. |
- | Concurrent Signal Assignments. Die Funktionen "not" "and", "or" und andere | + | |
- | sind im package ieee.std_logic_1164 definiert. | + | |
- | <code vhdl> | + | ===== Signals ===== |
- | architecture rtl-1 of mux is | + | Note the signals s1, s2 and s3 in listing 2 which work as internal nets in "mux". But it is also possible to assign the value of an input port to a signal. The value of a signal can also be assign to an output port. |
- | signal s1, s2, s3 : std_ulogic; | + | |
- | begin | + | |
- | s1 <= not s_i; | + | Signals are defined between "architecture" and the following "begin". |
- | s2 <= s1 and a_i; | + | |
- | s3 <= s_i and b_i; | + | |
- | y_o <= s2 or s3; | + | |
- | end rtl-1 | + | ===== Multiplexer Code - the real thing ===== |
- | </code> | + | |
- | == Funktionale Beschreibung mit einem Prozess == | + | The previous code example in listing 2 and listing 1 show the hierarchical design of a multiplexer. Nobody would ever do it like that - it only serves as an example for hierarchical design which is used when the subcircuits have some complexity. The multiplexer function as described in listing 2 can be written in one line of code in VHDL. Listing 3 shows the full code of "mux" with entity and architecture. The function inside the architecture is only one line of code. |
- | + | ||
- | Ein Prozess enthält sequentielle Anweisungen. Ein Prozess wird immer ausgeführt, wenn | + | |
- | sich ein Signal in der "sensitivity list" ändert. | + | |
- | + | ||
- | Die Sequenz der Anweisungen in einem Prozess entspricht nicht einer zeitlichen Sequenz. | + | |
- | Das bedeutet der Prozess berechnet die neuen Werte der Signale und diese werden dann alle | + | |
- | zeitgleich zugewiesen. Im folgenden Beispiel wurde die Anweisung s3 <= s_i and b_i durch einen | + | |
- | Prozess ersetzt. Die Funktion hat sich dadurch nicht geändert. | + | |
<code vhdl> | <code vhdl> | ||
+ | library ieee; | ||
+ | use ieee.std_logic_1164.all; | ||
- | architecture rtl-2 of mux is | + | entity mux is |
- | signal s1, s2, s3 : std_ulogic; | + | port ( |
- | begin | + | a_i : in std_ulogic; |
+ | b_i : in std_ulogic; | ||
+ | s_i : in std_ulogic; | ||
+ | y_o : out std_ulogic); | ||
+ | end mux; | ||
- | s1 <= not s_i; | + | architecture rtl of mux is |
- | s2 <= s1 and a_i; | + | |
- | -- s3 replaced with process | + | |
- | y_o <= s2 or s3; | + | |
- | + | ||
- | s3_and_p : process (s_i, b_i) | + | |
begin | begin | ||
- | s3 <= '0'; | + | y_o <= a_i when s_i = '0' else b_i; |
- | if s_i = '1' and b_i = '1' then | + | end architecture; |
- | s3 <= '1'; | + | |
- | end if; | + | |
- | end process s3_and_p; | + | |
- | + | ||
- | end rtl-2 | + | |
</code> | </code> | ||
- | == Komplette funtkionale Beschreibung in einem Prozess == | + | Listing 3: Multiplexer Code in one line |
- | + | ||
- | Alternativ lässt sich auch die ganze Multiplexerfunktion in einem | + | |
- | Prozess beschreiben. Die Lesbarkeit wird durch diese Beschreibung häufig erhöht. | + | |
- | + | ||
- | <code vhdl> | + | |
- | + | ||
- | architecture rtl-3 of mux is | + | |
- | + | ||
- | begin | + | |
- | + | ||
- | mux_p : process (s_i, a_i, b_i) | + | |
- | begin | + | |
- | y_o <= '0'; | + | |
- | if s_i = '1' then | + | |
- | y_o <= b_i; | + | |
- | else | + | |
- | y_o <= a_i; | + | |
- | end if; | + | |
- | end process mux_p; | + | |
- | + | ||
- | end rtl-3 | + | |
- | </code> | + | |
- | + | ||
- | == Prozess mit einem case statement == | + | |
- | + | ||
- | Alternativ lässt sich auch ein case statement in einem Prozess verwenden. | + | |
- | + | ||
- | <code vhdl> | + | |
- | + | ||
- | architecture rtl-4 of mux is | + | |
- | + | ||
- | begin | + | |
- | + | ||
- | mux_p : process (s_i, a_i, b_i) | + | |
- | begin | + | |
- | y_o <= '0'; | + | |
- | case s_i is | + | |
- | when '0' => y_o <= b_i; | + | |
- | when '1' => y_o <= a_i; | + | |
- | when others => y_o <= '0'; | + | |
- | end case; | + | |
- | end process mux_p; | + | |
- | + | ||
- | end rtl-4 | + | |
- | </code> | + | |
- | + | ||
- | == Conditional Signal Assignment == | + | |
- | + | ||
- | Dann gibt es noch das Conditional Signal Assignment. | + | |
- | + | ||
- | <code vhdl> | + | |
- | + | ||
- | architecture rtl-5 of mux is | + | |
- | + | ||
- | begin | + | |
- | + | ||
- | y_o <= b_i when s_i = '1' else a_i; | + | |
- | + | ||
- | end rtl-5 | + | |
- | </code> | + | |
- | + | ||
- | == Selected Signal Assignment == | + | |
- | + | ||
- | Noch eine alternative ist das selected signal assignment. | + | |
- | + | ||
- | <code vhdl> | + | |
- | + | ||
- | architecture rtl-6 of mux is | + | |
- | + | ||
- | begin | + | |
- | + | ||
- | with s_i select | + | |
- | y_o <= a_i when '0', | + | |
- | b_i when '1'; | + | |
- | + | ||
- | end rtl-6 | + | |
- | </code> | + | |
- | + | ||
- | + | ||