You are on page 1of 194

TABLE OF CONTENTS

TOPICS INCLUDED Acknowledgement Introduction What is VHDL? History Capabilities Modeling features of the language Basic Terminology Entity Declarations Architecture Body Configuration Declaration Package Declaration Package Body Model Analysis Simulation Basic Language Elements Identifiers

Data Objects Data Types Operators Theory related to VHDL Processes Conditional Statements Loops Structure Design Components Functions Procedures Different Styles of Modeling Structural Style of Modeling Dataflow Style of Modeling Behavioral Style if modeling Mixed Style of Modeling Programs demonstrating usage of VHDL Electronic Voting Machine

Introduction alarm system Program Simulation Waveform Description Conclusion References

INTRODUCTION

What is VHDL?
VHDL is an acronym for VHSIC Hardware Description

Language (VHSIC is an acronym for very high speed integrated circuits). It is a hardware description language that can be used to model a digital system at many levels of abstraction, ranging from algorithmic level to gate level. The complexity of the digital system being modeled could vary from that of a simple gate to a complete a digital electronic system, or anything in between. The digital system can also be described hierarchically. Timing can also be explicitly modeled in the same description. The VHDL Language can be regarded as the amalgamation of the following languages: . Sequential language + . Concurrent language + . Net-list language + . Timing specification + . Waveform generation language => VHDL

Therefore the language has constructs that enable to express the concurrent or sequential behavior of a digital system with or without timing. It also allows modeling the system as an

interconnection of components. Test waveforms can also be generated using the same constructs. The language not only defines the syntax but also defines very clear simulation semantics for each language constructs. It is a strongly typed language and is often verbose to write. Because VHDL provides an extensive range of modeling capabilities, it is often quite difficult to understand. Fortunately it is possible to quickly assimilate a core subset of the language that is both easy and simple to understand without learning the more complex features. The complete language, however, has sufficient power to capture the descriptions of the most complex chips to a complete electronic system.

HISTORY
The requirements for the language were first generated in 1981 under the VHSIC program. In this program, a number of U.S. companies were involved in the designing VHSIC chips for the Department of Defense (DoD). At that time, most of the companies were using different hardware description languages to describe and develop their integrated circuits. As a result, different vendors could not effectively exchange designs with one another. Also, different vendors provided DoD with descriptions of their chips in different hardware description languages. Reprocurement and reuse was also a big issue. Thus, a need for a standardized hardware description language for the design, documentation and verification of digital systems was generated. A team of three companies, IBM, Texas Instruments and Intermetrics, were first awarded the contract by the DoD to

develop a version of the language in 1983. Version 7.2 of VHDL was developed and released to the public in 1985. There was strong industry participation throughout the VHDL language development process, especially from the companies that were developing the VHSIC chips. After the release of the version 7.2, there was an increasing need to make the language an industrywide standard. Consequently, the language was transferred to the IEEE for standardization in 1986. After a substantial enhancement to the language, made by a team of industry, university, and DoD representatives, the language was standardized by the IEEE in December 1987; this version of the language is known as the IEEE std 1076-1987. The official language description appears in the IEEE Standard VHDL Language Reference Manual, available from IEEE. The language has also been recognized as an American National Standards Institute (ANSI) standard. According to IEEE rules, an IEEE standard has to be revaluated every five years so that it may remain a standard. Consequently, the language was upgraded with new features, the syntax of many constructs was made more uniform, and many ambiguities present in the 1987 version of the language were resolved. This new version of the language is known as IEEE Std 1076-1993. Since 1987, there has also been a great need for a standard package to aid in model interoperability. This was because different computer-aided engineering vendors supported different packages on their systems, causing a major interoperability problem. Some of the logic values used were 46-value logic, 7value logic, 4-value logic and so on. A committee was set up to standardize such a package. The outcome of this committee was 9value logic package. This package, called STD_LOGIC_1164, was then balloted and approved to become an IEEE standard, labeled

IEEE Std 1164_1993.

CAPABILITEIS OF THE LANGUAGE


The following are the major capabilities that the language provides along with the features that differentiate it from other hardware description languages. 1. The language can be used as an exchange medium between chip vendors and CAD tool users. Different chip vendors can provide VHDL descriptions of their components to the system designers. CAD tool users can use it to capture the behavior of the design at the level of abstraction for functional simulation. 2. The language can also be used as a communication medium between CAD and CAE tools. For example, a schematic capture program may be used to generate a VHDL description for the design, which may be used as an input to the simulation program. 3. The language supports hierarchy; that is, a digital system can be modeled as a set of interconnected components; each component, in turn, can be modeled as set of interconnected set of subcomponents. 4. The language supports flexible design methodologies: topdown, bottom-up, or mixed. 5. The language is not technology-specific, but is capable of supporting technology-specific features. It can also support various hardware technologies. 6. It supports both synchronous and asynchronous timing models. 7. Various digital modeling techniques, such as finite-state

machine descriptions, and Boolean equations, can be modeled using the language. 8. The language is publicly available, human readable, machinereadable, and, above all, it is not proprietary. 9. It is an IEEE and ANSI standard; therefore, models described using this language are portable. The government also has a strong interest in maintaining this as a standard so that Reprocurement and second sourcing may become easier. 10. The language supports three basic different description styles: structural, dataflow, and behavioral. A design may also be expressed in any combination of these three descriptive styles. 11. It supports a wide range of abstraction levels ranging from abstract behavioral descriptions to very precise gate-level descriptions. It does not, however, support modeling at or below the transistor level. It allows a design to be captured at a mixed level using a single coherent language. 12. Arbitrarily large designs can be modeled using the language, and there are no limitations imposed by the language on the size of the design. 13. The language has elements that make large-scale design easier; for example, components, functions, modeling 14. 15.

procedures, and packages. Test benches can be written using the same language to Nominal propagation delays, min-max delays, setup and test other VHDL models. hold timing constraints, and spike detection can all be described very naturally in this language. 16. The use of generics and attributes in the models facilitate of static information such as timing or back-annotation

placement information. 17. 18. Generics and attributes are also useful in describing A model can not only describe the functionality of a parameterized designs. design, but can also contain information about the design itself in terms of user defined attributes, such as total area and speed. 19. A common language can be used to describe library components from different vendors since the language is a standard. 20. Models written in this language can be verified by simulation since precise simulation semantics are defined for each language constructs. 21. Behavioral models that confirm to a certain synthesis description style are capable of being synthesized to gate-level descriptions. 22. The capability of defining new data types provides the power to describe and simulate a new design technique at a very high level of abstraction without any concern about the implementation details.

MODELING FEATURES OF THE LANGUAGE


BASIC TERMINOLOGY
VHDL is a hard ware description language that can be used to model a digital system. The digital system can be as simple as a logic gate or as complex as a complete electronic system. A hardware abstraction of this digital system is called an entity in this text. An entity X, when used in another entity Y, becomes a component for the entity Y. therefore, a component is also an entity, depending on the level at which we are tying to model. To describe an entity, VHDL provides five different types of primary constructs, called design units. They are: 1. Entity Declaration 2. Architecture Body 3. Configuration Declaration 4. Package Declaration 5. Package Body A note on the language syntax:

The language is case-insensitive ; that is, lower-

case and uppercase characters are treated alike (except in extended identifiers, string literals and character literals), for example CARRY, CaRRy, carry all refer to the same name. The language is also free format, very much like ADA and PASCAL. Comments are specified in the language by preceding the text with two constructive dashes (--). All text between the two dashes and the end of that line is treated as a comment.

ENTITY DECLARATION
The entity declaration specifies the name of the entity being modeled and lists the set of interface ports. Ports are signals through which the entity communicates with the other models in its external environments. Here is an example of an entity declaration for the half-adder: entity half_adder is ports (a, b: in bit; sum, carry: out bit ); end half_adder; The entity half_adder has two input ports, a and b (the mode in specifies input port), and two output ports, SUM and Carry (the mode out specifies the output port). BIT is a predefined type of the language; it is an enumeration type containing the character literals 0 and 1.

ARCHITECTURE BODY
The internal details of the entity are specified by an architecture body using the following modeling styles:

11 11

As a set of interconnected components (to represent As a set of concurrent assignment statements (to As a set of sequential assignment statements (to

represent data-flow). 11 represent behavior). 11 As a combination of the above three.

SYNTAX of the architecture body: architecture arch_name of entity_name is begin ______________________ concurrent statements end arch_name;

CONFIGURATION DECLARATION
The configuration declaration is used to select one of the possibly many architecture bodies that an entity may have, and to bind components, used to represent structure in that architecture body, to entities represented by an entity-architecture pair or by a configuration, which reside in a design library. Consider the following configuration declaration for the HALF_ADDER entity, library CMOS_LIB, MY_LIB; configuration ha_binding of HALF_ADDER is for ha_structure for x1: xor2 use entity CMOS_LIB.xor_gate (dataflow); end for; for a1: and2 use configuration MY_LIB. And_config; end for;

end for; end ha_binding; The first statement is a library clause that makes the library names CMOS_LIB and MY_LIB visible within the configuration declaration. The name of the configuration is ha_binding, and it specifies a configuration for the half_adder entity. The next statement specifies that the architecture body ha_structure is selected for this configuration. Since this architecture body contains two component instantiations, two component bindings are required. The first statement ( for x1end for) binds the component instantiation with label x1 to an entity represented by the entity-architecture pair, the xor_gate entity declaration, and the dataflow architecture body, which resides in the CMOS_LIB design library. Similarly, component instantiation a1 is bound to a configuration of an entity defined by the configuration declaration, with name and_config, residing in the MY_LIB design library. There are no behavioral or simulation semantics associated with a configuration declaration. It merely specifies a binding that is used to build a configuration for an entity. These bindings are performed during the elaboration phase of simulation when the entire design to be simulated is being assembled. Having defined a configuration for an entity, the configuration simulated. can then be

PACKAGE DECLARATION
A package declaration is used to store a set of common declarations, such as components, types, procedures and functions. These declarations can then be imported into other

design units using a use clause. Here is an example of a package declaration. package example_pack is type summer is (may, jun, jul, aug, sep); component d_flip_flop port (d, clk : in bit; q, qbar : out bit ); end component; constant pin2pin_delay: time:= 125 ns; function int2bit_vec (int_value: integer) return bit_vector; end example_pack; The name of the package declared is example_pack. It contains type, component, constant and function declarations. Notice that the behavior of the function int2bit_vec does not appear in the package declaration; only the function interface appears. The definition, or body, of the function appears in a package body. Assume that this package has been compiled into a design library called DESIGN_LIB. Consider the -following this is a clauses library associated with an entity declaration. library DESIGN_LIB; clause. use DESIGN_LIB.EXAMLE_PACK. all; clause. entity rx is... The library clause makes the name of the design library DESIGN_LIB visible within this description; that is, the name DESIGN_LIB can be used within the description. This is followed by -- this is a use

the use clause that imports all declarations in the package EXAMPLE_PACK into the entity declaration of rx. It is also possible to selectively import declarations from a package declaration into other design units. For example, library DESIGN_LIB; use DESIGN_LIB.EXAMPLE_PACK.D_FLIP_FLOP; use DESIGN_LIB.EXAMPLE_PACK.PIN2PIN_DELAY; architecture RX_STRUCTURE of rx is ... the two clauses make the component declaration for D_FLIP_FLOP and the constant declaration for PIN2PIN_DELAY visible within the architecture body.

PACKAGE BODY
A package body is used to store the definitions of functions and procedures that were declared in the corresponding package declaration, and also the complete constant declarations for any deferred constants that appear in the package declaration. Therefore, a package body is always associated with a package declaration. Furthermore, a package declaration can have at the most one package body associated with it. Contrast this with an architecture body and an entity declaration, where multiple architecture bodies may be associated with a single entity declaration. A package body may contain other declarations as well. Here is the package body for the package EXAMPLE_PACK, declared in the previous section. package body EXAMPLE_PACK is function INT2BIT_VEC(INT_VALUE:INTEGER) return BIT_VECTOR is

begin --Behavior of function described here. end INT2BIT_VEC; end EXAMPLE_PACK; The name of the package body must be same as that of the package declaration with which it is associated. It is important to note that a package body is not necessary if the corresponding package declaration has no function or procedure declarations and no deferred constant declarations.

MODEL ANALYSIS
Once an entity is described in VHDL, it can be validated using an analyzer and a simulator that are a part of VHDL system. The first step in validation process is analysis. The analyzer takes a file that contains one or more design units and compiles them into an intermediate form. The format of this compiled intermediate representation is not defined by the language. During compilation the analyzer validates the syntax and performs the static semantic checks. The generated intermediate form is stored in specific design library that has been designated as the working library. The design library is a location in the host environment (the computer that supports the VHDL system) where compiled descriptions are stored. Each design library has a logical name that is used when referring to a library in a VHDL description. The mapping of the logical library name to a physical storage location is provided externally by the host environment and is not defined by the language. As an example, a design library can be implemented as a directory in the host environment with the compiled design units being stored as files within this directory.

One possible way of providing the mapping of physical names to logical names is by specifying the mappings in a special file that the VHDL system can interpret. An arbitrary number of design libraries may exist simultaneously of all the design libraries that may coexist. One particular library is designated as the working library with the logical name WORK. The language analyzer always compiles descriptions into the library; therefore, at given time, only one library is updated. If compiled descriptions need to be stored in a different design library, the reference to WORK is changed to point to this design library prior to analysis. The mapping of WORK to a design library is again provided to the host environment. Items compiled on one design library can be imported into design units compiled in a different design library by using library and use clauses or by accessing them with a selected name. There is a design library with the logical name STD predefined by the VHDL language environment. This library contains two packages STANDARD and TEXTIO. The STANDRD package contains declarations for all the predefined types of the language (BIT, TIME, INTEGER etc). The TEXTIO package contains procedures and functions that are necessary for supporting formatted text read and write operations. There called also exists an and IEEE contains standard its package called STD_LOGIC_1164. this package defines a 9-value logic type, STD_ULOGIC, associated subtypes, overloaded operator functions and other useful facilities the standard is called the IEEE std1164-1993. if available, a host environment provide this package in a design library called IEEE.

SIMULATION
Once the modeled descriptions are successfully compiled into one or more design libraries, the next step in the validation process is simulation. For a hierarchical entity to be simulated, all of its lowest level components must be described at the behavioral level. A simulation can be performed on either one of the following: 1 1 An entity declaration and an architecture pair A configuration

Preceding the actual simulation are two major steps: 11 Elaboration phase: In this phase, hierarchy of the entity is expanded and linked, components are bound two entities in the library, and the top level entity is built as a network of behavioral models that is ready to be simulated. Also storage is allocated for signals, variables, and contents declared in the design units. Initial values are also assigned to variables and constants. Files are opened if so indicated in their declarations. 11 Initializing Phase: Driving and effective values for all explicitly declared signals are computed, implicit signals are assigned values, processes are executed once until they suspend and simulation time is set to 0 ns. Simulation commences by advancing time to that of the next event. Values that are scheduled to be assigned to signals are assigned at this time. If the value of a signal changes, and if that

signal is present in the sensitivity list of a process, the process is executed until it suspends. Simulation stops when an assertion violation occurs, depending on the implementation of the VHDL system or when the maximum time as defined by the language is reached.

BASIC LANGUAGE ELEMENTS


IDENTIFIERS
There are two kinds of identifiers in VHDL, basic identifiers and extended identifiers. A basic identifier in VHDL is composed of a sequence of one or more characters. A legal character is an upper case letter (AZ), a lower case letter (az), a digit (09), or the underscore (_) character. The first character in a basic identifier must be a letter, and the last character may not be an underscore. Lower-case and upper-case letters are considered to b identical when used in a basic identifier; as an example, count, Count, COUNT, CouNt all refer to the same basic identifier. Also, two underscore characters cannot appear consecutively. Some more basic examples of basic identifiers are: DRIVE_BUS SET_CK_HIGH SelectSignal const32_59 r2d2 RAM_Address An extended identifier is a sequence of characters written between two backslashes. any of the allowable characters can be used, including characters like ., !, @, ', and $. within an extended

identifier, lower-case and upper-case letters are considered to be distinct.

DATA OBJECTS
A data object holds a value of a specified type. it is created by means of an object declaration. an example is: variable COUNT :INTEGER; this results in the creation of a data object called COUNT, which can hold integer values. the object COUNT is also declared to be of variable class. every data object belongs to one of the following four classes: 1. Constant : An object of constant class can hold a single value of a given type. This value is assigned to the constant before simulation starts, and the value cannot be changed during the course of simulation. examples of constant declarations are: constant RISE_TIME : TIME := 10 ns; constant BUS_WIDTH :INTEGER := 8; constant NO_OF_INPUTS : INTEGER; 2. Variable : An object of variable class can also hold a single value of a given type. however, in this case, different values can be assigned to a variable at a different times using a variable assignment statement. examples of variable assignment statement are: variable CTRL_STATUS : BIT_VECTOR ( 10 downto 0); variable SUM:INTEGER range 0 to 10 := 100; variable FOUND,DONE: BOOLEAN; 3. Signal : an object belonging to the signal class holds a list of values, which include the current value of the signal, and a set of possible future values that are to appear on the signal. future

values can be assigned to a signal using signal assignment statement. examples of signal assignment are: signal CLOCK:BIT; signal DATA_BUS:BIT_VECTOR(0 to 7); signal GATE_DELAY:TIME:10 ns; signal INT_P:STD_LOGIC_VECTOR( 7 downto 0):=(0 =>'1',others=>'u'); 4. File : An object belonging to the file class contains a sequence of values. Values can be read or written to the file using read procedures and write procedures, respectively. The syntax of file declaration is : file file_names:file_type_name [[open mode] is string_expression];

DATA TYPES
Every data objects in VHDL can hold a value that belongs to a set of values. This set of values is specified using a type declaration. A type is a name that has associated with it a set of values and a set of operations. Certain types and operations that can be performed on objects of these types, are predefined in the language. For example, INTEGER is a predefined type, with a set of values being integers in a specific range provided by the VHDL system. The minimum range that must be provided is -(231 - 1) through +(231 - 1). Some of the allowable and frequently used predefined operators are + for addition, - for subtraction, / for division and * for multiplication. BOOLEAN is another predefined type that has the values FALSE and TRUE, and some of its predefined operators are and, or, nor, nand, xor, xnor, and

not. The language also provides the facility to define new types by using type declarations and also to define a set of operations on these types by writing functions that return values of this new type. All the possible types that can exist in the language can be categorized into following four major categories: 1. Scalar Types : Values belonging to these types appear in the sequential order. 2. Composite Types : These are composed of the elements of a single type or elements of different types. 3. Access Types : These provide access to objects of a given type ( via pointers). 4. File Types : These provide access to objects that contain a sequence of values of a given type. It is possible to derive subtypes from predefined or user-defined types.

OPERATORS
The predefined operators in the language are classified into the following six categories: 11 and not The operators nand and nor are not associative; therefore, the syntax of an expression with a sequence of nand or nor operations is illegal. For example, the following expression is illegal. A nand B nand C --is illegal. Parenthesis can be used to avoid this problem. LOGICAL OPERATORS or nand nor xor xnor The seven logical operators are

2. RELATIONAL OPERATORS These are = /= < <= > >= The type for all relational operators is always the predefined type BOOLEAN. The (=) equality and the /= (inequality) operators are predefined on any type except file types. The remaining four relational operators are predefined on any scalar type or discrete array type. When the operands are discrete array types, comparison is performed one element at a time from left to right. For example, BIT_VECTOR(0,1,1)<BIT_VECTOR(0,0,1 ) is true, since the first element in the first array aggregate is less than the first element in the second array aggregate. 3. SHIFT OPERATORS sll srl sla sra rol ror Each of the operators takes an array of BIT or BOOLEAN as the left operand and an integer value as the right operand and performs the specified operation. If the integer value is a negative number, the opposite action is performed, that is, left shift or rotate becomes a right shift or rotate , respectively, and viceversa. Here are some examples: 1001010 sll 2 is 0101000 1001010 srl 3 is 0001001 4. ADDITION OPERATORS These are + &

The operands for the + (addition) and (subtraction) operators must be of the same numeric type, with the result being of the same numeric type. The addition and subtraction operators may also be used as unary operators, in which case the operands and the result type are the same. The operands for the & (concatenation) operator can be either a one-dimensional array type or an element type. The result is always an array type. For example, 0 &1 results in an array of characters 01. C&A&T results in the value CAT. 5. MULTIPLYING OPERATORS These are: * The / mod (*) rem and division(/) operators are multiplication

predefined for both operands being of the same integer or the floating point type. The result is also of the same type. The multiplication operator is also defined for the case when one of the operands is of the physical type and the second operand is of the integer or the real type. Here are some examples using mod and rem operators: 7 mod 4 (-7) mod 4 7 mod (-4) (-7) mod(-4) --has value 3 --has value -3 --has value -1 --has value -3

6. MISCELLANEOUS OPERATORS The miscellaneous operators are abs **

The abs(absolute) operator is defined for any numeric type. The ** (exponential) operator is defined for the left operand to be of the integer or floating point type, and for the right operand (i.e. the exponent) to be of the integer type only. The not logical operator has the same precedence as the above two operators.

THEORY RELATED TO VHDL


PROCESS
Statements within architecture block, to this point, are executed concurrently- that is at the same time. also, there is no way to synchronize their execution with clocking or any other kind of signals. To incorporate sequential statement execution and some manner of synchronization, we need to use a process block whose general syntax form is: process_name : process(sensitivity list) variable variable_names:variable_type; begin statements; end process; Process statements are placed in the architecture block of your design. The process name and the variable declarations are optional. Process names are handy if your design contains more than one process. Variable declarations are used to define a variable local to and used by the process. Variable declarations are

added in the declaration area preceding the body of the process block. The variable assignment operator is: = which is same one used for assigning initial literal values. The syntax for the variable assignment is ; variable_identifier := expression; To evaluate expressions used in a variable declaration or process block, you must be familiar with the operators used by VHDL. Most of them have already explained earlier but in their order of precedence, they are : Highest o ( ) parenthesis o ** exponential o abs-absolute unsigned magnitude numbers o not- inversion Next o * multiplication o / division o mod-modulo or quotient from division o rem-remainder from division Next o +- identity o - - negation Next o + addition o - subtraction o & concatenation Next o sll shift left logical

o srl shift right logical o sla shift left arithmetic o sra shift right arithmetic o rol rotate left o ror rotate right next o = equality o /= not equal to o < less than o > greater than o <= less than or equal to o >= greater than or equal Lowest o and-logic and o or logic or o nand- logic nand o nor-logic nor o xor-logic exclusive or o xnor-logic exclusive nor

CONDITIONAL STATEMENTS
a) IF THEN ELSE STATEMENT The primary conditional test function is the if..then..else construct that works the same as it works in any other programming language. The syntax for this function is: if conditional_test then statements; else

statements; end if; The statements following then are executed if the condition is true. The else block is optional and used only if there is an alternate process required to be done if the conditional result is false. If statements can be nested using an elsif block. In that case, the syntax is: if conditional test then statements; elsif conditional test then statements; else statements; end if; b) WHEN STATEMENT Syntax of when statement: identifier <= expression1 WHEN condition 1 ELSE expression2 WHEN condition2 ELSE expression3 WHEN condition3 ELSE expression WHEN OTHERS; Identifier is assigned the expression for the WHEN condition that is true.

c) CASE STATEMENT Syntax of the case statement is:

FONT color = #0000FF>CASE test_var IS WHEN test_val1 => identifier <=expression1; WHEN test_val2 => identifier <=expression2; WHEN test_val3 => identifier <=expression3; WHEN test_val4 => identifier <=expression4; WHEN test_val5 => identifier <=expression5; WHEN OTHERS => identifier <=expression6; Note: = may be used instead of <= Conditional test is done on all values concurrently. Assignment is made for true WHEN condition.

LOOPS
The FOR Loop: The FOR loop is used to repeat the execution of a section of code for a given number of times. The general syntax for a FOR loop is: for variable in range loop statements; end loop;

STRUCTURE DESIGN
The architecture block defines how the entity operates and can be described in many ways, two of which are the most prevalent: structural and behavioral (data flow). This section explores the structural approach which defines how the entity is constructedwhat logic devices make up the design. The general format for structural

architecture is: architecture architecture_name of entity_name is internal interconnecting signal declarations; component (object)declarations; begin iterations (copies) of components; end architecture_name;

COMPONENTS
A component is created from any previously designed entity it can be declared on the same page as the current design or imported from the library. A component defines a design (object) which can be instantiated or copied. As such, there are some definite procedures to follow when using components. The general syntax for a component declaration is: component entity_name port (names: mode type); end component; Components are related to the entity through the use of same name and port list. Port signal declarations must be in the same order as the entity port declarations and must have the same name, mode and type- after all, a component is going to be nothing more than a reference for a copy of an entity design. The content of a component block must match the content of the source entity block exactly. Once the component is declared, it may be instantiated (copied) and reused any number of times within the design by the use of this code: port_name: component_name port map (signals in exact order);

FUNCTIONS
A function in VHDL is similar to functions in the most upper level languages. It is a subprogram that accepts input parameters and returns a single result. The syntax for a function declaration is: function function_name (formal parameters) return return_type is variable declarations; begin statements; return return_variable_name; end function_name; Functions are called using a signal assignment statement that has the general form of: variable <= function_name (actual parameters); The actual parameter(s) passed to the function must be of the same type and length ( if a specified array size was made) as the formal parameter(s) in the function declaration. The returned value of the function is stored into the variable on the left side of the expression.

PROCEDURES
A procedure, like a function, is a subprogram that must first be declared and then called. Unlike the function, procedures can pass

out numerous results through its parameters list. Because of this, parameters declarations must include an in or out mode declaration as well as a data type indication. The SYNTAX for declaring a procedures is procedure procedure_name ( formal parameters: mode type, formal parameter : mode type) is variable declaration; begin statements; end procedure_name; Since there are possible multiple results, procedures are not called using an assignment statement like a function. Instead they are called using format: procedure_name(actual parameter list); The parameter list contains the names of the actual parameters to be passed in and out of the procedure and while they do not have to have the same identifier names as those in the declaration, they must follow the exact order as well as having the same mode and type as the formal parameters in the procedure declaration.

DIFFERENT STYLES OF MODELING

1) STRUCTURAL STYLE OF MODELING In the structural style of modeling, an entity is described as a set of interconnected components. The architecture body is composed of two parts: 1. The declarative part (before the keyword begin) 2. The statement part (after the keyword begin). The two components declarations are present in the declarative part of the architecture body. These declarations specify the interface of components that are used in the architecture body. The declared components are instantiated in the statement part of the architecture body using component instantiation statement. SYNTAX: architecture arch_name of entity_name is component comp_name is port ( signal_name, signal_name: mode type; Signal_name, signal_name: mode type); end comp_name; begin z1 : comp_name port map (list of signals associated sequentially); end arch_name; 2) DATAFLOW STYLE OF MODELING In this modeling style, the flow of data through the entity is expressed primarily using concurrent signal assignment statements. The structure is not explicitly specified in this modeling style. But it can be implicitly deduced. In a signal assignment statement, the symbol <= implies an assignment of a

value to a signal. The value of the expression on the right hand side of the statement is computed and is assigned to the signal on the left hand side, called the target signal. Delay information is included in a signal assignment statements using after clauses. Concurrent signal assignment statements are concurrent statements, and therefore, the ordering of these statements in the architecture body is not important. SYNTAX architecture arch_name of entity_name is begin concurrently executed statements; end arch_name; BEHAVIORAL STYLE OF MODELING The behavioral style of modeling specifies the behavior of an entity as a set of statements that are executed sequentially in the specified order. This set of sequential statements which are specified inside a process statement, do not explicitly specify the structure of an entity but merely its functionality. A process statement is a concurrent statement that can appear within an architecture body. A process statement also has a declarative part and a statement part. The statements appearing within the statement part are sequential statements and are executed sequentially. The list of signals specified within the parentheses after the keyword process constitutes the sensitivity list, and the process statement is invoked whenever there is any event on any signal on the list. SYNTAX architecture arch_name of entity_name is

11

begin process (sensitivity list) begin sequentially executed statements end process; end arch_name; MIXED STYLE OF MODELING It is possible to mix the three styles of modeling in a single architecture body. That is, within an architecture body, we can use component instantiation statements (that represent structure), concurrent signal assignment statements (that represent dataflow), and process statement (that represent behavior). All these statements are concurrent statements; therefore, their order of appearance within the architecture body is not important. A process statement is a concurrent statement; however, statements within a process statement are always executed sequentially. SYNTAX architecture arch_name of entity_name is component comp_name is port (signal_name, signal_name: mode type; signal_name, signal_name: mode type); end comp_name; begin z1: comp_name port map ( list of signals associated sequentially); process (sensitivity list) begin --sequentially executed statements

11

end process; --concurrently executed statements; end arch_name;

VHDL SOURCE CODE AND SIMULATION

OF BASIC CIRCUITS
Program to calculate remainder of two numbers
(DATAFLOW STYLE OF MODELING)

Library ieee; Use ieee.std_logic_1164.all; entity \rem\ is

--entity begins

port ( a: in INTEGER; b: in INTEGER; c: out INTEGER ); end \rem\ ; ends architecture \rm\ of \rem\ is --architecture begins begin c <= a - (a/b) * b; end \rm\; --architecture ends

--entity

Waveform :

Program to implement shift operators : entity


sm is

port ( a: in BIT_VECTOR (7 downto 0) := "00100110"; b: out BIT_VECTOR (7 downto 0); c: out BIT_VECTOR (7 downto 0); d: out BIT_VECTOR (7 downto 0); e: out BIT_VECTOR (7 downto 0); f: out BIT_VECTOR (7 downto 0); g: out BIT_VECTOR (7 downto 0); h: out BIT_VECTOR (7 downto 0); i: out BIT_VECTOR (7 downto 0); j: out BIT_VECTOR (7 downto 0); k: out BIT_VECTOR (7 downto 0); l: out BIT_VECTOR (7 downto 0); m: out BIT_VECTOR (7 downto 0) ); end sm; architecture sm of sm is begin b <= a sll 3; c <= a srl 2; d <= a sla 4; e <= a sra 2; f <= a ror 2; g <= a rol 3; h <= a sll -3; i <= a srl -2; j <= a sla -4; k <= a sra -2; l <= a ror -2; m <= a rol -3; end sm;

Waveform :

Program to reverse a number


Library ieee; Use ieee.std_logic_1164.all; entity reverse is port ( a: inout INTEGER:=458; y: out INTEGER ); end reverse; architecture rev of reverse is begin process (a) variable b,c,d,e: integer; begin b := a/100; c := a mod 100; d := c/10; e := c mod 10; y <= ((e*100) + (d*10) + b); end process; end rev;

Waveform :

Program to calculate salary of aa employe


Library ieee; Use ieee.std_logic_1164.all; entity salary is port ( bp: inout INTEGER:=5000 ; gi: out INTEGER ); end salary; architecture pay of salary is begin process (bp) variable hra, cca, da: integer; begin hra := (bp*25)/100 ; cca := (bp*5)/100 ; da := (bp*102)/100 ; gi <= bp + hra + cca + da ; end process; end pay;

Waveform :

Program to calculate sum of digits of a number


Library ieee; Use ieee.std_logic_1164.all; entity sum is port ( a: inout INTEGER:=458; y: out INTEGER ); end sum; architecture sum of sum is begin process (a) variable b,c,d,e:integer; begin b := a/100; c := a mod 100; d := c/10; e := c mod 10; y <= b + d +e; end process; end sum;

Waveform :

Program of SR flip flop using case statement

Library ieee; Use ieee.std_logic_1164.all; entity \sr flipflop\ is port ( s: in BIT; r: in BIT; q: out BIT ); end \sr flipflop\; architecture \sr1\ of \sr flipflop\ is begin process (r,s) variable q1: bit := '0' ; variable ctrl: bit_vector (0 to 1); begin ctrl := ( r & s); case ctrl is when "00" when "01" when "10" when "11" end case; end process; end \sr1\; => => => => q <= q1; q <= '0'; q <= '1'; null;

Waveform :

SEQUENTIAL MODELLING Program to calculate factorial of a number


Library ieee; Use ieee.std_logic_1164.all; entity factorial is port ( a: in INTEGER; c: out INTEGER ); end factorial; architecture factorial of factorial is begin process (a) variable factor: integer; begin factor := 1; for num in 1 to a loop factor := factor * num; end loop; c <= factor; end process; end factorial;

Waveform :

Program of 4:1 mux

Library ieee; Use ieee.std_logic_1164.all; entity mux is port ( a: in BIT_VECTOR (0 to 1); b: in BIT_VECTOR (0 to 1); c: in BIT_VECTOR (0 to 1); d: in BIT_VECTOR (0 to 1); ctrl: in BIT_VECTOR (0 to 1); t: out BIT_VECTOR (0 to 1) ); end mux; architecture mux of mux is begin process (ctrl) begin case ctrl is when "00" when "01" when "10" when "11" end case; end process; end mux;

=> => => =>

t t t t

<= <= <= <=

a; b; c; d;

Waveform :

JK flip flop using case statement

Library ieee; Use ieee.std_logic_1164.all; entity jk is port ( j: in BIT; k: in BIT; q: out BIT ); end jk;

architecture jk1 of jk is begin process (j,k) variable q1: bit := '0' ; variable ctrl: bit_vector (0 to 1); begin ctrl := ( j & k); case ctrl is when "00" => q <= q1; when "01" => q <= '0'; when "10" => q <= '1'; when "11" => q <= not q1; end case; end process; end jk1;

Waveforms:-

T flip flop
Library ieee; Use ieee.std_logic_1164.all; entity \t flipflop\ is port ( t: in BIT; q: out BIT ); end \t flipflop\; architecture \t1\ of \t flipflop\ is begin process (t) variable ctrl: bit; variable q1:bit:='0'; begin ctrl := t; case ctrl is when '0' => q <= q1; when '1' => q <= not q1 ; end case; end process; end \t1\;

Waveform :

Program using If statement


