Skip to content

Commit

Permalink
formatting
Browse files Browse the repository at this point in the history
  • Loading branch information
KelvinChung2000 committed Feb 26, 2024
1 parent bc8234d commit bbc9dab
Show file tree
Hide file tree
Showing 19 changed files with 4,180 additions and 2,343 deletions.
447 changes: 266 additions & 181 deletions FABulous.py

Large diffs are not rendered by default.

216 changes: 129 additions & 87 deletions fabric_cad/bit_gen.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,90 +9,107 @@
import numpy
import pickle
import csv
from fasm import * #Remove this line if you do not have the fasm library installed and will not be generating a bitstream

from fasm import * # Remove this line if you do not have the fasm library installed and will not be generating a bitstream


def replace(string, substitutions):
substrings = sorted(substitutions, key=len, reverse=True)
regex = re.compile('|'.join(map(re.escape, substrings)))
regex = re.compile("|".join(map(re.escape, substrings)))
return regex.sub(lambda match: substitutions[match.group(0)], string)



def bitstring_to_bytes(s):
return int(s, 2).to_bytes((len(s) + 7) // 8, byteorder='big')
return int(s, 2).to_bytes((len(s) + 7) // 8, byteorder="big")

#CAD methods from summer vacation project 2020

# CAD methods from summer vacation project 2020

#Method to generate bitstream in the output format - more detail at the end

# Method to generate bitstream in the output format - more detail at the end
def genBitstream(fasmFile: str, specFile: str, bitstreamFile: str):
lGen = parse_fasm_filename(fasmFile)
canonStr = fasm_tuple_to_string(lGen, True)
canonList = list(parse_fasm_string(canonStr))

specDict = pickle.load(open(specFile,"rb"))
specDict = pickle.load(open(specFile, "rb"))
tileDict = {}
tileDict_No_Mask = {}

FrameBitsPerRow = specDict["ArchSpecs"]["FrameBitsPerRow"]
MaxFramesPerCol = specDict["ArchSpecs"]["MaxFramesPerCol"]

#Change this so it has the actual right dimensions, initialised as an empty bitstream
# Change this so it has the actual right dimensions, initialised as an empty bitstream
for tile in specDict["TileMap"].keys():
tileDict[tile] = [0]*(MaxFramesPerCol*FrameBitsPerRow)
tileDict_No_Mask[tile] = [0]*(MaxFramesPerCol*FrameBitsPerRow)
tileDict[tile] = [0] * (MaxFramesPerCol * FrameBitsPerRow)
tileDict_No_Mask[tile] = [0] * (MaxFramesPerCol * FrameBitsPerRow)

###NOTE: SOME OF THE FOLLOWING METHODS HAVE BEEN CHANGED DUE TO A MODIFIED BITSTREAM SPEC FORMAT
#Please bear in mind that the tilespecs are now mapped by tile loc and not by cell type
# Please bear in mind that the tilespecs are now mapped by tile loc and not by cell type

for line in canonList:
if 'CLK' in set_feature_to_str(line.set_feature):
if "CLK" in set_feature_to_str(line.set_feature):
continue
if (line.set_feature):
if line.set_feature:
tileVals = set_feature_to_str(line.set_feature).split(".")
tileLoc = tileVals[0]
featureName = ".".join((tileVals[1], tileVals[2]))
if tileLoc not in specDict["TileMap"].keys():
raise Exception("Tile found in fasm file not found in bitstream spec")
tileType = specDict["TileMap"][tileLoc] #Set the necessary bits high
tileType = specDict["TileMap"][tileLoc] # Set the necessary bits high
if featureName in specDict["TileSpecs"][tileLoc].keys():
if specDict["TileSpecs"][tileLoc][featureName]:
for bitIndex in specDict["TileSpecs"][tileLoc][featureName]:
tileDict[tileLoc][bitIndex] = int(specDict["TileSpecs"][tileLoc][featureName][bitIndex])
for bitIndex_No_Mask in specDict["TileSpecs_No_Mask"][tileLoc][featureName]:
tileDict_No_Mask[tileLoc][bitIndex_No_Mask] = int(specDict["TileSpecs_No_Mask"][tileLoc][featureName][bitIndex_No_Mask])
tileDict[tileLoc][bitIndex] = int(
specDict["TileSpecs"][tileLoc][featureName][bitIndex]
)
for bitIndex_No_Mask in specDict["TileSpecs_No_Mask"][tileLoc][
featureName
]:
tileDict_No_Mask[tileLoc][bitIndex_No_Mask] = int(
specDict["TileSpecs_No_Mask"][tileLoc][featureName][
bitIndex_No_Mask
]
)

else:
#print(specDict["TileSpecs"][tileLoc].keys())
# print(specDict["TileSpecs"][tileLoc].keys())
print(tileType)
print(tileLoc)
print(featureName)
raise Exception("Feature found in fasm file was not found in the bitstream spec")

raise Exception(
"Feature found in fasm file was not found in the bitstream spec"
)

#Write output string and introduce mask
# Write output string and introduce mask
coordsRE = re.compile("X(\d*)Y(\d*)")
num_columns = 0
num_rows = 0

for tileKey in tileDict:
coordsMatch = coordsRE.match(tileKey)
num_columns = max(int(coordsMatch.group(1))+1,num_columns)
num_rows = max(int(coordsMatch.group(2))+1,num_rows)
num_columns = max(int(coordsMatch.group(1)) + 1, num_columns)
num_rows = max(int(coordsMatch.group(2)) + 1, num_rows)
outStr = ""
bitStr = bytes.fromhex('00AAFF01000000010000000000000000FAB0FAB1')
bit_array = [[b'' for x in range(20)] for y in range(num_columns)]
bitStr = bytes.fromhex("00AAFF01000000010000000000000000FAB0FAB1")
bit_array = [[b"" for x in range(20)] for y in range(num_columns)]

verilog_str = ''
vhdl_str = 'library IEEE;\nuse IEEE.STD_LOGIC_1164.ALL;\n\npackage emulate_bitstream is\n'
verilog_str = ""
vhdl_str = (
"library IEEE;\nuse IEEE.STD_LOGIC_1164.ALL;\n\npackage emulate_bitstream is\n"
)
for tileKey in tileDict_No_Mask:
if specDict["TileMap"][tileKey] == "NULL" or len(specDict["FrameMap"][specDict["TileMap"][tileKey]]) == 0:
if (
specDict["TileMap"][tileKey] == "NULL"
or len(specDict["FrameMap"][specDict["TileMap"][tileKey]]) == 0
):
continue
verilog_str += f"// {tileKey}, {specDict['TileMap'][tileKey]}\n"
verilog_str += f"`define Tile_{tileKey}_Emulate_Bitstream {MaxFramesPerCol*FrameBitsPerRow}'b"

vhdl_str += f"--{tileKey}, {specDict['TileMap'][tileKey]}\n"
vhdl_str += f"constant Tile_{tileKey}_Emulate_Bitstream : std_logic_vector({MaxFramesPerCol*FrameBitsPerRow}-1 downto 0) := \""
vhdl_str += f'constant Tile_{tileKey}_Emulate_Bitstream : std_logic_vector({MaxFramesPerCol*FrameBitsPerRow}-1 downto 0) := "'

for i in range((MaxFramesPerCol*FrameBitsPerRow)-1,-1,-1):
for i in range((MaxFramesPerCol * FrameBitsPerRow) - 1, -1, -1):
verilog_str += str(tileDict_No_Mask[tileKey][i])
vhdl_str += str(tileDict_No_Mask[tileKey][i])
verilog_str += "\n"
Expand All @@ -109,81 +126,99 @@ def genBitstream(fasmFile: str, specFile: str, bitstreamFile: str):
bitPos = 0

for frameIndex in range(MaxFramesPerCol):
#print (tileDict[tileKey]) #:FrameBitsPerRow*frameIndex
# print (tileDict[tileKey]) #:FrameBitsPerRow*frameIndex
if specDict["TileMap"][tileKey] == "NULL":
frame_bit_row = '0' * FrameBitsPerRow
frame_bit_row = "0" * FrameBitsPerRow
else:
frame_bit_row = (''.join(map(str, (tileDict[tileKey][FrameBitsPerRow*frameIndex:(FrameBitsPerRow*frameIndex)+FrameBitsPerRow]))))[::-1]
curStr += ",".join((f"frame{frameIndex}", str(frameIndex), str(FrameBitsPerRow), frame_bit_row))
frame_bit_row = (
"".join(
map(
str,
(
tileDict[tileKey][
FrameBitsPerRow
* frameIndex : (FrameBitsPerRow * frameIndex)
+ FrameBitsPerRow
]
),
)
)
)[::-1]
curStr += ",".join(
(
f"frame{frameIndex}",
str(frameIndex),
str(FrameBitsPerRow),
frame_bit_row,
)
)
curStr += "\n"

bit_hex = bitstring_to_bytes(frame_bit_row)
bit_array[x][frameIndex] += bit_hex

#concatenatedTileDict[tileKey] = curStr
# concatenatedTileDict[tileKey] = curStr
outStr += curStr + "\n"

#print(num_columns)
# print(num_columns)
for i in range(num_columns):
for j in range(20):
bin_temp = f"{i:05b}"[::-1]
frame_select = ['0' for k in range(32)]
#bitStr += "X"+str(i)+", frame"+str(j)+"\n"
frame_select = ["0" for k in range(32)]
# bitStr += "X"+str(i)+", frame"+str(j)+"\n"

for k in range(-5,0,1):
for k in range(-5, 0, 1):
frame_select[k] = bin_temp[k]
frame_select[j] = '1'
frame_select_temp = (''.join(frame_select))[::-1]
frame_select[j] = "1"
frame_select_temp = ("".join(frame_select))[::-1]

bitStr += bitstring_to_bytes(frame_select_temp)
bitStr += bit_array[i][j]


#Note - format in output file is line by line:
#Tile Loc, Tile Type, X, Y, bits...... \n
#Each line is one tile
# Note - format in output file is line by line:
# Tile Loc, Tile Type, X, Y, bits...... \n
# Each line is one tile
# Write out bitstream CSV representation
print(outStr, file = open(bitstreamFile.replace("bin","csv"), "w+"))
print(outStr, file=open(bitstreamFile.replace("bin", "csv"), "w+"))
# Write out HDL representations
print(verilog_str, file = open(bitstreamFile.replace("bin","vh"), "w+"))
print(vhdl_str, file = open(bitstreamFile.replace("bin","vhd"), "w+"))
print(verilog_str, file=open(bitstreamFile.replace("bin", "vh"), "w+"))
print(vhdl_str, file=open(bitstreamFile.replace("bin", "vhd"), "w+"))
# Write out binary representation
with open(bitstreamFile, 'bw+') as f:
f.write(bitStr)
with open(bitstreamFile, "bw+") as f:
f.write(bitStr)


#This class represents individual tiles in the architecture
# This class represents individual tiles in the architecture
class Tile:
tileType = ""
bels = []
wires = []
atomicWires = [] #For storing single wires (to handle cascading and termination)
wires = []
atomicWires = [] # For storing single wires (to handle cascading and termination)
pips = []
belPorts = set()
matrixFileName = ""
pipMuxes_MapSourceToSinks= []
pipMuxes_MapSinkToSources= []
pipMuxes_MapSourceToSinks = []
pipMuxes_MapSinkToSources = []

x = -1 #Init with negative values to ease debugging
x = -1 # Init with negative values to ease debugging
y = -1

def __init__(self, inType):
self.tileType = inType

def genTileLoc(self, separate = False):
if (separate):
return("X" + str(self.x), "Y" + str(self.y))
def genTileLoc(self, separate=False):
if separate:
return ("X" + str(self.x), "Y" + str(self.y))
return "X" + str(self.x) + "Y" + str(self.y)


#This class represents the fabric as a whole
# This class represents the fabric as a whole
class Fabric:
tiles = []
height = 0
width = 0
cellTypes = []


def __init__(self, inHeight, inWidth):
self.width = inWidth
self.height = inHeight
Expand Down Expand Up @@ -214,43 +249,50 @@ def getTileAndWireByWireDest(self, loc: str, dest: str, jumps: bool = True):
destx = tile.x + int(wire["xoffset"])
desttileLoc = f"X{destx}Y{desty}"

if (desttileLoc == loc) and (wire["destination"] + str(i) == dest):
if (desttileLoc == loc) and (
wire["destination"] + str(i) == dest
):
return (tile, wire, i)

return None



#####################################################################################
# Main
#####################################################################################

#Strip arguments
# Strip arguments
caseProcessedArguments = list(map(lambda x: x.strip(), sys.argv))
processedArguments = list(map(lambda x: x.lower(), caseProcessedArguments))
flagRE = re.compile("-\S*")

if ('-genBitstream'.lower() in str(sys.argv).lower()):
argIndex = processedArguments.index('-genBitstream'.lower())

if len(processedArguments) <= argIndex + 3:
raise ValueError('\nError: -genBitstream expect three file names - the fasm file, the spec file and the output file')
elif (flagRE.match(caseProcessedArguments[argIndex + 1])
or flagRE.match(caseProcessedArguments[argIndex + 2])
or flagRE.match(caseProcessedArguments[argIndex + 3])):
raise ValueError('\nError: -genBitstream expect three file names, but found a flag in the arguments:'
f' {caseProcessedArguments[argIndex + 1]}, {caseProcessedArguments[argIndex + 2]}, {caseProcessedArguments[argIndex + 3]}\n')
if "-genBitstream".lower() in str(sys.argv).lower():
argIndex = processedArguments.index("-genBitstream".lower())

FasmFileName = caseProcessedArguments[argIndex + 1]
SpecFileName = caseProcessedArguments[argIndex + 2]
OutFileName = caseProcessedArguments[argIndex + 3]
if len(processedArguments) <= argIndex + 3:
raise ValueError(
"\nError: -genBitstream expect three file names - the fasm file, the spec file and the output file"
)
elif (
flagRE.match(caseProcessedArguments[argIndex + 1])
or flagRE.match(caseProcessedArguments[argIndex + 2])
or flagRE.match(caseProcessedArguments[argIndex + 3])
):
raise ValueError(
"\nError: -genBitstream expect three file names, but found a flag in the arguments:"
f" {caseProcessedArguments[argIndex + 1]}, {caseProcessedArguments[argIndex + 2]}, {caseProcessedArguments[argIndex + 3]}\n"
)

FasmFileName = caseProcessedArguments[argIndex + 1]
SpecFileName = caseProcessedArguments[argIndex + 2]
OutFileName = caseProcessedArguments[argIndex + 3]

genBitstream(FasmFileName, SpecFileName, OutFileName)



if ('-help'.lower() in str(sys.argv).lower()) or ('-h' in str(sys.argv).lower()):
print('')
print('Options/Switches')
print(' -genBitstream foo.fasm spec.txt bitstream.txt - generates a bitstream - the first file is the fasm file, the second is the bitstream spec and the third is the fasm file to write to')



if ("-help".lower() in str(sys.argv).lower()) or ("-h" in str(sys.argv).lower()):
print("")
print("Options/Switches")
print(
" -genBitstream foo.fasm spec.txt bitstream.txt - generates a bitstream - the first file is the fasm file, the second is the bitstream spec and the third is the fasm file to write to"
)
Loading

0 comments on commit bbc9dab

Please sign in to comment.