2013年5月27日 星期一

Xilinx ucf constrain notes

ucf constrain

  • timing constrain
    • input pad to first flip-flop groups
      • input offset
    • internal flip-flop to flip flop groups
      • period
    • out flip-flop to output pad groups 
      • output offset
    • clock
      • offset
      • duty
      • jitter
      • rotate
        • 90 
        • 180
        • 270
  • multi cycle path
    • from one clock dom to another clock dom
    • using async fifo to avoid the data missing issue
      • data valid
      • req fifo.empty/fifo.full
      • status
  • false path
    • not normal paths
    • -to
    • -from -to
    • -through
    • -from -through -to 
  • data path
    • normal paths
  • fanout
    • set maxfanout
  • DCM / DLL/ PLL
    • ECO div/mux
  • TNM (timing group)

  • pin assignment constrain
    • pad assignment 

  • slack
    • Slack (setup path): =  (requirement - (data path - clock path 
    • skew + uncertainty))
    • Slack (hold path): = requirement - (clock path skew + uncertainty - data path) 

2013年5月25日 星期六

sytemverilog virtual interface setup time hold time check

we use systemveirlog virtual interface and simulator keys $setup, $hold to check the setup/hold time.




interface my_if #(c_clk_high_time = 5,
                  c_clk_low_time  = 5) (input clk, en);
  specify
    specparam clk_high_time = c_clk_high_time;
    specparam clk_low_time = c_clk_row_time;
    $setup(en, negedge clk, clk_high_time * 4 / 5);
    $hold(negedge clk, en, clk_low_time * 4 / 5);
  endspecify

endinterface;
or
module timing_checks_in_sv (input clk, data, ...); 
  ...
  event ev_data_delayed_toggled;
  
  always @(data)
  begin
    fork
    begin
      # tSetup;
      -> ev_data_delayed_toggled;
    end
    join_none
  end

  property setup_hold_time_checker;
    time curr_time;
    @(posedge clk) (1, curr_time = $time) |->
    @(ev_data_delayed_toggled) (($time - curr_time) > (tSetup + tHold)); // check data arrival time is meet $time - cur_time > (SetUp + Hold)
  endproperty : setup_hold_time_checker

  ASSERT_SETUP_HOLD: assert property setup_hold_time_checker;
endmodule 

ref :
http://learn-systemverilog.blogspot.tw/2010/07/writing-systemverilog-assertion-for.html
http://www.ee.ed.ac.uk/~gerard/Teach/Verilog/me5cds/me95rh.html

2013年5月24日 星期五

UVM TLM2.0 notes

if your are a ESL designer, you may heard about the SystemC TLM2.0 model that can help designer to design system level evaluation models very quick without any detail info such as Pin assignment, protocol selected, timing(real).... as you known, if you can use these abstract level api(blocking_trans, non_blocking_trans), you can replay or remodel design very quick without reconstruct your design again when the project is in evaluation phase. right now you can migrate your design from SystemC to UVM1.1d, because UVM1.1d is based on SystemVerilog that can be more suitable for EDA vendor supported and more friendly for verification designer... that's my guess ...


socket channel connection
initiator_socket : as same as master socket
target_socket    : as same as slave socket

ex:
1. create sockets in master/slave sides
initiator_socket ini_socket; // master socket
target_socket tgt_socket; // slave socket

connect(ini_socket, [tat_socket,...]) // connect one master to multi slaves

2. create trx payload to socket channel in master side
Trx trx = new();
trx.addr = 0x100;
trx.data = [0x1, 0x2, 0x3]; // generation payload
init_socket.write(trx);

