Ejemplo n.º 1
0
    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
Ejemplo n.º 2
0
    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
Ejemplo n.º 3
0
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
Ejemplo n.º 4
0
 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
Ejemplo n.º 5
0
    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
Ejemplo n.º 6
0
    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
Ejemplo n.º 7
0
 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
Ejemplo n.º 8
0
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
Ejemplo n.º 9
0
 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
Ejemplo n.º 10
0
 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
Ejemplo n.º 11
0
    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
Ejemplo n.º 12
0
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
Ejemplo n.º 13
0
    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
Ejemplo n.º 14
0
    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)
Ejemplo n.º 15
0
 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)
Ejemplo n.º 16
0
    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
Ejemplo n.º 17
0
 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
Ejemplo n.º 18
0
    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
Ejemplo n.º 19
0
    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
Ejemplo n.º 20
0
    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
Ejemplo n.º 21
0
    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
Ejemplo n.º 22
0
    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
Ejemplo n.º 23
0
    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
Ejemplo n.º 24
0
    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