Commit 48ea2d41 authored by Andrey Filippov's avatar Andrey Filippov
Browse files

Working on hyperlinks to hierarchical names in tools output

parent 7c6665e9
Loading
Loading
Loading
Loading
+141 −2
Original line number Diff line number Diff line
@@ -3,10 +3,31 @@
import sys
import re
pattern=re.compile("\[[^[:]*:\d*]")
START_REF="(\\"
END_REF=" )"
PREFIX_REF="@{"
SUFFIX_REF="}@"
MODE_IMMED=0
MODE_SINGLE=1
MODE_ONCE=1
MODE_POSTPONE=3
tool="EXTERNAL_TOOL"
if len(sys.argv)>1:
    tool=sys.argv[1]
    
try:
    global_mode=int(sys.argv[2])
except:
    global_mode=MODE_POSTPONE # MODE_SINGLE

global_db={}
global_pRef=()        

try:
    global_top_module=int(sys.argv[3])
except:
    global_top_module="test_ps7"

def isProblem(string):
    if string.startswith("ERROR:") or string.startswith("WARNING:") or string.startswith("INFO:"):
        return True
@@ -20,22 +41,140 @@ def hasFileVivado(string): # [*:*]
    if pattern.findall(string):
        return True
    return False

def getLineSignalBit(string):
#    sys.stdout.write(START_REF)
    if START_REF in string:
        start = string.find(START_REF)
        end = string.find(END_REF,start)
        if end <0:
            return None
        line=string[:start]+PREFIX_REF+"%s"+SUFFIX_REF+string[end+len(END_REF):]
        ref=string[start+len(START_REF):end]
        # replace "/" (used in Xilinx Vivado) with "." for Verilog
        ref=ref.replace("/",".")
        if "[" in ref:
            bitStart= ref.find("[")
            bitEnd=ref.find("]",bitStart)
            try:
                bit=int(ref[bitStart+1:bitEnd])
                ref=ref[:bitStart+1]+"%s"+ref[bitEnd:]
            except:
                bit=-1
        else:
            bit=-1
        return (line,ref,bit)
    else:
        return None

def addRef(pRef):
    global global_db
#TODO: put try on all    
    if pRef:
        if not pRef[0] in global_db:
            global_db[pRef[0]]={}
        line_type=global_db[pRef[0]]
        if not pRef[1] in line_type:
             line_type[pRef[1]]=set()
        line_type[pRef[1]].add(pRef[2])
def getRanges(pRef):
    global global_db
    try:
        s=global_db[pRef[0]][pRef[1]]
    except:
        s=set();
    ranges=[];
    while s:
        l=min(s)
        s.remove(l)
        h=l+1
        while h in s:
            s.remove(h)
            h=h+1
        ranges.append((l,h))
    return ranges        
            
def printLineRef(pRef):
    global global_pRef
    global global_mode
    global global_db
    global global_top_module
    if pRef:
#        add(pRef) # just in case
        ranges=getRanges(pRef)
        if ranges:
            line=pRef[0]
            ref=pRef[1];
            if global_top_module:
               ref= global_top_module+"."+ref
            for rng in ranges:
                if (rng[0]<0):
                    sys.stdout.write(pRef[0]%(ref))
                elif (rng[1]<=(rng[0]+1)):
                    sys.stdout.write(pRef[0]%(ref%(rng[0])))
                else:
                    sys.stdout.write(pRef[0]%(ref%("%d:%d"%(rng[1]-1,rng[0]))))
            if (global_mode == MODE_ONCE):
                for rng in ranges:
                    try:
                        global_db[pRef[0]][pRef[1]] -= set(range(rng[0],rng[1]))
                        if not global_db[pRef[0]][pRef[1]]:
                            global_db[pRef[0]].pop(pRef[1])
                            if not global_db[pRef[0]]:
                                 global_db.pop(pRef[0])
                    except:
                        pass
                    
                
            

#add [tool_name:0000] if there is no {file:line_no] to generate Eclipse problem marker
def addTool(string,tool):
    global global_pRef
    global global_mode
    if hasFileVivado(string):
        if ((global_mode == MODE_SINGLE) or (global_mode == MODE_ONCE))  and global_pRef:
            printLineRef(global_pRef)
            global_pRef=None
        return string
    else:
        return string[:len(string)-1]+"[%s:0000]"%tool+string[len(string)-1]
