Está en la página 1de 9

VHDL as a language

VHDL is a combined language: it contains, like other typical programming languages, a number of constructs and commands that describe the processes and behavior over time, and also further elements that define the structures and relationships. These are used to define the behavior of the circuit. What is essential is the functional dependence of the outputs of circuit modules of their inputs, and the connection of the inputs to the outputs of the modules with other modules. This can be linked directly by or to flip flops, making the transfer of information takes place only in the next cycle. With this basic topology, all the important basic functions of digital circuits are represented. Finally, the behavior of the chip outputs is defined as a function of the chip inputs and all possible states in which the sub-circuits can be located, described here in full. VHDL is important in the understanding that all explicit temporal processes are only executed during the simulation as they are expected from the usual rules of software technology. In the synthesis, however, some temporal constructs and relationships are ignored and only the structures themselves are included in the circuit. Such as the arrangement of the code and the order of the processes and sequence of signal assignments so that is in a module but largely irrelevant.
[ edit ]

Simulation

In the simulation, the code is compiled and executed in a classical manner. The arrangement of lines of code may also be relevant, as the timing of modules specific dependencies have individual signals.In this role, VHDL is used mainly for writing testbenches and models. For details see the article VHDL testbench .
[ edit ]

Synthesis

In the description of the synthesis of a synthesis software is converted into a net list. The fundamental difference to the use of VHDL as a simulation language is that you can not write any code, but must adhere to certain structures that knows the synthesizer and can implement in hardware. Loops are executed at compile time, for example, to describe matrices, vectors or redundant structures and have no temporal relevance to the execution time. As these structures look like in general, is described below, we learn details in the documentation of the software, such as the XST User Guide .
[ edit ]

Basic rules for synthesizable VHDL code

The following basic rules should especially beginners comply in any case: There may be only two types of processes: 1. Purely combinatorial processes (no state memory): All signals are read in the process enter in the sensitivity list

Each output must be assigned a different value in each of themselves if branch, so that no latches arise (mein_signal<= mein_signal, are not allowed!) No clock edge query 2. Purely clocked processes (flip-flops as storage condition): Only Clk and asynchronous reset in the sensitivity list A maximum reset Only one clock edge query (rising_edge) As only one clock in the overall design, only rising OR evaluate falling clock edge. In order to detect an edge of an other signal, see VHDL edge detection . No clocks divide down, instead Clock Enable use. Etc. No "after", "wait for" use, which is not synthesized No use shared variable Variables only be used if you understand exactly what is the difference of a signal and can not solve the problem with signals No IEEE.STD_LOGIC_ use (UN) SIGNED, but IEEE.NUMERIC_STD (see calculation in VHDL )

[ edit ]

FAQ
= '1 'and CLK'event

[ edit ]CLK

or rising_edge

()

Question: In the description of flip-flops, two different constructs are used depending on the book / programmers: Variant 1 (classic): process(clk) begin ifclk= ' 1 ' andclk'event then - snip end if; end process; and Option 2: process(clk) begin if rising_edge (clk) then - snip end if; end process; What is recommended?

