Added ghdl simulation toolchain

Signed-off-by: Joppe Blondel <joppe@blondel.nl>
This commit is contained in:
2022-09-06 12:12:38 +02:00
parent 945af0f249
commit 246d53fa00
5 changed files with 192 additions and 0 deletions

2
examples/formal/.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
OUT
BUILD

View File

@ -0,0 +1,40 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity counter is
generic (
-- Formal generic is used to embed formal validation stuff
formal : boolean := false;
-- Data width
width : integer := 16;
-- Max count
mxcnt : integer := 256
);
port (
ACLK : in std_logic;
ARESETN : in std_logic;
cnt : out std_logic_vector(width-1 downto 0)
);
end entity;
architecture behav of counter is
signal icnt : unsigned (width-1 downto 0);
begin
cnt <= std_logic_vector(icnt);
process(ACLK, ARESETN)
begin
if ARESETN='0' then
icnt <= (others=>'0');
elsif rising_edge(ACLK) then
if icnt<mxcnt then
icnt <= icnt + 1;
else
icnt <= (others=>'0');
end if;
end if;
end process;
end architecture;

View File

@ -0,0 +1,48 @@
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity tb_counter is
end entity;
architecture behav of tb_counter is
component counter is
generic (
formal : boolean := false;
width : integer := 16;
mxcnt : integer := 256
);
port (
ACLK : in std_logic;
ARESETN : in std_logic;
cnt : out std_logic_vector(width-1 downto 0)
);
end component;
signal ACLK, ARESETN : std_logic := '0';
signal cnt : std_logic_vector(15 downto 0);
begin
ACLK <= not ACLK after 10 ns;
ARESETN <= '1' after 50 ns;
process
begin
wait for 2 us;
report "END OF SIMULATION" severity failure;
end process;
c_counter : component counter
generic map(
formal => false,
width => cnt'length,
mxcnt => 5
) port map (
ACLK => ACLK,
ARESETN => ARESETN,
cnt => cnt
);
end architecture;

View File

@ -0,0 +1,28 @@
[project]
name = formal_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
# ######################################
# Basic VHDL simulation with GHDL
[target.sim]
toolchain = ghdl
# Toolchain settings
toplevel = tb_counter
runtime = all
#ghdla_opts =
#ghdle_opts =
#ghdlr_opts =
# Fileset
files_vhdl = RTL/counter.vhd
SIM/tb_counter.vhd
# ######################################

View File

@ -0,0 +1,74 @@
import shutil
import os
import time
import subprocess
def execp(cmd, subprocesses, cwd):
p = subprocess.Popen(cmd,
shell=True, cwd=cwd,
stdin=subprocess.DEVNULL, stdout=subprocess.DEVNULL, stderr=subprocess.DEVNULL)
subprocesses.append(p)
while p.poll() is None:
time.sleep(1)
res = p.returncode
return res
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')
runtime = config.get(f'target.{target}', 'runtime', fallback='100 ns')
ghdla_opts = config.get(f'target.{target}', 'ghdla_opts', fallback='')
ghdle_opts = config.get(f'target.{target}', 'ghdle_opts', fallback='')
ghdlr_opts = config.get(f'target.{target}', 'ghdlr_opts', fallback='')
files_vhdl = config.get(f'target.{target}', 'files_vhdl', 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(" - analyze files")
res = 0
for f in files_vhdl:
res = execp(f"echo +++{f} >> a.log && ghdl -a {ghdla_opts} {prefix}/{f} 2>&1 >> a.log", subprocesses, build_dir)
if res!=0:
break
log(" - copy logs")
shutil.copy(f'{build_dir}/a.log', f'{out_dir}/a.log')
if res!=0:
log("ERROR: ghdl -a returned with", res)
return res
log(" - elaborate")
res = execp(f"echo {toplevel} >> e.log && ghdl -e {ghdle_opts} {toplevel} 2>&1 >> e.log", subprocesses, build_dir)
log(" - copy logs")
shutil.copy(f'{build_dir}/e.log', f'{out_dir}/e.log')
if res!=0:
log("ERROR: ghdl -e returned with", res)
return res
log(" - simulate")
extra = ''
if runtime!='all':
extra = f'--stop-time={runtime.replace(" ", "")}'
res = execp(f"echo {toplevel} >> r.log && ghdl -r {ghdlr_opts} {extra} {toplevel} --vcd=out.vcd 2>&1 >> r.log", subprocesses, build_dir)
log(" - copy logs")
shutil.copy(f'{build_dir}/r.log', f'{out_dir}/r.log')
# Ignore simulation errors: vhdl stopping with failure results in returned with 1
# if res!=0:
# log("ERROR: ghdl -r returned with", res)
# return res
log(" - copy output files")
shutil.copy(f'{build_dir}/out.vcd', f'{out_dir}/out.vcd')
return 0