Verilog

From ScienceZero
Jump to: navigation, search

Sensitivity list

  • the list is only sensitive to changes in the operation result, not the operands

Assignment

Combinational logic is implemented by Boolean circuits, where the output is a pure function of the present input only. In sequential logic the output not only depends on the present input but also on the history of the input. Sequential logic has memory while combinational logic does not.

Continuous Assignment

  • Order doesn’t matter because of concurrent execution
  • Syntax is "assign LHS = RHS" where LHS is a wire/bus and RHS is an expression
wire [8:0] sum;            // Output bus
wire [7:0] a, b;           // Input busses
wire cin;                  // Carry input
assign sum = a + b + cin;  // sum is recomputed when a, b, or cin change

Procedural Assignment

Inside an initial or always block:
sum = a + b + cin; (Blocking assignment, RHS evaluated and assigned to LHS before next statement)
RHS (Right Hand side of equation / assignment) may contain wires and regs
LHS (Left Hand side) must be a reg
Primitives or assignment may set wire values?

Wire, reg, tri

wire a;                  // Simple wire
tri [15:0] dbus;         // 16-bit tristate bus
reg [-1:4] vec;          // Six-bit register
integer imem[0:1023];    // Array of 1024 integers
reg [31:0] dcache[0:63]; // A 32-bit memory with 64 words

For, while, forever

While and forever loops must contain @(posedge clk) or @(negedge clk)


Input, inout, output

If else

Case end

Reduction operators

 & AND   &(4’b0101) = 0 & 1 & 0 & 1 = 1’b0
~& NAND
 | OR
~| NOR
 ^ XOR
~^ XNOR
^~ XNOR

Logical operations

Logical Negation      !
Logical AND          &&
Logical OR           ||
Logical Equality     ==
Logical Inequality   != 

Bitwise operations

Bitwise Negation      ~
Bitwise AND           &  
Bitwise Inclusive OR  | 
Bitwise Exclusive OR  ^
Bitwise Equivalence  ~^, ^~ 

Shifts

8'h12 << 4 = 8'h20
8'h12 >> 4 = 8'h01

Conditional ?:

CASE statement and if/else statements are recommended for inferring MUX

Replication {n{}}

{4{2'b01}} = 8'b01010101

Concatenation {,}

{2'b01, 4'hF, 1'b1, 1'b0} = 8'b01111110

Literals

  • Literal number syntax is: <size>’<signed><base><value>
    • <size> (optional) is the number of bits (default size is 32 bits)
    • <signed> (optional) is the letter s or S (default is unsigned)
    • <base> is b, o, d, h for binary, octal, decimal or hex (not case sensitive)
  • If the size does not match the number of bits in the value:
    • If the left-most bit of value is 0 or 1, the value is left-extended with 0
    • If the left-most bit of value is Z, the value is left-extended with Z
    • If the left-most bit of value is X, the value is left-extended with X
    • A signed value is not sign-extended!


Base         Symbol   Legal Values
binary       b or B   0, 1, x, X, z, Z, ?, _  
octal        o or O   0-7, x, X, z, Z, ?, _  
decimal      d or D   0-9, _  
hexadecimal  h or H   0-9, a-f, A-F, x, X, z, Z, ?, _

Examples
8'b11111111    = 255
32'hBAADF00D   = 3 131 961 357
123_456        = 123 567

Arrays

reg [3:0] name [31:0];

The above describes an array of 32 Elements each, 4 bits wide which can be assigned via behavioral Verilog code.

Blocks

Block statements are used to group statements together. XST only supports sequential blocks. Within these blocks, the statements are executed in the order listed. Parallel blocks are not supported by XST. Block statements are designated by begin and end keywords, and are discussed within examples later in this chapter.

Modules

In Verilog a design component is represented by a module. The connections between components are specified within module instantiation statements. Such a statement specifies an instance of a module. Each module instantiation statement must be given a name (instance name). In addition to the name, a module instantiation statement contains an association list that specifies which actual nets or ports are associated with which local ports (formals) of the module declaration.

All procedural statements occur in blocks that are defined inside modules. There are two kinds of procedural blocks: the initial block and the always block. Within each block, Verilog uses a begin and end to enclose the statements. Since initial blocks are ignored during synthesis, only always blocks are discussed. Always blocks usually take the following format:

always 
  begin 
  statement 
  ... 
end 

where each statement is a procedural assignment line terminated by a semicolon.

Testbench

reg clk;

initial    // clock generation
begin
  clk = 0;
  forever #10 clk = ~clk;
end 

initial
begin
    @(posedge clk);
    while(value==0) @(posedge clk);
    repeat(100) @(posedge clk);

    $stop;
    $finish;
end

Operation Size and Sign Extension

Table 4_3 Expression Bit-Widths
Expression Bit Length Comments
unsized constant 32-bit self-determined
sized constant as specified self-determined
i + j max(L(i),L(j)) context-determined
i - j max(L(i),L(j)) context-determined
i * j max(L(i),L(j)) context-determined
i / j max(L(i),L(j)) context-determined
i % j max(L(i),L(j)) context-determined
i & j max(L(i),L(j)) context-determined
j max(L(i),L(j)) context-determined
i ^ j max(L(i),L(j)) context-determined
i ^~ j max(L(i),L(j)) context-determined
~i L(i) context-determined
i == j 1-bit self-determined
i !== j 1-bit self-determined
i && j 1-bit self-determined
i || j 1-bit self-determined
i > j 1-bit self-determined
i >= j 1-bit self-determined
i < j 1-bit self-determined
i <= j 1-bit self-determined
&i 1-bit self-determined
i 1-bit self-determined
^i 1-bit self-determined
~&i 1-bit self-determined
i 1-bit self-determined
~^i 1-bit self-determined
i >> j L(i) j is self-determined
{i{j}} i*L(j) j is self-determined
i << j L(i) j is self-determined
i ? j : k Max(L(j),L(k)) j is self-determined
{i,...,j} L(i)+...+L(j) self-determined
{i {j,...,k}} /*(L(j)+...+L(k)) self-determined