diff --git a/examples/zynq7000/SIM/tb_heartbeat.vhd b/examples/zynq7000/SIM/tb_heartbeat.vhd new file mode 100644 index 0000000..82b10b2 --- /dev/null +++ b/examples/zynq7000/SIM/tb_heartbeat.vhd @@ -0,0 +1,44 @@ +library IEEE; +use IEEE.STD_LOGIC_1164.all; +use IEEE.NUMERIC_STD.all; + +entity tb_heartbeat is +end entity; + +architecture behavioural of tb_heartbeat is + -- COMPONENTS + -- ---------- + component heartbeat is + generic ( + Fin : integer := 100000000; + Fout : integer := 8 + ); + port ( + ACLK : in std_logic; + ARESETN : in std_logic; + LED : out std_logic_vector(1 downto 0) + ); + end component; + -- SIGNALS + -- ------- + signal ACLK : std_logic := '0'; + signal LED : std_logic_vector(1 downto 0) := "00"; + signal ARESETN : std_logic := '0'; +begin + c_heartbeat : component heartbeat generic map( + 50000000, + 5000000 + ) port map( + ACLK => ACLK, + ARESETN => ARESETN, + LED => LED + ); + ACLK <= not ACLK after 10 ns; + ARESETN <= '1' after 150 ns; + + process + begin + wait for 5000 ns; + report "END OF SIMULATION" severity failure; + end process; +end architecture; \ No newline at end of file diff --git a/examples/zynq7000/project.cfg b/examples/zynq7000/project.cfg index c7e19fa..bf674e6 100644 --- a/examples/zynq7000/project.cfg +++ b/examples/zynq7000/project.cfg @@ -39,7 +39,7 @@ package = clg400 speedgrade = -2 toplevel = toplevel # Created netlist toplevel -netlist_top = toplevel +netlist_top = toplevel.heartbeat_i synth_opts = -flatten_hierarchy none -keep_equivalent_registers #opt_opts = #place_opts = @@ -51,4 +51,23 @@ files_vhdl = RTL/heartbeat.vhd RTL/toplevel.vhd #files_sysverilog = files_con = CON/toplevel.xdc files_xci = OUT/ip/rst_gen/rst_gen.xci OUT/ip/zynqps/zynqps.xci +# ###################################### + +# ###################################### +# Behavioural simulation +[target.sim] +toolchain = xsim + +# Toolchain settings +toplevel = tb_heartbeat +vcdlevels = 20 +runtime = all +#xelab_opts = + +# Fileset +files_vhdl = RTL/heartbeat.vhd + SIM/tb_heartbeat.vhd +#files_verilog = +#files_sysverilog = +#files_xci = # ###################################### \ No newline at end of file diff --git a/remotesyn/toolchains/isim.py b/remotesyn/toolchains/isim.py index 1509138..94ab41c 100644 --- a/remotesyn/toolchains/isim.py +++ b/remotesyn/toolchains/isim.py @@ -4,6 +4,10 @@ import time import subprocess def do(config, target, log, subprocesses, prefix='.'): + shutil.rmtree(config.get('project', 'build_dir', fallback='build'), True) + + log("Starting simulation") + log(" - parsing options") toplevel = config.get(f'target.{target}', 'toplevel', fallback='toplevel') vcdlevels = config.get(f'target.{target}', 'vcdlevels', fallback='1') diff --git a/remotesyn/toolchains/xsim.py b/remotesyn/toolchains/xsim.py new file mode 100644 index 0000000..56e71ad --- /dev/null +++ b/remotesyn/toolchains/xsim.py @@ -0,0 +1,154 @@ +import shutil +import os +import time +import subprocess + +def do(config, target, log, subprocesses, prefix='.'): + shutil.rmtree(config.get('project', 'build_dir', fallback='build'), True) + + log("Starting simulation") + + log(" - parsing options") + device = config.get(f'target.{target}', 'device', fallback='') + package = config.get(f'target.{target}', 'package', fallback='') + speedgrade = config.get(f'target.{target}', 'speedgrade', fallback='') + toplevel = config.get(f'target.{target}', 'toplevel', fallback='toplevel') + runtime = config.get(f'target.{target}', 'runtime', fallback='100 ns') + xelab_opts = config.get(f'target.{target}', 'xelab_opts', fallback='') + files_vhdl = config.get(f'target.{target}', 'files_vhdl', fallback='').split() + files_verilog = config.get(f'target.{target}', 'files_verilog', fallback='').split() + files_sysverilog = config.get(f'target.{target}', 'files_sysverilog', fallback='').split() + files_xci = config.get(f'target.{target}', 'files_xci', fallback='').split() + build_dir = config.get(f'project', 'build_dir', fallback='build') + out_dir = config.get(f'project', 'out_dir', fallback='out') + + prefix = f'{os.getcwd()}/{prefix}' + build_dir = f'{prefix}/{build_dir}' + out_dir = f'{prefix}/{out_dir}/{target}' + + log(" - creating output directories") + os.makedirs(build_dir, exist_ok=True) + os.makedirs(out_dir, exist_ok=True) + + log(" - writing project tcl file") + with open(f'{build_dir}/do.tcl', 'w') as f: + f.write('set_param general.maxThreads 8\n') + f.write(f'create_project -force sim sim\n') + for s in files_vhdl: + f.write(f"add_files -norecurse -scan_for_includes \"{prefix}/{s}\"\n") + f.write(f"import_files -norecurse \"{prefix}/{s}\"\n") + for s in files_verilog: + f.write(f"add_files -norecurse -scan_for_includes \"{prefix}/{s}\"\n") + f.write(f"import_files -norecurse \"{prefix}/{s}\"\n") + for s in files_sysverilog: + f.write(f"add_files -norecurse -scan_for_includes \"{prefix}/{s}\"\n") + f.write(f"import_files -norecurse \"{prefix}/{s}\"\n") + for s in files_xci: + f.write(f"add_files -norecurse -scan_for_includes \"{prefix}/{s}\"\n") + # TODO C files for VPI + + f.write(f"set_property top {toplevel} [get_filesets sim_1]\n") + f.write("set_property top_lib xil_defaultlib [get_filesets sim_1]\n") + f.write("launch_simulation -noclean_dir -scripts_only -absolute_path\n") + + log(" - run vivado") + + p = subprocess.Popen(f"vivado -mode batch -source do.tcl", + shell=True, cwd=build_dir, + stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + subprocesses.append(p) + while p.poll() is None: + time.sleep(1) + res = p.returncode + + log(" - copy logs") + shutil.copy(f'{build_dir}/vivado.log', f'{out_dir}/synth.log') + + if res!=0: + return res + + log(" - patch run scripts") + + p = subprocess.Popen(f'sed -i "s/xelab/xelab {xelab_opts}/g" elaborate.sh', + shell=True, cwd=f'{build_dir}/sim/sim.sim/sim_1/behav/xsim', + 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!=0: + return res + + # needed for postsim? + # p = subprocess.Popen(f"sed -i '/ \/I /d' netlist.sdf >> {build_dir}/patch.log && sed -i '/glbl.v/d' *.prj >> {build_dir}/patch.log", + # shell=True, cwd=f'{build_dir}/sim/sim.sim/sim_1/behav/xsim', + # stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + # subprocesses.append(p) + # while p.poll() is None: + # time.sleep(1) + # res = p.returncode + + # log(" - copy logs") + # shutil.copy(f'{build_dir}/patch.log', f'{out_dir}/patch.log') + + # if res!=0: + # return res + + log(" - compile") + + p = subprocess.Popen(f'bash compile.sh', + shell=True, cwd=f'{build_dir}/sim/sim.sim/sim_1/behav/xsim', + stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + subprocesses.append(p) + while p.poll() is None: + time.sleep(1) + res = p.returncode + + log(" - copy logs") + shutil.copy(f'{build_dir}/sim/sim.sim/sim_1/behav/xsim/compile.log', f'{out_dir}/compile.log') + + if res!=0: + return res + + log(" - elaborate") + + p = subprocess.Popen(f'bash elaborate.sh', + shell=True, cwd=f'{build_dir}/sim/sim.sim/sim_1/behav/xsim', + stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + subprocesses.append(p) + while p.poll() is None: + time.sleep(1) + res = p.returncode + + log(" - copy logs") + shutil.copy(f'{build_dir}/sim/sim.sim/sim_1/behav/xsim/elaborate.log', f'{out_dir}/elaborate.log') + + if res!=0: + return res + + log(" - write simulation script") + with open(f'{build_dir}/sim/sim.sim/sim_1/behav/xsim/{toplevel}.tcl', 'w') as f: + f.write(f"open_vcd out.vcd\nlog_vcd\nrun {runtime}\nclose_vcd\nquit\n") + + log(" - simulate") + + p = subprocess.Popen(f'bash simulate.sh', + shell=True, cwd=f'{build_dir}/sim/sim.sim/sim_1/behav/xsim', + stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL) + subprocesses.append(p) + while p.poll() is None: + time.sleep(1) + res = p.returncode + + log(" - copy logs") + shutil.copy(f'{build_dir}/sim/sim.sim/sim_1/behav/xsim/simulate.log', f'{out_dir}/simulate.log') + + if res!=0: + return res + + log(" - copy output files") + shutil.copy(f'{build_dir}/sim/sim.sim/sim_1/behav/xsim/out.vcd', f'{out_dir}/out.vcd') + + return res +