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
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_)
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
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
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
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