⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 spec2vhdl.py

📁 CNC 的开放码,EMC2 V2.2.8版
💻 PY
📖 第 1 页 / 共 2 页
字号:
		if (addr & (1<<n)) :		    self.name += '1'		else :		    self.name += '0'	    else :		self.name += 'x'	if count_ones(mask) <= 4 :	    # can decode with a single 4 bit LUT	    self.version = 0	    self.finalmask = mask	    return	# need multiple level decode	# find best available upper level decode	mask1 = mask	for s in chip_selects :	    m = s._remainder(addr, mask)	    if ( m < mask1 ) :		upper1 = s		mask1 = m	if ( mask1 == mask ) or ( count_ones(mask1) > 9 ) :	    # didn't find a suitable decode, need to make one	    # these values are magic, designed to result in no more than	    # three levels of logic, and no more than four inputs at each level	    lut = { 5:3, 6:3, 7:3, 8:5, 9:5, 10:6, 11:3, 12:3, 13:3, 14:8, 15:8, 16:9 }	    umask = trim_ones_lsb(mask, lut[count_ones(mask)])	    upper1 = ChipSelect(addr, umask)	    chip_selects.append(upper1)	    mask1 = upper1._remainder(addr, mask)	if count_ones(mask1) <= 3 :	    # can decode with a single upper level	    self.version = 1	    self.ena1name = upper1.name	    self.finalmask = mask1	    return	# need another upper level decode	# find best available upper level decode	mask2 = mask1	for s in chip_selects :	    m = s._remainder(addr, mask1)	    if count_ones(m) < count_ones(mask2) :		upper2 = s		mask2 = m	    elif ( count_ones(m) == count_ones(mask2)) and ( m < mask2 ) :		upper2 = s		mask2 = m	if count_ones(mask2) > 2 :	    # didn't find a suitable decode, need to make one	    # we want to have 2 bits left to decode	    umask = trim_ones_lsb(mask1, 2)	    upper2 = ChipSelect(addr, umask)	    chip_selects.append(upper2)	    mask2 = upper2._remainder(addr, mask1)	# combine the two upper decodes and 2 bits of address	self.version = 3	self.ena1name = upper1.name	self.ena2name = upper2.name	self.finalmask = mask2	return    # return the bits in the 'addr, mask' block that    # this chipselect object does not decode    def _remainder(self, addr, mask) :	if ( self.mask & addr ) != ( self.mask & self.addr ) :	    # wrong address	    return mask	if ( self.mask & mask ) != self.mask :	    # too specific	    return mask	return mask & ~self.mask    def __str__ (self) :	return self.name    def __repr__ (self) :	return self.name    def __cmp__ (self, other) :	# ordering is such that upper level selects come	# before lower level ones that (might) use them	smask = self.mask	for n in reversed(range(14)) :	    if (smask & (1<<n)) : break	    smask |= (1<<n)	omask = other.mask	for n in reversed(range(14)) :	    if (omask & (1<<n)) : break	    omask |= (1<<n)	saddr = self.addr & smask	oaddr = other.addr & omask	if saddr < oaddr : return -2	if saddr > oaddr : return  2	if smask < omask : return -1	if smask > omask : return  1	return 0    def signal (self) :	# the VHDL signal declaration	return "\tsignal "+self.name+" : std_logic;\n"    def logic (self) :	# the VHDL implementation	logic = "    "+self.name+" <= "	if self.version & 1 :	    logic += " and "+self.ena1name	if self.version & 2 :	    logic += " and "+self.ena2name	for n in reversed(range(14)) :	    if (self.finalmask & (1<<n)) :		logic += " and "		if (self.addr & (1<<n)) :		    logic += "addr("+str(n+2)+")"		else :		    logic += "not(addr("+str(n+2)+"))"	logic += ";\n"	# its easier to put 'and' in front of every term and delete	# the first one later, than to figure out which term is first	logic = logic.replace(" and ","",1)	return logicdef usage ():    print "\nUsage: spec2vhdl [options] <name>\n"    print "  Reads <name>.spec, writes <name>.rspec and <name>.vhd, where"    print "  <name>.spec is an FPGA spec, <name>.rspec is a config RAM data"    print "  spec (used later in the build process), and <name>.vhd is a top"    print "  level VHDL file that implements the specfied FPGA.\n"    print "  Options:"    print "    -s <spec_name>    use <spec_name> as input file"    print "    -r <rspec_name>   use <rspec_name> for RAM spec output"    print "    -v <vhdl_name>    use <vhdl_name> for VHDL output"    print "    -l <lib_path>     read module specs from <lib_path>"    print "    -h                print this help screen"try:    opts, args = getopt.gnu_getopt(sys.argv[1:],"hs:r:v:l:")except getopt.GetoptError:    usage()    sys.exit(2)if len(args) > 1 :    usage()    sys.exit(2)libpath = "."if len(args) == 1 :    spec_fname = args[0]+".spec"    rspec_fname = args[0]+".rspec"    vhdl_fname = args[0]+".vhd"else :    spec_fname = ""    rspec_fname = ""    vhdl_fname = ""for opt,value in opts :    if opt == '-h' :	usage()	sys.exit(2)    if opt == "-s" :	spec_fname = value    if opt == "-r" :	rspec_fname = value    if opt == "-v" :	vhdl_fname = value    if opt == "-l" :	libpath = valuefor name in spec_fname, rspec_fname, vhdl_fname :    if len(name) == 0 :	usage()	sys.exit(2)# read the source file into a config file objectsrc = ConfigParser.ConfigParser()# read in core stuff firstsrc.read("core.spec")src.read(spec_fname)if len(src.sections()) == 0 :    print "ERROR: source file '"+spec_fname+"' not found, empty, or misformatted"    sys.exit(2)# get a list of all module spec files in the librarylibpath += "/*.mspec"mspecs = glob.glob(libpath)if len(mspecs) == 0 :    print "ERROR: no module specs found at '"+libpath+"'"    sys.exit(2)# read the module spec file(s) into a config file objectlib = ConfigParser.ConfigParser()for name in mspecs :    lib.read(name)# create empty data structuresinstances = []modspecs = {}packages = []chip_selects = []# create instances of VHDL modules based on spec filefor name in src.sections() :    instances.append(ModuleInstance(name))# assign addresses to instances# size of address space: 16K 32-bit words, with the# first 256 words (1K bytes) reserved for config RAMupper_limit = 0x4000lower_limit = 0x0100# chip select for the RAMchip_selects.append(ChipSelect(0,0x3F00))# preliminary sort gets like modules together, and instances# in numerical orderinstances.sort(key=ModuleInstance.get_id_code_and_instance)# instances are placed from largest to smallest, since larger# address spaces have more demanding alignment requirementsinstances.sort(key=ModuleInstance.get_num_regs, reverse=1)for i in instances :    if i.get_num_regs() == 0 :	# no registers, doesn't need address space or chip select	break    # instances are placed starting at the top of the address    # space, since the RAM block at the bottom would mess    # up alignment of anything bigger than 256 registers.    upper_limit -= i.get_blk_size()    if upper_limit < lower_limit :	print "ERROR: ran out of address space in FPGA"	sys.exit(1)    i.assign_address(upper_limit)# sort so that derived selects come after the ones they use# (not strictly neccessary, VHDL can figure it out anyway)chip_selects.sort()# restore "sorted by ID code and instance" ordering for# subsequent processinginstances.sort(key=ModuleInstance.get_id_code_and_instance)# more gathering of infomation and validation needs to be done here# start generating output, top level VHDL file first# prepare for substitution into top-level VHDL filetoplevel_values = {}toplevel_values["outfile"] = vhdl_fnametoplevel_values["preprocessor"] = sys.argv[0]toplevel_values["infile"] = spec_fnametoplevel_values["timestamp"] =  str(datetime.datetime.now()).split(".")[0]toplevel_values["packages"] = ""for p in packages :    toplevel_values["packages"] += "use work."+p+"_pkg.all;\n"toplevel_values["instance_vhdl"] = ""for i in instances :    toplevel_values["instance_vhdl"] += i.vhdl()toplevel_values["chipselect_signals"] = ""toplevel_values["chipselect_logic"] = ""for cs in chip_selects :    toplevel_values["chipselect_signals"] += cs.signal()    toplevel_values["chipselect_logic"] += cs.logic()# do the substitution and write output filetoplevel_in = open("toplevel.vhd", "r")toplevel_out = open(vhdl_fname, "w")toplevel_out.write(string.Template(toplevel_in.read()).substitute(toplevel_values))# next we generate the data to be merged into the final .fpga fileram_template = ""symbol_values = {}#print instancesfor i in instances:    ram_template += i.ram_template()    symbol_values.update(i.symbol_table())symbol_specs = {}for m in modspecs.values():    symbol_specs.update(m.symbol_table())bf = bitfile.BitFile()# 't' section - template for RAMbf["t"] = repr(ram_template)# 'v' section - symbol valuesbf["v"] = repr(symbol_values)# 's' section - symbol specsbf["s"] = repr(symbol_specs)# write to filebf.tofilename(rspec_fname)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -