450 likes | 581 Views
Some VHDL slides from the ebook “Free Range VHDL” by Brian Mealy and Fabrizio Tappero The ebook is licensed under the Creative Commons – see www.freerangefactory.org for details, and a copy. IJ.McCrum@ulster.ac.uk Room 5B18, Telephone: 02890366364 voicemail on 6 th ring
E N D
Some VHDL slides from the ebook“Free Range VHDL”by Brian Mealy and FabrizioTapperoThe ebook is licensed under the Creative Commons – see www.freerangefactory.org for details, and a copy. IJ.McCrum@ulster.ac.uk Room 5B18, Telephone: 02890366364 voicemail on 6th ring http://www.eej.ulst.ac.uk/~ian/modules
VHDL : the V is short for yet another acronym: VHSIC or Very High-Speed Integrated Circuit. The HDL stands for Hardware Description Language. HDL was invented to describe hardware and VHDL is a concurrent language. What this means is that, normally, VHDL instructions are all executed at the same time Attempts to write VHDL code with a high-level language style generally result in code that nobody understands. Moreover, the tools used to synthesize this type of code have a tendency to generate circuits that generally do not work correctly and have bugs that are nearly impossible to trace. There are two primary purposes for hardware description languages such as VHDL. First, VHDL can be used to model digital circuits and systems. Second, having some type of circuit model allows for the subsequent simulation and/or testing of the circuit. The VHDL model can also be translated into a form that can be used to generate actual working circuits. - synthesis Held at www.eej.ulst.ac.uk
Golden Rules of VHDL VHDL is a hardware-design language. Although most people have probably already been exposed to some type of higher-level computer language, these skills are only indirectly applicable to VHDL. When you are working with VHDL, you are not programming, you are ``designing hardware''. Your VHDL code should reflect this fact. What does this mean? It means that unless you are inside certain constructs, your code lines will be executed almost all at once. If your VHDL code appears too similar to code of a higher-level computer language, it is probably bad VHDL code. This is vitally important. Have a general concept of what your hardware should look like. Digital design is similar to higher-level language programming in that even the most complicated programming at any level can be broken down into some simple programming constructs. if you are not able to roughly envision the digital circuit you are trying to model in terms of basic digital circuits, you will probably misuse VHDL. Held at www.eej.ulst.ac.uk
VHDL Language • Several variants: -87 -93 and then minor 2000,2002,2008 • VHDL is not case sensitive • White space: VHDL ignores spaces or tabs • Comments: The VHDL synthesizer ignores anything after two dashes up to the line end • Brackets: VHDL is relatively lax on its requirement for using () parentheses. Like other computer languages, there are a few precedence rules associated with the various operators in the VHDL language. Though it is possible to learn all these rules and write clever VHDL source code that will ensure the readers of your code are left scratching their heads, a better idea is to practice liberal use of parentheses to ensure the human reader of your source code understands the purpose of the code. • Indenting: USE IT. Held at www.eej.ulst.ac.uk
VHDL Statements • every VHDL statement is terminated with a semicolon but beware what a “statement” is. • Every if statement has a corresponding then • If tests need not have ( ) but please add them • Each if is terminated with an end if; • The else if construct in VHDL is elsif • case statements are terminated with end case; • loop statements have an end loop; statement • Identifiers should be well named, letters, digits and underscores • Begin identifiers with a letter, do not use _ _ or end in an _ Use a good editor/help file; A good programmer distinguishes himself by other means than perfectly remembering code syntax. Held at www.eej.ulst.ac.uk
VHDL Design Units • VHDL descriptions of circuits are based on the black-box approach. • In VHDL, the black box is referred to as entity and the stuff that goes inside it is referred to as the architecture • Entities list the interface between the edge of the black box and the rest of the world; the external interface. This uses the PORT keyword. • There is also a GENERIC keyword. We can adjust this for each instance of an entity in our design – each black box can use the GENERIC data inside to configure that particular instance. << ignore this for now >> Held at www.eej.ulst.ac.uk
entitymy_entityis port( port_name_1 : in std_logic ; -- std_logic is a “TYPE” port_name_2 : out std_logic; -- useful for real circuits port_name_3 : inoutstd_logic ); --do not forget the semicolon endmy_entity; -- do not forget this semicolon either Mode can be one of 4 words, use in and out at first. Avoid mode “buffer” The most common typing error is to add an extra semicolon here! ------------------------------------------------------------------------------------------- -- Example of a MUX that selects one of four bus lines for the output. -------------------------------------------------------------------------------------------- entity mux4 is port ( a_data : in std_logic_vector(0 to 7); -- how groups of bits are handled b_data : in std_logic_vector(0 to 7); -- you can also say 7 downto 0 c_data : in std_logic_vector(0 to 7); -- these “TYPES” are defined d_data : in std_logic_vector(0 to 7); -- in an IEEE library which you specify sel1,sel0 : in std_logic; -- note also you can have a list of identifiers data_out : out std_logic_vector(0 to 7)); -- NB watch out for that semicolon! end mux4; Earlier versions of VHDL used end entity mux4; as the correct syntax, most systems now accept it as well Held at www.eej.ulst.ac.uk
Data type std_logic and std_logic_vector The data type std_logic and the data type std_logic_vector are what the IEEE has standardized for the representation of digital signals. Normally, these data types assume the logic value 1 or the logic value 0. However, as specified in the std_logic_1164 package, the implementation of these types includes 9 different values, specifically: 0,1,U,X,Z,W,L,H,-. The data type std_logic becomes available to you after you declare. library IEEE; use IEEE.std_logic_1164.all; at the beginning of your code. The reason for all these values is the desire for modelling three-state drivers, pull-up and pull-down outputs, high impedance state and a few others types of inputs/outputs. For more details refer to the IEEE 1164 Standard or http://en.wikipedia.org/wiki/IEEE_1164 avoid the use of the simpler bit types You are allowed to have std_logic outputs connected together – needed for open-collector and tristate modelling. There is a std_ulogic type that does not allow outputs to be wired together. Just use std_logic for now Held at www.eej.ulst.ac.uk
VHDL Standard Libraries library IEEE; use IEEE.std_logic_1164.all; -- basic IEEE library useIEEE.numeric_std.all; -- IEEE library for unsigned type and arithmetic operators -- WARNING DO NOT use the following libraries (not universal) -- IEEE.std_logic_arith.,IEEE.std_logic_unsigned or IEEE.std_logic_signed entitymy_entis port ( A,B,C : in std_logic; F : out std_logic); endmy_ent; architecturemy_archofmy_entis -- connects architecture “my_arch” to the entity -- signals are internal wires declared like ports but without mode -- a std_logic_vector is a collection of wires, not a number, hence we need other types. signal v1,v2 : std_logic_vector (3 downto 0); -- can’t add or subtract std_logic_vectors signal u1 : unsigned (3 downto 0); -- a collection of bits treated as a number signal i1 : integer; -- VHDL has ordinary numbers, avoid if building hardware begin u1 <= "1101"; -- note how to have std_logic_vector constants, must match length! i1 <= 13; -- note SIGNAL ASSIGNMENT operator “will become equal to “ v1 <=std_logic_vector(u1); -- = "1101" VHDL strictly typed MUST use conversions v2 <= std_logic_vector(to_unsigned(i1, v2'length)); -- = "1101“ must pass length -- "4" could be used instead of "v2'length", but the "length“ attribute handier F <= NOT (A AND B AND C); -- VHDL operators,OR and EXOR etc., also available. end my_arch;. Held at www.eej.ulst.ac.uk
ARCHITECTURES Three common architectural styles (if your target is h/w) • Data-flow – contains just concurrent statements, each with a <= signal assignment. There are 3 or 4 types of signal assignments; simple concurrent signal assignment, conditional concurrent signal assignment and selected signal assignment (and processes - avoid use in simple data-flow architectures.) If you can picture the h/w dataflow is easy. • Behavioural - contains concurrent and sequential statements (sequential statements are inside processes but each process is a concurrent statement). Useful to partition design quickly, writing processes is easy if done right. • Structural – list a number of entities and simple list the connections between them – like a CAD netlist. One to one mapping to circuit diagram. Handy for testbenches. (required for some simulators) These are all close to the hardware, in practice you tend to combine them a bit – hybrid styles. This flavour of VHDL is sometimes called RTL-VHDL. If you want, you could write a VHDL architecture as a simple language program – an algorithmic style, this can’t be synthesised but can be “simulated”. VHDL is not a computer language, we often use the words analyse and elaborate a model rather than compiling a program and we simulate a model instead of running a compiled program… Having said that, our VHDL tools may (mis)use the verb compile and actually they synthese into a actual “circuit” and then “run” the model (i.e simulate) so don’t get hung up on the words used. Held at www.eej.ulst.ac.uk
Variables, Signals and Constants • The most frequently used object type is the signal. Its manipulation takes time into account. It represents a physical, real thing holding a value – a wire (the other popular HDL known as Verilog uses “wire” as a keyword, but VHDL uses signal) we use <= for signal assignment “will become equal to” or “a transaction is scheduled to occur at a point in the future”! • Ports are treated as signals coming in or going out from/to the outside world. • Conventional variables also exist, they have no physical significance and are typically only used inside processes – to hold a temporary value or loop counter. Typically you assign a variables contents to a signal at the end of the process. We use := to do variable assignment “becomes equal to” • The third object type is a constant – like a variable but can’t change. • You must declare these all before use, signals before the begin of a architecture, variables before the begin of a process • These three objects are strictly typed, you must match types, by extending/decreasing lengths or using conversions functions (or overloading operators) • There is a fourth data object is the file, which is not used for synthesis but is very convenient for large testbenches when simulating, or to store simulation results. We can avoid its use by using the simulator output viewers manually. Held at www.eej.ulst.ac.uk
After covering simple digital circuits (and this ebook) we can move on to simulate and synthesize a MIPs CPU written in VHDL. This requires using Quartus libraries (and packages) to efficiently implement memories. But the code above is fine for small memories within the FPGA. Most FPGAs have special provision for memory outside the normal 2D logic cells, hence the provision of special libraries Held at www.eej.ulst.ac.uk
Example of variable assignment (and a Process) Within the process all signal assignments are done as you execute the process. The process only gets executed if triggered by one of the signals that it is sensitive to changing (or once at “power up”) (a,b,c) is the sensitivity list for the process. We can (and should) name processes. Signal assignments are done as you exit the process These “execute” at the same time. If A or B changed in the process, G would use the “old” values of A and B Held at www.eej.ulst.ac.uk
Concurrent Statements: (note there is only a single <= and a single ; per statement) Signal Assignment Statement <target> <= <expressions> e.g. F <= NOT(A AND B AND C); Conditional Signal Assignment Statement <target> <= <expressions> when <condition> else <expression> when <condition> else <expression>; F <= ‘0’ WHEN (A=‘1’ )ELSE ‘0’; F <= ‘1’ WHEN (INP = “000”) ELSE ‘1’ WHEN (INP = “010”) ELSE ‘0’; -- always have a default! Selected Signal Assignment Statement with <choice expression > select <target> <= <expressions>when <choices>, <expressions>when <choices>, <expressions>when <choices>, WITH (INP) SELECT F<= ‘1’ WHEN “000”, ‘1’ WHEN “010”, ‘1’ WHEN “101”, ‘0’ WHEN OTHERS; always have an others clause std_logic_vectors can be “–XZLH” The conditional tests can use relational operators = /= < > <= and >= There are other “concurrent statements” – not needed for simple dataflow designs - process, component instantiation, generate, block, assert and concurrent procedures
One way of implementing a multiplexor using a conditional signal assignment A useful technique involves the & operator – known as the concatenation operator it can “join” bits to bits (or vectors to vectors, vectors to bits etc.,) So if you have two signals S0 and S1 of type std_logic you can make a 2 bit std_logic_vector SEL<=S0 & S1 or a 3 bit… SEL <= S0 & S1 & ‘0’;
As you will often be manipulating STD_LOGIC bits and STD_LOGIC_VECTORS (for buses or “bundles” of wires) you need to know how to get at parts of a bus/bundle and the use of ‘1’ and “11” constants and the concatenation operator &. You will use the a lot…
A decoder – generating different outputs depending on the input code
The conditional signal assignment is like an if statement The selected signal assignment is like the switch/case statements in C BUT they are concurrent; we use different verbs to distinguish them. WHEN is used in conditional signal assignment statements and in the body of selected signal assignments It is also used in the body of the sequential VHDL CASE statement WITH is used in selected signal assignments Sequential VHDL statements are not executed concurrently – they use the keywords if then…elsif…else… end if case…is…when…end case . Only allowed within Processes
Process statements; -- the entire process is one concurrent statement. 4 or 5 parts – Label, (optional but desirable! – do it!) Sensitivity list of signals that trigger the process execution, Declaration area and a Begin-end part with sequential statements (and signal assignments) Note if you had two or more processes, each process would execute simultaneously.
Actually, although we haven’t emphasised it, what happens is that any time A or B changes then F is evaluated and changed Any time A or B changes then the Process is run – (A,B) is called the sensitivity list. Note there are several variations, there are “wait” and “wait until” keywords, best to just use sensitivity lists as shown . Don’t give the synthesiser a hard time!
Keep your process statements as simple as possible, do not just lump all your code into one process. It is often sensible to have a number of processes, each of which does one thing. Implementing a system by partitioning it into a number of smaller systems. This is just good practice. At the beginning, think of a top level block diagram (schematic) containing a number of black boxes. Later on, possibly convert the top to VHDL -- NB OLD A1!!!!
Sequential Statements: Signal Assignment Statement <target> <= <expressions>; This is the sequential form of A signal assignment Updated at the end of the process. If you use any signals during a process it is their OLD values you get. Also if a signal is actually an OUT port in the entity you can only put it on the righthand side of a signal assignment (if of mode OUT) Keep an internal signal (or variable) to remember its value and use it on the lefthand of assignments if you need to. IF Statement Put the condition test inside round brackets, optional but recommended Case statement The whenothersclause is recommended- don’t forget that STD_LOGIC can have other values than ‘0’ or ‘1’. Also the poor old synthesiser may create a storage device if you imply it should do nothing for an input pattern – you imply “keep” the old value.
Example of another CASE statement Best to avoid use of “don’t care” terms as different synthesisers do different things
For and while loops You need not declare the loop variable. You cannot assign values to the loop variable The loop variable will only increrment or decrement (with the downto option) y 1 There is also a NEXT and EXIT keyword to continue or break out of a loop Held at www.eej.ulst.ac.uk
VHDL Operators Invalid on bundles of bits, ok on integers The list above is in vertical order of precedence there is no precedence horizontally. In any case you should use ( ) parenthesis brackets to make your meaning clear. Early VHDL had a slightly smaller subset of the above. Arithmetic shifts preserve the sign (MSB) bit.
Using VHDL for sequential circuits Note most libraries have a rising_edge function, a lot of texts use the event attribute of a signal instead. There a number of attributes, accessed by following the signal by the ‘ and the name of the attribute, -- else do nothing to Q A process is executed whenever an item on the sensitivity list changes – so the model above is a purely synchronous device, only active clock transitions cause a change of state. Note the implied memory. An if statement which does not cover all eventualities. C.f page 78-79
D-types with sync and async set and clear Note falling_edge function
T-types with asynchronous set We had to use an intermediate signal since Q is of mode OUT and cannot be used on the righthand side of an expression. This is the approved way to do this Read pages 83 of the text
Finite State Machines (FSMs) in VHDL FSMs can implement any sequential system described by a state diagram, there are several ways of doing this in VHDL (of course) and these are sometimes called the one process, two process of three process methods. We use the two process one here as it I the most common. Read your synthesis tool manual to see what is recommended for your particular CAD tool Usually more than 2 states! But the example shows there is one synchronous input called TOG_EN. We usually don’t count RESET or CLK as inputs. FSM State machines typically use clocked D-types As the output is only a function of the present state this is a Moore type machine. Mealy machines have outputs that depend on present state and present inputs
Example two process VHDL FSM We use a user defined type called state_type The system will allocate a suitable state assignment. Forcing a state assignment is not easy And depends on your cad tool. Read P94-5 carefully, A implied latch is formed by PS – we don’t specify its value under all conditions. We pre-assign Z1 to avoid creating a latch for it.
VHDL FSM – forcing state assignment(p104) Check your CAD tool to ensure your synthesiser will work efficiently with these attributes, the manual may suggest an alternative. • Important points; (page 106 – Section 7.3) • Modelling FSMs in VHDL is straightforward – generating the state diagram is the creative part# • Due to the versatility of VHDL there are many ways of producing FSMs, the text gives the most common and straightforward style • Actual encoding of the state variables is bet left to the synthesis tool
Structural VHDL; components, portmaps and packages To use components we must have entities and archtectures for the “parts” we wish to use. In general these will already exist, possibly in “packages” If this code is not in the main file it can be precompiled into the work library To use components; 1-name the module you plan to describe, (its entity), 2- describe what it will do – (its architecture), 3-let the main program(model) know that the module exists and can be used (component declaration) and 4- use the module by instantiating it into your main code and “wire it up” using portmap statements.
Declaring components – same text as entity Held at www.eej.ulst.ac.uk
Somebody somewhere has to know where the components live – their architectures and entities… As in the last slide you need to bring in the details of the components – include the entity and architecture here or precompile. Or access a package. The FPGA vendor provides packages that you can use. E.g see Altera Quartus VHDL help file. With implied mapping the order of the nets really matters – it must match the entity/component declaration Held at www.eej.ulst.ac.uk
Using generics in VHDL Rather than design a single process or component for each situation, there is an advantage in writing a general purpose part. Perhaps a counter where you can have any width of count. Then you specify a parameter when you instantiate the component. It is even worth using this in any VHDL as it makes design reuse easier. Make your programs general purpose to avoid re-inventing the wheel! The generic keyword belongs in the entity alongside the port list. We pass in any constant which we can use in the architecture or entity It can be used to specify a time delay, then every time we instantiate a component we can specify what delay to use – from knowledge of the target FPGA or perhaps from a routing calculation. (long tracks or fanout cause slower operation) CAD tools use this for post layout simulation… Held at www.eej.ulst.ac.uk
Using generics in VHDL We use this model in the next slide as a component Check out your FPGA tool vendor, Altera supply many parameter driven parts – it saves them work as they have written one module that can be used in a wide variety of applications. It would be painlful to supply components for every possible bus width! Held at www.eej.ulst.ac.uk
n gen_parity_check So for each instantiation of gen_parity_check give both the port map and the generic map for that particular instance of that part (component) Held at www.eej.ulst.ac.uk
Other bits of VHDL We shall ignore the FILE data object and not do much with functions and procedures We shall ignore several other VHDL keywords – block, configuration, package declarations and bodies, subprograms. We shall only use STD_LOGIC and STD_LOGIC_VECTOR and the signed and unsigned types in the IEEE.numeric_stdlibrary. Avoid ieee.std_logic_arith , std_logic_signed and std_logic_unsigned libraries, whilst these do overload arithmetic to allow e.g adding STD_LOGIC_VECTORS they are non standard (written by a vendor) Also minimise use of; Integers are useful in larger models, they can be defined over a range of values up to 32 bits. Held at www.eej.ulst.ac.uk
Other bits of VHDL signed and unsigned are defined in the library ieee.numeric_std The libraries ieee.numeric_signed and ieee.numeric_unsigned offer arithmetic and type conversion functions. You must declare a width for signed and unsigned – e.g port( x : in signed(7 downto 0); Held at www.eej.ulst.ac.uk
Note the conversion functions unsigned(x) , std_logic_vector(x) see p22 for more Held at www.eej.ulst.ac.uk
The beginning… In some ways the text is unusual, not for what it explains, which it does very well, but for what it leaves out. Most other texts try to be complete, the ebook “Free Range VHDL” gives you the minimum to be able to useful work. Like most languages you will never stop learning once you start using VHDL in earnest. The best “next book” is Mark Zwolinski“Digital System Design with VHDL” £30 2nd hand! Earlier works by Peter Ashendun are worth reading, “The students guide to VHDL” is only £20 and Peter has several reference documents available free – the VHDL cookbook for example. There are minor syntactical differences between VHDL-87 and VHDL-93. Use code taken from the web carefully! I created these slides from the eBook to allow me to talk through the text. You really do need to read the book, do the exercises or take on a VHDL project. See the MIPs processor on my website if you want to play… Held at www.eej.ulst.ac.uk