#        return string[:len(string)-1]+"[%s:0000]"%tool+string[len(string)-1]
        if (string):
            string=string[:len(string)-1]+"[%s:0000]"%tool+string[len(string)-1]
        if global_mode != MODE_IMMED: 
            parseRef=getLineSignalBit(string)
        if (global_mode != MODE_IMMED) and parseRef:
            addRef(parseRef)
            if ((global_mode != MODE_POSTPONE) and global_pRef and 
             ((parseRef[0] != global_pRef[0]) or(parseRef[1] != global_pRef[1]))) :
                 printLineRef(global_pRef)
            global_pRef=parseRef
            return ""
        else:
            if ((global_mode == MODE_SINGLE) or (global_mode == MODE_ONCE))  and global_pRef:
                printLineRef(global_pRef)
                global_pRef=None
            return string


#### Start
pline=""
for line in iter(sys.stdin.readline,''):
    if isProblem(pline):
        if line.startswith("   ") :
            pline = pline[:len(pline)-1]+line[2:]
        else:
            sys.stdout.write(addTool(pline,tool))
            pline=addTool(pline,tool)
            sys.stdout.write(pline)
            pline = line
    else:
        pline = line
if isProblem(pline):
    sys.stdout.write(addTool(pline,tool))
    addTool("",tool)
    
if global_mode == MODE_POSTPONE:
    for line in global_db:
        for ref in global_db[line]:
             printLineRef((line,ref,0)) # will not add
+1 −0
Original line number Diff line number Diff line
@@ -122,6 +122,7 @@
	<syntax name="DashListCommon"      format="-%%ParamName %(%%ParamValue%| %)" />
	<syntax name="DashName"            format=" -%%ParamName" />
	<syntax name="QuotedDash"          format=' -%%ParamName "%%ParamValue"' />
	<syntax name="NameValue"           format=" %%ParamName %%ParamValue" />
<!--
Does not work according to 2.2.1. "Inside text-repetitor, one and only one pattern-generator is mandatory".
	
+7 −1
Original line number Diff line number Diff line
@@ -92,6 +92,11 @@
        <parameter id="parser_name" label="Vivado parser name" tooltip= "Vivado output parser script path"
        			default="parser_vivado.py" visible="true" omit="" type="String" format="CopyValue"/>

        <parameter	id="MaxMsg"    outid="set_param messaging.defaultLimit"
        		    label="Maximal messages" tooltip= "Maximum number of messages to output (per type)"
        			default="100"  visible="true" omit="100" type="Cardinal" format="NameValue"/>

        			
		<input>
			<group name="Parser"
			       weight="10">
@@ -100,6 +105,7 @@
				"---"
				"ShowWarnings"
				"ShowInfo"
				"MaxMsg"
				"GrepEWI"
				"---"
				"NoFileProblem"
+25 −4
Original line number Diff line number Diff line
@@ -120,6 +120,14 @@
		           default="true"
		           type= "Boolean" format="None"/>

		<parameter id="SkipPreSynth" label="Skip pre-synthesis" tooltip="Do not run pre-synthesis TCL commands"
		           default="false" type= "Boolean" format="None"/>
                   
		<parameter id="PreTCL" label="Pre-synthesis TCL commands" tooltip="TCL commands to run before synthesis"
			type="Stringlist" format="ProgramSyntax" default="" omit=""
			readonly="false" visible="true" />

		           
  
<!-- synth_design arguments -->  

@@ -205,7 +213,7 @@
        <parameter id="PreGrepW"/>
        <parameter id="PreGrepI"/>
        <parameter id="GrepEWI"/>
        
        <parameter id="MaxMsg"/>
<!--  invisible/calculated parameters -->        			
        <parameter	id="AutosaveVivadoSynthesis" default="?%%ChosenActionIndex=0 ^ %SkipSnapshotSynth=false : true, false"
                    visible="false" type="Boolean" format="None"/>
@@ -219,6 +227,9 @@
				"SkipSnapshotSynth"
 				"SnapshotSynth" <!--  same as in project -->
				"ResetProject"
				"---"
				"SkipPreSynth"
				"PreTCL"
			</group>
			<group name="Synthesis">
		        "directive"
@@ -294,6 +305,16 @@
	                     "%read_xdc\n"
				      </if-not>
			      </if>
		          <!-- Run pre-synthesis TCL commands (if specified) -->
			      <if SkipPreSynth="false">
				      <if-not PreTCL="">
				      		"%PreTCL\n"
				      </if-not>
				      <if PreTCL="">
				      		"puts \"No pre-synthesis TCL commands specified\"\n"'
				      </if>
			      </if>
			      "%MaxMsg\n"
			      "synth_design"
		          "%top"
			      <if VivadoSynthActionIndex="0">