def wrapper(dut, module_name, iterator_support, config_path_input, name, in_file_name="", out_file_name=""): lc, ls = check_env() # we are in the process of transitioning to csvs being in this folder # lc = <path to clockwork>/aha_garnet_design/ config_path = lc + config_path_input configs = dut.get_static_bitstream(config_path) # prints out list of configs for compiler team configs_list = set_configs_sv(dut, "configs.sv", get_configs_dict(configs), iterator_support) # get flattened module flattened = create_wrapper_flatten(dut.internal_generator.clone(), f"{module_name}_W") inst = Generator(f"{module_name}_W", internal_generator=flattened) verilog(inst, filename=f"{module_name}_W.v") # get original verilog verilog(dut, filename=f"{module_name}_dut.v") # prepend wrapper module to original verilog file with open(f"{module_name}_W.v", "a") as with_flatten: with open(f"{module_name}_dut.v", "r") as dut_file: for line in dut_file: with_flatten.write(line) generate_lake_config_wrapper(configs_list, "configs.sv", f"{module_name}_W.v", name, module_name)
def test_regression_flatten_array_param(): from _kratos import create_wrapper_flatten mod = Generator("mod") p = mod.parameter("param", value=16) mod.input("in", width=p) inst = create_wrapper_flatten(mod.internal_generator, "wrapper") gen = Generator("", internal_generator=inst) src = verilog(gen)["wrapper"] assert "parameter param = 32'h10" in src
def get_static_bitstream_json(self, root_node): # Dummy variables to fill in later when compiler # generates different collateral for different designs flattened = create_wrapper_flatten(self.internal_generator.clone(), self.name + "_W") # Store all configurations here config = [] # Get controllers from json node... assert "in2regfile_0" in root_node assert "regfile2out_0" in root_node in2rf_ctrl = map_controller( extract_controller_json(root_node["in2regfile_0"]), "in2regfile") rf2out_ctrl = map_controller( extract_controller_json(root_node["regfile2out_0"]), "regfile2out") # Configure registers based on controller data... config.append(("rf_write_iter_0_dimensionality", in2rf_ctrl.dim)) config.append( ("rf_write_addr_0_starting_addr", in2rf_ctrl.in_data_strt)) config.append(("rf_write_sched_0_sched_addr_gen_starting_addr", in2rf_ctrl.cyc_strt)) config.append(("rf_write_sched_0_enable", 1)) for i in range(in2rf_ctrl.dim): config.append( (f"rf_write_addr_0_strides_{i}", in2rf_ctrl.in_data_stride[i])) config.append( (f"rf_write_iter_0_ranges_{i}", in2rf_ctrl.extent[i])) config.append((f"rf_write_sched_0_sched_addr_gen_strides_{i}", in2rf_ctrl.cyc_stride[i])) config.append(("rf_read_iter_0_dimensionality", rf2out_ctrl.dim)) config.append( ("rf_read_addr_0_starting_addr", rf2out_ctrl.out_data_strt)) config.append(("rf_read_sched_0_sched_addr_gen_starting_addr", rf2out_ctrl.cyc_strt)) config.append(("rf_read_sched_0_enable", 1)) for i in range(rf2out_ctrl.dim): config.append((f"rf_read_addr_0_strides_{i}", rf2out_ctrl.out_data_stride[i])) config.append( (f"rf_read_iter_0_ranges_{i}", rf2out_ctrl.extent[i])) config.append((f"rf_read_sched_0_sched_addr_gen_strides_{i}", rf2out_ctrl.cyc_stride[i])) # Handle control registers... (should really be done in garnet TODO) config.append(("flush_reg_sel", 0)) # 1 config.append(("flush_reg_value", 0)) # 1 # Activate the tile... config.append(("tile_en", 1)) # 1 # Trim the list return trim_config_list(flattened, config)
def get_static_bitstream(self, config_path): controllers = [ "in2regfile_0", "in2regfile_1", "regfile2out_0", "regfile2out_1" ] controller_objs = [None] * len(controllers) for i in range(len(controllers)): c = controllers[i] path = config_path + '/' + c + '.csv' if os.path.isfile(path): print(path) controller_objs[i] = map_controller(extract_controller(path), c) else: # print(f"No {c} file provided. Is this expected?") print(f"No {c} file provided. ?") controller_objs[i] = None in2rf_ctrl_1, in2rf_ctrl_2, rf2out_ctrl_1, rf2out_ctrl_2 = controller_objs # Dummy variables to fill in later when compiler # generates different collateral for different designs flattened = create_wrapper_flatten(self.internal_generator.clone(), self.name + "_W") # Store all configurations here config = [] # Configure registers based on controller data... if in2rf_ctrl_1: config.append(("rf_write_iter_0_dimensionality", in2rf_ctrl_1.dim)) config.append( ("rf_write_addr_0_starting_addr", in2rf_ctrl_1.in_data_strt)) config.append(("rf_write_sched_0_sched_addr_gen_starting_addr", in2rf_ctrl_1.cyc_strt)) config.append(("rf_write_sched_0_enable", 1)) for i in range(in2rf_ctrl_1.dim): config.append((f"rf_write_addr_0_strides_{i}", in2rf_ctrl_1.in_data_stride[i])) config.append( (f"rf_write_iter_0_ranges_{i}", in2rf_ctrl_1.extent[i])) config.append((f"rf_write_sched_0_sched_addr_gen_strides_{i}", in2rf_ctrl_1.cyc_stride[i])) if rf2out_ctrl_1: config.append(("rf_read_iter_0_dimensionality", rf2out_ctrl_1.dim)) config.append( ("rf_read_addr_0_starting_addr", rf2out_ctrl_1.out_data_strt)) config.append(("rf_read_sched_0_sched_addr_gen_starting_addr", rf2out_ctrl_1.cyc_strt)) config.append(("rf_read_sched_0_enable", 1)) for i in range(rf2out_ctrl_1.dim): config.append((f"rf_read_addr_0_strides_{i}", rf2out_ctrl_1.out_data_stride[i])) config.append( (f"rf_read_iter_0_ranges_{i}", rf2out_ctrl_1.extent[i])) config.append((f"rf_read_sched_0_sched_addr_gen_strides_{i}", rf2out_ctrl_1.cyc_stride[i])) if in2rf_ctrl_2: config.append(("rf_write_iter_1_dimensionality", in2rf_ctrl_2.dim)) config.append( ("rf_write_addr_1_starting_addr", in2rf_ctrl_2.in_data_strt)) config.append(("rf_write_sched_1_sched_addr_gen_starting_addr", in2rf_ctrl_2.cyc_strt)) config.append(("rf_write_sched_1_enable", 1)) for i in range(in2rf_ctrl_2.dim): config.append((f"rf_write_addr_1_strides_{i}", in2rf_ctrl_2.in_data_stride[i])) config.append( (f"rf_write_iter_1_ranges_{i}", in2rf_ctrl_2.extent[i])) config.append((f"rf_write_sched_1_sched_addr_gen_strides_{i}", in2rf_ctrl_2.cyc_stride[i])) if rf2out_ctrl_2: config.append(("rf_read_iter_1_dimensionality", rf2out_ctrl_2.dim)) config.append( ("rf_read_addr_1_starting_addr", rf2out_ctrl_2.out_data_strt)) config.append(("rf_read_sched_1_sched_addr_gen_starting_addr", rf2out_ctrl_2.cyc_strt)) config.append(("rf_read_sched_1_enable", 1)) for i in range(rf2out_ctrl_2.dim): config.append((f"rf_read_addr_1_strides_{i}", rf2out_ctrl_2.out_data_stride[i])) config.append( (f"rf_read_iter_1_ranges_{i}", rf2out_ctrl_2.extent[i])) config.append((f"rf_read_sched_1_sched_addr_gen_strides_{i}", rf2out_ctrl_2.cyc_stride[i])) # Handle control registers... (should really be done in garnet TODO) config.append(("flush_reg_sel", 0)) # 1 config.append(("flush_reg_value", 0)) # 1 # Activate the tile... config.append(("tile_en", 1)) # 1 # Trim the list return trim_config_list(flattened, config)
def to_magma(kratos_inst, flatten_array=False, top_name=None, **kargs): # pragma: no cover import magma as m from kratos import verilog, Generator from _kratos import create_wrapper_flatten if flatten_array: inst = create_wrapper_flatten(kratos_inst.internal_generator, kratos_inst.name + "_W") inst = Generator(kratos_inst.name, internal_generator=inst) # only add the child, nothing more inst.add_child(kratos_inst.instance_name, kratos_inst, python_only=True) kratos_inst = inst if top_name is not None: kratos_inst.instance_name = top_name circ_name = kratos_inst.name internal_gen = kratos_inst.internal_generator ports = internal_gen.get_port_names() io = {} for port_name in ports: port = kratos_inst.ports[port_name] width = port.width size = port.size dir_ = m.In if port.port_direction == _kratos.PortDirection.In \ else m.Out type_ = port.port_type signed = port.signed if type_ == _kratos.PortType.Clock: type_value = m.Clock elif type_ == _kratos.PortType.AsyncReset: if port.active_high or port.active_high is None: type_value = m.AsyncReset else: type_value = m.AsyncResetN else: # normal logic/wire, loop through the ndarray to construct # magma arrays, notice it's in reversed order type_value = m.Bits[width] if not signed else m.SInt[width] if len(size) > 1 or size[0] > 1: for idx, array_width in enumerate(reversed(size)): type_value = m.Array[array_width, type_value] io[port_name] = (dir_(type_value)) magma_io = m.IO(**io) class _Definition(m.Circuit): name = circ_name io = magma_io kratos = kratos_inst os.makedirs(".magma", exist_ok=True) filename = f".magma/{circ_name}-kratos.sv" enable_multi_generate() # multiple definition inside the kratos instance is taken care of by # the track definition flag verilog(kratos_inst, filename=filename, track_generated_definition=True, **kargs) with open(filename, 'r') as f: _Definition.verilogFile = f.read() return _Definition
def generate_pond_api(interconnect, pondcore, ctrl_rd, ctrl_wr, pe_x, pe_y, config_data): flattened = create_wrapper_flatten(pondcore.dut.internal_generator.clone(), pondcore.dut.name) (tform_ranges_rd, tform_strides_rd) = transform_strides_and_ranges(ctrl_rd[0], ctrl_rd[1], ctrl_rd[2]) (tform_ranges_wr, tform_strides_wr) = transform_strides_and_ranges(ctrl_wr[0], ctrl_wr[1], ctrl_wr[2]) name_out, val_out = trim_config(flattened, "tile_en", 1) idx, value = pondcore.get_config_data(name_out, val_out) config_data.append((interconnect.get_config_addr(idx, 1, pe_x, pe_y), value)) name_out, val_out = trim_config(flattened, "rf_read_iter_0_dimensionality", ctrl_rd[2]) idx, value = pondcore.get_config_data(name_out, val_out) config_data.append((interconnect.get_config_addr(idx, 1, pe_x, pe_y), value)) name_out, val_out = trim_config(flattened, "rf_read_addr_0_starting_addr", ctrl_rd[3]) idx, value = pondcore.get_config_data(name_out, val_out) config_data.append((interconnect.get_config_addr(idx, 1, pe_x, pe_y), value)) name_out, val_out = trim_config(flattened, "rf_read_addr_0_strides_0", tform_strides_rd[0]) idx, value = pondcore.get_config_data(name_out, val_out) config_data.append((interconnect.get_config_addr(idx, 1, pe_x, pe_y), value)) name_out, val_out = trim_config(flattened, "rf_read_addr_0_strides_1", tform_strides_rd[1]) idx, value = pondcore.get_config_data(name_out, val_out) config_data.append((interconnect.get_config_addr(idx, 1, pe_x, pe_y), value)) name_out, val_out = trim_config(flattened, "rf_read_iter_0_ranges_0", tform_ranges_rd[0]) idx, value = pondcore.get_config_data(name_out, val_out) config_data.append((interconnect.get_config_addr(idx, 1, pe_x, pe_y), value)) name_out, val_out = trim_config(flattened, "rf_read_iter_0_ranges_1", tform_ranges_rd[1]) idx, value = pondcore.get_config_data(name_out, val_out) config_data.append((interconnect.get_config_addr(idx, 1, pe_x, pe_y), value)) name_out, val_out = trim_config( flattened, "rf_read_sched_0_sched_addr_gen_starting_addr", ctrl_rd[4]) idx, value = pondcore.get_config_data(name_out, val_out) config_data.append((interconnect.get_config_addr(idx, 1, pe_x, pe_y), value)) name_out, val_out = trim_config( flattened, "rf_read_sched_0_sched_addr_gen_strides_0", tform_strides_rd[0]) idx, value = pondcore.get_config_data(name_out, val_out) config_data.append((interconnect.get_config_addr(idx, 1, pe_x, pe_y), value)) name_out, val_out = trim_config( flattened, "rf_read_sched_0_sched_addr_gen_strides_1", tform_strides_rd[1]) idx, value = pondcore.get_config_data(name_out, val_out) config_data.append((interconnect.get_config_addr(idx, 1, pe_x, pe_y), value)) name_out, val_out = trim_config(flattened, "rf_write_iter_0_dimensionality", ctrl_wr[2]) idx, value = pondcore.get_config_data(name_out, val_out) config_data.append((interconnect.get_config_addr(idx, 1, pe_x, pe_y), value)) name_out, val_out = trim_config(flattened, "rf_write_addr_0_starting_addr", ctrl_wr[3]) idx, value = pondcore.get_config_data(name_out, val_out) config_data.append((interconnect.get_config_addr(idx, 1, pe_x, pe_y), value)) name_out, val_out = trim_config(flattened, "rf_write_addr_0_strides_0", tform_strides_wr[0]) idx, value = pondcore.get_config_data(name_out, val_out) config_data.append((interconnect.get_config_addr(idx, 1, pe_x, pe_y), value)) name_out, val_out = trim_config(flattened, "rf_write_addr_0_strides_1", tform_strides_wr[1]) idx, value = pondcore.get_config_data(name_out, val_out) config_data.append((interconnect.get_config_addr(idx, 1, pe_x, pe_y), value)) name_out, val_out = trim_config(flattened, "rf_write_iter_0_ranges_0", tform_ranges_wr[0]) idx, value = pondcore.get_config_data(name_out, val_out) config_data.append((interconnect.get_config_addr(idx, 1, pe_x, pe_y), value)) name_out, val_out = trim_config(flattened, "rf_write_iter_0_ranges_1", tform_ranges_wr[1]) idx, value = pondcore.get_config_data(name_out, val_out) config_data.append((interconnect.get_config_addr(idx, 1, pe_x, pe_y), value)) name_out, val_out = trim_config( flattened, "rf_write_sched_0_sched_addr_gen_starting_addr", ctrl_wr[4]) idx, value = pondcore.get_config_data(name_out, val_out) config_data.append((interconnect.get_config_addr(idx, 1, pe_x, pe_y), value)) name_out, val_out = trim_config( flattened, "rf_write_sched_0_sched_addr_gen_strides_0", tform_strides_wr[0]) idx, value = pondcore.get_config_data(name_out, val_out) config_data.append((interconnect.get_config_addr(idx, 1, pe_x, pe_y), value)) name_out, val_out = trim_config( flattened, "rf_write_sched_0_sched_addr_gen_strides_1", tform_strides_wr[1]) idx, value = pondcore.get_config_data(name_out, val_out) config_data.append((interconnect.get_config_addr(idx, 1, pe_x, pe_y), value))
def get_static_bitstream(self, config_path, in_file_name, out_file_name): input_ports = 1 output_ports = 1 in2agg = map_controller(extract_controller(config_path + '/' + in_file_name + '_in2agg_0.csv'), "in2agg") agg2sram = map_controller(extract_controller(config_path + '/' + in_file_name + '_agg2sram.csv'), "agg2sram") sram2tb = map_controller(extract_controller(config_path + '/' + out_file_name + '_2_sram2tb.csv'), "sram2tb") tb2out0 = map_controller(extract_controller(config_path + '/' + out_file_name + '_2_tb2out_0.csv'), "tb2out0") tb2out1 = map_controller(extract_controller(config_path + '/' + out_file_name + '_2_tb2out_1.csv'), "tb2out1") # Getting bitstreams is a little unweildy due to fault (or its underlying implementation) not # handling arrays in the interface. # To alleviate this, we create the flattened wrapper so we can query widths of config # registers and trim values to their bitwidths... print(f"Current_name: {self.name}") flattened = create_wrapper_flatten(self.internal_generator.clone(), self.name + "_W") # Set configuration... config = [ ("agg0_agg1_sram_edge_read_addr_gen_starting_addr", agg2sram.out_data_strt), ("agg0_agg1_sram_edge_write_addr_gen_starting_addr", agg2sram.in_data_strt), ("agg0_agg1_sram_edge_sched_gen_sched_addr_gen_starting_addr", agg2sram.cyc_strt), ("agg0_agg1_sram_edge_sched_gen_enable", 1), ("agg0_agg1_sram_edge_forloop_dimensionality", agg2sram.dim), ("sram_tb0_tb1_edge_read_addr_gen_starting_addr", sram2tb.out_data_strt), ("sram_tb0_tb1_edge_write_addr_gen_starting_addr", sram2tb.in_data_strt), ("sram_tb0_tb1_edge_sched_gen_sched_addr_gen_starting_addr", sram2tb.cyc_strt), ("sram_tb0_tb1_edge_sched_gen_enable", 1), ("sram_tb0_tb1_edge_forloop_dimensionality", sram2tb.dim), ("input_port0_2agg0_write_addr_gen_starting_addr", in2agg.in_data_strt), ("input_port0_2agg0_write_sched_gen_sched_addr_gen_starting_addr", in2agg.cyc_strt), ("input_port0_2agg0_write_sched_gen_enable", 1), ("input_port0_2agg0_forloop_dimensionality", in2agg.dim), ("tb02output_port0_read_addr_gen_starting_addr", tb2out0.out_data_strt), ("tb02output_port0_read_sched_gen_sched_addr_gen_starting_addr", tb2out0.cyc_strt), ("tb02output_port0_read_sched_gen_enable", 1), ("tb02output_port0_forloop_dimensionality", tb2out0.dim), ("tb12output_port1_read_addr_gen_starting_addr", tb2out1.out_data_strt), ("tb12output_port1_read_sched_gen_sched_addr_gen_starting_addr", tb2out1.cyc_strt), ("tb12output_port1_read_sched_gen_enable", 1), ("tb12output_port1_forloop_dimensionality", tb2out1.dim), ("tile_en", 1), # 1 ] # Check the hardware if it supports stencil valid if self.stencil_valid: cfg_path = config_path + '/' + 'stencil_valid.csv' # Check if the stencil valid file exists...if it doesn't we just won't program it if os.path.exists(cfg_path): stcl_valid = map_controller(extract_controller(cfg_path), "stencil_valid") config.append((f"loops_stencil_valid_dimensionality", stcl_valid.dim)) config.append((f"stencil_valid_sched_gen_sched_addr_gen_starting_addr", stcl_valid.cyc_strt)) for i in range(stcl_valid.dim): config.append((f"loops_stencil_valid_ranges_{i}", stcl_valid.extent[i])) config.append((f"stencil_valid_sched_gen_sched_addr_gen_strides_{i}", stcl_valid.cyc_stride[i])) else: print("No configuration file provided for stencil valid...are you expecting one to exist?") print(f"Bogus stencil valid path: {cfg_path}") for i in range(in2agg.dim): config.append((f"input_port0_2agg0_forloop_ranges_{i}", in2agg.extent[i])) config.append((f"input_port0_2agg0_write_addr_gen_strides_{i}", in2agg.in_data_stride[i])) config.append((f"input_port0_2agg0_write_sched_gen_sched_addr_gen_strides_{i}", in2agg.cyc_stride[i])) for i in range(agg2sram.dim): config.append((f"agg0_agg1_sram_edge_read_addr_gen_strides_{i}", agg2sram.out_data_stride[i])) config.append((f"agg0_agg1_sram_edge_forloop_ranges_{i}", agg2sram.extent[i])) config.append((f"agg0_agg1_sram_edge_write_addr_gen_strides_{i}", agg2sram.in_data_stride[i])) config.append((f"agg0_agg1_sram_edge_sched_gen_sched_addr_gen_strides_{i}", agg2sram.cyc_stride[i])) tbs = [tb2out0, tb2out1] for i in range(sram2tb.dim): config.append((f"sram_tb0_tb1_edge_forloop_ranges_{i}", sram2tb.extent[i])) config.append((f"sram_tb0_tb1_edge_read_addr_gen_strides_{i}", sram2tb.out_data_stride[i])) config.append((f"sram_tb0_tb1_edge_sched_gen_sched_addr_gen_strides_{i}", sram2tb.cyc_stride[i])) config.append((f"sram_tb0_tb1_edge_write_addr_gen_strides_{i}", sram2tb.in_data_stride[i])) tbs = [tb2out0, tb2out1] for tb in range(len(tbs)): elem = tbs[tb] for i in range(elem.dim): if tb == 0: config.append((f"tb02output_port0_read_addr_gen_strides_{i}", elem.out_data_stride[i])) config.append((f"tb02output_port0_read_sched_gen_sched_addr_gen_strides_{i}", elem.cyc_stride[i])) config.append((f"tb02output_port0_forloop_ranges_{i}", elem.extent[i])) else: config.append((f"tb12output_port1_read_addr_gen_strides_{i}", elem.out_data_stride[i])) config.append((f"tb12output_port1_read_sched_gen_sched_addr_gen_strides_{i}", elem.cyc_stride[i])) config.append((f"tb12output_port1_forloop_ranges_{i}", elem.extent[i])) return trim_config_list(flattened, config)