Esempio n. 1
0
 def make_name(self, port):
     if isinstance(port, PortWrapper):
         port = port.select_path
     if isinstance(port, SelectPath):
         if len(port) > 2:
             name = f"dut.{port.system_verilog_path}"
         else:
             # Top level ports assign to the external reg
             name = verilog_name(port[-1].name)
     elif isinstance(port, fault.WrappedVerilogInternalPort):
         name = f"dut.{port.path}"
     else:
         name = verilog_name(port.name)
     return name
Esempio n. 2
0
    def make_expect(self, i, action):
        if value_utils.is_any(action.value):
            return []
        if isinstance(action.port, SelectPath):
            name = f"dut.{action.port.system_verilog_path}"
            debug_name = action.port[-1].name
        elif isinstance(action.port, fault.WrappedVerilogInternalPort):
            name = f"dut.{action.port.path}"
            debug_name = name
        else:
            name = verilog_name(action.port.name)
            debug_name = action.port.name
        value = action.value
        if isinstance(value, actions.Peek):
            if isinstance(value.port, fault.WrappedVerilogInternalPort):
                value = f"dut.{value.port.path}"
            else:
                value = f"{value.port.name}"
        elif isinstance(value, PortWrapper):
            value = f"dut.{value.select_path.system_verilog_path}"
        elif isinstance(action.port, m.SIntType) and value < 0:
            # Handle sign extension for verilator since it expects and
            # unsigned c type
            port_len = len(action.port)
            value = BitVector(value, port_len).as_uint()

        return [
            f"if ({name} != {value}) $error(\"Failed on action={i}"
            f" checking port {debug_name}. Expected %x, got %x\""
            f", {value}, {name});"
        ]
Esempio n. 3
0
 def make_poke(self, i, action):
     name = verilog_name(action.port.name)
     value = action.value
     width = get_width(action.port)
     # self.curr_state_pokes.append(
     #     f"{name} = {value}_{width}")
     self.curr_state_pokes.append(
         f"self.{name} = {value}_{width}")
Esempio n. 4
0
 def make_poke(self, i, action):
     if isinstance(action.port, SelectPath):
         if len(action.port) > 2:
             name = f"dut.{action.port.system_verilog_path}"
         else:
             # Top level ports assign to the external reg
             name = verilog_name(action.port[-1].name)
     elif isinstance(action.port, fault.WrappedVerilogInternalPort):
         name = f"dut.{action.port.path}"
     else:
         name = verilog_name(action.port.name)
     # For now we assume that verilog can handle big ints
     value = action.value
     if isinstance(action.port, m.SIntType) and value < 0:
         # Handle sign extension for verilator since it expects and
         # unsigned c type
         port_len = len(action.port)
         value = BitVector(value, port_len).as_uint()
     return [f"{name} = {value};", f"#{self.clock_step_delay}"]
Esempio n. 5
0
 def make_step(self, i, action):
     name = verilog_name(action.clock.name)
     code = []
     for step in range(action.steps):
         code.append("top->eval();")
         code.append("main_time++;")
         code.append("#if VM_TRACE")
         code.append("tracer->dump(main_time);")
         code.append("#endif")
         code.append(f"top->{name} ^= 1;")
     return code
Esempio n. 6
0
    def make_expect(self, i, action):
        # For verilator, if an expect is "AnyValue" we don't need to
        # perform the expect.
        if value_utils.is_any(action.value):
            return []
        if self.verilator_version > 3.874:
            prefix = f"{self.circuit_name}"
        else:
            prefix = f"v"
        if isinstance(action.port, fault.WrappedVerilogInternalPort):
            path = action.port.path.replace(".", "->")
            name = f"{prefix}->{path}"
            debug_name = name
        elif isinstance(action.port, SelectPath):
            name = action.port.verilator_path
            if len(action.port) > 2:
                name = f"{prefix}->" + name
            if self.verilator_version >= 3.856:
                if len(action.port) > 2:
                    self.debug_includes.add(f"{action.port[0].circuit.name}")
            for item in action.port[1:-1]:
                circuit_name = type(item.instance).name
                self.debug_includes.add(f"{circuit_name}")
            debug_name = action.port[-1].debug_name
        else:
            name = verilog_name(action.port.name)
            debug_name = action.port.debug_name
        value = action.value
        if isinstance(value, actions.Peek):
            if isinstance(value.port, fault.WrappedVerilogInternalPort):
                path = action.port.path.replace(".", "->")
                value = f"top->{prefix}->{path}"
            else:
                value = f"top->{verilog_name(value.port.name)}"
        elif isinstance(value, PortWrapper):
            if self.verilator_version >= 3.856:
                if len(action.port) > 2:
                    self.debug_includes.add(f"{action.port[0].circuit.name}")
            for item in value.select_path[1:-1]:
                circuit_name = type(item.instance).name
                self.debug_includes.add(f"{circuit_name}")
            value = f"top->{prefix}->" + value.select_path.verilator_path
        elif isinstance(action.port, m.SIntType) and value < 0:
            # Handle sign extension for verilator since it expects and
            # unsigned c type
            port_len = len(action.port)
            value = BitVector(value, port_len).as_uint()

        return [f"my_assert(top->{name}, {value}, " f"{i}, \"{debug_name}\");"]