Library ieee; Use ieee.std_logic_1164.all; entity \sr flipflop1\ is port ( r: in BIT; s: in BIT; q: out BIT ); end \sr flipflop1\; architecture \sr1\ of \sr flipflop1\ is begin process (r,s) variable q1 : bit :='0'; begin if ( s = '0' and r = '0') then q <= q1; else if ( s= '0' and r = '1') then q <= '0'; else if ( s= '1' and r = '0') then q <= '1'; else if ( s= '1' and r = '1') then null; end if; end if; end if; end if; end process; end \sr1\;

Waveform :

Program of D flip flop


Library ieee; Use ieee.std_logic_1164.all; entity \d 1\ is--entity begins port ( d: in BIT; q: out BIT ); end \d 1\; architecture \d 1\ of \d 1\ is begin process (d) begin if (d = '0') then q <= '0'; else if (d= '1') then q <= '1'; end if; end if; end process; end \d 1\;

Waveform :

Program to implement alu


Library ieee; Use ieee.std_logic_1164.all; entity alu is port ( a: in INTEGER; b: in INTEGER; p: out INTEGER; q: out INTEGER; r: out INTEGER; s: out INTEGER ); end alu; architecture alu of alu is type op is (add, sub, mul, div); signal exp: op; begin process (a,b) begin case exp is when add => p<= a+b; when sub => q <= a - b; when mul => r <= a*b; when div => s <= a/b; end case; end process; end alu;

Waveform :

Program to implement RAM


Library ieee; Use ieee.std_logic_1164.all; entity ram is port ( din: in BIT; chipsel: in BIT; w_r: in BIT; address0: in INTEGER range 8 downto 1; address1: in INTEGER range 8 downto 1; dout: out BIT ); end ram;

architecture ram of ram is type std_array is array ( 1 to 8) of bit_vector(1 to 8); begin process ( chipsel, address0, address1, din, w_r) variable temp: std_array; begin if (chipsel = '1') then if ( w_r ='1') then temp (address0)(address1) :=din; end if; if (w_r='0') then dout <= temp (address0)(address1); end if; end if; if ( chipsel ='0') then null; end if; end process; end ram;

Waveform :

Program to implement 9-bit parity generator


Library ieee; Use ieee.std_logic_1164.all; entity pg is port ( d0: in BIT; d1: in BIT; d2: in BIT; d3: in BIT; d4: in BIT; d5: in BIT; d6: in BIT; d7: in BIT; d8: in BIT; odd: out BIT; even: inout BIT ); end pg; architecture pg of pg is signal e0, e1, e2, e3, f0, f1, h0: bit; component xor1 port (a,b:in bit; c:out bit); end component; component not1 port ( r: in bit; s: out bit); end component; begin

x1: xor1 port map (d0, d1, e0); x2: xor1 port map (d2, d3, e1); x3:xor1 port map (d4, d5, e2); x4 : xor1 port map (d6, d7, e3); x5 : xor1 port map(e0, d1, f0); x6 : xor1 port map (e2, e3,f1); x7 : xor1 port map (f0, f1, h0); x8 : xor1 port map (h0, d8, even); x9 : not1 port map (even, odd); -- <<enter your statements here>> end pg;

Waveform :

Program to implement 7 segment bcd_display


library IEEE; use IEEE.std_logic_1164.all; entity bcd_7seg is port ( b0: in STD_LOGIC; b1: in STD_LOGIC; b2: in STD_LOGIC; b3: in STD_LOGIC; a: out STD_LOGIC; b: out STD_LOGIC; c: out STD_LOGIC; d: out STD_LOGIC; e: out STD_LOGIC; f: out STD_LOGIC; g: out STD_LOGIC ); end bcd_7seg; architecture bcd_7seg of bcd_7seg is begin process (b3,b2,b1,b0) variable b3bar, b2bar,b1bar,b0bar: std_logic; begin b3bar := not b3; b2bar := not b2; b1bar := not b1; b0bar := not b0; a <= (b0bar and b1bar and b2bar and b3bar) or (b0bar and b1bar and b2 and b3bar) or (b0 and b1bar and b2 and b3bar) or (b0bar and b1 and b2 and b3bar);

b <= (b0bar and b1bar and b2bar and b3bar) or (b0bar and b1 and b2bar and b3bar) or (b0 and b1 and b2bar and b3bar) or (b0 and b1bar and b2 and b3bar) or (b0bar and b1 and b2 and b3bar) or (b0 and b1 and b2 and b3bar); c <= (b0bar and b1bar and b2bar and b3bar) or (b0 and b1bar and b2bar and b3bar) or (b0bar and b1 and b2bar and b3bar) or (b0 and b1 and b2bar and b3bar) or (b0bar and b1bar and b2 and b3bar) or (b0 and b1 and b2 and b3bar); d <= (b0bar and b1bar and b2bar and b3bar) or (b0 and b1bar and b2bar and b3bar) or (b0 and b1 and b2bar and b3bar) or (b0bar and b1bar and b2 and b3bar) or (b0 and b1bar and b2 and b3bar) or (b0bar and b1 and b2 and b3bar) or (b0 and b1 and b2 and b3bar); e <= (b0bar and b1bar and b2bar and b3bar) or (b0bar and b1 and b2bar and b3bar) or (b0 and b1 and b2bar and b3bar) or (b0 and b1bar and b2 and b3bar) or (b0bar and b1 and b2 and b3bar); f <= (b0bar and b1bar and b2bar and b3bar) or (b0bar and b1 and b2bar and b3bar) or (b0bar and b1 and b2 and b3bar); g <= (b0bar and b1 and b2bar and b3bar) or (b0 and b1 and b2bar and b3bar) or (b0bar and b1bar and b2 and b3bar) or (b0 and b1bar and b2 and b3bar) or (b0bar and b1 and b2 and b3bar); end process; end bcd_7seg;

Waveform :

Program to implement half adder


Library ieee; Use ieee.std_logic_1164.all; entity ha is port ( a: in BIT; b: in BIT; sum: out BIT; carry: out BIT ); end ha; architecture ha of ha is function ha1 (c,d:bit) return bit is variable e:bit; begin e := c xor d; return e; end ha1; function ha2 (c,d:bit) return bit is variable f:bit; begin f := c and d; return f; end ha2; begin process (a,b) begin

sum <= ha1(a,b); carry <= ha2 (a,b); end process; end ha;

Waveform :

Program to implement binary to grey converter


Library ieee; Use ieee.std_logic_1164.all; entity binary_to_grey is port ( a0: in BIT; a1: in BIT; a2: in bit; b0: out BIT; b1: out BIT; b2 : out bit ); end binary_to_grey;

architecture binary_to_grey of binary_to_grey is begin b2 <= a2; b1 <= a2 xor a1; b0 <= a1 xor a0; end binary_to_grey;

Waveform :

Program to implement demux

Library ieee; Use ieee.std_logic_1164.all; entity demux is port ( s0: in BIT; s1: in BIT; t: in bit; a0: out BIT; a1: out bit; a2: out BIT; a3: out BIT ); end demux; architecture demux of demux is begin process (s0,s1) variable ctrl : bit_vector ( 0 to 1); begin ctrl:=s1&s0; case ctrl is when "00" => a0 <= t; when "01" => a1 <= t; when "10" => a2 <= t;

when "11" => a3 <= t; end case; end process; end demux;

Waveform :

To verify program using test bench

Library ieee; Use ieee.std_logic_1164.all; entity full_adder is port ( a: in BIT; b: in BIT; c: in BIT; sum: out BIT; carry: out BIT ); end full_adder; architecture full_adder of full_adder is begin sum <= a xor (b xor c); carry <= a or b or c; end full_adder; entity full_bench is end entity full_bench;

architecture full_bench of full_bench is signal d,e,f,sum1,carry1 : bit; begin dut : entity work.full_adder port map (d,e,f,sum1,carry1); process begin d <= '0'; wait for 10ns; d <= '0'; wait for 10ns; d <= '0'; wait for 10ns; d <= '0'; wait for 10ns; d <= '1'; wait for 10ns; d <= '1'; wait for 10ns; d <= '1'; wait for 10ns; d <= '1'; wait for 10ns; end process; process begin e <= '0'; wait for 10ns; e <= '0'; wait for 10ns; e <= '1'; wait for 10ns; e <= '1'; wait for 10ns; e <= '0'; wait for 10ns; e <= '0'; wait for 10ns; e <= '1'; wait for 10ns; e <= '1'; wait for 10ns; end process; process begin f <= '0'; wait for 10ns; f <= '1'; wait for 10ns; f <= '0'; wait for 10ns; f <= '1'; wait for 10ns; f <= '0'; wait for 10ns; f <= '1'; wait for 10ns; f <= '0'; wait for 10ns; f <= '1'; wait for 10ns; end process; end full_bench;

Waveform :

Using a MIXED STYLE of MODELING Library ieee; Use ieee.std_logic_1164.all; entity full_adder_mixed is port ( a, b, cin : in bit; sum, cout : out bit); end full_adder_mixed; architecture full_adder_mixed of full_adder_mixed is component xor2 port (p1, p2 : in bit; pz : out bit ); end component; signal s1 : bit; begin x1 : xor2 port map (a, b, s1);

process ( a, b, cin) variable t1, t2, t3 : bit; begin t1 := a and b; t2 := b and cin; t3 := a and cin; cout <= t1 or t2 or t3; end process; sum <= s1 xor cin; end full_adder_mixed; entity xor2 is port (p1, p2 : in bit; pz :out bit); end xor2; architecture xor2 of xor2 is begin pz <= p1 xor p2; end xor2;

Waveform :

50

100

1 50

200

250

300

350

ns

sum carry c b a

Program to implement a HALF SUBTRACTOR


library IEEE; use IEEE.std_logic_1164.all; entity half_sub is port ( a: in bit; b: in bit;

c: out bit; diff: out bit; borr: out bit); end half_sub; architecture hsub1 of half_sub is begin c <= not a; diff <= a xor b; borr <= not a and b; end hsub1;

Waveform :
50 100 150 200 250 300 350 ns

diff c borr b a

Program to implement SWAPPING of two numbers


library ieee; use ieee.std_logic_1164.all; use ieee.std_logic_unsigned.all; entity swap is port ( a: inout integer := 3;

b: inout integer := 7 ); end swap; architecture swap1 of swap is signal clk : bit; begin process (clk) variable v1, v2 : integer; begin v1 := a; v2 := b; a <= v2 after 1 ns; b <= v1 after 1 ns; end process; end swap1;

Waveform :

50

100

150

200

250

300

350

ns

clk b a
7 3 3 7

Program to implement a 2-BIT COMPARATOR


entity \2_bit_comparator\ is port (a: in BIT_VECTOR (0 to 1); b: in BIT_VECTOR (0 to 1); greater: out BIT; lesser: out BIT; equal_to: out BIT);

end \2_bit_comparator\; architecture \2_bit_comparator\ of \2_bit_comparator\ is begin process (a, b) variable a1b , a0b , b1b , b0b :bit; begin a1b := not a(1); a0b := not a(0); b1b := not b(1); b0b := not b(0); greater <= ( a(1) and b1b) or ( a(1) and a(0) and b0b) or ( a(0) and b1b and b0b); lesser <= ( b(1) and a1b) or ( a1b and a0b and b(0)) or (b(1) and b(0) and a0b); equal_to <= (a0b and a1b and b0b and b1b) or ( a1b and a(0) and b1b and b(0)) or ( a(1) and a(0) and b(1) and b(0)) or (a(1)AND a0b and b(1)and b0b); end process; end \2_bit_comparator\;

Waveform :

Example of driver using VHDL


library ieee; use ieee.std_logic_1164.all; entity Driver is port( x: in std_logic; F: out std_logic ); end Driver; architecture Driver1 of Driver is begin process(x) begin -- compare to truth table if (x='1') then F <= '1'; else F <= '0'; end if; end process; end Driver1 ; architecture Driver2 of Driver is begin F <= x; end Driver 2;

Example of or gate
library ieee; use ieee.std_logic_1164.all; entity OR_ent is port( x: in std_logic; y: in std_logic; F: out std_logic); end OR_ent; architecture OR_arch of OR_ent is begin process(x, y) begin -- compare to truth table if ((x='0') and (y='0')) then F <= '0'; else F <= '1'; end if; end process; end OR_arch; architecture OR_beh of OR_ent is begin F <= x or y; end OR_beh;

Example of nor gate


entity NOR_ent is port( x: in std_logic; y: in std_logic; F: out std_logic); end NOR_ent; architecture behv1 of NOR_ent is begin process(x, y) begin -- compare to truth table if (x='0' and y='0') then F <= '1'; else F <= '0'; end if; end process; end behv1; architecture behv2 of NOR_ent is begin F <= x nor y; end behv2;

Example of and gate


entity AND_ent is port( x: in std_logic; y: in std_logic; F: out std_logic ); end AND_ent;

architecture behav1 of AND_ent is begin process(x, y) begin -- compare to truth table if ((x='1') and (y='1')) then F <= '1'; else F <= '0'; end if; end process; end behav1; architecture behav2 of AND_ent is begin F <= x and y; end behav2;

Example of nand gate


entity NAND_ent is port( x: in std_logic; y: in std_logic;

F: out std_logic); end NAND_ent; architecture behv1 of NAND_ent is begin process(x, y) begin -- compare to truth table if (x='1' and y='1') then F <= '0'; else F <= '1'; end if; end process; end behv1; architecture behv2 of NAND_ent is begin F <= x nand y; end behv2;

Example of xor gate


entity XOR_ent is port( x: in std_logic; y: in std_logic; F: out std_logic

); end XOR_ent; architecture behv1 of XOR_ent is begin process(x, y) begin -- compare to truth table if (x/=y) then F <= '1'; else F <= '0'; end if; end process; end behv1; architecture behv2 of XOR_ent is begin F <= x xor y; end behv2;

Example of xnor gate


entity XNOR_ent is port( x: in std_logic;

y: in std_logic; F: out std_logic); end XNOR_ent; architecture behv1 of XNOR_ent is begin process(x, y) begin -- compare to truth table if (x/=y) then F <= '0'; else F <= '1'; end if; end process; end behv1; architecture behv2 of XNOR_ent is begin F <= x xnor y; end behv2;

Example of combinational logic ckt


entity OR_GATE is port( X: in std_logic; Y: in std_logic; F2: out std_logic ); end OR_GATE; architecture behv of OR_GATE is

begin process(X,Y) begin F2 <= X or Y; end process; end behv; library ieee; use ieee.std_logic_1164.all;

-- behavior des.

-- component #2

============entity AND_GATE is port( A: in std_logic; B: in std_logic; F1: out std_logic ); end AND_GATE; architecture behv of AND_GATE is begin process(A,B) begin F1 <= A and B; -- behavior des. end process; end behv;=========== library ieee; use ieee.std_logic_1164.all; use work.all; entity comb_ckt is -- top level circuit

port( input1: in std_logic; input2: in std_logic; input3: in std_logic; output: out std_logic ); end comb_ckt; architecture struct of comb_ckt is component AND_GATE is AND_GATE port( A: in std_logic; B: in std_logic; F1: out std_logic ); end component; component OR_GATE is port( X: in std_logic; Y: in std_logic; F2: out std_logic ); end component; signal wire: std_logic; begin -- use sign "=>" to clarify the pin mapping -- as entity of

-- as entity of OR_GATE

-- signal just like wire

Gate1: AND_GATE port map (A=>input1, B=>input2, F1=>wire); Gate2: OR_GATE port map (X=>wire, Y=>input3, F2=>output); end struct; Example of mux entity Mux is port( I3: in std_logic_vector(2 downto 0); I2: in std_logic_vector(2 downto 0); I1: in std_logic_vector(2 downto 0); I0: in std_logic_vector(2 downto 0); S: in std_logic_vector(1 downto 0); O: out std_logic_vector(2 downto 0) ); end Mux; architecture behv1 of Mux is begin process(I3,I2,I1,I0,S) begin -- use case statement case S is when "00" => when "01" => when "10" => when "11" => when others => end case; end process; end behv1;

O <= I0; O <= I1; O <= I2; O <= I3; O <= "ZZZ";

architecture behv2 of Mux is begin -- use when.. else statement O <= I0 when S="00" else I1 when S="01" else I2 when S="10" else I3 when S="11" else "ZZZ"; end behv2;

Example of decoder
entity DECODER is port( I: in std_logic_vector(1 downto 0); O: out std_logic_vector(3 downto 0) ); end DECODER; architecture behv of DECODER is begin -- process statement process (I) begin -- use case statement case I is when "00" => O <= "0001"; when "01" => O <= "0010"; when "10" => O <= "0100"; when "11" => O <= "1000"; when others => O <= "XXXX"; end case;

end process; end behv; architecture when_else of DECODER is begin -- use when..else statement O <= "0001" when I = "00" else "0010" when I = "01" else "0100" when I = "10" else "1000" when I = "11" else "XXXX"; end when_else;

Example of adder
entity ADDER is generic(n: natural :=2); port( A: in std_logic_vector(n-1 downto 0); B: in std_logic_vector(n-1 downto 0); carry: out std_logic; sum: out std_logic_vector(n-1 downto 0)); end ADDER; architecture behv of ADDER is -- define a temparary signal to store the result signal result: std_logic_vector(n downto 0); begin -- the 3rd bit should be carry result <= ('0' & A)+('0' & B);

