HOME    COMMUNITY    BLOGS & FORUMS    VIP Central
VIP Central

Power Management of PCIe PIPE Interface

Posted by VIP Experts on March 3rd, 2015

Lately we have seen a trend of serial data transfers in place of parallel data transfer for improved performance and data integrity. One example of this is the migration from PCI/PCI-X to PCI Express. A serial interface between two devices results in fewer number of pins per device package. This not only results in reduced chip and board design cost but also reduces board design complexity. As serial links can be clocked considerably faster than parallel links,  they would be  highly scalable in terms of performance.

However, to accelerate verification of PCI Express based sub-systems and to accelerate the PCI Express endpoint development time ,  PIPE (PHY Interface for the PCI Express Architecture) was defined by Intel and was published for industry review in 2002. PIPE is a standard interface defined between a PHY sub-layer which handles the lower levels of serial signaling and the Media Access Layer (MAC) which handles addressing/access control mechanisms. The following diagram illustrates the role PIPE plays in partitioning the PHY layer for PCI Express.

Partitioning Phy Layer

(Source:  PHY Interface for thePCI Express Architecture specification, Version 2.00)

With this interface, developers can validate their designs without having to worry about the analog circuitry associated with teh Phy interface.  For the MAC core verification, the PHY Bus Functional Model (BFM) would  be connected directly to it. Without PIPE, it would be required to have the PHY and Serdes (serializer/deserializer) combination along with the Root Complex BFM. Additionally, the user would have to ensure the correctness of the PHY and SerDes behavior as well with the serial interface.

Given the value of the PIPE interface, it is now being widely used. In our recent experiences, we have observed that the different power states in the PIPE interface can create some confusion with respect to their interpretation. This blog post and the next will throw some light on the different power states of this interface. Hopefully, this will lead to a better understanding of the same. The assumption here is that the reader has a high level understanding of PCIe LTSSM.

Power states of PIPE

The power management signals allow the PHY to minimize the power consumption.  Four power states, P0, P0s, P1, and P2 are defined for this interface. P0 state is the normal operational state for the PHY. One it transitions from P0 to a lower power state, the PHY can immediately take appropriate power saving measures.

All power states are represented by signals PowerDown [2:0](MAC output). The Bit representation is as follows:

2]   [1]   [0]                           Description

0       0      0                            P0, normal operation

0       0      1                            P0s, low recovery time latency, power saving state

0       1      0                            P1, longer recovery time latency, lower power state

0       1      1                            P2, lowest power state.

PIPE interface power state can be correlated with power state of LTSSM as mentioned in Base specification (Refer to PCI_Express_Base_r3.0_10Nov10).

  1. P0 is equivalent to LTSSM State where Data/Order Set can transfer
  2. P0s is equivalent to L0s of LTSSM
  3. P1 is equivalent to Disabled, all Detect , and L1.Idle  state of LTSSM
  4. P2 is equivalent to L2 of LTSSM

Power state transitions in PIPE

In states P0, P0s and P1, the PHY is required to keep PCLK operational. For all state transitions between these three states, the PHY indicates successful transition into the designated power state  by a single cycle assertion of PhyStatus.

There is a limited set of legal power state transitions that a MAC can cause the PHY to make. Referencing the main state diagram of the LTSSM in the base specification and the mapping of LTSSM states to PHY power states described in the preceding paragraphs, those legal transitions are:

  1. P0 to P0s
  2. P0 to P1
  3. P0 to P2
  4. P0s to P0
  5. P1 to P0
  6. P2 to P1

Given that we understand the valid power state transitions,  I would capture more details about the individual power states and all possible transitions in more detail in my subsequent blog.  Stay tuned.

You can get more information at Synopsys Verification IP and VC Verification IP Datasheet.

Authored by Saurabh Shrivastava

 

Posted in Methodology, PCIe | No Comments »

How to Integrate AXI VIP into a UVM Testbench

Posted by VIP Experts on February 26th, 2015

Here, Synopsys VIP manager Tushar Mattu describes how best we can integrate AXI VIP into a UVM Testbench:  http://bit.ly/1Ay3zfb 

For more info, please check out Verification IP for AMBA 4 AXI.

Posted in AMBA, SystemVerilog, UVM | No Comments »

Parameterized Interfaces and Reusable VIP (3 of 3)

Posted by VIP Experts on February 24th, 2015

This is the third part of a three part series discussing SystemVerilog interfaces and strategies for dealing with parameterization.

You can get more information at Synopsys Verification IP and VC Verification IP Datasheet.

