Esempio n. 1
0
 def _format_value(self, data_type, value):
   if data_type == DataType.F32:
     return "".join("{:02x}".format(ord(byte)) for byte in
         struct.pack(">f", value))
   if data_type.is_integer and data_type.length <= 32:
     return "".join("{:02x}".format(ord(byte)) for byte in
         struct.pack(">I", value))
   elif data_type.is_integer and data_type.length >= 64:
     return self._format_value(DataType.U32, chips_c.low_word(value)) + \
         "\n" + self._format_value(DataType.U32, chips_c.high_word(value))
   elif data_type == DataType.F64:
     return self._format_value(DataType.U64, chips_c.double_to_bits(value))
   else:
     assert False, data_type
Esempio n. 2
0
    def data_source(self):
        """
        This is a private function, you shouldn't need to call this directly.
        """

        if self.type_ == "int":
            return next(self.iterator)

        elif self.type_ == "long":

            if self.high_word:
                self.high_word = not self.high_word
                word = self.high
                return word
            else:
                self.high_word = not self.high_word
                long_word = next(self.iterator)
                self.high = high_word(long_word)
                low = low_word(long_word)
                return low

        elif self.type_ == "float":

            return float_to_bits(next(self.iterator))

        elif self.type_ == "double":

            if self.high_word:
                self.high_word = not self.high_word
                word = self.high
                return word
            else:
                self.high_word = not self.high_word
                long_word = double_to_bits(next(self.iterator))
                self.high = high_word(long_word)
                low = low_word(long_word)
                return low

        else:
            raise Exception("unknown type", self.type_)
Esempio n. 3
0
    def data_source(self):
        """
        This is a private function, you shouldn't need to call this directly.
        """

        if self.type_ == "int":
            return next(self.iterator)

        elif self.type_ == "long":

            if self.high_word:
                self.high_word = not self.high_word
                word = self.high
                return word
            else:
                self.high_word = not self.high_word
                long_word = next(self.iterator)
                self.high = high_word(long_word)
                low = low_word(long_word)
                return low

        elif self.type_ == "float":

            return float_to_bits(next(self.iterator))

        elif self.type_ == "double":

            if self.high_word:
                self.high_word = not self.high_word
                word = self.high
                return word
            else:
                self.high_word = not self.high_word
                long_word = double_to_bits(next(self.iterator))
                self.high = high_word(long_word)
                low = low_word(long_word)
                return low
