verilog lecture notes

Embed Size (px)

DESCRIPTION

best document to learn verilog

Citation preview

  • Re Configurable Computing

    CS G553

    Introduction to Verilog

  • Hardware Description Languages (HDL)

    The 'capture language'often beginning with a high-level algorithmic description.

    Resemble concurrent programming languages.

    HDL design generally ends at the synthesis stage

    HDLs, 'compiler' refers to synthesis, a process of transforming the HDL code listing into a physically realizable gate netlist

    Simulation by a test bench. Even driven.

    Two widely used hardware description languages

    VHDL

    Verilog

    HDL languages can describe circuits from two perspectives

    function

    structure

    Verilog introduced by Gateway Design automation in 1985.

  • Levels of Abstraction

    Switch Level: Module implemented with switches and interconnects. Lowest level of Abstraction

    Gate Level: Module implemented in terms of logic gates and interconnection between gates

    Dataflow Level: Module designed by specifying dataflow. Designer is aware of how data flows between hardware registers and how the data is processed in the design

    Behavioral Level :Module can be implemented in terms of the desired design algorithm without concern for the hardware implementation details. Very similar to C programming.

  • Module

    Basic building block in Verilog.

    A module definition starts with the keyword module ends with the keyword endmodule

    module name (port_list)

    port declarations parameter declarations

    include directives

    variable declarations assignments low-level module instantiation initial and always blocks task and function

    End module

    Interface

    Optional add-ons

    Body

  • Ex: Module

    module toggle(q, clk, reset); endmodule

    toggle q

    clk

    reset

    The internal of each module can be defined at four levels of abstraction

    o Behavioral or algorithmic level

    o Dataflow level

    o Gate level

    o Switch level

    Verilog allows different levels of abstraction to be mixed in the same module.

  • Number specification

    Comments are designated by // to the end of a line or by /* to */ across several lines.

    specifies the

    number of bits

    in the number d or D for decimal

    h or H for hexadecimal

    b or B for binary

    o or O for octal

    Number

    depends on

    the base

    Examples: 4b1111 12habc 16d235 12h13x -6d3 12b1111_0000_1010

    X or x: dont care Z or z: high impedence

    _ : used for readability

  • Net

    Represents connections between hardware elements.

    Continuously driven by output of connected devices.

    Declared using the keyword wire.

    wire a;//Declare net a for above ckt wire b, c;//Declare two wires b,c wire d=1b0;

  • Ex: Net declaration

    Me

    mo

    ry

    Pro

    ce

    sso

    r

    r_w

    data

    addr

    wire r_w; // scalar signal

    wire [7:0] data; // vector signal

    wire [9:0] addr; // vector signal

  • Port

    Provide interface by which a module can communicate with its environment

    module fulladd4(sum, c_out, a, b, c_in); //Module with a list of ports

    module Top; // No list of ports, top-level module in simulation

    Verilog keyword

    Type of port

    input Input port

    output Output port

    inout Bi-directional

  • Ex: Port

    module DFF(q, d, clk, reset);

    output q;

    reg q;

    input d, clk, reset;

    ...

    ...

    endmodule

  • Port connection rules

    Internally, input ports must always be of the type net.

    Externally, the inputs can be connected to a variable which is a reg or a net.

    Internally, outputs ports can be of the type reg or net.

    Externally, outputs must always be connected to a net.

    Internally, inout ports must always be of the type net.

    Externally, inout ports must always be connected to a net.

    Legal to connect internal and external items of different sizes when making intermodule port connections.

    Allows ports to remain unconnected

  • Nets vs Ports

    Me

    mo

    ry

    Pro

    ce

    sso

    r

    r_w

    data[7:0]

    addr[9:0]

    clk

    rst

    status[3:0]

    i_o[7:0]

    pc module pc (clk, rst, status, i_o);

    input clk, rst;

    output [3:0] status;

    inout [7:0] i_o;

    wire r_w;

    wire [7:0] data;

    wire [9:0] addr;

    endmodule

    Nets are internal signals that cannot be accessed by outside

    environment

    Ports are external signals to interface with outside environment input ports can be read but cannot be written

    output ports can be written but cannot be read

    inout ports can be read and written

  • Register

    Registers represent data storage elements. They retain value until another value is placed

    onto them.

    In Verilog, a register is merely a variable that can hold a value.

    They do not need a clock as hardware registers do.

    reg reset; initial begin

    reset = 1b1; #100 reset=1b0;

    end

  • Register declaration

    module pc (clk, rst, status, i_o);

    input clk, rst;

    output [3:0] status;

    reg [3:0] status;

    inout [7:0] i_o;

    A register declaration starts with keyword reg. Registers can be used to describe the behaviour of

    sequential circuits

    Registers can also be used to implement registered output ports

  • Vectors

    A net or register can be declared as vectors. wire a; wire [7:0] bus; wire [31:0] busA, busB, busC; reg clock; reg [0:40] virt_address;

    Possible to address bits or parts of vectors busA[7] bus[2:0] virt_addr[0:2]

  • Real

    real delta; initial begin

    delta = 4e10; delta = 2.13;

    end integer i; initial

    i = delta;

    declared with the keyword real cannot have a range declaration default value is 0

  • Arrays

    Arrays are multiple elements that are 1-bit or n-bits wide. Possible to have arrays of type reg, integer, real Arrays of nets can also be used to connect ports of generated

    instances

    integer count[0:7]; reg [4:0] port_id[0:7]; // Array of 8 port_ids; each port_id is 5 bits wide integer matrix[4:0][0:255]; // Two dimensional array of integers

  • Memory

    Used to model register files, RAMs and ROMs. A memory component can be defined using reg variables Modeled in Verilog as a one-dimensional array of registers.

    reg mem1bit[0:1023]; // Memory mem1bit with 1K 1-bit words

    reg [7:0] membyte[0:1023]; // Memory membyte with 1K 8-bit words(bytes)

    membyte[511] // Fetches 1 byte word whose address is 511.

    myMem[0]

    myMem[1]

    myMem[2]

    myMem[3]

    reg [7:0] myMem [3:0];

  • Parameters

    Define constants . Makes code easy to read and modify Cant be used as variables.

    parameter port_id=5; parameter bussize = 8; reg [bussize-1 : 0] databus1; reg [bussize-1 : 0] databus2;

  • Strings

    Strings can be stored in reg.

    The width of the register variables must be large enough to hold the

    string. reg [8*19:1] string_value; initial string_value = Hello Verilog World;

  • Modules and ports

    module fulladd4(sum, c_out, a, b, c_in); output [3:0] sum; output c_out; input [3:0] a, b; input c_in; endmodule

    If the output hold their value,

    they must be declared as reg

    module DFF(q, d, clk, reset); output reg q; input d, clk, reset; endmodule

    All port declarations (input,

    output, inout) are implicitly

    declared as wire

  • Module declaration (ANSI C style)

    module fulladd4(output reg[3:0] sum, output reg c_out, input [3:0] a, b, input c_in); endmodule

  • Module instantiation

    module Top; reg [3:0] A, B; reg C_IN;//externally, inputs can be a reg or a wire; internally must be wires wire [3:0] SUM; //externally must be wires wire C_OUT; // one way fulladd4 FA1(SUM, C_OUT, A, B, CIN); // another possible way fulladd4 FA2(.c_out(C_OUT), .sum(SUM), .b(B), .c_in(C_IN), .a(A)); endmodule

    module fulladd4(sum, c_out, a, b, c_in); output [3:0] sum; output c_out; input [3:0] a, b; input c_in; endmodule

  • Module instantiation..

    Port connecting rules

    input net or reg

    inout net

    output net

  • Module instantiation

    Signal assignment follows port list order

  • Module instantiation..

    Signal assignment by port names

    The two methods cannot be mixed!

  • Module instantiation..

    Unconnected ports

    by port list order

    by name

  • Gate level modeling (structural)

    . wire Z, Z1, OUT, OUT1, OUT2, IN1, IN2; and a1(OUT1, IN1, IN2); nand na1(OUT2, IN1, IN2); xor x1(OUT, OUT1, OUT2); not (Z, OUT); buf final (Z1, Z); .

    The circuit is described in terms of gates. Hardware design at this level is intuitive All instances are executed concurrently just as in hardware Instance name is not necessary The first terminal in the list of terminals is an output and the other

    terminals are inputs

  • Predefined gate primitives

    a b d c

    and (d, a, b, c)

    not (a, b, c) a

    b c

    buf (a, b) a b

    supports basic logic gates as predefined primitives. instantiated like any other modules.

  • tri-state gates: bufif1, bufif0, notif1, notif0

    notif0 (a, b, c)

    e.g.

    bufif1 (a, b, c)

    e.g.

    a b

    c

    a b

    c

    Predefined gate primitives

  • Example of structural Verilog code

    Example of using predefined gate primitives

  • Array of gate instances

    wire [7:0] OUT, IN1, IN2; // array of gates instantiations nand n_gate [7:0] (OUT, IN1, IN2); // which is equivalent to the following nand n_gate0 (OUT[0], IN1[0], IN2[0]); nand n_gate1 (OUT[1], IN1[1], IN2[1]); nand n_gate2 (OUT[2], IN1[2], IN2[2]); nand n_gate3 (OUT[3], IN1[3], IN2[3]); nand n_gate4 (OUT[4], IN1[4], IN2[4]); nand n_gate5 (OUT[5], IN1[5], IN2[5]); nand n_gate6 (OUT[6], IN1[6], IN2[6]); nand n_gate7 (OUT[7], IN1[7], IN2[7]);

  • User Defined Primitives (UDPs)

    custom-built primitives

    do not instantiate other modules or primitives

    instantiated exactly like gate-level primitives

    //UDP name and terminal list

    primitive (

    (only one allowed)

    );

    //Terminal declarations

    output ;

    input ;

    reg ;(optional; only for

    sequential UDP)

    // UDP initialization (optional; only for sequential UDP

    initial = ;

    //UDP state table

    table

    endtable

    //End of UDP definition

    endprimitive

  • Combinational UDPs

    Example: 2-to-1 multiplexer

    Combinational UDPs dont need initialization

    The first signal in the port list is always output. However, in the truth table

    the output signal value is at the end (after a colon).

    Input order in the truth table must follow the order given in the port list.

    Output for unspecified combination is always X.

    primitive (

    );

    output ;

    input ;

    table

    endtable

    endprimitive

  • Sequential UDPs

    Example: D-Latch

    Output Q is initialized by initial block.

    In the truth table Q is the current state, Q* is the next state.

    Symbol indicates the next state is the same as the current state.

    primitive (

    );

    output ;

    input ;

    reg ;

    initial = ;

    table

    endtable

    endprimitive

  • Sequential UDPs

    Example: D Flip-Flop

    r for rising edge, same as (01)

    f for falling edge, same as (10)

    p for positive edge, same as (01), (0X), (X1)

    n for negative edge, same as (10), (1X), (X0)

    * for any change, same as (??)

  • Using UDPs

    Example: 4-bit synchronous counter

    Cannot be defined within modules.

    Can be defined after

    or before the module in

    the same file.

    Can be defined

    in a separate file

    and use include

    directive to include

    to the code.

    Defining UDPs

  • Dataflow modeling

    Module is designed by specifying the data flow. Designer is aware of how data flows between hardware registers

    and how the data is processed in the design

    Continuous assignment is one of the main constructs used in dataflow modeling assign out = i1 & i2; assign addr[15:0] = addr1[15:0] ^ addr2[15:0]; assign {c_out, sum[3:0]}=a[3:0]+b[3:0]+c_in;

    A continuous assignment is always active and the assignment expression is evaluated as soon as one of the right-hand-side

    variables changes

    Left-hand side must be a scalar or vector net. Right-hand side operands can be registers, nets, integers, real,

  • Operators in dataflow expressions

    Similar to C except that there are no ++ or

    Arithmetic: *, /, +, -, % and ** Logical: !, && and || Relational: >, = and >> and

  • Example

    module mux4(out, i0, i1, i2, i3, s1, s0); output out; input i0, i1, i2, i3; output s1, s0; assign out = (~s1 & ~s0 & i0) | (~s1 & s0 & i1) | (s1 & ~s0 & i2) | (s1 & s0 & i3); // OR THIS WAY assign out = s1 ? (s0 ? i3:i2) : (s0 ? i1:i0); endmodule

  • Example: A 2-to-4 decoder

    Circuit schematic

    Structural code Data flow code

  • Arithmetic operators

    Available operators: +, -, *, /, % (modulo) Arithmetic operators treat register operands as unsigned values Example:

    integer A;

    A = -12;

    A/4 -3

    reg [7:0] A;

    A = -12;

    A/4 61

  • Shifter operators

    > : shift right

    reg [3:0] A;

    1 1 0 1 A > 2 0 0 1 1

  • Concatenation operators

    Example

    reg [7:0] A, B, Data;

    reg c;

    A = 10101101; B= 00110011;

    c = 0;

    Data = {A[3:0], B[7:6], c, c}; // Data = 11010000

    1 1 0 1 0 0 0 0 Data

    A[3:0] B[7:6]

    c c

  • Continuous assignment

    Example

    a

    b

    c

    x

    o

    AND

    OR

    module cir1 (o, a, b, c);

    output o;

    input a, b, c;

    wire x;

    assign x = a & b;

    assign o = x | c;

    endmodule

    module cir1 (o, a, b, c);

    output o;

    input a, b, c;

    wire x = a & b;

    assign o = x | c;

    endmodule

    OR

    Continuous assignment starts with keyword assign.

    The left hand side of a continuous assignment command must be a net-type signal

  • Rules:

    The left hand side of an assignment must always be a scalar or vector net

    It cannot be a scalar or vector register.

    Continuous assignments are always active.

    The assignment expression is evaluated as soon as one of the right-hand-side operands changes and the value is assigned to the left-hand-side net.

    The operands on the right-hand side can be registers or nets.

    Delay values can be specified for assignments in terms of time units. Delay values are used to control the time when a net is assigned the evaluated value.

  • Conditional assignment

    A conditional assignment has three signals at the right hand side. The first signal is the control signal If the control signal is true, the second signal is assigned to

    the left hand side (LHS) signal ; otherwise, the third signal

    is assigned to LHS signal.

  • Adding delay to continuous assignment

    `timescale 10ns/1ns // /

    module buf1 (o, i);

    output o;

    input i;

    . assign #3 o = 1; // delay for 3 time units

    . endmodule

    Delay is added by # t after keyword assign, t is the number of delayed time units.

    Time unit is defined by `timescale

    Example

  • Delay in procedural assignments

    Delay specified in front of procedural assignment statements (e.g. #3 a = b&c;) delay the execution of the entire statement.

    Module delayTest;

    integer a, b, c;

    initial begin

    a = 2; b = 3;

    end

    initial #3 a = 4;

    initial #5 c = a+b;

    endmodule

    Execution order:

    1. delay

    2. evaluation

    3. assignment

    Result: c=7

    Change a from 2 to 4 after 3 time unit

  • Delay in procedural assignments

    Delay specified right after = in procedural assignment statements (e.g. a = #3 b&c;) just delay the assignment operation. The evaluation of the right hand side expression is executed without delay.

    Module delayTest;

    integer a, b, c;

    initial begin

    a = 2; b = 3;

    end

    initial #3 a = 4;

    initial c = #5 a+b;

    endmodule

    Execution order:

    1. evaluation

    2. delay

    3. assignment

    Result: c=5

    Change a from 2 to 4 after 3 time unit

  • Behavioral or algorithmic modeling

    Design is expressed in algorithmic level, which frees designers from thinking in terms of logic gates or data flow.

    Designing at this model is very similar to programming in C.

    All algorithmic statements in Verilog can appear only inside two statements: always and initial.

    Each always and initial statement represents a separate activity flow in Verilog.

    Activity flows in Verilog run in parallel.

    You can have multiple initial and always statements but you cant nest them.

    .

    . reg a, b, c; initial a=1b0; . . always begin b = a ^ 1b1; c = a + b; end . .

  • Behavioral blocks

    In additional to assignment, other functional description codes are included in two-type behavioural blocks: initial blocks always blocks

    A module can have multiple blocks, but blocks cannot be nested.

    When a block has multiple statements, they must be grouped using begin and end (for sequential statements) or

    fork and join (for concurrent statements). An initial block is executed at the beginning of simulation. It

    is executed only once. Always blocks are repeatedly executed until simulation is

    stopped.

  • Initial statement An initial block start at time 0, executes exactly once

    and then never again.

    If there are multiple initial blocks, each block starts to execute concurrently at time 0 and each block finishes execution independently of the others.

    Multiple behavioral statements must be grouped using begin and end. If there is one statement then grouping is not necessary.

    reg x, y, m; initial m=1b0; initial begin x=1b0; y=1b1; end

  • Example

    A 2-to-4 decoder behavioral Verilog code

  • always statement The always statement starts at time 0 and executes the

    statements in the always block continuously in a looping fashion.

    It models a block of activity that is repeated continuously in a digital circuit.

    Multiple behavioral statements must be grouped using begin and end. If there is one statement then grouping is not necessary.

    integer count; count=0; always begin count=count+1; end

  • Events-based timing control An event is the change in the value on a register or a net.

    Events can be utilized to trigger the execution of a statement of a block of statements.

    The @ symbol is used to specify an event control.

    Statements can be executed on changes in signal value or at a positive (posedge) or negative (negedge) transition of the signal.

    input clock; integer count; count=0; always @(clock) begin count=count+1; end

    input clock1, clock 2; integer count; count=0; always @(clock1 or clock2) begin count=count+1; end

  • Procedural assignments Procedural assignments update values of reg, integer,

    or real variables.

    The value will remain unchanged until another procedural assignment updates the variable with a different value different from dataflow continuous assignments.

    Two types of procedural assignments: blocking and nonblocking.

    Blocking statements,

    specified using the =

    operator.

    are executed in the

    order they are specified

    in a sequential block.

    Nonblocking

    statements

    specified using the

  • Blocking assignments v.s. Non-blocking assignments

    Blocking assignments are performed sequentially.

    Non-blocking assignments are performed concurrently.

    initial begin

    a = #1 1; // assignment at time 1

    b = #3 0; // assignment at time 4 (3+1)

    c = #6 1; // assignment at time 10 (6+3+1)

    end

    initial begin

    #1 a < = 1; // assignment at time 1

    #3 b

  • Parallel blocks

    Parallel block is a more flexible method to write concurrent statements. It uses fork and join, instead of begin and end, in block description.

    Sequential block with

    blocking assignments

    Sequential block with

    Non-blocking assignments

    Parallel block

  • Event control statements

    An event occurs when a net or register changes it value. The event can be further specified as a rising edge (by posedge) or

    falling edge (by negedge) of a signal. An event control statement always starts with symbol @

    @ (clk) Q = D; // assignment will be performed whenever signal clk changes to its value

    @ (posedge clk) Q = D; // assignment will be performed whenever signal clk has a rising edge (01, 0X, 0Z, X1, Z1)

    @ (negedge clk) Q = D; // assignment will be performed whenever signal clk has a falling edge (10, 1X, 1Z, X0, Z0)

  • Uses of nonblocking assignments

    always @(posedge clock) begin a = b; b = a; end

    always @(posedge clock) begin a

  • Conditional statements Very similar to C

    Can always appear inside always and initial blocks

    . if(x) begin y= 1b1; z= 1b0; end . if (count < 10) count = count+1; else count = 0; .

    expression

    . if(alu_control == 0) y = x + z; else if (alu_control == 1) y = x z; else if (alu_control == 2) y = x * z; else y = x; .

    reg [1:0] alu_control; .. case (alu_control) 2d0 : y = x + z; 2d1 : y = x z; 2d2 : y = x * z; default: y=x; endcase

  • Loops

    integer count; integer y=1; integer x=2; initial for (count = 0; count < 128; count = count + 1) begin x

  • Loop Example..

  • Synthesizing registers

  • Wait statements

    Allow designers to more specifically control when to execute statements. Starts with keyword wait followed by a logic condition

    module testWait;

    integer a, b, c;

    reg en;

    initial a = 0;

    initial #3 a = 3;

    intial #6 a = 7;

    wait (a==7) b = 1; // assign 1 to b when a=7

    wait (en) c = 2; // assign 2 to c when en is true

    endmodule

  • Case statement

    Readable alternative to nested if-else statements.

  • Sensitivity list

    Sensitivity list specifies events on which signals activate or block

    //A level-sensitive latch with asynchronous reset

    always @( reset or clock or d)

    //Wait for reset or clock or d to change

    begin

    if (reset) //if reset signal is high, set q to 0.

    q = 1'b0;

    else if(clock) //if clock is high, latch input

    q = d;

    end

  • Hierarchical naming

    As described, every module instance, signal, or variable is identified with an identifier.

    Each identifier has a unique place in the design hierarchy.

    Hierarchical name referencing allows us to denote every identifier in the design hierarchy with a unique name.

    A hierarchical name is a list of identifiers separated by dots . for each level of hierarchy

    Examples: stimulus.q, stimulus.m1.Q, stimulus.m1.n2

  • Named blocks Blocks can be given names

    Local variables can be declared from the names block

    Variables in a named block can be accessed by using hierarchical name referencing

    Named blocks can be disabled

    always begin : block1 integer i; i=1; end always begin : block2 integer j; j = block1.i^1; end

  • Disabling named blocks

    The keyword disable provides a way to terminate the execution of a named block.

    Disable can be used to get out of loops, handle error conditions, or control execution of pieces of code based on control signal

    Disabling a block causes the execution control to be passed to the statement immediately succeeding the block

    initial begin i=0; flag=8b0010_0101; begin: block1 while (i < 16) begin if (flag[i]) disable block1; i = i+1; end end

  • Tasks and functions

    Often it is required to implement the same functionality at many times in a behavioral design.

    Verilog provides tasks and functions to break up large behavioral code into smaller pieces.

    Tasks and functions are included in the design hierarchy. Like named blocks, tasks and functions can be addressed by means of hierarchical names.

    Tasks have input, output and inout arguments

    Functions have input arguments

    Tasks and functions are included in the design hierarchy. Like named blocks, tasks or functions can be addressed by means of hierarchical names

  • Tasks Tasks are declared with the

    keywords task and endtask. Tasks can have input, inout,

    and output arguments to pass values (different than in modules).

    Tasks or functions can have local variables but cannot have wires.

    Tasks and functions can only contain behavioral statements.

    Tasks and functions do not contain always or initial statements but are called from always blocks, initial blocks, or other tasks and functions.

    Can operate directly on reg variables defined in the module

    module always begin BOP (AB_AND, AB_OR, AB_XOR, A, B); BOP (CD_AND, CD_OR, CD_XOR, C, D); end task BOP; output [15:0] ab_and, ab_or, ab_xor; input [15:0] a, b; begin ab_and = a & b; ab_or = a | b; ab_xor = a ^ b; end endtask endmodule

  • Module vs task instantiation

    Instantiated modules create duplicate copies in hardware.

    In contrast tasks are static in nature. All declared items are statically allocated and they are shared across all uses of the task.

    If a task is called from within a behavioral block, only one copy is needed

    However, a task/function might be called concurrently form different behavioral blocks, which can lead to incorrect operation avoid by using the automatic keyword to make a task re-entrant

    module always BOP (AB_AND, AB_OR, AB_XOR, A, B); always BOP (CD_AND, CD_OR, CD_XOR, C, D); task automatic BOP; output [15:0] ab_and, ab_or, ab_xor; input [15:0] a, b; begin ab_and = a & b; ab_or = a | b; ab_xor = a ^ b; end endtask endmodule

  • Functions

    Functions are typically used for combinational modeling (use for

    conversions and commonly used

    calculations).

    Need at least one input argument but cannot have output or inout arguments.

    The function is invoked by specifying function name and input

    arguments, and at the end

    execution, the return value is

    placed where the function was

    invoked

    Functions cannot invoke other tasks; they can only invoke other

    functions. Recursive functions are

    not synthesizable

    module reg [31:0] parity; always @(addr) begin parity = calc_parity(addr); end function calc_parity; input [31:0] address; begin calc_parity = ^address; end endfunction endmodule

  • Functions vs Tasks

    Functions Tasks

    A function can enable another function but not another task.

    A task can enable other tasks and functions.

    Functions always execute in 0 simulation time.

    Tasks may execute in non-zero simulation time.

    Functions must not contain any delay, event, or timing control statements.

    Tasks may contain delay, event, or timing control statements.

    Functions must have at least one input argument. They can have more than one input.

    Tasks may have zero or more arguments of type input, output, or inout.

    Functions always return a single value. They cannot have output or inout arguments.

    Tasks do not return with a value, but can pass multiple values through output and inout arguments.

  • Avoiding unwanted latches

    Incomplete system specifications (if-else, or case) lead to unwanted latches

    Latch-prone code Latch-free code

  • Creating testbench

    Used to verify the designed circuit.

  • Testbench example

    Testbench Unit under test

    Simulation result

  • Example: clock display

    seconds

    HEX1 HEX0

    minutes

    HEX3 HEX2

  • Task to display digits

    task digit2sev(input integer digit, output [6:0] disp); begin if (digit == 0) disp = 7'b1000000; else if (digit == 1) disp = 7'b1111001; else if (digit == 2) disp = 7'b0100100; else if (digit == 3) disp = 7'b0110000; else if (digit == 4) disp = 7'b0011001; else if (digit == 5) disp = 7'b0010010; else if (digit == 6) disp = 7'b0000011; else if (digit == 7) disp = 7'b1111000; else if (digit == 8) disp = 7'b0000000; else if (digit == 9) disp = 7'b0011000; end endtask

  • task display_time(input [5:0] s, input [5:0] m); begin digit2sev(s%10, HEX0); digit2sev(s/10, HEX1); digit2sev(m%10, HEX2); digit2sev(m/10, HEX3); end endtask task digit2sev(input integer digit, output [6:0] disp); begin if (digit == 0) disp = 7'b1000000; else if (digit == 1) disp = 7'b1111001; else if (digit == 2) disp = 7'b0100100; else if(digit == 3) disp = 7'b0110000; else if(digit == 4) disp = 7'b0011001; else if(digit == 5) disp = 7'b0010010; else if(digit == 6) disp = 7'b0000011; else if(digit == 7) disp = 7'b1111000; else if(digit == 8) disp = 7'b0000000; else if(digit == 9) disp = 7'b0011000; end endtask endmodule

    HEX3 HEX2 HEX1 HEX0

  • Implementation module clock(CLOCK_50, HEX0, HEX1, HEX2, HEX3); output reg [6:0] HEX0, HEX1, HEX2, HEX3; input CLOCK_50; integer count=0; reg [3:0] d1=0, d2=0, d3=0, d4=0; always @(posedge CLOCK_50) begin count=count+1; if (count == 50_000_000) begin count=0; d1 = d1+1; if(d1 == 10) begin d1 = 0; d2 = d2+1; if(d2 == 6) begin d2 = 0; d3 = d3 + 1; if(d3 == 10) begin d3 = 0; d4 = d4 + 1; if(d4 == 6) d4 = 0; end end end digit2sev(d1, HEX0); digit2sev(d2, HEX1); digit2sev(d3, HEX2); digit2sev(d4, HEX3); end end task digit2sev; endtask endmodule

    module clock(CLOCK_50, HEX0, HEX1, HEX2, HEX3); input CLOCK_50; output reg [6:0] HEX0, HEX1, HEX2, HEX3; integer count=0; reg [15:0] ticks=16'd0; reg [5:0] seconds=6'd0, minutes=6'd0; initial display_time(seconds, minutes); always @(posedge CLOCK_50) begin count = count+1; if (count == 50_000_000) begin count=0; ticks = ticks + 1; seconds = ticks % 60; minutes = ticks / 60; display_time (seconds, minutes); end end

    Alt-2

    Alt-1

  • Resource utilization is 152 LEs

    Resource utilization=Alt 1

  • Resource utilization for Alt-2

    Circuit consumes 611 LEs (2% of the chip logic resources).

    You have to be careful! Changing ticks, seconds and minutes to integer increases area to become 2500 LEs (8% of the utilization)

  • Synthesis tips

    Nested if-else leads to lengthy mux-chain, which is normally slow. Using case instead.

    However, case results in mux with multiple inputs, which makes routing more difficult.

    Using instantiated module to implement arithmetic operators, instead of directly using arithmetic operators. Good partition leads to better results.

    Assign values to all outputs in all cases (to avoid unwanted latches).

  • Register all the outputs of critical design blocks Avoid path that traces through number of hierarchies

    and then return back to same hierarchy

    Partition the design based on functional goals and the clock domains

    Avoid instantiating technology specific modules Use parameters and declare them at the top with

    meaningful names

    Avoid internally generated clocks and resets Avoid glue logic at the top level

    Synthesis for Reusability

  • References

    Verilog HDL by Samir Palnitkar; Pearson Verilog Interactive tutorial by Aldec Design guidelines: http://www.inno-logic.com/resourcesTips.html