Esempio n. 7
0
 def make_poke(self, i, action):
     if isinstance(action.port, SelectPath):
         name = f"dut.{action.port.system_verilog_path}"
     elif isinstance(action.port, fault.WrappedVerilogInternalPort):
         name = f"dut.{action.port.path}"
     else:
         name = verilog_name(action.port.name)
     if isinstance(action.value, BitVector) and \
             action.value.num_bits > 32:
         raise NotImplementedError()
     else:
         value = action.value
         if isinstance(action.port, m.SIntType) and value < 0:
             # Handle sign extension for verilator since it expects and
             # unsigned c type
             port_len = len(action.port)
             value = BitVector(value, port_len).as_uint()
         return [f"{name} = {value};", f"#{self.clock_step_delay}"]
Esempio n. 8
0
 def make_print(self, i, action):
     name = verilog_name(action.port.name)
     return [
         f'printf("{action.port.debug_name} = '
         f'{action.format_str}\\n", top->{name});'
     ]
Esempio n. 9
0
    def make_poke(self, i, action):
        if self.verilator_version > 3.874:
            prefix = f"{self.circuit_name}"
        else:
            prefix = f"v"
        if isinstance(action.port, fault.WrappedVerilogInternalPort):
            path = action.port.path.replace(".", "->")
            name = f"{prefix}->{path}"
        elif isinstance(action.port, SelectPath):
            name = ""
            if len(action.port) > 2:
                # TODO: Find the version that they changed this, 3.874 is known
                # to use top->v instead of top->{circuit_name}
                name += f"{prefix}->"
            name += action.port.verilator_path
            if len(action.port) > 2:
                self.debug_includes.add(f"{action.port[0].circuit.name}")
            for item in action.port[1:-1]:
                circuit = type(item.instance)
                circuit_name = circuit.verilog_name
                # Verilator specializes each parametrization into a separate
                # mdoule, this is an attempt to reverse engineer the naming
                # scheme
                if circuit_name == "coreir_reg":
                    circuit_name += "_"
                    circuit_name += f"_I{circuit.coreir_configargs['init']}"
                    circuit_name += f"_W{circuit.coreir_genargs['width']}"
                elif circuit_name == "coreir_reg_arst":
                    circuit_name += "_"
                    circuit_name += f"_I{circuit.coreir_configargs['init']}"
                    if circuit.coreir_genargs['width'] != 1:
                        circuit_name += f"_W{circuit.coreir_genargs['width']}"
                self.debug_includes.add(f"{circuit_name}")
        else:
            name = verilog_name(action.port.name)

        # Special case poking internal registers
        is_reg_poke = isinstance(action.port, SelectPath) and \
            isinstance(action.port[-1], fault.WrappedVerilogInternalPort) \
            and action.port[-1].path == "outReg"

        # max_bits = 64 if platform.architecture()[0] == "64bit" else 32
        max_bits = 32
        if isinstance(action.value, BitVector) and \
                action.value.num_bits > max_bits:
            asserts = []
            for i in range(math.ceil(action.value.num_bits / max_bits)):
                value = action.value[i * max_bits:min(
                    (i + 1) * max_bits, action.value.num_bits)]
                asserts += [f"top->{name}[{i}] = {value};"]
            if is_reg_poke:
                raise NotImplementedError()
            return asserts
        else:
            value = action.value
            if isinstance(value, actions.FileRead):
                value = f"*{value.file.name_without_ext}_in"
            if isinstance(action.port, m.SIntType) and value < 0:
                # Handle sign extension for verilator since it expects and
                # unsigned c type
                port_len = len(action.port)
                value = BitVector(value, port_len).as_uint()
            result = [f"top->{name} = {value};"]
            # Hack to support verilator's semantics, need to set the register
            # mux values for expected behavior
            if is_reg_poke:
                action.port[-1].path = "out"
                result += self.make_poke(i, action)
                action.port[-1].path = "in"
                result += self.make_poke(i, action)
                if "enable_mux" in action.port[-3].instance_map:
                    mux_inst = action.port[-3].instance_map["enable_mux"]
                    action.port[-2] = InstanceWrapper(mux_inst,
                                                      action.port[-3])
                    action.port[-1] = type(mux_inst).I0
                    result += self.make_poke(i, action)
            return result
Esempio n. 10
0
 def make_step(self, i, action):
     name = verilog_name(action.clock.name)
     code = []
     for step in range(action.steps):
         code.append(f"#5 {name} ^= 1;")
     return code
Esempio n. 11
0
 def make_print(self, i, action):
     name = verilog_name(action.port.name)
     return [
         f'$display("{action.port.debug_name} = '
         f'{action.format_str}", {name});'
     ]