Esempio n. 4
0
    def simulation_step(self):
        """execute the python simulation by one step"""

        l = self.get_line()
        f = self.get_file()
        if f in self.breakpoints:
            if l in self.breakpoints[f]:
                raise BreakSim

        instruction = self.instructions[self.program_counter]
        current_stack = self.registers.get(register_map.tos, 0)
        self.max_stack = max([current_stack, self.max_stack])

        if self.profile:
            trace = instruction.get("trace", "-")
            lines = self.files.get(trace.filename, {})
            lines[trace.lineno] = lines.get(trace.lineno, 0) + 1
            self.files[trace.filename] = lines

        if "literal" in instruction:
            literal = instruction["literal"]

        if "label" in instruction:
            literal = instruction["label"]

        # read operands
        #
        a = instruction.get("a", 0)
        b = instruction.get("b", 0)
        z = instruction.get("z", 0)

        operand_b = self.registers.get(b, 0)
        operand_a = self.registers.get(a, 0)

        this_instruction = self.program_counter
        self.program_counter += 1
        wait = False
        result = None

        if instruction["op"] == "stop":
            self.program_counter = this_instruction
            wait = True
            for file_ in self.input_files.values():
                file_.close()
            for file_ in self.output_files.values():
                file_.close()
            raise StopSim

        elif instruction["op"] == "literal":
            if literal & 0x8000:
                result = -65536 | literal
            else:
                result = literal
            result &= 0xffffffff
        elif instruction["op"] == "addl":
            if literal & 0x8000:
                sext = -65536 | literal
            else:
                sext = literal
            result = sext + operand_a
            result &= 0xffffffff
        elif instruction["op"] == "literal_hi":
            if literal & 0x8000:
                sext = -65536 | literal
            else:
                sext = literal
            result = (sext << 16) | (operand_a & 0x0000ffff)
            result &= 0xffffffff
        elif instruction["op"] == "store":
            self.memory[operand_a] = operand_b
        elif instruction["op"] == "load":
            result = self.memory.get(operand_a, 0)
        elif instruction["op"] == "call":
            result = this_instruction + 1
            self.program_counter = literal
        elif instruction["op"] == "return":
            self.program_counter = operand_a
        elif instruction["op"] == "a_lo":
            result = self.a_lo
            self.a_lo = operand_a
        elif instruction["op"] == "b_lo":
            result = self.b_lo
            self.b_lo = operand_a
        elif instruction["op"] == "a_hi":
            result = self.a_hi
            self.a_hi = operand_a
        elif instruction["op"] == "b_hi":
            result = self.b_hi
            self.b_hi = operand_a
        elif instruction["op"] == "not":
            result = (~operand_a) & 0xffffffff
        elif instruction["op"] == "int_to_long":
            if operand_a & 0x80000000:
                result = 0xffffffff
            else:
                result = 0
        elif instruction["op"] == "int_to_float":
            f = float(to_32_signed(self.a_lo))
            self.a_lo = float_to_bits(f)
        elif instruction["op"] == "float_to_int":
            i = bits_to_float(self.a_lo)
            if math.isnan(i):
                self.a_lo = 0
            else:
                self.a_lo = int(i) & 0xffffffff
        elif instruction["op"] == "long_to_double":
            double = float(to_64_signed(chips_c.join_words(self.a_hi, self.a_lo)))
            if math.isnan(double):
                self.a_hi = 0
                self.a_lo = 0
            else:
                self.a_hi = chips_c.high_word(double_to_bits(double))
                self.a_lo = chips_c.low_word(double_to_bits(double))
        elif instruction["op"] == "double_to_long":
            bits = int(bits_to_double(chips_c.join_words(self.a_hi, self.a_lo)))
            bits &= 0xffffffffffffffff
            self.a_hi = chips_c.high_word(bits)
            self.a_lo = chips_c.low_word(bits)
        elif instruction["op"] == "float_to_double":
            f = bits_to_float(self.a_lo)
            bits = double_to_bits(f)
            self.a_hi = chips_c.high_word(bits)
            self.a_lo = chips_c.low_word(bits)
        elif instruction["op"] == "double_to_float":
            f = bits_to_double(chips_c.join_words(self.a_hi, self.a_lo))
            self.a_lo = float_to_bits(f)
        elif instruction["op"] == "add":
            total = add(operand_a, operand_b, 0);
            result = total.lo
            self.carry = total.hi
        elif instruction["op"] == "add_with_carry":
            total = add(operand_a, operand_b, self.carry);
            result = total.lo
            self.carry = total.hi
        elif instruction["op"] == "subtract":
            total = subtract(operand_a, operand_b, 1);
            result = total.lo
            self.carry = total.hi
        elif instruction["op"] == "subtract_with_carry":
            total = subtract(operand_a, operand_b, self.carry);
            result = total.lo
            self.carry = total.hi
        elif instruction["op"] == "multiply":
            lw = operand_a * operand_b
            self.carry = chips_c.high_word(lw)
            result = chips_c.low_word(lw)
        elif instruction["op"] == "divide":
            a = operand_a
            b = operand_b
            result = chips_c.divide(a, b)
        elif instruction["op"] == "unsigned_divide":
            a = operand_a
            b = operand_b
            result = chips_c.unsigned_divide(a, b)
        elif instruction["op"] == "modulo":
            a = operand_a
            b = operand_b
            result = chips_c.modulo(a, b)
        elif instruction["op"] == "unsigned_modulo":
            a = operand_a
            b = operand_b
            result = chips_c.unsigned_modulo(a, b)
        elif instruction["op"] == "long_divide":
            a = chips_c.join_words(self.a_hi, self.a_lo)
            b = chips_c.join_words(self.b_hi, self.b_lo)
            quotient = chips_c.long_divide(a, b)
            self.a_hi = chips_c.high_word(quotient)
            self.a_lo = chips_c.low_word(quotient)
        elif instruction["op"] == "long_modulo":
            a = chips_c.join_words(self.a_hi, self.a_lo)
            b = chips_c.join_words(self.b_hi, self.b_lo)
            remainder = chips_c.long_modulo(a, b)
            self.a_hi = chips_c.high_word(remainder)
            self.a_lo = chips_c.low_word(remainder)
        elif instruction["op"] == "unsigned_long_divide":
            a = chips_c.join_words(self.a_hi, self.a_lo)
            b = chips_c.join_words(self.b_hi, self.b_lo)
            quotient = chips_c.unsigned_long_divide(a, b)
            self.a_hi = chips_c.high_word(quotient)
            self.a_lo = chips_c.low_word(quotient)
        elif instruction["op"] == "unsigned_long_modulo":
            a = chips_c.join_words(self.a_hi, self.a_lo)
            b = chips_c.join_words(self.b_hi, self.b_lo)
            remainder = chips_c.unsigned_long_modulo(a, b)
            self.a_hi = chips_c.high_word(remainder)
            self.a_lo = chips_c.low_word(remainder)
        elif instruction["op"] == "carry":
            result = self.carry
        elif instruction["op"] == "or":
            result = operand_a | operand_b
        elif instruction["op"] == "and":
            result = operand_a & operand_b
        elif instruction["op"] == "xor":
            result = operand_a ^ operand_b
        elif instruction["op"] == "shift_left":
            total = shift_left(operand_a, operand_b, 0)
            result = total.lo
            self.carry = total.hi
        elif instruction["op"] == "shift_left_with_carry":
            total = shift_left(operand_a, operand_b, self.carry)
            result = total.lo
            self.carry = total.hi
        elif instruction["op"] == "shift_right":
            total = shift_right(operand_a, operand_b)
            result = total.lo
            self.carry = total.hi
        elif instruction["op"] == "unsigned_shift_right":
            total = unsigned_shift_right(operand_a, operand_b, 0)
            result = total.lo
            self.carry = total.hi
        elif instruction["op"] == "shift_right_with_carry":
            total = unsigned_shift_right(operand_a, operand_b, self.carry)
            result = total.lo
            self.carry = total.hi
        elif instruction["op"] == "greater":
            result = greater(operand_a, operand_b)
        elif instruction["op"] == "greater_equal":
            result = greater_equal(operand_a, operand_b)
        elif instruction["op"] == "unsigned_greater":
            result = unsigned_greater(operand_a, operand_b)
        elif instruction["op"] == "unsigned_greater_equal":
            result = unsigned_greater_equal(operand_a, operand_b)
        elif instruction["op"] == "equal":
            result = operand_a == operand_b
        elif instruction["op"] == "not_equal":
            result = operand_a != operand_b
        elif instruction["op"] == "jmp_if_false":
            if operand_a == 0:
                self.program_counter = literal
        elif instruction["op"] == "jmp_if_true":
            if operand_a != 0:
                self.program_counter = literal
        elif instruction["op"] == "goto":
            self.program_counter = literal
        elif instruction["op"] == "timer_low":
            result = self.clock&0xffffffff
        elif instruction["op"] == "timer_high":
            result = self.clock>>32
        elif instruction["op"] == "file_read":
            value = self.input_files[instruction["filename"]].getline()
            result = value
        elif instruction["op"] == "float_file_write":
            self.output_files[instruction["file_name"]].write(
                "%.7f\n" %
                bits_to_float(operand_a))
        elif instruction["op"] == "unsigned_file_write":
            self.output_files[instruction["file_name"]].write(
                "%i\n" %
                operand_a)
        elif instruction["op"] == "file_write":
            self.output_files[instruction["file_name"]].write(
                "%i\n" %
                to_32_signed(operand_a))
        elif instruction["op"] == "read":
            if operand_a not in self.inputs:
                result = 0
            else:
                input_ = self.inputs[operand_a]
                if input_.src_rdy and input_.dst_rdy:
                    result = input_.q
                    input_.next_dst_rdy = False
                else:
                    input_.next_dst_rdy = True
                    wait = True
        elif instruction["op"] == "ready":
            if operand_a not in self.inputs:
                operand_a = 0
            else:
                input_ = self.inputs[operand_a]
                if input_.src_rdy:
                    result = 1
                else:
                    result = 0
        elif instruction["op"] == "output_ready":
            if operand_a not in self.outputs:
                operand_a = 0
            else:
                output_ = self.outputs[operand_a]
                if output_.dst_rdy:
                    result = 1
                else:
                    result = 0
        elif instruction["op"] == "write":
            if operand_a not in self.outputs:
                pass
            else:
                output_ = self.outputs[operand_a]
                if output_.src_rdy and output_.dst_rdy:
                    output_.next_src_rdy = False
                else:
                    output_.q = operand_b
                    output_.next_src_rdy = True
                    wait = True
        elif instruction["op"] == "float_add":
            a = operand_a
            b = operand_b
            float_ = bits_to_float(a)
            floatb = bits_to_float(b)
            result = float_to_bits(float_ + floatb)
        elif instruction["op"] == "float_subtract":
            a = operand_a
            b = operand_b
            float_ = bits_to_float(a)
            floatb = bits_to_float(b)
            result = float_to_bits(float_ - floatb)
        elif instruction["op"] == "float_multiply":
            a = operand_a
            b = operand_b
            float_ = bits_to_float(a)
            floatb = bits_to_float(b)
            result = float_to_bits(float_ * floatb)
        elif instruction["op"] == "float_divide":
            a = operand_a
            b = operand_b
            float_ = bits_to_float(a)
            floatb = bits_to_float(b)
            try:
                result = float_to_bits(float_ / floatb)
            except ZeroDivisionError:
                result = float_to_bits(float("nan"))
        elif instruction["op"] == "long_float_add":
            double = bits_to_double(chips_c.join_words(self.a_hi, self.a_lo))
            doubleb = bits_to_double(chips_c.join_words(self.b_hi, self.b_lo))
            self.a_hi = chips_c.high_word(double_to_bits(double + doubleb))
            self.a_lo = chips_c.low_word(double_to_bits(double + doubleb))
        elif instruction["op"] == "long_float_subtract":
            double = bits_to_double(chips_c.join_words(self.a_hi, self.a_lo))
            doubleb = bits_to_double(chips_c.join_words(self.b_hi, self.b_lo))
            self.a_hi = chips_c.high_word(double_to_bits(double - doubleb))
            self.a_lo = chips_c.low_word(double_to_bits(double - doubleb))
        elif instruction["op"] == "long_float_multiply":
            double = bits_to_double(chips_c.join_words(self.a_hi, self.a_lo))
            doubleb = bits_to_double(chips_c.join_words(self.b_hi, self.b_lo))
            self.a_hi = chips_c.high_word(double_to_bits(double * doubleb))
            self.a_lo = chips_c.low_word(double_to_bits(double * doubleb))
        elif instruction["op"] == "long_float_divide":
            double = bits_to_double(chips_c.join_words(self.a_hi, self.a_lo))
            doubleb = bits_to_double(chips_c.join_words(self.b_hi, self.b_lo))
            try:
                self.a_hi = chips_c.high_word(double_to_bits(double / doubleb))
                self.a_lo = chips_c.low_word(double_to_bits(double / doubleb))
            except ZeroDivisionError:
                self.a_hi = chips_c.high_word(double_to_bits(float("nan")))
                self.a_lo = chips_c.low_word(double_to_bits(float("nan")))
        elif instruction["op"] == "long_float_file_write":
            long_word = chips_c.join_words(self.a_hi, self.a_lo)
            self.output_files[instruction["file_name"]].write(
                "%.16f\n" %
                bits_to_double(long_word))
        elif instruction["op"] == "long_file_write":
            long_word = chips_c.join_words(self.a_hi, self.a_lo)
            self.output_files[instruction["file_name"]].write(
                "%f\n" %
                long_word)
        elif instruction["op"] == "assert":
            if operand_a == 0:
                raise ChipsAssertionFail(
                    instruction["file"],
                    instruction["line"])
        elif instruction["op"] == "report":
            print "%d (report (int) at line: %s in file: %s)" % (
                to_32_signed(self.a_lo),
                instruction["line"],
                instruction["file"],
            )
        elif instruction["op"] == "long_report":
            print "%d (report (long) at line: %s in file: %s)" % (
                to_64_signed(chips_c.join_words(self.a_hi, self.a_lo)),
                instruction["line"],
                instruction["file"],
            )
        elif instruction["op"] == "float_report":
            print "%f (report (float) at line: %s in file: %s)" % (
                bits_to_float(self.a_lo),
                instruction["line"],
                instruction["file"],
            )
        elif instruction["op"] == "long_float_report":
            print "%s (report (double) at line: %s in file: %s)" % (

                bits_to_double(chips_c.join_words(self.a_hi, self.a_lo)),
                instruction["line"],
                instruction["file"],
            )
        elif instruction["op"] == "unsigned_report":
            print "%d (report (unsigned) at line: %s in file: %s)" % (
                self.a_lo,
                instruction["line"],
                instruction["file"],
            )
        elif instruction["op"] == "long_unsigned_report":
            print "%d (report (unsigned long) at line: %s in file: %s)" % (
                chips_c.join_words(self.a_hi, self.a_lo),
                instruction["line"],
                instruction["file"],
            )
        elif instruction["op"] == "wait_clocks":
            if self.timer == operand_a:
                wait = False
                self.timer = 0
            else:
                wait = True
                self.timer += 1

        else:
            print "Unknown machine instruction", instruction["op"]
            sys.exit(-1)

        # Write data back
        if result is not None:
            self.registers[z] = result

        # manipulate stack pointer
        if wait:
            self.program_counter = this_instruction

        self.clock += 1
