Ok, I'd like to start giving Verilog lessons on the list. As this goes along, we can clear up questions people have and turn them into formal lessons on the wiki. Perhaps we can turn this into a book under Creative Commons and perhaps sell a dead tree version for fund-raising. But I'm getting ahead of myself. :)
I'd hate to bias this too much towards the semantics of Verilog, but it's kinda hard to avoid it. What matters is the semantics of the hardware and how to get that to happen given the particular language. VHDL also translates into hardware, so although some of the semantics are different, they aren't at all alien. So what I want to do is teach HDL-based digital circuit design, using Verilog as a means of expression. Picking something out of a hat, I thought today, it would be good to start by discussing nothing but signals. Signals are binary digital numbers. They're wires that go between logic gates. They carry information without performing any computation. Signals are very important for transporting data, and they underlie everything else that we'll do. The most basic kind of signal is the "wire". The wire is used for continuous assignment. That is, if you have an expression, you can associate the result of that expression with a named wire, and then you can use that wire name in another expression. It's a lot like a variable, but you cannot reassign it. The value of the wire is directly a function of what's assigned to it, and you can only assign one thing. Here's a single-bit wire: wire a; You can assign some other signal, say 'b', to it, like this: assign a = b; Or you can define and assign it in the same statement: wire a = b; You can have multi-bit wires: wire [3:0] c; A multi-bit wire is also called a "bus". And assign to them just the same: wire [3:0] d; assign c = d; The range of bits in a wire can any two numbers. That is, these are also valid: wire [11:4] e; wire [0:255] f; Given a wire, you can select individual bits, which is to say that you can pick out a bit from a vector of bits: wire g; assign g = f[2]; // assign bit 2 of f to g; The bit-select can be variable: wire [7:0] h; wire i = f[h]; You can do bit slices, but the range must be constants: wire [3:0] j = e[7:4]; You can also have arrays of wires (in most dialects of Verilog): wire [7:0] k [0:20]; // An array of twenty-one 8-bit busses There's another kind of signal element called a "reg". A reg is assigned in behavioral code, which we'll explain later. A reg will be much like a wire for behavioral code that is combinatorial, or it will correspond to a physical register (a flip-flop or group of flip-flops) in synchronous logic. Regs are defined similarly to wires: reg [3:0] m; reg [0:100] n; They can be treated just like wires on the right-hand-side of an expression: wire [1:0] p = m[2:1]; You can also have arrays of regs, which we usually refer to as a RAM: reg [7:0] q [0:15]; // 16-entry memory of 8-bit words One other sometimes useful kind of signal is the integer. It's like a reg, but it's fixed at 32 bits and is the only signed datatype. integer loop_count; Verilog allows you to group logic into blocks. A block of logic is called a "module". Modules have inputs and outputs that behave very much like wires. Modules first list their ports: module my_module_name (port_a, port_b, w, z, y, z); And then define the directions of their ports: input port_a; output [6:0] port_b; input [0:4] w; inout y; // bidirectional signal, mostly used on external pins Later, we'll see that you can override the wire-ness of an output for behavioral logic by also declaring it to be a reg: output [3:0] z; reg [3:0] z; Now we can treat inputs like wires: wire r = w[1]; And make continuous assignments to outputs: assign port_b = h[6:0]; The last kind of 'signal' we'll talk about in this lesson is the constant sort of signal, which is to say a number: wire [12:0] s = 12; // 32-bit decimal that gets truncated wire [3:0] t = 4'b0101; // explicitly sized 4-bit binary wire [63:0] u = 64'hdeadbeefcafebabe; // 64-bit hex If you don't specify a size, it's 32 bits, which can cause problems for larger-sized bit vectors. These numbers are just like any sort of number, which can be used in an expression. Skipping ahead to math, for instance, you can add 1 to a number: wire [3:0] aa; wire [3:0] bb; assign bb = aa + 1; [I haven't decided if I want to discuss the 'parameter' here.] _______________________________________________ Open-graphics mailing list [email protected] http://lists.duskglow.com/mailman/listinfo/open-graphics List service provided by Duskglow Consulting, LLC (www.duskglow.com)
