Exemplo n.º 1
0
    def __init__(self, component, chip, inputs, outputs):
        self.chip = chip
        self.inputs = inputs
        self.outputs = outputs
        self.component = component
        self.chip.instances.append(self)
        if component not in chip.components:
            chip.components.append(component)

        if len(self.component.inputs) != len(self.inputs):
            raise C2CHIPError("Instance %s does not have the right number or inputs"%self.name)

        if len(self.component.outputs) != len(self.outputs):
            raise C2CHIPError("Instance %s does not have the right number or outputs"%self.name)

        for i in inputs.values():
            if i.sink is not None:
                raise C2CHIPError("%s allready has a sink"%i.name)
            i.sink = self

        for i in outputs.values():
            if i.source is not None:
                raise C2CHIPError("%s has allready has a source"%i.name)
            i.source = self

        for i in inputs.keys():
            if i not in self.component.inputs:
                raise C2CHIPError("%s is not an input of component %s"%(i, component.name))

        for i in outputs.keys():
            if i not in self.component.outputs:
                raise C2CHIPError("%s has allready has a source %s"%(i, component.name))
Exemplo n.º 2
0
    def prepare_for_simulation(self, inputs, outputs):
        #        for io_port in self.inputs.values() + self.outputs.values():
        #            io_port.delete()
        self.inputs = inputs
        self.outputs = outputs

        # generate a python simulation model of the instance
        ret = chips.compiler.compiler.make_python_model(
            self.asm_program, inputs, outputs, self.debug, self.profile)

        #TODO use inputs/outputs from asm_program
        self.model, component_inputs, component_outputs = ret

        # check that correct number of wires have been passed in
        if len(component_inputs) != len(self.inputs):
            for i in component_inputs:
                print "component inputs:"
            for i in self.inputs:
                print "instance inputs:"
            raise C2CHIPError(
                "Instance %s does not have the right number or inputs" %
                (self.component_name))

        if len(component_outputs) != len(self.outputs):
            raise C2CHIPError(
                "Instance %s does not have the right number or outputs" %
                (self.component_name))

        # check for multiple sources or sinks
        for i in inputs.values():
            if i.sink is not None:
                raise C2CHIPError("%s already has a sink" % i.name, i.filename,
                                  i.lineno)
            i.sink = self

        for i in outputs.values():
            if i.source is not None:
                raise C2CHIPError("%s has already has a source" %
                                  (i.name, i.filename, i.lineno))
            i.source = self

        for i in inputs.keys():
            if i not in component_inputs:
                raise C2CHIPError(
                    "%s is not an input of component %s" %
                    (i, self.component_name), i.filename, i.lineno)

        for i in outputs.keys():
            if i not in component_outputs:
                raise C2CHIPError(
                    "%s is not an output of component %s" %
                    (i, self.component_name), i.filename, i.lineno)
Exemplo n.º 3
0
    def __init__(self,
                 component,
                 chip,
                 parameters,
                 inputs,
                 outputs,
                 debug=False,
                 profile=False):
        self.chip = chip
        self.parameters = parameters
        self.inputs = inputs
        self.outputs = outputs
        self.component = component
        self.chip.instances.append(self)
        self.debug = debug
        self.profile = profile
        self.sn = chip.sn
        chip.sn += 1
        _, self.filename, self.lineno, _, _, _ = inspect.stack()[1]

        # generate a python simulation model of the instance
        ret = chips.compiler.compiler.compile_python_model(
            self.component.C_file, self.component.options, parameters, inputs,
            outputs, self.debug, self.profile, self.sn)

        self.model, component_inputs, component_outputs, component_name = ret

        self.component_name = component_name
        if component_name not in chip.components:
            chip.components[component_name] = self

        # check that correct number of wires have been passed in
        if len(component_inputs) != len(self.inputs):
            for i in component_inputs:
                print "component inputs:"
            for i in self.inputs:
                print "instance inputs:"
            raise C2CHIPError(
                "Instance %s does not have the right number or inputs" %
                (component_name))

        if len(component_outputs) != len(self.outputs):
            raise C2CHIPError(
                "Instance %s does not have the right number or outputs" %
                (component_name))

        # check for multiple sources or sinks
        for i in inputs.values():
            if i.sink is not None:
                raise C2CHIPError("%s already has a sink" % i.name, i.filename,
                                  i.lineno)
            i.sink = self

        for i in outputs.values():
            if i.source is not None:
                raise C2CHIPError("%s has already has a source" %
                                  (i.name, i.filename, i.lineno))
            i.source = self

        for i in inputs.keys():
            if i not in component_inputs:
                raise C2CHIPError(
                    "%s is not an input of component %s" % (i, component_name),
                    i.filename, i.lineno)

        for i in outputs.keys():
            if i not in component_outputs:
                raise C2CHIPError(
                    "%s is not an output of component %s" %
                    (i, component_name), i.filename, i.lineno)
