=====Structural Verilog===== This is a quick introduction and reference for **Structural Verilog**. It is by no means a complete guide to Verilog, but does include everything you will need to know for the Structural Verilog portion of the class. More details are contained in the textbook. ((Appendix A)) ====General Verilog Rules==== Verilog is case-sensitive. \\ Module, wire, port, instance names, etc. cannot start with a number. \\ All lines of code must end in a semicolon '';'' except for the **endmodule** line. \\ Underscores ''_'' can be used in naming but not dashes ''-'', other punctuation, or white space.\\ Comment syntax: /* Multi line comment */ // Single line comment ====Verilog Execution==== Verilog does not operate sequentially. Meaning, it does not run through and execute each line of code as it reaches that line. Instead, as each line of Verilog is processed, the needed hardware implementation is created, its inputs and outputs are hooked up, and it is placed in the implementation. Then the following lines are processed. Only **after** all the code has been processed does the hardware begin operating. This is because Verilog is a Hardware Description Language (**HDL**). All the hardware must be described and implemented before anything can execute. ====Modules==== **Modules** look like functions in C style languages (such as C++). They have internals that are kept hidden from other modules, but are interfaced with through what is called their **port list**. A port list is a list of all the inputs and outputs for a module. Here is an example module using **Structural Verilog**: module myModule(a, b, c); output a; input b, c; wire b_not; not(b_not, b); and(a, b_not, c); endmodule **myModule** is the name of the module. You will use this when you instantiate this module from elsewhere. Instantiating a module is like making a function call in C. In Verilog, it creates an instance of that hardware. \\ **(a, b, c)** is the port list. This lists the names of the inputs and outputs for the module. This is similar to a parameter list that you would make for a function in C. \\ **output a;** declares the port a as an output. All ports and variables must have a declared type. \\ **input b, c;** declares b and c as inputs. This uses a comma separated list to declare multiple variables as the same type. All type declarations may also contain a list like this. \\ **wire b_not;** declares a wire. A wire is a connection or variable that is internal to the module. Outside module don't need it and won't have access to it. \\ ====Using Modules==== Using modules inside of other modules is very similar to making function calls in C but is instead called **instantiation**; you are making an instance of the module. Also unlike C, every instantiation requires an **instance name**. For example, if we wanted to use the module from above named **myModule** inside of another module, it would look like this: module anotherModule(a, b); input a, b; wire c; myModule foo(c, a, b); // Module Instantiation endmodule **foo** is the name of that instance of myModule. **(c, a, b)** will be hooked up to that instance of myModule's port list, just like passing arguments into a function call in C. ====Gates==== In the **myModule** example in the Modules example, there are two gates being used. The following will explain how they work: not(b_not, b); and(a, b_not, c); **not(b_not, b);** is an instance of a ''not'' gate, or an inverter. The first argument is what will be connected to its output, the second argument will be connected to its input. It would look like this: {{ :tutorials:structural_verilog:not_gate.png?nolink |}} **and(a, b_not, c);** is like the not gate, but is an ''and'' gate with two inputs. This creates a gate that would look like this: {{ :tutorials:structural_verilog:and_gate.png?nolink |}} The general rule for instantiating gates is the following, where **type** is the name of the type of gate (not, and, etc.). For gates besides the not gate (which only have one input), you can have as many inputs to a gate as you want, all separated by a comma. These same rules apply to using the ''or'' gate. type(output, inputs); If you're connecting multiple gates together, you'll have to make ''wire'' variables to connect to the output of a gate, and the input of the other gates. The variable type **output** should only be used for your module's outputs, not for simple gate outputs. ====Variables and Ports==== Within the context of this tutorial for Structural Verilog, you will only be using variables and ports of types **input**, **output**, and **wire**. Ports are the inputs and outputs declared in the module declaration. For example, in myModule (shown again here), the ports are **a**, **b**, and **c**. This is determined by the first line, ''module myModule(a, b, c);''. These ports are the only variables that should be declared are outputs or inputs. Everything should be wires. module myModule(a, b, c); output a; input b, c; wire b_not; not(b_not, b); and(a, b_not, c); endmodule ====Number Constants==== Numbers in Verilog will default to 32 bit decimal numbers if no radix (base) or bit length is given. To prevent unexpected behavior and keep your code clear, you should specify the **bit length** and **radix** of numbers that you use. The general syntax for doing so is explained in the following. 'value **** is the number of bits that the number will be. This is just a number like ''1'' or ''4''.\\ **** specifies whether the number is signed or unsigned. Use ''s'' for signed and leave blank for unsigned. (Signed numbers are in 2's complement.) For this class, you will never need to use signed numbers, so you can just forget about this part. \\ **** designates what radix or base the number is in. This is only one letter. The radix abbreviations are: ^ b | binary | ^ o | octal | ^ d | decimal | ^ h | hexadecimal | You will never use octal in this class, unless you like making things unnecessarily difficult for yourself. **value** should be replaced by the number you plan to use. All the elements inside ''<>'' are optional. Examples: 5'sb01 4'd5 4'hf 0 **5'sb01** is a signed 5 bit binary number with the value 1. \\ **4'd5** is a 4 bit unsigned decimal number with the value 5. \\ **4'hf** is a 4 bit unsigned hexadecimal number with the value 15 (F in hexidecimal). \\ **0** is a 32 bit unsigned decimal number with the value 0. That's a lot of bits just to represent zero. It's better to always specify how many bits a number needs, this will keep the code and simulations more clear and concise. This can prevent bugs that are very hard to spot. ====Buses==== Ports that hold multiple bits, known as **buses**, are easy to create and use in Verilog. They are similar to arrays in most programming languages, though the syntax is slightly different. Wires, inputs, outputs, etc. can all be made into buses. ===Declaring=== To declare a bus, provide the width of the bus directly after the type declaration. However, instead of stating the size of the bus, give the most significant bit (**MSB**) index followed by the least significant bit (**LSB**) index. The following example demonstrates how this is done: input [3:0] myBus; **input [3:0] myBus;** will create an input bus with the MSB being 3 and the LSB being 0. This has a total of 4 bits. ===Accessing=== You can access the bits in a bus individually or in a range. It uses similar syntax. Individually: myBus[3] This will access the third bit of **myBus**. This can be used to read the value in that bit or to store a value in that bit. By range: myBus[3:0] This will access all of the bits in **myBus** from bit 0 to bit 3 (4 bits total). This allows you to read or set all of those bits at once! It is very powerful and convenient! When using a bus in a TCL file, you add values onto it in the following ways. add_force myBusName {0011 0} add_force myOtherBus[0] {0 0} **add_force myBusName {0011 0}** adds the entire value ''0011'' onto myBusName all at once (at time 0).\\ **add_force myOtherBus[0] {0 0}** adds the value ''0'' onto bit 0 of myOtherBus (at time 0);.