zoukankan      html  css  js  c++  java
  • Verilog 语法

    Syntax

    Verilog Modules

    • Modules are the building blocks of verilog designs. They are a means of abstraction and encapsulation for your design
    • A module consists of a port declaration and verilog code to implement the desired functionality
    • Modules should be created in a verilog file where the filename matches the module name(the module below should be stored in full_adder.v)
    module full_adder(input x, input y, input cin, output s, output cout);
    endmodule
    

    The Top-Level Module

    • Every verilog design has a top-level module which sits at the highest level of the design hierarchy, the top-level module defines the I/O for the entire digital system, all the modules in your design reside inside the top-level module
    • Modules can be instantiated inside other modules
    module top_level(input switch0,
                     input switch1,
                     input switch2,
                     output led0,
                     output led1
                     );
    
          // instantiate the module full_adder, adder0 is his name
          full_adder adder0(
                            .x(switch0),
                            .y(switch1),
                            .cin(switch2),
                            .s(led0),
                            .cout(led1)
                            );
    
    endmodule
    

    Wire Nets

    • Wires are analogous to wires in a circuit you build by hand, they are used to transmist values between inputs and outputs, Declare wires before they are used.
    wire a;
    wire b;
    
    • The wires above are scalar. They can also be vectors.
    wire [7:0] c; // 8-bit wire declaration
    

    Operators

    • Arithmetic
      For the FPGA, division and multiplication are very expensive and sometimes you can not synthesize division. If you use Z or X for values the result is unknown. The operations treat the values as unsigned.
      If a=5, b=10, c=2'b01 and d=2'b0Z
    • Bitwise
      Each bit is operated, result is the size of the largest operand and the smaller operand is left extended with zeroes to the size of the bigger operand.
      If a=3'b101, b=3'b110 and c=3'b01X
    • Reduction
      These operators reduces the vectors to only one bit. If there are the characters z and x the result can be a known value.
      If a=5'b10101, b=4'b0011, c=3'bz00 and d=4'bx011
    • Relational
      These operators compare operands and results a 1 bit scalar boolean value. The case equality and inequality operations can be used for unknown or high impedance(x or z) and if the two operands are unknown the result is a 1.
      If a=3'b010, b=3'b100, c=3'b111, d=3'b01z and e=3'b01x
    • Logical
      These operators compare operands and results a 1bit scalar boolean value.
      If a=3'b010 and b=3'b000
    • Shift operators
      These operators shift operands to the right or left, the size is kept constant, shifted bits are lost and the vector is filled with zeroes.
      If a= 4'b1010 and b=4'b10x0
    • Others
      These are operators used for condition testing and to create vectors
      If a=4'b1010 and b=4'b10x0

    Operators Precedence

    The order of the table tells what operation is made first, the first ones has the highest priority. The () can be used to override default.

    // conditional operator ?:, this example is an expression that implements min(a, 10)
    wire out;
    assign out = a > 10 ? 10 : a;
    
    // if a==b then c=0
    // else if a<b then c=1
    // else c=2
    assign c = a==b ? 2'd0 : (a<b ? 2'd1 : 2'd2);
    

    Macros

    • constants.vh:
    `ifndef CONSTANTS // guard prevents header file from being included more than once, it is similar to the header file of C
    `define CONSTANTS
    
    `define ADDR_BITS 16
    `define NUM_WORDS 32
    `define LOG2(x) (x <= 2) ? 1 :     // calculate the log2(x)
                    (x <= 4) ? 2 : 
                    (x <= 8) ? 3 : 
                    (x <= 16) ? 4 : 
                    (x <= 32) ? 5 : 
                    (x <= 64) ? 6 : 
                    -1
    `endif
    
    • design.v:
    `include "constant.vh"
    
    module memory (input [`ADDR_BITS - 1 : 0] address,
                   output [`LOG2(`NUM_WORDS) - 1 : 0] data
                   );
          // implementation
    endmodule
    

    Register Nets

    Verilog has two types of nets: wire and reg. Reg nets are required whenever a net must preserve state(i.e. in an always block). Wires are used for structural verilog(to connect inputs to outputs) and for continuous assignment.

    1.Combinational logic block

    verilog allows more complex logic through the use of always blocks.
    Combinational logic(i.e. no state elements) can be written using always@(*). The value inside the parentheses is called the sensitivity list. Using a * will tell the compiler to compute the sensitivity list automatically(recommended for combinational logic)
    Only reg nets can be assigned in an always block

    input wire a;
    input wire c;
    output wire b;
    reg b_out;
    
    //
    always @(*)
    begin
      b_out = ~a;
    end
    assign b = b_out;
    
    // if-else statements
    always @(*)
    begin
        if(a)
            b_out = c;
        else
            b_out = ~c;
    end
    
    // case statement
    always @(*)
    begin
        case(a)
            0: b_out = c;
            1: b_out = ~c;
            default: b_out = c;
        endcase
    end
    

    WARNING:

    • For and while loops can not be mapped to hardware! They are non-synthesizable control statements
    • Every signal should have a default value. Assigning a value to a reg only under given conditions will result in latch synthesis. For example:
    // This code will generate a latch
    input [1:0] x;
    reg [1:0] y;
    always @(*) begin
        if(x == 2'b10)
            y = 2'd3;
        else if(x == 2'b11)
            y = 2'd2;
    end
    
    // y has a default value so that this code will not generate a latch
    always @(*) begin
        y = 2'b00;
        if(x == 2'b10)
            y = 2'd3;
        else if(x == 2'b11)
            y = 2'd2;
    end
    

    2.Synchronous logic block

    Synchronous logic blocks are generated using special identifiers in the sensitivity list. Here we only want to update on the positive edge of the clock, so we use posedge. This will generate a synchronous circuit that implements x every clock cycle.

    input clk;
    reg [1:0] x;
    
    always @(posedge clk)
    begin
        x <= x + 1;
    end
    

    Wire vs Reg

    Rules for picking a wire or reg net type:

    • If a signal needs to be assigned inside an always block, it must be declared as a reg
    • If a signal is assigned using continuous assignment statement, it must be declared as a wire
    • By default module input and output ports are wires; if any output ports are assigned in an always block, they must be explicitly declared as reg: output reg
      How to know if a net represents a register or a wire
    • a wire net always represents a combinational link
    • a reg net represents a wire if it is assigned in an always@(*) block
    • a reg net represents a register if it is assigned in an always @(posedge/negedge clock) block

    Localparam/parameter Declaration

    1.localparam: Private module parameters are defined using the localparam directive. These are useful for constants that are needed only by a single local module, and it can not be instantiated with it
    2.parameter: it's feature is similar to localparam, further more, it can transimit the parameter setting
    For example, first define a module

    module example #(parameter SIZE=7)
                  (input clk,
                   input rst_n,
                   output [SIZE-1 : 0] data
                   );
    
    localparam K = 5;
    reg [7:0] x;
    
    always @(posedge clk or negedge rst_n)
    begin
        if(!rst_n)
            data <= 0;
        else
            data <= K + x;
    end
    
    endmodule
    

    second when to instantiate the example module in the top level, and data size is required to modified as 32-bit

    example EX1
    #(.SIZE(32))     // 参数例化
    (
        .clk(clk),
        .rst_n(rst_n),
        .data(data)
    );
    

    Code Generation with for-generate loops

    -- wait to fill up

    Multidimentional Nets in verilog

    // A memory structure that has eight 32_bit elements
    reg [31:0] fifo_ram [7:0];
    fifo_ram[2] // represents the full 3rd 32-bit element
    fifo_ram[5][7:0] // represents the lowest byte of 6th 32-bit element
    

    Initial blocks and Testbench

    `timescale 1ns/1ps
    // a delay of #1 would result in a 1ns step
    // Delays as low as #0.001 would be supported due to the resolution of 1ps
    
    module tb;
    
    reg clk_in;
    reg rst_n;
    wire clk_out;
    
    reg a_in;
    wire b_out;
    
    initial
    begin
      clk_in = 0;
      repeat (20) #10 clk_in = ~clk_in;
    end
    
    initial
    begin
      rst_n = 0;
      #10;
      rst_n = 1;
    end
    
    initial
    begin
      a_in = 0;
      #10 a_in = 1;
      #10 a_in = 0;
    end
    
    divider D1(
      .clk_in(clk_in),
      .clk_out(clk_out),
      .rst_n(rst_n),
      .a(a_in),
      .b(b_out)
    );
    
    endmodule
    

    Others

    repeat (8'hff) @(posedge clk);  // repeat 0xff positive edges of clk
    @(posedge clk);  // wait for the positive edge of clk
    
    --------------------------------------------- Study needs record, record needs review ---------------------------------------------
  • 相关阅读:
    Python – GitHub CentOS
    Python – GitHub Ubuntu
    学习jQuery Treeview一天的感受
    让我郁闷了一个下午的list为null
    在徘徊中前进的一天
    都是被逼的,被逼的
    和技术无关,生活中的一点感受
    我又错了
    忽然的感受
    学习jQuery的一天
  • 原文地址:https://www.cnblogs.com/georgemxx/p/14002835.html
Copyright © 2011-2022 走看看