sum <= result(n-1 downto 0); carry <= result(n); end behv; Example of alu entity ALU is port( A: in std_logic_vector(1 downto 0); B: in std_logic_vector(1 downto 0); Sel: in std_logic_vector(1 downto 0); Res: out std_logic_vector(1 downto 0) ); end ALU; architecture behv of ALU is begin process(A,B,Sel) begin -- use case statement to achieve -- different operations of ALU case Sel is when "00" => Res <= A + B; when "01" => Res <= A + (not B) +1; when "10" => Res <= A and B; when "11" => Res <= A or B; when others => Res <= "XX"; end case;

end process; end behv;

Example of multiplier
-- two 4-bit inputs and one 8-bit outputs entity multiplier is port( num1, num2: in std_logic_vector(1 downto 0); product: out std_logic_vector(3 downto 0)); end multiplier; architecture behv of multiplier is begin process(num1, num2) variable num1_reg: std_logic_vector(2 downto 0); variable product_reg: std_logic_vector(5 downto 0); begin num1_reg := '0' & num1; product_reg := "0000" & num2; -- use variables doing computation -- algorithm is to repeat shifting/adding for i in 1 to 3 loop if product_reg(0)='1' then product_reg(5 downto 3) := product_reg(5 downto 3) + num1_reg(2 downto 0);

end if; product_reg(5 downto 0) := '0' & product_reg(5 downto 1); end loop; -- assign the result of computation back to output signal product <= product_reg(3 downto0); end process; end behv;

Example of latch- D
entity D_latch is port( data_in: in std_logic; enable: in std_logic; data_out: out std_logic ); end D_latch; architecture behv of D_latch is begin -- compare this to D flipflop process(data_in, enable) begin if (enable='1') then -- no clock signal here data_out <= data_in; end if; end process;

end behv;

Example of j-kff
entity JK_FF is port ( clock: in std_logic; J, K: in std_logic; reset: in std_logic; Q, Qbar: out std_logic); end JK_FF; architecture behv of JK_FF is -- define the useful signals here signal state: std_logic; signal input: std_logic_vector(1 downto 0); begin -- combine inputs into vector input <= J & K; p: process(clock, reset) is begin if (reset='1') then state <= '0'; elsif (rising_edge(clock)) then -- compare to the truth table case (input) is when "11" => state <= not state; when "10" => state <= '1';

when "01" => state <= '0'; when others => null; end case; end if; end process; -- concurrent statements Q <= state; Qbar <= not state; end behv;

Example of decoder
entity DECODER is port( I: in std_logic_vector(1 downto 0); O: out std_logic_vector(3 downto 0) ); end DECODER; architecture behv of DECODER is begin -- process statement process (I) begin -- use case statement case I is when "00" => O <= "0001"; when "01" => O <= "0010";

when "10" => O <= "0100"; when "11" => O <= "1000"; when others => O <= "XXXX"; end case; end process; end behv; architecture when_else of DECODER is begin -- use when..else statement O <= "0001" when I = "00" else "0010" when I = "01" else "0100" when I = "10" else "1000" when I = "11" else "XXXX";

end when_else;

Subprogram Procedures
We start our discussion of subprograms with procedures. There are two aspects to using procedures in a model: first the procedure is declared, then elsewhere the procedureis called. The syntax rule for a procedure declaration is subprogram_body procedure identifier [ ( parameter_interface_list ) ] is { subprogram_declarative_part } begin { sequential_statement } end [ procedure ] [ identifier ] ; The actions of a procedure are invoked by a procedure call statement, which isyet another VHDL sequential statement. A procedure with no parameters is calledsimply by writing its name, as shown by the syntax rule procedure_call_statement procedure_name ; When the last statement in the procedure is completed, the procedure returns.

EXAMPLE.
architecture rtl of control_processor is type func_code is (add, subtract);

signal op1, op2, dest : integer; signal Z_flag : boolean; signal func : func_code; begin alu : process is procedure do_arith_op is variable result : integer; begin case func is when add => result := op1 + op2; when subtract => result := op1 op2; end case; dest <= result after Tpd; Z_flag <= result = 0 after Tpd; end procedure do_arith_op; begin do_arith_op; end process alu; end architecture rtl; An outline of an architecture body with a process containing a procedure. The procedure encapsulates part of the behavior of the process and is invoked by the procedure call statement within the process. Procedure Parameters Now that we have looked at the basics of procedures, we will discuss procedures thatinclude parameters. When we write a

parameterized procedure, we include informationin the parameter list about the parameters to be passed to the procedure.The syntax rule for a procedure declaration on upper page shows where the parameter list fitsin. Following is the syntax rule for a parameter list: interface_list ( [ constant I variable I signal ] identifier { , } : [ mode ] subtype_indication [ := static_expression ] ) { ; } mode in I out I inout The parameter list defines the formal parameters of the procedure. We quite complex, let us start with some simple examples and work up from them.

EXAMPLE
procedure do_arith_op ( op : in func_code ) is variable result : integer; begin case op is when add => result := op1 + op2; when subtract => result := op1 op2; end case; dest <= result after Tpd; Z_flag <= result = 0 after Tpd; end procedure do_arith_op; A procedure to perform an arithmetic operation, parameterized by the kind of operation. EXAMPLE procedure addu ( a, b : in word32; result : out word32; overflow : out boolean ) is

variable sum : word32; variable carry : bit := '0'; begin for index in sum'reverse_range loop sum(index) := a(index) xor b(index) xor carry; carry := ( a(index) and b(index) ) or ( carry and ( a(index) xor b(index) ) ); end loop; result := sum; overflow := carry = '1'; end procedure addu; A procedure to add two bit vectors representing unsigned integers. A call to this procedure may appear as follows: variable PC, next_PC : word32; variable overflow_flag : boolean; addu ( PC, X"0000_0004", next_PC, overflow_flag);

EXAMPLE
Suppose we wish to model the receiver part of a network interface. It receives fixed-length packets of data on the signal rx_data. The data is synchronized with changes, from 0 to 1, of the clock signal rx_clock. architecture behavioral of receiver is type declarations, etc signal recovered_data : bit; signal recovered_clock : bit; procedure receive_packet ( signal rx_data : in bit; signal rx_clock : in bit; data_buffer : out packet_array ) is begin for index in packet_index_range loop

wait until rx_clock = '1'; data_buffer(index) := rx_data; end loop; end procedure receive_packet; begin packet_assembler : process is variable packet : packet_array; begin receive_packet ( recovered_data, recovered_clock, packet ); end process packet_assembler; end architecture behavioral; An outline of a model of a network receiver, including a procedure with signal parameters of mode in.

EXAMPLE
library ieee; use ieee.std_logic_1164.all; architecture top_level of signal_generator is signal raw_signal : std_ulogic; procedure generate_pulse_train ( width, separation : in delay_length; number : in natural; signal s : out std_ulogic ) is begin for count in 1 to number loop s <= '1', '0' after width; wait for width + separation; end loop; end procedure generate_pulse_train; begin

raw_signal_generator : process is begin generate_pulse_train ( width => period / 2, separation => period period / 2, number => pulse_count, s => raw_signal ); end process raw_signal_generator; end architecture top_level; An outline of a model for a signal generator, including a pulse generator procedure with an out mode. Unconstrained Array Parameters

EXAMPLE
is a procedure that finds the index of the first bit set to 1 in a bit vector. The formal parameter v is of type bit_vector, which is an unconstrainedarray type. Note that in writing this procedure, we do not explicitly refer to theindex bounds of the formal parameter v, since they are not known. Instead, weuse the 'range attribute. procedure find_first_set ( v : in bit_vector; found : out boolean; first_set_index : out natural ) is begin for index in v'range loop if v(index) = '1' then found := true; first_set_index := index; return; end if;

end loop; found := false; end procedure find_first_set; A procedure to find the first set bit in a bit vector. Functions Let us now turn our attention to the second kind of subprogram in VHDL: functions.The syntax rule for a function declaration is very similar to that for a procedure declaration: subprogram_body function identifier [ ( parameter_interface_list ) ] return type_mark is { subprogram_declarative_item } begin { sequential_statement } end [ function ] [ identifier ] ; A function passes the result of its computation back to its caller using a return statement, given by the syntax rule return_statement return expression ; A function must include at least one return statement. The first to be executed causes the function to complete and return its result to the caller. function_call function_name [ ( parameter_association_list ) ]

EXAMPLE
determines the number represented in binary by a bit-vector value. function bv_to_natural ( bv : in bit_vector ) return natural is variable result : natural := 0; begin for index in bv'range loop result := result * 2 + bit'pos(bv(index));

end loop; return result; end function bv_to_natural; A function that converts the binary representation of an unsigned number to a numeric value. As an example of using this function, consider a model for a readonly memory, which represents the stored data as an array of bit vectors, as follows: type rom_array is array (natural range 0 to rom_size1) of bit_vector(0 to word_size1); variable rom_data : rom_array; If the model has an address port that is a bit vector, we can use the function toconvert the address to a natural value to index the ROM data array, as follows: data <= rom_data ( bv_to_natural(address) ) after Taccess;

Package Package Declarations and Bodies


A VHDL package is simply a way of grouping a collection of related declarations thatserve a common purpose. They allow us to separate the external view of the itemsthey declare from the implementation of those items. The external view is specifiedin a package declaration, whereas the implementation is defined in a separate packagebody. The syntax rule for writing a package declaration is package_declaration package identifier is { package_declarative_item } end [ package ] [ identifier ] ; The identifier provides a name for the package, which we can use

EXAMPLE
package cpu_types is constant word_size : positive := 16; constant address_size : positive := 24; subtype word is bit_vector(word_size 1 downto 0); subtype address is bit_vector(address_size 1 downto 0);

type status_value is ( halted, idle, fetch, mem_read, mem_write, io_read, io_write, int_ack ); end package cpu_types; A package that declares some useful constants and types for a CPU model. Subprograms in Package Declarations Another kind of declaration that may be included in a package declaration is a subprogram declarationeither a procedure or a function declaration. An important aspect of declaring a subprogram in a package declaration is that we only write the header of the subprogram, that is, the part that includes the name and the interfacelist defining the parameters (and result type for functions). We leave out the body ofthe subprogram. For example, suppose we have a package declaration that definesa bitvector subtype: subtype word32 is bit_vector(31 downto 0); We can include in the package a procedure to do addition on word32 values that represent tsigned integers. The procedure declaration in the package declaration is procedure add ( a, b : in word32; result : out word32; overflow : out boolean ); package_body package body identifier is { package_body_declarative_item } end [ package body ] [ identifier ] ;

EXAMPLE
shows outlines of a package declaration and a package body declaringarithmetic functions for bit-vector values. The functions treat bit vectorsas representing signed integers in binary form.

Only the function headers are included in the package declaration. The package body contains the full function bodies. It also includes a function, mult_unsigned, not defined in the package declaration. It is used internally in the package body to implement the signed multiplication operator. package bit_vector_signed_arithmetic is function add ( bv1, bv2 : bit_vector ) return bit_vector; function sub ( bv : bit_vector ) return bit_vector; function mult ( bv1, bv2 : bit_vector ) return bit_vector; end package bit_vector_signed_arithmetic; package body bit_vector_signed_arithmetic is function add ( bv1, bv2 : bit_vector ) return bit_vector is function sub ( bv : bit_vector ) return bit_vector is function mult_unsigned ( bv1, bv2 : bit_vector ) return bit_vector is begin end function mult_unsigned; function mult ( bv1, bv2 : bit_vector ) return bit_vector is begin if bv1(bv1'left) = '0' and bv2(bv2'left) = '0' then return mult_unsigned(bv1, bv2); elsif bv1(bv1'left) = '0' and bv2(bv2'left) = '1' then return mult_unsigned(bv1, bv2); elsif bv1(bv1'left) = '1' and bv2(bv2'left) = '0' then return mult_unsigned(bv1, bv2); else return mult_unsigned(bv1, bv2); end if; end function mult;

end package body bit_vector_signed_arithmetic; An outline of a package declaration and body that define signed arithmetic functions on integers represented as bit vectors. Use Clauses use_clause use selected_name { , } ; selected_name identifier . identifier . ( identifier I all ) use work.cpu_types.word, work.cpu_types.address; and then refer to the used names in declarations: variable data_word : word; variable next_address : address use ieee.std_logic_116 4.all; library ieee; use ieee.std_logic_116 4.all; entity logic_block is port ( a, b : in std_ulogic; y, z : out std_ulogic ); end entity logic_block;

VHDL

99

SWAP PROGRAM
-- File: swap.vhd -- created by Design Wizard: 05/26/11 11:45:33 ---{{ Section below this comment is automatically maintained -- and may be overwritten --{entity {swap} architecture {swap}} entity swap is port ( a: inout integer:=9; b: inout integer:=6; clk: in BIT ); end swap; --}} End of automatically maintained section architecture swap of swap is begin process (clk) variable c,d:integer; begin c := a ; d := b; b <= c; a <= d; -- <<enter your statements here>> end process; end swap;

VHDL

100

Add progarm
--- File: add.vhd -- created by Design Wizard: 05/26/11 12:15:52 ---{{ Section below this comment is automatically maintained -- and may be overwritten --{entity {add} architecture {add}} entity add is port ( a: in integer; b: in integer; c: out integer ); end add; --}} End of automatically maintained section architecture add of add is begin c<= a + b; -- <<enter your statements here>> end add;

VHDL

101

Boolean progam
-- File: bolean.vhd -- created by Design Wizard: 05/30/11 11:44:52 ---{{ Section below this comment is automatically maintained -- and may be overwritten --{entity {bolean} architecture {bolean}} entity bolean is port ( a: in BIT; b: in BIT; c: in BIT; d: in BIT; e: out BIT ); end bolean; --}} End of automatically maintained section architecture bolean of bolean is begin e<= (a and b and c and d) or (not b and c and d) or (b and not c and d); -- <<enter your statements here>> end bolean; shift operator --- File: shiftoperators.vhd -- created by Design Wizard: 05/30/11 11:54:44 ---{{ Section below this comment is automatically maintained -- and may be overwritten --{entity {shiftoperators} architecture {shiftoperators}} entity shiftoperators is

VHDL

102

port ( a: in BIT_VECTOR (0 to 6); b0,b1,b2,b3,b4,b5,b6,b7,b8,b9: out BIT_VECTOR (0 to 6) ); end shiftoperators; --}} End of automatically maintained section architecture shiftoperators of shiftoperators is begin b0 <= a sll 4; b1<= a srl 3; b2<= a sla 3; b3<= a sra 3; b4<= a rol 3; b5<= a rol 2; b6<= a ror 3; b7<=a ror -4; b8<= a srl -5; b9<= a sla -2; -- <<enter your statements here>> end shiftoperators; bolean shift opretot --- File: bollean.vhd -- created by Design Wizard: 05/30/11 12:09:27 ---{{ Section below this comment is automatically maintained -- and may be overwritten --{entity {bollean} architecture {bollean}} entity bollean is port ( a: in BIT_VECTOR (0 to 6); b0,b1,b2,b3: out BIT_VECTOR (0 to 6) ); end bollean;

VHDL

103

--}} End of automatically maintained section architecture bollean of bollean is begin b0 <= a sra 3; b1<= a sll 2; b2<= a srl 3; b3<= a sla 3; -- <<enter your statements here>> end bollean;

VHDL

104

k map
-- File: k map.vhd -- created by Design Wizard: 05/30/11 12:17:15 ---{{ Section below this comment is automatically maintained -- and may be overwritten --{entity {\k map\} architecture {\k map\}} entity \k map\ is port ( x: in BIT; y: in BIT; z: in BIT; w: in BIT; a: out BIT ); end \k map\; --}} End of automatically maintained section architecture \k map\ of \k map\ is begin a<= (not w and not w and not z) or (not x and not w and not y) or (w and x and y) or (w and y and z) or (x and y and z); -- <<enter your statements here>> end \k map\;

VHDL

105

compute
--- File: compute_value.vhd -- created by Design Wizard: 05/31/11 10:52:22 ---{{ Section below this comment is automatically maintained -- and may be overwritten --{entity {compute_value} architecture {compute_value}} library IEEE; use IEEE.std_logic_1164.all; entity compute_value is port ( x: in integer:= 2**5-1; y: in integer:= 17 * 18 + 5; a: out INTEGER ); end compute_value; --}} End of automatically maintained section architecture compute_value of compute_value is begin a<= x/y; -- <<enter your statements here>> end compute_value; string.;statement --- File: string.vhd -- created by Design Wizard: 05/31/11 11:14:56 ---{{ Section below this comment is automatically maintained -- and may be overwritten --{entity {string} architecture {string}}

VHDL

106

entity string1 is port ( d: out string(1 to 3) ); end string1; --}} End of automatically maintained section architecture string1 of string1 is begin d<= 'c' & 'a' & 't' ; -- <<enter your statements here>> end string1; compute other --- File: compute_234.vhd -- created by Design Wizard: 05/31/11 11:35:29 ---{{ Section below this comment is automatically maintained -- and may be overwritten --{entity {compute_234} architecture {compute_234}} library IEEE; use IEEE.std_logic_1164.all; entity compute_234 is port ( x: in integer:=5; y: in integer:=7; z1: out integer; z2: out INTEGER ); end compute_234; --}} End of automatically maintained section architecture compute_234 of compute_234 is begin z1<= x**2 + y**2 - 2*x*y;

