blob: 47df2d2725de93eec5d31335ced6ba955284bd7d [file] [log] [blame]
# -------------------------------------------------------------------------------
# subset.py
#
# Generating Subset of dataflow graph
#
# Copyright (C) 2013, Shinya Takamaeda-Yamazaki
# License: Apache 2.0
# -------------------------------------------------------------------------------
from __future__ import absolute_import
from __future__ import print_function
import sys
import os
import collections
import pyverilog.utils.util as util
import pyverilog.utils.verror as verror
import pyverilog.utils.signaltype as signaltype
from pyverilog.dataflow.merge import VerilogDataflowMerge
class VerilogSubset(VerilogDataflowMerge):
def __init__(self, topmodule, terms, binddict,
resolved_terms, resolved_binddict, constlist):
VerilogDataflowMerge.__init__(self, topmodule, terms, binddict,
resolved_terms, resolved_binddict, constlist)
self.clock_name = 'CLK'
self.clock_edge = 'posedge'
self.reset_name = 'RST_X'
self.reset_edge = 'negedge'
def set_clock_info(self, clock_name, clock_edge):
self.clock_name = clock_name
self.clock_edge = clock_edge
def set_reset_info(self, reset_name, reset_edge):
self.reset_name = reset_name
self.reset_edge = reset_edge
def getBindSubset(self, termname, visited_sources=set()):
term = self.getTerm(termname)
if term is None:
raise verror.DefinitionError('No such signal')
bindlist = self.getBindlist(termname)
nextsources = visited_sources.copy()
ret_binds = collections.OrderedDict()
for bind in bindlist:
if not termname in ret_binds:
ret_binds[termname] = []
ret_binds[termname].append(bind)
if bind.isClockEdge():
clock_name = bind.getClockName()
if clock_name != util.toTermname((self.topmodule, self.clock_name)):
r_binds, r_sources = self.getBindSubset(clock_name, nextsources)
nextsources |= r_sources
ret_binds = util.dictlistmerge(ret_binds, r_binds)
sources = self.getBindSources(termname)
for source in sources:
if source in visited_sources:
continue
nextsources.add(source)
r_binds, r_sources = self.getBindSubset(source, nextsources)
ret_binds = util.dictlistmerge(ret_binds, r_binds)
nextsources |= r_sources
return ret_binds, nextsources
def getBindSourceSubset(self, targets):
visited_binddict = collections.OrderedDict()
visited_sources = set()
for target in targets:
termname = util.toTermname(target)
r_binds, r_sources = self.getBindSubset(termname, visited_sources)
visited_sources |= r_sources
visited_binddict = util.dictlistmerge(visited_binddict, r_binds)
return visited_binddict, visited_sources
def getEntire(self):
visited_binddict = self.resolved_binddict
visited_sources = self.terms.keys()
return self._discretion(visited_binddict, visited_sources)
def getSubset(self, targets):
visited_binddict, visited_sources = self.getBindSourceSubset(targets)
return self._discretion(visited_binddict, visited_sources)
def _discretion(self, visited_binddict, visited_sources):
terms = collections.OrderedDict()
parameter = collections.OrderedDict()
assign = collections.OrderedDict()
always_clockedge = collections.OrderedDict()
always_combination = collections.OrderedDict()
# discretion the signal desclaration
for source in visited_sources:
termtype = self.getTermtype(source)
if signaltype.isParameter(termtype):
continue
if signaltype.isLocalparam(termtype):
continue
terms[source] = self.terms[source]
for left, rights in visited_binddict.items():
for right in rights:
assign_type = self.getAssignType(left, right)
if assign_type == 'clockedge':
if not left in always_clockedge:
always_clockedge[left] = set([])
always_clockedge[left].add(right)
elif assign_type == 'combination':
if not left in always_combination:
always_combination[left] = set([])
always_combination[left].add(right)
elif assign_type == 'assign':
if not left in assign:
assign[left] = set([])
assign[left].add(right)
elif assign_type == 'parameter':
parameter[left] = right
continue
elif assign_type == 'localparam':
parameter[left] = right
continue
if not left in terms:
terms[left] = self.terms[left]
return terms, parameter, assign, always_clockedge, always_combination