THE VLSI HOMEPAGE

A Practical guide to VLSI Design and Verification..

Interfaces in SystemVerilog - 2

Posted in SystemVerilog by Nigam on the October 23rd, 2007

SystemVerilog allows tasks and functions to be declared within interface definitions known as interface methods. The task or function has the same syntax as when declared in a module. Using these interface methods, the communication protocol details can be embedded within the interface definition itself.

SV:
  1. interface ahb_bus (input logic ahb_hclk, ahb_hresetn); // Interface can have ports.
  2.    wire [31:0]     ahb_hdata;
  3.    wire [31:0]     ahb_addr;
  4.    logic              ahb_hwrite;
  5.    logic [1:0]      ahb_htrans;
  6.    logic [2:0]      ahb_hsize;
  7.    logic [2:0]      ahb_hburst;
  8.    logic              ahb_hready;
  9.    logic [1:0]      ahb_hresp;
  10.  
  11. // Task defined internal to interface
  12.    task slave_read ( input logic [31:0] raddr);
  13.    // ...
  14.    endtask
  15.  
  16. endinterface

Interface methods can also be imported if they are not defined within the interface definition itself. If an interface is connected using modport construct, then the import keyword is used to specify the method. Alternative way is to add the task keyword next to the import and also include function arguments - this is required if the task is exported from an external module.

SV:
  1. interface ahb_bus (input logic ahb_hclk, ahb_hresetn); // Interface can have ports.
  2.    wire [31:0]     ahb_hdata;
  3.    wire [31:0]     ahb_addr;
  4.    logic              ahb_hwrite;
  5.    logic [1:0]      ahb_htrans;
  6.    logic [2:0]      ahb_hsize;
  7.    logic [2:0]      ahb_hburst;
  8.    logic              ahb_hready;
  9.    logic [1:0]      ahb_hresp;
  10.  
  11.   modport slave ( import slave_read,   // simplest way of importing tasks
  12.                         inout ahb_hdata,
  13.                         input ahb_haddr,
  14.                         input ahb_hsize,
  15.                         output ahb_hready,
  16.                         ---
  17.                );
  18.  
  19. // Alternative explicit way
  20.    modport slave ( import task slave_read (input [31:0] addr),   // explicit
  21.                          inout ahb_hdata,
  22.                          input ahb_haddr,
  23.                          input ahb_hsize,
  24.                          output ahb_hready,
  25.                           ---
  26.                   );

Importing a task or a function through a modport gives the module access to that task by prepending the interface port name to the task name as with other variables. The imported function/task must be declared as automatic in order to be synthesizable.

SV also includes a way to export a task defined in one module to be available to other modules through an interface. For example, if a function is defined in module A and is exported in the modport construct within interface definition using the export keyword, then the task is available to module B that uses that modport. However, this is not synthesizable and we cannot export the same function from multiple instances of a module.

It is also possible to define a task or function using extern keyword without associating it with the modport construct.

SV:
  1. interface shb_bus (....)
  2. ---
  3.      extern check_parity (input logic [31:0] data); // Not associated with modport
  4.  
  5.      modport ahb_slave (...);
  6.  
  7. endinterface
  8.  
  9. module A (...);
  10.  
  11.   task check_parity (input logic [31:0] data);
  12.   // --
  13.   endtask
  14. endmodule

Interfaces can also contain procedural blocks like always, always_ff, parameters and generate statements similar to modules.

Sphere: Related Content

Interfaces in SystemVerilog

Posted in SystemVerilog by Nigam on the October 22nd, 2007

Connectivity across different design modules in Verilog is accomplished through port connections for each interface signal in instantiations. For large designs, this is not very productive as it involves redundant instances and signal declarations and is prone to error.

To resolve this issue, SystemVerilog adds a powerful interface construct to encapsulate the communication between blocks i.e. multiple signals are grouped together to form a single port. The signals declared in the interface definition is in a single location so that any changes in the interface can be captured accurately modifying only once instead of multiple modules as in Verilog. All the modules using this interface need only declare a single interface type port rather than multiple signals. An example of SV interface is below