VHDL

107

z2<= x**2 + y**2 + 2*x*y;-- <<enter your statements here>> end compute_234;

integer input using process


--- File: integerinput.vhd -- created by Design Wizard: 06/01/11 10:58:29 ---{{ Section below this comment is automatically maintained -- and may be overwritten --{entity {integerinput} architecture {integerinput}} entity integerinput is port ( a: in INTEGER; b: out INTEGER ); end integerinput; --}} End of automatically maintained section architecture integerinput of integerinput is begin process (a) begin if a<60 then b<=a+20; elsif a>60 and a<80 then b<=a+15; elsif a>80 then b<=a+5; end if; end process; -- <<enter your statements here>> end integerinput;

VHDL

108

program of mux using process


--- File: mux.vhd -- created by Design Wizard: 06/01/11 11:07:12 ---{{ Section below this comment is automatically maintained -- and may be overwritten --{entity {mux} architecture {mux}} entity mux is port ( a: in integer; b: in integer; c: in integer; d: in integer; s: in bit_vector(0 to 1); y: out integer ); end mux; --}} End of automatically maintained section architecture mux of mux is begin process (s,a,b,c,d) begin if (s(0)='0' and s(1)='0') then y<=a; else if (s(0)='0' and s(1)='1') then y<=b; else if (s(0)='1' and s(1)='0') then y<=c; else if (s(0)='1' and s(1)='1') then y<=d; end if; end if; end if; end if; end process;

VHDL

109

-- <<enter your statements here>> end mux;

df/f using process


--- File: dff.vhd -- created by Design Wizard: 06/01/11 11:34:50 ---{{ Section below this comment is automatically maintained -- and may be overwritten --{entity {dff} architecture {dff}} entity dff is port ( a: in BIT; b: out BIT ); end dff; --}} End of automatically maintained section architecture dff of dff is begin process(a) begin if a<='0' then b<='0'; elsif a<='1' then b<='1'; end if; end process; -- <<enter your statements here>> end dff; largest_no_find--- process steatment --- File: largest_no.vhd

VHDL

110

-- created by Design Wizard: 06/01/11 12:28:29 ---{{ Section below this comment is automatically maintained -- and may be overwritten --{entity {largest_no} architecture {largest_no}} entity largest_no is port ( a: in INTEGER; b: in INTEGER; c: in INTEGER; y: out INTEGER ); end largest_no; --}} End of automatically maintained section architecture largest_no of largest_no is begin process(a,b,c) begin if (a > b) and (a > c) then y <= a; elsif (b > a) and (b > c) then y<= b; elsif (c > a)and (c > b) then y <= c; end if; end process; -- <<enter your statements here>> end largest_no;

VHDL

111

s-rf/f using case_statement


ibrary IEEE; use IEEE.std_logic_1164.all; entity case_srff is port ( a: in integer; b: in integer; y: out integer; c: in integer; d: in integer; s: in BIT_vector(0 to 1) ); end case_srff; --}} End of automatically maintained section architecture case_srff of case_srff is begin process (a,b,c,d,s) begin case s is when "00" => y<= a; when "01" => y<= b; when "10" => y<= c; when "11" => y<= d; end case; end process;-- <<enter your statements here>> end case_srff;

VHDL

112

1_4 demux case- process


library IEEE; use IEEE.std_logic_1164.all; entity \1_4 demux\ is port ( a: in bit_vector (0 to 1); s: in bit_vector (0 to 1); w: out bit_vector(0 to 1); x: out bit_vector (0 to 1); y: out bit_vector ( 0 to 1); z: out bit_vector (0 to 1) ); end \1_4 demux\; --}} End of automatically maintained section architecture \1_4 demux\ of \1_4 demux\ is begin process(a,s) begin case s is when "00" => w<= a; when "01" => x<= a; when "10" => y<= a; when "11" => z<= a; end case; end process; -- <<enter your statements here>> end \1_4 demux\;

VHDL

113

bcd to access3 process


ntity bcd_to_acess3 is port ( a: in bit; b:in bit; c: in bit; d : in bit; w: inout bit; x: inout bit; y: inout bit; z: inout BIT; k: out bit_vector(0 to 3) ); end bcd_to_acess3; --}} End of automatically maintained section architecture bcd_to_acess3 of bcd_to_acess3 is type alu is (add); signal s:alu; signal j,t,u,v:bit; begin -process(a,b,c,d) -begin --case s is (j,t,u,v)<=bit_vector'("0011"); w<= a or j; x<=b or t; y<=c or u; z<=d or v; k<=(w & x & y & z); -- begin -when add=>z<=a+y; -when others=>null; -end case; -end process; -- <<enter your statements here>>

VHDL

114

end bcd_to_acess3; ALU USING IF STATEMENT entity alu_using_if_statement is port ( a: in INTEGER; b: in INTEGER; c: out INTEGER ); end alu_using_if_statement; --}} End of automatically maintained section architecture alu_using_if_statement of alu_using_if_statement is type alu is (add,sub,div,mul); signal s:alu; begin process(a,b) begin case s is when add=>c<=a+b; when sub=>c<=a-b; when mul=>c<=a*b; when div=>c<=a/b; when others=>null; end case; end process; -- <<enter your statements here>> end alu_using_if_statement;

VHDL

115

BINARY TO GRAY
entity \binary to gray\ is port ( a: in BIT; b: in BIT; c: in BIT; d: in BIT; w: inout BIT; x: inout BIT; y: inout BIT; z: inout BIT ); end \binary to gray\; --}} End of automatically maintained section architecture \binary to gray\ of \binary to gray\ is signal k:bit_vector(0 to 3); begin process(a,b,c,d,w,x,y,z) begin w<=a; x<=a xor b; y<=b xor c; z<=c xor d; k<=(w & x & y & z); end process; -- <<enter your statements here>> end \binary to gray\;

VHDL

116

dff-using block statement


entity dff_using_block_statement is port ( d: in BIT; clk: in BIT; q: out BIT; qbar: out BIT ); end dff_using_block_statement; --}} End of automatically maintained section architecture dff_using_block_statement of dff_using_block_statement is begin g1:block(clk='1') begin q<=guarded d; qbar <= guarded not(d); end block g1; -- <<enter your statements here>> end dff_using_block_statement;

VHDL

117

Encoder
entity \encoder _using_block_statement\ is port ( a: in BIT; b: in BIT;b en: in BIT; w: out BIT_vector(0 to 3) --x: out BIT; --y: out BIT; --z: out BIT ); end \encoder _using_block_statement\; --}} End of automatically maintained section architecture \encoder _using_block_statement\ of \encoder _using_block_statement\ is begin g1:block(en='1') signal a,b,abar,bbar:bit; begin abar<=not a; bbar<=not b; w(0)<=guarded (abar and bbar and en); w(1)<=guarded (abar and b and en); w(2)<=guarded (a and bbar and en); w(3)<=guarded (a and b and en); --qbar <= guarded not(d); end block g1; -- <<enter your statements here>> end \encoder _using_block_statement\; 4t0 1 mux entity \4to1_mux\ is port ( a: in integer; b: in integer;

VHDL

118

c: in integer; d: in integer; s0: inout BIT; s1: inout BIT; clk:in bit; z: out integer ); end \4to1_mux\; --}} End of automatically maintained section architecture \4to1_mux\ of \4to1_mux\ is begin g1:block(clk='1')is signal s0bar,s1bar:bit; signal z1:integer; begin --s0<='0'; -s1<='0'; s0bar<=not s0; s1bar<=not s1; z1<= a when (s0bar='0' and s1bar='0') else b when (s0bar='0' and s1='1') else c when (s0='1' and s1bar='0') else d when (s0='1' and s1='1') ; z<= z1; end block g1; -- <<enter your statements here>> end \4to1_mux\;

VHDL

119

parity generator
library IEEE; use IEEE.std_logic_1164.all; entity \parity gen\ is port ( x: in bit; y: in bit; z: out BIT; d0,d1,d2,d3,d4,d5,d6,d7,d8: in bit; even: inout bit; odd: out bit ); end \parity gen\; --}} End of automatically maintained section architecture \parity gen\ of \parity gen\ is component xor1 port(x,y:in bit; z:out bit); end component; component not1 port(x: in bit; z: out bit); end component; signal e0,e1,e2,e3,f0,f1,h0:bit; begin x1:xor1 port map(d0,d1,e0); x2:xor1 port map(d0,d1,e0);-- <<enter your statements here>> x3:xor1 port map(d2,d3,e1); x4:xor1 port map(d4,d5,e2);-x5:xor1 port map(d6,d7,e3); x6:xor1 port map(e0,e1,f0);-- <<enter your statements here>> x7:xor1 port map(e2,e3,f1); x8:xor1 port map(f0,f1,h0);--

--

VHDL

120

x9:xor1 port map(h0,d8,even); x10:not1 port map(even,odd);-end \parity gen\;

xor program
entity xor1 is port ( x: in BIT; y: in BIT; z: out BIT ); end xor1; --}} End of automatically maintained section architecture xor1 of xor1 is begin z<= x xor y; -- <<enter your statements here>> end xor1; norentity not1 is port ( x: in BIT; z: out BIT ); end not1; --}} End of automatically maintained section architecture not1 of not1 is begin z<= not x; -- <<enter your statements here>> end not1; and ibrary IEEE;

VHDL

121

use IEEE.std_logic_1164.all; entity and2 is port ( a: in bit; b: in bit; z: out bit ); end and2; --}} End of automatically maintained section architecture and2 of and2 is begin z<= a and b;-- <<enter your statements here>> end and2;

dff using structure


library IEEE; use IEEE.std_logic_1164.all; entity \d_using structure\ is port ( mr: in bit; din: in bit; a: in bit; clk: in bit; rdy: out bit; ctrla: out BIT ); end \d_using structure\; --}} End of automatically maintained section architecture \d_using structure\ of \d_using structure\ is component dff port (d,m:in bit; q,qbar:out bit); end component ;

VHDL

122

component nor1 port (x,y: in bit; z: out bit); end component; component and1 port(x,y:in bit; z:out bit); end component; signal s1,s2: bit; begin A1: dff port map (a,clk,s1,s2); A2: nor1 port map (mr,s1,rdy); A3: and1 port map (s2,din,ctrla); -- <<enter your statements here>> end \d_using structure\;

4_bit_full adder
entity \4_bit_full_adder\ is port ( x: in BIT_VECTOR (3 downto 0); y: in BIT_VECTOR (3 downto 0); sum: out BIT_VECTOR (3 downto 0); cout: out bit; v:out bit; cin:in bit ); end \4_bit_full_adder\; --}} End of automatically maintained section architecture \4_bit_full_adder\ of \4_bit_full_adder\ is component full_adder1 port (a,b,c9: in bit; z,c: out bit); end component; component xor3

VHDL

123

port (a,b: in bit; z: out bit); end component; signal c1,c2,c3,c4: bit; begin d1: full_adder1 port map (x(0),y(0),cin,sum(0),c1); d2: full_adder1 port map (x(1),y(1),c1,sum(1),c2); d3: full_adder1 port map (x(2),y(2),c2,sum(2),c3); d4: full_adder1 port map (x(3),y(3),c3,sum(3),c4); d5: xor3 port map (c4,c3,v); -- <<enter your statements here>>

Mux using structure


entity mux_using_structural_statement is port ( s: in BIT_VECTOR (0 to 3); b0,b1: in BIT; y: out BIT ); end mux_using_structural_statement; --}} End of automatically maintained section architecture mux_using_structural_statement of mux_using_structural_statement is component and1 port(p,q,r:in bit;z:out bit); end component; component or1 port(p,q,r,s:in bit;z:out bit); end component; component not1 port(x:in bit;z:out bit); end component; signal n1,n2,l1,l2,l3,l4:bit;

VHDL

124

begin T1: not1 port map(b0,n1); T2: not1 port map(b1,n2); A1: and1 port map (s(0),n1,n2,l1); A2: and1 port map (s(1),n2,b0,l2); A3: and1 port map (s(2),n1,b1,l3); A4: and1 port map (s(3),b1,b0,l4); A5: or1 port map (l1,l2,l3,l4,y);-- <<enter your statements here>> end mux_using_structural_statement;

not generic
entity not_generic is generic (tpd:time:=10ns); port ( a: in BIT; z: out BIT ); end not_generic; --}} End of automatically maintained section architecture not_generic of not_generic is begin z<= not a after tpd; -- <<enter your statements here>> end not_generic;

xnor generic
entity exnor_generic is generic (tpd:time:=10 ns); port ( a: in BIT; b: in BIT; z: out BIT );

VHDL

125

end exnor_generic; --}} End of automatically maintained section architecture exnor_generic of exnor_generic is begin z<=a xnor b after tpd; -- <<enter your statements here>> end exnor_generic;

factorial using function


entity factorial_using_functions is port ( a: in INTEGER; b: out INTEGER ); end factorial_using_functions; --}} End of automatically maintained section architecture factorial_using_functions of factorial_using_functions is function fact1(s:integer) return integer is variable y: integer:=1; begin for i in 1 to s loop y:= y * i; end loop; return y; end fact1; begin b<= fact1(a); -- <<enter your statements here>> end factorial_using_functions;

VHDL

126

half adder using function..


entity \halfadder_using_function overloading\ is port ( a: in BIT; b: in BIT; sum: out BIT; carry: out BIT ); end \halfadder_using_function overloading\; --}} End of automatically maintained section architecture \halfadder_using_function overloading\ of \halfadder_using_function overloading\ is function ha1 (y,z: bit) return bit is variable t: bit; begin t:=y xor z; return t; end ha1; begin sum <= ha1(a,b); process (a,b) function ha2 (m,n:bit) return bit is variable w: bit; begin w:=m and n; return w; end ha2; begin carry <= ha2(a,b); end process; -- <<enter your statements here>> end \halfadder_using_function overloading\;

VHDL

127

half adder using package package p1 is function ha (x,y:bit) return bit; function ha1 (x,y:bit) return bit; end p1; package body p1 is function ha (x,y:bit) return bit is variable w:bit; begin w:= x xor y; return w; end ha; function ha1 (x,y:bit) return bit is variable w:bit; begin w:= x and y; return w; end ha1; end p1; --library ieee; use ieee.std--all; use work.p1.all;--all;

--

entity halfadder_using_package is port ( a: in BIT; b: in BIT; sum: out BIT; carry: out BIT ); end halfadder_using_package;

VHDL

128

--}} End of automatically maintained section architecture halfadder_using_package of halfadder_using_package is begin sum<= ha(a,b); carry<= ha1(a,b); -- <<enter your statements here>> end halfadder_using_package;

OR GATE IN BEHAVIORAL STATEMENT


entity or_gate is port (a: in BIT; b: in BIT; c: in BIT; y: out BIT); end or_gate; --}} End of automatically maintained section architecture or_gate of or_gate begin y <= a or b or c; -- <<enter your statements here>> End or_gate;

Half adder
--{entity {half_adder} architecture {half_adder}} entity half_adder is port ( a: in BIT; b: in BIT; s: out BIT; c: out BIT ); end half_adder; --}} End of automatically maintained section

VHDL

129

architecture half_adder of half_adder is begin s <= a xor b; c <= a and b; -- <<enter your statements here>> end half_adder;

half sub
entity half_sub is port ( a: in BIT; b: in BIT; d: out BIT; y: out BIT ); end half_sub; --}} End of automatically maintained section architecture half_sub of half_sub is begin d <= a xor b; y <= not a and b; -- <<enter your statements here>> end half_sub;

full adder
-{entity {full_adder} architecture {full_adder}} entity full_adder is port ( a: in BIT; b: in BIT; c: in BIT; s: out BIT; y: out BIT

VHDL

130

); end full_adder; --}} End of automatically maintained section architecture full_adder of full_adder is begin s <= a xor b xor c; y <= ((a and b) or (b and c) or (a and c)); -- <<enter your statements here>> end full_adder;

full sub
--- File: full_sub.vhd -- created by Design Wizard: 05/26/11 10:47: ---{{ Section below this comment is automatically maintained -- and may be overwritten --{entity {full_sub} architecture {full_sub}} entity full_sub is port (a: in BIT; b: in BIT; c: in BIT; d: out BIT; y: out BIT); end full_sub; --}} End of automatically maintained section architecture full_sub of full_sub is begin d <= a xor b xor c; y <= (((not a)and b) or (b and c) or ((not a) and c)); -- <<enter your statements here>> end full_sub;

kmap
entity k_mapp is port (a: in BIT; b: in BIT; c: in BIT;d: in BIT;f: out BIT); end k_mapp; --}} End of automatically maintained section

VHDL

131

architecture k_mapp of k_mapp is begin f <= (((b and c) and d)or ((not a and b)and (not d))or ((a and (not b))and c and (not d))); -- <<enter your statements here>> end k_mapp;