Exemplo n.º 4
0
    def generate_verilog(self):
        """

        Synopsis:

            .. code-block:: python

               chip.generate_verilog(name)

        Description:

            Generate synthesisable Verilog output.

        Arguments:

            None

        Returns:

            None

        """

        for component in self.components.values():
            component.generate_verilog()

        for i in self.wires:
            if i.source is None:
                raise C2CHIPError("wire %s has no source" % i.name, i.filename,
                                  i.lineno)
            if i.sink is None:
                raise C2CHIPError("wire %s has no sink" % i.name, i.filename,
                                  i.lineno)

        for i in self.inputs.values():
            if i.sink is None:
                raise C2CHIPError("input %s has no sink" % i.name, i.filename,
                                  i.lineno)

        for i in self.outputs.values():
            if i.source is None:
                raise C2CHIPError("output %s has no source" % i.name,
                                  i.filename, i.lineno)

        ports = ["clk", "rst", "exception"]
        ports += ["%s" % i.name for i in self.inputs.values()]
        ports += ["%s_stb" % i.name for i in self.inputs.values()]
        ports += ["%s_ack" % i.name for i in self.inputs.values()]
        ports += ["%s" % i.name for i in self.outputs.values()]
        ports += ["%s_stb" % i.name for i in self.outputs.values()]
        ports += ["%s_ack" % i.name for i in self.outputs.values()]
        ports = ", ".join(ports)

        output_file = open(self.name + ".v", "w")
        output_file.write("module %s(%s);\n" % (self.name, ports))
        output_file.write("  input  clk;\n")
        output_file.write("  input  rst;\n")
        output_file.write("  output  exception;\n")
        for i in self.inputs.values():
            output_file.write("  input  [31:0] %s;\n" % i.name)
            output_file.write("  input  %s_stb;\n" % i.name)
            output_file.write("  output %s_ack;\n" % i.name)
        for i in self.outputs.values():
            output_file.write("  output [31:0] %s;\n" % i.name)
            output_file.write("  output %s_stb;\n" % i.name)
            output_file.write("  input  %s_ack;\n" % i.name)
        for i in self.wires:
            output_file.write("  wire   [31:0] %s;\n" % i.name)
            output_file.write("  wire   %s_stb;\n" % i.name)
            output_file.write("  wire   %s_ack;\n" % i.name)
        for instance in self.instances:
            output_file.write("  wire   exception_%s;\n" % (id(instance)))
        for instance in self.instances:
            component = instance.component_name
            output_file.write("  %s %s_%s(\n    " %
                              (component, component, id(instance)))
            ports = []
            ports.append(".clk(clk)")
            ports.append(".rst(rst)")
            ports.append(".exception(exception_%s)" % id(instance))
            for name, i in instance.inputs.iteritems():
                ports.append(".input_%s(%s)" % (name, i.name))
                ports.append(".input_%s_stb(%s_stb)" % (name, i.name))
                ports.append(".input_%s_ack(%s_ack)" % (name, i.name))
            for name, i in instance.outputs.iteritems():
                ports.append(".output_%s(%s)" % (name, i.name))
                ports.append(".output_%s_stb(%s_stb)" % (name, i.name))
                ports.append(".output_%s_ack(%s_ack)" % (name, i.name))
            output_file.write(",\n    ".join(ports))
            output_file.write(");\n")
        output_file.write(
            "  assign exception = %s;\n" %
            (" || ".join(["exception_" + str(id(i)) for i in self.instances])))
        output_file.write("endmodule\n")
        output_file.close()
