diff --git a/.github/workflows/fabric_gen.yml b/.github/workflows/fabric_gen.yml index 2394e4b3..df1647de 100644 --- a/.github/workflows/fabric_gen.yml +++ b/.github/workflows/fabric_gen.yml @@ -11,15 +11,15 @@ jobs: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v2 + - uses: actions/checkout@v4 with: submodules: recursive - name: Set up Python 3.9 - uses: actions/setup-python@v2 + uses: actions/setup-python@v4 with: python-version: 3.9 - name: Set up OSS CAD suite - uses: YosysHQ/setup-oss-cad-suite@v1 + uses: YosysHQ/setup-oss-cad-suite@v2 - name: Install dependencies run: | python3 -m pip install --upgrade pip @@ -31,15 +31,16 @@ jobs: - name: Lint with flake8 run: | # stop the build if there are Python syntax errors or undefined names - flake8 FABulous/fabric_generator/ --count --select=E9,F63,F7,F82 --show-source --statistics + flake8 FABulous/**/*.py --count --select=E9,F63,F7,F82 --show-source --statistics # exit-zero treats all errors as warnings. The GitHub editor is 127 chars wide - flake8 FABulous/fabric_generator --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics + flake8 FABulous/**/*.py --count --exit-zero --max-complexity=10 --max-line-length=127 --statistics + - name: Install FABulous + run: | + pip3 install -e . - name: Run fabric generator flow run: | - export FAB_ROOT=. - python3.9 FABulous/FABulous.py -c demo - python3.9 FABulous/FABulous.py demo --script ./demo/FABulous.tcl - + FABulous -c demo + FABulous demo --script ./demo/FABulous.tcl - name: Run simulation smoketest run: | cd ./demo/Test diff --git a/.gitignore b/.gitignore index 47872020..9e824d6f 100755 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ demo/ +*.egg-info/ +__pycache__/ diff --git a/FABulous/FABulous.py b/FABulous/FABulous.py index 700261e4..7e86f290 100644 --- a/FABulous/FABulous.py +++ b/FABulous/FABulous.py @@ -33,15 +33,16 @@ from typing import List, Literal import docker -import fabric_generator.code_generator as codeGen -import fabric_generator.file_parser as fileParser -import fabric_generator.model_generation_npnr as model_gen_npnr -import fabric_generator.model_generation_vpr as model_gen_vpr -from fabric_generator.code_generation_Verilog import VerilogWriter -from fabric_generator.code_generation_VHDL import VHDLWriter -from fabric_generator.fabric import Fabric -from fabric_generator.fabric_gen import FabricGenerator -from fabric_generator.utilities import GetFabric, genFabricObject + +from FABulous.fabric_generator import code_generator as codeGen +from FABulous.fabric_generator import file_parser as fileParser +from FABulous.fabric_generator import model_generation_npnr as model_gen_npnr +from FABulous.fabric_generator import model_generation_vpr as model_gen_vpr +from FABulous.fabric_generator.code_generation_Verilog import VerilogWriter +from FABulous.fabric_generator.code_generation_VHDL import VHDLWriter +from FABulous.fabric_generator.fabric import Fabric +from FABulous.fabric_generator.fabric_gen import FabricGenerator +from FABulous.fabric_generator.utilities import GetFabric, genFabricObject readline.set_completer_delims(' \t\n') diff --git a/FABulous/fabric_cad/__init__.py b/FABulous/fabric_cad/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/FABulous/fabric_cad/bit_gen.py b/FABulous/fabric_cad/bit_gen.py index 24e54a11..f558b603 100644 --- a/FABulous/fabric_cad/bit_gen.py +++ b/FABulous/fabric_cad/bit_gen.py @@ -1,21 +1,17 @@ -# Python 3 -from array import array +#!/usr/bin/env python + +import pickle import re import sys -from contextlib import redirect_stdout -from io import StringIO -import math -import os -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))) 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') @@ -52,7 +48,7 @@ def genBitstream(fasmFile: str, specFile: str, bitstreamFile: str): 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]: @@ -106,7 +102,6 @@ def genBitstream(fasmFile: str, specFile: str, bitstreamFile: str): tileKey = f"X{x}Y{y}" curStr = ",".join((tileKey, specDict["TileMap"][tileKey], str(x), str(y))) curStr += "\n" - bitPos = 0 for frameIndex in range(MaxFramesPerCol): #print (tileDict[tileKey]) #:FrameBitsPerRow*frameIndex @@ -137,9 +132,9 @@ def genBitstream(fasmFile: str, specFile: str, bitstreamFile: str): 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 + #Tile Loc, Tile Type, X, Y, bits...... \n #Each line is one tile print(outStr, file = open(bitstreamFile.replace("bin","fasm"), "w+")) print(verilog_str, file = open(bitstreamFile.replace("bin","vh"), "w+")) @@ -152,7 +147,7 @@ def genBitstream(fasmFile: str, specFile: str, bitstreamFile: str): class Tile: tileType = "" bels = [] - wires = [] + wires = [] atomicWires = [] #For storing single wires (to handle cascading and termination) pips = [] belPorts = set() @@ -162,7 +157,7 @@ class Tile: x = -1 #Init with negative values to ease debugging y = -1 - + def __init__(self, inType): self.tileType = inType @@ -214,39 +209,41 @@ def getTileAndWireByWireDest(self, loc: str, dest: str, jumps: bool = True): return (tile, wire, i) return None - + ##################################################################################### # Main ##################################################################################### -#Strip arguments -caseProcessedArguments = list(map(lambda x: x.strip(), sys.argv)) -processedArguments = list(map(lambda x: x.lower(), caseProcessedArguments)) -flagRE = re.compile("-\S*") +def bit_gen(): + #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 ('-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 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] + FasmFileName = caseProcessedArguments[argIndex + 1] + SpecFileName = caseProcessedArguments[argIndex + 2] + OutFileName = caseProcessedArguments[argIndex + 3] - genBitstream(FasmFileName, SpecFileName, OutFileName) + 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') +if __name__ == "__main__": + bit_gen() diff --git a/FABulous/fabric_generator/code_generation_VHDL.py b/FABulous/fabric_generator/code_generation_VHDL.py index 87a1fdf0..034ee874 100644 --- a/FABulous/fabric_generator/code_generation_VHDL.py +++ b/FABulous/fabric_generator/code_generation_VHDL.py @@ -1,11 +1,8 @@ -from typing import Literal, Tuple -import os import math import re -from fabric_generator.fabric import Fabric, Tile, Port, Bel, IO -from fabric_generator.code_generator import codeGenerator -from fabric_generator.fabric import ConfigBitMode +from FABulous.fabric_generator.code_generator import codeGenerator +from FABulous.fabric_generator.fabric import IO class VHDLWriter(codeGenerator): diff --git a/FABulous/fabric_generator/code_generation_Verilog.py b/FABulous/fabric_generator/code_generation_Verilog.py index 1c3c5530..cd723747 100644 --- a/FABulous/fabric_generator/code_generation_Verilog.py +++ b/FABulous/fabric_generator/code_generation_Verilog.py @@ -1,9 +1,8 @@ -from typing import Literal import math import re -from fabric_generator.fabric import Tile, Bel, ConfigBitMode, IO -from fabric_generator.code_generator import codeGenerator +from FABulous.fabric_generator.code_generator import codeGenerator +from FABulous.fabric_generator.fabric import IO class VerilogWriter(codeGenerator): diff --git a/FABulous/fabric_generator/code_generator.py b/FABulous/fabric_generator/code_generator.py index ffe185f9..bd09858d 100644 --- a/FABulous/fabric_generator/code_generator.py +++ b/FABulous/fabric_generator/code_generator.py @@ -1,6 +1,7 @@ import abc from typing import List, Tuple -from fabric_generator.fabric import Bel, IO, ConfigBitMode + +from FABulous.fabric_generator.fabric import IO class codeGenerator(abc.ABC): @@ -87,7 +88,7 @@ def addHeaderEnd(self, name: str, indentLevel=0): Add end to header. Only useful with VHDL. Examples : - | Verilog: + | Verilog: | VHDL: end entity **name**; Args: @@ -136,7 +137,7 @@ def addParameter(self, name: str, type, value, indentLevel=0): Args: name (str): name of the parameter type (_type_): type of the parameter. Only useful with VHDL. - value (_type_): value of the parameter. + value (_type_): value of the parameter. indentLevel (int, optional): The indentation Level. Defaults to 0. """ pass @@ -221,7 +222,7 @@ def addDesignDescriptionStart(self, name: str, indentLevel=0): @abc.abstractmethod def addDesignDescriptionEnd(self, indentLevel=0): """ - Add end of design description. + Add end of design description. Examples : | Verilog: endmodule @@ -274,7 +275,7 @@ def addConnectionVector(self, name: str, startIndex, endIndex=0, indentLevel=0): Args: name (str): name of the connection - startIndex : Start index of the vector. Can be a string. + startIndex : Start index of the vector. Can be a string. endIndex (int, optional): End index of the vector. Can be a string. Defaults to 0. indentLevel (int, optional): The indentation Level. Defaults to 0. """ @@ -286,7 +287,7 @@ def addLogicStart(self, indentLevel=0): Add start of logic. Only useful with VHDL. Examples : - | Verilog: + | Verilog: | VHDL: begin Args: @@ -319,7 +320,7 @@ def addInstantiation(self, compName: str, compInsName: str, portsPairs: List[Tup | . **paramPorts[1]** (**paramSignals[1]**), | ... | . **paramPorts[n]** (**paramSignals[n]**) - | ) ( + | ) ( | . **compPorts[0]** (**signals[0]**), | . **compPorts[1]** (**signals[1]**), | ... @@ -391,9 +392,9 @@ def addFlipFlopChain(self, configBits: int, indentLevel=0): @abc.abstractmethod def addAssignScalar(self, left, right, delay=0, indentLevel=0): """ - Add a scalar assign statement. Delay is provided by currently not being used by any of the code generator. - If **right** is a list, it will be concatenated. - Verilog will be concatenated with comma ','. + Add a scalar assign statement. Delay is provided by currently not being used by any of the code generator. + If **right** is a list, it will be concatenated. + Verilog will be concatenated with comma ','. VHDL will be concatenated with ampersand '&'. Examples : diff --git a/FABulous/fabric_generator/fabric_gen.py b/FABulous/fabric_generator/fabric_gen.py index e96955dd..734e2507 100644 --- a/FABulous/fabric_generator/fabric_gen.py +++ b/FABulous/fabric_generator/fabric_gen.py @@ -16,24 +16,24 @@ # SPDX-License-Identifier: Apache-2.0 -import re +import csv +import logging import math import os +import re import string -import csv from typing import Dict, List, Tuple -import logging - from fasm import * # Remove this line if you do not have the fasm library installed and will not be generating a bitstream - -from fabric_generator.file_parser import parseMatrix, parseConfigMem, parseList -from fabric_generator.fabric import IO, Direction, MultiplexerStyle, ConfigBitMode -from fabric_generator.fabric import Fabric, Tile, Port, SuperTile, ConfigMem -from fabric_generator.code_generation_VHDL import VHDLWriter -from fabric_generator.code_generation_Verilog import VerilogWriter -from fabric_generator.code_generator import codeGenerator +from FABulous.fabric_generator.code_generation_Verilog import VerilogWriter +from FABulous.fabric_generator.code_generation_VHDL import VHDLWriter +from FABulous.fabric_generator.code_generator import codeGenerator +from FABulous.fabric_generator.fabric import (IO, ConfigBitMode, ConfigMem, Direction, + Fabric, MultiplexerStyle, Port, + SuperTile, Tile) +from FABulous.fabric_generator.file_parser import (parseConfigMem, parseList, + parseMatrix) SWITCH_MATRIX_DEBUG_SIGNAL = True logger = logging.getLogger(__name__) @@ -1763,7 +1763,7 @@ def split_port(p): self.writer.addComment( "External IO port", onNewLine=True, indentLevel=2) - for name, group in sorted(portGroups.items(), key=lambda x:x[0]): + for name, group in sorted(portGroups.items(), key=lambda x:x[0]): if self.fabric.numberOfBRAMs > 0 and ("RAM2FAB" in name or "FAB2RAM" in name): continue self.writer.addPortVector(name, group[0], len(group[1])-1, indentLevel=2) diff --git a/FABulous/fabric_generator/fabulous_top_wrapper_temp/top_wrapper_generator.py b/FABulous/fabric_generator/fabulous_top_wrapper_temp/top_wrapper_generator.py index da293354..95a13b72 100644 --- a/FABulous/fabric_generator/fabulous_top_wrapper_temp/top_wrapper_generator.py +++ b/FABulous/fabric_generator/fabulous_top_wrapper_temp/top_wrapper_generator.py @@ -1,8 +1,8 @@ +import getopt import re +import sys from array import * -import fileinput -import sys, getopt -import csv + def split_port(p): # split a port according to how we want to sort ports: @@ -51,7 +51,7 @@ def main(argv): NumberOfBRAMs = 4; fabric = None - + try: opts, args = getopt.getopt(argv,"hr:c:b:f:d:t:",["NumberOfRows=","NumberOfCols=","FrameBitsPerRow=","MaxFramesPerCol=","desync_flag=","fabric="]) except getopt.GetoptError: @@ -114,14 +114,14 @@ def main(argv): except IOError: print("eFPGA_top_template.v not accessible") sys.exit(1) - + try: with open("fabulous_top_wrapper_temp/Config_template.v", 'r') as file : config_str = file.read() except IOError: print("Config_template.v not accessible") sys.exit(1) - + try: with open("fabulous_top_wrapper_temp/ConfigFSM_template.v", 'r') as file : configfsm_str = file.read() @@ -148,15 +148,15 @@ def main(argv): config_str = config_str.replace("parameter RowSelectWidth = 5", "parameter RowSelectWidth = "+str(RowSelectWidth)) config_str = config_str.replace("parameter FrameBitsPerRow = 32", "parameter FrameBitsPerRow = "+str(FrameBitsPerRow)) #config_str = config_str.replace("parameter desync_flag = 20", "parameter desync_flag = "+str(desync_flag)) - + configfsm_str = configfsm_str.replace("parameter NumberOfRows = 16", "parameter NumberOfRows = "+str(NumberOfRows)) configfsm_str = configfsm_str.replace("parameter RowSelectWidth = 5", "parameter RowSelectWidth = "+str(RowSelectWidth)) configfsm_str = configfsm_str.replace("parameter FrameBitsPerRow = 32", "parameter FrameBitsPerRow = "+str(FrameBitsPerRow)) configfsm_str = configfsm_str.replace("parameter desync_flag = 20", "parameter desync_flag = "+str(desync_flag)) - + for row in range(NumberOfRows): data_reg_module_temp ="" - + data_reg_name = 'Frame_Data_Reg_'+str(row) wrapper_top_str+='\t'+data_reg_name+' Inst_'+data_reg_name+' (\n' wrapper_top_str+='\t.FrameData_I(LocalWriteData),\n' @@ -178,10 +178,10 @@ def main(argv): data_reg_modules += data_reg_module_temp+'\n\n' #with open("verilog_output/"+data_reg_name+".v", 'w') as file: # file.write(data_reg_module_temp) - + for col in range(NumberOfCols): strobe_reg_module_temp ="" - + strobe_reg_name = 'Frame_Select_'+str(col) wrapper_top_str+='\t'+strobe_reg_name+' Inst_'+strobe_reg_name+' (\n' wrapper_top_str+='\t.FrameStrobe_I(FrameAddressRegister[MaxFramesPerCol-1:0]),\n' @@ -216,7 +216,7 @@ def main(argv): wrapper_top_str+='\t.FrameData(FrameData),\n' wrapper_top_str+='\t.FrameStrobe(FrameSelect)\n' wrapper_top_str+='\t);\n\n' - + wrapper_top_str+="\tassign FrameData = {32'h12345678,FrameRegister,32'h12345678};\n\n" wrapper_top_str+='endmodule\n\n' @@ -231,19 +231,19 @@ def main(argv): if strobe_reg_modules: with open("Frame_Select_Pack.v", 'w') as file: file.write(strobe_reg_modules) - + if config_str: with open("Config.v", 'w') as file: file.write(config_str) - + if configfsm_str: with open("ConfigFSM.v", 'w') as file: file.write(configfsm_str) - + #if testbench_str: # with open("tb_bitbang.vhd", 'w') as file: # file.write(testbench_str) - + print("Finish") if __name__ == "__main__": diff --git a/FABulous/fabric_generator/fabulous_top_wrapper_temp/top_wrapper_generator_with_BRAM.py b/FABulous/fabric_generator/fabulous_top_wrapper_temp/top_wrapper_generator_with_BRAM.py index b067cc95..8a1ce52b 100644 --- a/FABulous/fabric_generator/fabulous_top_wrapper_temp/top_wrapper_generator_with_BRAM.py +++ b/FABulous/fabric_generator/fabulous_top_wrapper_temp/top_wrapper_generator_with_BRAM.py @@ -1,11 +1,7 @@ -import re -from array import * -import fileinput -import sys -import getopt -import csv -import os import argparse +import os +import sys +from array import * FABulous_root = os.getenv('FABulous_root') diff --git a/FABulous/fabric_generator/fabulous_top_wrapper_temp/top_wrapper_generator_with_BRAM_vhdl.py b/FABulous/fabric_generator/fabulous_top_wrapper_temp/top_wrapper_generator_with_BRAM_vhdl.py index 609edd92..1307d6f9 100644 --- a/FABulous/fabric_generator/fabulous_top_wrapper_temp/top_wrapper_generator_with_BRAM_vhdl.py +++ b/FABulous/fabric_generator/fabulous_top_wrapper_temp/top_wrapper_generator_with_BRAM_vhdl.py @@ -1,11 +1,7 @@ -import re -from array import * -import fileinput -import sys -import getopt -import csv -import os import argparse +import os +import sys +from array import * FABulous_root = os.getenv('FABulous_root') @@ -281,7 +277,7 @@ def main(): RAM2FAB_D_str += f" Tile_X{NumberOfCols-1}Y{count}_RAM2FAB_D3_I1 => RAM2FAB_D_Readable({i-13}),""\n" RAM2FAB_D_str += f" Tile_X{NumberOfCols-1}Y{count}_RAM2FAB_D3_I2 => RAM2FAB_D_Readable({i-14}),""\n" RAM2FAB_D_str += f" Tile_X{NumberOfCols-1}Y{count}_RAM2FAB_D3_I3 => RAM2FAB_D_Readable({i-15}),""\n" - + FAB2RAM_D_str += f" Tile_X{NumberOfCols-1}Y{count}_FAB2RAM_D0_O0 => FAB2RAM_D({i}),""\n" FAB2RAM_D_str += f" Tile_X{NumberOfCols-1}Y{count}_FAB2RAM_D0_O1 => FAB2RAM_D({i-1}),""\n" FAB2RAM_D_str += f" Tile_X{NumberOfCols-1}Y{count}_FAB2RAM_D0_O2 => FAB2RAM_D({i-2}),""\n" diff --git a/FABulous/fabric_generator/file_parser.py b/FABulous/fabric_generator/file_parser.py index aea8e222..54140290 100644 --- a/FABulous/fabric_generator/file_parser.py +++ b/FABulous/fabric_generator/file_parser.py @@ -1,15 +1,12 @@ +import csv +import os import re from copy import deepcopy from typing import Dict, List, Literal, Tuple, Union, overload -import csv -import os - -from fabric_generator.fabric import Fabric, Port, Bel, Tile, SuperTile, ConfigMem -from fabric_generator.fabric import IO, Direction, Side, MultiplexerStyle, ConfigBitMode - -# from fabric import Fabric, Port, Bel, Tile, SuperTile, ConfigMem -# from fabric import IO, Direction, Side, MultiplexerStyle, ConfigBitMode +from FABulous.fabric_generator.fabric import (IO, Bel, ConfigBitMode, ConfigMem, + Direction, Fabric, MultiplexerStyle, + Port, Side, SuperTile, Tile) oppositeDic = {"NORTH": "SOUTH", "SOUTH": "NORTH", "EAST": "WEST", "WEST": "EAST"} @@ -310,7 +307,7 @@ def parseList(fileName: str, collect: Literal["source", "sink"]) -> Dict[str, Li def parseList(fileName: str, collect: Literal["pair", "source", "sink"] = "pair") -> Union[List[Tuple[str, str]], Dict[str, List[str]]]: """ - parse a list file and expand the list file information into a list of tuples. + parse a list file and expand the list file information into a list of tuples. Args: fileName (str): "" @@ -413,9 +410,9 @@ def parseFileVHDL(filename: str, belPrefix: str = "") -> Tuple[List[Tuple[str, I ValueError: Cannot find the port section in the file which defines the bel ports. Returns: - Tuple[List[Tuple[str, IO]], List[Tuple[str, IO]], List[Tuple[str, IO]], List[Tuple[str, IO]], int, bool, Dict[str, int]]: + Tuple[List[Tuple[str, IO]], List[Tuple[str, IO]], List[Tuple[str, IO]], List[Tuple[str, IO]], int, bool, Dict[str, int]]: Bel internal ports, bel external ports, bel config ports, bel shared ports, number of configuration bit in the bel, - whether the bel have UserCLK, and the bel config bit mapping. + whether the bel have UserCLK, and the bel config bit mapping. """ internal: List[Tuple[str, IO]] = [] external: List[Tuple[str, IO]] = [] @@ -536,7 +533,7 @@ def parseFileVHDL(filename: str, belPrefix: str = "") -> Tuple[List[Tuple[str, I def parseFileVerilog(filename: str, belPrefix: str = "") -> Tuple[List[Tuple[str, IO]], List[Tuple[str, IO]], List[Tuple[str, IO]], List[Tuple[str, IO]], int, bool, Dict[str, Dict]]: """ - Parse a Verilog bel file and return all the related information of the bel. The tuple returned for relating to ports + Parse a Verilog bel file and return all the related information of the bel. The tuple returned for relating to ports will be a list of (belName, IO) pair. The function will also parse and record all the FABulous attribute which all starts with :: @@ -551,26 +548,26 @@ def parseFileVerilog(filename: str, belPrefix: str = "") -> Tuple[List[Tuple[str * **GLOBAL** * **CONFIG_PORT** - The **BelMap** attribute will specify the bel mapping for the bel. This attribute should be placed before the start of + The **BelMap** attribute will specify the bel mapping for the bel. This attribute should be placed before the start of the module The bel mapping is then used for generating the bitstream specification. Each of the entry in the attribute will have the following format:: = ```` is the name of the feature and ```` will be the bit position of the feature. ie. ``INIT=0`` will specify that the feature ``INIT`` is located at bit 0. - Since a single feature can be mapped to multiple bits, this is currently done by specifying multiple entries for the same feature. This will be changed in the future. + Since a single feature can be mapped to multiple bits, this is currently done by specifying multiple entries for the same feature. This will be changed in the future. The bit specification is done in the following way:: INIT_a_1=1, INIT_a_2=2, ... - The name of the feature will be converted to ``INIT_a[1]``, ``INIT_a[2]`` for the above example. This is necessary - because Verilog does not allow square brackets as part of the attribute name. + The name of the feature will be converted to ``INIT_a[1]``, ``INIT_a[2]`` for the above example. This is necessary + because Verilog does not allow square brackets as part of the attribute name. **EXTERNAL** attribute will notify FABulous to put the pin in the top module during the fabric generation. **SHARED_PORT** attribute will notify FABulous this the pin is shared between multiple bels. Attribute need to go with the **EXTERNAL** attribute. - **GLOBAL** attribute will notify FABulous to stop parsing any pin after this attribute. + **GLOBAL** attribute will notify FABulous to stop parsing any pin after this attribute. **CONFIG_PORT** attribute will notify FABulous the port is for configuration. @@ -599,9 +596,9 @@ def parseFileVerilog(filename: str, belPrefix: str = "") -> Tuple[List[Tuple[str ValueError: No permission to access the file Returns: - Tuple[List[Tuple[str, IO]], List[Tuple[str, IO]], List[Tuple[str, IO]], List[Tuple[str, IO]], int, bool, Dict[str, Dict]]: + Tuple[List[Tuple[str, IO]], List[Tuple[str, IO]], List[Tuple[str, IO]], List[Tuple[str, IO]], int, bool, Dict[str, Dict]]: Bel internal ports, bel external ports, bel config ports, bel shared ports, number of configuration bit in the bel, - whether the bel have UserCLK, and the bel config bit mapping. + whether the bel have UserCLK, and the bel config bit mapping. """ internal: List[Tuple[str, IO]] = [] external: List[Tuple[str, IO]] = [] diff --git a/FABulous/fabric_generator/model_generation_npnr.py b/FABulous/fabric_generator/model_generation_npnr.py index 2669ddef..e9d76e31 100644 --- a/FABulous/fabric_generator/model_generation_npnr.py +++ b/FABulous/fabric_generator/model_generation_npnr.py @@ -1,8 +1,9 @@ import string from typing import Tuple -from fabric_generator.utilities import * -from fabric_generator.fabric import Fabric, Tile -from fabric_generator.file_parser import parseMatrix, parseList + +from FABulous.fabric_generator.fabric import Fabric +from FABulous.fabric_generator.file_parser import parseList, parseMatrix +from FABulous.fabric_generator.utilities import * def genNextpnrModel(fabric: Fabric): diff --git a/FABulous/fabric_generator/model_generation_vpr.py b/FABulous/fabric_generator/model_generation_vpr.py index 040d7d09..c645dae1 100644 --- a/FABulous/fabric_generator/model_generation_vpr.py +++ b/FABulous/fabric_generator/model_generation_vpr.py @@ -1,14 +1,13 @@ +import logging import string -from sys import prefix -from typing import List -from fabric_generator.fabric_gen import FabricGenerator -from fabric_generator.utilities import * -from fabric_generator.fabric import IO, Bel, Fabric import xml.etree.ElementTree as ET -import os -from xml.dom import minidom -from fabric_generator.file_parser import parseMatrix, parseList -import logging +from typing import List + +from FABulous.fabric_generator.fabric import Bel, Fabric +from FABulous.fabric_generator.fabric_gen import FabricGenerator +from FABulous.fabric_generator.file_parser import parseMatrix +from FABulous.fabric_generator.utilities import * + logger = logging.getLogger(__name__) @@ -197,9 +196,9 @@ def genVPRModel(fabric: Fabric, customXMLfile: str = "") -> str: continue pbTypeWrapper = ET.SubElement( complexBlockList, "pb_type", name=f"{bel.name}_wrapper") - + if bel.name in allCustomXMLBelName: - element = customXML.find(f".//bel_info[@name='{bel.name}']//pb_type") + element = customXML.find(f".//bel_info[@name='{bel.name}']//pb_type") pbTypeWrapper.append(element) else: pbType = ET.SubElement( @@ -236,7 +235,7 @@ def genVPRModel(fabric: Fabric, customXMLfile: str = "") -> str: name=i.removeprefix(bel.prefix), num_pins="1") ET.SubElement(interConnect, "direct", name=f"{bel.name}_{i.removeprefix(bel.prefix)}_child_to_top", input=f"{bel.name}.{i.removeprefix(bel.prefix)}", output=f"{bel.name}_wrapper.{i.removeprefix(bel.prefix)}") - + # switch list block switchList = ET.SubElement(root, "switchlist") diff --git a/pyproject.toml b/pyproject.toml index b4f1b18b..272d830b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,8 +1,44 @@ [build-system] -requires = ["flit_core >=3.2,<4"] -build-backend = "flit_core.buildapi" +requires = ["setuptools>=45", "setuptools_scm[toml]>=6.2"] +build-backend = "setuptools.build_meta" [project] -name = "FABulous Documentation" +name = "FABulous-FPGA" authors = [{name = "Jing, Nguyen, Bea, Bardia, Dirk", email = "dirk.koch@manchester.ac.uk"}] -dynamic = ["version", "description"] +description = "FABulous FPGA Fabric generator" +readme = "README.md" +requires-python = ">=3.9" +dynamic = ["version"] + +classifiers = [ + "Programming Language :: Python :: 3", + "License :: OSI Approved :: Apache Software License", + "Operating System :: OS Independent", +] + + +dependencies = [ + 'numpy', + 'fasm', + 'docker', +] + +[project.urls] +"Homepage" = "https://github.com/FPGA-Research-Manchester/FABulous" +"Bug Tracker" = "https://github.com/FPGA-Research-Manchester/FABulous/issues" + + +[project.scripts] +FABulous = "FABulous.FABulous:main" +bit_gen = "FABulous.fabric_cad.bit_gen:bit_gen" + +[tool.setuptools_scm] +version_scheme = "post-release" +local_scheme = "dirty-tag" + + +[tool.setuptools.packages.find] +exclude = ["docs, demo"] # exclude packages matching these glob patterns (empty by default) + +[tool.setuptools.package-data] +mypkg = ["FABulous/**/*"]