def generateArchitectureDefinition(self): architecture = """ architecture rtl of {} is type enable_stage_type is array(natural range <>) of std_logic_vector(0 to DEMUX_NUM-1 + DEMUX_FACTOR); signal enable_stage : enable_stage_type(0 to DEMUX_STAGES); type index_stage_type is array(natural range <>) of demux_index_array_type(0 to DEMUX_NUM-1 + DEMUX_FACTOR); signal index_stage : index_stage_type(0 to DEMUX_STAGES); type data_stage_type is array(natural range <>) of demux_data_array_type(0 to DEMUX_NUM-1 + DEMUX_FACTOR); signal data_stage : data_stage_type(0 to DEMUX_STAGES); {} begin enable_stage(0)(0) <= enable_in; index_stage(0)(0) <= index_in; data_stage(0)(0) <= data_in; GEN_STAGES: for s in 0 to DEMUX_STAGES-1 generate GEN_STAGE: for i in 0 to (DEMUX_NUM-1) / (DEMUX_FACTOR ** (DEMUX_STAGES - s)) generate {} end generate GEN_STAGE; end generate GEN_STAGES; enable_out <= enable_stage(DEMUX_STAGES)(0 to DEMUX_NUM-1); data_out <= data_stage(DEMUX_STAGES)(0 to DEMUX_NUM-1); end rtl; """ component_declaration = self.dsg.generateComponentDeclaration() signal_map = { "clk": "clk", "enable_in": "enable_stage(s)(i)", "index_in": "index_stage(s)(i)", "data_in": "data_stage(s)(i)", "data_out": "data_stage(s+1)(0 + i*DEMUX_FACTOR to DEMUX_FACTOR-1 + i*DEMUX_FACTOR)", "enable_out": "enable_stage(s+1)(0 + i*DEMUX_FACTOR to DEMUX_FACTOR-1 + i*DEMUX_FACTOR)", "rest_out": "index_stage(s+1)(0 + i*DEMUX_FACTOR to DEMUX_FACTOR-1 + i*DEMUX_FACTOR)" } generic_map = {"STAGE_FACTOR": "DEMUX_STAGES-1 - s"} component_instantiation = generateComponentInstantiation( "DEMUX_SINGLE_INST", self.dsg.entity_name, signal_map, generic_map) return architecture.format(self.entity_name, component_declaration, component_instantiation)
def generateAsynchronousArchitectureDefinition(self): frame = """ ARCHITECTURE a{} OF {} IS {} BEGIN process(clk) begin if rising_edge(clk) then if val_en_in = '1' then state <= u_outstate; end if; end if; end process; {} END a{}; """ decl = "" #Declarations ## Update Stage decl += self.ug.generateComponentDeclaration() ## Connecting signals for signal in self.ug.generateDeclarationSignals(): decl += "\nsignal u_{} : {};".format(signal[0], signal[2]) decl += "\nsignal state : std_logic_vector({} downto 0) := {};".format( self.wstate - 1, self.initial_state) #Architecture behavior ## Generate component instanciations bhv = "" signal_map = generateSignalMap(self.ug.generateDeclarationSignals(), "u_") bhv += generateComponentInstantiation("u", self.ug.entity_name, signal_map, None) uin = { "u_clk": "clk", "u_v": "val_in", "u_seed": "useed_in", "u_state": "state", } bhv += generateAssignments(uin) uout = { "rd_data_out": "state", } bhv += generateAssignments(uout) return frame.format(self.entity_name, self.entity_name, decl, bhv, self.entity_name)
def generateAsynchronousArchitecture(self): #Generate auxilliary signals sm = self.generateSignalTypeMap() aux_signals = "" update_declaration = self.ug.generateComponentDeclaration() aux_signals += "\nsignal istate : {};".format(sm["state"]) aux_signals += "\nsignal ioutstate : {};".format(sm["outstate"]) aux_signals += "\nsignal iloutstate : {};".format(sm["outstate"]) aux_signals += "\nsignal iladdress : {};".format(sm["addr_in"]) update_signal_map = { "clk": "clk", "v": "v", "seed": "seed", "state": "istate", "outstate": "ioutstate" } update_component = generateComponentInstantiation( "u", self.ug.entity_name, update_signal_map, None) bhv = """ istate <= iloutstate when fwd_enable_in = '1' and cmp_in = '1' else state ; outstate <= iloutstate; addr_out <= iladdress; process(clk) begin if rising_edge(clk) then iloutstate <= ioutstate; iladdress <= addr_in; end if; end process; """ return self.architecture_frame.format(self.entity_name, self.entity_name, update_declaration + aux_signals, update_component + bhv, self.entity_name)
def generateArchitectureDefinition(self): frame = """ ARCHITECTURE a{} OF {} IS {} BEGIN {} END a{}; """ decl = "" #Declarations for ssg in self.ssgl: decl += ssg.generateComponentDeclaration() decl += self.demuxg.generateComponentDeclaration() decl += self.muxg.generateComponentDeclaration() ## Connecting signals for ssg in self.ssgl: for signal in ssg.generateDeclarationSignals(): decl += "\nsignal ss{}_{} : {};".format( ssg.identifier, signal[0], signal[2]) for signal in self.muxg.generateDeclarationSignals(): decl += "\nsignal smux_{} : {};".format(signal[0], signal[2]) for signal in self.demuxg.generateDeclarationSignals(): decl += "\nsignal sdemux_{} : {};".format(signal[0], signal[2]) decl += "\nsignal addr : std_logic_vector({}-1 downto 0) := (others => '0');".format( self.waddr) decl += "\nsignal index : std_logic_vector({}-1 downto 0) := (others => '0');".format( int(math.ceil(math.log2(self.n_rows)))) decl += "\ntype mem_type is array({} downto 0) of std_logic_vector({} downto 0);".format( self.nss_per_package - 1, self.wvalue - 1) #Architecture behavior ## Generate component instanciations bhv = "" for ssg in self.ssgl: signal_map = generateSignalMap(ssg.generateDeclarationSignals(), "ss{}_".format(ssg.identifier)) bhv += generateComponentInstantiation( "ss{}".format(ssg.identifier), ssg.entity_name, signal_map, None) signal_map = generateSignalMap(self.muxg.generateDeclarationSignals(), "smux_") bhv += generateComponentInstantiation("smux", self.muxg.entity_name, signal_map, None) signal_map = generateSignalMap( self.demuxg.generateDeclarationSignals(), "sdemux_") bhv += generateComponentInstantiation("sdemux", self.demuxg.entity_name, signal_map, None) clk_map = {} clk_map["smux_clk"] = "clk" clk_map["sdemux_clk"] = "clk" seed_map = {} for ssg in self.ssgl: clk_map["ss{}_clk".format(ssg.identifier)] = "clk" seed_map["ss{}_sseed_in".format( ssg.identifier)] = "selector_seeds({})".format(ssg.identifier) seed_map["ss{}_useed_in".format( ssg.identifier)] = "update_seeds({})".format(ssg.identifier) bhv += generateAssignments(clk_map) bhv += generateAssignments(seed_map) demux_inmap = { "sdemux_data_in": "addr", "sdemux_enable_in": "rd_en_in", "sdemux_index_in": "index" } bhv += generateAssignments(demux_inmap) mux_outmap = { "rd_data_out": "smux_data_out", "rd_valid_out": "smux_enable_out" } bhv += generateAssignments(mux_outmap) assignments = "" for ssg in self.ssgl: assignments += " ss{}_val_en_in <= enable_pipe({});\n".format( ssg.identifier, ssg.identifier // self.ss_factor) assignments += " ss{}_val_in <= value_pipe({});\n".format( ssg.identifier, ssg.identifier // self.ss_factor) for ssg in self.ssgl: #Connect demux output to read inputs bhv += "ss{}_rd_en_in <= sdemux_enable_out({});\n".format( ssg.identifier, ssg.identifier) bhv += "ss{}_rd_addr_in <= sdemux_data_out({});\n".format( ssg.identifier, ssg.identifier) #Connect demux output to read inputs bhv += "smux_data_in({}) <= ss{}_rd_data_out ;\n".format( ssg.identifier, ssg.identifier) bhv += "smux_enable_in({}) <= ss{}_rd_valid_out;\n".format( ssg.identifier, ssg.identifier) bhv += """ process(clk) begin if rising_edge(clk) then if rd_en_in = '1' then if to_integer(unsigned(addr)) >= {} then addr <= (others => '0'); if to_integer(unsigned(index)) >= {} then index <= (others => '0'); else index <= std_logic_vector(to_unsigned(to_integer(unsigned(index)) + 1, index'LENGTH)); end if; else addr <= std_logic_vector(to_unsigned(to_integer(unsigned(addr)) + 1, addr'LENGTH)); end if; end if; end if; end process; process(clk) variable enable_pipe : std_logic_vector({} downto 0) := (others => '0'); variable value_pipe : mem_type; begin if rising_edge(clk) then enable_pipe(0) := val_en_in; value_pipe(0) := val_in; {} for i in {} downto 0 loop enable_pipe(i+1) := enable_pipe(i); value_pipe(i+1) := value_pipe(i); end loop; end if; end process; """.format(self.total_size - 1, self.n_rows - 1, self.nss_per_package - 1, assignments, self.nss_per_package - 2) return frame.format(self.entity_name, self.entity_name, decl, bhv, self.entity_name)
def generateArchitectureDefinition(self): frame = """ ARCHITECTURE a{} OF {} IS {} BEGIN {} END a{}; """ decl = "" #Declarations decl += self.ssg.generateComponentDeclaration() decl += self.muxg.generateComponentDeclaration() decl += self.demuxg.generateComponentDeclaration() ## Connecting signals for i in range(0, self.n_sstages): for signal in self.ssg.generateDeclarationSignals(): decl += "\nsignal ss{}_{} : {};".format( i, signal[0], signal[2]) for signal in self.muxg.generateDeclarationSignals(): decl += "\nsignal smux_{} : {};".format(signal[0], signal[2]) for signal in self.demuxg.generateDeclarationSignals(): decl += "\nsignal sdemux_{} : {};".format(signal[0], signal[2]) decl += "\nsignal index : std_logic_vector({}-1 downto 0) := (others => '0');".format( int(math.ceil(math.log2(self.n_sstages)))) decl += "\ntype mem_type is array({} downto 0) of std_logic_vector({} downto 0);".format( self.nss_per_package - 1, self.wvalue - 1) #Architecture behavior ## Generate component instanciations bhv = "" for i in range(0, self.n_sstages): signal_map = generateSignalMap( self.ssg.generateDeclarationSignals(), "ss{}_".format(i)) bhv += generateComponentInstantiation("ss{}".format(i), self.ssg.entity_name, signal_map, None) signal_map = generateSignalMap(self.muxg.generateDeclarationSignals(), "smux_") bhv += generateComponentInstantiation("smux", self.muxg.entity_name, signal_map, None) signal_map = generateSignalMap( self.demuxg.generateDeclarationSignals(), "sdemux_") bhv += generateComponentInstantiation("sdemux", self.demuxg.entity_name, signal_map, None) clk_map = {} clk_map["smux_clk"] = "clk" clk_map["sdemux_clk"] = "clk" seed_map = {} for i in range(0, self.n_sstages): clk_map["ss{}_clk".format(i)] = "clk" seed_map["ss{}_useed_in".format(i)] = "update_seeds({})".format( i % self.size) bhv += generateAssignments(clk_map) bhv += generateAssignments(seed_map) demux_inmap = { "sdemux_enable_in": "rd_en_in", "sdemux_index_in": "index" } bhv += generateAssignments(demux_inmap) mux_outmap = { "rd_data_out": "smux_data_out", "rd_valid_out": "smux_enable_out" } bhv += generateAssignments(mux_outmap) assignments = "" loop_assignments = "" for i in range(0, self.n_parallel): loop_assignments += "enable_pipe{}(i+1) := enable_pipe{}(i);\n".format( i, i) loop_assignments += "value_pipe{}(i+1) := value_pipe{}(i);\n".format( i, i) assignments += "enable_pipe{}(0) := val{}_en_in;\n".format(i, i) assignments += "value_pipe{}(0) := val{}_in;\n".format(i, i) for i in range(0, self.n_sstages): assignments += " ss{}_val_en_in <= enable_pipe{}({});\n".format( i, i // self.size, (i % self.size) // self.ss_factor) assignments += " ss{}_val_in <= value_pipe{}({});\n".format( i, i // self.size, (i % self.size) // self.ss_factor) for i in range(0, self.n_sstages): #Connect demux output to read inputs bhv += "smux_data_in({}) <= ss{}_rd_data_out ;\n".format(i, i) bhv += "smux_enable_in <= sdemux_enable_out;\n" process_declaration = "" for i in range(0, self.n_parallel): process_declaration += "variable enable_pipe{} : std_logic_vector({} downto 0) := (others => '0');\n".format( i, self.nss_per_package - 1) process_declaration += "variable value_pipe{} : mem_type;\n".format( i) bhv += """ process(clk) begin if rising_edge(clk) then if rd_en_in = '1' then if to_integer(unsigned(index)) >= {} then index <= (others => '0'); else index <= std_logic_vector(to_unsigned(to_integer(unsigned(index)) + 1, index'LENGTH)); end if; end if; end if; end process; process(clk) {} begin if rising_edge(clk) then {} for i in {} downto 0 loop {} end loop; end if; end process; """.format(self.n_sstages - 1, process_declaration, assignments, self.nss_per_package - 2, loop_assignments) return frame.format(self.entity_name, self.entity_name, decl, bhv, self.entity_name)
def generateArchitectureDefinition(self): frame = """ ARCHITECTURE a{} OF {} IS {} BEGIN {} END a{}; """ decl = "" #Declarations ## Memory component according to provided sizes decl += self.mcg.generateComponentDeclaration() ## Selector Stage decl += self.sg.generateComponentDeclaration() ## Update Stage decl += self.ug.generateComponentDeclaration() decl += self.dvg.generateComponentDeclaration() decl += self.dsg.generateComponentDeclaration() ## Optional: Modulo arithmetic if log2(sum(sizes)) != wselector if not self.hcg is None: decl += self.hcg.generateComponentDeclaration() ## DFU decl += self.dfug.generateComponentDeclaration() ## Connecting signals for signal in self.mcg.generateDeclarationSignals(): decl += "\nsignal mc_{} : {};".format(signal[0], signal[2]) for signal in self.sg.generateDeclarationSignals(): decl += "\nsignal s_{} : {};".format(signal[0], signal[2]) for signal in self.ug.generateDeclarationSignals(): decl += "\nsignal u_{} : {};".format(signal[0], signal[2]) for signal in self.dvg.getEntitySignals(): dec = "\nsignal vdv_{} : {};".format(signal[0], signal[2]) decl += dec.replace("WIDTH", str(self.wvalue)) for signal in self.dsg.getEntitySignals(): decl += "\nsignal rds_{} : {};".format(signal[0], signal[2]) for signal in self.dsg.getEntitySignals(): decl += "\nsignal eds_{} : {};".format(signal[0], signal[2]) if not self.hcg is None: for signal in self.hcg.getEntitySignals(): dec = "\nsignal hc_{} : {};".format(signal[0], signal[2]) dec = dec.replace("ADDR_WIDTH", str(self.waddr)) decl += dec for signal in self.dfug.getEntitySignals(): dec = "\nsignal dfu_{} : {};".format(signal[0], signal[2]) dec = dec.replace("ADDR_WIDTH", str(self.waddr)) dec = dec.replace("MEM_WIDTH", str(self.wstate)) decl += dec #Architecture behavior ## Generate component instanciations bhv = "" signal_map = generateSignalMap(self.mcg.generateDeclarationSignals(), "mc_") bhv += generateComponentInstantiation("mc", self.mcg.entity_name, signal_map, None) signal_map = generateSignalMap(self.sg.generateDeclarationSignals(), "s_") bhv += generateComponentInstantiation("s", self.sg.entity_name, signal_map, None) signal_map = generateSignalMap(self.ug.generateDeclarationSignals(), "u_") bhv += generateComponentInstantiation("u", self.ug.entity_name, signal_map, None) signal_map = generateSignalMap(self.dsg.getEntitySignals(), "rds_") generic_map = {"STAGES": self.computeMemoryLatency()} bhv += generateComponentInstantiation("rds", self.dsg.entity_name, signal_map, generic_map) if not self.hcg is None: signal_map = generateSignalMap(self.hcg.getEntitySignals(), "hc_") generic_map = { "ADDR_WIDTH": self.waddr, "MAX_VAL": self.total_size } bhv += generateComponentInstantiation("hc", self.hcg.entity_name, signal_map, generic_map) signal_map = generateSignalMap(self.dfug.getEntitySignals(), "dfu_") generic_map = { "MEM_WIDTH": self.wstate, "ADDR_WIDTH": self.waddr, "DFU_WIDTH": self.computeDFULatency() } bhv += generateComponentInstantiation("dfux", self.dfug.entity_name, signal_map, generic_map) vdv_latency = self.computeValuePipelineLatency() if vdv_latency > 0: signal_map = generateSignalMap(self.dvg.getEntitySignals(), "vdv_") generic_map = {"STAGES": vdv_latency, "WIDTH": self.wvalue} bhv += generateComponentInstantiation("vdv", self.dvg.entity_name, signal_map, generic_map) vdv_inputs = {"vdv_data_in": "val_in", "vdv_clk": "clk"} bhv += generateAssignments(vdv_inputs) assert vdv_latency >= 0, "The update function latency is currently not allowed to exceed the latency of all previous stages plus one." signal_map = generateSignalMap(self.dsg.getEntitySignals(), "eds_") generic_map = {"STAGES": self.computeEnablePipelineLatency()} bhv += generateComponentInstantiation("eds", self.dsg.entity_name, signal_map, generic_map) input_to_sel = { "s_clk": "clk", "s_v": "val_in", "s_seed": "sseed_in", "eds_data_in": "val_en_in", "eds_clk": "clk", "rds_data_in": "rd_en_in", "rds_clk": "clk" } bhv += generateAssignments(input_to_sel) if not self.hcg is None: sel_to_hcg = { "hc_clk": "clk", "hc_addr_in": "s_offset({} downto 0)".format(self.waddr - 1), } bhv += generateAssignments(sel_to_hcg) hcg_to_mc = { "mc_clk": "clk", "mc_rd_addr_in": "hc_addr_out when rd_en_in = '0' else rd_addr_in" } bhv += generateAssignments(hcg_to_mc) else: sel_to_mc = { "mc_clk": "clk", "mc_rd_addr_in": "s_offset({} downto 0) when rd_en_in = '0' else rd_addr_in". format(self.waddr - 1) } bhv += generateAssignments(sel_to_mc) mc_to_dfu = { "dfu_clk": "clk", "dfu_addr_in": "mc_rd_addr_out", "dfu_data_in": "mc_rd_data_out", } bhv += generateAssignments(mc_to_dfu) dfu_to_up = { "u_clk": "clk", "u_v": "vdv_data_out", "u_seed": "useed_in", "u_state": "dfu_data_out", "u_addr_in": "dfu_addr_out", "u_fwd_enable_in": "eds_data_out", "u_cmp_in": "dfu_cmp_out" } up_to_mcg_dfu = { "mc_wr_en_in": "eds_data_out", "mc_wr_addr_in": "u_addr_out", "mc_wr_data_in": "u_outstate", "dfu_enable_r_in": "eds_data_out", "dfu_addr_r_in": "u_addr_out", "dfu_data_r_in": "u_outstate" } bhv += generateAssignments(up_to_mcg_dfu) if vdv_latency == 0: up_to_mcg_dfu["u_v"] = "val_in" bhv += generateAssignments(dfu_to_up) mcg_to_out = { "rd_data_out": "mc_rd_data_out", "rd_valid_out": "rds_data_out" } bhv += generateAssignments(mcg_to_out) return frame.format(self.entity_name, self.entity_name, decl, bhv, self.entity_name)
def generateAsynchronousArchitectureDefinition(self): frame = """ ARCHITECTURE a{} OF {} IS {} BEGIN process(clk) begin if rising_edge(clk) then state <= u_outstate; end if; end process; {} END a{}; """ decl = "" #Declarations ## Functions decl += self.ug.generateComponentDeclaration() decl += self.cg.generateComponentDeclaration() ## Connecting signals for signal in self.ug.generateDeclarationSignals(): decl += "\nsignal u_{} : {};".format(signal[0], signal[2]) for signal in self.cg.generateDeclarationSignals(): for i in range(0, self.n_parallel): decl += "\nsignal c{}_{} : {};".format(i, signal[0], signal[2]) decl += "\nsignal state : std_logic_vector({} downto 0) := {};".format( self.wstate - 1, self.initial_state) #Architecture behavior ## Generate component instanciations bhv = "" signal_map = generateSignalMap(self.ug.generateDeclarationSignals(), "u_") bhv += generateComponentInstantiation("u", self.ug.entity_name, signal_map, None) for i in range(0, self.n_parallel): signal_map = generateSignalMap( self.cg.generateDeclarationSignals(), "c{}_".format(i)) bhv += generateComponentInstantiation("c{}".format(i), self.cg.entity_name, signal_map, None) for i in range(0, self.n_parallel): cin = { "c{}_clk".format(i): "clk", "c{}_v".format(i): "val{}_in".format(i), "c{}_seed".format(i): "useed_in", } bhv += generateAssignments(cin) uin = { "u_clk": "clk", "u_seed": "useed_in", "u_state": "state", } bhv += generateAssignments(uin) for i in range(0, self.n_parallel): uin = { "u_v{}".format(i): "c{}_offset when val{}_en_in = '1' else {}".format( i, i, self.neutral_compout), } bhv += generateAssignments(uin) uout = { "rd_data_out": "state", } bhv += generateAssignments(uout) return frame.format(self.entity_name, self.entity_name, decl, bhv, self.entity_name)
def generateArchitectureDefinition(self): frame = """ ARCHITECTURE a{} OF {} IS {} BEGIN {} END a{}; """ #Declare memory pipeline segments declarations = self.msg.generateComponentDeclaration() #Generate connection signals. One connecting signal for each in and out signal per clock. signals = [] for index, size in enumerate(self.sizes): for signal in self.msg.getEntitySignals(): dec = "\nsignal stage{}_{} : {}".format( index, signal[0], signal[2]) #There are logic vector sizes depending on the generic variables. We need to replace those. dec = dec.replace("ADDR_WIDTH_FULL", str(self.width)) dec = dec.replace("MEM_WIDTH", str(self.depth)) dec = dec.replace("VAL_WIDTH", str(self.val_width)) signals += [dec] declarations += self.mbg.generateComponentDeclaration() for signal in self.mbg.getEntitySignals(): dec = "\nsignal buf_{} : {}".format(signal[0], signal[2]) #There are logic vector sizes depending on the generic variables. We need to replace those. dec = dec.replace("ADDR_WIDTH_FULL", str(self.width)) dec = dec.replace("MEM_WIDTH", str(self.depth)) dec = dec.replace("VAL_WIDTH", str(self.val_width)) signals += [dec] declarations += "\n" + ";".join(signals) + ";" #BEGIN #Instantiate memory segment components bhv = "" lo = 0 for index, size in enumerate(self.sizes): args = {} for signal in self.msg.getEntitySignals(): args[signal[0]] = "stage{}_{}".format(index, signal[0]) generic_values = { "ADDR_WIDTH_FULL": self.width, "VAL_WIDTH": self.val_width, "MEM_WIDTH": self.depth } generic_values["ADDR_WIDTH"] = int(log2(size)) generic_values["LO"] = lo generic_values["HI"] = lo + size - 1 bhv += generateComponentInstantiation("stage{}".format(index), self.msg.entity_name, args, generic_values) lo += size args = {} for signal in self.mbg.getEntitySignals(): args[signal[0]] = "buf_{}".format(signal[0]) generic_values = { "ADDR_WIDTH_FULL": self.width, "VAL_WIDTH": self.val_width, "MEM_WIDTH": self.depth } bhv += generateComponentInstantiation("buf", self.mbg.entity_name, args, generic_values) #Connect Signals #First connect input signals to first stage. signals = [] signals += ["buf_clk <= clk"] signals += ["buf_rd_data_in <= (others => '0')"] signals += ["buf_rd_addr_in <= rd_addr_in"] signals += ["buf_wr_en_in <= wr_en_in"] signals += ["buf_wr_addr_in <= wr_addr_in"] signals += ["buf_wr_data_in <= wr_data_in"] signals += ["stage0_clk <= clk"] signals += ["stage0_rd_data_in <= buf_rd_data_out"] signals += ["stage0_rd_addr_in <= buf_rd_addr_out"] signals += ["stage0_wr_en_in <= buf_wr_en_out"] signals += ["stage0_wr_addr_in <= buf_wr_addr_out"] signals += ["stage0_wr_data_in <= buf_wr_data_out"] #Connect pipeline stages for index in range(1, len(self.sizes)): signals += ["stage{}_clk <= clk".format(index)] signals += [ "stage{}_rd_addr_in <= stage{}_rd_addr_out".format( index, index - 1) ] signals += [ "stage{}_rd_data_in <= stage{}_rd_data_out ".format( index, index - 1) ] signals += [ "stage{}_wr_en_in <= stage{}_wr_en_out".format( index, index - 1) ] signals += [ "stage{}_wr_addr_in <= stage{}_wr_addr_out".format( index, index - 1) ] signals += [ "stage{}_wr_data_in <= stage{}_wr_data_out".format( index, index - 1) ] #Finally, connect the output signals to the last stage last_stage_index = len(self.sizes) - 1 signals += [ "rd_addr_out <= stage{}_rd_addr_out".format(last_stage_index) ] signals += [ "rd_data_out <= stage{}_rd_data_out".format(last_stage_index) ] bhv += "\n" + ";\n".join(signals) + ";" return frame.format(self.entity_name, self.entity_name, declarations, bhv, self.entity_name)