2013年1月5日 星期六

vcd file info tracer



在 IP 驗證時, 除了用 synopsys VIP 來驗證 bus 的 protocol 跟 performance 的分析. 但有時候為了 customer design 時, 會把 protocol 作些變形, 這樣就不符合 standard protocol 的方式. 底下就用大家都熟知的 VCD 擋把 bus info 錄出來轉到 data base 讓使用者可以直接用 query 的方式把 performance 跟 dynamic power 算出來. 底下用 vcdparser.py 把 vcd info 讀出來.之後再透過後端的 big data 處理把資料寫到 data base 上.
python db link
"""
conn = sqlite3.connect('example.db')
c = conn.cursor()

c.execute('''CREATE TABLE vcd
      (version, timeType(s,ns,fs...), time''')
c.execute('''CREATE TABLE _scopes_
      (scopeDomain, scopeType(fork,module,...), top(scopeNm)''')
c.execute('''CREATE TABLE _signals_
      (scopeDomain, signalID, signalType(Real,Bit,...), width, name''')
c.execute('''CREATE TABLE _signalID_ # _0_
             (time , val)''')

# ex :
#
# module top();
# #0 clk =1;
# #5 clk =0; ...
# endmodule

# header create
c.execute('''CREATE TABLE _scopes_
      (scopeDomain, scopeType, scopeNm''')
c.execute('''CREATE TABLE _signals_
      (scopeDomain, signalID, signalType, width, name''')
c.execute('''CREATE TABLE _signalID_ # _0_
             (time , val)''')

# body create
c.execute("INSERT INTO _scopes_ VALUES (0, 1(module), "top")")
c.execute("INSERT INTO _signals_ VALUES (0, 0, 0(bit), "top.clk")")

c.execute("INSERT INTO _0_ VALUES (0, 1)")
c.execute("INSERT INTO _1_ VALUES (5, 0)")

#
conn.commit()
c.close()
"""
VcdParser.py
from __future__ import with_statement
from itertools import dropwhile, takewhile, izip
from collections import defaultdict
from pprint import pprint as pp

from os import *
import io
from src.vcdDB  import *
from src.vcdErr import *
from src.vcdContext import *


class VcdParser(object):
  """ parser VCD 2 VcdDB """

  def __init__(self,vcd=None):
    self._vfile = None

    try:
      if not isinstance(vcd,VcdDB):
       raise VcdParserError("vcdDB ptr is None")
    except VcdDBError, e:
      print e._msg

    self._vcd   = vcd


  def parse_error(self,tokeniser, keyword):
    raise "Don't understand keyword: " + keyword


  def do_drop_declaration(self,tokeniser, keyword):
    dropwhile(lambda x: x != "$end", tokeniser).next()


  def do_vcd_date(self,tokeniser, keyword):
    """ parser vcd date and set 2 VcdDB::date """

    date = ' '.join(takewhile(lambda x: x != "$end", tokeniser))
    self._vcd.set_date(date)


  def do_vcd_timescale(self,tokeniser, keyword):
    """ parser vcd timescale and set 2 VcdDB::timescale """

    val, scale = tuple(takewhile(lambda x: x!= "$end", tokeniser))
    self._vcd.set_timescale(scale,val)


  def do_vcd_version(self,tokeniser, keyword):
    """ parser vcd version and set 2 VcdDB::version """

    version = ' '.join(takewhile(lambda x: x!= "$end", tokeniser))
    self._vcd.set_version(version)


  def do_vcd_enddefinitions(self,tokeniser, keyword):
    """ parser vcd enddefinitions """

    self.do_drop_declaration(tokeniser, keyword)
    self._vcd.set_enddefinition(1)


  def do_vcd_scope(self,tokeniser, keyword):
    """ parser vcd scope and set 2 VcdDB::scope """

    scope, name = tuple(takewhile(lambda x: x != "$end", tokeniser))
    self._vcd.set_scope(self._vcd,scope,name)


  def do_vcd_upscope(self,tokeniser, keyword):
    """ parser vcd upscope """

    tokeniser.next()


  def do_vcd_var(self,tokeniser, keyword):
    """ parser vcd signalInfo and set 2 vcdDB::nameMap """

    varTyp, width, uniqNm, refNm = tuple(takewhile(lambda x: x != "$end", tokeniser))
    scope = self._vcd.get_end_scope()
    maptb = self._vcd.get_mapTb()

    scope.set_signals(scope,varTyp,refNm,width)
    signal = scope.get_signal(refNm)
    maptb.set_tb(uniqNm,signal)


  def do_vcd_dumpall(tokeniser, keyword): pass
  def do_vcd_dumpoff(tokeniser, keyword): pass
  def do_vcd_dumpon(tokeniser, keyword): pass
  def do_vcd_dumpvars(tokeniser, keyword): pass
  def do_vcd_end(tokeniser, keyword): pass


  def vcd_2_VcdDB(self,vcdfile=None):
    """ parser vcd file 2 VcdDB format """

  # define key 2 proc
    keyword2handler = {
        # declaration_keyword ::=
        "$comment":        self.do_drop_declaration,
        "$date":           self.do_vcd_date,
        "$enddefinitions": self.do_vcd_enddefinitions,
        "$scope":          self.do_vcd_scope,
        "$timescale":      self.do_vcd_timescale,
        "$upscope":        self.do_vcd_upscope,
        "$var":            self.do_vcd_var,
        "$version":        self.do_vcd_version,
        # simulation_keyword ::=
        "$dumpall":        self.do_vcd_dumpall,
        "$dumpoff":        self.do_vcd_dumpoff,
        "$dumpon":         self.do_vcd_dumpon,
        "$dumpvars":       self.do_vcd_dumpvars,
        "$end":            self.do_vcd_end,
        }

    keyword2handler = defaultdict(self.parse_error, keyword2handler)

    f = io.open(vcdfile,"r")
    tokeniser = (word for line in f for word in line.split() if word)
    time = 0
    for count,token in enumerate(tokeniser):
      if self._vcd.get_enddefinition() != 1:
        keyword2handler[token](tokeniser, token)
      else:
        c, rest = token[0], token[1:]
        if c == '$':
          # skip $dump* tokens and $end tokens in sim section
          continue
        # time info
        elif c == '#':
          time = rest
        # (1)bit info
        elif c in '01xXzZ':
          uniqNm = rest
          val    = c
          maptb  = self._vcd.get_mapTb()
     signal = maptb.get_tb(uniqNm)
          signal.set_NodeInfoList(signal,time,"bit",val)
        # binary info
        elif c in 'bB':
   uniqNm = tokeniser.next()
   val    = rest
   maptb  = self._vcd.get_mapTb()
   signal = maptb.get_tb(uniqNm)
   signal.set_NodeInfoList(signal,time,"binary",val)
        # real info
        elif c in 'rR':
   uniqNm = tokeniser.next()
   val    = rest
   maptb  = self._vcd.get_mapTb()
   signal = maptb.get_tb(uniqNm)
   signal.set_NodeInfoList(signal,time,"real",val)
        else:
          raise "Don't understand: %s After %i words" % (token, count)

    f.close()

    return self._vcd

code download 主要改寫 writing-vcd-to-toggle-count-generator 成我們要跟底層溝通的api




Refs:
http://www.semiwiki.com/forum/content/753-what-changes-expect-verification-ip-landscape-after-synopsys-acquisition-nsys.html
VMM performance user guide
http://vmmcentral.org/pdfs/perf_user_guide.pdf
http://i.cmpnet.com/eetimes/news/online/2010/09/Whitepaper_Mediatek_2010.pdf


沒有留言:

張貼留言