Sidhartha Sankar Rout - Home



5410200-352425Summer Training(03rd Aug, 2011 to 23rd Aug, 2011)FPGA Programming using Verilog HDL LanguageTraining ManualConducted by:BHUBANESWAR INSTITUTE OF TECHNOLOGYInfovalley, Harapur, Bhubaneswar, Orissa - 752054, IndiaPh - ?+91-674-2113498, Fax - +91-674-2113497, Email: info@bit.edu.in Website: bit.edu.in Training CoordinatorEr. Sidhartha Sankar RoutLecturer,ECE Department,BIT, Bhubaneswar Dedicated to, ~~~Maa~~~Contents:Acknowledgement……………………………. p.5Course Objective………………………………. p.6ISE 10.1………………………………………... p.07 to p.22Verilog Programming Language………............. p.23 to p.61Function and Task………………………........... p.61 to p.64Modeling Finite State Machine……………….. p.64 to p.67Writing Test Benches…………………………. p.67 to p.73Basics of FPGA……………………………….. p.74 to p.75Acknowledgement We convey our heartiest gratitude to Prof. Rabi N Mahapatra (Chairman, BIT) for his words of inspiration. He willingly extracted time from his busy schedule while helping us technically by providing esteemed tutorials (of his own that he uses to teach undergraduates of Texas A&M Univ., USA) regarding FPGA programming. We are highly thankful to Mr. Arun Prusty (H.O.D, ECE Dept, BIT) and the system support team for their full time support in configuring ISE and ADEPT to all the systems. The successful design of this training manual would not have happened without the full time endeavor of Mr. Prabhas Nanda (Placement & Training Officer). We tried our level best in designing an error free manual for the trainees. We welcome everyone’s feedback regarding improvement of this manual. Sidhartha Sankar Rout Lecturer, ECE Dept, BIT. Dharanidhar Dang Lecturer, ECE Dept, BIT.COURSE OBJECTIVECreate and implement designs by using the ISE software design environment and Basys-2 Spartan3E FPGA board.Verilog code for synthesisFunctions and TasksCreating Finite State Machine (FSM) by using Verilog Verilog test fixtures for simulation Introduction to FPGA Project Work 1. ISE 10.1 Before you start using the FPGA board you will have to be familiar with ISE 10.1.It would lead you to create, verify and implement logic on FPGA board.This tutorial contains the following sections:? “Getting Started”? “Create a New Project”? “Create an HDL Source”? “Design Simulation”? “Create Timing Constraints”? “Implement Design and Verify Constraints”? “Reimplement Design and Verify Pin Locations”? “Download Design to the Spartan?-3 Demo Board”For an in-depth explanation of the ISE design tools, see the ISE In-Depth Tutorial on theXilinx? web site at: GETTING STARTEDStarting the ISE SoftwareTo start ISE, double-click the desktop icon,230505049530or start ISE from the Start menu by selecting:Start → All Programs →Xilinx ISE Design Suite 10.1→ISE→ Project NavigatorAccessing HelpAt any time you can access online help for additional information about the ISE software and related tools. To open Help, do either of the following:Press F1 to view Help for the specific tool or function that you have selected or highlighted.Launch the ISE Help Contents from the Help menu. It contains information about creating and maintaining your complete design flow in ISE.247650622301.2 CREATE A NEW PROJECTCreate a new ISE project which will target the FPGA device. To create a new project:Select File > New Project... The New Project Wizard appears.Type tutorial (any Project name) in the Project Name field.Enter or browse to a location (directory path) for the new project. A tutorial subdirectory is created automatically.Verify that HDL is selected from the Top-Level Source Type list.Click Next to move to the device properties page.Fill in the properties in the table as shown below:Product Category: AllFamily: Spartan3EDevice: XC3S100EPackage: CP132Speed Grade: -5Top-Level Source Type: HDLSynthesis Tool: XST (VHDL/Verilog)Simulator: ISE Simulator (VHDL/Verilog)Preferred Language: Verilog Verify that Enable Enhanced Design Summary is selected.Leave the default values in the remaining fields.When the table is complete, your project properties will look like the following:1905008890Click Next to proceed to the Create New Source window in the New Project Wizard. At the end of the next section, your new project will be complete.1.3 CREATE AN HDL SOURCEIn this section, you will create the top-level HDL file for your design. Determine the language as Verilog to use for the tutorial. Create the top-level Verilog source file for the project as follows:Click New Source in the New Project dialog box.Select Verilog Module as the source type in the New Source dialog box.Type in the file name counter.Verify that the Add to Project checkbox is selected.Click Next.Declare the ports for the counter design by filling in the port information as shown below:314325148590Click Next, then Finish in the New Source Information dialog box to complete the new source file template.Click Next, then Next, then Finish.The source file containing the counter module displays in the Workspace, and the counter displays in the Sources tab, as shown below:-95250Using Language Templates (Verilog)The next step in creating the new source is to add the behavioral description for counter. Use a simple counter code example from the ISE Language Templates and customize it for the counter design.Place the cursor on the line below the output [3:0] COUNT_OUT; statement. Open the Language Templates by selecting Edit → Language Templates…You can tile the Language Templates and the counter file by selecting Window → Tile Vertically to make them both visible.Using the “+” symbol, browse to the following code example:Verilog → Synthesis Constructs → Coding Examples → Counters → Binary → Up/Down Counters → Simple CounterWith Simple Counter selected, select Edit → Use in File. This step copies the template into the counter source file.Close the Language Templates.Final Editing of the Verilog SourceTo declare and initialize the register that stores the counter value, modify the declaration statement in the first line of the template as follows:replace “reg [<upper>:0] <reg_name>;” with “reg [3:0] count_int = 0;”Customize the template for the counter design by replacing the port and signal name.replace all occurrences of <clock> with CLOCKreplace all occurrences of <up_down> with DIRECTIONreplace all occurrences of <reg_name> with count_intAdd the following line just above the endmodule statement to assign the register value to the output port:assign COUNT_OUT = count_int;Save the file by selecting File → Save.When you are finished, the code for the counter will look like the following:module counter(CLOCK, DIRECTION, COUNT_OUT);input CLOCK;input DIRECTION;output [3:0] COUNT_OUT;);reg [3:0] count_int = 0;always @(posedge CLOCK)if (DIRECTION)count_int <= count_int + 1;elsecount_int <= count_int - 1;assign COUNT_OUT = count_int;endmoduleChecking the Syntax of the New Counter ModuleWhen the source files are complete, check the syntax of the design to find errors.Verify that Implementation is selected from the drop-down list in the Sources window.Select the counter design source in the Sources window to display the related processes in the Processes window.Click the “+” next to the Synthesize-XST process to expand the process group.Double-click the Check Syntax process.You must correct any errors found in your source files. You can check for errors in the Console tab of the Transcript window. If you continue without valid syntax, you will not be able to simulate or synthesize your design.Close the HDL file.1.4 DESIGN SIMULATIONCreate a test bench waveform containing input stimulus where you can verify the functionality of the counter module. The test bench waveform is a graphical view of a test bench.Create the test bench waveform as follows:Select the counter HDL file in the Sources window.Create a new test bench source by selecting Project → New Source.In the New Source Wizard, select Test Bench Waveform as the source type, and type counter_tbw in the File Name field.Click Next.The Associated Source page shows that you are associating the test bench waveform with the source file counter. Click Next.The Summary page shows that the source will be added to the project, and it displays the source directory, type, and name. Click Finish.You need to set the clock frequency, setup time and output delay times in the Initialize Timing dialog box before the test bench waveform editing window opens.The requirements for this design are the following:The counter must operate correctly with an input clock frequency = 25 MHz.The DIRECTION input will be valid 10 ns before the rising edge of CLOCK.The output (COUNT_OUT) must be valid 10 ns after the rising edge of CLOCK.The design requirements correspond with the values below.Fill in the fields in the Initialize Timing dialog box with the following information:Clock High Time: 20 ns.Clock Low Time: 20 ns.Input Setup Time: 10 ns.Output Valid Delay: 10 ns.Offset: 0 ns.Global Signals: GSR (FPGA)Note: When GSR (FPGA) is enabled, 100 ns. is added to the Offset value automatically.Initial Length of Test Bench: 1500 ns.Leave the default values in the remaining fields.Click Finish to complete the timing initialization.The blue shaded areas that precede the rising edge of the CLOCK correspond to the Input Setup Time in the Initialize Timing dialog box. Toggle the DIRECTION port to define the input stimulus for the counter design as follows:Click on the blue cell at approximately the 300 ns to assert DIRECTION high so that the counter will count up.Click on the blue cell at approximately the 900 ns to assert DIRECTION low so that the counter will count down.27622553975Save the waveform.In the Sources window, select the Behavioral Simulation view to see that the test bench waveform file is automatically added to your project.155257519685Close the test bench waveform.Simulating Design FunctionalityVerify that the counter design functions as you expect by performing behavior simulation as follows:Verify that Behavioral Simulation and counter_tbw are selected in the Sources window.In the Processes tab, click the “+” to expand the Xilinx ISE Simulator process and double-click the Simulate Behavioral Model process.The ISE Simulator opens and runs the simulation to the end of the test bench.To view your simulation results, select the Simulation tab and zoom in on the transitions.The simulation waveform results will look like the following:19050-161925Verify that the counter is counting up and down as expected.Close the simulation view. If you are prompted with the following message, “You have an active simulation open. Are you sure you want to close it?” Click Yes to continue.You have now completed simulation of your design using the ISE Simulator.1.5 CREATE TIMING CONSTRAINTSSpecify the timing between the FPGA and its surrounding logic as well as the frequency the design must operate at internal to the FPGA. The timing is specified by entering constraints that guide the placement and routing of the design. It is recommended that you enter global constraints. The clock period constraint specifies the clock frequency at which your design must operate inside the FPGA. The offset constraints specify when to expect valid data at the FPGA inputs and when valid data will be available at the FPGA outputs.Entering Timing ConstraintsTo constrain the design do the following:Select Implementation from the drop-down list in the Sources window.Select the counter HDL source file.Click the “+” sign next to the User Constraints processes group, and double-click the Create Timing Constraints process.ISE runs the Synthesis and Translate steps and automatically creates a User Constraints File (UCF). You will be prompted with the following message:19050133986Click Yes to add the UCF file to your project.The counter.ucf file is added to your project and is visible in the Sources window.The Xilinx Constraints Editor opens automatically.Note: You can also create a UCF file for your project by selecting Project → Create New Source.In the Timing Constraints dialog, enter the following in the Period, Pad to Setup, and CLock to Pad fields:? Period: 40? Pade to Setup: 10? Clock to Pad: 10Press Enter.After the information has been entered, the dialog should look like what is shown below.-15240068580Select Timing Constraints under Constraint Type in the Timing Constraints tab and the newly created timing constraints are displayed as follows:-152400190500Save the timing constraints. If you are prompted to rerun the TRANSLATE or XST step, click OK to continue.9. Close the Constraints Editor.1.6 IMPLEMENT DESIGN AND VERIFY CONSTRAINTSImplement the design and verify that it meets the timing constraints specified in the previous section.Implementing the DesignSelect the counter source file in the Sources window.Open the Design Summary by double-clicking the View Design Summary process in the Processes tab.Double-click the Implement Design process in the Processes tab.Notice that after Implementation is complete, the Implementation processes have a green check mark next to them indicating that they completed successfully without Errors or Warnings.-180975151130Post Implementation Design SummaryLocate the Performance Summary table near the bottom of the Design Summary.Click the All Constraints Met link in the Timing Constraints field to view the Timing Constraints report. Verify that the design meets the specified timing requirements.19050137160All Constraints Met ReportClose the Design Summary.Assigning Pin Location ConstraintsSpecify the pin locations for the ports of the design so that they are connected correctly on the Spartan-3E Basys-2 board.To constrain the design ports to package pins, do the following:Verify that counter is selected in the Sources window.Double-click the Floorplan Area/IO/Logic - Post Synthesis process found in the User Constraints process group. The Xilinx Pinout and Area Constraints Editor (PACE) opens.Select the Package View tab.In the Design Object List window, enter a pin location for each pin in the Loc column using the following information:? CLOCK input port connects to FPGA pin C8 (RCCLK signal on board)? COUNT_OUT<0> output port connects to FPGA pin M5 (LD0 signal on board)? COUNT_OUT<1> output port connects to FPGA pin M11 (LD1 signal on board)? COUNT_OUT<2> output port connects to FPGA pin P7 (LD2 signal on board)? COUNT_OUT<3> output port connects to FPGA pin P6 (LD3 signal on board)? DIRECTION input port connects to FPGA pin P11 (SW0 signal on board)-20002547625Select File → Save. You are prompted to select the bus delimiter type based on the synthesis tool you are using. Select XST Default <> and click OK.Close PACE.Notice that the Implement Design processes have an orange question mark next to them, indicating they are out-of-date with one or more of the design files. This is because the UCF file has been modified.1.7 REIMPLEMENT DESIGN AND VERIFY PIN LOCATIONSReimplement the design and verify that the ports of the counter design are routed to the package pins specified in the previous section. First, review the Pinout Report from the previous implementation by doing the following:Open the Design Summary by double-clicking the View Design Summary process in the Processes window.Select the Pinout Report and select the Signal Name column header to sort the signal names. Notice the Pin Numbers assigned to the design ports in the absence of location constraints.-285750-66675Reimplement the design by double-clicking the Implement Design process.Select the Pinout Report again and select the Signal Name column header to sort the signal names.Verify that signals are now being routed to the correct package pins.-333375138430Close the Design Summary.1.8 DOWNLOAD DESIGN TO THE SPARTA-3E BASYS-2 BOARDThis is the last step in the design verification process. This section provides simple instructions for downloading the counter design to the Spartan-3E Basys-2 board.Select Implementation from the drop-down list in the Sources window.Select counter in the Sources window.In the Process window, double-click the Configure Target Device process.Click OK in the following warning.85725148590Click finish on the iMPACT window857255080Now connect the Basys-2 board to the PC through the USB cable. Power on the board through the power sliding switch.Then open the Adept software.Then click “Initialize Chain”.2857564770To program a device:Click the Browse button next to the device icon in the window. An Open dialog box appears.Select the appropriate configuration file (.bit file) in the Open dialog box and click the Open button. Adept displays a history of configuration files in the drop-down list box next to the device.Click the Program button or right-click on the device icon and select Program Device.The Test Tab1905081915Adept can run simple diagnostic tests on boards so that you can verify that the board is functioning properly. To begin a test of the board, click the Start Test button. This automatically loads a diagnostic test configuration to the FPGA. The red button changes to green. You see "PASS" and "128" appear alternately on the 7-seg display. Play with the 8 switches and notice that the 8 singular LEDs on the board follow the switches. The test can be stopped any time by pressing the Stop Test button, switching to a different tab, or changing the connected device.VERILOG PROGRAMMING LANGUAGE1. INTRODUCTIONThe complexity of hardware design has grown exponentially in the last decade. The exponential growth is fueled by new advances in design technology as well as the advances in fabrication technology. The usage of Hardware Description Language (HDL) to model, simulate, synthesize, analyze, and test the design has been a cornerstone of this rapid development. Verilog HDL is a Hardware Description Language. A Hardware Description Language is a language used to describe a digital system: for example, a network switches, a microprocessor or a memory or a simple flip-flop. HDL allows the design to be simulated earlier in the design cycle in order to correct errors or experiment with different architectures. Designs described in HDL are technology-independent, easy to design and debug, and are usually more readable than schematics, particularly for large circuits. One may describe a digital system at several levels. For example, an HDL might describe the layout of the wires, resistors and transistors on an Integrated Circuit (IC) chip, i.e., the switch level. Or, it might describe the logical gates and flip flops in a digital system, i.e., the gate level. An even higher level describes the registers and the transfers of vectors of information between registers. This is called the Register Transfer Level (RTL). Verilog supports all of these levels.1.1 WHAT IS VERILOG?Verilog is one of the two major Hardware Description Languages (HDL) used by hardware designers in industry and academia. VHDL is the other one. The industry is currently split on which is better. Many feel that Verilog is easier to learn. Verilog is very C-like and liked by electrical and computer engineers as most learn the C language in college. VHDL is very Ada-like and most engineers have no experience with Ada.Verilog was introduced in 1985 by Gateway Design System Corporation, now a part of Cadence Design Systems. Until May, 1990, with the formation of Open Verilog International (OVI), Verilog HDL was a proprietary language of Cadence. Cadence was motivated to open the language to the Public Domain with the expectation that the market for Verilog HDL-related software products would grow more rapidly with broader acceptance of the language. Verilog HDL allows a hardware designer to describe designs at a high level of abstraction such as at the architectural or behavioral level as well as the lower implementation levels (i.e., gate and switch levels) leading to Very Large Scale Integration (VLSI) Integrated Circuits (IC) layouts and chip fabrication. A primary use of HDLs is the simulation of designs before the designer must commit to fabrication. 1.2 WHY USE VERILOG HDL?Digital systems are highly complex. At their most detailed level, they may consist of millions of elements, i.e., transistors or logic gates. Therefore, for large digital systems, gate-level design is dead. For many decades, logic schematics served as the bridge language of logic design, but not anymore. Today, hardware complexity has grown to such a degree that a schematic with logic gates is almost useless as it shows only a web of connectivity and not the functionality of design.Since the 1970s, Computer engineers and electrical engineers have moved toward hardware description languages (HDLs). The most prominent modern HDLs in industry are Verilog and VHDL. Verilog is the top HDL used by over 10,000 designers at such hardware vendors as Sun Microsystems, Apple Computer and Motorola. The Verilog language provides the digital designer with a means of describing a digital system at a wide range of levels of abstraction and at the same time provides access to computer-aided design tools to aid in the design process at these levels. Verilog allows hardware designers to express their design with behavioral constructs, deterring the details of implementation to a later stage of design. An abstract representation helps the designer explore architectural alternatives through simulations and to detect design bottlenecks before detailed design begins. Computer-aided-design tools, i.e., programs, exist which will “compile” programs in the Verilog notation to the level of circuits consisting of logic gates and flip flops. One could then go to the lab and wire up the logical circuits and have a functioning system. And, other tools can “compile” programs in Verilog notation to a description of the integrated circuit masks for very large scale integration (VLSI). Verilog also allows the designer to specific designs at the logical gate level using gate constructs and the transistor level using switch constructs. Verilog allows engineers to optimize the logical circuits and VLSI layouts to maximize speed and minimize area of the VLSI chip.1.3 HIERARCHICAL MODELING CONCEPTSBefore we discuss the details of the Verilog language, we must first understand basic hierarchical modeling concepts in digital design. Design MethodologiesThere are two basic types of digital design methodologies: a top-down design methodology and a bottom-up design methodology. In a top-down design methodology, we define the top-level block and identify the sub-blocks necessary to build the top-level block. We further subdivide the sub-blocks until we come to leaf cells, which are the cells that cannot further be divided. Figure 1-1 shows the top-down design process.Figure 1-1. Top-down Design MethodologyIn a bottom-up design methodology, we first identify the building blocks that are available to us. We build bigger cells, using these building blocks. These cells are then used for higher-level blocks until we build the top-level block in the design. Figure 1-2. Bottom-up Design Methodology Typically, a combination of top-down and bottom-up flows is used. Design architects define the specifications of the top-level block. Logic designers decide how the design should be structured by breaking up the functionality into blocks and sub-blocks. At the same time, circuit designers are designing optimized circuits for leaf-level cells. They build higher-level cells by using these leaf cells. The flow meets at an intermediate point where the switch-level circuit designers have created a library of leaf cells by using switches, and the logic level designers have designed from top-down until all modules are defined in terms of leaf cells.2. VERILOG FOR DESCRIPTION2.1 MODULE DEFINITIONVerilog provides the concept of a module. A module is the basic building block in Verilog. A module can be an element or a collection of lower-level design blocks. Typically, elements are grouped into modules to provide common functionality that is used at many places in the design. A module provides the necessary functionality to the higher-level block through its port interface (inputs and outputs), but hides the internal implementation. This allows the designer to modify module internals without affecting the rest of the design. Modules communicate with the outside world through input, output and bi-directional (inout) ports. In Verilog, a module is declared by the keyword module. A corresponding keyword endmodule must appear at the end of the module definition. Each module must have a module_name, which is the identifier for the module, and a port list, which describes the input and output terminals of the module. Design functionality is implemented inside module, after port declaration. The design functionality implementation part is represented as “body” here.3067050302260-133350302260Syntax:30670504445030670501397003067050196215Example:3200400190501MATenabledata[3:0]all_zeroresult[3:0] status[1:0]module MAT (enable, data, all_zero, result, status);input enable; // scalar inputinput [3:0] data; // vector inputoutput all_zero; // scalar outputoutput [3:0] result; // vector output438150119380LSBMSBInout [1:0] status // bi-directional port ……endmoduleTo make code easy to read, use self-explanatory port names. For the purpose of conciseness, use short port names. In vector port declaration, MSB can be smaller index. For e.g. output [0:3] result (result[0] is the MSB)2.1.1 THE MODULE NAMEThe module name, formally called an identifier serves documentation purpose. Based on this in your module names you should use such noun phrases that best describes what the system is doing. Each identifier in Verilog, including module names must follow these rules:It can be composed of letters, digits, dollar sign ($), and underscore characters (_) only.It must start with a letter or underscore.No spaces are allowed inside an identifier.Upper and lower case characters are distinguished (Verilog is case sensitive)Reserved keywords cannot be used as identifiers.Ex: Counter_4Bit, ALU, Receiver, UART_Transmit2.1.2 PORTSPorts provide a means for a module to communicate through input and output. Every port in the port list must be declared as input, output or inout, in the module. All ports declared as one of the above is assumed to be a wire by default, to declare it otherwise it is neccessary to declare it again. For example in the D-type flip flop we want the ouput to hold on to its value until the next clock edge so it has to be a register.module d_ff(q, d, reset, clock);output q; // all ports must be declaredinput d, reset, clock; // as input or outputreg q; // the ports can be declared again as required.Note: by convention, outputs of the module are always first in the port list. This convention is also used in the predefined modules in Verilog.Input ports:In an inner module inputs must always be of a net type, since values will be driven into them. In the outer module the input may be a net type or a reg.Output ports:In an inner module outputs can be of a net type or a reg. In an outer module the output must be of a net type since values will be driven into them by the inner module.Inout ports:Inouts must always be of a net type.Port Matching:When calling a module the width of each port must be the same, eg, a 4-bit register cannot be matched to a 2-bit register. However, output ports may remain unconnected, by missing out their name in the port list. This would be useful if some outputs were for debugging purposes or if some outputs of a more general module were not required in a particular context. However input ports cannot be omitted.For example:d_ff dff0( , d, reset, clock); // the output (q) has been omitted// the comma is ESSENTIAL2.2 ONE LANGUAGE, MANY CODING STYLES0-10410825MATenabledata[3:0]all_zeroresult[3:0] status[1:0]Verilog is both a behavioral and a structural language. Internals of each module can be defined at four levels of abstraction, depending on the needs of the design. The module behaves identically with the external environment irrespective of the level of abstraction at which the module is described. The internals of the module are hidden from the environment. Thus, the level of abstraction to describe a module can be changed without any change in the environment.2.2.1 BEHAVIORAL OR ALGORITHMIC LEVELThis is the highest level of abstraction provided by Verilog HDL. A module can be implemented in terms of the desired design algorithm without concern for the hardware implementation details. Designing at this level is very similar to C programming.66675-2857566675577852.2.2 DATAFLOW LEVELAt this level, the module is designed by specifying the data flow. The designer is aware of how data flows between hardware registers and how the data is processed in the design. Here a circuit can be specified with assignment statements and can be expressed as a list of outputs and expressions that transform the input values to the desired outputs. The expressions can be based on a broad range of operators such as logical operators, bit-wise, reduction, arithmetic, conditional and concatenation operators. All of them can be applied to the assignment statements making data flow style more universal than logical equations.6667585725666753149602.2.3 GATE LEVEL or STRUCTURAL LEVELThe module is implemented in terms of logic gates and interconnections between these gates. Design at this level is similar to describing a design in terms of a gate-level logic diagram. It resembles a schematic drawing with components connected with signals. The functionality of the design is hidden inside the component. The components in structural specification can be either primitives or instantiated modules. The former ones are such simple components as gates and flip-flops (or other small scale blocks), and the latter ones can be of any complexity.A change in the value of any input signal of a component activates the component. If two or more components are activated concurrently, they will perform their actions concurrently as well.-1905066675-19050298452.2.4 SWITCH LEVELThis is the lowest level of abstraction provided by Verilog. A module can be implemented in terms of transistors, switches, storage nodes, and the interconnections between them. Design at this level requires knowledge of switch-level implementation details.Verilog allows the designer to mix and match all four levels of abstractions in a design. In the digital design community, the term register transfer level (RTL) is frequently used for a Verilog description that uses a combination of behavioral and dataflow constructs and is acceptable to logic synthesis tools. If a design contains four modules, Verilog allows each of the modules to be written at a different level of abstraction. As the design matures, most modules are replaced with gate-level implementations. Normally, the higher the level of abstraction, the more flexible and technology-independent the design. As one goes lower toward switch-level design, the design becomes technology-dependent and inflexible. A small modification can cause a significant number of changes in the design. Consider the analogy with C programming and assembly language programming. It is easier to program in a higher-level language such as C. The program can be easily ported to any machine. However, if you design at the assembly level, the program is specific for that machine and cannot be easily ported to another machine.2.3 MODULE INSTANTIATIONA module provides a template from which you can create actual objects. When a module is invoked, Verilog creates a unique object from the template. Each object has its own name, variables, parameters, and I/O interface. The process of creating objects from a module template is called instantiation, and the objects are called instances. A module can be instantiated in another module thus creating hierarchy.Syntax:Module_name Instance_name (Port_Association_List)Module instantiation consists of module_name followed by instance_name and port_association_list. Need of instance_name is, we can have multiple instance of same module in the same program. Instance name should be unique for each instance of the same module. Port_association_list shows how ports are mapped. Port mapping can be done in two different ways i.e. “Port mapping by order” and “Port mapping by name’. Let us take an example of 4-bit adder for explaining module instantiation.2990850165100module fulladd (s, c_out, ain, bin, c_in);output s, c_out;input ain, bin, c_in;assign s = (ain ^ bin) ^ c_in;assign c_out = (a & b) | (b & c_in) | (c_in & a);endmodule;Example of 4-bit adder:module fulladder_4bit(sum, cout, a, b, cin);//input output port declarationsoutput [3:0] sum;output cout;input [3:0] a, b;input cin;wire c1, c2, c3; // Instantiate four 1-bit full addersfulladd f0 (sum[0], c1, a[0], b[0], cin);fulladd f1 (sum[1], c2, a[1], b[1], c1);fulladd f2 (sum[2], c3, a[2], b[2], c2);fulladd f3 (sum[3], cout, a[3], b[3], c3);endmodule;Module for 1-bit adder is fulladd. This 1-bit adder is instantiated ‘4’ times to get functionality of 4-bit adder i.e. fulladder_4bit. Each instance of full adder has different instance name and port association list.SYNCHRODCLKDFFQCLKDFFDQSYNCCLOCKASYNCDFF1DFF2C1_ASYNCAN EXAMPLE:Figure shows an example for module instantiation. Figure shows module “SYNCHRO” which consists of 2 ‘D’ flip-flops and are connected in serial fashion. Module “SYNCHRO” has 2 input ports “ASYNC” and “CLOCK” and 1 output port “SYNC”. The first ‘D’ flip-flop has 2 inputs “ASYNC” and “CLOCK” and 1 output “C1_ASYNC”. The second ‘D’ flip-flop 2 inputs “C1_ASYNC” and “CLOCK” and 1 output “SYNC”.2.3.1 MODULE PORT CONNECTION BY ORDER333375082550Verilog Programming for DFFmodule DFF (Q, D, CLK);input D, CLK;output Q;reg Q;always @ (posedge CLK)Q <= D;endmodulemodule SYNCHRO(ASYNC,SYNC,CLOCK);input ASYNC;input CLOCK;output SYNC;wire C1_ASYNC;DFF DFF1 (C1_ASYNC, ASYNC, CLOCK);DFF DFF2 (SYNC, C1_ASYNC, CLOCK);//DFF DFF1 (ASYNC, C1_ASYNC, CLOCK);//DFF DFF2 (SYNC, C1_ASYNC, CLOCK);endmoduleHere first instance name of ‘D’ flip-flop is “DFF1” and second instance name is “DFF2”. In this module ports are connected by order. Order of ports in instantiation of DFF1 and DFF2 is same as order of ports in DFF. If the number of ports increased, then it is very difficult to do “module ports connection by order”.2.3.2 MODULE PORT CONNECTION BY NAMEModule SYNCHRO (ASYNC, SYNC, CLOCK);input ASYNC;input CLOCK;output SYNC;wire C1_ASYNC;DFF DFF1 (.D (ASYNC), .CLK (CLOCK), .Q (C1_ASYNC));DFF DFF2 (.D (C1_ASYNC), .Q (SYNC), .CLK (CLOCK));endmodule;In this module ports are connected by Name. Order of ports in instantiation of DFF1 and DFF2 is different from order of ports in DFF. In this ‘.’ Is used to represent port name followed by associated port name in small brackets i.e. “()”. Advantage of using “port connection by name” is, it is easy to port map for large number of ports in a design.Note: Always connect ports by name.Inside the same module, instance names of particular module should be different. In the same way, inside the same module, instance name of different modules should be different.For example:module A();DFF DFF1();DFFE DFF1();endmoduleIS NOT ALLOWEDAbove example shows module ‘A’ is top-level module, in that ‘2’ different modules “DFF” and “DFFE” are instantiated with same instance name “DFF1”. Since instance name is same, this is not allowed.952547625NOT ALLOWEDALLOWEDFigure shows a Design hierarchy. In this “ABC” is the top-level module. Two scenarios are shown here. In first scenario “ABC” is the top-level module and “SYNCHRO1” and “SYNCHRO2” are instance names. Under “SYNCHRO1”, “DFF1” and “DFF2” are instance names. Under “SYNCHRO2”, “DFF1” and “DFF2” are instance names. In this instance names are different at same hierarchy. Hence this is allowed in scenario-1.In second scenario “ABC” is the top-level module and “SYNCHRO1” and “SYNCHRO1” are instance names. Under “SYNCHRO1”, “DFF1” and “DFF2” are instance names. Under another “SYNCHRO1”, “DFF1” and “DFF2” are instance names. In this instance names “SYNCHRO1” and “SYNCHRO1” are same at the same hierarchy. Hence this is not allowed in scenario2Note: At the same hierarchy the instance name should not be same.2.4 LEXICOGRAPHYVerilog, like any high level language has a number of tokens like comments, operators, numbers, strings, identifiers and keywords.2.4.1 COMMENTSComments can be inserted in the code for readability and documentation. There are two ways to write comments. A one line comment starts with "//". Verilog skips from that point to the end of line. A multiple-line comment block comment starts with "/*" and ends with "*/". Multiple-line comments cannot be nested. However, one-line comments can be embedded in multiple-line comments.a = b && c; // This is a one-line comment/* This is a multiple linecomment *//* This is /* an illegal */ comment *//* This is //a legal comment */2.4.2 OPERATORSVerilog has three types of operators; they take either one, two or three operands. Unary operators appear on the left of their operand, binary in the middle, and ternary separates its three operands by two operators.clock = ~clock; // ~ is the unary bitwise negation operator, clock is the operandc = a || b; // || is the binary logical or, a and b are the operandsr = s ? t : u; // ?: is the ternary conditional operator, which// reads r = [if s is true then t else u]2.4.3 NUMBERSIntegersIntegers can be in binary ( b or B ), decimal ( d or D ), hexidecimal ( h or H ) or octal ( o or O ).Numbers are specified by1. <size>'<base><number> : for a full description2. <base><number>: this is given a default size which is machine dependant but at least 32 bits.3. <number> : this is given a default base of decimalThe size specifies the exact number of bits used by the number. For example, a 4 bit binary will have 4 as the size specification and a 4 digit hexadecimal will have 16 as the size specification since each hexadecimal digit requires 4 bits.8'b10100010 // 8 bit number in binary representation8'hA2 // 8 bit number in hexadecimal representationX and Z valuesx represents an unknown, and z a high impedance value. An x declares 4 unknown bits in hexadecimal, 3 in octal and 1 in binary. z declares high impedance values similarly.4'b10x0 // 4 bit binary with 2nd least sig. fig. unknown4'b101z // 4 bit binary with least sig. fig. of high impedance12'dz // 12 bit decimal high impedance numberNegative numbersA number can be declared to be negative by putting a minus sign in front of the <size>. It must not appear between the <size> and <base>, nor between the <base> and the number.-8'd5 // 2's compliment of 5, held in 8 bits8'b-5 // illegal syntaxUnderscoreUnderscores can be put anywhere in a number, except the beginning, to improve readability.16'b0001_1010_1000_1111 // use of underscore to improve readability8'b_0001_1010 // illegal use of underscoreRealReal numbers can be in either decimal or scientific format, if expressed in decimal format they must have at least one digit either side of the decimal point.1.83_2387.3398_30473.8e10 // e or E for exponent2.1e-93. // illegal 2.4.4 STRINGSStrings are delimited by " ... ", and cannot be on multiple lines. "hello world"; // legal string"goodbyeworld"; // illegal string2.4.5 IDENTIFIERSIdentifiers are user-defined words for variables, function names, module names, block names and instance names. Identifiers begin with a letter or underscore (Not with a number or $) and can include any number of letters, digits and underscores. Identifiers in Verilog are case-sensitive._ABC_ /* is not the same as */ _abc_2.4.6 VERILOG KEYWORDSThese are words that have special meaning in Verilog. Some examples are assign, case, while, wire, reg, and, or, nand, module etc. They should not be used as identifiers. All keywords must be in lower case2.5 DATA TYPES2.5.1 DATA VALUESValue LevelCondition in Hardware Circuits (Logic State)0Logic Zero/ False Condition/ Ground1Logic One/ True Condition/ PowerxUnknown/ UninitializedzHigh Impedance/ FloatingValues ‘x’ and ‘z’ are case insensitive.2.5.2 NETSKeywords: wire, tri, supply0, supply1Default value: zDefault size: 1 bitNets represent the continuous updating of outputs with respect to their changing inputs. For example in the figure below, c is connected to a by a not gate. If c is declared and initialized as shown, it will continuously be driven by the changing value of a, its new value will not have to be explicitly assigned to it.11430069215If the drivers of a wire have the same value, the wire assumes this value. If the drivers have different values it chooses the strongest, if the strengths are the same the wire assumes the value of unknown, ‘x’. If no driver is connected it defaults to value of ‘z’.The net types wire and tri shall be identical in their syntax and functions. A wire net can be used for nets that are driven by a single gate or continuous assignment. The tri net type can be used where multiple drivers drive a net.Supply0 and supply1 define wires tied to logic 0 (ground) and logic 1 (power), respectively.supply0 my_gnd; // equivalent to a wire assigned 0supply1 a, b;2.5.3 REGISTERSKeywords: regDefault value: xDefault size: 1 bitRegisters represent data storage elements. Registers retain value until another value is placed onto them. Do not confuse the term registers in Verilog with hardware registers built from edge-triggered flip-flops in real circuits. In Verilog, the term register merely means a variable that can hold a value. Unlike a net, a register does not need a driver. Verilog registers do not need a clock as hardware registers do. Values of registers can be changed anytime in a simulation by assigning a new value to the register. Register data types are commonly declared by the keyword reg. The default value for a reg data type is x. reg a; // single 1-bit register variablereg [7:0] b; // an 8-bit vector; a bank of 8 registers.An example of how registers are used is shown. Any object assigned within a Verilog procedural block (always and initial) must be declared as a reg data type.reg reset; // declare a variable reset that can hold its valueinitial // this construct will be discussed laterbeginreset = 1'b1; //initialize reset to 1 to reset the digital circuit.#100 reset = 1'b0; // after 100 time units reset is deasserted.endComparing reg versus wire:Comparison between reg and wire can be done through an example for multiplexure.module MUX21 (input A, B, SEL, output wire OUT1);assign OUT1 = (A & SEL) | (B & ~SEL);endmoduleOUT1 is a wire by defaultmodule MUX21 (input A, B, SEL, output reg OUT1);always @ (A, B, SEL)if (SEL)OUT1 = A;elseOUT1 = B;endmoduleOUT1 must be declared as reg2.5.4 VECTORS and ARRAYSNets or reg data types can be declared as vectors (multiple bit widths). If bit width is not specified, the default is scalar (1-bit).wire a; // scalar net variablewire [7:0] bus; // 8-bit buswire [31:0] busA,busB,busC; // 3 buses of 32-bit width.reg clock; // scalar registerreg [0:40] virtual_addr; // Vector register, virtual address 41 bits wideVectors can be declared at [high# : low#] or [low# : high#], but the left number in the squared brackets is always the most significant bit of the vector. In the example shown above, bit 0 is the most significant bit of vector virtual_addr.Vector Part Select:For the vector declarations shown above, it is possible to address bits or parts of vectors.busA[7] // bit # 7 of vector busAbusB[2:0] /* Three least significant bits of vector bus. Using busB[0:2] is illegal because the significant bit should always be on the left of a range specification. */virtual_addr[0:1] // Two most significant bits of vector virtual_addrMulti-dimensional arrays can also be declared with any number of dimensions.reg [4:0] port_id[0:7]; // Array of 8 port_ids; each port_id is 5 bits wide2.5.5 MEMORIESIn digital simulation, one often needs to model register files, RAMs, and ROMs. Memories are modeled in Verilog simply as a one-dimensional array of registers. Each element of the array is known as an element or word and is addressed by a single array index. Each word can be one or more bits. It is important to differentiate between n 1-bit registers and one n-bit register. A particular word in memory is obtained by using the address as a memory array subscript.reg mem1bit[0:1023]; // Memory mem1bit with 1K 1-bit wordsreg [7:0] membyte[0:1023]; // Memory membyte with 1K 8-bit words(bytes)membyte[511] // Fetches 1 byte word whose address is 511.2.5.6 “INTEGER”, “REAL”, AND “TIME” REGISTER DATA TYPESInteger, real, and time register data types are supported in Verilog.Integer:An integer is a general purpose register data type used for manipulating quantities. Integers are declared by the keyword integer. Although it is possible to use reg as a general-purpose variable, it is more convenient to declare an integer variable for purposes such as counting. The default width for an integer is the host-machine word size, which is implementation-specific but is at least 32 bits. Registers declared as data type reg store values as unsigned quantities, whereas integers store values as signed quantities.integer counter; // general purpose variable used as a counter.initialcounter = -1; // A negative one is stored in the counterReal:Real number constants and real register data types are declared with the keyword real. They can be specified in decimal notation (e.g., 3.14) or in scientific notation (e.g., 3e6, which is 3x106). Real numbers cannot have a range declaration, and their default value is 0. When a real value is assigned to an integer, the real number is rounded off to the nearest integer.real delta; // Define a real variable called deltainitialbegindelta = 4e10; // delta is assigned in scientific notationdelta = 2.13; // delta is assigned a value 2.13endinteger i; // Define an integer iinitiali = delta; // i gets the value 2 (rounded value of 2.13)Time:Verilog simulation is done with respect to simulation time. A special time register data type is used in Verilog to store simulation time. A time variable is declared with the keyword time. The width for time register data types is implementation-specific but is at least 64 bits. The system function $time is invoked to get the current simulation time.time save_sim_time; // Define a time variable save_sim_timeinitialsave_sim_time = $time; // Save the current simulation timeSimulation time is measured in terms of simulation seconds. The unit is denoted by s, the same as real time. However, the relationship between real time in the digital circuit and simulation time is left to the user. 2.5.7 PARAMETERSVerilog allows constants to be defined in a module by the keyword parameter. Parameters cannot be used as variables. Parameter types and sizes can also be defined.parameter port_id = 5; // Defines a constant port_idparameter signed [15:0] WIDTH; // Fixed sign and range for parameter WIDTH2.5.8 STRINGSStrings can be stored in reg. The width of the register variables must be large enough to hold the string. Each character in the string takes up 8 bits (1 byte). If the width of the register is greater than the size of the string, Verilog fills bits to the left of the string with zeros. If the register width is smaller than the string width, Verilog truncates the leftmost bits of the string. It is always safe to declare a string that is slightly wider than necessary.reg [8*18:1] string_value; // Declare a variable that is 18 bytes wideinitialstring_value = "Hello Verilog World"; // String can be stored in variable2.6 EXPRESSIONS, OPERANDS AND OPERATORSDataflow modeling describes the design in terms of expressions instead of primitive gates. Expressions, operators, and operands form the basis of dataflow modeling.2.6.1 EXPRESSIONSExpressions are constructs that combine operators and operands to produce a result.// Examples of expressions. Combines operands and operatorsa ^ baddr1[20:17] + addr2[20:17]in1 | in22.6.2 OPERANDSOperands can be any one of the data types defined in Section 2.5, Data Types. Operands can be constants, integers, real numbers, nets, registers, times, bit-select (one bit of vector net or a vector register), part-select (selected bits of the vector net or register vector), and memories or function calls.integer count, final_count;final_count = count + 1; //count is an integer operand2.6.3 OPERATORSOperators act on the operands to produce desired results. Verilog provides various types of operators. Operators can be arithmetic, logical, relational, equality, bitwise, reduction, shift, concatenation, or conditional.Operator Types and Symbols:Operator TypeOperator SymbolOperation PerformedNumber of OperandsArithmetic*multiplytwo/dividetwo+addtwo-subtracttwo%modulustwo**power (exponent)twoLogical!logical negationone&&logical andtwo||logical ortwoRelational>greater thantwo<less thantwo>=greater than or equaltwo<=less than or equaltwoEquality==equalitytwo!=inequalitytwo===case equalitytwo!==case inequalitytwoBitwise~bitwise negationone&bitwise andtwo|bitwise ortwo^bitwise xortwo^~ or ~^bitwise xnortwoReduction&reduction andone~&reduction nandone|reduction orone~|reduction norone^reduction xorone^~ or ~^reduction xnoroneShift>>Right shifttwo<<Left shifttwo>>>Arithmetic right shifttwo<<<Arithmetic left shifttwoConcatenation { }Concatenationany numberReplication { { } }Replicationany numberConditional ?:ConditionalthreeOperator Order of Precedence:-142875-31752.6.3.1 Arithmetic Operators:There are two types of arithmetic operators: binary and unary.Binary operatorsBinary arithmetic operators are multiply (*), divide (/), add (+), subtract (-), power (**), and modulus (%). Binary operators take two operands.A = 4'b0011; B = 4'b0100; // A and B are register vectorsD = 6; E = 4; F=2; // D and E are integersA * B // Multiply A and B. Evaluates to 4'b1100D / E // Divide D by E. Evaluates to 1. Truncates any fractional part.F = E ** F; //E to the power F, yields 16If any operand bit has a value x, then the result of the entire expression is x. Modulus operators produce the remainder from the division of two numbers. They operate similarly to the modulus operator in the C programming language.13 % 3 // Evaluates to 116 % 4 // Evaluates to 0-7 % 2 // Evaluates to -1, takes sign of the first operand7 % -2 // Evaluates to +1, takes sign of the first operandUnary operatorsThe operators + and - can also work as unary operators. They are used to specify the positive or negative sign of the operand. Unary + or - operators have higher precedence than the binary + or - operators.-4 // Negative 4+5 // Positive 5Negative numbers are represented as 2's complement internally in Verilog. 2.6.3.2 Logical Operators:Logical operators are logical-and (&&), logical-or (||) and logical-not (!). Operators && and || are binary operators. Operator ! is a unary operator. Logical operators always evaluate to a 1-bit value, 0 (false), 1 (true), or x (ambiguous).// Logical operationsA = 3; B = 0;A && B // Evaluates to 0. Equivalent to (logical-1 && logical-0)A || B // Evaluates to 1. Equivalent to (logical-1 || logical-0)!A // Evaluates to 0. Equivalent to not(logical-1)// UnknownsA = 2'b0x; B = 2'b10;A && B // Evaluates to x. Equivalent to (x && logical 1)// Expressions(a == 2) && (b == 3) // Evaluates to 1 if both a == 2 and b == 3 are true.// Evaluates to 0 if either is false.2.6.3.3 Relational Operators:Relational operators are greater-than (>), less-than (<), greater-than-or-equal-to (>=), and less-than-or-equal-to (<=). If relational operators are used in an expression, the expression returns a logical value of 1 if the expression is true and 0 if the expression is false. If there are any unknown or z bits in the operands, the expression takes a value x. These operators function exactly as the corresponding operators in the C programming language.// A = 4, B = 3// X = 4'b1010, Y = 4'b1101, Z = 4'b1xxxA <= B // Evaluates to a logical 0A > B // Evaluates to a logical 1Y >= X // Evaluates to a logical 1Y < Z // Evaluates to an x2.6.3.4 Equality Operators:Equality operators are logical equality (==), logical inequality (!=), case equality (===), and case inequality (!==). When used in an expression, equality operators return logical value 1 if true, 0 if false. These operators compare the two operands bit by bit, with zero filling if the operands are of unequal length. It is important to note the difference between the logical equality operators (==, !=) and case equality operators (===, !==). The logical equality operators (==, !=) will yield an x if either operand has x or z in its bits. However, the case equality operators (===, !== ) compare both operands bit by bit and compare all bits, including x and z. The result is 1 if the operands match exactly, including x and z bits. The result is 0 if the operands do not match exactly. Case equality operators never result in an x.// A = 4, B = 3// X = 4'b1010, Y = 4'b1101// Z = 4'b1xxz, M = 4'b1xxz, N = 4'b1xxxA == B // Results in logical 0X != Y // Results in logical 1X == Z // Results in xZ === M // Results in logical 1 (all bits match, including x and z)Z === N // Results in logical 0 (least significant bit does not match)M !== N // Results in logical 12.6.3.5 Bitwise Operators:Bitwise operators are negation (~), and (&), or (|), xor (^), xnor (^~, ~^). Bitwise operators perform a bit-by-bit operation on two operands. They take each bit in one operand and perform the operation with the corresponding bit in the other operand. If one operand is shorter than the other, it will be bit-extended with zeros to match the length of the longer operand. A z is treated as an x in a bitwise operation. The exception is the unary negation operator (~), which takes only one operand and operates on the bits of the single operand.-85725165100// X = 4'b1010, Y = 4'b1101// Z = 4'b10x1~X // Negation. Result is 4'b0101X | Y // Bitwise or. Result is 4'b1111X ^~ Y // Bitwise xnor. Result is 4'b1000X & Z // Result is 4'b10x0It is important to distinguish bitwise operators ~, &, and | from logical operators !, &&, ||. Logical operators always yield a logical value 0, 1, x, whereas bitwise operators yield a bit-by-bit value. Logical operators perform a logical operation, not a bit-by-bit operation.// X = 4'b1010, Y = 4'b0000X | Y // bitwise operation. Result is 4'b1010X || Y // logical operation. Equivalent to 1 || 0. Result is 1.2.6.3.6 Reduction Operators:Reduction operators are and (&), nand (~&), or (|), nor (~|), xor (^), and xnor (~^, ^~). Reduction operators take only one operand. Reduction operators perform a bitwise operation on a single vector operand and yield a 1-bit result. The logic tables for the operators are the same as shown for Bitwise Operators. The difference is that bitwise operations are on bits from two different operands, whereas reduction operations are on the bits of the same operand. Reduction operators work bit by bit from right to left. Reduction nand, reduction nor, and reduction xnor are computed by inverting the result of the reduction and, reduction or, and reduction xor, respectively.// X = 4'b1010&X //Equivalent to 1 & 0 & 1 & 0. Results in 1'b0^X //Equivalent to 1 ^ 0 ^ 1 ^ 0. Results in 1'b02.6.3.7 Shift Operators:Shift operators are right shift ( >>), left shift (<<), arithmetic right shift (>>>), and arithmetic left shift (<<<). Regular shift operators shift a vector operand to the right or the left by a specified number of bits. When the bits are shifted, the vacant bit positions are filled with zeros. Arithmetic shift operators use the context of the expression to determine the value with which to fill the vacated bits.// X = 4'b1100Y = X >> 1; //Y is 4'b0110. Shift right 1 bit. 0 filled in MSB position.Y = X << 2; //Y is 4'b0000. Shift left 2 bits.2.6.3.8 Concatenation Operator:The concatenation operator ( {, } ) provides a mechanism to append multiple operands. The operands must be sized. Unsized operands are not allowed because the size of each operand must be known for computation of the size of the result.// A = 1'b1, B = 2'b00, C = 2'b10, D = 3'b110Y = {B , C} // Result Y is 4'b0010Y = {A , B[0], C[1]} // Result Y is 3'b1012.6.3.9 Replication Operator:Repetitive concatenation of the same number can be expressed by using a replication constant. A replication constant specifies how many times to replicate the number inside the brackets ( { } ).A = 1'b1; B = 2'b00; C = 2'b10;Y = { 4{A} } // Result Y is 4'b1111Y = { 4{A} , 2{B} , C } // Result Y is 8'b11110000102.6.3.10 Conditional Operator:The conditional operator (?:) takes three operands.Usage: condition_expr ? true_expr : false_expr ;The condition expression (condition_expr) is first evaluated. If the result is true (logical 1), then the true_expr is evaluated. If the result is false (logical 0), then the false_expr is evaluated. i0 i1 s314325381002-to-1 Multiplexer, Using Logic Equations// Module 2-to-1 multiplexer using data flow. Logic equationmodule mux2_to_1 (out, i0, i1, s);// Port declarations from the I/O diagramoutput out;input i0, i1;input s;//Logic equation for outassign out = (~s & i0) | (s & i1);endmodule2-to-1 Multiplexer, Using Conditional Operators// Module 2-to-1 multiplexer using data flow. Conditional operator.module multiplexer2_to_1 (out, i0, i1, s);// Port declarations from the I/O diagramoutput out;input i0, i1;input s;assign out = s ? i1 : i0;endmodule2.7 SYSTEM TASKS AND COMPILER DIRECTIVESIn this section, we introduce two special concepts used in Verilog: system tasks and compiler directives.2.7.1 SYSTEM TASKSVerilog provides standard system tasks for certain routine operations. All system tasks appear in the form $<keyword>. System TaskDescriptionUsage$displayPrints the formatted message once when the statement is executed during simulation. A new line is automatically added at the end of its output.Exampleinitial $display(“Hello World”);Prints the string between the quotation marks with a new line added at the end of the string.$writePrints the formatted message once when the statement is executed during simulation. No newline is added at the end of its output.Exampleinitial $write(“Hello World”);Prints the string between the quotation marks with no new line added at the end of the string.$strobeIt executes after all simulation events in the current time step have executed. Prints the formatted message once when executed. This task guarantees that the printed values for the signals/variables are the final values the signals/ variables can have at that time step.Exampleinitial $strobe(“Current values of A, B and C are A=%b, B=%b, C=%b”, A, B, C);Prints A, B and C and prints their value in binary format after all simulation events in the current time step have executed.$monitorInvokes a background process that continuously monitors the signals listed, and prints the formatted message whenever one of the signals changes. A newline is automatically added at the end of its output. Only one $monitor can be active at a time.Exampleinitial $monitor(“Current values of A, B and C are A=%b, B=%b, C=%b”, A, B, C);Monitors A, B and C and prints their value in binary format whenever one of the signals (i.e A or B or C) changes its value during simulation.$timeReturns the current simulation time as a 64-bit integer.Exampleinitial $monitor(“time = %d, A = %d”, $time, A);Prints the current simulation time as a 64-bit decimal whenever $monitor gets executed.$finishFinishes a simulation and exits the simulation process.Exampleinitial $finish;$stopHalts a simulation and enters an interactive debug mode.Exampleinitial $stop;2.7.2 COMPILER DIRECTIVESCompiler Directives direct the pre-processor part of Verilog Parser or Simulator. They are not bound by modules or files. When a Simulator encounters a compiler directive, the directive remains in effect until another compiler directive either modifies it or turns it off. All compiler directives are defined by using the `<keyword> piler DirectiveDescriptionUsage‘includeFile inclusion. The contents of another Verilog source file is inserted where the ‘include directive appears.17145-1269Here the contents of ‘define.h’ are included within the ‘idu’ module.‘defineAllows a text string to be defined as a macro name.Example‘define gate_regression 1Allows ‘gate_regression’ to be substituted by 1 where ever it gets used.2.8 WHAT ARE THE TIMING CONTROL STATEMENTS IN VERILOGTiming ControlsDescription#1714513271517145552450It delays execution for a specific amount of time, ‘delay’ may be a number, a variable or an expression. Example of a procedural block using ‘#” is shown below.Here ‘(c & d)’ gets evaluated at time 0 but gets assigned to ‘a’ after 2 time units whereas gets evaluated after 3 time units and gets assigned to ‘e’ immediately.@-3048071120It delays execution until there is a transition on any one of the signals in the sensitivity list. ‘edge’ may be either a posedge or negedge. If no edge is specified then any logic transition is used. Signals here may be scalar or vector, and any data type. Example of a procedural block using ‘@’ is shown below.-3048040005Here the statement within the always block gets evaluated whenever there is a transition on ‘b’ or ‘c’.wait1714530480It delays execution until the condition evaluates as true. Example of a procedural block using ‘wait’ is shown below.171453175Here we wait for ‘a’ to be equal to 2 before evaluating ‘e’.2.9 BASIC BLOCKS2.9.1 INTRODUCTION TO PROCEDURAL CONSTRUCTSThere are two kinds of assignment, continuous and procedural. Continuous assignments can only be made to nets, or a concatenation of nets. The operands can be of any data type. If one of the operands on the right hand side (RHS) of the assignment change, as the name suggests, the net on the left hand side (LHS) of the assignment is updated. In this way values are said to be driven into nets. Continuous assignments can be used to replace gate level descriptions with a higher level of abstraction.Procedural assignments are made to reg, integer, real or time, they need updating constantly to reflect any change in the value of the operands on the RHS. Procedural blocks in Verilog are used to model both combinatorial and sequential logic. They are also used in building a test bench environment for a design. There are two types of Procedural blocks which are ‘initial’ and ‘always’.2.9.2 INITIAL BLOCKKeywords: initialAn initial block consists of a statement or a group of statements enclosed in begin... end which will be executed only once at simulation time 0. If there is more than one block they execute concurrently and independently. The initial block is normally used for initialization, monitoring, generating wave forms (eg, clock pulses) and processes which are executed once in a simulation. An example of initialization and wave generation is given below.initialclock = 1'b0; // variable initializationinitialbegin // multiple statements have to be groupedalpha = 0;#10 alpha = 1; // waveform generation#20 alpha = 0;#5 alpha = 1;end;2.9.3 ALWAYS BLOCKKeywords: alwaysAn always block is similar to the initial block, but the statements inside an always block will repeated continuously, in a looping fashion, until stopped by $finish or $stop.Note: the $finish command actually terminates the simulation where as $stop merely pauses it and awaits further instructions. Thus $finish is the preferred command unless you are using an interactive version of the simulator.One way to simulate a clock pulse is shown in the example below. module pulse;reg clock;initial clock = 1'b0; // start the clock at 0always #10 clock = ~clock; // toggle every 10 time unitsinitial #5000 $finish // end the simulation after 5000 time unitsendmodule2.10 BEHAVIORAL MODELINGThe Behavioral or procedural level statements are used to model a design at a higher level of abstraction than the other levels. They provide powerful ways of doing complex designs. However small changes n coding methods can cause large changes in the hardware generated. 2.10.1 PROCEDURAL ASSIGNMENTSProcedural assignments are assignment statements used within Verilog procedures (always and initial blocks). Only reg variables and integers (and their bit/part-selects and concatenations) can be placed left of the “=” in procedures. The right hand side of the assignment is an expression which may use any of the operator types.2.10.2 DELAY IN ASSIGNMENT (not for synthesis)In a delayed assignment Δt time units pass before the statement is executed and the left-hand assignment is made. With intra-assignment delay, the right side is evaluated immediately but there is a delay of Δt before the result is place in the left hand assignment. Delays are not supported by synthesis tools.Syntax for Procedural Assignmentvariable = expressionDelayed assignment#Δt variable = expression;Intra-assignment delayvariable = #Δt expression;2.10.3 BLOCKING ASSIGNMENTSProcedural (blocking) assignments (=) are done sequentially in the order the statements are written. A second assignment is not started until the preceding one is complete. Syntaxvariable = expression;variable = #Δt expression;grab inputs now, deliver ans. later.#Δt variable = expression;grab inputs later, deliver ans. laterExample: For simulationinitialbegina=1; b=2; c=3;#5 a = b + c; // wait for 5 units, and execute a= b + c =5.d = a; // Time continues from last line, d=5 = b+c at t=5.2.10.4 NONBLOCKING (RTL) ASSIGNMENTS RTL (nonblocking) assignments (<=), which follow each other in the code, are started in parallel. The right hand side of nonblocking assignments is evaluated starting from the completion of the last blocking assignment or if none, the start of the procedure. The transfer to the left hand side is made according to the delays. An intra-assignment delay in a non-blocking statement will not delay the start of any subsequent statement blocking or non-blocking. However normal delays will are cumulative and will delay the output.For synthesisOne must not mix “<=” or “=” in the same procedure.“<=” best mimics what physical flip-flops do; use it for “always @ (posedge clk ..) type procedures. “=” best corresponds to what c/c++ code would do; use it for combinational procedures.Syntaxvariable <= expression;variable <= #Δt expression;#Δt variable <= expression;Example: For simulationinitialbegin#3 b <= a; /* grab a at t=0 Deliver b at t=3.#6 x <= b + c; // grab b+c at t=0, wait and assign x at t=6.x is unaffected by b’s change. */The following example shows interactions between blocking and non-blocking for simulation. Do not mix the two types in one procedure for synthesis.Example: for simulation onlyinitial begina=1; b=2; c=3; x=4;#5 a = b + c; // wait for 5 units, then grab b,c and execute a=2+3.d = a; // Time continues from last line, d=5 = b+c at t=5.x <= #6 b + c; // grab b+c now at t=5, don’t stop, make x=5 at t=11.b <= #2 a; /* grab a at t=5 (end of last blocking statement).Deliver b=5 at t=7. Previous x is unaffected by b change. */y <= #1 b + c; // grab b+c at t=5, don’t stop, make y=5 at t=6.#3 z = b + c; // grab b+c at t=8 (#5+#3), make z=8 (b =5 at t=7 and c = 3) at t=8.w <= x // make w=4 at t=8. Starting at last blocking assignm.2.10.5 PROCEDURAL ASSIGNMENT GROUPSIf a procedure block contains more than one statement, those statements must be enclosed withinSequential begin - end blockParallel fork - join blockWhen using begin-end, we can give name to that group. This is called named blocks.Example: "begin-end" and "fork - join"Begin: clk gets 0 after 1 time unit, reset gets 0 after 6 time units, enable after 11 time units, data after 13 units. All the statements are executed in sequentially.Fork: clk gets value after 1 time unit, reset after 5 time units, enable after 5 time units, data after 2 time units. All the statements are executed in parallel.Sequential Statement GroupsThe begin - end keywords group several statements together and cause the statements to be evaluated in sequentially (one at a time). Any timing within the sequential groups is relative to the previous statement. Delays in the sequence accumulate (each delay is added to the previous delay). Block finishes after the last statement in the block.Parallel Statement GroupsThe fork - join keywords group several statements together and cause the statements to be evaluated in parallel (all at the same time). Timing within parallel group is absolute to the beginning of the group. Block finishes after the last statement completes (Statement with high delay, it can be the first statement in the block).2.10.6 CONTINUOUS ASSIGNMENT STATEMENTSContinuous assignment statements drive nets (wire data type). They represent structural connections. They can be used for modeling combinational logic. They are outside the procedural blocks (always and initial blocks). The left-hand side of a continuous assignment must be net data type.Syntax : assign # delay net = expression;Example: 1-bit Addermodule adder (a,b,sum,carry);input a, b;output sum, carry;assign #5 {carry,sum} = a+b;endmodule2.10.7 VARIOUS PROGRAMMING STATEMENTS USED IN VERILOGProgrammingStatementsUsageExampleif17145129540It executes the statement or statement_group if the condition evaluates as true. If we need more than one statement (i.e statement_group) then we need to use begin-end or a fork-join block. The condition here can be an expression or a single value. If the condition evaluates to ‘0’ or unknown then the condition is considered false, and if the condition evaluates to ‘1’ or more then the condition is considered true.if (alu_func == 2’b00)aluout = a + b;else if (alu_func == 2’b01)aluout = a - b;else if (alu_func == 2’b10)aluout = a & b;else // alu_func == 2’b11aluout = a | b;if (a == b) begin x = 1; ot = 4’b1111;endif-else1714541275It executes the first statement or statement_group if the condition evaluates as true and executes the second statement or statement_group if the condition evaluates as false. The condition here can be an expression or a single value. If the condition evaluates to ‘0’ or unknown then the condition is considered false, and if the condition evaluates to ‘ 1’ or more then the condition is considered true. case8382069215It compares the expression with each of the case_item’s and executes the statement or statement_group associated with the first matching case_item.It executes the default if none of the case_item’s match. Here the default case is optional. case (alu_ctr)2’b00: aluout = a + b;2’b01: aluout = a - b;2’b10: aluout = a & b;default: aluout = 1’bx; /* Treated as don’t cares for minimum logic generation. */endcasecase (x, y, z)2’b00: aluout = a + b; /*case if x or y or z is 2’b00.*/2’b01: aluout = a - b;2’b10: aluout = a & b;default: aluout = a | b;endcasecasez1460531750It is special version of case statement where ‘z’ and ‘?’ are treated as don’t cares. Similar to case statement it compares the expression with each of the case_item’s and executes the statement or statement_group associated with the first matching case_item. It executes the default if none of the case_item’s match. Here the default case is optional. casez (d)3’b1??: b = 2’b11; /* b = 11 if d = 100 or 101 or 110 or 111 */3’b01?: b = 2’b10; // b = 10 if d = 010 or 011default: b = 2’b00;endcasecasex-508079375It is special version of case statement where ‘x’, ‘z’ and ‘?’ are treated as don’t cares. Similar to case statement it compares the expression with each of the case_item’s and executes the statement or statement_group associated with the first matching case_item. It executes the default if none of the case_item’s match. Here the default case is optional. casex (a)2’b1x: msb = 1; // msb = 1 if a = 10 or a = 11/* If this were case(a) then only a=1x would match.*/default: msb = 0;endcaseforever1714531750It is an infinite loop that continuously executes the statement or statement_group. forever begin@(posedge clk); // or use a= #9 a+1;a = a + 1;endrepeatSyntaxrepeat(expression)statement or statement _groupLike forever it is a loop that executes the statement or statement _group a fixed number of times based on the expression.repeat (2) begin // after 50, a = 00,#50 a = 2’b00; // after 100, a = 01,#50 a = 2’b01; // after 150, a = 00,end// after 200, a = 01whileSyntaxwhile(condition)statement or statement_groupIt executes the statement or statement_group as long as the condition evaluates as true. while (!overflow) begin@(posedge clk);a = a + 1;endforSyntaxfor(initial_value; condition; step)statement or statement_groupThe for loop here uses three expressions separated by semicolons to control the loop. The first expression (initial_value) is executed once before entering the loop the first time. The second expression (condition) is evaluated to determine if the contents of the loop (i.e statement or statement_group) should be executed. If the loop condition expression is true, the loop is entered. The final expression (step) is evaluated at the end of the loop.for (j = 0; j <= 7; j = j + 1)beginc[j] = a[j] & b[j];d[j] = a[j] | b[j];enddisableSyntaxdisable group_name;It discontinues execution of a named group of statements.begin: accumulateforeverbegin@(posedge clk);a = a + 1;if (a == 2’b0111) disable accumulate;endend3. FUNCTION and TASKVerilog provides Functions and Tasks to allow the behavioral description of a module to be broken into more manageable parts allowing better readability and manageability. Functions and Tasks are useful for several reasons which are, they allow often used behavioral sequences to be written once and called when needed, they allow for a cleaner writing style and finally they allow data to be hidden from other parts of the design.3.1 FUNCTIONFunctions are defined in the module in which they are used. It is possible to define function in separate file and use compile directive 'include to include the function in the file which instantiates the function. Function can call other functions, but cannot call task.The following are some of the general rules for functions:Functions must contain at least one input argument and cannot drive more than one output.Functions cannot contain an inout or output declaration.Functions cannot contain time controlled statements (#, @, wait), i.e., it cannot contain delays .Function cannot include timing delays, like posedge, negedge, # delay. Which means that function should be executed in "zero" time delay.Functions must contain a statement that assigns the return value to the implicit function name register.The variables declared within the function are local to that function. The order of declaration within the function defines how the variables passed to the function by the caller are used.SyntaxFunction begins with keyword function and ends with keyword endfunction.Inputs are declared after the keyword function.function [msb:lsb] function_name;input [msb:lsb] input_arguments;reg [msb:lsb] reg_variable_list;parameter [msb:lsb] parameter_list;integer [msb:lsb] integer_list;... statements ...endfunctionExamplefunction [7:0] my_func; // function return 8-bit valueinput [7:0] i;reg [3:0] temp;integer n;temp= i[7:4] | ( i[3:0]);my_func = {temp, i[3:0]};endfunctionExample: Simple Functionfunction myfunction;input a, b, c, d;beginmyfunction = ((a+b) + (c-d));endendfunctionCalling a FunctionLet’s assume that function in above example is stored in a file called myfunction.v. Advantage of coding function in separate file is that, it can be used in multiple module's.module func_test(a, b, c, d, e, f);input a, b, c, d, e ;output f;wire f;`include "myfunction.v"assign f = (myfunction (a,b,c,d)) ? e :0;endmodule3.2 TASKTasks are used in all programming languages, generally known as procedures or sub routines. A task is similar to a function, but unlike a function it has any number input and output ports. Therefore tasks do not return values. Included in the main body of code tasks can be called many times, reducing code repetition. Tasks are defined in the module in which they are used. It is possible to define task in separate file and use compile directive 'include to include the task in the file which instantiates the task. Task can include timing delays, like posedge, negedge, # delay. The variables declared within the task are local to that task. The order of declaration within the task defines how the variables passed to the task by the caller are used. Task can call another task or function. SyntaxTask begins with keyword task and end's with keyword endtask Input and output are declared after the keyword task.Local variables are declared after input and output declaration.task task_name;input [msb:lsb] input_port_list;output [msb:lsb] output_port_list;reg [msb:lsb] reg_variable_list;parameter [msb:lsb] parameter_list;integer [msb:lsb] integer_list;... statements ...endtaskExample : Simple Tasktask convert;input [7:0] temp_in;output [7:0] temp_out;begintemp_out = (9/5) *( temp_in + 32);endendtaskExample : Task using Global Variablestask convert;begintemp_out = (9/5) *( temp_in + 32);endendtaskCalling a TaskLet’s assume that task in example “Simple Task” is stored in a file called mytask.v. Advantage of coding task in separate file is that, it can be used in multiple modules.module temp_cal (temp_a, temp_b, temp_c, temp_d);input [7:0] temp_a, temp_c;output [7:0] temp_b, temp_d;reg [7:0] temp_b, temp_d;`include "mytask.v"always @ (temp_a)convert (temp_a, temp_b);always @ (temp_c)convert (temp_c, temp_d);endmodule4. MODELING FINITE STATE MACHINE (FSM)State machine or FSM are the heart of any digital design. There are two types of state machines classified by the types of outputs generated from each. The first is the Moore State Machine where the outputs are only a function of the present state, the second is the Mealy State Machine where one or more of the outputs are a function of the present state and one or more of the inputs.Mealy Model1905027305Moore Model1905040641Modeling State machines.One thing that needs to be kept in mind when coding FSM is that, combinational logic and sequence logic should be in two different always blocks. In the above two figures, next state logic is always the combinational logic. State Registers and Output logic are sequential logic. It is very important that any asynchronous signal to the next state logic should be synchronized before feeding to FSM. Always try to keep FSM in separate Verilog file.Using constants declaration like parameter or `define to define states of the FSM, this makes code more readable and easy to manage.State Diagram.1905051435Verilog CodeFSM code should have three sections,Encoding binational part.Sequential part.Encoding StyleOne Hot Encodingparameter [1:0] IDLE = 3'b001,GNT0 = 3'b010,GNT1 = 3'b100;Binary Encodingparameter [1:0] IDLE = 2'b00,GNT0 = 2'b01,GNT1 = 2'b10;Combinational SectionThis section can be modeled using function, assign statement or using always block with case statement. For time being let’s see always block version.next_state = 3'b000case(state)IDLE : if (req_0 == 1'b1)next_state = GNT0;else if (req_1 == 1'b1)next_state= GNT1;elsenext_state = IDLE;GNT0 : if (req_0 == 1'b1)next_state = GNT0;elsenext_state = IDLE;GNT1 : if (req_1 == 1'b1) beginnext_state = GNT1;elsenext_state =1 IDLE;default : next_state = IDLEendcaseendSequential SectionThis section has be modeled using only edge sensitive logic such as always block with posedge or negedge of clock.always @ (posedge clock)begin : OUTPUT_LOGICif (reset == 1'b1) begingnt_0 <= #1 1'b0;gnt_1 <= #1 1'b0;state <= #1 IDLE;endelse beginstate <= #1 next_state;case(state)IDLE :begingnt_0 <= #1 1'b0;gnt_1 <= #1 1'b0;endGNT0 : begingnt_0 <= #1 1'b1;gnt_1 <= #1 1'b0;endGNT1 : begingnt_0 <= #1 1'b0;gnt_1 <= #1 1'b1;enddefault : begingnt_0 <= #1 1'b0;gnt_1 <= #1 1'b0;endendcaseendend5. WRITING TESTBENCHESWriting a testbench is as complex as writing the RTL code itself. These days ASICs are getting more and more complex and thus verifying these complex ASIC has become a challenge. Typically 60-70% of time needed for any ASIC is spent on verification/validation/testing. For writing testbench it is important to have the design specification of "design under test" or simply DUT. Specs need to be understood clearly and test plan is made, which basically documents the test bench architecture and the test scenarios ( test cases) in detail.Example : CounterLet’s assume that we have to verify a simple 4-bit up counter, which increments its count when ever enable is high and resets to zero, when reset is asserted high. Reset is synchronous to clock.Code for Countermodule counter (clk, reset, enable, count);input clk, reset, enable;output [3:0] count;reg [3:0] count;always @ (posedge clk)if (reset == 1'b1)count <= 0;else if ( enable == 1'b1)count <= count + 1;endmoduleTest PlanWe will write self checking test bench, but we will do this in steps to help you understand the concept of writing automated test benches. Our testbench environment will look something like shown in below figure.-1905045085DUT is instantiated in testbench, and testbench will contain a clock generator, reset generator, enable logic generator, compare logic, which basically calculate the expected count value of counter and compare the output of counter with calculated value.Test CasesReset Test : We can start with reset deasserted, followed by asserting reset for few clock ticks and deasserting the reset, See if counter sets its output to zero.Enable Test : Assert/deassert enable after reset is applied.Random Assert/deassert of enable and reset.Writing TestBenchFirst step of any testbench creation is to create a dummy template which basically declares inputs to DUT as reg and outputs from DUT as wire, instantiate the DUT as shown in code below. Note: there is no port list for the test bench.Test Benchmodule counter_tb;reg clk, reset, enable;wire [3:0] count;counter U0 (.clk (clk),.reset (reset),.enable (enable),.count (count));endmoduleNext step would be to add clock generator logic. Before we add clock generator we need to drive all the inputs to DUT to some known state as shown in code below.Test Bench with Clock genmodule counter_tb;reg clk, reset, enable;wire [3:0] count;counter U0 (.clk (clk),.reset (reset),.enable (enable),.count (count));initialbeginclk = 0;reset = 0;enable = 0;endalways#5 clk = !clk;endmoduleInitial block in verilog is executed only once, thus simulator sets the value of clk, reset and enable to 0, which by looking at the counter code (of course you will be refering to the the DUT specs) could be found that driving 0 makes all this signals disabled. There are many ways to generate clock, one could use forever loop inside an initial block as an alternate to above code. At this point, you would like test if the testbench is generating the clock correctly. You will see that simulator does not come out, or print anything on screen or does it dump any waveform. Thus we need to add support for all the above as shown in code below.Test Bench continues...module counter_tb;reg clk, reset, enable;wire [3:0] count;counter U0 (.clk (clk),.reset (reset),.enable (enable),.count (count));initialbeginclk = 0;reset = 0;enable = 0;endalways#5 clk = !clk;initialbegin$dumpfile ("counter.vcd");$dumpvars;endinitialbegin$display("\t\ttime,\tclk,\treset,\tenable,\tcount");$monitor("%d,\t%b,\t%b,\t%b,\t%d",$time, clk, reset, enable, count);endinitial#100 $finish;//Rest of testbench code after this lineendmodule$dumpfile is used for specifying the file that simulator will use to store the waveform, that can be used later to view using waveform viewer. $dumpvars basically instructs the Verilog compiler to start dumping all the signals to "counter.vcd".$display is used for printing text or variables to stdout (screen), \t is for inserting tab. Syntax is same as printf. Second line $monitor is bit different, $monitor keeps track of changes to the variables that are in the list (clk, reset, enable, count). Whenever anyone of them changes, it prints their value, in the respective radix specified.$finish is used for terminating simulation after #100 time units (note, all the initial, always blocks start execution at time 0).Adding Reset LogicOnce we have the basic logic to allow us to see what our testbench is doing, we can next add the reset logic, If we look at the testcases, we see that we had added a constraint that it should be possible to activate reset anytime during simulation. To achieve this we have many approaches, but we will follow something that will go long way. There is something called 'events' in Verilog, events can be triggered, and also monitored to see, if an event has occurred. Lets code our reset logic in such a way that it waits for the trigger event "reset_trigger" to happen, when this event happens, reset logic asserts reset at negative edge of clock and de-asserts on next negative edge as shown in code below. Also after de-asserting the reset, reset logic triggers another event called "reset_done_trigger". This trigger event can then be used at somewhere else in test bench to sync up.Code of reset logicevent reset_trigger;event reset_done_trigger;initial beginforever begin@ (reset_trigger);@ (negedge clk);reset = 1;@ (negedge clk);reset = 0;-> reset_done_trigger;endendAdding test case logicMoving forward, let’s add logic to generate the test cases, ok we have three testcases as in the first part of this tutorial. Lets list them again.Reset Test : We can start with reset deasserted, followed by asserting reset for few clock ticks and deasserting the reset, See if counter sets its output to zero.Enable Test : Assert/deassert enable after reset is applied.Random Assert/deassert of enable and reset.Test Case # 1 : Asserting/ Deasserting resetIn this test case, we will just trigger the event reset_trigger after 10 simulation units.initialbegin: TEST_CASE#10 -> reset_trigger;endTest Case # 2 : Asserting/ Deasserting enable after reset is applied.In this test case, we will trigger the reset logic and wait for the reset logic tocomplete its operation, before we start driving enable signal to logic 1.initialbegin: TEST_CASE#10 -> reset_trigger;@ (reset_done_trigger);@ (negedge clk);enable = 1;repeat (10) begin@ (negedge clk);endenable = 0;endTest Case # 3 : Asserting/Deasserting enable and reset randomly.In this testcase we assert the reset, and then randomly drive values on to enable and reset signal.initialbegin : TEST_CASE#10 -> reset_trigger;@ (reset_done_trigger);fork beginrepeat (10) begin@ (negedge clk);enable = $random;repeat (10) begin@ (negedge clk);reset = $random;endendendWell you might ask, are all this three test case exist in same file, well the answer is no. If we try to have all three test cases on one file, then we end up having race condition due to three initial blocks driving reset and enable signal. So normally, once test bench coding is done, test cases are coded separately and included in testbench as `include directive as shown below. If you look closely all the three test cases, you will find that, even through test case execution is not complete, simulation terminates. To have better control, what we can do is, add a event like "terminate_sim" and execute $finish only when this event is triggered. We can trigger this event at the end of test case execution. The code for $finish now could look as below.event terminate_sim;initial begin@ (terminate_sim);#5 $finish;Endand the modified test case #2 would like.initialbegin: TEST_CASE#10 -> reset_trigger;@ (reset_done_trigger);@ (negedge clk);enable = 1;repeat (10) begin@ (negedge clk);endenable = 0;#5 -> terminate_sim;endBASICS OF FPGAA Hard-Coded World – ASICASIC stands for Application Specific Integrated Circuit. ASIC design flow takes huge amount of time and hence costly. It is an IC which is designed only for a particular application; i.e., one time programmability. For Example Pentium chips (P I, P II) are ASIC chips. ASIC involves huge rework cost. Aim should be for right output from first time even in re-work cycle.A Re-programmability WorldRehearse your act as many times till perfection.Very less turnaround time involved.Can afford to commit initial mistakes.Proto-type complex systems before going to a hard coded world.Emulation platform can be developed using FPGA’s to validate designs at system level. Designs can be downloaded into an FPGA based system to validate the functionality. If any defects are encountered during the validation process the design can be fixed and verified using the same platform.What Re-programmability means to H/WSame piece of hardware.Different types of functionality.Matter of loading a new bitmap.Easy design changes.Faster development cycle.Suitable for low volume production.The same piece of hardware can be used multiple times to validate either new designs or modified (bug fixes, feature enhancement) designs. The development cycle is faster as this involves only the design and verification cycle followed by synthesis and FPGA P&R instead of the entire backend flow and fabrication of the hardware. NOTE: ASIC is cost effective for mass production & FPGA is effective for low volume production.So What’s an FPGA?Field Programmable Gate Array.Gate Array – a custum VLSI circuit consisting of huge number of unconnected gates.Circuit function determined at the field by the user.Re-programmable.Pre tested for manufacturing defects.It is:An ASIC for FPGA manufacturer.An FPGA for the es as chip ready to operate.Field Programmable means that the FPGA’s function is defined by a user’s program rather than by the manufacturer of the device. A typical integrated circuit performs a particular function defined at the time of manufacturer. In contrast, the FPGA’s function is defined by a program written by someone other than the device manufacturer. This user programmability gives the user access to complex integrated designs without the high engineering costs associated with application specific integrated circuit.The FPGA is an integrated circuit that contains many identical logic cells that can be viewed as standard components. The individual cells are interconnected by a matrix of wires and programmable switches. A user’s design is implemented by specifying the simple logic function for each cell and selectively closing the switches in the interconnected matrix. The array of logic cells and interconnects from a fabric of basic building blocks for logic circuits. Complex designs are created by combining these basic blocks to create the desired circuit.FPGA DevicesXilinx DevicesVertex SeriesVertex-5 family, Vertex-4 family, Vertex II family, Vertex familyHigh cost, Highly efficientSpartan SeriesSpartan-3A, 3E, 3 family, Spartan IIE, II family, Spartan familyLow cost, Low efficientAltera DevicesStratix SeriesStratix III family, Stratix II (GX) family, Stratix (GX) familyCyclone SeriesCyclone III family, Cyclone II family, Cyclone family ................
................

In order to avoid copyright disputes, this page is only a partial summary.

Google Online Preview   Download