Exemplo n.º 5
0
    def generate_verilog(self):

        """Generate verilog for the chip"""

        for i in self.wires:
            if i.source is None:
                raise C2CHIPError("wire %s has no source"%i.name)
            if i.sink is None:
                raise C2CHIPError("wire %s has no sink"%i.name)

        for i in self.inputs:
            if i.sink is None:
                raise C2CHIPError("input %s has no sink"%i.name)

        for i in self.outputs:
            if i.source is None:
                raise C2CHIPError("output %s has no source"%i.name)

        ports = ["clk", "rst"]
        ports += ["%s"%i.name for i in self.inputs]
        ports += ["%s_stb"%i.name for i in self.inputs]
        ports += ["%s_ack"%i.name for i in self.inputs]
        ports += ["%s"%i.name for i in self.outputs]
        ports += ["%s_stb"%i.name for i in self.outputs]
        ports += ["%s_ack"%i.name for i in self.outputs]
        ports = ", ".join(ports)

        output_file = open(self.name + ".v", "w")
        output_file.write("module %s(%s);\n"%(self.name, ports))
        output_file.write("  input  clk;\n")
        output_file.write("  input  rst;\n")
        for i in self.inputs:
            output_file.write("  input  [15:0] %s;\n"%i.name)
            output_file.write("  input  %s_stb;\n"%i.name)
            output_file.write("  output %s_ack;\n"%i.name)
        for i in self.outputs:
            output_file.write("  output [15:0] %s;\n"%i.name)
            output_file.write("  output %s_stb;\n"%i.name)
            output_file.write("  input  %s_ack;\n"%i.name)
        for i in self.wires:
            output_file.write("  wire   [15:0] %s;\n"%i.name)
            output_file.write("  wire   %s_stb;\n"%i.name)
            output_file.write("  wire   %s_ack;\n"%i.name)
        for instance in self.instances:
            component = instance.component.name
            output_file.write("  %s %s_%s(\n    "%(component, component, id(instance)))
            ports = []
            ports.append(".clk(clk)")
            ports.append(".rst(rst)")
            for name, i in instance.inputs.iteritems():
                ports.append(".input_%s(%s)"%(name, i.name))
                ports.append(".input_%s_stb(%s_stb)"%(name, i.name))
                ports.append(".input_%s_ack(%s_ack)"%(name, i.name))
            for name, i in instance.outputs.iteritems():
                ports.append(".output_%s(%s)"%(name, i.name))
                ports.append(".output_%s_stb(%s_stb)"%(name, i.name))
                ports.append(".output_%s_ack(%s_ack)"%(name, i.name))
            output_file.write(",\n    ".join(ports))
            output_file.write(");\n")
        output_file.write("endmodule\n")
        output_file.close()
Exemplo n.º 6
0
    def scan(self, filename, input_file=None):

        """Convert the test file into tokens"""
        self.filename = filename

        if input_file is None:
            try:
                input_file = open(self.filename)
            except IOError:
                raise C2CHIPError("Cannot open file: "+self.filename)

        token = []
        tokens = []
        self.lineno = 1
        for line in input_file:

            #include files
            line = line+" "
            if line.strip().startswith("#include"):
                filename = self.filename
                lineno = self.lineno
                self.tokens.extend(tokens)
                directory = os.path.abspath(self.filename)
                directory = os.path.dirname(directory)
                if line.strip().endswith(">"):
                    self.filename = "library"
                    library = line.strip().split("<")[1].strip(' ><"')
                    self.scan(self.filename, StringIO.StringIO(libs[library]))
                else:
                    self.filename = line.strip().replace("#include", "").strip(' ><"')
                    self.filename = os.path.join(directory, self.filename)
                    self.scan(self.filename)
                self.lineno = lineno
                self.filename = filename
                tokens = []
                continue

            newline = True
            for char in line:

                if not token:
                    token = char

                #c style comment
                elif (token + char).startswith("/*"):
                    if (token + char).endswith("*/"):
                        token = ""
                    else:
                        token += char

                #c++ style comment
                elif token.startswith("//"):
                    if newline:
                        token = char
                    else:
                        token += char

                #identifier
                elif token[0].isalpha():
                    if char.isalnum() or char== "_":
                        token += char
                    else:
                        tokens.append((self.filename, self.lineno, token))
                        token = char

                #number
                elif token[0].isdigit():
                    if char.upper() in "UXABCDEFL0123456789.":
                        token += char
                    else:
                        tokens.append((self.filename, self.lineno, token))
                        token = char

                #string literal
                elif token.startswith('"'):
                    if char == '"' and previous_char != "\\":
                        token += char
                        tokens.append((self.filename, self.lineno, token))
                        token = ""
                    else:
                        #remove dummy space from the end of a line
                        if newline:
                            token = token[:-1]
                        previous_char = char
                        token += char

                #character literal
                elif token.startswith("'"):
                    if char == "'":
                        token += char
                        tokens.append((self.filename, self.lineno, token))
                        token = ""
                    else:
                        token += char

                #operator
                elif token in operators:
                    if token + char in operators:
                        token += char
                    else:
                        tokens.append((self.filename, self.lineno, token))
                        token = char

                else:
                    token = char

                newline = False
            self.lineno += 1

        self.tokens.extend(tokens)