3. collected trx in slave side
trx = tgt_socket.get_trx();     // fetch trx from socket channel fifo, and double check the trx is valid
if (trx != NULL) { // do something .... }


4. blocking trx
blocking interface conveys transactions in blocking fashion; its methods do not return until the transaction has been successfully sent or retrieved.  Because delivery may consume time to complete, the methods in such an interface are declared as tasks

5. non blocking trx
A non-blocking interface attempts to convey a transaction without consuming simulation time.  Its methods are declared as functions.  Because delivery may fail (e.g. the target component is busy and can not accept the request), the methods may return with failed status.

6. port, export, imps
port: instantiated in components that require, or use, the associate interface to initiate transaction requests. export : instantiated by components that forward an implementation of the methods defined in the associated interface. The implementation is typically provided by an imp port in a child component.

2013年5月21日 星期二

deep copy or shadow copy in your systemverilog object

as the same methodology as c/c++ or any languages. we usually used copy function to copy trx to avoid the overwrite trx when the trx had new ptr triggered. this is an sample example about what's the difference between deep copy and shadow copy, in short word. deep copy is top down copy, copy from this(current) level info to it's parents info. shadow copy is template current level copy, only for this level info.
class Based #(type T=int unsigned);
  T val;

  function new (T v=0);
    val = v; // assign new val
  endfunction : new

  virtual function void deep_copy(Based b);
    assert(b!=null);
    b.val = val; // b.val = this.val
  endfunction : deep_copy

  virtual function void shadow_copy(Based b);
    assert(b!=null);
    b.val = val; // b.val = this.val
  endfunction : shadow_copy

  virtual function bool eq(Based b);
    return b.val == val;
  endfunction : eq

endclass : Based

class A #(type T=int unsigned) extens Based;
  T val_a

  function new (T v=0);
    super.new();
    val_a = v; // assign val_a
  endfunction : new 

  virtual function void deep_copy(A a); 
    assert(a!=null);
    Based b;
    a.val_a = val_a;
    $cast(b,a);
    super.deep_copy(b);
    // or
    // a.val_a = val_a
    // a.val  = super.val
  endfunction : deep_copy

  // operator overwrite ... eq, lt, lt, ...
  virtual function bool eq(A a0);
    assert(a0!=null);
    Based b0;
    $cast(b0,a0);
    return val_a == a0.val_a & super.eq(b0);
  endfunction : eq


endclass : A


A a0 = new(1);
A a1 = new(2);

a0.val_a = 3;
a0.val = 2;

a0.deep_copy(a1);

// check a0, a1 contains are eq  a0 = a1
assert(a0.eq(a1));  

waveform modeling

as well as your are a ATE engineer, you may very familiar with the ATE test pattern formats that can transfer the waveform info into sample digital codes.
this is  a very example code for req/grant test case.
// timing modeling
task req_grant_00();                                                                                                                                                                 
  m_vif.REQ   <= 0;
  m_vif.GRANT <= 0;
  @(posedge m_vif.CLK);
endtask : req_grant_00

task req_grant_01();
  m_vif.REQ   <= 0;
  m_vif.GRANT <= 1;
  @(posedge m_vif.CLK);
endtask : req_grant_01

task req_grant_10();
  m_vif.REQ   <= 1;
  m_vif.GRANT <= 0;
  @(posedge m_vif.CLK);
endtask : req_grant_10

task req_grant_11();
  m_vif.REQ   <= 1;
  m_vif.GRANT <= 1;
  @(posedge m_vif.CLK);
endtask : req_grant_1

task

task wave_gen();
  list = {`ON_OFF, `ON_ON, `OFF_ON, `OFF_OFF};

  foreach(list[i]) begin
    case(list[i])
      `ON_OFF : req_grant_10();
      `ON_ON  : req_grant_11();
      `OFF_OFF: req_grant_00();
      `OFF_ON : req_grant_01();
    endcase
  end 
endtask

2013年5月17日 星期五

UVM scoreboard to check with c/c++ golden model via uvm analysis port

1.systemverilog DPI interface to interconnect the c/c++ part and systemverilog part

2.uvm analysis port to valid event channel
// golden cehck via uvm analysis port
// ps : the port should be connected to it's callback module. that uvm can collected.
// ex: item_port.connect( analysis_export );

uvm_analysis_port item_port

// DPI import ... for our golen model
import "DPI" void *yuv2rgb(int unsigned y, int unsigned u, int unsigned v);  
// yub2rgb(void* trx); using ptr is a more friendly interface....
import "DPI" void *rgb2yuv(int unsigned r, int unsigned g, int unsigned b); 

// callback func called from callable func/module
task callback(sample_trx trx);

  assert(trx!=null);
  if (trx.type == YUV2RGB)
    dpi_c_yuv2rgb(trx);
  else
    dpi_c_rgb2yuv(trx);

endtask

void dpi_c_yuv2rgb(sample_trx trx);
                                                                                                                                                                                    
  assert(trx!=null);
  c_rst = yuv2rgb(trx.y, trx.u, trx.v)
  assert( c_rst.r == trx.r &
          c_rst.g == trx.g &
          c_rst.b == trx.b);
endtask

2013年5月16日 星期四

adding performance monitor to your design

the UVM monitor can play not only a functional checker but also a performance checker which means, user can use it more quickly to find out where is their design bottleneck without waveform tracing. in this topic, we focused on how to use UVM monitor to point out the collected transactions had timing violation immediately when the simulation was running.

we write a UVM SystemVerilog "req happened until grant received" to our demo case.

 
// spawn sub procs(threads)                                                                                                       
task run_phase(uvm_phase);
  fork
    sent_req();
    sent_grant();

    collected_req();
    collected_grant();

    check_performance();
    check_protocol();
  join
endtask : run_phase


// sent req 
task sent_req();

  forever begin
    // random  wait ....
    repeat($urandom_range(8,16)) @(posedge m_vif.CLK);

    // sent req 
    `delay(conf.half_cycle);
    m_vif.REQ <= `TRUE;
    @(posedge m_vif.CLK);

    // wait until grant received
    while(!m_vif.GRANT) @(posedge m_vif.CLK);

    // free req 
    `delay(conf.half_cycle);
    m_vif.REQ <= `FALSE;
    @(posedge m_vif.CLK);

  end

endtask : sent_req


// snet grant
task sent grant();

  forever begin

    // sent unvalid grant
    `delay(conf.half_cycle);
    m_vif.GRANT <= `FALSE;
    @(posedge m_vif.CLK);

    // wait until req received
    while(!m_vif.REQ) @(posedge m_vif.CLK);

    // random wait ...
    repeat($urandom_range(8,16)) @(posedge m_vif.CLK);

    // sent valid grant to free req
    `delay(conf.half_cycle);
    m_vif.GRANT <= `TRUE;
    @(posedge m_vif.CLK);

  end

endtask : sent grant                                                                                                              


task collected_req();

  forever begin
     // @ neg edge check
      @(negedge m_vif.CLK iff m_vif.REQ);

      // assert only one fifo deep when req/grant case
      assert(m_trx_q.size() < 1);

      // collect trx
      TRX m_trx = new();
      m_trx.REQ = m_vif.REQ;
      m_trx.TIME = $time;
      m_trx_q.push_back(m_trx);

  end
endtask : collected_req


task collected_grant();

  forever begin
    // @ neg edge cehck
    @(negedge m_vif.CLK iff m_vif.GRANT);

    //assert the queue size must be 1, means the req has been stored in the queue
    assert(m_trx.q.size() == 1);

    // free queue
    m_trx_q.pop_front();

  end
                                                                                                                                  
endtask : collected_grant


task check_performance();
  forever begin
    // at each pos edge check
    @(posedge m_vif.CLK);

    //assert queue
    if (m_trx_q.size() == 1) begin
        if ($time - m_trx_q[0].TIME > conf.min_offset) begin
          `uvm_error(get_full_name(), {$psprintf("out of time %d"), conf.min_offset}, UVM_LOW)
        end else begin
          `uvm_error(get_full_name(), {$psprintf("req/grant seuence is not valid")}, UVM_LOW)
        end
    end
  end

endtask             

2013年5月15日 星期三

python unittest + UVM testsuites + Jenkins = DUT regression

in recently, i got a order from my boss. he asked me to build up a automatically unittest env that can very quick to know where is the problem such as protocol error, functional error, timing error ... when the design is changed. the below list is my auto regression flow and requirements


  • i used python unittest to our based unittest framework
    • python unittest
      • check testsuite is pass/fail
    • python nose 
      • call python unittest folder and testsuites
    • python subprocess/multiprocess
      • call system call (irun, vcs....)
    • python re(regular expression)
      • check simulation result is pass/faill if the error tokens are not found

  • UVM testsuites
    • define UVM test sequence for your simulator
      • irun -uvm +UVM_TESTNAME=""...
    • prepare your test sequence
      • like xxSequences.sv
        • test_1read_after_1write
        • test_mread_after_mwrite
        • test_read_write_at_same_time
  • jenkins
    • job manager
      • daily regression run 

2013年5月8日 星期三

Microsemi BFM script language


  • a very useful script language for bus performance estimation and bus functional check
    • example:
      • # read B uart 0;
        Reading offset 0 of uart – data = 0x1c
        # write B uart 4 bb;
        Writing 0xbb to offset 4 of uart
        # read B uart 8;
        Reading offset 8 of uart – data = 0x28
        # write B mac 30 11;
        Writing 0x11 to offset 30 of mac
        # readcheck B mac 11;
        Reading offset 0 of mac
        Error: Expected data = 0x11, Actual data = 0x22
        Test Failed, with 1 error
          
          

      • 
        
      • advantage
        • simple 
        • error check 
      • disadvantage
        • no time stamp
          • maybe it use ASAP(as soon as possible) methodology to transfer transactions, it means masters or slaves are not in busy status, or fetch/push buffers not full
        • no atomic transfer
          • if valid/ready is not continuous in the burst transaction, the interlevel transactions will happened, 
          • like A1(4), A2(4), A1 has burst 4 trxs, A2 has burst 4 trxs.
            • A1(2), A2(2), A1(2), A2(2) => atomic transactions when the A1 or A2 has busy or error in the internal transaction.

    synplify + ise TCL xflow

    http://outputlogic.com/xcell_using_xilinx_tools/74_xperts_04.pdf https://github.com/dlitz/openmsp430/blob/master/core/synthesis/actel/synplify.tcl https://github.com/martinjthompson/VHDL-compare/blob/master/Synplify/rev_1/run_ise.tcl https://github.com/martinjthompson/VHDL-compare/tree/master/Synplify https://github.com/zakiali/pocket_corr/blob/master/pfb_core/SgIseProject.tcl

    2013年5月6日 星期一

    SystemVerilog Unit test = SVUnit = TDD(test drivent Development of Verification IP)

    SystemVerilog UVM Unit test framework


    • Methodology
      • get UVM domain class and register it to unit test list
      • fetch runnable  test suite from test list, the sorted priority is based on schedule manager definition
      • collect test suite UVM report 
      • report pass/fail coverages

    ex:
     
      //************************************************************
      // Test:
      //   xformation_test
      //  
      // Desc:
      //   ensure that objects going through the simple model have                                                                                                                       
      //   their field property updated appropriately (multiply by
      //   2)
      //************************************************************
      `SVTEST(xformation_test)
        begin
          simple_xaction in_tr = new();
          simple_xaction out_tr;
     
          void'(in_tr.randomize() with { field == 2; }); 
     
          put_port.put(in_tr);
          get_port.get(out_tr);
     
          `FAIL_IF(in_tr.field != 2); 
          `FAIL_IF(out_tr.field != 4); 
        end 
      `SVTEST_END(xformation_test)
    

    ref : http://www.agilesoc.com/svunit/

    2013年5月4日 星期六

    SystemVerilog parallel tasks by event trigger

    SystemVeilog event trigger is implemented by event manager, that can define the dependences of parent and child tasks. and each tasks will be registered in event list when the building phase is done, after it, the task manager will sort event list by it's dependence or timing (such as E(timing(0)(0)), E(timing(1)(1)) E0 > E1, E0 will be run first than E1.

    AXI write phase example. using delay constrain to define which one is first, which one is second


    // @ write phase before write addr phase
    // cfg.write_addr_delay = 10;
    // cdg.write_data_phase = 0;
    
    
    // @ write phase after write addr phase
    // cfg.write_addr_phase = 0;
    // cfg.write_data_phase = 10;
    
    task run_phase();
      fork
        write_addr_phase();
        write_data_phase();
        get_next_trx();
      join
    endtask
    
    
    task get_next_trx();
      forever begin
        @(posedge vif.clk);
        if (sequencer.item.has_next_trx()) begin
          trx = sequencer.item.get_next_trx();
          if (trx.rw == `WRITE)
            -> start_write;
          else
            -> start_read;
        end 
      end 
    endtask
    
    task write_addr_phase();
      forever begin
        if (start_write.triggered) begin
          repeat(cfg.write_addr_delay) @(posedge vif.clk);
          // do write phase
        end 
      end 
    endtask
    
    task write_data_phase();
      forever begin
        if (start_write.triggered) begin
          repeat(cfg.write_data_delay) @(posedge vif.clk);
          // do data phase
      end 
    endtask
    
    

    2013年5月1日 星期三

    PyHVL = verilog PLI is going died....


    • open source tool supported 
      • iverilog VPI 2.0 
        • http://iverilog.wikia.com/wiki/Using_VPI
    • what's VPI/PLI(Verilog Procedural Interface)
      • http://en.wikipedia.org/wiki/Verilog_Procedural_Interface
    • what's DPI(SystemVerilog Direct Programming Interface)
      • http://en.wikipedia.org/wiki/SystemVerilog_DPI
    • third party language support 
      • perl
        • http://www.veripool.org/wiki/verilog-pli/Manual-verilog-pli
      • ruby
        • http://snk.tuxfamily.org/lib/ruby-vpi/
      • python
        • http://sourceforge.net/projects/pyhvl/?source=dlp
    • disadvantage
      • hard to read
        • more rules need to follow
          • init pli
          • register pli 
          • free pli
        • using third part language to mix simulation run that's very difficult for designer view. they need to know how to driver system call and catch the simulation error when the segment fault happened 
        • only for behavior model verification / profile
        • why not using SystemVerilog + DPI to replace it?
          • more closer with Verilog language
          • more easily to understand 
          • OO suport
          • more flexible to designer(customer DPI)
          • UVM 

    AXI BFM(bus function model)


    • standard protocol
      • write phase (fork events)
        • write address phase
          • collect transactions when AXI_AWVALID and AXI_AWREADY
        • write data phase
          • collect transactions when AXI_WVALID and AXI_WREADY
        • write response phase
          • collect transactions when AXI_BVALID and AXI_BREADY
        • the valid transaction should have the same ID at address, data, response 

      • read phase(fork events)
        • read address phase
          • collect transactions when AXI_ARVALID and AXI_ARREADY
        • read data phase
          • collect transactions when AXI_RVALID and AXI_RREADY
        • the valid transaction should have the same ID at address, data
    • extend protocol
      • qos
      • user
      • region
      • lock
      • cache
      • strb
    • https://github.com/funningboy/axi-bfm