Ejemplo n.º 1
0
    def make_constant_array_mul_signal(self, expr: Product):
        # figure out which operand is the constant array and which is the signal (note: if both are constant arrays,
        # that is not handled in a special fashion.  although that shouldn't usually occur due to the way that
        # expressions are built up.)
        if isinstance(expr.operands[0], Array) and expr.operands[0].all_constants:
            constant_array = expr.operands[0]
            signal = self.expr_to_signal(expr.operands[1])
        elif isinstance(expr.operands[1], Array) and expr.operands[1].all_constants:
            constant_array = expr.operands[1]
            signal = self.expr_to_signal(expr.operands[0])
        else:
            raise Exception(f'This expression does not represent a constant array times a signal: {expr}.')

        # create the output signal
        output = Signal(name=next(self.namer), format_=expr.format_)

        # create a short real variable to be assigned the selected value from the array
        array_name = next(self.namer)
        self.macro_call('MAKE_SHORT_REAL', array_name, compile_range_expr(constant_array.format_.range_))

        # perform the multiplication
        self.macro_call('MUL_REAL', array_name, signal.name, output.name)

        # compile the array address to a signal
        address = self.expr_to_signal(constant_array.address)

        # compute the valuess to go in the array
        values = [f'`FROM_REAL({element.value}, {array_name})' for element in constant_array.elements]

        # create the array itself
        case_statment(gen=self, sel=address.name, var=array_name, values=values, default=0)

        # return the output signal
        return output
Ejemplo n.º 2
0
    def make_constant(self, expr: Constant):
        output = Signal(name=next(self.namer), format_=expr.format_)

        if isinstance(expr.format_, RealFormat):
            # compile the range, width, and exponent expressions.
            if isinstance(expr.value, Integral):
                # avoid a synthesis corner-case:
                # https://forums.xilinx.com/t5/Synthesis/Possible-synthesis-bug-casting-integer-to-real-in-a-function/td-p/1140910
                const = str(float(expr.value))
            else:
                const = str(expr.value)
            range = compile_range_expr(expr.format_.range_)
            width = compile_width_expr(expr.format_.width)
            exponent = compile_exponent_expr(expr.format_.exponent)

            # call the appropriate macro
            if width is None:
                self.macro_call('MAKE_CONST_REAL', const, output.name)
            elif exponent is None:
                self.macro_call('MAKE_GENERIC_CONST_REAL', const, output.name, width)
            else:
                self.macro_call('MAKE_FORMAT_REAL', output.name, range, width, exponent)
                self.macro_call('ASSIGN_CONST_REAL', const, output.name)
        elif isinstance(expr.format_, IntFormat):
            self.make_signal(output)
            self.digital_assignment(output, expr.value)
        else:
            raise ValueError(f'Unknown expression format type: ' + expr.format_.__class__.__name__)

        return output
Ejemplo n.º 3
0
    def make_constant(self, expr: Constant):
        output = Signal(name=next(self.namer), format_=expr.format_)

        if isinstance(expr.format_, RealFormat):
            # compile the range, width, and exponent expressions
            const = str(expr.value)
            range = compile_range_expr(expr.format_.range_)
            width = compile_width_expr(expr.format_.width)
            exponent = compile_exponent_expr(expr.format_.exponent)

            # call the appropriate macro
            if width is None:
                self.macro_call('MAKE_CONST_REAL', const, output.name)
            elif exponent is None:
                self.macro_call('MAKE_GENERIC_CONST_REAL', const, output.name, width)
            else:
                self.macro_call('MAKE_FORMAT_REAL', output.name, range, width, exponent)
                self.macro_call('ASSIGN_CONST_REAL', const, output.name)
        elif isinstance(expr.format_, IntFormat):
            self.make_signal(output)
            self.digital_assignment(output, expr.value)
        else:
            raise ValueError(f'Unknown expression format type: ' + expr.format_.__class__.__name__)

        return output
Ejemplo n.º 4
0
    def make_signal(self, signal: Signal):
        if isinstance(signal.format_, RealFormat):
            # compile the range, width, and exponent expressions
            range = compile_range_expr(signal.format_.range_)
            width = compile_width_expr(signal.format_.width)
            exponent = compile_exponent_expr(signal.format_.exponent)

            # call the appropriate macro
            if width is None:
                self.macro_call('MAKE_REAL', signal.name, range)
            elif exponent is None:
                self.macro_call('MAKE_GENERIC_REAL', signal.name, range, width)
            else:
                self.macro_call('MAKE_FORMAT_REAL', signal.name, range, width, exponent)
        elif isinstance(signal.format_, IntFormat):
            self.writeln(f'{self.int_type_str(signal.format_)} {signal.name};')
        else:
            raise Exception('Invalid signal type.')