Esempio n. 5
0
    def simulation_step(self):
        """execute the python simulation by one step"""

        l = self.get_line()
        f = self.get_file()
        if f in self.breakpoints:
            if l in self.breakpoints[f]:
                raise BreakSim

        instruction = self.instructions[self.program_counter]
        current_stack = self.registers.get(register_map.tos, 0)
        self.max_stack = max([current_stack, self.max_stack])

        if self.profile:
            trace = instruction.get("trace", "-")
            lines = self.files.get(trace.filename, {})
            lines[trace.lineno] = lines.get(trace.lineno, 0) + 1
            self.files[trace.filename] = lines

        if "literal" in instruction:
            literal = instruction["literal"]

        if "label" in instruction:
            literal = instruction["label"]

        # read operands
        #
        a = instruction.get("a", 0)
        b = instruction.get("b", 0)
        z = instruction.get("z", 0)

        operand_b = self.registers.get(b, 0)
        operand_a = self.registers.get(a, 0)

        this_instruction = self.program_counter
        self.program_counter += 1
        wait = False
        result = None

        if instruction["op"] == "stop":
            self.program_counter = this_instruction
            wait = True
            for file_ in self.input_files.values():
                file_.close()
            for file_ in self.output_files.values():
                file_.close()
            raise StopSim

        elif instruction["op"] == "literal":
            if literal & 0x8000:
                result = -65536 | literal
            else:
                result = literal
            result &= 0xffffffff
        elif instruction["op"] == "addl":
            if literal & 0x8000:
                sext = -65536 | literal
            else:
                sext = literal
            result = sext + operand_a
            result &= 0xffffffff
        elif instruction["op"] == "literal_hi":
            if literal & 0x8000:
                sext = -65536 | literal
            else:
                sext = literal
            result = (sext << 16) | (operand_a & 0x0000ffff)
            result &= 0xffffffff
        elif instruction["op"] == "store":
            self.memory[operand_a] = operand_b
        elif instruction["op"] == "load":
            result = self.memory.get(operand_a, 0)
        elif instruction["op"] == "call":
            result = this_instruction + 1
            self.program_counter = literal
        elif instruction["op"] == "return":
            self.program_counter = operand_a
        elif instruction["op"] == "a_lo":
            result = self.a_lo
            self.a_lo = operand_a
        elif instruction["op"] == "b_lo":
            result = self.b_lo
            self.b_lo = operand_a
        elif instruction["op"] == "a_hi":
            result = self.a_hi
            self.a_hi = operand_a
        elif instruction["op"] == "b_hi":
            result = self.b_hi
            self.b_hi = operand_a
        elif instruction["op"] == "not":
            result = (~operand_a) & 0xffffffff
        elif instruction["op"] == "int_to_long":
            if operand_a & 0x80000000:
                result = 0xffffffff
            else:
                result = 0
        elif instruction["op"] == "int_to_float":
            f = float(to_32_signed(self.a_lo))
            self.a_lo = float_to_bits(f)
        elif instruction["op"] == "float_to_int":
            i = bits_to_float(self.a_lo)
            if math.isnan(i):
                self.a_lo = 0
            else:
                self.a_lo = int(i) & 0xffffffff
        elif instruction["op"] == "long_to_double":
            double = float(
                to_64_signed(chips_c.join_words(self.a_hi, self.a_lo)))
            if math.isnan(double):
                self.a_hi = 0
                self.a_lo = 0
            else:
                self.a_hi = chips_c.high_word(double_to_bits(double))
                self.a_lo = chips_c.low_word(double_to_bits(double))
        elif instruction["op"] == "double_to_long":
            bits = int(bits_to_double(chips_c.join_words(self.a_hi,
                                                         self.a_lo)))
            bits &= 0xffffffffffffffff
            self.a_hi = chips_c.high_word(bits)
            self.a_lo = chips_c.low_word(bits)
        elif instruction["op"] == "float_to_double":
            f = bits_to_float(self.a_lo)
            bits = double_to_bits(f)
            self.a_hi = chips_c.high_word(bits)
            self.a_lo = chips_c.low_word(bits)
        elif instruction["op"] == "double_to_float":
            f = bits_to_double(chips_c.join_words(self.a_hi, self.a_lo))
            self.a_lo = float_to_bits(f)
        elif instruction["op"] == "add":
            total = add(operand_a, operand_b, 0)
            result = total.lo
            self.carry = total.hi
        elif instruction["op"] == "add_with_carry":
            total = add(operand_a, operand_b, self.carry)
            result = total.lo
            self.carry = total.hi
        elif instruction["op"] == "subtract":
            total = subtract(operand_a, operand_b, 1)
            result = total.lo
            self.carry = total.hi
        elif instruction["op"] == "subtract_with_carry":
            total = subtract(operand_a, operand_b, self.carry)
            result = total.lo
            self.carry = total.hi
        elif instruction["op"] == "multiply":
            lw = operand_a * operand_b
            self.carry = chips_c.high_word(lw)
            result = chips_c.low_word(lw)
        elif instruction["op"] == "divide":
            a = operand_a
            b = operand_b
            result = chips_c.divide(a, b)
        elif instruction["op"] == "unsigned_divide":
            a = operand_a
            b = operand_b
            result = chips_c.unsigned_divide(a, b)
        elif instruction["op"] == "modulo":
            a = operand_a
            b = operand_b
            result = chips_c.modulo(a, b)
        elif instruction["op"] == "unsigned_modulo":
            a = operand_a
            b = operand_b
            result = chips_c.unsigned_modulo(a, b)
        elif instruction["op"] == "long_divide":
            a = chips_c.join_words(self.a_hi, self.a_lo)
            b = chips_c.join_words(self.b_hi, self.b_lo)
            quotient = chips_c.long_divide(a, b)
            self.a_hi = chips_c.high_word(quotient)
            self.a_lo = chips_c.low_word(quotient)
        elif instruction["op"] == "long_modulo":
            a = chips_c.join_words(self.a_hi, self.a_lo)
            b = chips_c.join_words(self.b_hi, self.b_lo)
            remainder = chips_c.long_modulo(a, b)
            self.a_hi = chips_c.high_word(remainder)
            self.a_lo = chips_c.low_word(remainder)
        elif instruction["op"] == "unsigned_long_divide":
            a = chips_c.join_words(self.a_hi, self.a_lo)
            b = chips_c.join_words(self.b_hi, self.b_lo)
            quotient = chips_c.unsigned_long_divide(a, b)
            self.a_hi = chips_c.high_word(quotient)
            self.a_lo = chips_c.low_word(quotient)
        elif instruction["op"] == "unsigned_long_modulo":
            a = chips_c.join_words(self.a_hi, self.a_lo)
            b = chips_c.join_words(self.b_hi, self.b_lo)
            remainder = chips_c.unsigned_long_modulo(a, b)
            self.a_hi = chips_c.high_word(remainder)
            self.a_lo = chips_c.low_word(remainder)
        elif instruction["op"] == "carry":
            result = self.carry
        elif instruction["op"] == "or":
            result = operand_a | operand_b
        elif instruction["op"] == "and":
            result = operand_a & operand_b
        elif instruction["op"] == "xor":
            result = operand_a ^ operand_b
        elif instruction["op"] == "shift_left":
            total = shift_left(operand_a, operand_b, 0)
            result = total.lo
            self.carry = total.hi
        elif instruction["op"] == "shift_left_with_carry":
            total = shift_left(operand_a, operand_b, self.carry)
            result = total.lo
            self.carry = total.hi
        elif instruction["op"] == "shift_right":
            total = shift_right(operand_a, operand_b)
            result = total.lo
            self.carry = total.hi
        elif instruction["op"] == "unsigned_shift_right":
            total = unsigned_shift_right(operand_a, operand_b, 0)
            result = total.lo
            self.carry = total.hi
        elif instruction["op"] == "shift_right_with_carry":
            total = unsigned_shift_right(operand_a, operand_b, self.carry)
            result = total.lo
            self.carry = total.hi
        elif instruction["op"] == "greater":
            result = greater(operand_a, operand_b)
        elif instruction["op"] == "greater_equal":
            result = greater_equal(operand_a, operand_b)
        elif instruction["op"] == "unsigned_greater":
            result = unsigned_greater(operand_a, operand_b)
        elif instruction["op"] == "unsigned_greater_equal":
            result = unsigned_greater_equal(operand_a, operand_b)
        elif instruction["op"] == "equal":
            result = operand_a == operand_b
        elif instruction["op"] == "not_equal":
            result = operand_a != operand_b
        elif instruction["op"] == "jmp_if_false":
            if operand_a == 0:
                self.program_counter = literal
        elif instruction["op"] == "jmp_if_true":
            if operand_a != 0:
                self.program_counter = literal
        elif instruction["op"] == "goto":
            self.program_counter = literal
        elif instruction["op"] == "timer_low":
            result = self.clock & 0xffffffff
        elif instruction["op"] == "timer_high":
            result = self.clock >> 32
        elif instruction["op"] == "file_read":
            value = self.input_files[instruction["filename"]].getline()
            result = value
        elif instruction["op"] == "float_file_write":
            self.output_files[instruction["file_name"]].write(
                "%.7f\n" % bits_to_float(operand_a))
        elif instruction["op"] == "unsigned_file_write":
            self.output_files[instruction["file_name"]].write("%i\n" %
                                                              operand_a)
        elif instruction["op"] == "file_write":
            self.output_files[instruction["file_name"]].write(
                "%i\n" % to_32_signed(operand_a))
        elif instruction["op"] == "read":
            if operand_a not in self.inputs:
                result = 0
            else:
                input_ = self.inputs[operand_a]
                if input_.src_rdy and input_.dst_rdy:
                    result = input_.q
                    input_.next_dst_rdy = False
                else:
                    input_.next_dst_rdy = True
                    wait = True
        elif instruction["op"] == "ready":
            if operand_a not in self.inputs:
                operand_a = 0
            else:
                input_ = self.inputs[operand_a]
                if input_.src_rdy:
                    result = 1
                else:
                    result = 0
        elif instruction["op"] == "output_ready":
            if operand_a not in self.outputs:
                operand_a = 0
            else:
                output_ = self.outputs[operand_a]
                if output_.dst_rdy:
                    result = 1
                else:
                    result = 0
        elif instruction["op"] == "write":
            if operand_a not in self.outputs:
                pass
            else:
                output_ = self.outputs[operand_a]
                if output_.src_rdy and output_.dst_rdy:
                    output_.next_src_rdy = False
                else:
                    output_.q = operand_b
                    output_.next_src_rdy = True
                    wait = True
        elif instruction["op"] == "float_add":
            a = operand_a
            b = operand_b
            float_ = bits_to_float(a)
            floatb = bits_to_float(b)
            result = float_to_bits(float_ + floatb)
        elif instruction["op"] == "float_subtract":
            a = operand_a
            b = operand_b
            float_ = bits_to_float(a)
            floatb = bits_to_float(b)
            result = float_to_bits(float_ - floatb)
        elif instruction["op"] == "float_multiply":
            a = operand_a
            b = operand_b
            float_ = bits_to_float(a)
            floatb = bits_to_float(b)
            result = float_to_bits(float_ * floatb)
        elif instruction["op"] == "float_divide":
            a = operand_a
            b = operand_b
            float_ = bits_to_float(a)
            floatb = bits_to_float(b)
            try:
                result = float_to_bits(float_ / floatb)
            except ZeroDivisionError:
                result = float_to_bits(float("nan"))
        elif instruction["op"] == "long_float_add":
            double = bits_to_double(chips_c.join_words(self.a_hi, self.a_lo))
            doubleb = bits_to_double(chips_c.join_words(self.b_hi, self.b_lo))
            self.a_hi = chips_c.high_word(double_to_bits(double + doubleb))
            self.a_lo = chips_c.low_word(double_to_bits(double + doubleb))
        elif instruction["op"] == "long_float_subtract":
            double = bits_to_double(chips_c.join_words(self.a_hi, self.a_lo))
            doubleb = bits_to_double(chips_c.join_words(self.b_hi, self.b_lo))
            self.a_hi = chips_c.high_word(double_to_bits(double - doubleb))
            self.a_lo = chips_c.low_word(double_to_bits(double - doubleb))
        elif instruction["op"] == "long_float_multiply":
            double = bits_to_double(chips_c.join_words(self.a_hi, self.a_lo))
            doubleb = bits_to_double(chips_c.join_words(self.b_hi, self.b_lo))
            self.a_hi = chips_c.high_word(double_to_bits(double * doubleb))
            self.a_lo = chips_c.low_word(double_to_bits(double * doubleb))
        elif instruction["op"] == "long_float_divide":
            double = bits_to_double(chips_c.join_words(self.a_hi, self.a_lo))
            doubleb = bits_to_double(chips_c.join_words(self.b_hi, self.b_lo))
            try:
                self.a_hi = chips_c.high_word(double_to_bits(double / doubleb))
                self.a_lo = chips_c.low_word(double_to_bits(double / doubleb))
            except ZeroDivisionError:
                self.a_hi = chips_c.high_word(double_to_bits(float("nan")))
                self.a_lo = chips_c.low_word(double_to_bits(float("nan")))
        elif instruction["op"] == "long_float_file_write":
            long_word = chips_c.join_words(self.a_hi, self.a_lo)
            self.output_files[instruction["file_name"]].write(
                "%.16f\n" % bits_to_double(long_word))
        elif instruction["op"] == "long_file_write":
            long_word = chips_c.join_words(self.a_hi, self.a_lo)
            self.output_files[instruction["file_name"]].write("%f\n" %
                                                              long_word)
        elif instruction["op"] == "assert":
            if operand_a == 0:
                raise ChipsAssertionFail(instruction["file"],
                                         instruction["line"])
        elif instruction["op"] == "report":
            print "%d (report (int) at line: %s in file: %s)" % (
                to_32_signed(self.a_lo),
                instruction["line"],
                instruction["file"],
            )
        elif instruction["op"] == "long_report":
            print "%d (report (long) at line: %s in file: %s)" % (
                to_64_signed(chips_c.join_words(self.a_hi, self.a_lo)),
                instruction["line"],
                instruction["file"],
            )
        elif instruction["op"] == "float_report":
            print "%f (report (float) at line: %s in file: %s)" % (
                bits_to_float(self.a_lo),
                instruction["line"],
                instruction["file"],
            )
        elif instruction["op"] == "long_float_report":
            print "%s (report (double) at line: %s in file: %s)" % (
                bits_to_double(chips_c.join_words(self.a_hi, self.a_lo)),
                instruction["line"],
                instruction["file"],
            )
        elif instruction["op"] == "unsigned_report":
            print "%d (report (unsigned) at line: %s in file: %s)" % (
                self.a_lo,
                instruction["line"],
                instruction["file"],
            )
        elif instruction["op"] == "long_unsigned_report":
            print "%d (report (unsigned long) at line: %s in file: %s)" % (
                chips_c.join_words(self.a_hi, self.a_lo),
                instruction["line"],
                instruction["file"],
            )
        elif instruction["op"] == "wait_clocks":
            if self.timer == operand_a:
                wait = False
                self.timer = 0
            else:
                wait = True
                self.timer += 1

        else:
            print "Unknown machine instruction", instruction["op"]
            sys.exit(-1)

        # Write data back
        if result is not None:
            self.registers[z] = result

        # manipulate stack pointer
        if wait:
            self.program_counter = this_instruction

        self.clock += 1
