From caee8908157b57f6ce480f4728a5af794db56c5b Mon Sep 17 00:00:00 2001 From: Riley Wilton Date: Mon, 5 Aug 2024 20:21:09 -0400 Subject: [PATCH 1/7] Working on gowin fpga support --- apio/resources/boards.json | 7 +++++++ apio/resources/fpgas.json | 8 +++++++- apio/resources/gowin/SConstruct | 0 apio/resources/programmers.json | 4 ++++ check/apio.ini | 4 ++++ check/blink.pcf | 1 + check/blink.v | 17 +++++++++++++++++ 7 files changed, 40 insertions(+), 1 deletion(-) create mode 100644 apio/resources/gowin/SConstruct create mode 100644 check/apio.ini create mode 100644 check/blink.pcf create mode 100644 check/blink.v diff --git a/apio/resources/boards.json b/apio/resources/boards.json index 4fb9237d..ab9189af 100644 --- a/apio/resources/boards.json +++ b/apio/resources/boards.json @@ -788,5 +788,12 @@ "ftdi": { "desc": "ETH4K" } + }, + "Sipeed-Tang-Primer-25k": { + "name":"Sipeed Tang Primer 25k", + "fpga": "GW5A-LV25MG121", + "programmer": { + "type": "openfpgaloader_tangprimer25k" + } } } diff --git a/apio/resources/fpgas.json b/apio/resources/fpgas.json index c9d9c39e..0ec475ca 100644 --- a/apio/resources/fpgas.json +++ b/apio/resources/fpgas.json @@ -397,5 +397,11 @@ "type": "um5g-85k", "size": "85k", "pack": "CSFBGA285" - } + }, + "GW5A-LV25MG121": { + "arch": "gowin", + "type": "gw5a", + "size": "25k", + "pack": "MG121N" + } } diff --git a/apio/resources/gowin/SConstruct b/apio/resources/gowin/SConstruct new file mode 100644 index 00000000..e69de29b diff --git a/apio/resources/programmers.json b/apio/resources/programmers.json index 6a99920d..980abf16 100644 --- a/apio/resources/programmers.json +++ b/apio/resources/programmers.json @@ -73,5 +73,9 @@ "openfpgaloader_usb-blaster": { "command": "openFPGALoader", "args": "-c usb-blaster -v --file-type bin" + }, + "openfpgaloader_tangprimer25k": { + "command": "openFPGALoader", + "args": "-b tangprimer25k -c usb-blaster -v --file-type bin" } } diff --git a/check/apio.ini b/check/apio.ini new file mode 100644 index 00000000..1eb566eb --- /dev/null +++ b/check/apio.ini @@ -0,0 +1,4 @@ +[env] +board = Sipeed-Tang-Primer-25k +top-module = main + diff --git a/check/blink.pcf b/check/blink.pcf new file mode 100644 index 00000000..fba59953 --- /dev/null +++ b/check/blink.pcf @@ -0,0 +1 @@ +set_io LED A11 \ No newline at end of file diff --git a/check/blink.v b/check/blink.v new file mode 100644 index 00000000..2556bab2 --- /dev/null +++ b/check/blink.v @@ -0,0 +1,17 @@ + +module main ( + input CLK, + output LED, +); + +//-- Modify this value for changing the blink frequency +localparam N = 22; //-- N<=21 Fast, N>=23 Slow + +reg +always @(posedge CLK) + r_LED_state <= !r_LED_state; + +assign PMOD1 = r_LED_state; +assign PMOD2 = r_LED_state2; + +endmodule From 34960f856c325d3fb6e19a9cfc66368a0e435f93 Mon Sep 17 00:00:00 2001 From: Riley Wilton Date: Mon, 5 Aug 2024 23:27:58 -0400 Subject: [PATCH 2/7] Tring to get gowin boards working. --- apio/resources/boards.json | 12 +- apio/resources/distribution.json | 3 +- apio/resources/fpgas.json | 8 +- apio/resources/gowin/SConstruct | 368 +++++++++++++++++++++++++++++++ apio/resources/packages.json | 4 +- apio/resources/programmers.json | 4 +- check/apio.ini | 2 +- check/blink.pcf | 3 +- check/blink.v | 9 +- 9 files changed, 393 insertions(+), 20 deletions(-) diff --git a/apio/resources/boards.json b/apio/resources/boards.json index ab9189af..1e3a2f4f 100644 --- a/apio/resources/boards.json +++ b/apio/resources/boards.json @@ -789,11 +789,15 @@ "desc": "ETH4K" } }, - "Sipeed-Tang-Primer-25k": { - "name":"Sipeed Tang Primer 25k", - "fpga": "GW5A-LV25MG121", + "Sipeed-Tang-Nano-20k": { + "name":"Sipeed Tang Nano 20k", + "fpga": "GW2AR-LV18QN88C8/I7", "programmer": { - "type": "openfpgaloader_tangprimer25k" + "type": "openfpgaloader_tangnano20k" + }, + "usb": { + "vid": "0403", + "pid": "6010" } } } diff --git a/apio/resources/distribution.json b/apio/resources/distribution.json index d3a46ae2..1dcad16a 100644 --- a/apio/resources/distribution.json +++ b/apio/resources/distribution.json @@ -10,6 +10,7 @@ "litterbox": ">=0.2.1,<0.3.0", "tinyfpgab": ">=1.1.0,<1.2.0", "tinyprog": ">=1.0.21,<1.1.0", - "icefunprog": ">=2.0.3,<3.0.0" + "icefunprog": ">=2.0.3,<3.0.0", + "apycula": "0.12" } } diff --git a/apio/resources/fpgas.json b/apio/resources/fpgas.json index 0ec475ca..023d1a3a 100644 --- a/apio/resources/fpgas.json +++ b/apio/resources/fpgas.json @@ -398,10 +398,10 @@ "size": "85k", "pack": "CSFBGA285" }, - "GW5A-LV25MG121": { + "GW2AR-LV18QN88C8/I7": { "arch": "gowin", - "type": "gw5a", - "size": "25k", - "pack": "MG121N" + "type": "gw2ar", + "size": "20k", + "pack": "QN88" } } diff --git a/apio/resources/gowin/SConstruct b/apio/resources/gowin/SConstruct index e69de29b..dc013da1 100644 --- a/apio/resources/gowin/SConstruct +++ b/apio/resources/gowin/SConstruct @@ -0,0 +1,368 @@ +# -*- coding: utf-8 -*- +# ---------------------------------------------------------------------- +# -- Generic Scons script for Sintesizing hardware on an FPGA and more. +# -- This file is part of the Apio project +# -- (C) 2016-2019 FPGAwars +# -- Authors Riley Wilton, Juan Gonzáles, Jesús Arroyo +# -- Licence GPLv2 +# ---------------------------------------------------------------------- + +import os +import re +from platform import system + +from SCons.Script import (Builder, DefaultEnvironment, Default, AlwaysBuild, + GetOption, Exit, COMMAND_LINE_TARGETS, ARGUMENTS, + Variables, Help, Glob) + +# -- Load arguments +PROG = ARGUMENTS.get('prog', '') +FPGA_SIZE = ARGUMENTS.get('fpga_size', '') +FPGA_TYPE = ARGUMENTS.get('fpga_type', '') +FPGA_PACK = ARGUMENTS.get('fpga_pack', '') +YOSYS_TOP = ARGUMENTS.get('top_module', '') +VERBOSE_ALL = ARGUMENTS.get('verbose_all', False) +VERBOSE_YOSYS = ARGUMENTS.get('verbose_yosys', False) +VERBOSE_PNR = ARGUMENTS.get('verbose_pnr', False) +TESTBENCH = ARGUMENTS.get('testbench', '') +VERILATOR_ALL = ARGUMENTS.get('all', False) +VERILATOR_NO_STYLE = ARGUMENTS.get('nostyle', False) +VERILATOR_NO_WARN = ARGUMENTS.get('nowarn', '').split(',') +VERILATOR_WARN = ARGUMENTS.get('warn', '').split(',') +VERILATOR_TOP = ARGUMENTS.get('top', '') +VERILATOR_PARAM_STR = '' +for warn in VERILATOR_NO_WARN: + if warn != '': + VERILATOR_PARAM_STR += ' -Wno-' + warn + +for warn in VERILATOR_WARN: + if warn != '': + VERILATOR_PARAM_STR += ' -Wwarn-' + warn + +# Update FPGA_TYPE to a less readable version supported +# by apicula. +if FPGA_TYPE == "gw2ar" and FPGA_SIZE == "20k": + FPGA_TYPE = "GW2AR-LV18QN88C8/I7" + FPGA_TYPE_PACK = "GW2AR-18" + FPGA_FAMILY = "GW2A-18C" + +# -- Size. Possible values: 20k +# -- Type. Possible values: gw2ar +# -- Package. Unused. + +# -- Add the FPGA flags as variables to be shown with the -h scons option +vars = Variables() +vars.Add('fpga_size', 'Set the Gowin FPGA size (25k)', FPGA_SIZE) +vars.Add('fpga_type', 'Set the Gowin FPGA type (gw5a)', FPGA_TYPE) +vars.Add('fpga_pack', 'Set the Gowin FPGA packages', FPGA_PACK) + +# -- Create environment +env = DefaultEnvironment(ENV=os.environ, + tools=[], + variables=vars) + +# -- Show all the flags defined, when scons is invoked with -h +Help(vars.GenerateHelpText(env)) + +# -- Just for debugging +if 'build' in COMMAND_LINE_TARGETS or \ + 'upload' in COMMAND_LINE_TARGETS or \ + 'time' in COMMAND_LINE_TARGETS: + + # print('FPGA_SIZE: {}'.format(FPGA_SIZE)) + # print('FPGA_TYPE: {}'.format(FPGA_TYPE)) + # print('FPGA_PACK: {}'.format(FPGA_PACK)) + + if 'upload' in COMMAND_LINE_TARGETS: + + if PROG == '': + print('Error: no programmer command found') + Exit(1) + + # print('PROG: {}'.format(PROG)) + +# -- Resources paths +IVL_PATH = os.environ['IVL'] if 'IVL' in os.environ else '' +ICEBOX_PATH = os.environ['ICEBOX'] if 'ICEBOX' in os.environ else '' +CHIPDB_PATH = os.path.join(ICEBOX_PATH, 'chipdb-{0}.txt'.format(FPGA_SIZE)) +YOSYS_PATH = os.environ['YOSYS_LIB'] if 'YOSYS_LIB' in os.environ else '' + +isWindows = 'Windows' == system() +VVP_PATH = '' if isWindows or not IVL_PATH else '-M "{0}"'.format(IVL_PATH) +IVER_PATH = '' if isWindows or not IVL_PATH else '-B "{0}"'.format(IVL_PATH) + +# -- Target name +TARGET = 'hardware' + +# -- Scan required .list files +list_files_re = re.compile(r'[\n|\s][^\/]?\"(.*\.list?)\"', re.M) + + +def list_files_scan(node, env, path): + contents = node.get_text_contents() + includes = list_files_re.findall(contents) + return env.File(includes) + + +list_scanner = env.Scanner(function=list_files_scan) + +# -- Get a list of all the verilog files in the src folfer, in ASCII, with +# -- the full path. All these files are used for the simulation +v_nodes = Glob('*.v') +v_files = [str(f) for f in v_nodes] + +# Construct disjoint lists of .v module and testbench files. +src_synth = [f for f in v_files if f[-5:].upper() != '_TB.V'] +list_tb = [f for f in v_files if f[-5:].upper() == '_TB.V'] + +if len(src_synth) == 0: + print('Error: no verilog module files found (.v)') + Exit(1) + +# -- Get the PCF file +PCF = '' +PCF_list = Glob('*.pcf') + +try: + PCF = PCF_list[0] +except IndexError: + print('\n---> WARNING: no PCF file found (.pcf)\n') + +# -- Debug +# print('PCF Found: {}'.format(PCF)) + +# -- Synthesizing Builder +synth_builder = Builder( + action='yosys -p \"synth_gowin {0} -json $TARGET\" {1} $SOURCES'.format( + ('-top '+YOSYS_TOP) if YOSYS_TOP else '', + '' if VERBOSE_ALL or VERBOSE_YOSYS else '-q' + ), + suffix='.json', + src_suffix='.v', + source_scanner=list_scanner) +env.Append(BUILDERS={'Synth': synth_builder}) + +# -- Place and route Builder. +pnr_builder = Builder( + action='nextpnr-himbaechel --device {0} --json $SOURCE --write $TARGET --vopt family={5} --vopt cst={3} {4}'.format( + FPGA_TYPE, FPGA_SIZE, FPGA_PACK, PCF, + '' if VERBOSE_ALL or VERBOSE_PNR else '-q', FPGA_FAMILY), + suffix='.pack', + src_suffix='.json') +env.Append(BUILDERS={'PnR': pnr_builder}) + +# -- Bitstream Builder. +bitstream_builder = Builder( + action='gowin_pack -d {0} -o $TARGET $SOURCE'.format(FPGA_TYPE_PACK), + suffix='.bin', + src_suffix='.pack') +env.Append(BUILDERS={'Bin': bitstream_builder}) + +# -- Time report builder +# https://github.com/cliffordwolf/icestorm/issues/57 +time_rpt_builder = Builder( + action='echo No timme analysis report implemented for Gowin devices $TARGET $SOURCE > $TARGET', + suffix='.rpt', + src_suffix='.pack') +env.Append(BUILDERS={'Time': time_rpt_builder}) + +# -- Generate the bitstream +blif_target = env.Synth(TARGET, [src_synth]) +asc_target = env.PnR(TARGET, [blif_target, PCF]) +bitstream_target = env.Bin(TARGET, asc_target) + +build_target = env.Alias('build', bitstream_target) +AlwaysBuild(build_target) + +if(VERBOSE_ALL or VERBOSE_YOSYS): + AlwaysBuild(blif_target) +if(VERBOSE_ALL or VERBOSE_PNR): + AlwaysBuild(asc_target) + +# -- Upload the bitstream into FPGA +upload_target = env.Alias('upload', bitstream_target, '{0} $SOURCE'.format(PROG)) +AlwaysBuild(upload_target) + +# -- Target time: calculate the time +rpt_target = env.Time(asc_target) +AlwaysBuild(rpt_target) +time_target = env.Alias('time', rpt_target) + +# -- Icarus Verilog builders + +def iverilog_generator(source, target, env, for_signature): + """Constructs dynamically a commands for iverlog targets builders. """ + target_name, _ = os.path.splitext(str(target[0])) # E.g. "my_module" or"my_module_tb" + # Testbenches use the value macro VCD_OUTPUT to know the name of the waves output file. + # We also pass a dummy when the verify command to avoid a warning about the undefined macro. + is_testbench = target_name.upper().endswith("_TB") + is_verify = 'verify' in COMMAND_LINE_TARGETS + vcd_output_flag = ( + f'-D VCD_OUTPUT=dummy_vcd_output' if is_verify + else f'-D VCD_OUTPUT={target_name}' if is_testbench + else "") + # If running a testbench with the sim command, we define the macro INTERACTIVE_SIM that + # allows the testbench to supress assertions so we can examine the waves in gtkwave. + # For example, with an assertion macro like this one that fails when running apio test. + # `define EXPECT(signal, value) \ + # if (signal !== value) begin \ + # $display("ASSERTION FAILED in %m: signal != value"); \ + # `ifndef INTERACTIVE_SIM \ + # $fatal; \ + # `endif \ + # end + is_interactive_sim = is_testbench and 'sim' in COMMAND_LINE_TARGETS + interactive_sim_flag = f'-D INTERACTIVE_SIM' if is_interactive_sim else "" + result = 'iverilog {0} -o $TARGET {1} {2} -D NO_ICE40_DEFAULT_ASSIGNMENTS "{3}/ice40/cells_sim.v" $SOURCES'.format( + IVER_PATH, vcd_output_flag, interactive_sim_flag, YOSYS_PATH) + return result + +iverilog_builder = Builder( + # Action string is computed automatically by the generator. + generator = iverilog_generator, + suffix='.out', + src_suffix='.v', + source_scanner=list_scanner) +env.Append(BUILDERS={'IVerilog': iverilog_builder}) + +dot_builder = Builder( + action='yosys -f verilog -p \"show -format dot -colors 1 -prefix hardware {0}\" {1} $SOURCES'.format( + YOSYS_TOP if YOSYS_TOP else 'unknown_top', + '' if VERBOSE_ALL else '-q' + ), + suffix='.dot', + src_suffix='.v', + source_scanner=list_scanner) +env.Append(BUILDERS={'DOT': dot_builder}) + +svg_builder = Builder( + # Expecting graphviz dot to be installed and in the path. + action='dot -Tsvg $SOURCES -o $TARGET', + suffix='.svg', + src_suffix='.dot', + source_scanner=list_scanner) +env.Append(BUILDERS={'SVG': svg_builder}) + +# NOTE: output file name is defined in the iverilog call using VCD_OUTPUT macro +vcd_builder = Builder( + action='vvp {0} $SOURCE'.format( + VVP_PATH), + suffix='.vcd', + src_suffix='.out') +env.Append(BUILDERS={'VCD': vcd_builder}) + +# --- Verify +vout_target = env.IVerilog(TARGET, src_synth + list_tb) +AlwaysBuild(vout_target) +verify_target = env.Alias('verify', vout_target) + +# --- Graph +# TODO: Launch some portable SVG (or differentn format) viewer. +dot_target = env.DOT(TARGET, src_synth) +AlwaysBuild(dot_target) +svg_target = env.SVG(TARGET, dot_target) +AlwaysBuild(svg_target) +graph_target = env.Alias('graph', svg_target) + +# --- Simulation +# Since the simulation targets are dynamic due to the testbench selection, we +# create them only when running simulation. +if 'sim' in COMMAND_LINE_TARGETS: + assert 'test' not in COMMAND_LINE_TARGETS, COMMAND_LINE_TARGETS + if TESTBENCH: + # Explicit testbench file name is given via --testbench. + sim_testbench = TESTBENCH + else: + # No --testbench flag specified. If there is exactly one testbench then pick + # it, otherwise fail. + if len(list_tb) == 0: + print('Error: no testbench found for simulation.') + Exit(1) + if len(list_tb) > 1: + # TODO: consider to allow specifying the default testbench in apio.ini. + print('Error: found {} testbranches, please use the --testbench flag.'.format(len(list_tb))) + for tb in list_tb: + print('- {}'.format(tb)) + Exit(1) + sim_testbench = list_tb[0] # Pick the only available testbench. + # Here sim_testbench contains the testbench, e.g. my_module_tb.v. + # Construct list of files to build. + src_sim = [] + src_sim.extend(src_synth) # All the .v files. + src_sim.append(sim_testbench) + # Create targets sim target and its dependent. + sim_name, _ = os.path.splitext(sim_testbench) #e.g. my_module_tb + sout_target = env.IVerilog(sim_name, src_sim) + vcd_file_target = env.VCD(sout_target) + # 'do_initial_zoom_fit' does max zoom only if .gtkw file not found. + waves_target = env.Alias('sim', vcd_file_target, 'gtkwave {0} {1} {2}.gtkw'.format( + '--rcvar "splash_disable on" --rcvar "do_initial_zoom_fit 1"', + vcd_file_target[0], sim_name)) + AlwaysBuild(waves_target) + + +# --- Testing +# Since the simulation targets are dynamic due to the testbench selection, we +# create them only when running simulation. +if 'test' in COMMAND_LINE_TARGETS: + assert 'sim' not in COMMAND_LINE_TARGETS, COMMAND_LINE_TARGETS + if TESTBENCH: + # Explicit testbench file name is given via --testbench. We test just that one. + test_tbs= [ TESTBENCH ] + else: + # No --testbench flag specified. We will test all them. + if len(list_tb) == 0: + print('Error: no testbenchs found for simulation.') + Exit(1) + test_tbs= list_tb # All testbenches. + tests = [] # Targets of all tests + for test_tb in test_tbs: + # Create a list of source files. All the modules + the current testbench. + src_test = [] + src_test.extend(src_synth) # All the .v files. + src_test.append(test_tb) + # Create the targets for the 'out' and 'vcd' files of the testbench. + # NOTE: Remove the two AlwaysBuild() calls below for an incremental test. Fast, correct, + # but may confuse the user seeing nothing happens. + test_name, _ = os.path.splitext(test_tb) #e.g. my_module_tb + test_out_target = env.IVerilog(test_name, src_test) + AlwaysBuild(test_out_target) + test_vcd_target = env.VCD(test_out_target) + AlwaysBuild(test_vcd_target) + test_target = env.Alias(test_name, [test_out_target, test_vcd_target]) + tests.append(test_target) + # Create a target for the test command that depends on all the test targets. + tests_target = env.Alias('test', tests) + AlwaysBuild(tests_target) + +# -- Verilator builder +verilator_builder = Builder( + action='verilator --lint-only --timing -Wno-TIMESCALEMOD {0} {1} {2} {3} $SOURCES'.format( + '-Wall' if VERILATOR_ALL else '', + '-Wno-style' if VERILATOR_NO_STYLE else '', + VERILATOR_PARAM_STR if VERILATOR_PARAM_STR else '', + '--top-module ' + VERILATOR_TOP if VERILATOR_TOP else ''), + src_suffix='.v', + source_scanner=list_scanner) +env.Append(BUILDERS={'Verilator': verilator_builder}) + +# --- Lint +lint_out_target = env.Verilator(TARGET, src_synth + list_tb) + +lint_target = env.Alias('lint', lint_out_target) +AlwaysBuild(lint_target) + +Default(bitstream_target) + +# -- These is for cleaning the artifact files. +if GetOption('clean'): + # Identify additional files that may not be associated with targets and + # associate them with a target such that they will be cleaned up as well. + # This cleans for example artifacts of past simulation since the testbench + # target are dynamic and changes with the selected testbench. + for glob_pattern in ['*.out', '*.vcd']: + for node in Glob(glob_pattern): + env.Clean(time_target, str(node)) + + env.Default([time_target, build_target, vout_target, graph_target]) + diff --git a/apio/resources/packages.json b/apio/resources/packages.json index 3b8daacf..ad37dea5 100644 --- a/apio/resources/packages.json +++ b/apio/resources/packages.json @@ -18,7 +18,7 @@ "oss-cad-suite": { "repository": { "name": "tools-oss-cad-suite", - "organization": "FPGAwars" + "organization": "wireboy5" }, "release": { "tag_name": "v%V", @@ -26,7 +26,7 @@ "uncompressed_name": "", "package_name": "tools-oss-cad-suite", "extension": "tar.gz", - "url_version": "https://github.com/FPGAwars/tools-oss-cad-suite/raw/main/VERSION_DEV" + "url_version": "https://github.com/wireboy5/tools-oss-cad-suite/raw/main/VERSION_DEV" }, "description": "YosysHQ/oss-cad-suite" }, diff --git a/apio/resources/programmers.json b/apio/resources/programmers.json index 980abf16..cbf24ef3 100644 --- a/apio/resources/programmers.json +++ b/apio/resources/programmers.json @@ -74,8 +74,8 @@ "command": "openFPGALoader", "args": "-c usb-blaster -v --file-type bin" }, - "openfpgaloader_tangprimer25k": { + "openfpgaloader_tangnano20k": { "command": "openFPGALoader", - "args": "-b tangprimer25k -c usb-blaster -v --file-type bin" + "args": "-b tangnano20k" } } diff --git a/check/apio.ini b/check/apio.ini index 1eb566eb..ed2c8044 100644 --- a/check/apio.ini +++ b/check/apio.ini @@ -1,4 +1,4 @@ [env] -board = Sipeed-Tang-Primer-25k +board = Sipeed-Tang-Nano-20k top-module = main diff --git a/check/blink.pcf b/check/blink.pcf index fba59953..5d6ed023 100644 --- a/check/blink.pcf +++ b/check/blink.pcf @@ -1 +1,2 @@ -set_io LED A11 \ No newline at end of file +IO_LOC "LED" 15; +IO_PORT "LED" PULL_MODE=UP DRIVE=8 BANK_VCCIO=1.8 \ No newline at end of file diff --git a/check/blink.v b/check/blink.v index 2556bab2..ac363ae1 100644 --- a/check/blink.v +++ b/check/blink.v @@ -1,17 +1,16 @@ module main ( input CLK, - output LED, + output LED ); //-- Modify this value for changing the blink frequency localparam N = 22; //-- N<=21 Fast, N>=23 Slow -reg +reg [N:0] counter; always @(posedge CLK) - r_LED_state <= !r_LED_state; + counter <= counter + 1; -assign PMOD1 = r_LED_state; -assign PMOD2 = r_LED_state2; +assign LED = counter[N]; endmodule From a8f449b5294043ce62bbe79765565101512c0557 Mon Sep 17 00:00:00 2001 From: Riley Wilton Date: Tue, 6 Aug 2024 10:33:09 -0400 Subject: [PATCH 3/7] Sipeed tang nano 20k working!!! Needs some cleanup. --- apio/resources/gowin/SConstruct | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/apio/resources/gowin/SConstruct b/apio/resources/gowin/SConstruct index dc013da1..f6546105 100644 --- a/apio/resources/gowin/SConstruct +++ b/apio/resources/gowin/SConstruct @@ -41,9 +41,9 @@ for warn in VERILATOR_WARN: # Update FPGA_TYPE to a less readable version supported # by apicula. +FPGA_FAMILY = "" if FPGA_TYPE == "gw2ar" and FPGA_SIZE == "20k": FPGA_TYPE = "GW2AR-LV18QN88C8/I7" - FPGA_TYPE_PACK = "GW2AR-18" FPGA_FAMILY = "GW2A-18C" # -- Size. Possible values: 20k @@ -133,7 +133,7 @@ except IndexError: # -- Synthesizing Builder synth_builder = Builder( - action='yosys -p \"synth_gowin {0} -json $TARGET\" {1} $SOURCES'.format( + action='yosys -D LEDS_NR=6 -p \"synth_gowin {0} -json $TARGET\" {1} $SOURCES'.format( ('-top '+YOSYS_TOP) if YOSYS_TOP else '', '' if VERBOSE_ALL or VERBOSE_YOSYS else '-q' ), @@ -147,15 +147,15 @@ pnr_builder = Builder( action='nextpnr-himbaechel --device {0} --json $SOURCE --write $TARGET --vopt family={5} --vopt cst={3} {4}'.format( FPGA_TYPE, FPGA_SIZE, FPGA_PACK, PCF, '' if VERBOSE_ALL or VERBOSE_PNR else '-q', FPGA_FAMILY), - suffix='.pack', + suffix='.pnr.json', src_suffix='.json') env.Append(BUILDERS={'PnR': pnr_builder}) # -- Bitstream Builder. bitstream_builder = Builder( - action='gowin_pack -d {0} -o $TARGET $SOURCE'.format(FPGA_TYPE_PACK), - suffix='.bin', - src_suffix='.pack') + action='gowin_pack -d {0} -o $TARGET $SOURCE'.format(FPGA_FAMILY), + suffix='.fs', + src_suffix='.pnr.json') env.Append(BUILDERS={'Bin': bitstream_builder}) # -- Time report builder @@ -163,7 +163,7 @@ env.Append(BUILDERS={'Bin': bitstream_builder}) time_rpt_builder = Builder( action='echo No timme analysis report implemented for Gowin devices $TARGET $SOURCE > $TARGET', suffix='.rpt', - src_suffix='.pack') + src_suffix='.pnr.json') env.Append(BUILDERS={'Time': time_rpt_builder}) # -- Generate the bitstream From a40cc8c3c16417a064ac7fa943b15a7e556ed990 Mon Sep 17 00:00:00 2001 From: Riley Wilton Date: Tue, 6 Aug 2024 10:54:31 -0400 Subject: [PATCH 4/7] Now persists the image to the flash on the tang nano, instead of to the ram. --- apio/resources/programmers.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/apio/resources/programmers.json b/apio/resources/programmers.json index cbf24ef3..181fb04f 100644 --- a/apio/resources/programmers.json +++ b/apio/resources/programmers.json @@ -76,6 +76,6 @@ }, "openfpgaloader_tangnano20k": { "command": "openFPGALoader", - "args": "-b tangnano20k" + "args": "-b tangnano20k -f" } } From b3147f35ee139e3a67a9cde93c593453c98e983c Mon Sep 17 00:00:00 2001 From: Riley Wilton Date: Tue, 6 Aug 2024 14:47:56 -0400 Subject: [PATCH 5/7] Added fpga_model flag. --- apio/managers/arguments.py | 1 + apio/resources/fpgas.json | 2 +- apio/resources/gowin/SConstruct | 16 +++++++--------- check/apio.ini | 4 ---- check/blink.pcf | 2 -- check/blink.v | 16 ---------------- 6 files changed, 9 insertions(+), 32 deletions(-) delete mode 100644 check/apio.ini delete mode 100644 check/blink.pcf delete mode 100644 check/blink.v diff --git a/apio/managers/arguments.py b/apio/managers/arguments.py index bd1e9651..aec1826b 100644 --- a/apio/managers/arguments.py +++ b/apio/managers/arguments.py @@ -242,6 +242,7 @@ def process_arguments( # -- Build Scons flag list flags = serialize_scons_flags( { + "fpga_model": config[FPGA], "fpga_arch": config[ARCH], "fpga_size": config[SIZE], "fpga_type": config[TYPE], diff --git a/apio/resources/fpgas.json b/apio/resources/fpgas.json index 023d1a3a..5cd21e33 100644 --- a/apio/resources/fpgas.json +++ b/apio/resources/fpgas.json @@ -400,7 +400,7 @@ }, "GW2AR-LV18QN88C8/I7": { "arch": "gowin", - "type": "gw2ar", + "type": "gw2a-18c", "size": "20k", "pack": "QN88" } diff --git a/apio/resources/gowin/SConstruct b/apio/resources/gowin/SConstruct index f6546105..c6fa2404 100644 --- a/apio/resources/gowin/SConstruct +++ b/apio/resources/gowin/SConstruct @@ -17,6 +17,7 @@ from SCons.Script import (Builder, DefaultEnvironment, Default, AlwaysBuild, # -- Load arguments PROG = ARGUMENTS.get('prog', '') +FPGA_MODEL = ARGUMENTS.get('fpga_model', '') FPGA_SIZE = ARGUMENTS.get('fpga_size', '') FPGA_TYPE = ARGUMENTS.get('fpga_type', '') FPGA_PACK = ARGUMENTS.get('fpga_pack', '') @@ -39,22 +40,19 @@ for warn in VERILATOR_WARN: if warn != '': VERILATOR_PARAM_STR += ' -Wwarn-' + warn -# Update FPGA_TYPE to a less readable version supported -# by apicula. -FPGA_FAMILY = "" -if FPGA_TYPE == "gw2ar" and FPGA_SIZE == "20k": - FPGA_TYPE = "GW2AR-LV18QN88C8/I7" - FPGA_FAMILY = "GW2A-18C" + # -- Size. Possible values: 20k # -- Type. Possible values: gw2ar # -- Package. Unused. + # -- Add the FPGA flags as variables to be shown with the -h scons option vars = Variables() vars.Add('fpga_size', 'Set the Gowin FPGA size (25k)', FPGA_SIZE) vars.Add('fpga_type', 'Set the Gowin FPGA type (gw5a)', FPGA_TYPE) vars.Add('fpga_pack', 'Set the Gowin FPGA packages', FPGA_PACK) +vars.Add('fpga_model', 'Set a specific Gowin FPGA model', FPGA_MODEL) # -- Create environment env = DefaultEnvironment(ENV=os.environ, @@ -145,15 +143,15 @@ env.Append(BUILDERS={'Synth': synth_builder}) # -- Place and route Builder. pnr_builder = Builder( action='nextpnr-himbaechel --device {0} --json $SOURCE --write $TARGET --vopt family={5} --vopt cst={3} {4}'.format( - FPGA_TYPE, FPGA_SIZE, FPGA_PACK, PCF, - '' if VERBOSE_ALL or VERBOSE_PNR else '-q', FPGA_FAMILY), + FPGA_MODEL, FPGA_SIZE, FPGA_PACK, PCF, + '' if VERBOSE_ALL or VERBOSE_PNR else '-q', FPGA_TYPE), suffix='.pnr.json', src_suffix='.json') env.Append(BUILDERS={'PnR': pnr_builder}) # -- Bitstream Builder. bitstream_builder = Builder( - action='gowin_pack -d {0} -o $TARGET $SOURCE'.format(FPGA_FAMILY), + action='gowin_pack -d {0} -o $TARGET $SOURCE'.format(FPGA_TYPE.upper()), suffix='.fs', src_suffix='.pnr.json') env.Append(BUILDERS={'Bin': bitstream_builder}) diff --git a/check/apio.ini b/check/apio.ini deleted file mode 100644 index ed2c8044..00000000 --- a/check/apio.ini +++ /dev/null @@ -1,4 +0,0 @@ -[env] -board = Sipeed-Tang-Nano-20k -top-module = main - diff --git a/check/blink.pcf b/check/blink.pcf deleted file mode 100644 index 5d6ed023..00000000 --- a/check/blink.pcf +++ /dev/null @@ -1,2 +0,0 @@ -IO_LOC "LED" 15; -IO_PORT "LED" PULL_MODE=UP DRIVE=8 BANK_VCCIO=1.8 \ No newline at end of file diff --git a/check/blink.v b/check/blink.v deleted file mode 100644 index ac363ae1..00000000 --- a/check/blink.v +++ /dev/null @@ -1,16 +0,0 @@ - -module main ( - input CLK, - output LED -); - -//-- Modify this value for changing the blink frequency -localparam N = 22; //-- N<=21 Fast, N>=23 Slow - -reg [N:0] counter; -always @(posedge CLK) - counter <= counter + 1; - -assign LED = counter[N]; - -endmodule From 89ee5f9f2c83659c195e7cb1f40ed16bf6aae2ff Mon Sep 17 00:00:00 2001 From: Riley Wilton Date: Tue, 6 Aug 2024 15:10:26 -0400 Subject: [PATCH 6/7] Revert the oss-cad-suite sources to the official FPGAwars repository. --- apio/resources/packages.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apio/resources/packages.json b/apio/resources/packages.json index ad37dea5..3b8daacf 100644 --- a/apio/resources/packages.json +++ b/apio/resources/packages.json @@ -18,7 +18,7 @@ "oss-cad-suite": { "repository": { "name": "tools-oss-cad-suite", - "organization": "wireboy5" + "organization": "FPGAwars" }, "release": { "tag_name": "v%V", @@ -26,7 +26,7 @@ "uncompressed_name": "", "package_name": "tools-oss-cad-suite", "extension": "tar.gz", - "url_version": "https://github.com/wireboy5/tools-oss-cad-suite/raw/main/VERSION_DEV" + "url_version": "https://github.com/FPGAwars/tools-oss-cad-suite/raw/main/VERSION_DEV" }, "description": "YosysHQ/oss-cad-suite" }, From 835fdca80da5d74604495e0cd0b252b4c34b73e7 Mon Sep 17 00:00:00 2001 From: Riley Wilton Date: Tue, 6 Aug 2024 15:34:26 -0400 Subject: [PATCH 7/7] Use CST extension instead of PCF. --- apio/resources/gowin/SConstruct | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/apio/resources/gowin/SConstruct b/apio/resources/gowin/SConstruct index c6fa2404..8a85a284 100644 --- a/apio/resources/gowin/SConstruct +++ b/apio/resources/gowin/SConstruct @@ -117,17 +117,17 @@ if len(src_synth) == 0: print('Error: no verilog module files found (.v)') Exit(1) -# -- Get the PCF file -PCF = '' -PCF_list = Glob('*.pcf') +# -- Get the CST file +CST = '' +CST_list = Glob('*.cst') try: - PCF = PCF_list[0] + CST = CST_list[0] except IndexError: - print('\n---> WARNING: no PCF file found (.pcf)\n') + print('\n---> WARNING: no CST file found (.cst)\n') # -- Debug -# print('PCF Found: {}'.format(PCF)) +# print('CST Found: {}'.format(CST)) # -- Synthesizing Builder synth_builder = Builder( @@ -143,7 +143,7 @@ env.Append(BUILDERS={'Synth': synth_builder}) # -- Place and route Builder. pnr_builder = Builder( action='nextpnr-himbaechel --device {0} --json $SOURCE --write $TARGET --vopt family={5} --vopt cst={3} {4}'.format( - FPGA_MODEL, FPGA_SIZE, FPGA_PACK, PCF, + FPGA_MODEL, FPGA_SIZE, FPGA_PACK, CST, '' if VERBOSE_ALL or VERBOSE_PNR else '-q', FPGA_TYPE), suffix='.pnr.json', src_suffix='.json') @@ -166,7 +166,7 @@ env.Append(BUILDERS={'Time': time_rpt_builder}) # -- Generate the bitstream blif_target = env.Synth(TARGET, [src_synth]) -asc_target = env.PnR(TARGET, [blif_target, PCF]) +asc_target = env.PnR(TARGET, [blif_target, CST]) bitstream_target = env.Bin(TARGET, asc_target) build_target = env.Alias('build', bitstream_target)