In the first part of this series, the basic concepts of SystemVerilog interfaces were introduced, and the problems that parameterization of those interfaces introduce to testbench code was described.  In the second part, the method of using an accessor class to shield the VIP code from the parameterization effects was described, but this solution imposes new restrictions on VIP access to that interface.  In this final post of this series, a process is introduced that allows the testbench to make use of parameterized interfaces without imposing any limits on the way that the VIP can access the interface that it is provided.

Maximum Footprint: Best of both worlds

The problem that parameterized interfaces introduce to dynamic testbench code cannot be resolved using today’s existing SystemVerilog functionality.  Therefore we must design a way to avoid exposing these parameters to the VIP code.  The previous post in this series introduced the accessor class to achieve this.  An alternate solution is to define a maximum footprint style interface that the VIP can interact with, and a parameterized interface that wraps this maximum footprint interface and connects to the signals that it needs from the max footprint interface.

Maximum footprint style interfaces define the maximum width for each signal and individual VIP components can be configured to utilize bit slices from those signals.  This allows for multiple VIP instances with different widths and does not require parameterized classes to work with parameterized interfaces.  The following code segments demonstrate these concepts.

First, we define the max footprint style interface.  Note that this interface is not parameterized because this is the interface that the VIP code will interact with:

  // Redefinable max footprint
  `ifndef MAX_DATA_WIDTH
   `define MAX_DATA_WIDTH 32
  `endif

  interface max_footprint_if;
    logic clk;
    logic[`MAX_DATA_WIDTH-1:0] data_in;
    logic[`MAX_DATA_WIDTH-1:0] data_out;

    clocking active_cb @(posedge clk);
      default input #1 output #1;
      input data_in;
      output data_out;
    endclocking

    modport active_mp (clocking active_cb);
  endinterface

  typedef virtual max_footprint_if max_footprint_vif;

Next, the parameterized interface is defined which is used to wrap the max footprint interface:

  interface param_if#(int width = 8);
    logic clk;
    logic[width-1:0] data_in;
    logic[width-1:0] data_out;

    max_footprint_if internal_if();

    assign internal_if.clk = clk;

    // Z values driven on unused inputs of the max footprint
    assign internal_if.data_in = {`MAX_DATA_WIDTH'hz, data_in};

    // Only selected output values used from the max footprint
    assign data_out = internal_if.data_out[width-1:0];
  endinterface

After this, the VIP code is implemented to work with the max footprint interface rather than the parameterized interface.  The one additional class shown below which is not shown in earlier posts is the configuration class which is used to define the signal width for each VIP instance.  Another complication that this solution creates is that the VIP must use bitslicing techniques when sampling and driving signals.  This is unfortunate, but SystemVerilog is fully equipped to handle this.

  //=======================================================================
  class cust_cfg extends uvm_object;
    rand int data_width;
    constraint valid_data_width {
      data_width inside {8, 16, 32};
    }
…

  //=======================================================================
  class cust_driver extends uvm_driver#(cust_data);
    max_footprint_vif vif;
    cust_cfg cfg;

    `uvm_component_utils(cust_driver)

    function void build_phase(uvm_phase phase);
      if (!uvm_config_db#(max_footprint_vif)::get(this, "", "vif", vif))
        `uvm_fatal("build", "A valid virtual interface was not received.");
      if (!uvm_config_db#(cust_cfg)::get(this, "", "cfg", cfg))
        `uvm_fatal("build", "A valid configuration was not received.");
…

    task consume_from_seq_item_port();
        seq_item_port.get_next_item(req);
        vif.active_cb.prop_out <= ((req.prop <> (`MAX_DATA_WIDTH-cfg.data_width));
        @(vif.active_cb);