Answer: In short, in the synthesis there are no differences, small in the simulation. Use the more readable version. With the rising_edge () (or falling_edge () ) is generally considered the better (readability and accuracy of simulation). Who wants to know: The classic version is only correct for signals that can assume only the values '1 'and '0'. For signals of type std_logic (the default type for signals) are detected edges that are actually none. For example, when driving a PullUps ('H' -> '1 'but no actual edge of clk = '1 'and CLK'event ) or at the start of the simulation without initialization value for the signals ('U' -> '1 ') (. signals are declared with initialization: signal a: std_logic: = '0 '; ). The functions rising_edge () and falling_edge () to convert std_logic value before comparison to '1 'or '0' and thus simulate any edge where the real hardware is also no. http://www.mikrocontroller.net/forum/read-9-391894.html

[ edit ]

Synchronous or asynchronous reset

The following rules apply when considering whether one should use aansynchronen reset: In FPGAs, the use of reset functions usually leads to increased resource consumption. Sometimes, clock nets are used. Asynchronous resets require special treatment, so that the negative clock edge RST not come at a Clk edge, as this will inkonsitenten start conditions of the FFs can result in the FPGA. Many FPGAs as the init command are initialized in VHDL and no need to start (re) set - neither synchronous nor aysnchron. Often FPGAs operational safety reasons, require a synchronous reset operation by the middle of an instance as a controller when an error was detected. In these cases, an asynchronous reset is unnecessary. Asynchronous reset should be applied only at points of the circuit independent of each other electronics, such as have several chips, where one already assumes no total synchronicity and take measures to secure start-up of all circuit components. asynchronous reset must be clocked separately in each domain to keep them safe to run in synchronous reset Within an FPGA asynchronous resets to as PLLs should be performed so that the reset is not dependent on a second PLL. Should be translated into ASICs and FPGAs necessarily an asynchronous reset must be used there, asynchronous resets can be built conditionally compilable, so they need not necessarily be active in the FPGA

[ edit ]

reset default path in FPGAs

An effective and generally well-functioning design is as follows: external asynchronous reset the IO-PAD (for nReset via inverters) directly at the top level to the master PLL / or the main DCM, called "PLL1" The "PLL1" next to the clocks generated a LOCKED signal, which is used in inverted form as a reset for this domain. Is characterized by means of the LOCK signal from the aynchronen an internal reset, synchronous reset This internal reset zweimmaleinsynchronisiert in each individual domain of the PLL, to produce local reset signals. Thus the effects of metastable states can be prevented which may arise in the negative edge reset if the clock edges of the PLL generated clocks are accurate to this edge The internal reset "PLL1" also supplies all other PLLs of the other domains that generate to their local reset in the same way. The PLL1 in the domain of synchronous reset affects these PLLs asynchronous quasi.

This ensures that all PLLs have its own reset and they definitely start it. It is now important that is noted that the exact time of the reset, the different domains is unknown. Therefore, the locked signals that must be einsynchronsiert domains gfs again, so is known in the master domain if all subcircuits are underway and "start" the design is. For critical applications, where appropriate, must also be ensured that in the period between the start of the work of all FPGAs and FPGA PLLs all outputs are maintained at an appropriate level.
[ edit ]

When and why to use variables?

Variables are to be understood as intermediate results / synonyms for values derived from combinatorics / signals. They will each receive "immediately" after assigning its new value, which can be directly used elsewhere - such as if there were a direct wiring before. The use of variables thus decoupled from the calculation of any time constraints, especially the clock. Thus, it is possible to calculate complex architectures and model behavior within simulations without loss of time, see examples below. Signals obtained against its newly assigned value after the complete execution of a process, according to any practical delta delay or after a specified time. They represent a physical signal chain with actual data flow. While variables therefore in a process may be the same continue to be used, signals are in fact leads until the next cycle to date (the delta delay means that the value for this run is not valid, the next iteration of the clocked process happens only one clock cycle later . For asynchronous processes, the process of using signals is then started again ... (Or often, so many interdependent signal assignments are in it), it is calculated for variables in a single run (Simulationszeit!).

Has the use of variables to signals sometimes advantages in terms of execution time in simulations where extensive calculations are needed, which would otherwise be carried out with vectors.

Examples:
[ edit ]

Example 1

- Use of signals - the last statement is valid and overrides all previous instructions - Is real in the signal definition to begin signal a : std_logic; process(clk) begin if rising_edge (clk) then a <= a andb , a <= a andc , end if, end process; - Result: a <= a and c, the above line is ignored

- Use of variables - Consecutive statements are logically effective immediately and incorporated into the new instructions, the instructions are thus linked process(clk) variable a : std_logic; begin if rising_edge (clk) then a : = a and b , a : = a and c , end if, end process; - Result: a <= a and b and c, as in the normal chain of command languages It can be quite confusing when you have a complex calculation and those with many nested levels of parentheses describes directly in the signal assignment. Here it may be better value "by and by" using tags "to assemble" and assign only at the end of a signal. Sometimes you want to pre-compute common subexpressions, eg

Var1 : = A + var2 : = C + Var3 : = E + Result1 <= Result2 <=

B ; D ; F ; Var1 -Var2 ; Var1 -Var3 ;

is usually better than Result1 <= ( A + B ) - ( C + D ) ; Result2 <= ( A + B ) - ( E + F ) ; When things get more complex, it is also easier because what to change. Different synthesis tools can sometimes more, sometimes less well optimized. So you can, for example, by combining a partial printout achieve a better optimization (keyword resource sharing). For example:

if (opcode= add ) then res<= a + b ; else -opcode = sub res<= a - b ; end if; or if (opcode= add ) then var1 : = b , else var1 : = - b ; end if; res<= a + var1 ; In the first case, an adder and a subtracter (adder noch'n) is incorporated, if necessary and are multiplexed the result, in the second case may be an adder only and is incorporated multiplexed b-input of the adder. If a and b, for example, 32-bit vectors, then makes the HW standard of something. Good synthesis tools should automatically do this but in the meantime, as in both cases the same thing comes out (was not always). (BTW, I myself usually tend to the first option, since more readable - and one should not necessarily anticipate the hardware implementation, but since everyone has their own opinion ...)
[ edit ]

Example 2

For analog filters, it is often necessary to use iterative loop to obtain the results. Only the use of variables and loops it possible to achieve complex computational results of "analog" response rate from the simulator, simulation without time or to let pass even bars.

[ edit ]

Speed

Simulators usually expect quicker than using signals with variables. So if you have a lot of processes with signals vs. Variables in a large design, then this can already make up what ... See above for asynchronous processes that are possibly go through with signals much more often. Thus, even if a system is to be mapped to signals, the use of variables is recommended but sometimes. Exception: Usually based only on the signals and clocked processes models are fully and easily synthesierbar. If, for example, a model in a HIL tested system, the use of signals with appropriate consideration of the timing is appropriate.
[ edit ]

Beginner problems

Beginners often think they can use the direct assignment of a value to a variable in the process profitable. Thus variables are then used extensively and overlooked one of the main problems of variables: they can not be listed in the Sensitive List of a process. From this side effect in particular are stored variables concerned. In the post http://www.mikrocontroller.net/topic/117630 a few examples are mentioned. , the main problem in this behavior is that the (error-free) simulation are not the result of synthesis (which was also created without errors or warnings) fits .
[ edit ]

encoder circuits

Encoding circuits (Coder) are circuits having a multi-digit input and output. In any of the FF circuit or other memory may be used. A typical example is the conversion of a binary number into a binary-coded decimal. A very concise notation uses a constant field. Advantages and disadvantages of various VHDL variants to describe a coder here discussed.
[ edit ]

If outside of a process?

If conditions are not possible outside of a process. Solution: vector_or<= ' 0 ' Whenoder_vector= X "0000" else ' 1 ' ; This is the technical conditional assignment (conditional assignment), it is one of the concurrent statements of VHDL. There are also similar purpose to a select statement: with vector select bit_pos<= "00" When "0001" , "01" When"0010" , "10" When"0100" , "11" When"1000" , "00" Whenothers ;

For bulky cases that can be formulated using these concurrent assignments partout unreadable and / or elegantly, either offers a combinatorial process or to pack the assignment in a function. In both cases the result vector can then gradually assemble with if statements.
[ edit ]

All lines on "0000 .." or "1111 ..." set?

Set to zero: count<= ( others => ' 0 ' ) ; Set on one: count<= ( others => ' one ' ) ;
[ edit ]

Comparison of a std_logic_vector with a constant

A std_logic_vector to "00000 ..." or "1111 ..." compare the (others => '0 ') notation can not be used because the vector width is not defined. Here, then, a range must be specified: if VECTOR = ( 15 downto0 => ' 0 ' ) then .. or if VECTOR = ( VECTOR ' range => ' 0 ' ) then ... This notation is universal for all libs. Values "000." Unequal and "1111 ..." somewhat more complex must be converted using the NUMERIC_STD.ALL (here the value 77): if VECTOR = std_logic_vector (to_unsigned( 77 , VECTOR 'length ) ) then ... If the vendor specific synopsis Lib STD_LOGIC_UNSIGNED.ALL used can also be simply written as: if VECTOR = 0 then ... Just as easily go a comparison to, for example the value 77: if VECTOR = 77 then ...
[ edit ]

Report of std_logic_vector

Report can only handle strings, so a std_logic_vector must be transformed into a string: report integer'image (to_integer( unsigned (rdata) ) ) ;

[ edit ]

parallel -> serial: shift register or multiplexer?

También podría gustarte