edalize icon indicating copy to clipboard operation
edalize copied to clipboard

Adding IP Generation to the Efinity flow.

Open RiceShelley opened this issue 10 months ago • 2 comments

Hello, I'm looking to upstream / get some guidance on adding Efinity IP generation support to Edalize. I needed this feature for a project I am working on and quickly hacked something together. Feels like this could be done in a cleaner way so I am very open to suggestions.

I am using Efinity version 2023.2 because the python IP generation was broken until 2023.1.150.4: image

Here is the relevant documentation on generating IP with the Efinity python interface: Efinity python API docs

Here is an example usage from my project:

import os
from edalize.flows.efinity import Efinity

# Verilog files generated by spinalHDL
spinal_verilog_files = list(
    map(
        lambda file: {
            "name": file,
            "file_type": "verilogSource",
        },
        ["my_generated_spinal_verilog_file.v"],
    )
)
verilog_files = spinal_verilog_files

# Efinity interface designer file
isf = list(
    map(
        lambda file: {
            "name": "../../src/edalize/ti60f100/" + file,
            "file_type": "ISF",
        },
        ["my_efinity_io.isf"],
    )
)

# Synopsys Design Constraint files
constraint_files = list(
    map(
        lambda file: {"name": "../../src/edalize/ti60f100/" + file, "file_type": "SDC"},
        ["const.sdc"],
    )
)

# Use efinity toolchain
tool = "efinity"

# FPGA used for project
fpga_family = "Titanium"
part = "Ti60F100S3F2"
timing_model = "C4"

project_name = "MyProjectName"
top_level = "MyTopLevel"
work_root = "../../../hw/gen"

# Configuration for Efinity HyperRAM IP
hyper_ram_ip = {
    "module_name": "hyper_ram",
    "vendor": "efinixinc.com",
    "library": "memory_controller",
    "name": "efx_hyper_ram",
    "config": {
        "RAM_DBW": "16",
        "RAM_ABW": "25",
        "CR0_DPD": "1'b1",
        "CR0_ILC": "2",
        "CR0_ODS": "0",
        "CR0_HBE": "1'b1",
        "CR0_WBL": "3",
        "CR1_MCT": "1'b1",
        "CR1_PAR": "0",
        "CR1_HSE": "1'b0",
        "AXI_DBW_2": "128",
        "DDIN_MODE": "1'b0",
        "AXI_AWR_DEPTH": "16",
        "AXI_R_DEPTH_2": "256",
        "AXI_W_DEPTH_2": "256",
        "RDO_DELAY": "3",
        "CAL_CLK_CH": "4",
        "CAL_MODE": "2",
        "MHZ": "200",
        "AXI_IF": "1'b0",
        "NATIVE_DBW": "32",
        "NATIVE_R_DEPTH": "512",
        "NATIVE_W_DEPTH": "512",
    },
}

# Efinity tool flow options
tool_options = {
    "family": fpga_family,
    "part": part,
    "timing": timing_model,
    "ip_gen": [hyper_ram_ip],
}

# Design files
files = [*verilog_files, *isf, *constraint_files]

# Edalize edam
edam = {
    "files": files,
    "name": project_name,
    "toplevel": top_level,
    "flow_options": tool_options,
}

# Start Efinity toolchain
efinity = Efinity(edam=edam, work_root=work_root, verbose=False)

# Make directory for project
os.makedirs(name=work_root, exist_ok=True)

# Configure project
efinity.configure()
# Generate bit stream
efinity.build()

RiceShelley avatar Apr 02 '24 16:04 RiceShelley

Howdy, just popping in here since I have a commit on this MR: In the course of bringing up our board, we realized that there wasn't support for passive mode, or generating the 'hex bin' files required to do passive programming over SPI. My change set is relatively minor and enables the user to specify what formats they require:


# Efinity tool flow options
tool_options = {
    "family": fpga_family,
    "part": part,
    "timing": timing_model,
    "ip_gen": [hyper_ram_ip],
    "pgm_opts": ["passive"],
    "bitstream_gen": {
        "mode": "passive",
        "formats": ["bit", "hex", "hexbin"],
        "clk_div": "DIV1",
    },
}

Jeff-Ciesielski avatar May 09 '24 19:05 Jeff-Ciesielski

Thanks for this. The patch looks nice and clean and I presume it solves your problems. I have some philosophical objections to some of the design choices, but the Efinity API is such a complete disaster so I'm not sure there's much we can do.

I will need an update to the test suite first though before merging this. Typically, run tox from the repo root to try it locally (or pytest -k <testcase> to just run a specific test). Set the GOLDEN_RUN env var to get some help with updating the expected values. More about this here https://edalize.readthedocs.io/en/latest/dev/tests.html

olofk avatar May 26 '24 08:05 olofk