…

    task sample_signals();
        bit[31:0] sampled_prop_in = ((vif.active_cb.prop_in <> (`MAX_DATA_WIDTH-cfg.data_width));
VM_LOW);
        @(vif.active_cb);
…

  //=======================================================================
  class cust_agent extends uvm_agent;
    `uvm_component_utils(cust_agent)

    max_footprint_vif vif;
    cust_driver driver;

    function void build_phase(uvm_phase phase);
      if (!uvm_config_db#(max_footprint_vif)::get(this, "", "vif", vif))
        `uvm_fatal("build", "A valid virtual interface was not received.");
      if (!uvm_config_db#(cust_cfg)::get(this, "", "cfg", cfg))
        `uvm_fatal("build", "A valid configuration was not received.");

      uvm_config_db#(max_footprint_vif)::set(this, "driver", "vif", vif);
      uvm_config_db#(cust_cfg)::set(this, "driver", "cfg", cfg);
      driver = cust_driver::type_id::create("driver", this);
…

Finally, the testbench code is presented.  Testcases can access VIPs without parameterization, and the top level module where the interfaces are instantiated can work with parameterized interfaces.  The additional step of creating a configuration object for each VIP instance is also shown (this is not an extra step, as this would have been needed with the earlier solutions as well but was left out for conciseness).

Utilizing max footprint style interfaces for VIP access to signals allows VIP code to be created without requiring that the VIP code be parameterized.  Defining parameterized interfaces allow testbenches to take advantage of the improved integration capabilities that they enable.  The strategy of using parameterized interfaces to wrap max footprint interfaces enables the benefits of both styles.

  //=======================================================================
  class cust_test extends uvm_test;
    cust_cfg cfg8;
    cust_cfg cfg16;
    cust_cfg cfg32;

    cust_agent agent8;
    cust_agent agent16;
    cust_agent agent32;

    virtual function void build_phase(uvm_phase phase);
      cfg8 = new("cfg8");
      cfg8.data_width = 8;
      uvm_config_db#(cust_cfg)::set(this, "agent8", "cfg", cfg8);
      agent8 = cust_agent::type_id::create("agent8", this);

      cfg16 = new("cfg16");
      cfg16.data_width = 16;
      uvm_config_db#(cust_cfg)::set(this, "agent16", "cfg", cfg16);
      agent16 = cust_agent::type_id::create("agent16", this);

      cfg32 = new("cfg32");
      cfg32.data_width = 32;
      uvm_config_db#(cust_cfg)::set(this, "agent32", "cfg", cfg32);
      agent32 = cust_agent::type_id::create("agent32", this);
    endfunction
  endclass

  //=======================================================================
  module test_top;
    param_if#(8) if8();
    param_if#(16) if16();
    param_if#(32) if32();

    initial begin

      uvm_config_db#(max_footprint_vif)::set(uvm_root::get(), "uvm_test_top.agent8", "vif", if8.internal_if);
      uvm_config_db#(max_footprint_vif)::set(uvm_root::get(), "uvm_test_top.agent16", "vif", if16.internal_if);
      uvm_config_db#(max_footprint_vif)::set(uvm_root::get(), "uvm_test_top.agent32", "vif", if32.internal_if);

      run_test("cust_test");
    end
  endmodule

Utilizing max footprint style interfaces for VIP access to signals allows VIP code to be created without requiring that the VIP code be parameterized. Defining parameterized interfaces allow testbenches to take advantage of the improved integration capabilities that they enable. The strategy of using parameterized interfaces to wrap max footprint interfaces enables the benefits of both styles.

Authored by Aron Pratt

You can get more information at Synopsys Verification IP and VC Verification IP Datasheet.

Posted in Methodology, SystemVerilog, UVM | No Comments »

Parameterized Interfaces and Reusable VIP (2 of 3)

Posted by VIP Experts on February 19th, 2015

This is the second part of a three part series discussing SystemVerilog interfaces and strategies for dealing with parameterization.

You can get more information at Synopsys Verification IP and VC Verification IP Datasheet.

In the first part of this series the basic concepts of SystemVerilog interfaces were introduced and the problems that parameterization of those interfaces introduce to testbench code was described.   This post will describe a possible workaround for this problem, but one that comes with a price…

Trojan Horse: The sneak attack method

Virtual interfaces do not support polymorphism because they are associated with static design elements.  However, SystemVerilog classes do support polymorphism and this fact can be utilized to create an interface accessor class.

A virtual class is created that declares pure virtual accessor methods that perform specific operations on a SystemVerilog interface.  Then, a parameterized class extends this class to perform the actual accesses to a strongly typed interface.  The VIP code interacts only with the non-parameterized base accessor class and so the VIP code does not need to be parameterized to work with strongly typed interfaces.  The testbench must set up the strongly typed accessor class and pass this in to the VIP, but after this all interaction with the VIP can be performed without needing to parameterize the VIP.  The following code segments demonstrate how to set this up.

First we define the parameterized virtual interface which is the same interface used in last week’s code segments:

  interface param_if#(int width = 8);
    logic clk;
    logic[width-1:0] data;

    clocking active_cb @(posedge clk);
      default input #1 output #1;
      output data;
    endclocking

    modport active_mp (clocking active_cb);
  endinterface

  typedef virtual param_if param_vif

Next, we define the non-parameterized interface accessor class and the extended class that is parameterized to work with a parameterized interface:

  //=======================================================================
  virtual class port_wrapper extends uvm_object;
    pure virtual task do_write(logic[31:0] data);
    pure virtual task do_read(output logic[31:0] data);
    pure virtual task sync_driver_cb();
  endclass

  //=======================================================================
  class port_wrapper_typed#(type vif_t=param_vif) extends port_wrapper;
    vif_t vif;

    function new(vif_t vif);
      this.vif = vif;
    endfunction

    virtual task do_write(logic[31:0] data);
      vif.active_cb.data &amp;lt;= data;
    endtask

    virtual task do_read(output logic[31:0] data);
      data = vif.active_cb.data;
    endtask

    virtual task sync_driver_cb();
      @(vif.active_cb);
    endtask

  endclass

After this the VIP code is implemented to work with this accessor class rather than directly accessing the virtual interface.  The code segment below showcases a driver and an agent class, and demonstrates the various places where the accessor methods must be used.  One thing to note about this VIP code is that it is accepts the non-parameterized accessor class through the config DB rather than the interface:

  //=======================================================================
  class cust_driver extends uvm_driver#(cust_data);
    `uvm_component_utils(cust_driver)

    port_wrapper port;

    task consume_from_seq_item_port();
      forever begin
        seq_item_port.get_next_item(req);
        port.do_write(req.data);
        port.sync_driver_cb();
…
    task sample_signals();
      forever begin
        bit[31:0] sampled_data;

        port.do_read(sampled_data);
        port.sync_driver_cb();
…
    function void build_phase(uvm_phase phase);
      if (!uvm_config_db#(port_wrapper)::get(this, &quot;&quot;, &quot;port&quot;, port))
        `uvm_fatal(&quot;build&quot;, &quot;A valid port wrapper was not received.&quot;);
…

  //=======================================================================
  class cust_agent extends uvm_agent;
    `uvm_component_utils(cust_agent)

    cust_driver driver;

    function void build_phase(uvm_phase phase);
      port_wrapper port;

      if (!uvm_config_db#(port_wrapper)::get(this, &quot;&quot;, &quot;port&quot;, port))
        `uvm_fatal(&quot;build&quot;, &quot;A valid port wrapper was not received.&quot;);

      uvm_config_db#(port_wrapper)::set(this, &quot;driver&quot;, &quot;port&quot;, port);
      driver = cust_driver::type_id::create(&quot;driver&quot;, this);
…

Finally, the testbench code is presented.  The testcases can access the VIPs without parameterization, but the top level module where the interfaces are instantiated does have to implement a few extra steps.  It must not only instantiate the parameterized interfaces, but it must also create the parameterized interfaces accessor class and pass those to the VIP instances:

  //=======================================================================
  class cust_test extends uvm_test;
    `uvm_component_utils(cust_test)

    cust_agent agent8;
    cust_agent agent16;
    cust_agent agent32;

    virtual function void build_phase(uvm_phase phase);
      agent8 = cust_agent::type_id::create(&quot;agent8&quot;, this);
      agent16 = cust_agent::type_id::create(&quot;agent16&quot;, this);
      agent32 = cust_agent::type_id::create(&quot;agent32&quot;, this);
    endfunction
  endclass

  //=======================================================================
  module test_top;
    param_if#(8) if8();
    param_if#(16) if16();
    param_if#(32) if32();

    initial begin
      port_wrapper_typed#(virtual param_if#(8)) port_wrapper8;
      port_wrapper_typed#(virtual param_if#(16)) port_wrapper16;
      port_wrapper_typed#(virtual param_if#(32)) port_wrapper32;

      port_wrapper8 = new(if8);
      port_wrapper16 = new(if16);
      port_wrapper32 = new(if32);

      uvm_config_db#(port_wrapper)::set(uvm_root::get(), &quot;uvm_test_top.agent8&quot;, &quot;port&quot;, port_wrapper8);
      uvm_config_db#(port_wrapper)::set(uvm_root::get(), &quot;uvm_test_top.agent16&quot;, &quot;port&quot;, port_wrapper16);
      uvm_config_db#(port_wrapper)::set(uvm_root::get(), &quot;uvm_test_top.agent32&quot;, &quot;port&quot;, port_wrapper32);

      run_test(&quot;cust_test&quot;);
    end
  endmodule

As you can see, this solution does resolve the use model issues with parameterized interfaces.  There is a bit of extra code needed to create a properly typed port wrapper, but testbench writers can access agents that are working with differently specialized interfaces without needing to know how those interfaces are specialized.

However, this solution imposes severe restrictions on how the VIP can utilize the virtual interface.  The driver and monitor classes cannot interact directly with the interface, and must instead defer these accesses to the strongly typed wrapper class.  This productivity loss can be offset by moving the bulk of the functionality of the driver and monitor classes to the strongly typed wrapper classes; however this more complex structure can be confusing and less flexible.  The code segments above show just a few of the access methods that a driver class might need, but in a real environment this list has the potential to grow many times larger and monitor classes will need a full battery of accessor methods as well.

Upon reflection, neither the brute force approach nor the Trojan Horse method of dealing with parameterized interfaces is ideal.  With the former approach the addition of parameters to classes complicates the use model of the VIP.  With the later approach the access methods that the port wrapper class supports must be planned for in advance and VIP access to the virtual interface is restricted.  What if functionality similar to parameterized interfaces could be enabled by the VIP code without actually using parameterized interfaces?  This leads to the third and final solution, will be described in next week’s post.

You can get more information at Synopsys Verification IP and VC Verification IP Datasheet.

Authored by Aron Pratt

 

Posted in Methodology, SystemVerilog, UVM | No Comments »

AMBA based Subsystems: What does it Take to Verify Them?

Posted by VIP Experts on February 17th, 2015

Let’s look at a typical AMBA based subsystem in the SOCs that we find today:

From this picture, what is clear to me is a preponderance of multiple AMBA components of different flavors (AXI3/4, ACE, AHB, APB). So, even if we have all of the different VIPs to represent these .different flavors, it is not a slam dunk as far as completing the verification of the full subsystem. Stitching all these components together and bringing up such a verification environment itself is a big challenge. To deal with market pressures of shipping out new devices every 4-6 months, SoC companies are adding new design blocks incrementally to existing platforms. Given these time constraints, new verification environments cannot be developed again from scratch.  If we dig deeper, we see the types of verification needed to bring in changes to the SoC:

Ensuring Data Integrity:  Maintaining the integrity of data flow across different blocks of the system environment is important. This is because each block or sub-system has its own transaction types with which it communicates within the sub-system For instance, AXI coherent transactions should get translated to AHB transactions when multiple AXI-ACE masters are talking to multiple AHB Slave memories through the interconnect fabric.

Transaction routing: One important objective of a system level verification environment is to ensure that different transactions that are routed across various components are as per the specified memory map.

Synchronization: There needs to be adequate synchronization between multiple AMBA components. This is important for meaningful stimulus generation.

Connectivity: In a system environment with multiple instances of AMBA components, there is a need to ensure that they have been hooked as per the specification. This calls for correct connectivity of various AMBA bus functional models in the testbench.

System Level Checks, Performance Analysis: Although checks at the individual blocks are important, as we graduate towards the system level, the verification environment needs to be capable of performing all system-level checks across all the AHB, APB & AXI ports within the system. It also needs to cover the transaction flow across protocols while analyzing the performance of the bust matrix with respect to throughput, latency etc.

Also, of the above requirements need to be addressed in multiple variants of the original system level infrastructure. This calls for quite a lot to be done by the verification team, right?

 This got me thinking: There is no magic switch to have all these challenges addressed. So how can we support an SOC verification team in their endeavors?  What would definitely be useful to have is a reusable verification environment which can be tweaked minimally so that it can be reused for the new system. In my next blog, let me put down my thoughts as to what such an environment ought to encapsulate, and how it might address some of the system level verification challenges.

Authored by Satyapriya Acharya

Here’s where you can find more information on Verification IP for AMBA 4 AXI.

Posted in AMBA, Methodology | No Comments »

Accelerating Memory Debug

Posted by VIP Experts on February 12th, 2015

Following on his recent talk about Key Advantages of Synopsys Memory VIP Architecture, here Synopsys R&D Director Bernie DeLay talks about protocol-aware debug for memories: a single environment to simultaneously visualize transactions, state machines, and memory arrays   http://bit.ly/1KKRmMn

Here’s where you can learn more about our Memory VIP

Posted in AMBA, DDR, Debug, LPDDR, Methodology | No Comments »

Video Frame Transmission in MIPI-DSI

Posted by VIP Experts on February 10th, 2015

DSI is a high speed serial interface targeted to reduce the cost of display sub-systems in a mobile device by transferring the data to the display module in real time without storing the data in the device. However this means that the data has to be sent with proper timing information. The most important aspect in verifying the MIPI-DSI is the timing parameters associated with the video frame transmission. I went through this whole exercises with a couple of VIP users and felt that this would be useful to share as it would benefit others in understanding the complexities involved in video frame transmission.

You can learn more about Synopsys’ MIPI DSI VIP here.

In this blog let’s see the timing details associated in transmitting the video frame by taking an example of RGB888 video frame in 640×480 resolution.

Figure1: RGB888 video format in 640×480 display

In RGB888 data format, each pixel has 3 bytes (24bits) of information, 1byte (8bits) for each component (R and G and B).  In 640×480 resolution frame, each line has 640 pixels and frame has 480 lines. Let’s see the timing information which needs to be sent along with this RGB data.

Every video frame should have below information (in the order of sequence):

  1. VSYNC (Sync information)
  2. VBP (Vertical back porch timing information)
  3. VACT (Active video data along with horizontal back porch and front porch timing)
  4. VFP (Vertical front porch timing information)

VSYNC (Sync information)

VSYNC has the information of synchronization pulses. Each pulse information is conveyed by sending Vertical Sync Start or Horizontal Sync Start packet (first pulse alone has VSS and remaining has HSS) followed by Horizontal Sync Active (which is nothing but a blanking packet), Horizontal Sync End and BLLP (which is again a blanking packet, if time permits low power state can be introduced), see figure2. This information is sent for each VSA (Vertical Sync Active) line.  In a simplified mode (non-burst/burst with sync event) host can only send the start event of synchronization pulse (only VSS or HSS), peripheral may regenerate the sync pulse from sync event received, whenever required. Each VSA line should be in the range of tL (line time), timing parameter as defined by the peripheral.

Timing parameters involved during this state is tL (Line Time), tHSA (Horizontal sync active time) and BLLP, constraints for these timing parameters are shown in the VACT section as these also depends on other parameters(HBP, HACT, HFP)  in VACT.

VBP (Vertical back porch timing information)

VBP has the information of vertical back porch timing. VBP line information is conveyed by sending Vertical Sync End or Horizontal Sync Start (first line alone has VSE and remaining has HSS) packet followed by Horizontal Sync Active (which is nothing but a blanking packet), Horizontal Sync End and BLLP (which is again a blanking packet, if time permits low power state can be introduced), see figure2. This information is sent for each VBP line. Each VBP line should be in the range of tL (line time).

Figure2: Non-Burst with sync pulse timing information (source: DSI 1.1 specification)

Timing parameters involved during this state is same as in VSA and will be covered in VACT as these also depends on other parameters (HBP, HACT, HFP) in VACT.

VACT (Active video data along with horizontal back porch and front porch timing)

VACT has the information of active video data along with horizontal back porch and horizontal front porch. Each VACT line has below information in it

  • HSYNC (Horizontal Sync information):

This is same as Hsync information we have seen in VSA or VBP. This is conveyed by HSS followed by HAS and HSE. Sync information should be in the range of tHSA timing parameter defined by peripheral.

  • HBP (Horizontal Back Porch timing information):

This is nothing but a blanking packet with the horizontal back porch timing information. This information should be in the range of tHBP timing parameter defined by peripheral.

  • Active line data (RGB888 data in our example)

This is the active video pixel data having the 24bit pixel information.  Each line is sent as one long packet or can be divided into multiple long packets. But multiple lines cannot be merged as a one long packet in which case we may not be able to convey the HBP and HFP of the second line. This information should be in the range of tHACT timing parameter defined by peripheral.

  • HFP (Horizontal Front Porch timing information)

This is nothing but a blanking packet with the horizontal front porch timing information. This information should be in the range of tHFP timing parameter defined by peripheral.

Each line should be in the range of tL (line time) timing parameter. Timing parameters involved during this state is tL, tHSA, tHBP, tHACT, tHFP. HSA should be in the range of tHSA minimum and maximum range. Similarly Line, HBP, HACT, HFP should be in the range of corresponding minimum and maximum timing parameters. It is difficult to constraint on real time and so we recommend converting the time into word count and constraint on word count. For example if minimum tL is tL_MIN and maximum tL is tL_MAX then calculate the word count by dividing it by bitrate and then by 8 (to get no of bytes = word count). Similarly calculate word counts for other parameters from their minimum and maximum range.

bit[15:0] min_line_wc = ((tL_MIN ) / bitrate) / 8;
bit[15:0] max_line_wc = ((tL_MAX ) / bitrate) / 8;
// Note: tL_MIN and tL_MAX are in micro seconds and so make sure the units of bitrate is also in micro seconds

constraint constraint_hsa {
    hsa_wc inside {[min_hsa_wc:max_hsa_wc]};
}

constraint constraint_hbp {
    hbp_wc inside {[min_hbp_wc:max_hbp_wc]};
}

constraint constraint_hfp {
    hfp_wc inside {[min_hfp_wc:max_hfp_wc]};
}

constraint constraint_hact {
    hact_wc inside {[min_hact_wc:max_hact_wc]};
    // Below constraint is required to make sure HACT has one byte of data for RGB in each pixel
    (hact_wc % 3) == 0;
}

constraint constraint_line {
    line_wc inside {[min_line_wc:max_line_wc]};
    // LINE = HSS (4bytes short packet) + HSA + HSE (4bytes short packet) + HBP + HACT + HFP
    line_wc == 4 + hsa_wc + 4 + hbp_wc + hact_wc + hfp_wc;
}

constraint constraint_bllp {
    //BLLP = LINE – HSS (4bytes short packet) – HSA – HSE (4bytes short packet)
    bllp_wc == line_wc – 4 – has_wc – 4;
}

Line timing is constraint to be sum of hsa_wc, hbp_wc, hact_wc, hfp_wc, HSS and HSE. HSS and HSE are 2 short packets and so 4 bytes each. Word count for BLLP (used in VSA, VBP, and VFP) should be line word count subtracted by has word count and 2 short packets, each for HSS and HSE.

VFP (Vertical front porch timing information)

VFP has the information of vertical front porch timing. VFP line information is conveyed by sending Horizontal Sync Start packet followed by Horizontal Sync Active (which is nothing but a blanking packet), Horizontal Sync End and BLLP (which is again a blanking packet, if time permits low power state can be introduced). This information is sent for VFP times. Each VFP line should be in the range of tL (line time) timing parameter as defined by the peripheral.

The range (min and max) for timing parameters mentioned in the DSI1.1 specification (Table 22, section 8.11.5) has been left to the discrete of peripheral suppliers. There are different modes of sending the video frame information other than the non-burst with sync pulse which is explained in this blog, with minute changes like, in non-burst with sync event, one need not send HSA and HSE rather can just contain with HSS. Similarly DSI also has burst mode where pixel data is transferred in a shorter time using time compressed burst format, thus giving more time for LP state. Let’s look at these other modes in follow up blogs. Hope this blogs helps those who are verifying the video frame transmission in DSI.

Authored by Hari Balisetty, Broadcom

You can learn more about Synopsys’ MIPI DSI VIP here.

Posted in MIPI | No Comments »

Key Advantages of Synopsys Memory VIP Architecture

Posted by VIP Experts on February 5th, 2015

Following on his recent talk about why Synopsys chose a SystemVerilog Architecture for interface VIP, here Synopsys R&D Director Bernie DeLay talks about how a similar architecture based on SystemVerilog for Memory VIP brings some key advantages for verifying the memory interfaces in your SoC design and memory controller IP:  http://bit.ly/1zaAcip 

Here’s where you can learn more about our Memory VIP

Posted in DDR, LPDDR, Methodology, SystemVerilog | No Comments »

A Strategy To Verify an AXI/ACE Compliant Interconnect (3 of 4)

Posted by VIP Experts on February 3rd, 2015

In the last post of this series, I wrote about basic coherent testing. In this post, I will discuss some of the nuances of the specification relative to accesses to overlapping addresses. Since multiple masters may be sharing the same location and the data could be distributed across the caches of different masters, this is an important part of the verification of a coherent system. The interconnect plays a very important role in maintaining coherency for such accesses.

Here’s where you can find more information on Verification IP for AMBA 4 AXI.

The Gory Details

There are three key aspects that the Interconnect should take care of relative to accesses to overlapping transactions.

  1. Sequencing transactions
  2. Timing of snoop accesses relative to responses to coherent transactions
  3. ‘Re-fetch’ of data from memory if it is possible that the data read from memory is different from the data read after all associated snoop transactions have completed

Sequencing transactions

Consider the example below:

Here, Master 1 and Master 2 want to write to the same location and store it in their local caches, at approximately the same time. For this, Master 1 and Master 2 send MakeUnique transactions (represented in the figure by 1a and 2a). For a moment let’s consider the effects of an incorrect behavior pattern of the interconnect. Let’s say the interconnect sends both Master 1 and Master 2 MakeInvalid snoop transactions (represented by 1b and 2b) corresponding to the MakeUnique transactions it received from Master 2 and Master 1 respectively. Once the masters respond with a snoop response (represented by 1c and 2c), the interconnect sends responses back to the masters (represented by 1d and 2d). When the transactions have completed in both Master 1 and Master 2, both masters update the cache to a Unique State. This violates protocol because a cacheline can be held in a Unique state by only master. Moreover, each master may store a different value in its local cache with both masters incorrectly thinking that they have a unique copy of the cacheline. Clearly, the effect of not sequencing correctly is incoherency as shown in the figure, where two masters have two different views of the data. In order to deal with this, the specification requires that such accesses to overlapping addresses be sequenced. The  specification states:

“It is the responsibility of the interconnect to ensure that there is a defined order in which transactions to the same cache line can occur, and that the defined order is the same for all components. In the case of two masters issuing transactions to the same cache line at approximately the same time, then the interconnect determines which of the transactions is sequenced first and which is sequenced last. The arbitration method used by the interconnect is not defined by the protocol. The interconnect indicates the order of transactions to the same cache line by sequencing transaction responses and snoop transactions to the masters. The ordering rules are:

• If a master issues a transaction to a cache line and it receives a snoop transaction to the same cache line before it receives a response to the transaction it has issued, then the snoop transaction is defined as ordered first.

• If a master issues a transaction to a cache line and it receives a response to the transaction before it receives a snoop transaction to the same cache line, then the transaction issued by the master is defined as ordered first.” [1]

In the above example, let us assume that the interconnect gives priority to Master 1. If so, it must send a snoop transaction (1b) to Master 2, wait for the snoop response (1c) and send the response back to Master 1 (1d). At the end of this sequence, Master 1 will have its cacheline in a unique state and may write a value in its cache. The interconnect may then sequence Master 2 and can send a snoop transaction (2b) to Master 1 which will invalidate the cacheline in Master 1, wait for a snoop response (2c) and send the response back to Master 2 (2d). At the end of this sequence, Master 1 has its cacheline invalidated and Master 2 will have its cacheline allocated to a Unique state.

Timing of Snoop Accesses Relative to Responses to Coherent Transactions

The specification lays down some rules on the ordering of responses to coherent transactions and snoop transactions to the same cacheline. These are given below:

“The interconnect must ensure the following:

• if the interconnect provides a master with a response to a transaction, it must not send that master a snoop transaction to the same cache line before it has received the associated RACK or WACK response from that master

• If the interconnect sends a snoop transaction to a master, it must not provide that master with a response to a transaction to the same cache line before it has received the associated CRRESP response from that master.”

An important point to note relative to this aspect of the protocol is that this requirement is not applicable to WriteBack and WriteClean transactions although it is not explicitly stated in the specification. Applying the above rules to WriteBack and WriteClean transactions could lead to a deadlock. This is because a master that receives a snoop transaction to a cacheline is allowed to stall it until any pending WriteBack or WriteClean transactions that it initiated or is about to initiate to the same cacheline is complete. In other words, this master must be allowed to receive a response to the WriteBack or WriteClean transaction before it can allow an incoming snoop to proceed (that is, respond to it). If the above rule is applied to WriteBack or WriteClean transactions, the interconnect will not be able to send a response to the WriteBack or WriteClean transaction since a snoop transaction has already been sent to the master. Therefore, it is important that this rule is not applied to WriteBack and WriteClean transactions.

Re-fetching Data from Memory

In certain circumstances, data may have to be re-fetched from memory. For example, consider that Master 1 issues a ReadShared transaction and Master 2 which has a dirty copy of the cacheline issues a WriteBack transaction. Let us say that the interconnect issues a read from main memory for the ReadShared transaction. After the Read transaction sent to main memory is complete, let us assume that the WriteBack makes progress. After this, any snoop transaction sent by the interconnect will not return data because the WriteBack would have invalidated the cacheline in Master 2. However, if the interconnect uses the data received in the prior read to memory, it will be stale, because a WriteBack transaction has updated memory after the read to memory was issued. It is therefore necessary to re-fetch data from memory and use that data to respond to Master 1. How do we detect issues related to this? These can be detected through coherency checks. In the above example, the ReadShared transaction will be passed clean data and its contents should match that of memory. If it doesn’t, it probably means that the interconnect used stale data to respond to the ReadShared transaction.

Testing Accesses to Overlapping Address

Testing all the scenarios related to accesses to overlapping addresses can be overwhelming. Given a system, there are multiple ports of different interface types which can send transactions to overlapping addresses. However, not all combinations of masters accessing a given address may be valid, because some masters may be allowed to access only certain address spaces and a group of masters may access only a restricted set of the address space and these group of masters form a shareability domain. Add to this, the fact that so many different transaction types can be initiated by a master with different initial states for a cacheline of a given address. The power of randomization and configuration-aware sequences can meet these requirements. A sequence that tests this could do the following:

  1. Based on the shareability domain given by a user, randomly choose two masters in that domain
  2. Based on the interface types of these masters, choose a random transaction type for each of these masters
  3. Initialize cachelines to valid, random states for a set of addresses
  4. Send transactions from both masters at the same time

Key Verification Points

All the verification points mentioned in the previous blog are applicable here as well. In addition to this, the following need to be checked:

  • Sequencing of transactions:  the order of transactions must be the same as seen by all masters
  • Ordering requirements relative to coherent responses and snoop accesses
  • Ensuring coherency when data needs to be re-fetched from memory

In this post, I have described the testing strategy and the key aspects of testing relative to accesses to overlapping addresses. In the next post I will write about testing of Barrier and DVM transactions.

Here’s where you can find more information on Verification IP for AMBA 4 AXI

Authored by Ray Varghese

Posted in AMBA | No Comments »

Spec-based Coverage Closure with Synopsys VIP

Posted by VIP Experts on January 29th, 2015

Here, Synopsys R&D Director Bernie DeLay talks about achieving coverage closure for protocol compliance checking and integration testing by utilizing the built-in verification plans and functional coverage provided with VC VIP.

He describes configuration-aware coverage: how it correlates with the user’s specification:  http://bit.ly/1EqRsIj

You can learn more about our Verification IP here.

Posted in Debug, Methodology, SystemVerilog | No Comments »