Welcome to this continued discussion on Verilog fundamentals. In this video you will learn about Verilog data types, what they mean and how to use them, and the difference between Nets and Registers, which are the two main data types found in Verilog. Ports define the interface of a Verilog module to the outside world. Ports can be input, output, or inout. These keywords declare input, output, and bidirectional ports of a module or task. The input and inout ports are of type wire always. An output port can be configured to be of type wire, reg, wand, wor, or tri. The default is wire though. So in this example, we have an input a and outputs b and e which are going to default to wire. And then we have an output c which is a vector. The signals are enumerated so you'd have c1, c0, so on. So this two bit vector then is later defined to be a reg and that makes it different than a wire. A wire is a Net, a reg is part of the Register data type. And so this is a vector here and so you can use vectors to create bus structures in Verilog. So here's a little more detail about buses. Suppose we have this Verilog code. Module inverter with a 4-bit input a and a 4-bit output y and then all you do is assign y equals to the not of a. What kind of circuit do you think this would produce? We'd get a bank of inverters, one for every bit between the 4-bit bus a and the 4-bit bus y. In a, the bits from most significant to least our a[3], a[2], a[1], and a[0] and can be accessed individually using this nomenclature. You can also access a part of the bus by using the same kind of nomenclature. You'd represent it as a[1:0] and that would give you the last two bits of a. So this particular order that's used here is the little-endian order because the least significant bit has the smallest bit number. If it had been written a[0:3], this would be a big-endian order with the MSB accessed with the smallest bit number. Typically most code you're going to see uses little-endian. So there are two main types in Verilog, Nets and Registers. Nets represent connections between hardware elements. The most common type of net that you see is a wire. So it represents the wire connection between different elements within a circuit. Nets have to be driven continuously. They're used to wire up instantiations. So when you have modules inside of modules and so on, they're wired together using wires typically, but some kind of net. Net types include wire, wor which is a wired or, and a wired and, and also tris which help represent tri-state structures within the device. So then Registers are different from Nets. They imply they're some kind of storage. So they're going to retain the last value assigned. They're often used to represent storage elements like flip flops and latches and so on. They include the types Register or reg and integer, time, and real. Now reg is not Register, reg is part of the Register set of data types within Verilog, which include integer, time, and real as well. So integers are general purpose variables. For synthesis, they're mainly used as loop indexes, parameters and constants. They're implicitly of type reg, however, they store data as signed numbers whereas explicitly declared reg types store them as unsigned. If they hold numbers which aren't defined at compile time, their size will default to 32-bits. If they hold constants, the synthesizer will adjust them to the minimum width needed at compilation time. A reg represents storage, reg is not short for Register, they have slightly different meanings. Although a lot of times a variable that's defined as reg is going to be implemented as a Register within Verilog. Only reg type variables can be assigned to in an always block. So on the left hand side of an assignment in an an always block, that variable has to be a reg. Reg doesn't mean Register. It can be modeled as a wire or as a storage cell depending on context of the code that's being used. When used in combinational expressions and in an always block, no storage is implemented. So you might have an if then else statement in an always block that just generates logic in terms of gates and in that case you wouldn't get Registers. But when you're using it in sequential statements, if you have a beginning and an end, an if or a for or case and so on. And typically you're going to see a positive edge or a negative edge being referred to of a particular signal. Then in that case, a latch or a flip flop are going to be created. So it's important to understand port rules to prevent compilation errors. When connecting modules, inputs must be Nets, a type of wire or something similar to that. Outputs can be Nets or Registers, Inout must be Nets. The left-hand side of a procedural assignment must be of a Register type. For continuous assignments that are outside of procedural blocks, the left-hand side must be Nets, typically wires. These rules are pictured visually on the next slide. So here we kind of have a picture where we see the wire output is a Net that goes to a Net input. The reg output from the always block goes to a Net input. The wire inout is a Net tired externally to a Net inout. We'll talk more about modules and how they are structured in the next video. Other data types include, you'll see supply0, supply1, which define wires tied to a logic 0 or ground and logic 1 or power or VCC, respectively. Time is a 64-bit quantity that can be used in conjunction with the $time system task to hold simulation time. Time is not supported for synthesis, hence is used only for simulation purposes. Parameters allow constants like word length to be defined symbolically in one place. This makes it easy to change the word length later across the entire design by changing only the parameter. It's used in a fashion similar to what you use #defines for in C when you're programming in C. So now, knowing what you know about data types and vectors and parameters, assume we wanted to create this circuit. How would this be coded in Verilog? You have two input muxes together there in parallel and you want to code it in such a way that all of this logic would get generated concurrently. Here's the code for the previous schematic. The parameter n = 2 would be n equals 8, 16, 32 or whatever. This then could be expanded from two 2-bit muxes to 32 2-bit Muxes by the change of just one parameter. Note the use of the replication operator here to create a bus. So that's this operator over here within the double braces. This can also be done with a concatenation operator. So you could use that in order to combine a bunch of signals in order to create a bus. The outputs formed by use of bitwise not, and, and or operators, so you see here, that in the output assignment statement. Note that the order of these assignments does not matter as the assignments are assumed to occur concurrently. So this is a concept that's a little different in hardware description languages as opposed to software languages. Here we've got two different statements. They don't happen one and then the other. They're assumed to happen at the same time and they get simulated that way. We could list the output assignment first and the resulting circuit would still be the same. This is not the case for procedural type of an assignment statement within an always block. In those cases, the order oftentimes is going to matter so you have to be careful with the order of statements. When you're outside the always block, these are continuous assignment statements. They're assumed to be concurrent and the order doesn't matter. So to summarize, in this video you have learned what the Verilog data types are, what they mean, how to use them, how to use parameters. How to make buses, and how to use parameters to change the width of buses in one place, and the difference between Nets, or wires, and Registers, which represent storage.