decoder2_4
entity dec2_4 is port ( E: in BIT; z: out BIT_VECTOR (3 downto 0); a: in BIT; b: in BIT ); end dec2_4; --}} End of automatically maintained section architecture dec2_4 of dec2_4 is signal abar,bbar:bit; begin z(3) <= a and b and E; bbar <= not b; abar <= not a; z(2) <= a and bbar and E; z(1) <= abar and b and E; z(0) <= abar and bbar and E; -- <<enter your statements here>> end dec2_4; ===+++==== entity dec2_4_2 is port ( a: in BIT; b: in BIT;

VHDL

132

E: in BIT; Z: out BIT_VECTOR (0 to 3) ); end dec2_4_2; --}} End of automatically maintained section architecture dec2_4_2 of dec2_4_2 is begin process (a,b,E) variable abar,bbar:bit; begin abar := not a; bbar := not b; Z(0) <= abar and bbar and E; Z(1) <= abar and b and E; Z(2) <= a and bbar and E; Z(3) <= a and b and E; end process; -- <<enter your statements here>>

swap
entity swap_numbers is port ( a: inout INTEGER:=3; b: inout INTEGER:=2; clk: in BIT ); end swap_numbers; --}} End of automatically maintained section architecture swap_numbers of swap_numbers is begin process (clk) variable x,y:integer; begin

VHDL

133

x := a ; y := b ; a <= y ; b <= x ; end process; -- <<enter your statements here>> end swap_numbers;

shift operater
entity operators is port ( a: in BIT_VECTOR (0 to 6):= "1001010"; y1,y2,y3,y4,y5,y6,y7,y8,y9,y10: out BIT_VECTOR (0 to 6) ); end operators; --}} End of automatically maintained section architecture operators of operators is begin y1 <= a sll 2; y2 <= a srl 3; y3 <= a sla 2; y4 <= a sra 3; y5 <= a rol 2; y6 <= a ror 3; y7 <= a sll -4; y8 <= a srl -5; y9 <= a rol -2; y10 <= a sra -3; -- -- <<enter your statements here>> end operators;

Sop program

VHDL

134

entity SOP_3 is port ( A: in BIT; B: in BIT; C: in BIT; D: in BIT; Y: out BIT ); end SOP_3; --}} End of automatically maintained section architecture SOP_3 of SOP_3 is begin Y <= B xnor D; -- <<enter your statements here>> end SOP_3;

pos program
entity \POS _3\ is port ( A: in BIT; B: in BIT; C: in BIT; D: in BIT; Y: out BIT ); end \POS _3\; --}} End of automatically maintained section architecture \POS _3\ of \POS _3\ is signal Abar,Bbar,Cbar,Dbar:Bit; begin Abar <= not A; Bbar <= not B; Cbar <= not C;

VHDL

135

Dbar <= not D; Y <= (((A or C)or D) and ((A or B) or D)and((Bbar or Cbar) or Dbar)and ( (Abar or Bbar)or Dbar)and ((Abar or Bbar) or Cbar)); -- <<enter your statements here>> end \POS _3\;

sum of-3-d
entity sum_of_3_digit_no is port ( a: in INTEGER:= 465; b: in INTEGER:= 322; c: in INTEGER:= 777; y: out INTEGER ); end sum_of_3_digit_no; --}} End of automatically maintained section architecture sum_of_3_digit_no of sum_of_3_digit_no is begin y <= a + b + c; -- <<enter your statements here>> end sum_of_3_digit_no;

multiplication-operator
entity multiplication_operators is port ( a: in INTEGER; b: in INTEGER ); end multiplication_operators; --}} End of automatically maintained section

VHDL

136

architecture multiplication_operators of multiplication_operators is signal y0,y1,y2,y3,y4,y5 : integer; begin y0 <= a rem b; y1 <= (-a) rem b; y2 <= a mod b; y3 <= a rem (-b); y4 <= a mod (-b); y5 <= (-a) mod b; -- <<enter your statements here>> end multiplication_operators;

absolute operator
entity abs_operator is port ( A: in INTEGER:= 8; Y: out INTEGER ); end abs_operator; --}} End of automatically maintained section architecture abs_operator of abs_operator is begin Y <= abs (-A); -- <<enter your statements here>> end abs_operator;

reversing program
entity reversing_the_digits is port ( A: in integer:=345; Y: out integer ); end reversing_the_digits;

VHDL

137

--}} End of automatically maintained section architecture reversing_the_digits of reversing_the_digits is begin process (A) variable b,c,d,e:integer; begin e := A /100; b := A mod 100; c := b / 10; d := b mod 10; y<= ( d*100)+(c*10)+(e*1); end process; -- <<enter your statements here>> end reversing_the_digits;

sum-of 3 digit
entity sum_of_the_digits_1 is port ( A: in INTEGER:=345; Y: out INTEGER ); end sum_of_the_digits_1; --}} End of automatically maintained section architecture sum_of_the_digits_1 of sum_of_the_digits_1 is signal b,c,d,e:integer; begin b <= A/100; c<= A mod 100; d <= c/10; e <= c mod 10; Y <= b + d + e ; -- <<enter your statements here>> end sum_of_the_digits_1;

VHDL

138

data bus using string


entity data_bus_using_string is port ( b: in CHARACTER:='C'; d: in CHARACTER:='A'; e: in CHARACTER:='T'; y: out STRING (1 to 3) ); end data_bus_using_string; --}} End of automatically maintained section architecture data_bus_using_string of data_bus_using_string is begin y <= (b & d & e); -- <<enter your statements here>> end data_bus_using_string;

j-k flip-flop
entity JK_flipflop is port ( J1: inout BIT_VECTOR (0 to 1); J: in BIT; K: in BIT; clk:in bit; Q: out BIT ); end JK_flipflop; --}} End of automatically maintained section architecture JK_flipflop of JK_flipflop is begin process (J,K,clk) variable Qn : bit:= '0'; begin

VHDL

139

j1<=j & k; case J1 is when "00" => Q <= Qn; when "01" => Q <= '0'; when "10" => Q <= '1'; when "11" => report "prohibited st" severity error; --when others => null ; end case; end process; -- <<enter your statements here>> end JK_flipflop;

d-f-f
entity D_f_f is port ( D: in BIT; Q: out BIT ); end D_f_f; --}} End of automatically maintained section architecture D_f_f of D_f_f is signal D1:bit; begin process (D) begin case D1 is when '0' => Q <= '0'; when '1' => Q <= '1'; end case; end process; -- <<enter your statements here>> end D_f_f;

T-f-f

VHDL

140

entity T_f_f is port ( T: in BIT; Q: out BIT ); end T_f_f; --}} End of automatically maintained section architecture T_f_f of T_f_f is signal T1 : bit; begin process (T ) begin case T1 is when '0'=> Q <= '1'; when '1' => Q <= '0'; end case; end process; -- <<enter your statements here>> end T_f_f;

DMUX USING CASE


entity DEMUX_using_case is port ( W: out BIT; X: out BIT; Y: out BIT; Z: out BIT; S1: in BIT; S2: in BIT; A: in BIT ); end DEMUX_using_case; --}} End of automatically maintained section

VHDL

141

architecture DEMUX_using_case of DEMUX_using_case is begin process (A) variable A1 :bit_vector (0 to 1); begin A1:=S1 & S2; case A1 is when "00" => W <= A; when "01" => X <= A; when "10" => Y <= A; when "11" => Z <= A; when others => null; end case; end process; -- <<enter your statements here>> end DEMUX_using_case;

S-R USING CASE


entity SR_f_f is port ( S: in BIT; R: in BIT; clk: in BIT; Q: out BIT ); end SR_f_f; --}} End of automatically maintained section architecture SR_f_f of SR_f_f is signal S1:bit_vector (0 to 1); begin process (S,R,clk) variable Qn :bit:='0'; begin S1<= S & R; case S1 is

VHDL

142

when "00" => Q <= Qn; when "01" => Q <= '0'; when "10" => Q <= '1'; when "11" => report "forbidden state" severity warning; end case; end process; -- <<enter your statements here>> end SR_f_f;

ALU USING CASE


entity ALU_using_if_case is port ( A: in INTEGER; B: in INTEGER; Y: out INTEGER ); end ALU_using_if_case; --}} End of automatically maintained section architecture ALU_using_if_case of ALU_using_if_case is type S is ( add,sub,mul,div); signal ALU :s; begin process (A,B) begin case alu is when add => Y <= A + B; when sub=> Y <= A - B; when mul => Y <= A * B; when div => Y <= A / B; when others => report "result not found " severity NOTE; end case; -- <<enter your statements here>>

VHDL

143

end process ; end ALU_using_if_case; --end;

BCD-TO-SEVEN PROCESS
entity BCD_to_SEGMENT_using_cond is port ( --- b0,b1,b2,b3: in BIT; B : in std_logic_vector(0 to 3); S : out std_logic_vector (0 to 6) -e0,e1,e2,e3: out BIT ); end BCD_to_SEGMENT_using_cond; --}} End of automatically maintained section architecture BCD_to_SEGMENT_using_cond of BCD_to_SEGMENT_using_cond is --signal B,E : bit_vector ( 0 to 3); begin --process (B) --begin --B <= b0 & b1 & b2 & b3; with B select S <= "1111110" when "0000" , "1100000" when "0001" , "1101101" when "0010", "1111001" when "0011", "0110011" when "0100", "1011011" when"0101", "0011111" when"0110", "1110000" when "0111", "UXLHWZO" when others; --nd case; --nd process; -- <<enter your statements here>>

VHDL

144

end BCD_to_SEGMENT_using_cond;

GRAY TO BINARY CASE


entity GRAY_to_BIN is port ( G: in BIT_VECTOR (0 to 3); B: out BIT_VECTOR (0 to 3) ); end GRAY_to_BIN; --}} End of automatically maintained section architecture GRAY_to_BIN of GRAY_to_BIN is begin process (G) begin case G is when "0000" => B <= "0000"; when "0011" => B <= "0010"; when "0010" => B <= "0011"; when "0110" => B <= "0100"; when "0111" => B <= "0101"; when "0101" => B <= "0110"; when "0100" => B <= "0111"; when others => report "invalid result" severity WARNING; end case; end process; -- <<enter your statements here>> end GRAY_to_BIN;

IF STATEMENT
entity if_prg4 is port ( a: in INTEGER; b: in INTEGER; c: in INTEGER;

VHDL

145

y: out INTEGER ); end if_prg4; --}} End of automatically maintained section architecture if_prg4 of if_prg4 is begin process (a,b,c) begin if a > b then y <= a; elsif b > c then y <= b; -end if; else y <= c; end if; end process; -- <<enter your statements here>> end if_prg4;

D USING BLOCK
entity D_using_block is port ( D: in BIT; clk: in BIT; Q,Qbar: out BIT ); end D_using_block; --}} End of automatically maintained section architecture D_using_block of D_using_block is begin G1 :block(clk = '1')

VHDL

146

begin Q <= guarded D; Qbar <= guarded not D; end block; -- <<enter your statements here>> end D_using_block;

FACTORIAL LOOP
entity factorial_using_while_loop is port ( n: inout INTEGER ; clk: in bit; fact1: out INTEGER ); end factorial_using_while_loop; --}} End of automatically maintained section architecture factorial_using_while_loop of factorial_using_while_loop is --signal n:integer:=0; begin process (n,clk) variable fact,i : integer := 1; begin L1: loop fact := fact * i; n <= n + 1; exit when n > 10; end loop; fact1 <= fact; end process; -- <<enter your statements here>> end factorial_using_while_loop;

AIN-TO- BCD-COND

VHDL

147

ibrary IEEE; use IEEE.std_logic_1164.all; entity BIN_to_BCD_cond is port ( B: in STD_LOGIC_VECTOR (0 to 3); D: out STD_LOGIC_VECTOR (0 to 3) ); end BIN_to_BCD_cond; --}} End of automatically maintained section architecture BIN_to_BCD_cond of BIN_to_BCD_cond is --signal a:std_logic_vector ( 0 to 3):="0110"; begin -with B1 select D <= "0000" when b(0)='0'and b(1)='0' and b(2)='0' and b(3)='0' else "0001" when b(0)='0'and b(1)='0' and b(2)='0' and b(3)='1' else "0010" when b(0)='0'and b(1)='0' and b(2)='1' and b(3)='0' else "0011" when b(0)='0'and b(1)='0' and b(2)='1' and b(3)='1' else "0100" when b(0)='0'and b(1)='1' and b(2)='0' and b(3)='0' else "0101" when b(0)='0'and b(1)='1' and b(2)='0' and b(3)='1' else "0110" when b(0)='0'and b(1)='1' and b(2)='1' and b(3)='0' else "0111" when b(0)='0'and b(1)='1' and b(2)='1' and b(3)='1' else "1000" when b(0)='1'and b(1)='0' and b(2)='0' and b(3)='0' else "1001" when b(0)='1'and b(1)='0' and b(2)='0' and b(3)='1' else "01UX" ; -- <<enter your statements here>> end BIN_to_BCD_cond;

FACT USING WHILE


entity fact_using_while is port ( n: in INTEGER; fact1: out INTEGER ); end fact_using_while;

VHDL

148

--}} End of automatically maintained section architecture fact_using_while of fact_using_while is begin process (n) variable fact:integer:=1; -variable i : integer :=1; begin for number in 2 to n loop -while (i<=n) loop -L1:loop fact := fact * number; -i := i + 1; -exit when (i>n); end loop; fact1 <= fact; end process; -- <<enter your statements here>> end fact_using_while;

HALF ADDER USING STRUCTURE


entity HA_9_struct is port ( A: in BIT; B,C: in BIT; --sum: out BIT; diff,borrow :out bit -carry: out BIT ); end HA_9_struct; --}} End of automatically maintained section architecture HA_9_struct of HA_9_struct is component xor1 port ( x,y:in bit; z:out bit);

VHDL

149

end component; component and1 port (x,y:in bit ; z:out bit); end component; component or2 port (x,y,z:in bit; w:out bit); end component; component not1 port (x:in bit;y:out bit); end component; signal s1,s2,s3,s4,s5:bit; begin a1:xor1 port map (A,B,s1); a2:and1 port map (s5,b,s2); a3:not1 port map (A,s5); a4:xor1 port map (s1,c,diff); a5:and1 port map (s5,c,s3); a6:and1 port map (B,C,s4); a7:or2 port map (s2,s3,s4,borrow); --a2: or1 port map (s1,c,carry) ; --begin -- <<enter your statements here>> end HA_9_struct;

AND1 DEFINED
entity and1 is port ( x: in BIT; y: in BIT; z: out BIT ); end and1; --}} End of automatically maintained section architecture and1 of and1 is

VHDL

150

begin z<= x and y; -- <<enter your statements here>> end and1;

OR1DEFIND
entity or1 is port ( x: in BIT; y: in BIT; z: out BIT ); end or1; --}} End of automatically maintained section architecture or1 of or1 is begin z <= x or y; -- <<enter your statements here>> end or1

DECODER USING STRUC.entity decoder_9_struct is port ( A: in BIT; B,E: in BIT; Z: out BIT_vector(0 to 3) ); end decoder_9_struct; --}} End of automatically maintained section architecture decoder_9_struct of decoder_9_struct is component and1 port (x,y,z :in bit; w:out bit); end component;

VHDL

151

component not1 port (x:in bit; y:out bit); end component; signal Abar,Bbar:bit; begin a5:not1 port map (A,Abar); a6:not1 port map (B,Bbar); a1:and1 port map (Abar,Bbar,E,z(0)); a2:and1 port map (Abar,B,E,z(1)); a3:and1 port map (A,Bbar,E,z(2)); a4:and1 port map (A,B,E,z(3)); --a5:not1 port map (A,Abar); -a6:not1 port map (B,Bbar); -- <<enter your statements here>> end decoder_9_struct;

AND1 DEFIND
entity and1 is port ( x: in BIT; y: in BIT; z: out BIT ); end and1; --}} End of automatically maintained section architecture and1 of and1 is begin z<= x and y; -- <<enter your statements here>> end and1 FULL SUBTRECTOR entity FS_13_mixed is port (

VHDL

152

a: in BIT; b,c: in BIT; borrow: out BIT; difference: out BIT ); end FS_13_mixed; --}} End of automatically maintained section architecture FS_13_mixed of FS_13_mixed is component not1 port (x:in bit; y:out bit); end component; component and1 port (x,y :in bit ; z:out bit); end component; component or3 port (x,y,z :in bit; w :out bit); end component; signal s1,s2,s3,s4 :bit; begin A1 :not1 port map (a,s1); A2:and1 port map (s1,b,S2); A3 :and1 port map (S1,c,S3); A4 :and1 port map (b,c,s4); A5 :or3 port map (s2,s3,s4,borrow); difference <= a xor b xor c; -- <<enter your statements here>> end FS_13_mixed; (entity or3 is port ( x: in BIT; y: in BIT; z: in BIT; w: out BIT ); end or3; --}} End of automatically maintained section

VHDL

153

architecture or3 of or3 is begin w <= x or y or z; -- <<enter your statements here>> end or3;)

AND GENERIC
entity AND_13_generic is generic ( t : time:=8ns); port ( a: in BIT; b: in BIT; c: out BIT ); end AND_13_generic; --}} End of automatically maintained section architecture AND_13_generic of AND_13_generic is begin c <= a and b after 8ns; -- <<enter your statements here>> end AND_13_generic;

FACT USING FUNCTION