Exemplo n.º 7
0
    def error(self, string):

        """Generate an error message (including the filename and line number)"""

        raise C2CHIPError(string + "\n", self.filename, self.lineno)
Exemplo n.º 8
0
    def scan(self,
             filename,
             input_file=None,
             parameters={},
             external_preprocessor=True):
        """Convert the test file into tokens"""

        self.filename = filename

        if external_preprocessor:

            directory = os.path.abspath(__file__)
            directory = os.path.dirname(directory)
            directory = os.path.join(directory, "include")

            cpp_commands = [
                "cpp",
                "-nostdinc",
                "-isystem",
                directory,
                filename]
            pipe = subprocess.Popen(cpp_commands, stdout=subprocess.PIPE)
            input_file = pipe.stdout
        else:
            if input_file is None:
                try:
                    input_file = open(self.filename)
                except IOError:
                    raise C2CHIPError("Cannot open file: " + self.filename)

        token = []
        tokens = []
        self.lineno = 1
        jump = False
        for line in input_file:

            # include files
            line = line + " "
            if jump:
                if line.strip().startswith("#endif"):
                    jump = False
                if line.strip().startswith("#else"):
                    jump = False
                self.lineno += 1
                continue

            elif external_preprocessor and line.strip().startswith("#"):
                l = line.strip()
                l = l.lstrip("#")
                l = l.split('"')
                lineno = int(l[0].strip())
                self.lineno = lineno
                filename = l[1].strip().strip('"')
                self.filename = filename
                continue

            elif line.strip().startswith("#include"):
                filename = self.filename
                lineno = self.lineno
                self.tokens.extend(tokens)
                if line.strip().endswith(">"):
                    directory = os.path.abspath(__file__)
                    directory = os.path.dirname(directory)
                    directory = os.path.join(directory, "include")
                else:
                    directory = os.path.abspath(self.filename)
                    directory = os.path.dirname(directory)
                self.filename = line.strip().replace(
                    "#include", "").strip(' ><"')
                self.filename = os.path.join(directory, self.filename)
                self.scan(self.filename)
                self.lineno = lineno
                self.filename = filename
                tokens = []
                self.lineno += 1
                continue

            elif line.strip().startswith("#define"):
                definition = line.strip().split(" ")[1]
                self.definitions.append(definition)
                self.lineno += 1
                continue

            elif line.strip().startswith("#undef"):
                definition = line.strip().split(" ")[1]
                self.definitions.remove(definition)
                self.lineno += 1
                continue

            elif line.strip().startswith("#ifdef"):
                definition = line.strip().split(" ")[1]
                if definition not in self.definitions:
                    jump = True
                self.lineno += 1
                continue

            elif line.strip().startswith("#ifndef"):
                definition = line.strip().split(" ")[1]
                if definition in self.definitions:
                    jump = True
                self.lineno += 1
                continue

            elif line.strip().startswith("#else"):
                jump = True
                self.lineno += 1
                continue

            elif line.strip().startswith("#endif"):
                self.lineno += 1
                continue

            newline = True
            for char in line:

                if not token:
                    token = char

                # c style comment
                elif (token + char).startswith("/*"):
                    if (token + char).endswith("*/"):
                        token = ""
                    else:
                        token += char

                # c++ style comment
                elif token.startswith("//"):
                    if newline:
                        token = char
                    else:
                        token += char

                # identifier
                elif token[0].isalpha():
                    if char.isalnum() or char == "_":
                        token += char
                    else:
                        tokens.append((self.filename, self.lineno, token))
                        token = char

                # number
                elif token[0].isdigit():
                    if char.upper() in "0123456789ABCDEFXUL.":
                        token += char
                    elif token.upper().endswith("E") and char in ["+", "-"]:
                        token += char
                    else:
                        tokens.append((self.filename, self.lineno, token))
                        token = char

                # string literal
                elif token.startswith('"'):
                    if char == '"' and previous_char != "\\":
                        token += char
                        tokens.append((self.filename, self.lineno, token))
                        token = ""
                    else:
                        # remove dummy space from the end of a line
                        if newline:
                            token = token[:-1]
                        previous_char = char
                        token += char

                # character literal
                elif token.startswith("'"):
                    if char == "'":
                        token += char
                        tokens.append((self.filename, self.lineno, token))
                        token = ""
                    else:
                        token += char

                # operator
                elif token in operators:
                    if token + char in operators:
                        token += char
                    else:
                        tokens.append((self.filename, self.lineno, token))
                        token = char

                else:
                    token = char

                newline = False
            self.lineno += 1

        self.tokens.extend(tokens)