Esempio n. 6
0
def constant(chip, value, type_="int", out=None):
    if out is None:
        out = Wire(chip)

    verilog_value = value
    if type_ in ["int", "float"]:

        if type_ == "float":
            verilog_value = float_to_bits(value)

        verilog_file = """
        module {name} (output_out_ack,clk,rst,output_out,output_out_stb,exception);
          input output_out_ack;
          input clk;
          input rst;
          output [31:0] output_out;
          output output_out_stb;
          output exception;

          assign output_out = %s;
          assign output_out_stb = 1;
          assign exception = 0;
        endmodule
        """ % verilog_value

    elif type_ in ["long", "double"]:
        high = high_word(value)
        low = low_word(value)

        if type_ == "double":
            high = high_word(double_to_bits(value))
            low = low_word(double_to_bits(value))

        verilog_file = """
        module {name} (output_out_ack,clk,rst,output_out,output_out_stb,exception);
          input output_out_ack;
          input clk;
          input rst;
          output [31:0] output_out;
          output output_out_stb;
          output exception;
          reg [31:0] s_output_out_stb;
          reg [31:0] s_output_out;

          reg high;

          always @(posedge clk)
          begin

            if (high) begin
                s_output_out_stb <= 1;
                s_output_out <= %s;
                if (output_out_ack && s_output_out_stb) begin
                  s_output_out_stb <= 0;
                  high <= 0;
                end
            end else begin
                s_output_out_stb <= 1;
                s_output_out <= %s;
                if (output_out_ack && s_output_out_stb) begin
                  s_output_out_stb <= 0;
                  high <= 1;
                end
            end

            if (rst == 1'b1) begin
              high <= 0;
              s_output_out_stb <= 0;
            end

          end

          assign output_out = s_output_out;
          assign output_out_stb = s_output_out_stb;
          assign exception = 0;
        endmodule
        """ % (high, low)

    constant_component = VerilogComponent(C_file="""
            #include <stdio.h>
            int out = output("out");
            void main(){
                while(1){
                    fput_%s(%s, out);
                }
            }
        """ % (type_, value),
                                          V_file=verilog_file,
                                          inline=True)
    constant_component(
        chip,
        inputs={},
        outputs={"out": out},
        parameters={},
    )
    return out