Changes

Jump to navigation Jump to search
4,304 bytes added ,  17:53, 6 July 2007
no edit summary
Line 17: Line 17:     
Some notes on nomenclature and notation:
 
Some notes on nomenclature and notation:
* The term '''signal''' is sometimes used to generically refer to a line, pin, or bus.
+
* The term '''signal''' is sometimes used to generically refer to a line, pin, or bus.  Later you will see that the ''proper'' use of the term signal is to discuss an internal line or bus.  However, as pins are connected to internal lines and buses, sometimes sloppy terminology extends "signal" to include pins.
 
* Signals come in '''active-high''' and '''active-low''' varieties.  Active-high means that a logical 1 is "on" and a logical 0 is "off".  It is also known as "positive logic".  Active-low is the exact opposite; logical 0 is "on" and logical 1 is "off", and it is alternately known as "negative logic".
 
* Signals come in '''active-high''' and '''active-low''' varieties.  Active-high means that a logical 1 is "on" and a logical 0 is "off".  It is also known as "positive logic".  Active-low is the exact opposite; logical 0 is "on" and logical 1 is "off", and it is alternately known as "negative logic".
 
* Some signals serve double-duty.  As active-high logic they perform one operation, but as active-low logic they perform another operation.  This links these operations as complimentary pairs.  For example a shift register may shift its output or it may load a new value.  If it's not shifting then it's loading.  So the name would be something like "Shift/Load" to signify that shifting is active-high and loading is active-low.  Carrying over this notation, any signal that is written "/Name" is an active-low signal.  This notation is not always used, but it is quite common and I shall attempt to maintain this practice throughout the tutorial.  When writing on paper, an active-low signal is frequently denoted by an overbar instead of a leading slash.  Unless otherwise specified, a signal that is not marked as active-low is assumed to be active-high by default.  Some designs assume active-low as the default, but that will either be marked or implied by context (i.e. all active-high lines marked as such).
 
* Some signals serve double-duty.  As active-high logic they perform one operation, but as active-low logic they perform another operation.  This links these operations as complimentary pairs.  For example a shift register may shift its output or it may load a new value.  If it's not shifting then it's loading.  So the name would be something like "Shift/Load" to signify that shifting is active-high and loading is active-low.  Carrying over this notation, any signal that is written "/Name" is an active-low signal.  This notation is not always used, but it is quite common and I shall attempt to maintain this practice throughout the tutorial.  When writing on paper, an active-low signal is frequently denoted by an overbar instead of a leading slash.  Unless otherwise specified, a signal that is not marked as active-low is assumed to be active-high by default.  Some designs assume active-low as the default, but that will either be marked or implied by context (i.e. all active-high lines marked as such).
Line 142: Line 142:  
end DAC_emulator;
 
end DAC_emulator;
 
</pre>
 
</pre>
 +
 +
=== Filling the black box ===
 +
 +
Now that you have your black box, you need to fill it in.  The interior of the box is called the '''architecture'''.  First you declare that you are making an architecture and what it is an architecture of.  Then inside of there you have two sections: declaring your components, signals, and variables, and the actual control flow of the circuit.
 +
 +
Declarations come in three types (that I know of; there may be more):
 +
* '''Components''' are other blocks that you are including in your circuit.  Inside of a component is another circuit, which may contain still further components.
 +
* '''Signals''' are internal signals.  They are the wires connecting all of your components.  As with pins they come in STD_LOGIC and STD_LOGIC_VECTOR, but they do not have I/O polarity as they are strictly internal.  As a general rule you attach a signal to a pin so that you can either read from or write to that signal.
 +
* '''Variables''' are like variables in a normal software language.  They can only be used inside of a ''process'' (which I will discuss later).  Often in simple designs you can work around using variables and stick with just signals.  Unfortunately, you'll have to do a bit of online research to find out much detail about variables, as I hardly use them in these designs.
 +
Components and signals should all be declared up front in the declaration section.  As I mentioned, you can only use a variable inside of a process, so you would declare the variable within the process.
 +
 +
The framework for the architecture is shown here.
 +
 +
<pre>
 +
architecture DAC_emul_arch of DAC_emulator is
 +
    signal line_sig : STD_LOGIC;                    -- an internal signal line
 +
    signal bus_sig : STD_LOGIC_VECTOR (4 downto 2); -- a 3-bit internal signal bus
 +
begin
 +
    --------------------
 +
    -- code goes here --
 +
    --------------------
 +
end DAC_emul_arch;
 +
</pre>
 +
 +
As you can see, declarations happen before the "begin" and code goes after the "begin".  Even if you have no signals, components, or variables to declare, you must include the "begin" statement.
 +
 +
You may have noticed that I did not show a component.  Components require more discussion and will be demonstrated later.  Because the DAC emulator uses components, I will discuss that code later.  First we will discuss the components inside of the emulator and the final product will come later.
 +
 +
== The real code ==
 +
 +
Now that we've framed the whole thing, you're probably wondering what the actual code is.  Now we're going to discuss that.  We'll go through how the code works, showing examples from the DAC emulator components, and eventually build up to the full emulator.
 +
 +
=== A very important warning ===
 +
 +
The first thing you have to understand is that VHDL is '''not''' software.  It is a hardware description language.  Many people look at VHDL as a software tool to program the hardware and run into all sorts of problems.  Remember to think hardware.  The main pitfall is demonstrated in this bit of code:
 +
 +
<pre>
 +
statement_1;
 +
statement_2;
 +
for i = 1 to 5
 +
    statement_3;
 +
statement_4;
 +
</pre>
 +
 +
A software engineer looks at this and thinks it's quite simple.  First to execute is ''statement_1'', followed by ''statement_2''.  Then the loop is executed: the first iteration, followed by the second, all the way down to the fifth being the last part of the loop.  Finally ''statement_4'' is executed and the program terminates.  In software you'd be correct.
 +
 +
Now let's consider how this would run in VHDL.  Very simply: everything happens ''at once''.  If ''statement_1'' modifies signal x from 7 to 19 and ''statement_2'' reads statement x, what value will ''statement_2'' read?  '''7'''.  Not 19, because the two statements are simultaneous.  The same is true of the loop.  Iteration 1 comes no sooner than (and no later than) iteration 5.  So you need to keep that in mind: everything is simultaneous, regardless of where and how you type it into the code.  Forget that and you may never figure out why your circuit is trying to eat itself.
 +
 +
=== The basics: combinational logic ===
 +
 +
      Line 150: Line 201:  
|+VHDL Resolution Table
 
|+VHDL Resolution Table
 
|-
 
|-
!  !! U !! X !! 0 !! 1 !! Z !! W !! L !! H !! &#8212;
+
!  !! U !! X !! 0 !! 1 !! Z !! W !! L !! H !! &#8211;
 
|-
 
|-
 
! U
 
! U
Line 176: Line 227:  
| U || X || 0 || 1 || H || W || W || H || X
 
| U || X || 0 || 1 || H || W || W || H || X
 
|-
 
|-
! &#8212;
+
! &#8211;
 
| U || X || X || X || X || X || X || X || X
 
| U || X || X || X || X || X || X || X || X
 
|}
 
|}
Line 189: Line 240:  
* L: weak 0
 
* L: weak 0
 
* H: weak 1
 
* H: weak 1
* &#8212;: don't care
+
* &#8211;: don't care
461

edits

Navigation menu