SV:
  1. // AHB Interface Definition
  2. interface ahb_bus (input logic ahb_hclk, ahb_hresetn); // Interface can have ports.
  3. // These external signals (hclk, hresetn can be implicitly connected between modules
  4.    wire [31:0]     ahb_hdata;
  5.    wire [31:0]     ahb_addr;
  6.    logic              ahb_hwrite;
  7.    logic [1:0]      ahb_htrans;
  8.    logic [2:0]      ahb_hsize;
  9.    logic [2:0]      ahb_hburst;
  10.    logic              ahb_hready;
  11.    logic [1:0]      ahb_hresp;
  12. endinterface
  13.  
  14. // Top level Module
  15. module ahb_top (input logic ahb_hclk, ahb_hresetn);
  16.  
  17.    ahb_bus bus (
  18.       .ahb_hclk(ahb_hclk),
  19.       .ahb_hresetn(ahb_hresetn) ); // instance of interface
  20.  
  21.    arm_core arm_inst (
  22.       // ahb_bus ports
  23.       .bus (bus),
  24.      // other ports
  25.      .port1 (port1) // not part of the interface
  26.      ... );
  27.  
  28.    ahb_slave ahb_slave0 (
  29.         .bus (bus) );
  30.  
  31.    dma_master dma_master_inst (
  32.         .bus (bus),
  33.         // Other ports
  34.         ---
  35.    );
  36.  
  37.    on_chip_mem on_chip_mem_inst (
  38.       .bus (bus),
  39.       // Other ports
  40.       --
  41.      );
  42.  
  43. endmodule
  44.  
  45. // Module Definitions
  46. module arm_core (
  47.     ahb_bus bus, // interface port
  48.     // other ports
  49.     input logic port1
  50. );
  51.   // functionality
  52. endmodule
  53.  
  54. module ahb_slave (
  55.    ahb_slave bus
  56. );
  57.    logic [1:0] ahb_hsel;
  58.    logic [31:0] slave_address;
  59.    // functionality
  60.    // Referring signals inside interface requires using interface port name
  61.    assign bus.ahb_addr = (ahb_hsel == 2'b0) ? slave_address; 'z;
  62. endmodule
  63.  
  64. module dma_master (
  65.    ahb_bus bus;
  66.    // Other ports
  67.    ---
  68. );
  69.    // functionality
  70. endmodule

An interface can also have tasks, functions, parameters, procedural blocks and type declarations to aid in defining the communication protocol. SV interface cannot have a design hierarchy i.e. no modules can be instantiated in the interface. A modport constructs is provided to define the direction for interface port for different modules. Selecting the appropriate modport for each module can be accomplished during either module definition or during module instance as shown in example below.

SV:
  1. interface ahb_bus (input logic ahb_hclk, ahb_hresetn); // Interface can have ports.
  2.   wire [31:0]     ahb_hdata;
  3.   wire [31:0]     ahb_addr;
  4.   logic              ahb_hwrite;
  5.   logic [1:0]      ahb_htrans;
  6.   logic [2:0]      ahb_hsize;
  7.   logic [2:0]      ahb_hburst;
  8.   logic              ahb_hready;
  9.   logic [1:0]      ahb_hresp;
  10.  
  11.   modport master ( inout ahb_hdata,
  12.                         output ahb_haddr,
  13.                         output ahb_hsize,
  14.                         input ahb_hready,
  15.                         ---
  16.                       );
  17.  
  18.   modport slave ( inout ahb_hdata,
  19.                         input ahb_haddr,
  20.                         input ahb_hsize,
  21.                         output ahb_hready,
  22.                         ---
  23.                       );
  24. endinterface
  25.  
  26. module ahb_top (.. );
  27.    
  28.    ahb_bus bus (...);
  29.    dma_master dma_master_inst (bus.master); // Use the master modport view
  30.    ahb_slave ahb_slave0 (bus.slave); // Use the slave modport view
  31.  
  32. endmodule
  33.  
  34. // Alternatively, modport construct can be used in module definition
  35. module ahb_slave (ahb_bus.master bus);
  36. endmodule

If no modport is associated with a module, by default all net types are inout and all variable types are ref.

A generic interface port defines the port type using the keyword interface instead of using a name of a specific interface type - the advantage is being able to connect the module to different interfaces. Unlike Verilog, no interface port can be left unconnected and SV .name and .* connection rules can be also be used for interface instances.

SV:
  1. module ahb_slave (interface bus); // generic interface port
  2. ahb_slave ahb_slave0 (bus.slave);

Sphere: Related Content

Procedural Statements and Operators in SystemVerilog

Posted in SystemVerilog by Nigam on the October 20th, 2007

Verilog includes most of C-like control flow statements except for do-while, break, continue and goto. Verilog in addition supports the repeat statement that C does not and the disable. SystemVerilog offers enhanced control flow statements that we will cover in this post.

Enhanced if-else

SV adds unique and priority keywords which can be used before an if clause. A priority if indicates that the logic will be intrepreted in the order listed - i.e. like priority encoder. A unique if indicates that all the expressions in the if-else are mutually exclusive i.e. only one of the expressions is true at any given time. These keywords make the design intent more intuitive and aid synthesis tools infer priority encoder logic only when required. If no condition matches with either of these keywords without an explicit else, it results in a runtime error.

SV:
  1. logic [3:0] mode_sel;
  2.  
  3. always_comb begin
  4.     unique if (mode_sel == 4'b0001) out = in1; // unique - mutually exclusive conditions, can be executed in parallel
  5.     else    if (mode_sel == 4'b0010) out = in2;
  6.     else    if (mode_sel == 4'b0100) out = in3;
  7.     else    if (mode_sel == 4'b1000) out = in4;
  8. end
  9.  
  10. always_comb begin
  11.    priority if (mode_sel == 4'b0001) out = in1; // priority - sequential order, first true expression takes precedence
  12.    else    if (mode_sel == 4'b0010) out = in2;
  13.    else    if (mode_sel == 4'b0100) out = in3;
  14.    else    if (mode_sel == 4'b1000) out = in4;
  15. end

Enhanced case statements
Similar to if-else statements, SV supports priority and unique keywords for case, casex and casez statements also. For synthesis, the unique case is similar to enabling the full_case and parallel_case pragmas and priority case is similar to enabling the full_case. However, by including these keywords in the SV language rather than use synthesis pragmas, any simulation/synthesis mismatches in how tools intrepret the logic can be avoided.

Enhanced for loops
In Verilog, the variable used in a for loop expression should be declared prior to the loop. Also, if multiple for loops are running concurrently, separate variables need to be used. SV simplifies the for loops by allowing to declare the variable in for loop expression itself.

SV:
  1. always_ff @(posedge clk) begin : label_count   // SV allows named begin-end blocks
  2.    for (int i = 0; i <16; i++)  // automatic variable int, i visible only within for loop
  3.    count = count + incr[i]
  4. end : label_count
  5.  
  6. //foreach loop construct
  7. logic [15:0] parity;
  8. logic [15:0] [7:0] data;
  9. foreach (parity[i]) parity[i] = ^data[i]; // generates parity for each data byte

SV adds a foreach loop construct which can be used to iterate over elements of single and multidimensional arrays without specifying the array dimension. SV also adds continue, break and return statements like C. SV also supports labels before any procedural statement.

SV supports a final block that is executed at the end of simulation time (unlike initial time) and is used to display statistical information about the simulation using $display.

Operators

SV includes increment (++) and decrement (--) operators similar to C - they can be used to post-increment or pre-increment a variable. The increment and decrement operators behave as blocking assignments and should be used only for combinatorial blocks to avoid race conditions i.e. the ++ or -- operators should not be used in always_ff blocks.

SV supports C like assignment operators like +=, ^=, !=, *=, <<= etc. These assigment operators behave like blocking assignments like the above. SV adds two new comparison operators ==? and !=? in addition to == and === operators.

The ==? referred to as wildcard equality operator makes a bit wise comparison of two operands but any logic X or Z in the right operand is treated as a wildcard and matches any value in the LHS operand's corresponding bit position.

In addition, SV supports inside keyword to test if a variable matches anywhere within a set of values.

SV:
  1. logic [2:0] count;
  2.   if (count inside (3'b001, 3'b010, 3'b100)) // similar to if ((count==3'b001) || (count==3'b010)..)
  3. int count [0:31];
  4.   if (100 inside (count)); // can also be an array

Sphere: Related Content

Next Page »

Close
E-mail It