def get_instantiation(self, instance_name, intern_out=True): s = instance_name + ' ' s += ': entity work.' + self.name + '_' + self.bus.short_name + '_pif\n' s += indent_string('generic map (\n') par = 'g_{0}_baseaddr => g_{0}_baseaddr)\n'.format( self.bus.short_name) s += indent_string(par, 2) s += indent_string('port map (\n') if intern_out: inter = '_i' else: inter = '' par = '' if self.n_rw_regs > 0: par += self.bus.short_name + '_rw_regs => ' + self.bus.short_name + '_rw_regs,\n' if self.n_ro_regs > 0: par += self.bus.short_name + '_ro_regs => ' + self.bus.short_name + '_ro_regs,\n' if self.n_pulse_regs > 0: par += self.bus.short_name + '_pulse_regs => ' + self.bus.short_name + '_pulse_regs,\n' par += self.bus.clk_name + ' => ' + self.bus.short_name + '_' + self.bus.clk_name + ',\n' par += self.bus.reset_name + ' => ' + self.bus.short_name + '_' + str.strip( self.bus.reset_name) + ',\n' par += self.bus.get_instantiation(self.name, inter) par += ');\n' s += indent_string(par, 2) return s
def return_ipbus_addr_table(self): s = '<?xml version="1.0" encoding="ISO-8859-1"?>\n' s += '<node id="{}">\n'.format(self.module.name) for reg in self.module.registers: par = '<node id="{}" address="0x{:08X}" permission="{}" description="{}" parameters="reset={}'.format( reg.name, reg.address, reg.get_mode(), reg.description, reg.reset) if reg.mode == 'pulse': par += ';pulse_cycles={}'.format(reg.pulse_cycles) if reg.stall: par += ';stall_cycles={}'.format(reg.stall_cycles) if reg.sig_type == 'fields': par += '">\n' else: par += '"/>\n' if reg.sig_type == 'fields': for field in reg.fields: par2 = '<node id="{}" mask="{}" description="{}" parameters="reset={}"/>\n'.format( field.name, hex(field.get_mask()), field.description, field.reset) par += indent_string(par2, 2) par += '</node>\n' s += indent_string(par, 2) s += '</node>' return s
def sync_process(clk_name, reset_name, process_name, reset_string, logic_string, active_low=True, variables=None): s = process_name + " : process(" + clk_name + ")\n" if variables is not None: for var in variables: s += indent_string("variable " + var + ";\n") s += "begin\n" s += indent_string("if rising_edge(" + clk_name + ") then\n") s += indent_string("if " + reset_name + " = ", 2) if active_low: s += "'0'" else: s += "'1'" s += " then\n" s += indent_string(reset_string, 3) s += "\n" s += indent_string("else\n", 2) s += indent_string(logic_string, 3) s += indent_string("end if;\n", 2) s += indent_string("end if;\n") s += "end process " + process_name + ";\n" return s
def record_fields_definition_vhdl(self, reg): s = indent_string("type t_" + self.name + "_" + reg.mode + "_") s += reg.name + " is record\n" for field in reg.fields: s += indent_string(field.name, 2) + " : " if field.sig_type == "slv": s += "std_logic_vector(" + str(field.length - 1) s += " downto 0);\n" elif field.sig_type == "sl": s += "std_logic;\n" else: raise RuntimeError("Something went wrong..." + field.sig_type) s += indent_string("end record;\n\n") return s
def get_field_declarations(self, gen): s = "" for i, reg in enumerate(gen): par = '' par += reg.name + ' => ' # default values must be declared if reg.sig_type == 'default' or reg.sig_type == 'slv': if reg.reset == "0x0": par += "(others => '0')" else: par += str(reg.length) + 'X"' par += format(int(reg.reset, 16), 'X') + '"' elif reg.sig_type == 'fields': par += self.get_field_reset_value(reg) elif reg.sig_type == 'sl': par += "'" + format(int(reg.reset, 16), 'X') + "'" else: raise RuntimeError("Something went wrong... What now?" + reg.sig_type) if i < len(gen) - 1: par += ',' else: par += ');' par += '\n' s += indent_string(par, 2) return s
def get_field_reset_value(reg): par = "" if len(reg.fields) > 1: par += '(\n' else: par += '(' for j, field in enumerate(reg.fields): if len(reg.fields) > 1: par += indent_string(field.name + ' => ') else: par += field.name + ' => ' if field.sig_type == 'slv': if field.reset == "0x0": par += "(others => '0')" else: par += str(field.length) + 'X"' par += format(int(field.reset, 16), 'X') + '"' elif field.sig_type == 'sl': par += "'" + format(int(field.reset, 16), 'X') + "'" if j < len(reg.fields) - 1: par += ',\n' par += ')' return par
def check_bit_pulse_slv(self, c_addr, signal, reg, msg, offset=0, clk_cycles=None): if clk_cycles is None: clk_cycles = reg.pulse_cycles reset = reg.reset s = 'for i in 0 to {} loop\n'.format(reg.length - 1) if offset > 0: offset = '+{}'.format(offset) else: offset = '' sig_val = 'std_logic_vector(to_unsigned(1, {}) sll i)'.format( reg.length) bus_val = 'std_logic_vector(to_unsigned(1, data_width) sll i{})'.format( offset) par = self.bus.uvvm_write(c_addr, bus_val, msg) par += self.check_value(signal, sig_val, msg) par += self.await_stable(signal, clk_cycles, msg) par += self.check_value(signal, sig_val, msg) sig_val = self.sig_value(reset, reg.sig_type, reg.length) par += self.await_value(signal, sig_val, msg) s += indent_string(par) s += 'end loop;\n' return s
def comb_process(process_name, logic_string): s = process_name + " : process(all)\n" s += "begin\n\n" s += indent_string(logic_string) s += "end process " + process_name + ";\n" return s
def __str__(self): string = "Name: " + self.name + "\n" string += "Address width: " + str(self.addr_width) + "\n" string += "Data width: " + str(self.data_width) + "\n" string += "Description: " + self.description + "\n\n" string += "Registers: \n" for i, reg in enumerate(self.registers): string += indent_string(str(reg), 1) return string
def get_pulse_regs_vhdl(self): s = indent_string("-- PULSE Register Record Definitions\n\n") # Create all types for PULSE registers with records for reg in self.registers: if reg.mode == "pulse" and reg.sig_type == "fields": s += self.record_fields_definition_vhdl(reg) # The PULSE register record type s += indent_string("type t_" + self.name + "_pulse_regs is record\n") for reg in self.registers: if reg.mode == "pulse": s += indent_string(reg.name, 2) + " : " if reg.sig_type == "default" or (reg.sig_type == "slv" and reg.length == self.data_width): s += "t_" + self.name + "_data;\n" elif reg.sig_type == "slv": s += "std_logic_vector(" + \ str(reg.length - 1) + " downto 0);\n" elif reg.sig_type == "sl": s += "std_logic;\n" elif reg.sig_type == "fields": s += "t_" + self.name + "_pulse_" + reg.name + ";\n" else: raise RuntimeError("Something went wrong...") s += indent_string("end record;\n") s += "\n" s += indent_string("-- PULSE Register Reset Value Constant\n\n") s += indent_string("constant c_") + self.name + "_pulse_regs : t_" s += self.name + "_pulse_regs := (\n" gen = [reg for reg in self.registers if reg.mode == 'pulse'] s += self.get_field_declarations(gen) s += '\n' return s
def get_ro_regs_vhdl(self): s = indent_string("-- RO Register Record Definitions\n\n") # Create all types for RO registers with records for reg in self.registers: if reg.mode == "ro" and reg.sig_type == "fields": s += indent_string("type t_" + self.name + "_ro_") s += reg.name + " is record\n" for field in reg.fields: s += indent_string(field.name, 2) + " : " if field.sig_type == "slv": s += "std_logic_vector(" + str(field.length - 1) s += " downto 0);\n" elif field.sig_type == "sl": s += "std_logic;\n" else: raise RuntimeError("Something went wrong...") s += indent_string("end record;\n\n") # The RO register record type s += indent_string("type t_" + self.name + "_ro_regs is record\n") for reg in self.registers: if reg.mode == "ro": s += indent_string(reg.name, 2) + " : " if reg.sig_type == "default" or (reg.sig_type == "slv" and reg.length == self.data_width): s += "t_" + self.name + "_data;\n" elif reg.sig_type == "slv": s += "std_logic_vector(" + \ str(reg.length - 1) + " downto 0);\n" elif reg.sig_type == "sl": s += "std_logic;\n" elif reg.sig_type == "fields": s += "t_" + self.name + "_ro_" + reg.name + ";\n" else: raise RuntimeError("Something went wrong... What now?" + reg.sig_type) s += indent_string("end record;\n") s += "\n" s += indent_string("-- RO Register Reset Value Constant\n\n") s += indent_string("constant c_") + self.name + "_ro_regs : t_" s += self.name + "_ro_regs := (\n" gen = [reg for reg in self.registers if reg.mode == 'ro'] s += self.get_field_declarations(gen) return s
def comb_process_with_reset(reset_name, process_name, reset_string, logic_string, active_low=True): s = process_name + " : process(all)\n" s += "begin\n" s += indent_string("if " + reset_name + " = ") if active_low: s += "'0'" else: s += "'1'" s += " then\n" s += indent_string(reset_string, 2) s += "\n" s += indent_string("else\n") s += indent_string(logic_string, 2) s += "\n" s += indent_string("end if;\n") s += "end process " + process_name + ";\n" return s
def __str__(self): string = "Name: " + self.name + "\n" string += "Address: " + hex(self.address) + "\n" string += "Mode: " + self.mode + "\n" string += "Type: " + self.sig_type + "\n" string += "Length: " + str(self.length) + "\n" string += "Reset: " + self.reset if self.sig_type == 'record': for i in self.fields: string += "\n" string += indent_string("Name: " + i['name'] + " Type: " + i['type'] + " Length: " + str(i['length']) + " Reset: " + i['reset']) string += "\nDescription: " + self.description + "\n\n" return string
def pulse_reg_process(self, mod, reg): clk_name = self.clk_name reset_name = str.strip(self.reset_name) proc_name = "p_pulse_" + reg.name const_name = "c_" + mod.name + "_pulse_regs." + reg.name reg_name = self.short_name + "_pulse_regs_i." + reg.name reg_tmp_name = self.short_name + "_pulse_regs_cycle." + reg.name if reg.pulse_cycles > 1: variables = [ "cnt : natural range 0 to " + str(reg.pulse_cycles - 1) + " := 0" ] else: variables = [] reset_string = reg_name + " <= " + const_name + ";" logic_string = "if " + reg_tmp_name logic_string += " /= " + const_name logic_string += " then\n" par = "" if reg.pulse_cycles > 1: par = "cnt := " + str(reg.pulse_cycles - 1) + ";\n" par += reg_name + " <= " + reg_tmp_name + ";\n" logic_string += indent_string(par) logic_string += "else\n" if reg.pulse_cycles > 1: logic_string += indent_string("if cnt > 0 then\n") logic_string += indent_string("cnt := cnt - 1;\n", 2) logic_string += indent_string("else\n") par = reg_name + " <= " + const_name + ";\n" if reg.pulse_cycles > 1: logic_string += indent_string(par, 2) else: logic_string += indent_string(par, 1) if reg.pulse_cycles > 1: logic_string += indent_string("end if;\n") logic_string += "end if;\n" return sync_process(clk_name, reset_name, proc_name, reset_string, logic_string, self.reset_active_low, variables)
def get_subtypes_and_addrs_vhdl(self): par = '' par += "constant C_" + self.name.upper() par += "_ADDR_WIDTH : natural := " + str(self.addr_width) + ";\n" par += "constant C_" + self.name.upper() par += "_DATA_WIDTH : natural := " + str(self.data_width) + ";\n" par += "\n" par += "subtype t_" + self.name + "_addr is " par += "std_logic_vector(C_" + self.name.upper() + "_ADDR_WIDTH-1 " par += "downto 0);\n" par += "subtype t_" + self.name + "_data is " par += "std_logic_vector(C_" + self.name.upper() + "_DATA_WIDTH-1 " par += "downto 0);\n" par += "\n" for reg in self.registers: par += "constant C_ADDR_" + reg.name.upper() par += " : t_" + self.name + "_addr := " + str(self.addr_width) par += 'X"' + '%X' % reg.address + '";\n' par += '\n' return indent_string(par)
def return_python_header(self): s = '' s += "class " + self.module.name.upper() + "_H:\n\n" for reg in self.module.registers: s += indent_string('""" Register: ' + reg.name + ' """\n', 2) s += indent_string( reg.name.upper() + "_OFFSET = " + str(hex(reg.address)) + "\n", 2) s += indent_string( reg.name.upper() + "_RESET = " + reg.reset + "\n", 2) s += "\n" if reg.sig_type == "fields": for field in reg.fields: s += indent_string('""" Field: ' + field.name + ' """\n', 2) s += indent_string( reg.name.upper() + "_" + field.name.upper() + "_OFFSET = ", 2) s += str(field.pos_low) + "\n" s += indent_string( reg.name.upper() + "_" + field.name.upper() + "_WIDTH = ", 2) s += str(field.length) + "\n" s += indent_string( reg.name.upper() + "_" + field.name.upper() + "_RESET = ", 2) s += field.reset + "\n" s += indent_string( reg.name.upper() + "_" + field.name.upper() + "_MASK = ", 2) s += str( hex(pow(2, field.length) - 1 << field.pos_low)) + "\n" s += "\n" return s
def check_bit_rw_slv(self, c_addr, signal, reg, msg, offset=0): s = 'for i in 0 to {} loop\n'.format(reg.length - 1) if offset > 0: offset = '+{}'.format(offset) else: offset = '' sig_val = 'std_logic_vector(to_unsigned(1, {}) sll i)'.format( reg.length) bus_val = 'std_logic_vector(to_unsigned(1, data_width) sll i{})'.format( offset) par = self.bus.uvvm_write(c_addr, bus_val, msg) par += self.check_value(signal, sig_val, msg) par += self.bus.uvvm_check(c_addr, bus_val, msg) par += '-- Return to zero\n' sig_val = self.sig_value('0', 'slv', reg.length) bus_val = self.sig_value('0', 'default') par += self.bus.uvvm_write(c_addr, bus_val, msg) par += self.check_value(signal, sig_val, msg) par += self.bus.uvvm_check(c_addr, bus_val, msg) s += indent_string(par) s += 'end loop;\n' return s
def return_module_VHDL(self): s = lib_declaration() s += '-- User Libraries Start\n\n' s += '-- User Libraries End\n' s += '\n' if self.bus.comp_library != "work": s += "library " + self.bus.comp_library + ";\n" if self.bus.bus_type == 'ipbus': s += 'use ' + self.bus.comp_library + '.' + self.bus.bus_type + '.all;\n' else: s += 'use ' + self.bus.comp_library + '.' + self.bus.bus_type + '_pkg.all;\n' s += 'use work.' + self.name + '_pif_pkg.all;\n' s += '\n' s += 'entity ' + self.name + ' is\n' s += '\n' s += indent_string('generic (\n') par = '-- User Generics Start\n\n' par += '-- User Generics End\n' par += '-- ' + self.bus.bus_type.upper() + ' Bus Interface Generics\n' par += 'g_' + self.bus.short_name + '_baseaddr : std_logic_vector(' + str( self.bus.addr_width - 1) par += " downto 0) := (others => '0'));\n" s += indent_string(par, 2) s += indent_string('port (\n') par = '-- User Ports Start\n\n' par += '-- User Ports End\n' par += '-- {} Bus Interface Ports\n'.format(self.bus.bus_type.upper()) par += '{}_{} : in std_logic;\n'.format(self.bus.short_name, self.bus.clk_name) par += '{}_{} : in std_logic;\n'.format(self.bus.short_name, self.bus.reset_name) par += '{}_in : in {};\n'.format(self.bus.short_name, self.bus.in_type) par += '{}_out : out {}\n'.format(self.bus.short_name, self.bus.out_type) par += ');\n' s += indent_string(par, 2) s += '\n' s += 'end entity ' + self.name + ';\n' s += '\n' s += 'architecture behavior of ' + self.name + ' is\n' s += '\n' par = '-- User Architecture Start\n\n' par += '-- User Architecture End\n\n' s += indent_string(par) s += indent_string("-- " + self.bus.bus_type.upper() + " output signal for user readback\n") par = "signal {}_out_i : {};\n".format(self.bus.short_name, self.bus.out_type) s += indent_string(par) s += indent_string("-- Register Signals\n") if self.n_rw_regs > 0: s += indent_string('signal ' + self.bus.short_name + '_rw_regs : t_') s += self.name + '_rw_regs := c_' + self.name + '_rw_regs;\n' if self.n_ro_regs > 0: s += indent_string('signal ' + self.bus.short_name + '_ro_regs : t_') s += self.name + '_ro_regs := c_' + self.name + '_ro_regs;\n' if self.n_pulse_regs > 0: s += indent_string('signal ' + self.bus.short_name + '_pulse_regs : t_') s += self.name + '_pulse_regs := c_' + self.name + '_pulse_regs;\n' if self.n_rw_regs + self.n_ro_regs + self.n_pulse_regs > 0: s += '\n' s += 'begin\n' s += '\n' par = '-- User Logic Start\n\n' par += '-- User Logic End\n\n' s += indent_string(par) s += indent_string(self.bus.short_name + "_out <= " + self.bus.short_name + "_out_i;\n\n") s += indent_string( self.get_instantiation("i_{}_{}_pif".format( self.name, self.bus.short_name))) s += '\n' s += 'end architecture behavior;' return s
def return_ipbus_pif_VHDL(self, mod, clk_name, reset_name): s = '' par = ('signal ipb_out_i : ipb_rbus;\n' 'signal reg_rden : std_logic := \'0\';\n' 'signal reg_wren : std_logic := \'0\';\n' 'signal wr_ack, rd_ack : std_logic := \'0\';\n' 'signal wr_err, rd_err : std_logic := \'0\';\n' 'signal ack_d : std_logic := \'0\';\n') if mod.has_stall_regs(): par += ('signal wr_stall_ack : std_logic := \'0\';\n' 'signal rd_stall_ack : std_logic := \'0\';\n' 'signal stall : std_logic := \'0\';\n') par += 'signal reg_data_out : t_{}_data;\n\n'.format(mod.name) s += indent_string(par) s += 'begin\n\n' s += indent_string('ipb_out <= ipb_out_i;\n') if mod.count_rw_regs() > 0: s += indent_string('ipb_rw_regs <= ipb_rw_regs_i') + ';\n' if mod.count_pulse_regs() > 0: s += indent_string('ipb_pulse_regs <= ipb_pulse_regs_i') + ';\n' if mod.count_rw_regs() + mod.count_pulse_regs() > 0: s += '\n' if mod.has_stall_regs(): s += indent_string( 'reg_wren <= (ipb_in.ipb_strobe and ipb_in.ipb_write) and not (wr_ack or wr_err or ipb_out_i.ipb_ack or ipb_out_i.ipb_err or wr_stall_ack or stall);\n\n' ) else: s += indent_string( 'reg_wren <= (ipb_in.ipb_strobe and ipb_in.ipb_write) and not (wr_ack or wr_err or ipb_out_i.ipb_ack or ipb_out_i.ipb_err);\n\n' ) if mod.count_rw_regs() + mod.count_pulse_regs() > 0: ################################################################### # p_write ################################################################### reset_string = "\n" if mod.count_rw_regs() > 0: reset_string += 'ipb_rw_regs_i <= c_' + mod.name + '_rw_regs;\n' if mod.count_pulse_regs() > 0: reset_string += 'ipb_pulse_regs_cycle <= c_' + mod.name + '_pulse_regs;\n' reset_string += ("wr_ack <= '0';\n" "wr_err <= '0';\n") logic_string = "" # create a generator for looping through all pulse regs if mod.count_pulse_regs() > 0: logic_string += "\n-- Return PULSE registers to reset value every clock cycle\n" logic_string += 'ipb_pulse_regs_cycle <= c_' + mod.name + '_pulse_regs;\n\n' logic_string += ("wr_ack <= '0';\n" "wr_err <= '0';\n") if mod.has_stall_regs(): logic_string += "wr_stall_ack <= '0';\n" logic_string += "\nif (reg_wren) then\n\n" # create a generator for looping through all rw and pulse regs gen = (reg for reg in mod.registers if reg.mode == "rw" or reg.mode == "pulse") for i, reg in enumerate(gen): if reg.mode == 'rw': sig_name = 'ipb_rw_regs_i.' elif reg.mode == 'pulse': sig_name = 'ipb_pulse_regs_cycle.' if i == 0: par = "if" else: par = "elsif" par += " unsigned(ipb_in.ipb_addr) = resize(unsigned(C_BASEADDR) + unsigned(C_ADDR_" par += reg.name.upper() + "), " + str( self.addr_width) + ") then\n\n" logic_string += indent_string(par) par = '' if reg.sig_type == 'fields': for field in reg.fields: par += sig_name + reg.name + '.' + field.name par += ' <= ipb_in.ipb_wdata(' par += field.get_pos_vhdl() par += ');\n' elif reg.sig_type == 'default': par += sig_name + reg.name + ' <= ipb_in.ipb_wdata;\n' elif reg.sig_type == 'slv': par += sig_name + reg.name + ' <= ipb_in.ipb_wdata(' par += str(reg.length - 1) + ' downto 0);\n' elif reg.sig_type == 'sl': par += sig_name + reg.name + ' <= ipb_in.ipb_wdata(0);\n' if reg.stall: par += "wr_stall_ack <= '1';\n" else: par += "wr_ack <= '1';\n" logic_string += indent_string(par, 2) logic_string += "\n" logic_string += indent_string("else\n\n") logic_string += indent_string("wr_err <= '1';\n\n", 2) logic_string += indent_string('end if;\n') logic_string += 'end if;\n' if self.bus_reset == "async": s += indent_string( async_process(clk_name, reset_name, "p_write", reset_string, logic_string, self.reset_active_low)) elif self.bus_reset == "sync": s += indent_string( sync_process(clk_name, reset_name, "p_write", reset_string, logic_string, self.reset_active_low)) s += "\n" # Pulse reg process # create a generator for looping through all rw and pulse regs gen = (reg for reg in mod.registers if reg.mode == "pulse") for reg in gen: s += indent_string(self.pulse_reg_process(mod, reg)) s += '\n' if mod.has_stall_regs(): s += indent_string( '\nreg_rden <= (ipb_in.ipb_strobe and (not ipb_in.ipb_write)) and not (rd_ack or rd_err or ipb_out_i.ipb_ack or ipb_out_i.ipb_err or rd_stall_ack or stall);\n\n' ) else: s += indent_string( '\nreg_rden <= (ipb_in.ipb_strobe and (not ipb_in.ipb_write)) and not (rd_ack or rd_err or ipb_out_i.ipb_ack or ipb_out_i.ipb_err);\n\n' ) #################################################################### # p_read #################################################################### reset_string = ("reg_data_out <= (others => '0');\n" "rd_ack <= '0';\n" "rd_err <= '0';") logic_string = ("\n-- default values\n" "rd_ack <= '0';\n" "rd_err <= '0';\n") if mod.has_stall_regs(): logic_string += "rd_stall_ack <= '0';\n" logic_string += "\nif (reg_rden) then\n" logic_string += indent_string("reg_data_out <= (others => '0');\n\n") gen = [ reg for reg in mod.registers if reg.mode == "ro" or reg.mode == "rw" ] for i, reg in enumerate(gen): if i == 0: par = "if" else: par = "elsif" par += " unsigned(ipb_in.ipb_addr) = resize(unsigned(C_BASEADDR) + unsigned(C_ADDR_" par += reg.name.upper() + "), " + str( self.addr_width) + ") then\n\n" logic_string += indent_string(par) par = '' if reg.sig_type == 'fields': for field in reg.fields: par += 'reg_data_out(' par += field.get_pos_vhdl() if reg.mode == 'rw': par += ') <= ipb_rw_regs_i.' elif reg.mode == 'ro': par += ') <= ipb_ro_regs.' else: raise Exception("Unknown error occurred") par += reg.name + '.' + field.name + ';\n' elif reg.sig_type == 'default': par += 'reg_data_out <= ' if reg.mode == 'rw': par += 'ipb_rw_regs_i.' elif reg.mode == 'ro': par += 'ipb_ro_regs.' else: raise Exception("Unknown error occurred") par += reg.name + ';\n' elif reg.sig_type == 'slv': par += 'reg_data_out(' par += str(reg.length - 1) + ' downto 0) <= ' if reg.mode == 'rw': par += 'ipb_rw_regs_i.' elif reg.mode == 'ro': par += 'ipb_ro_regs.' else: raise Exception("Unknown error occurred") par += reg.name + ';\n' elif reg.sig_type == 'sl': par += 'reg_data_out(0) <= ' if reg.mode == 'rw': par += 'ipb_rw_regs_i.' elif reg.mode == 'ro': par += 'ipb_ro_regs.' else: raise Exception("Unknown error occurred") par += reg.name + ';\n' if reg.stall: par += "rd_stall_ack <= '1';\n" else: par += "rd_ack <= '1';\n" logic_string += indent_string(par, 2) logic_string += "\n" logic_string += indent_string("else\n\n") logic_string += indent_string('reg_data_out <= 32X"DEADBEEF";\n', 2) logic_string += indent_string("rd_err <= '1';\n\n", 2) logic_string += indent_string('end if;\n') logic_string += 'end if;\n' if self.bus_reset == "async": s += indent_string( async_process(clk_name, reset_name, "p_read", reset_string, logic_string, self.reset_active_low)) elif self.bus_reset == "sync": s += indent_string( sync_process(clk_name, reset_name, "p_read", reset_string, logic_string, self.reset_active_low)) s += "\n" #################################################################### # p_stall #################################################################### if mod.has_stall_regs(): variables = ['v_cnt : natural := 0'] reset_string = "stall <= '0';" logic_string = ("ack_d <= '0';\n" "if wr_stall_ack or rd_stall_ack then\n") logic_string += indent_string("stall <= '1';\n") gen = [reg for reg in mod.registers if reg.stall] for reg in gen: logic_string += indent_string( "if unsigned(ipb_in.ipb_addr) = resize(unsigned(C_BASEADDR) + unsigned(C_ADDR_{}), {}) then\n" .format(reg.name.upper(), str(self.addr_width))) logic_string += indent_string( "v_cnt := {};\n".format(reg.get_stall_cycles_str()), 2) logic_string += indent_string("end if;\n") logic_string += "elsif v_cnt > 0 then\n" logic_string += indent_string("v_cnt := v_cnt - 1;\n") logic_string += indent_string("stall <= '1';\n") logic_string += "elsif stall then\n" logic_string += indent_string("stall <= '0';\n") logic_string += indent_string("ack_d <= '1';\n") logic_string += "end if;\n" if self.bus_reset == "async": s += indent_string( async_process(clk_name, reset_name, "p_stall", reset_string, logic_string, self.reset_active_low, variables)) elif self.bus_reset == "sync": s += indent_string( sync_process(clk_name, reset_name, "p_stall", reset_string, logic_string, self.reset_active_low, variables)) s += '\n' #################################################################### # p_output #################################################################### reset_string = ("ipb_out_i.ipb_rdata <= (others => '0');\n" "ipb_out_i.ipb_ack <= '0';\n" "ipb_out_i.ipb_err <= '0';") logic_string = ("ipb_out_i.ipb_rdata <= reg_data_out;\n" "ipb_out_i.ipb_ack <= '0';\n" "ipb_out_i.ipb_err <= '0';\n\n") if mod.has_stall_regs(): logic_string += "if (rd_ack or rd_err) and (not stall) then\n" else: logic_string += "if (rd_ack or rd_err) then\n" logic_string += indent_string("ipb_out_i.ipb_ack <= rd_ack;\n") logic_string += indent_string("ipb_out_i.ipb_err <= rd_err;\n") if mod.has_stall_regs(): logic_string += "elsif (wr_ack or wr_err) and (not stall) then\n" else: logic_string += "elsif (wr_ack or wr_err) then\n" logic_string += indent_string("ipb_out_i.ipb_ack <= wr_ack;\n") logic_string += indent_string("ipb_out_i.ipb_err <= wr_err;\n") if mod.has_stall_regs(): logic_string += "elsif ack_d then\n" logic_string += indent_string("ipb_out_i.ipb_ack <= ack_d;\n") logic_string += "end if;\n" s += indent_string( comb_process_with_reset(reset_name, "p_output", reset_string, logic_string, self.reset_active_low)) s += "\n" s += 'end behavior;' return s
def return_bus_pkg_VHDL(self): if self.bus_type == 'axi': s = 'library ieee;\n' s += 'use ieee.std_logic_1164.all;\n' s += '\n' s += 'package ' + self.bus_type + '_pkg is\n' s += '\n\n' data_width_constant = 'C_' + self.bus_type.upper() + '_DATA_WIDTH' addr_width_constant = 'C_' + self.bus_type.upper() + '_ADDR_WIDTH' data_sub_type = 't_' + self.bus_type + '_data' addr_sub_type = 't_' + self.bus_type + '_addr' par = '' par += 'constant ' + data_width_constant par += ' : natural := ' + str(self.data_width) + ';\n' par += 'constant ' + addr_width_constant par += ' : natural := ' + str(self.addr_width) + ';\n' par += '\n' par += 'subtype ' + data_sub_type + ' is std_logic_vector(' par += data_width_constant + '-1 downto 0);\n' par += 'subtype ' + addr_sub_type + ' is std_logic_vector(' par += addr_width_constant + '-1 downto 0);\n' par += '\n' s += indent_string(par) s += indent_string('type t_' + self.bus_type) s += '_mosi is record\n' par = '' par += 'araddr : ' + addr_sub_type + ';\n' par += 'arvalid : std_logic;\n' par += 'awaddr : ' + addr_sub_type + ';\n' par += 'awvalid : std_logic;\n' par += 'bready : std_logic;\n' par += 'rready : std_logic;\n' par += 'wdata : ' + data_sub_type + ';\n' par += 'wvalid : std_logic;\n' s += indent_string(par, 2) s += indent_string('end record;\n') s += '\n' s += indent_string('type t_' + self.bus_type) s += '_miso is record\n' par = '' par += 'arready : std_logic;\n' par += 'awready : std_logic;\n' par += 'bresp : std_logic_vector(1 downto 0);\n' par += 'bvalid : std_logic;\n' par += 'rdata : ' + data_sub_type + ';\n' par += 'rresp : std_logic_vector(1 downto 0);\n' par += 'rvalid : std_logic;\n' par += 'wready : std_logic;\n' s += indent_string(par, 2) s += indent_string('end record;\n') s += '\n' s += 'end ' + self.bus_type + '_pkg;' return s
def return_axi_pif_VHDL(self, mod, clk_name, reset_name): s = '' par = '-- internal bus signals for readback\n' par += 'signal awaddr_i : t_' + mod.name + '_addr;\n' par += 'signal awready_i : std_logic;\n' par += 'signal wready_i : std_logic;\n' par += 'signal bresp_i : std_logic_vector(1 downto 0);\n' par += 'signal bvalid_i : std_logic;\n' par += 'signal araddr_i : t_' + mod.name + '_addr;\n' par += 'signal arready_i : std_logic;\n' par += 'signal rdata_i : t_' + mod.name + '_data;\n' par += 'signal rresp_i : std_logic_vector(1 downto 0);\n' par += 'signal rvalid_i : std_logic;\n\n' par += 'signal slv_reg_rden : std_logic;\n' par += 'signal slv_reg_wren : std_logic;\n' par += 'signal reg_data_out : t_' + mod.name + '_data;\n' par += '-- signal byte_index : integer' + '; -- unused\n\n' s += indent_string(par) s += 'begin\n\n' if mod.count_rw_regs() > 0: s += indent_string('axi_rw_regs <= axi_rw_regs_i') + ';\n' if mod.count_pulse_regs() > 0: s += indent_string('axi_pulse_regs <= axi_pulse_regs_i') + ';\n' if mod.count_rw_regs() + mod.count_pulse_regs() > 0: s += '\n' par = '' par += 'awready <= awready_i;\n' par += 'wready <= wready_i;\n' par += 'bresp <= bresp_i;\n' par += 'bvalid <= bvalid_i;\n' par += 'arready <= arready_i;\n' par += 'rdata <= rdata_i;\n' par += 'rresp <= rresp_i;\n' par += 'rvalid <= rvalid_i;\n' par += '\n' s += indent_string(par) #################################################################### # p_awready #################################################################### reset_string = "awready_i <= '0';" logic_string = "if (awready_i = '0' and awvalid = '1' and wvalid = '1') then\n" logic_string += indent_string("awready_i <= '1';\n") logic_string += "else\n" logic_string += indent_string("awready_i <= '0';\n") logic_string += "end if;" if self.bus_reset == "async": s += indent_string( async_process(clk_name, reset_name, "p_awready", reset_string, logic_string, self.reset_active_low)) elif self.bus_reset == "sync": s += indent_string( sync_process(clk_name, reset_name, "p_awready", reset_string, logic_string, self.reset_active_low)) s += "\n" #################################################################### # p_awaddr #################################################################### reset_string = "awaddr_i <= (others => '0');" logic_string = "if (awready_i = '0' and awvalid = '1' and wvalid = '1') then\n" logic_string += indent_string("awaddr_i <= awaddr;\n") logic_string += "end if;" if self.bus_reset == "async": s += indent_string( async_process(clk_name, reset_name, "p_awaddr", reset_string, logic_string, self.reset_active_low)) elif self.bus_reset == "sync": s += indent_string( sync_process(clk_name, reset_name, "p_awaddr", reset_string, logic_string, self.reset_active_low)) s += "\n" #################################################################### # p_wready #################################################################### reset_string = "wready_i <= '0';" logic_string = "if (wready_i = '0' and awvalid = '1' and wvalid = '1') then\n" logic_string += indent_string("wready_i <= '1';\n") logic_string += 'else\n' logic_string += indent_string("wready_i <= '0';\n") logic_string += "end if;" if self.bus_reset == "async": s += indent_string( async_process(clk_name, reset_name, "p_wready", reset_string, logic_string, self.reset_active_low)) elif self.bus_reset == "sync": s += indent_string( sync_process(clk_name, reset_name, "p_wready", reset_string, logic_string, self.reset_active_low)) s += "\n" s += indent_string( 'slv_reg_wren <= wready_i and wvalid and awready_i and awvalid;\n') s += '\n' if mod.count_rw_regs() + mod.count_pulse_regs() > 0: ################################################################### # p_mm_select_write ################################################################### reset_string = "\n" if mod.count_rw_regs() > 0: reset_string += 'axi_rw_regs_i <= c_' + mod.name + '_rw_regs;\n' if mod.count_pulse_regs() > 0: reset_string += 'axi_pulse_regs_cycle <= c_' + mod.name + '_pulse_regs;\n' logic_string = "" # create a generator for looping through all pulse regs if mod.count_pulse_regs() > 0: logic_string += "\n-- Return PULSE registers to reset value every clock cycle\n" logic_string += 'axi_pulse_regs_cycle <= c_' + mod.name + '_pulse_regs;\n\n' logic_string += "\nif (slv_reg_wren = '1') then\n\n" # create a generator for looping through all rw and pulse regs gen = (reg for reg in mod.registers if reg.mode == "rw" or reg.mode == "pulse") for reg in gen: if reg.mode == 'rw': sig_name = 'axi_rw_regs_i.' elif reg.mode == 'pulse': sig_name = 'axi_pulse_regs_cycle.' par = "if unsigned(awaddr_i) = resize(unsigned(C_BASEADDR) + unsigned(C_ADDR_" par += reg.name.upper() + "), " + str( self.addr_width) + ") then\n\n" logic_string += indent_string(par, 2) par = '' if reg.sig_type == 'fields': for field in reg.fields: par += sig_name + reg.name + '.' + field.name par += ' <= wdata(' par += field.get_pos_vhdl() par += ');\n' elif reg.sig_type == 'default': par += sig_name + reg.name + ' <= wdata;\n' elif reg.sig_type == 'slv': par += sig_name + reg.name + ' <= wdata(' par += str(reg.length - 1) + ' downto 0);\n' elif reg.sig_type == 'sl': par += sig_name + reg.name + ' <= wdata(0);\n' logic_string += indent_string(par, 3) logic_string += indent_string("\nend if;\n", 2) logic_string += '\n' logic_string += 'end if;\n' if self.bus_reset == "async": s += indent_string( async_process(clk_name, reset_name, "p_mm_select_write", reset_string, logic_string, self.reset_active_low)) elif self.bus_reset == "sync": s += indent_string( sync_process(clk_name, reset_name, "p_mm_select_write", reset_string, logic_string, self.reset_active_low)) s += "\n" # Pulse reg process # create a generator for looping through all rw and pulse regs gen = (reg for reg in mod.registers if reg.mode == "pulse") for reg in gen: s += indent_string(self.pulse_reg_process(mod, reg)) s += '\n' #################################################################### # p_write_response #################################################################### reset_string = "bvalid_i <= '0';\n" reset_string += 'bresp_i <= "00";' logic_string = "if (awready_i = '1' and awvalid = '1' and wready_i = '1' " logic_string += "and wvalid = '1' and bvalid_i = '0') then\n" logic_string += indent_string("bvalid_i <= '1';\n") logic_string += indent_string('bresp_i <= "00";\n') logic_string += "elsif (bready = '1' and bvalid_i = '1') then\n" logic_string += indent_string("bvalid_i <= '0';\n") logic_string += "end if;" if self.bus_reset == "async": s += indent_string( async_process(clk_name, reset_name, "p_write_response", reset_string, logic_string, self.reset_active_low)) elif self.bus_reset == "sync": s += indent_string( sync_process(clk_name, reset_name, "p_write_response", reset_string, logic_string, self.reset_active_low)) s += "\n" #################################################################### # p_arready #################################################################### reset_string = "arready_i <= '0';\n" reset_string += "araddr_i <= (others => '0');" logic_string = "if (arready_i = '0' and arvalid = '1') then\n" logic_string += indent_string("arready_i <= '1';\n") logic_string += indent_string('araddr_i <= araddr;\n') logic_string += 'else\n' logic_string += indent_string("arready_i <= '0';\n") logic_string += "end if;" if self.bus_reset == "async": s += indent_string( async_process(clk_name, reset_name, "p_arready", reset_string, logic_string, self.reset_active_low)) elif self.bus_reset == "sync": s += indent_string( sync_process(clk_name, reset_name, "p_arready", reset_string, logic_string, self.reset_active_low)) s += "\n" #################################################################### # p_arvalid #################################################################### reset_string = "rvalid_i <= '0';\n" reset_string += 'rresp_i <= "00";' logic_string = "if (arready_i = '1' and arvalid = '1' and rvalid_i = '0') then\n" logic_string += indent_string("rvalid_i <= '1';\n") logic_string += indent_string('rresp_i <= "00";\n') logic_string += "elsif (rvalid_i = '1' and rready = '1') then\n" logic_string += indent_string("rvalid_i <= '0';\n") logic_string += "end if;" if self.bus_reset == "async": s += indent_string( async_process(clk_name, reset_name, "p_arvalid", reset_string, logic_string, self.reset_active_low)) elif self.bus_reset == "sync": s += indent_string( sync_process(clk_name, reset_name, "p_arvalid", reset_string, logic_string, self.reset_active_low)) s += "\n" s += indent_string('slv_reg_rden <= arready_i and arvalid and ') s += '(not rvalid_i);\n' s += '\n' #################################################################### # p_mm_select_read #################################################################### logic_string = "reg_data_out <= (others => '0');\n\n" gen = [ reg for reg in mod.registers if reg.mode == "ro" or reg.mode == "rw" ] for reg in gen: par = "if unsigned(araddr_i) = resize(unsigned(C_BASEADDR) + unsigned(C_ADDR_" par += reg.name.upper() + "), " + str( self.addr_width) + ") then\n\n" logic_string += par par = '' if reg.sig_type == 'fields': for field in reg.fields: par += 'reg_data_out(' par += field.get_pos_vhdl() if reg.mode == 'rw': par += ') <= axi_rw_regs_i.' elif reg.mode == 'ro': par += ') <= axi_ro_regs.' else: raise Exception("Unknown error occurred") par += reg.name + '.' + field.name + ';\n' elif reg.sig_type == 'default': par += 'reg_data_out <= ' if reg.mode == 'rw': par += 'axi_rw_regs_i.' elif reg.mode == 'ro': par += 'axi_ro_regs.' else: raise Exception("Unknown error occurred") par += reg.name + ';\n' elif reg.sig_type == 'slv': par += 'reg_data_out(' par += str(reg.length - 1) + ' downto 0) <= ' if reg.mode == 'rw': par += 'axi_rw_regs_i.' elif reg.mode == 'ro': par += 'axi_ro_regs.' else: raise Exception("Unknown error occurred") par += reg.name + ';\n' elif reg.sig_type == 'sl': par += 'reg_data_out(0) <= ' if reg.mode == 'rw': par += 'axi_rw_regs_i.' elif reg.mode == 'ro': par += 'axi_ro_regs.' else: raise Exception("Unknown error occurred") par += reg.name + ';\n' logic_string += indent_string(par) logic_string += "\nend if;\n" logic_string += '\n' s += indent_string(comb_process("p_mm_select_read", logic_string)) s += "\n" #################################################################### # p_output #################################################################### reset_string = "rdata_i <= (others => '0');" logic_string = "if (slv_reg_rden = '1') then\n" logic_string += indent_string("rdata_i <= reg_data_out;\n") logic_string += "end if;" if self.bus_reset == "async": s += indent_string( async_process(clk_name, reset_name, "p_output", reset_string, logic_string, self.reset_active_low)) elif self.bus_reset == "sync": s += indent_string( sync_process(clk_name, reset_name, "p_output", reset_string, logic_string, self.reset_active_low)) s += "\n" s += 'end behavior;' return s
def return_bus_pif_VHDL(self, mod): clk_name = self.clk_name reset_name = self.reset_name s = 'library ieee;\n' s += 'use ieee.std_logic_1164.all;\n' s += 'use ieee.numeric_std.all;\n' s += '\n' if self.comp_library != "work": s += "library " + self.comp_library + ";\n" if self.bus_type == 'ipbus': s += 'use ' + self.comp_library + '.' + self.bus_type + '.all;\n' else: s += 'use ' + self.comp_library + '.' + self.bus_type + '_pkg.all;\n' s += 'use work.' + mod.name + '_pif_pkg.all;\n\n' s += 'entity ' + mod.name + '_' + self.short_name + '_pif is\n\n' s += indent_string('generic (\n') par = '-- ' + self.bus_type.upper() + ' Bus Interface Generics\n' par += 'g_' + self.short_name + '_baseaddr : std_logic_vector(' + str( self.addr_width - 1) par += " downto 0) := (others => '0'));\n" s += indent_string(par, 2) s += indent_string('port (') par = '' if mod.count_rw_regs() + mod.count_ro_regs() + mod.count_pulse_regs( ) > 0: par += '\n-- ' + self.bus_type.upper() + ' Bus Interface Ports\n' if mod.count_rw_regs() > 0: par += self.short_name + '_rw_regs : out t_' + mod.name + '_rw_regs := ' par += 'c_' + mod.name + '_rw_regs;\n' if mod.count_ro_regs() > 0: par += self.short_name + '_ro_regs : in t_' + mod.name + '_ro_regs := ' par += 'c_' + mod.name + '_ro_regs;\n' if mod.count_pulse_regs() > 0: par += self.short_name + '_pulse_regs : out t_' + mod.name + '_pulse_regs := ' par += 'c_' + mod.name + '_pulse_regs;\n' par += '\n' par += '-- bus signals\n' par += clk_name + ' : in std_logic;\n' par += reset_name + ' : in std_logic;\n' # Add bus-specific signals if self.bus_type == 'axi': par += 'awaddr : in t_' + mod.name + '_addr;\n' par += 'awvalid : in std_logic;\n' par += 'awready : out std_logic;\n' par += 'wdata : in t_' + mod.name + '_data;\n' par += 'wvalid : in std_logic;\n' par += 'wready : out std_logic;\n' par += 'bresp : out std_logic_vector(1 downto 0);\n' par += 'bvalid : out std_logic;\n' par += 'bready : in std_logic;\n' par += 'araddr : in t_' + mod.name + '_addr;\n' par += 'arvalid : in std_logic;\n' par += 'arready : out std_logic;\n' par += 'rdata : out t_' + mod.name + '_data;\n' par += 'rresp : out std_logic_vector(1 downto 0);\n' par += 'rvalid : out std_logic;\n' par += 'rready : in std_logic\n' elif self.bus_type == 'ipbus': par += '{}_in : in {};\n'.format(self.short_name, self.in_type) par += '{}_out : out {}\n'.format(self.short_name, self.out_type) par += ');\n' s += indent_string(par, 2) s += 'end ' + mod.name + '_' + self.short_name + '_pif;\n\n' s += 'architecture behavior of {}_{}_pif is\n\n'.format( mod.name, self.short_name) if self.bus_type == 'ipbus': par = "constant C_BASEADDR : std_logic_vector(31 downto 0) := g_" + self.short_name + "_baseaddr;\n" else: par = "constant C_BASEADDR : t_" + self.short_name + "_addr := g_" + self.short_name + "_baseaddr;\n" s += indent_string(par) s += "\n" if mod.count_rw_regs() + mod.count_pulse_regs() > 0: par = '' par += '-- internal signal for readback' + '\n' s += indent_string(par) if mod.count_rw_regs() > 0: par = 'signal ' + self.short_name + '_rw_regs_i : t_' par += mod.name + '_rw_regs := c_' + mod.name + '_rw_regs;\n' s += indent_string(par) if mod.count_pulse_regs() > 0: par = 'signal ' + self.short_name + '_pulse_regs_i : t_' par += mod.name + '_pulse_regs := c_' + mod.name + '_pulse_regs;\n' s += indent_string(par) par = 'signal ' + self.short_name + '_pulse_regs_cycle : t_' par += mod.name + '_pulse_regs := c_' + mod.name + '_pulse_regs;\n' s += indent_string(par) s += '\n' # Add bus-specific logic if self.bus_type == 'axi': s += self.return_axi_pif_VHDL(mod, clk_name, str.strip(reset_name)) elif self.bus_type == 'ipbus': s += self.return_ipbus_pif_VHDL(mod, clk_name, str.strip(reset_name)) return s
def return_vhdl_tb(self): self.logger.debug('Generating TB Sequencer VHDL') s = ('library ieee;\n' 'use ieee.std_logic_1164.all;\n' 'use ieee.numeric_std.all;\n\n') if self.bus.bus_type == 'ipbus': s += 'library ipbus;\n' s += 'use ipbus.ipbus.all;\n\n' else: if self.bus.comp_library != Bus.default_comp_library: s += 'library {};\n'.format(self.bus.comp_library) s += 'use {}.{}_pkg.all;\n'.format(self.bus.comp_library, self.bus.bus_type) s += 'use work.{}_pif_pkg.all;\n\n'.format(self.module.name) s += ('library uvvm_util;\n' 'context uvvm_util.uvvm_util_context;\n\n') s += self.bus.get_uvvm_lib() s += ( '\n-------------------------------------------------------------------------------\n' '\n' 'entity {0}_{1}_pif_tb is\n' '\n' 'end entity {0}_{1}_pif_tb;\n' '\n' '-------------------------------------------------------------------------------\n\n' '').format(self.module.name, self.bus.short_name) s += 'architecture tb of {}_{}_pif_tb is\n\n'.format( self.module.name, self.bus.short_name) s += indent_string( 'constant C_SCOPE : string := C_TB_SCOPE_DEFAULT;\n' 'constant C_CLK_PERIOD : time := 10 ns;\n') s += '\n' s += indent_string( '-- component generics\n' 'constant g_{}_baseaddr : std_logic_vector(31 downto 0) := 32X"FFAA0000";\n' 'constant g_instance_num : natural := 0;\n' ).format(self.bus.short_name) s += '\n' # Initial reset value if self.bus.reset_active_low: init_reset = "'1'" else: init_reset = "'0'" s += indent_string('-- component ports\n') if self.module.count_rw_regs() > 0: s += indent_string( 'signal {0}_rw_regs : t_{1}_rw_regs := c_{1}_rw_regs;\n'. format(self.bus.short_name, self.module.name)) if self.module.count_ro_regs() > 0: s += indent_string( 'signal {0}_ro_regs : t_{1}_ro_regs := c_{1}_ro_regs;\n'. format(self.bus.short_name, self.module.name)) if self.module.count_pulse_regs() > 0: s += indent_string( 'signal {0}_pulse_regs : t_{1}_pulse_regs := c_{1}_pulse_regs;\n' .format(self.bus.short_name, self.module.name)) s += indent_string( 'signal {0}_{2} : std_logic := \'1\';\n' 'signal {0}_{3} : std_logic := {4};\n' 'signal {0}_in : {5};\n' 'signal {0}_out : {6};\n' '').format(self.bus.short_name, self.module.name, self.bus.clk_name, self.bus.reset_name, init_reset, self.bus.in_type, self.bus.out_type) s += '\n' s += indent_string(self.bus.get_uvvm_signals()) s += '\n' s += indent_string(self.get_addr_func()) s += '\n' s += 'begin -- architecture tb\n\n' s += indent_string(self.bus.get_uvvm_signal_assignment()) s += '\n' s += indent_string('-- component instantiation\n') s += indent_string(self.module.get_instantiation("DUT", False)) s += '\n' s += indent_string( ('-- clock generator\n' 'clock_generator({}_{}, C_CLK_PERIOD);\n\n').format( self.bus.short_name, self.bus.clk_name)) s += indent_string(('-- main testbench\n' 'p_main : process\n\n')) s += indent_string(self.get_uvvm_gen_overloads(), 2) s += indent_string(self.bus.get_uvvm_overloads(), 2) s += indent_string('begin\n\n') par = ('-- enable_log_msg(ALL_MESSAGES);\n' 'disable_log_msg(ALL_MESSAGES, QUIET);\n' 'enable_log_msg(ID_LOG_HDR, QUIET);\n' 'enable_log_msg(ID_LOG_HDR_LARGE, QUIET);\n' 'enable_log_msg(ID_SEQUENCER, QUIET);\n' '-- enable_log_msg(ID_BFM, QUIET);\n' '-- enable_log_msg(ID_CLOCK_GEN, QUIET);\n' '-- enable_log_msg(ID_GEN_PULSE, QUIET);\n' '-- enable_log_msg(ID_POS_ACK, QUIET);\n' '\n' '-- report_global_ctrl(VOID);\n' '-- report_msg_id_panel(VOID);\n') s += indent_string(par, 2) s += '\n' # Initial reset value if self.bus.reset_active_low: pulse_reset = "'0'" else: pulse_reset = "'1'" par = 'gen_pulse({}_{}, {}, 500 ns, BLOCKING, "Reset for 500 ns");\n'.format( self.bus.short_name, str.strip(self.bus.reset_name), pulse_reset) s += indent_string(par, 2) s += '\n' for reg in self.module.registers: s += indent_string('--\n\n', 2) s += indent_string(self.reg_hdr(reg), 2) s += '\n' s += indent_string(self.check_default_value(reg), 2) s += '\n' s += indent_string(self.set_check_zero_value(reg), 2) s += '\n' s += indent_string(self.check_bit_fields(reg), 2) if self.bus.bus_type == 'ipbus': par = ( '--\n\n' 'log_hdr_large("Checking that invalid register returns ERR");\n\n' 'ipbus_bfm_config.expected_response <= ERR;\n\n' 'log_hdr("Check erroneous read");\n\n' 'read(32X"FFFFFFFF", dummy_data, "Read from register that does not exist");\n' 'check_value(dummy_data, 32X"DEADBEEF", error, "Check that the returned data is rubbish");\n\n' 'log_hdr("Check erroneous write");\n\n' 'write(32X"FFFFFFFF", 32X"0", "Write to register that does not exist");\n\n' ) s += indent_string(par, 2) par = ( '--==================================================================================================\n' '-- Ending the simulation\n' '--------------------------------------------------------------------------------------\n' 'wait for 100 ns; -- to allow some time for completion\n' 'report_alert_counters(FINAL); -- Report final counters and print conclusion for simulation (Success/Fail)\n' 'log(ID_LOG_HDR, "SIMULATION COMPLETED", C_SCOPE);\n\n' '-- Finish the simulation\n' 'std.env.stop;\n' 'wait; -- to stop completely\n') s += indent_string(par, 2) s += indent_string('end process p_main;\n\n') s += 'end architecture tb;\n' return s
def return_tex_documentation(self, test_version=None): if test_version is None: version = __VERSION__ else: version = test_version s = tex_top s += "\n\n" s += r"\title{" + utf8tolatex(self.module.name) + "}\n" s += r"\author{" + self.module.get_version() + "}\n" s += r"\date{\today\ \currenttime}" + "\n" s += "\n" s += r"\pagestyle{fancy}" + "\n" s += r"\fancyhf{}" + "\n" s += r"\fancyhead[C]{Generated by bust " + version + "}\n" s += r"\fancyfoot[L]{\today\ \currenttime}" + "\n" s += r"\fancyfoot[C]{\thepage}" + "\n" s += r"\fancyfoot[R]{" + self.module.get_version() + "}\n\n\n" s += r"\begin{document}" + "\n\n" s += r"\maketitle" + "\n" s += r"\thispagestyle{fancy}" + "\n" s += "\n" s += utf8tolatex(self.module.description) + "\n\n" s += r"\section{Register List}" + "\n\n" s += tex_table_top + "\n" for i, reg in enumerate(self.module.registers): p = str(i) + " & " p += utf8tolatex(reg.name) + " & " p += reg.mode.upper() + reg.return_stall_string() + " & " p += r"\texttt{" p += '0x{0:0{1}X}'.format(reg.address, int(self.module.addr_width/4)) + "} & " p += reg.sig_type.upper() + " & " p += str(reg.length) + " & " p += r"\texttt{" p += '0x' + format(int(reg.reset, 16), 'X') + "} \\\\\n" p += r"\hline" + "\n" s += indent_string(p, 3) s += tex_table_bot s += "\n\n" r"\section{Registers}" + "\n\n" for reg in self.module.registers: s += r"\begin{register}{H}{" + utf8tolatex(reg.name) + " - " s += reg.mode.upper() if reg.mode.lower() == "pulse": s += " for " + str(reg.pulse_cycles) + " cycles " if reg.stall: s += " - STALL for {} cycles".format(reg.stall_cycles) s += "}{" + '0x{0:0{1}X}'.format(reg.address, int(self.module.addr_width/4)) s += "}" s += indent_string(r"\par ") s += utf8tolatex(reg.description) + r" \regnewline" + "\n" s += indent_string(r"\label{" + reg.name + "}\n") if reg.length < self.module.data_width: p = r"\regfield{unused}{" p += str(self.module.data_width - reg.length) + "}{" p += str(reg.length) + "}{-}\n" s += indent_string(p) if reg.sig_type != "fields": p = r"\regfield{}{" + str(reg.length) + "}{0}{" if reg.length < 2: p += str(int(reg.reset, 16)) else: p += '{0x' + format(int(reg.reset, 16), 'X') + "}" p += "}\n" s += indent_string(p) else: for field in reversed(reg.fields): p = r"\regfield{" + utf8tolatex(field.name) + "}{" p += str(field.length) + "}{" p += str(field.pos_low) + "}{" if field.length < 2: p += str(int(field.reset, 16)) else: p += '{0x' + format(int(field.reset, 16), 'X') + "}" p += "}\n" s += indent_string(p) s += r"\reglabel{Reset}\regnewline" + "\n" if reg.sig_type == "fields": p = r"\begin{regdesc}\begin{reglist}[" # Get the longest field name and indent the list based on that length gen = [field.name for field in reg.fields] longest = max(gen, key=len) p += utf8tolatex(longest) p += "]\n" s += indent_string(p) for field in reg.fields: p = r"\item [" + utf8tolatex(field.name) + "] " p += utf8tolatex(field.description) s += indent_string(p, 2) s += indent_string(r"\end{reglist}\end{regdesc}" + "\n") s += r"\end{register}" + "\n\n" s += "\end{document}" return s