Added base GOWIN eda script

This commit is contained in:
2023-10-14 20:30:45 +02:00
parent da27f38f0f
commit 84695d44b4
7 changed files with 198 additions and 1 deletions

2
examples/GW1NSR-4C/.gitignore vendored Normal file
View File

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

View File

@ -0,0 +1,8 @@
IO_LOC "led_o" 10;
IO_PORT "led_o" PULL_MODE=NONE DRIVE=8;
IO_LOC "reset_n_i" 15;
IO_PORT "reset_n_i" PULL_MODE=UP;
IO_LOC "clk_i" 45;
IO_PORT "clk_i" PULL_MODE=UP;

View File

@ -0,0 +1 @@
create_clock -name CLK_IN -period 37.037 -waveform {0 18.52} [get_ports {clk_i}]

View File

@ -0,0 +1,23 @@
module led_blink
(
input clk_i,
input reset_n_i,
output led_o
);
reg [23:0] counter;
reg polarity;
always@(posedge clk_i) begin
if (!reset_n_i)
counter <= 24'h00000;
else
counter <= counter + 1'b1;
if (counter == 24'hFFFFF)
polarity <= ~polarity;
end
assign led_o = polarity;
endmodule

View File

@ -0,0 +1,28 @@
[project]
name = gowin_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 synthesis
[target.synth]
toolchain = gowin
# Toolchain settings
family = GW1NSR-4C
device = GW1NSR-LV4CQN48PC6/I5
toplevel = led_blink
# Fileset
# files_vhdl =
files_verilog = RTL/toplevel.v
files_con = CON/io.cst
CON/io.sdc
# ######################################

View File

@ -0,0 +1,135 @@
import shutil
import os
import time
import subprocess
import html2text
def do(config, target, log, subprocesses, prefix='.'):
shutil.rmtree(config.get('project', 'build_dir', fallback='build'), True)
shutil.rmtree(config.get('project', 'out_dir', fallback='out'), True)
log(" - parsing options")
family = config.get(f'target.{target}', 'family', fallback='')
device = config.get(f'target.{target}', 'device', fallback='')
toplevel = config.get(f'target.{target}', 'toplevel', fallback='toplevel')
files_vhdl = config.get(f'target.{target}', 'files_vhdl', fallback='').split()
files_verilog = config.get(f'target.{target}', 'files_verilog', fallback='').split()
files_con= config.get(f'target.{target}', 'files_con', 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 scripts")
with open(f'{build_dir}/synth.tcl', 'w') as f:
f.write(f'set_device {device} -name {family}\n')
for s in files_vhdl:
if s=='':
continue
f.write(f'add_file {prefix}/{s}\n')
for s in files_verilog:
if s=='':
continue
f.write(f'add_file {prefix}/{s}\n')
for s in files_con:
if s=='':
continue
f.write(f'add_file {prefix}/{s}\n')
f.write('set_option -synthesis_tool gowinsynthesis\n')
f.write(f'set_option -output_base_name {toplevel}\n')
f.write(f'set_option -top_module {toplevel}\n')
f.write('run syn\n')
with open(f'{build_dir}/pnr.tcl', 'w') as f:
f.write(f'set_device {device} -name {family}\n')
f.write('set_option -synthesis_tool gowinsynthesis\n')
f.write(f'set_option -output_base_name {toplevel}\n')
f.write(f'set_option -top_module {toplevel}\n')
for s in files_con:
if s=='':
continue
f.write(f'add_file {prefix}/{s}\n')
f.write(f'add_file {build_dir}/impl/gwsynthesis/{toplevel}.vg\n')
f.write('run pnr\n')
log(' - run syntesis')
p = subprocess.Popen(f"gw_sh synth.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
shutil.copy(f'{build_dir}/impl/gwsynthesis/{toplevel}.log', f'{out_dir}/synth.log')
if res!=0:
log("ERROR: synthesis failed with:", res)
return res
shutil.copy(f'{build_dir}/impl/gwsynthesis/{toplevel}.vg', f'{out_dir}/synth_netlist.vg')
with open(f'{build_dir}/impl/gwsynthesis/{toplevel}_syn.rpt.html', 'r') as fin, open(f'{out_dir}/synth_rpt.md', 'w') as fout:
text_maker = html2text.HTML2Text()
text_maker.bypass_tables = False
text_maker.ignore_links = True
text_maker.body_width = 500
fout.write(text_maker.handle(fin.read()))
log(' - run PnR')
p = subprocess.Popen(f"gw_sh pnr.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
shutil.copy(f'{build_dir}/impl/pnr/{toplevel}.log', f'{out_dir}/pnr.log')
if res!=0:
log("ERROR: pnr failed with:", res)
return res
shutil.copy(f'{build_dir}/impl/pnr/{toplevel}.fs', f'{out_dir}/{toplevel}.fs')
shutil.copy(f'{build_dir}/impl/pnr/{toplevel}.bin', f'{out_dir}/{toplevel}.bin')
with open(f'{build_dir}/impl/pnr/{toplevel}.rpt.html', 'r') as fin, open(f'{out_dir}/rpt.md', 'w') as fout:
text_maker = html2text.HTML2Text()
text_maker.bypass_tables = False
text_maker.ignore_links = True
text_maker.body_width = 500
fout.write(text_maker.handle(fin.read()))
with open(f'{build_dir}/impl/pnr/{toplevel}.power.html', 'r') as fin, open(f'{out_dir}/power.md', 'w') as fout:
text_maker = html2text.HTML2Text()
text_maker.bypass_tables = False
text_maker.ignore_links = True
text_maker.body_width = 500
fout.write(text_maker.handle(fin.read()))
with open(f'{build_dir}/impl/pnr/{toplevel}.pin.html', 'r') as fin, open(f'{out_dir}/pin.md', 'w') as fout:
text_maker = html2text.HTML2Text()
text_maker.bypass_tables = False
text_maker.ignore_links = True
text_maker.body_width = 500
fout.write(text_maker.handle(fin.read()))
with open(f'{build_dir}/impl/pnr/{toplevel}_tr_content.html', 'r') as fin, open(f'{out_dir}/timing.md', 'w') as fout:
text_maker = html2text.HTML2Text()
text_maker.bypass_tables = False
text_maker.ignore_links = True
text_maker.body_width = 500
fout.write(text_maker.handle(fin.read()))
return res

View File

@ -20,6 +20,6 @@ setup(
],
packages=['remotesyn'],
licence='BSD Licence',
install_requires=['paramiko'],
install_requires=['paramiko', 'html2text'],
scripts=['scripts/rbuild', 'scripts/rmbuild', 'scripts/rmserver']
)