entity fact_14_using_function is port ( a: in INTEGER; b: out INTEGER ); end fact_14_using_function; --}} End of automatically maintained section architecture fact_14_using_function of fact_14_using_function is function facto(S:integer)

VHDL

154

return integer is variable result: integer :=1; begin for i in 1 to s loop result:=result*i; end loop; return result; end facto; begin b<= facto(a); --end fact_14_using_function; -- <<enter your statements here>> end fact_14_using_function;

ALU USING PROCEDURE


entity alu_14_procedure is port ( a: in INTEGER; b: in INTEGER; c: out INTEGER ); end alu_14_procedure; --}} End of automatically maintained section architecture alu_14_procedure of alu_14_procedure is type s is (add,sub,mul,div,neq,eq); signal s1:s; procedure alu1 (signal q,w :in integer; signal r:out integer)is begin -process (q,w) -begin case s1 is when add => r<= q+w; when sub => r <=q-w; when mul => r <= q*w;

VHDL

155

when div => r <= q/w; when others => report "not found" severity error ; end case ; --end process; end procedure; begin alu1 (a,b,c); --end alu_14_procedure ; -- <<enter your statements here>> end alu_14_procedure;

J-K USING PROCEDURE


entity jk_14_procedure is port ( s: in BIT; r: in BIT; j :inout bit_vector (0 to 1); q: out BIT; qn: out BIT ); end jk_14_procedure; --}} End of automatically maintained section architecture jk_14_procedure of jk_14_procedure is procedure JK1 (signal a,b:in bit; signal j7 :inout bit_vector (0 to 1);signal c,d:out bit) is begin -process (a,b) -variable c:bit:='0'; -begin j7 <= a & b; case j7 is when "00" => d <= '0';

VHDL

156

when "01" => d <= '0'; when "10" => d <= '1'; when "11" => report "PROHIBITED STATE" severity error ; end case; -end process; end procedure; begin JK1 (s,r,j,q,qn); -- <<enter your statements here>> end jk_14_procedure;

J-K USING FUNCTION


entity JK_14_function is port ( s: in BIT; r: in BIT; q: out BIT -qn: out BIT ); end JK_14_function; --}} End of automatically maintained section architecture JK_14_function of JK_14_function is function JK1 (a,b:bit) return bit is variable result :bit; begin if (a ='0' and b= '0') then result := '0'; elsif (a='0' and b='1') then result := '0'; elsif (a='1' and b='0') then result := '1'; else report "PROHIBITED STATE" severity Error;

VHDL

157

end if ; return result ; end function ; begin q <=JK1 (s,r); -- <<enter your statements here>> end JK_14_function;

LARGEST NO USING FUNCTION


entity \greatest number_14_function\ is port ( a: in INTEGER; b: in INTEGER; c: in INTEGER; d: out INTEGER ); end \greatest number_14_function\; --}} End of automatically maintained section architecture \greatest number_14_function\ of \greatest number_14_function\ is function f (x,y,z:in integer ) return integer is variable result :integer ; begin if (x > y) then result := x; elsif (y > z) then result := y; else result :=z; end if; return result ; end function ; begin d <= f(a,b,c); -- <<enter your statements here>>

VHDL

158

end \greatest number_14_function\;

D USING FUNCTION
entity d_14_function is port ( d,clk: in BIT; q: out BIT ); end d_14_function; --}} End of automatically maintained section architecture d_14_function of d_14_function is function D1 (a,b:in bit) return bit is variable output :bit; begin if (a ='0') then output := '0'; else output := '1'; end if; return output; end function ; begin q <= d1(d,clk); -- <<enter your statements here>> end d_14_function;

D USING PROCEDURE
entity D_14_procedure is port ( d: in BIT; clk: in BIT; q: out BIT );

VHDL

159

end D_14_procedure; --}} End of automatically maintained section architecture D_14_procedure of D_14_procedure is procedure D1 (signal a,clk : in bit;signal b:out bit) is begin --case c is --when '0' => b <= '0'; --when '1' => b<= '1'; --when others => null; --end case; if (a ='0') then b <= '0'; else b<='1'; end if; end procedure; begin D1 (d,clk,q); -- <<enter your statements here>> end D_14_procedure;

VHDL

160

PROJECT REPORT 1

ELECTRONIC VOTING SYSTEM

VHDL

161

INTRODUCTION
THE ELECTRONIC VOTING MACHINE - AN ELECTRONIC MARVEL
Electronic Voting Machine (EVM) retains all the characteristics of voting by ballot papers, while making polling a lot more expedient. Being fast and absolutely reliable, the EVM saves considerable time, money and manpower. And, of course, helps maintain total voting secrecy without the use of ballot papers. The EVM is 100 per cent tamper proof. And, at the end of the polling, just press a button and there you have the results.

What does an EVM unit comprise of ?


The EVM consists of two units that can be inter-linked. One, a ballot unit which a voter uses to exercise his vote. And the other, a control unit - used by the polling officials.

The Ballot Unit : An electronic ballot box

A simple voting device, it displays the list of candidates. A facility to incorporate party names and symbols is in-built. All the voter has to do is press the desired switch located next to the name of each candidate. The main advantage is the speed, apart from the simplicity of operation, which requires no training at all. A single ballot unit takes in the names of 16 candidates. And thus, by connecting four ballot units the EVM can accommodate a total of 64 candidates in a single election.

VHDL

162

The control Unit : In Total control of the polling


Conduction of polling, display of total votes polled, sealing at the end of the poll, and finally, declaration of results - these are the various accomplishments of just one gadget : the control unit. In total control of the polling, this electronic unit gives you all necessary information at a press of a few buttons. For instance, if you need to know the total number of votes, you just have to press the Total switch. Candidates-wise results can be had only at the end of polling.

Independent & Reliable


The EVM is compact and comes in its reusable carry pack. Further, the EVM works/operates on a battery power source. Making it independent and totally reliable.

Hi-tech Simplicity
To commence polling, the polling officer activates the "Ballot" switch on the control unit. The voter then has to press the button of his choice on the ballot unit. This is followed by a short beep sound, indicating that the vote has been cast. Once again, the polling officer has to press the "Ballot" switch to clear the machine for the next voter to cast his vote.

Super-sensitive circuitry : No invalid votes


Inside the control unit, hidden from you, is an extremely sensitive circuitry that takes care of common election errors or malpractices like vote duplication. For instance, if one were to press two or more buttons simultaneously, then no vote would be cast. Even if there was a micro-second difference in the pressing of the switches, the EVM is sensitive enough to trace and identify the twitch that was press first.

Instant results
Once polling is completed, the election results can be known instantly at the counting station by pressing the ''Result''switch. This switch is located in a sealed compartment of the control unit.

Tamper proof design


The EVM is designed to be totally tamper proof. Each EVM comes with a sophisticated programme in assembly language : a software fully seated against outside influence. And the programme is itself fused on to a customised micro processor chip at the manufacturer's end. This ensures that the program is rendered tamper proof and inaccessible.

Result Printout

VHDL

163

Normally, an EVM displays results on the display panel of the control unit. But a printout option is available with the use of a Download Adaptor Unit (DAU). The DAU has to be connected to the control unit and any standard printer. Further, with the help of a modem, the DAU can also enable transmission of voting information to a distant centralised computer.

VHDL

164

Project : Program to implement ELECTRONIC VOTING SYSTEM

-- File: proj.vhd -- created by Design Wizard: 07/14/10 10:16:22 ---{{ Section below this comment is automatically maintained -- and may be overwritten --{entity {proj} architecture {proj}} entity evm is port ( switch : in bit; republicanparty : in bit ; democraticparty : in bit ; conservativeparty : in bit; labourparty : in bit; associationofcommunists : in bit; totalvotes: out INTEGER range 0 to 999 ); end evm; --entity begins

--entity ends

architecture evm of evm is --architecture begins begin process( switch ,republicanparty, democraticparty, conservativeparty, labourparty, associationofcommunists) --process begins variable rp,dp,cp,lp,aoc: integer range 0 to 999; begin if(switch='1') then if(republicanparty ='1') then rp:=rp+1; else null; end if;

VHDL if(democraticparty ='1') then dp:=dp+1; else null; end if; if(conservativeparty ='1') then cp:=cp+1; else null; end if; if(labourparty ='1') then lp:=lp+1; else null; end if; if(associationofcommunists ='1') then aoc:=aoc+1; else null; end if; else null; end if; totalvotes <= rp + dp + cp + lp + aoc; end process; end evm; --process ends --architecture ends

165

VHDL

166

STIMULATION WAVEFORM : Waveform of functioning of Electronic Voting Machine

VHDL

167

DESCRIPTION :
The functionality is described by three separate if statements. Each statement describes the functionality of one or more output ports. As the three if statements are separate and they generate separate outputs, we can expect the resulting logic would be three set of separate logic. However, the main disable signal is shared between the three logics. Any operation that makes use of this signal may be shared by the other logic pieces. Along with this there is alarm disable, which is shared only by the burglar alarm logic. i.e. any operation that makes use of this signal is shared only by the burglar alarm. Constituting the program, any program in VHDL makes use of the library IEEE, which includes all the keywords required e.g. entity, port, if, end etc, using the statement use IEEE.std_logic_1164.all . Thereafter, the declaration for the input and output ports is done using entity declaration which describe external view of the entity as in this case e_security_alarms. The inputs are the signals from smoke, back_door, front_door, side_door, alarm_disable, main_disable, water_detect and outputs are taken as fire_alarm, burglar_alarm, water_alarm. Entity is the hardware abstraction of the actual hardware device. Thus , entity declaration specify the name of the entity being modeled (e_security_alarms). Following the entity declaration is the architecture declaration and more importantly architecture body. The projects architecture (a_security_alarms) body is of behavioral type of modeling. The program makes use of three if statements separately for the three outputs. And each if statement includes a message to be displayed whenever the respective alarm goes on, as given in the program.

VHDL

168

CONCLUSION
The experienced we gained by working on this project enables us to put forth the following conclusions: VHDL is one of the most advanced hardware description language, which enables us to design various digital circuits and implement them on CPLDs and FPGAs. The various features of VHDL which distinguish it from other language include: a. Easy to use waveform editor, which allows us to stimulate before implementation and have, an idea as how various signals and variables are changing during simulation. b. Use of packages in other designs by making them libraries, which helps in reduction of size of source code. c. VHDL dramatically improves productivity. You can get your projects done faster using VHDL than using your existing design methods? But probably not the first time you use it, and only if you apply VHDL is a structured manner. VHDL, like any high-level design language, is of most benefit when you use a structured, top-down approach to design. Real increases in productivity will come later, when you have climbed higher on the VHDL learning curve and have accumulated a library of reusable VHDL components. Productivity increases will also occur when you begin to use VHDL to enhance communication between team members, and take advantage of the more powerful tools for simulation and design verification that are available. While it is advisable to invest a lot of time up front in contemplating, designing and brainstorming the key to coming up with the best design is to concretely test the design by efficient test benches.

VHDL

169

REFERENCES
A VHDL Primer : J.Bhaskar The designer guide to VHDL : Peter J.Ashden www.vlsibank.com www.cnet.com

VHDL

170

PROJECT REPORT 2
SHENON FANON

VHDL

171

Contents 1 Introduction 1
1.1 Background . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1.2 The library philosophy . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

2 The Compression Algorithms 3


2.1 RLE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.1.1 Principle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.1.2 Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2 Shannon-Fano . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2.1 Principle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.2.2 Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3 Huffman . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3.1 Principle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.3.2 Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.4 Rice . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.4.1 Principle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.4.2 Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.5 Lempel-Ziv (LZ77) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.5.1 Principle . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 2.5.2 Implementation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Compiling 11

4 Library API Reference 12


4.1 RLE_Compress . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.2 RLE_Uncompress . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.3 SF_Compress . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.4 SF_Uncompress . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.5 Huffman_Compress . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.6 Huffman_Uncompress . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.7 Rice_Compress . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.8 Rice_Uncompress . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.9 LZ_Compress . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 4.10 LZ_CompressFast . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

VHDL

172

4.11 LZ_Uncompress . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

Introduction
Background
The Basic Compression Library is a set of open source implementations of several well known lossless compression algorithms, such as Huffman and RLE, written in portable ANSI C. The library itself is not intended to serve as a competitor to advanced general purpose compression tools, but rather as a reference or a set of building blocks for custom compression algorithms. An example of a field where customized compression algorithms can be be useful is the compression of digitized media (such as images or audio), for which you usually have lots of apriori information, and can tailor an efficient method based on entropy reduction (e.g. differentiation) followed by simple entropy coding (e.g. Huffman coding). In many cases entropy reduction results in data that is NOT easily compressed with advanced dictionary based general purpose entropy coders, such as gzip or bzip2, since data often becomes very noisy after entropy reduction. Even a simple Huffman coder can give better compression results than the most advanced dictionary based coders under these circumstances.

The library philosophy


All compression algorithms are represented by a coder and a decoder (a compressor and a decompressor), often referred to as a CODEC. All coders and decoders work on preallocated memory buffers, and do not rely on any internal memory allocation or file I/O. In addition, all library functions are 100% reentrant. No data integrity checking is performed within the library (e.g. there are no CRCs stored in the compressed data streams, nor any information about the size of the uncompressed data). This kind of functionality is left to the user of the library. The entire library is written in portable ANSI C code. The code should work identically on 32-bit and

VHDL

173

64-bit architectures, and on both little endian and big endian systems (with the exception that the Rice coder/decoder imports/exports data in machine native endian format).

The Compression Algorithms


This chapter briefly explains each compression algorithm, as it has been implemented in the Basic Compression Library. For more in depth technical information, see the source code and a decent resource on compression algorithms

RLE
RLE, or Run Length Encoding, is a very simple method for lossless compression. It simply replaces repeated bytes with a short description of which byte to repeat, and how many times to repeat it. Though simple and obviously very inefficient fore general purpose compression, it can be very useful at times (it is used in JPEG compression, for instance).

Principle
An example of how a run length encoding algorithm can encode a data stream is shown in figure 2.1, where six occurrences of the symbol 93 have been replaced with three bytes: a marker byte (0 in this case), the repeat count (6), and the symbol itself (93). When the RLE decoder encounters the symbol 0, which is used as the marker byte, it will use the following two bytes to determine which symbol to output and how many times to repeat the symbol.

fig: The principle of run lenght encoding.

VHDL

174

Implementation
There are several different ways to do RLE. The particular method implemented in the Basic Compression Library is a very efficient one. Instead of coding runs for both repeating and non-repeating sections, a special marker byte is used to indicate the start of a repeating section. Non-repeating sections can thus have any length without being interrupted by control bytes, except for the rare case when the special marker byte appears in the non-repeating section (which is coded with at most two bytes). For optimal efficiency, the marker byte is chosen as the least frequent (perhaps even non-existent) symbol in the input stream. Repeating runs can be as long as 32768 bytes. Runs shorter than 129 bytes require three bytes for coding (marker + count + symbol), whereas runs longer than 128 bytes require four bytes for coding (marker + counthi|0x80 + countlo + symbol). This is normally a win in compression, and it is very seldom a loss of compression ratio compared to using a fixed coding of three bytes (which allows coding a run of 256 bytes in just three bytes). With this scheme, the worst case compression result is: outsize = 257 256 insize + 1.

Shannon-Fano
Shannon-Fano coding was invented by Claude Shannon (often regarded as the father of information theory) and Robert Fano in 1949. It is a very good compression method, but since David Huffman later improved the method (see 2.3), the original Shannon-Fano coding method is almost never used. However, it is presented here for completeness. The Shannon-Fano coding method replaces each symbol with an alternate binary representation, whose length is determined by the probability of the particular symbol. Common symbols are represented by

VHDL

175

few bits, while uncommon symbols are represented by many bits. The Shannon-Fano algorithm produces a very compact representation of each symbol that is almost optimal (it approaches optimal when the number of different symbols approaches infinite). However, it does not deal with the ordering or repetition of symbols or sequences of symbols.

Principle
I will not go into all the practical details about Shannon-Fano coding, but the basic principle is to find new binary representations for each symbol so that common symbols use few bits per symbol, while uncommon symbols use more bits per symbol. The solution to this problem is, in short, to make a histogram of the uncompressed data stream in order to find how common each symbol is. A binary tree is then created by recursively splitting this histogram in halves, where each half in each recursion should weigh as much as the other half (the weight is PNk =1 symbolcountk, where N is the number of symbols in the branch and symbolcountk is the number of occurrences of symbol k). This tree serves two purposes: 1. The coder uses the tree to find the optimal representations for each symbol. 2. The decoder uses the tree to uniquely identify the start and stop of each code in the compressed data stream: by traversing the tree from top to bottom while reading the compressed data bits, selecting branches based on each individual bit in the data stream, the decoder knows that a complete code has been read once a leaf node is reached. Let us have a look at an example to make it more clear. Figure 2.2 shows an uncompressed data stream consisting of ten bytes. Based on the symbol frequencies, the Shannon-Fano coder comes up with the Shannon-Fano tree (figure 2.4) and the accompanying coded representation (figure 2.3). As you can see, common symbols are closer to the root node (the top of the figure), thus requiring fewer bits for representation. Based on the found Shannon-Fano tree, the coder then encodes the data stream with the alternate representation, as can be seen in 2.5. The total size of the compressed data stream is 24 bits (three bytes), compared to the original 80 bits (10

VHDL

176

bytes). Of course, we would have to store the actual Shannon-Fano tree too so that the decoder is able to decode the compressed stream, which would probably make the true size of the compressed data stream larger than the input stream in this case. This is a side effect of the relatively short data set used in this example. For larger data sets, the overhead of the Shannon-Fano tree becomes negligible. As an exercise, try decoding the compressed data stream by traversing the Shannon-Fano tree from top to bottom, selecting left/right branches for each new bit in the compressed data stream. Each time a leaf node is encountered, the corresponding byte is written to the decompressed output stream, and the tree traversal starts over from the root again.

Implementation
The Shannon-Fano coder that can be found in the Basic Compression Library is a very straight forward implementation. It is mostly included here for the purpose of completeness.

Huffman
The Huffman coding method was presented by David A. Huffman, a graduate student of of Robert Fano, in 1952. Technically, it is very similar to the Shannon-Fano coder (see 2.2), but it has the nice property of being optimal in the sense that changing any of the binary codings of any of the symbols will result in a less compact representation. The only real difference between the Huffman coder and the Shannon-Fano coder is the way the binary coding tree is built: in the Shannon-Fano method, the binary tree is built by recursively splitting the histogram into equally weighted halves (i.e. top-down), while in the Huffman method, the tree is built

VHDL

177

by succesively joining the two least weighing nodes until there is only a single node left - the root node (i.e. bottom-up). Since Huffman coding has the same complexity as Shannon-Fano coding (this also holds for decoding),

VHDL

178

but always compresses better, although only slightly, Huffman coding is almost always used instead of Shannon-Fano coding in reality.

Principle
As mentioned above, the principle of the Huffman coding method is very similar to the Shannon-Fano coding method. The only difference lies in how the binary tree is built. In Huffman coding, the tree is built from the bottom up. Initially, all leaf nodes are stored in a list, containing their symbol and weight (proportional to the frequency of the specific symbol). The tree is built by successively joyning the two least weighing nodes in the list into a parent node. The parent node is assigned the sum of the weights of the two child nodes. The child nodes are removed from the list, and the parent node is added. When there is only one node left in the tree, the process stops, and the final node is the root node of the binary tree. Writing and reading the coded data stream is done in exactly the same way in Huffman coding as in Shannon-Fano coding.

Implementation
The Huffman coder that can be found in the Basic Compression Library is a very straight forward implementation. Primary flaws with this primitive implementation are: Slow bit stream implementation Maximum tree depth of 32 (the coder aborts if any code exceeds a size of 32 bits). If I am not mistaking, this should not be possible unless the input buffer is larger than 232 bytes, which is not supported by the coder anyway (max 232 1 bytes can be specified with an unsigned 32-bit integer). On the other hand, there are a few advantages of this implementation: The Huffman tree is stored in a very compact form, requiring only 10 bits per symbol on average (for 8 bit symbols), meaning a maximum of 320 bytes overhead. The code should be fairly easy to follow. The Huffman coder does quite well in situations where the data is noisy, in which case most dictionary based coders run into problems.

VHDL

179

Rice
For data consisting of large words (e.g. 16 or 32 bits) and mostly low data values, Rice coding can be very successful at achieving a good compression ratio. This kind of data is typically audio or high dynamic range images that has been pre-processed with some kind of prediction (such as delta to neighboring samples). Although Huffman coding should be optimal for this kind of data, it is not a very suitable method due to several reasons (for instance, a 32-bit word size would require a 16 GB histogram buffer to encode the Huffman tree). Therefor a more dynamic approach is more appropriate for data that consists of large words.

Principle
The basic idea behind Rice coding is to store as many words as possible with less bits than in the original representation (just as with Huffman coding). In fact, one can think of the Rice code as a fixed Huffman code (i.e. the codes are not determined by the actual statistical content of the data, but by the assumption that lower values are more common than higher values). The coding is very simple: Encode the value X with X 1 bits followed by a 0 bit.

Implementation
There are some optimizations in the Rice implementation that can be found in the Basic Compression Library: 1. The k least significant bits of each word are stored as is, and the N-k most significant bits are encoded with Rice coding. k is chosen as the average number of bits for the previous few samples in the stream. This usually makes the best use of the Rice coding, "hides" noise from the Rice coder, and does not result in very long Rice codes for signals with varying dynamic range. 2. If the rice code becomes longer than a fixed threshold, T, an alternate coding is used: output T 1 bits, followed by floor(log2(X-T)) 1 bits, and one 0 bit, followed by X-T (represented by the least significant floor(log2(X-T))-1 bits). This gives pretty efficient coding even for large values,

VHDL

180

and prevents ridiculously long Rice codes (in the worst case scenario, a single Rice code for a 32-bit word may become as long as 232 bits, or 512 MB). If the threshold is set to 4, then the following is the resulting code table:

As you can see, only two codes result in a worse representation with the threshold method used in this implementation. The rest of the codes result in shorter or equally short codes as for standard Rice coding. 3. In the worst case scenario, the output buffer may grow by several orders of magnitude compared to the input buffer. Therefor the Rice coder in this implementation aborts if the output becomes larger than the input by simply making a copy of the input buffer to the output buffer, with a leading zero byte (making the output at most one byte larger than the input).

VHDL

181

Lempel-Ziv (LZ77)
There are many different variants of the Lempel-Ziv compression scheme. The Basic Compression Library has a fairly straight forward implementation of the LZ77 algorithm (Lempel-Ziv, 1977) that performs very well, while the source code should be quite easy to follow. The LZ coder can be used for general purpose compression, and performs exceptionally well for compressing text. It can also be used in combination with the provided RLE and Huffman coders (in the order: RLE, LZ, Huffman) to gain some extra compression in most situations.

Principle
The idea behind the Lempel-Ziv compression algorithm is to take the RLE algorithm a few steps further by replacing sequences of bytes with references to previous occurrences of the same sequences. For simplicity, the algorithm can be thought of in terms of string matching. For instance, in written text certain strings tend to occur quite often, and can be represented by pointers to earlier occurrences of the string in the text. The idea is, of course, that pointers or references to strings are shorter than the strings themselves. For instance, in the previous paragraph the string string is quite common, and replacing all occurrences but the first of that string with references would gain several bytes of saved storage. A string reference is typically represented by: A unique marker. An offset count. A string length. Depending on the coding scheme a reference can either have a fixed length or a variable length. The latter is often preferred since that allows the coder to trade reference size for string size (i.e. it may be worth the increased size in the reference representation if the string is long enough).

Implementation
One of the problems with LZ77 is that the algorithm requires exhaustive string matching. For every single byte in the input data stream, every previous byte in the stream has to be considered as a possible starting point for a matching string, which means that the compressor is very slow.

VHDL

182

Another problem is that it is not very easy to tune the representation of a string reference for optimal compression. For instance, one has to decide if all references and all non-compressed bytes should occur on byte boundaries in the compressed stream or not. The Basic Compression Library uses a very straight forward implementation that guarantees that all symbols and references are byte aligned, thus sacrificing compression ratio, and the string matching routines are not very optimized (there are no caches, history buffers or other similar tricks to gain speed), which means that the routines are very slow. On the other hand, the decompression routines are very simple and fast. An attempt to speed up the LZ77 coder has been made, which uses an index array that speeds up the string matching process by a fair amount. Still, it is usually slower than any conventional compression program or library.1

Compiling
There is a Makefile included for the GNU C compiler (gcc). Just run make from the src directory, and you will get a file called libbcl.a, which is a static link library that you can copy to your compilers lib directory. You may also want to copy the .h files to your compilers include directory. The library has been compiled with gcc 3.3 under Linux without any problems, and it should compile under any environment with gcc support out of the box (e.g. Windows/MinGW, Mac OS X, DOS/DJGPP, etc). To compile the Basic Compression Library with an alternate compiler, you can either change the Makefile as appropriate, or simply add the .c/.h files to your own project.

Library API Reference


All functions act on input and output buffers, which contain any kind of binary data. All sizes are given in number of bytes. The output buffer usually has to be slightly larger than the input buffer, in order to accommodate potential overhead if the input data is difficult to compress.

RLE_Compress
Syntax: _ _ outsize = RLE_Compress(in,out,insize) _ _ outsize Size of output buffer after compression in Pointer to the input buffer (uncompressed data)

VHDL

183

out Pointer to the output buffer (compressed data) insize Size of input buffer The output buffer must be able to hold insize 257 256 + 1 bytes.

RLE_Uncompress
Syntax: _ _ RLE_Uncompress(in,out,insize) _ _ in Pointer to the input buffer (compressed data) out Pointer to the output buffer (uncompressed data) insize Size of input buffer The output buffer must be able to hold the entire uncompressed data stream.

SF_Compress
Syntax: _ _ outsize = SF_Compress(in,out,insize) _ _ outsize Size of output buffer after compression in Pointer to the input buffer (uncompressed data) out Pointer to the output buffer (compressed data) insize Size of input buffer The output buffer must be able to hold insize 101 100 + 384 bytes.

SF_Uncompress
Syntax: _ _ SF_Uncompress(in,out,insize,outsize) _ _ in Pointer to the input buffer (compressed data) out Pointer to the output buffer (uncompressed data) insize Size of input buffer outsize Size of output buffer The output buffer must be able to hold outsize bytes.

Huffman_Compress
Syntax: _ _ outsize = Huffman_Compress(in,out,insize) _ _ outsize Size of output buffer after compression in Pointer to the input buffer (uncompressed data) out Pointer to the output buffer (compressed data) insize Size of input buffer The output buffer must be able to hold insize 101 100 + 320 bytes.

Huffman_Uncompress
Syntax: _ _ Huffman_Uncompress(in,out,insize,outsize) _ _ in Pointer to the input buffer (compressed data) out Pointer to the output buffer (uncompressed data)

VHDL

184

insize Size of input buffer outsize Size of output buffer The output buffer must be able to hold outsize bytes.

Rice_Compress
Syntax: _ _ outsize = Rice_Compress(in,out,insize,format) _ _ outsize Size of output buffer after compression (in bytes) in Pointer to the input buffer (uncompressed data) out Pointer to the output buffer (compressed data) insize Size of input buffer (in bytes) format Word format (see rice.h) The output buffer must be able to hold insize + 1 bytes.

Rice_Uncompress
Syntax: _ _ Rice_Uncompress(in,out,insize,outsize,format) _ _ in Pointer to the input buffer (compressed data) out Pointer to the output buffer (uncompressed data) insize Size of input buffer (in bytes) outsize Size of output buffer (in bytes) format Word format (see rice.h) The output buffer must be able to hold outsize bytes.

LZ_Compress
Syntax: _ _ outsize = LZ_Compress(in,out,insize) _ _ outsize Size of output buffer after compression in Pointer to the input buffer (uncompressed data) out Pointer to the output buffer (compressed data) insize Size of input buffer The output buffer must be able to hold insize 257 256 + 1 bytes

LZ_CompressFast
Syntax: _ _ outsize = LZ_Compress(in,out,insize,work) _ _ outsize Size of output buffer after compression in Pointer to the input buffer (uncompressed data) out Pointer to the output buffer (compressed data) insize Size of input buffer work Pointer to a temporary buffer (internal working buffer) The output buffer must be able to hold insize 257 256 + 1 bytes, and the work buffer must be able to hold insize + 65536 unsigned integers

VHDL

185

LZ_Uncompress
Syntax: _ _ LZ_Uncompress(in,out,insize) _ _ in Pointer to the input buffer (compressed data) out Pointer to the output buffer (uncompressed data) insize Size of input buffer The output buffer must be able to hold the entire uncompressed data stream.

VHDL

186

Project : Program to implement Shannon-fano algorithm This is a basic information theoretic algorithm. A simple example will be used to illustrate the algorithm:

Symbol A B C D E ---------------------------------Count 15 7 6 6 5

Encoding for the Shannon-Fano Algorithm:

A top-down approach 1. Sort symbols according to their frequencies/probabilities, e.g., ABCDE. 2. Recursively divide into two parts, each with approx. same number of counts.

Symbol Count log(1/p) Code Subtotal (# of bits)

VHDL

187

------ ----- -------- --------- -------------------A 15 1.38 00 30 B 7 2.48 01 14 C 6 2.70 10 12 D 6 2.70 110 18 E 5 2.96 111 15 TOTAL (# of bits): 89 */ #include< stdio.h> #include< conio.h> #include< string.h> struct node { char sym[10]; float pro; int arr[20]; int top; }s[20]; typedef struct node node; void prints(int l,int h,node s[]) { int i; for(i=l;i< =h;i++) { printf("\n%s\t%f",s[i].sym,s[i].pro); }

VHDL

188

} void shannon(int l,int h,node s[]) { float pack1=0,pack2=0,diff1=0,diff2=0; int i,d,k,j; if((l+1)==h || l==h || l>h) { if(l==h || l>h) return; s[h].arr[++(s[h].top)]=0; s[l].arr[++(s[l].top)]=1; return; } else { for(i=l;i< =h-1;i++) pack1=pack1+s[i].pro; pack2=pack2+s[h].pro; diff1=pack1-pack2; if(diff1< 0) diff1=diff1*-1; j=2; while(j!=h-l+1) { k=h-j; pack1=pack2=0; for(i=l;i< =k;i++) pack1=pack1+s[i].pro; for(i=h;i>k;i--)

VHDL

189

pack2=pack2+s[i].pro; diff2=pack1-pack2; if(diff2< 0) diff2=diff2*-1; if(diff2>=diff1) break; diff1=diff2; j++; } k++; for(i=l;i< =k;i++) s[i].arr[++(s[i].top)]=1; for(i=k+1;i< =h;i++) s[i].arr[++(s[i].top)]=0; shannon(l,k,s); shannon(k+1,h,s); } } void main() { int n,i,j; float x,total=0; char ch[10]; node temp; clrscr(); printf("Enter How Many Symbols Do You Want To Enter\t: "); scanf("%d",&n); for(i=0;i< n;i++) {

VHDL

190

printf("Enter symbol %d ---> ",i+1); scanf("%s",ch); strcpy(s[i].sym,ch); } for(i=0;i< n;i++) { printf("\n\tEnter probability for %s ---> ",s[i].sym); scanf("%f",&x); s[i].pro=x; total=total+s[i].pro; if(total>1) { printf("\t\tThis probability is not possible.Enter new probability"); total=total-s[i].pro; i--; } } s[i].pro=1-total; for(j=1;j< =n-1;j++) { for(i=0;i< n-1;i++) { if((s[i].pro)>(s[i+1].pro)) { temp.pro=s[i].pro; strcpy(temp.sym,s[i].sym); s[i].pro=s[i+1].pro; strcpy(s[i].sym,s[i+1].sym); s[i+1].pro=temp.pro; strcpy(s[i+1].sym,temp.sym);

VHDL

191

} } } for(i=0;i< n;i++) s[i].top=-1; shannon(0,n-1,s); printf("---------------------------------------------------------------"); printf("\n\n\n\tSymbol\tProbability\tCode"); for(i=n-1;i>=0;i--) { printf("\n\t%s\t%f\t",s[i].sym,s[i].pro); for(j=0;j< =s[i].top;j++) printf("%d",s[i].arr[j]); } printf("\n---------------------------------------------------------------"); getch(); } /********************* OUTPUT ************************** Enter How Many Symbols Do You Want To Enter : 6 Enter symbol 1 ---> a Enter symbol 2 ---> b Enter symbol 3 ---> c Enter symbol 4 ---> d Enter symbol 5 ---> e Enter symbol 6 ---> f Enter probability for a ---> 0.3

VHDL

192

Enter probability for b ---> 0.25 Enter probability for c ---> 0.20 Enter probability for d ---> 0.12 Enter probability for e ---> 0.08 Enter probability for f ---> 0.05

--------------------------------------------------------------Symbol Probability Code a 0.300000 00 b 0.250000 01 c 0.200000 10 d 0.120000 110 e 0.080000 1110 f 0.050000 1111

VHDL

193

CONCLUSION
The experienced we gained by working on this project enables us to put forth the following conclusions: VHDL is one of the most advanced hardware description language, which enables us to design various digital circuits and implement them on CPLDs and FPGAs. The various features of VHDL which distinguish it from other language include: d. Easy to use waveform editor, which allows us to stimulate before implementation and have, an idea as how various signals and variables are changing during simulation. e. Use of packages in other designs by making them libraries, which helps in reduction of size of source code. f. VHDL dramatically improves productivity. You can get your projects done faster using VHDL than using your existing design methods? But probably not the first time you use it, and only if you apply VHDL is a structured manner. VHDL, like any highlevel design language, is of most benefit when you use a structured, top-down approach to design. Real increases in productivity will come later, when you have climbed higher on the VHDL learning curve and have accumulated a library of reusable VHDL components. Productivity increases will also occur when you begin to use VHDL to enhance communication between team members, and take advantage of the more powerful tools for simulation and design verification that are available. While it is advisable to invest a lot of time up front in contemplating, designing and brainstorming the key to coming up with the best design is to concretely test the design by efficient test benches.

VHDL

194

REFERENCES
A VHDL Primer : J.Bhaskar The designer guide to VHDL : Peter J.Ashden www.vlsibank.com www.cnet.com

You might also like