Example #1
0
def replace_class_references(ast, classrefs):
	"""
	This function performs rewrites for the HLS hardware design.
	Replace references to static class information with juniper_get_class_reference, a hardcoded syscall 
	back to the host which fetches a juniper_ref of the class metadata.
	"""
	def recurse(node):
		for c in node.children(): 
			recurse(c[1])	
		if isinstance(node, c_ast.ID):
			if node.name in classrefs.all:
				if not node.name in classrefs.referenced: 
					classrefs.referenced[node.name] = len(classrefs.referenced) + 1
				fcall = make_func_call_node("juniper_get_class_reference", ["1", str(classrefs.referenced[node.name])])
				replace_node(node, fcall)
		
	recurse(ast)
	add_parent_links(ast)
Example #2
0
def rewrite_RAM_structure_dereferences(ast):
	"""
	The replacement Jamaica headers use RAM_NAME as a global pointer to the external bus interface. 
	Unfortunately, JamaicaBuilder assumes that the type of this pointer is a complex 
	union-of-structs-of-arrays. This rewrites such accesses to use a set of memory access functions
	declared in fpgaporting.h that allow a more HLS-friendly representation of RAM.
	We are looking for structures like the following:
	  ArrayRef:
		StructRef: .
		  ArrayRef: 
			ID: __juniper_ram_master
			<Anything else>
		  ID: f
		Constant: int, 2
	"""
	def rewrite_structref(node):
		"""
		Called by recurse to check a StructRef node for if rewrites are necessary, and if so, make them. 
		"""
		deref_type = node.field.name  # What was dereferenced ('i', 's', 'c', 'r', etc.)

		# When a subword type, there may be a higher level arrayref :- __juniper_ram_master[x].s[4]
		# Save the '4' ast in top_array_deref
		top_array_deref = None
		if isinstance(node.parent, c_ast.ArrayRef) and not node == node.parent.subscript:
			top_array_deref = node.parent.subscript
			nodetoreplace = node.parent
		else:
			nodetoreplace = node	
		
		arf = node.name

		if isinstance(nodetoreplace.parent, c_ast.Assignment) and nodetoreplace.parent.op == "=" and nodetoreplace.parent.lvalue == nodetoreplace:
			callname = RAM_SET_NAME
			callargs = [arf.subscript, top_array_deref, nodetoreplace.parent.rvalue]
			nodetoreplace = nodetoreplace.parent  # The top level Assignment 
		else: 
			callname = RAM_GET_NAME
			callargs = [arf.subscript, top_array_deref]
		callname = callname + str(deref_type)
		
		replacementnode = make_func_call_node(callname, callargs)
		replace_node(nodetoreplace, replacementnode)

	def recurse(node):
		"""
		Recurse depth-first through the provided AST down to the leaf nodes.
		Then, whilst popping off the stack, any StructRef nodes are passed to rewrite_structref
		If changes are made, returns True
		"""
		changemade = False
		for c in node.children(): 
			if recurse(c[1]):
				changemade = True
		if isinstance(node, c_ast.StructRef):
			if node.type == "." and isinstance(node.name, c_ast.ArrayRef) and node.name.name.name == RAM_NAME:
				rewrite_structref(node)
				changemade = True
		return changemade
				
	while recurse(ast): 
		# After moving nodes we need to correct the parent links. 
		# TODO: Potential optimisation to fix the links only as they are moved, but this isn't too slow
		add_parent_links(ast)