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
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
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
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.')