From dc97a7d5a8e496ee355cc3074bd7d0de766a2138 Mon Sep 17 00:00:00 2001 From: Joppe Blondel Date: Sun, 4 Sep 2022 19:48:46 +0200 Subject: [PATCH] Added impl Signed-off-by: Joppe Blondel --- .gitignore | 4 +- examples/spartan6/.gitignore | 2 + examples/spartan6/CON/toplevel.ucf | 41 ++++++++++++++++ examples/spartan6/RTL/toplevel.vhd | 23 +++++++++ examples/spartan6/SIM/tb_toplevel.vhd | 38 +++++++++++++++ examples/spartan6/project.cfg | 26 ++++++++++ remotesyn/ISE/impl.py | 69 +++++++++++++++++++++++++++ remotesyn/ISE/syn.py | 1 + 8 files changed, 203 insertions(+), 1 deletion(-) create mode 100644 examples/spartan6/.gitignore create mode 100644 examples/spartan6/CON/toplevel.ucf create mode 100644 examples/spartan6/RTL/toplevel.vhd create mode 100644 examples/spartan6/SIM/tb_toplevel.vhd create mode 100644 examples/spartan6/project.cfg create mode 100644 remotesyn/ISE/impl.py diff --git a/.gitignore b/.gitignore index 264daca..18777d5 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1,3 @@ -*__pycache__ \ No newline at end of file +*__pycache__ +id_rsa* +authorized* \ No newline at end of file diff --git a/examples/spartan6/.gitignore b/examples/spartan6/.gitignore new file mode 100644 index 0000000..d28717d --- /dev/null +++ b/examples/spartan6/.gitignore @@ -0,0 +1,2 @@ +OUT +BUILD \ No newline at end of file diff --git a/examples/spartan6/CON/toplevel.ucf b/examples/spartan6/CON/toplevel.ucf new file mode 100644 index 0000000..ddf2525 --- /dev/null +++ b/examples/spartan6/CON/toplevel.ucf @@ -0,0 +1,41 @@ +NET "ACLK" LOC = P126; +NET "ACLK" TNM_NET = "SYS_CLK_PIN"; +TIMESPEC TS_SYS_CLK_PIN = PERIOD "SYS_CLK_PIN" 10 ns HIGH 50 %; + +NET "LED[0]" LOC = P119; +NET "LED[0]" IOSTANDARD = LVCMOS33; +NET "LED[0]" DRIVE = 8; +NET "LED[1]" LOC = P118; +NET "LED[1]" IOSTANDARD = LVCMOS33; +NET "LED[1]" DRIVE = 8; +NET "LED[2]" LOC = P117; +NET "LED[2]" IOSTANDARD = LVCMOS33; +NET "LED[2]" DRIVE = 8; +NET "LED[3]" LOC = P116; +NET "LED[3]" IOSTANDARD = LVCMOS33; +NET "LED[3]" DRIVE = 8; +NET "LED[4]" LOC = P115; +NET "LED[4]" IOSTANDARD = LVCMOS33; +NET "LED[4]" DRIVE = 8; +NET "LED[5]" LOC = P114; +NET "LED[5]" IOSTANDARD = LVCMOS33; +NET "LED[5]" DRIVE = 8; +NET "LED[6]" LOC = P112; +NET "LED[6]" IOSTANDARD = LVCMOS33; +NET "LED[6]" DRIVE = 8; +NET "LED[7]" LOC = P111; +NET "LED[7]" IOSTANDARD = LVCMOS33; +NET "LED[7]" DRIVE = 8; + +NET "SW[0]" LOC = P124; +NET "SW[0]" IOSTANDARD = LVCMOS33; +NET "SW[0]" PULLUP; +NET "SW[1]" LOC = P123; +NET "SW[1]" IOSTANDARD = LVCMOS33; +NET "SW[1]" PULLUP; +NET "SW[2]" LOC = P121; +NET "SW[2]" IOSTANDARD = LVCMOS33; +NET "SW[2]" PULLUP; +NET "SW[3]" LOC = P120; +NET "SW[3]" IOSTANDARD = LVCMOS33; +NET "SW[3]" PULLUP; \ No newline at end of file diff --git a/examples/spartan6/RTL/toplevel.vhd b/examples/spartan6/RTL/toplevel.vhd new file mode 100644 index 0000000..1bb9ea5 --- /dev/null +++ b/examples/spartan6/RTL/toplevel.vhd @@ -0,0 +1,23 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use IEEE.NUMERIC_STD.all; +entity toplevel is + port ( + ACLK : in std_logic; + LED : out std_logic_vector(7 downto 0); + SW : in std_logic_vector(3 downto 0) + ); +end toplevel; +architecture structural of toplevel is + signal ARESETN : std_logic; +begin + ARESETN <= SW(3); + process(ACLK, ARESETN) + begin + if ARESETN='0' then + LED <= "11111111"; + elsif rising_edge(ACLK) then + LED <= SW & SW; + end if; + end process; +end architecture; \ No newline at end of file diff --git a/examples/spartan6/SIM/tb_toplevel.vhd b/examples/spartan6/SIM/tb_toplevel.vhd new file mode 100644 index 0000000..c771f5c --- /dev/null +++ b/examples/spartan6/SIM/tb_toplevel.vhd @@ -0,0 +1,38 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use IEEE.NUMERIC_STD.all; +entity tb_toplevel is +end entity; +architecture behavioural of tb_toplevel is + -- COMPONENTS + -- ---------- + component toplevel is + port ( + ACLK : in std_logic; + LED : out std_logic_vector(7 downto 0); + SW : in std_logic_vector(3 downto 0) + ); + end component; + -- SIGNALS + -- ------- + signal ACLK : std_logic := '0'; + signal LED : std_logic_vector(7 downto 0) := "00000000"; + signal SW : std_logic_vector(3 downto 0) := "0111"; +begin + c_toplevel : component toplevel port map( + ACLK, LED, SW + ); + ACLK <= not ACLK after 10 ns; + SW(3) <= '1' after 150 ns; + process + begin + wait until SW(3)='1'; + SW(2 downto 0) <= "101"; + wait for 75 ns; + SW(2 downto 0) <= "010"; + wait for 19 ns; + SW(2 downto 0) <= "111"; + wait for 100 ns; + report "END OF SIMULATION" severity failure; + end process; +end architecture; \ No newline at end of file diff --git a/examples/spartan6/project.cfg b/examples/spartan6/project.cfg new file mode 100644 index 0000000..4713135 --- /dev/null +++ b/examples/spartan6/project.cfg @@ -0,0 +1,26 @@ +[project] +name = spartan6_project +version = 0.1 +out_dir = OUT +build_dir = BUILD + +[server] +hostname = localhost +port = 2020 +privkey = /home/joppe/.ssh/id_rsa +pubkey = /home/joppe/.ssh/id_rsa.pub + +[target:default] +family = spartan6 +device = xc6slx9 +package = tqg144 +speedgrade = -2 +toolchain = ISE + +[build:default] +target = default +toplevel = toplevel +constraints = CON/toplevel.ucf +src_vhdl = RTL/toplevel.vhd +src_verilog = +src_sysverilog = \ No newline at end of file diff --git a/remotesyn/ISE/impl.py b/remotesyn/ISE/impl.py new file mode 100644 index 0000000..5b28265 --- /dev/null +++ b/remotesyn/ISE/impl.py @@ -0,0 +1,69 @@ +from asyncio import constants +import threading +import shutil +import os +import time +import subprocess +import signal +import random + +def needed_files(config, target) -> list: + if not config.has_section(f'build:{target}'): + print("ERROR: config file has no build section for target") + return None + outdir = f"{config.get('project', 'out_dir', fallback='out')}" + needed_files = [ + f'{outdir}/{target}/synth.ngc', + ] + for s in config.get(f'build:{target}', 'constraints', fallback="").split(): + needed_files.append(s) + return needed_files + +def generated_files(config, target) -> list: + outdir = f"{config.get('project', 'out_dir', fallback='out')}" + return [ + f'{outdir}/{target}/impl.ngd', + f'{outdir}/{target}/impl-ngd.log', + ] + +def do(config, target, log, subprocesses, prefix='.') -> int: + log("Implement:") + + if not config.has_section(f'build:{target}'): + log("ERROR: config file has no build section for target") + return 1 + + devtarget = f'target:{config.get(f"build:{target}", "target", fallback="")}' + if not config.has_section(devtarget): + log("ERROR: config file has no section for device target") + return 1 + + device = f"{config.get(devtarget, 'device', fallback='')}{config.get(devtarget, 'speedgrade', fallback='')}-{config.get(devtarget, 'package', fallback='')}" + builddir = f"{prefix}/{config.get('project', 'build_dir', fallback='.build')}" + outdir = f"{prefix}/{config.get('project', 'out_dir', fallback='out')}" + + os.makedirs(builddir, exist_ok=True) + curdir = f"{os.getcwd()}/{prefix}" + + contstraints = [] + for s in config.get(f'build:{target}', 'constraints', fallback="").split(): + contstraints.append(f"{curdir}/{s}") + + log(" - Executing ngdbuild") + p = subprocess.Popen(f"ngdbuild -intstyle xflow -p {device} -uc {contstraints[0]} {curdir}/{outdir}/{target}/synth.ngc impl.ngd", shell=True, cwd=builddir, stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + subprocesses.append(p) + while p.poll() is None: + time.sleep(1) + res = p.returncode + if res: + log(" - ERROR: return code is", res) + log(" - copy log") + os.makedirs(f'{outdir}/{target}', exist_ok=True) + shutil.copy(f'{builddir}/impl.bld', f'{outdir}/{target}/impl-ngd.log') + return res + + log(" - copy output files") + os.makedirs(f'{outdir}/{target}', exist_ok=True) + shutil.copy(f'{builddir}/impl.ngd', f'{outdir}/{target}/impl.ngd') + shutil.copy(f'{builddir}/impl.bld', f'{outdir}/{target}/impl-ngd.log') + return 0 \ No newline at end of file diff --git a/remotesyn/ISE/syn.py b/remotesyn/ISE/syn.py index 9e53852..caa121c 100644 --- a/remotesyn/ISE/syn.py +++ b/remotesyn/ISE/syn.py @@ -60,6 +60,7 @@ def do(config, target, log, subprocesses, prefix='.') -> int: f.write(f'-top {config.get(f"sources:{target}", "toplevel", fallback="toplevel")}\n') f.write(f'-p {device}\n-glob_opt max_delay -opt_mode speed') + log(" - Executing xst") p = subprocess.Popen("xst -intstyle xflow -ifn prj.scr", shell=True, cwd=builddir, stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) subprocesses.append(p) while p.poll() is None: