Skip to content

Commit 5c21e72

Browse files
committed
Updated how Quartus workflow is run
Quartus workflow is now run as a system call in the background and its log file is read in Matlab until exit is encountered Additionally less html reports are generated by HDLCoder and it was updated for the new target names. Additionally the logging module is now used by the Quartus workflow. Also fixes were made regarding updating the target from De10 to Audiomini as compilitation previously was failing from the name change
1 parent 72d7a80 commit 5c21e72

8 files changed

+100
-81
lines changed

vhdl/autogen_quartus.py

+32-7
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,38 @@
11
import argparse
2+
import sys
3+
import logging
24

35
from dataplane_config import DataplaneConfig
46
from quartus.quartus_workflow import execute_quartus_workflow
57

68

7-
def main(inputFilename, working_dir):
9+
def main(inputFilename, working_dir, log_to_file=False):
810
if not(working_dir.endswith("/")):
911
working_dir += "/"
10-
dataplane_config = DataplaneConfig.parse_json(inputFilename)
11-
execute_quartus_workflow(
12-
dataplane_config, working_dir)
12+
logger = init_logging(logging.INFO, log_to_file)
13+
try:
14+
dataplane_config = DataplaneConfig.parse_json(inputFilename)
15+
execute_quartus_workflow(
16+
dataplane_config.target_system, dataplane_config.custom_components, dataplane_config.clock_rate, working_dir)
17+
finally:
18+
logger.info("exit")
19+
20+
def init_logging(debugLevel, log_to_file=False):
21+
logger = logging.getLogger('autogen_quartus')
22+
23+
if log_to_file:
24+
file_log_handler = logging.FileHandler('autogen_quartus.log', 'w')
25+
file_log_handler.setLevel(debugLevel)
26+
file_log_handler.setFormatter(logging.Formatter())
27+
logger.addHandler(file_log_handler)
28+
29+
console_handler = logging.StreamHandler()
30+
console_handler.setLevel(debugLevel)
31+
console_handler.setFormatter(logging.Formatter())
32+
logger.addHandler(console_handler)
33+
34+
logger.setLevel(debugLevel)
35+
return logger
1336

1437
def parseargs():
1538
"""
@@ -21,11 +44,13 @@ def parseargs():
2144
help="JSON file containing autogen configuration")
2245
parser.add_argument('-w', '--working-dir',
2346
help="Working directory to execute the quartus workflow in")
47+
parser.add_argument('-l', '--logging', required=False, action="store_true",
48+
help="Enable logging to autogen_quartus.log")
2449
args = parser.parse_args()
25-
return (args.json, args.working_dir)
50+
return (args.json, args.working_dir, args.logging)
2651

2752

2853
if __name__ == "__main__":
29-
(json_filename, working_dir) = parseargs()
54+
(json_filename, working_dir, log_to_file) = parseargs()
3055

31-
main(json_filename, working_dir)
56+
main(json_filename, working_dir, log_to_file)

vhdl/hdlworkflow.m

+5-5
Original file line numberDiff line numberDiff line change
@@ -3,10 +3,10 @@
33
dataplane_name = 'dataplane';
44
load_system(model);
55

6-
if strcmp(mp.target_system,'de10')
6+
if strcmp(mp.target_system,'audiomini')
77
device_family = 'Cyclone V';
88
device = '5CSEBA6U23I7';
9-
elseif strcmp(mp.target_system,'arria10')
9+
elseif strcmp(mp.target_system,'audioblade')
1010
device_family = 'Arria 10';
1111
device = '10AS066H2F34I1HG';
1212
end
@@ -19,10 +19,10 @@
1919
'CriticalPathEstimation', 'off', ...
2020
'GenerateHDLTestBench', 'off', ...
2121
'HDLCodingStandardCustomizations',hdlcodingstd.IndustryCustomizations(), ...
22-
'HDLGenerateWebview', 'on', ...
22+
'HDLGenerateWebview', 'off', ...
2323
'HDLSubsystem', [model '/' dataplane_name], ...
24-
'OptimizationReport', 'on', ...
25-
'ResourceReport', 'on', ...
24+
'OptimizationReport', 'off', ...
25+
'ResourceReport', 'off', ...
2626
'SynthesisTool', 'Altera QUARTUS II', ...
2727
'SynthesisToolChipFamily', device_family, ...
2828
'SynthesisToolDeviceName', device, ...

vhdl/quartus/quartus_workflow.py

+17-11
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
import fileinput
44
import sys
55
import re
6+
import logging
67
from shutil import copyfile
78
from quartus.quartus_templates import quartus_templates
89
from quartus.target import Audiomini, Audioblade, Target
@@ -71,7 +72,7 @@ def create_tcl_system_file(target, custom_components, sys_clock_rate_hz, templat
7172
"""
7273
tcl_file = target.system_name + ".tcl"
7374

74-
print("Making tcl file for qsys")
75+
logger.info("Making tcl file for qsys")
7576
copyfile(RES_DIR + target.base_qsys_file, working_dir + target.base_qsys_file)
7677

7778
quartus_version = re.search(r'.intelFPGA.(\d+\.\d+)', QUARTUS_BIN_DIR).group(1)
@@ -107,8 +108,9 @@ def run_cmd_and_log(cmd, log_msg, log_file_path, err_on_fail=True):
107108
ChildProcessError
108109
Throws error if the command fails
109110
"""
110-
print(log_msg)
111-
print(cmd.replace("\\", "\\\\"))
111+
logger.info(log_msg)
112+
logger.info(f"log file can be found at {log_file_path}")
113+
logger.info(cmd.replace("\\", "\\\\"))
112114
with open(log_file_path, "w") as log_file:
113115
process = subprocess.Popen(cmd,
114116
stdout=log_file,
@@ -170,7 +172,7 @@ def gen_qsys_system(target, custom_components, sys_clock_rate_hz, template, work
170172
"""
171173
ipx_file = "components.ipx"
172174
copyfile(RES_DIR + ipx_file, working_dir + ipx_file)
173-
175+
174176
if not(system_exists(target.system_name, working_dir)):
175177
gen_qsys_file(target, custom_components, sys_clock_rate_hz, template, working_dir)
176178
gen_qsys_system_from_qsys_file(target.system_name, working_dir)
@@ -212,7 +214,8 @@ def gen_project_tcl(project_name, target, template, working_dir):
212214
top_level_vhdl_file = target.top_level_vhdl_file
213215
original_system = target.original_system
214216

215-
print("Generating make_project.tcl")
217+
logger.info("Generating make_project.tcl")
218+
216219
with open(working_dir + "make_project.tcl", "w") as proj_file:
217220
proj_file.write(template.add_quartus_project(
218221
project_name, target))
@@ -244,7 +247,7 @@ def gen_pll_qsys(working_dir):
244247

245248
def project_with_revision_exists(project_name, project_revision, working_dir):
246249
try:
247-
with open(working_dir + project_name, "r") as project_file:
250+
with open(working_dir + project_name + ".qpf", "r") as project_file:
248251
for line in project_file:
249252
if f"PROJECT_REVISION = \"{project_revision}\"" in line:
250253
return True
@@ -273,10 +276,9 @@ def gen_project(project_name, target, template, working_dir):
273276

274277
def compile_project(project_name, project_revision, template, working_dir):
275278
tcl_file = "compile_project.tcl"
276-
if not(os.path.isfile(working_dir + tcl_file)):
277-
with open(working_dir + tcl_file, "w") as compile_file:
278-
compile_file.write(template.add_quartus_compile_project(
279-
project_name, project_revision))
279+
with open(working_dir + tcl_file, "w") as compile_file:
280+
compile_file.write(template.add_quartus_compile_project(
281+
project_name, project_revision))
280282

281283
log_msg = "Compiling project"
282284
cmd = f"cd {working_dir} && {QUARTUS_BIN_DIR}quartus_sh -t {tcl_file}"
@@ -301,6 +303,9 @@ def gen_rbf(working_dir, target_system):
301303

302304
run_cmd_and_log(cmd, log_msg, log_file_path)
303305

306+
def init_logging():
307+
global logger
308+
logger = logging.getLogger('autogen_quartus')
304309

305310
def execute_quartus_workflow(target_system, custom_components, sys_clock_rate_hz, working_dir=""):
306311
"""Executes quartus workflow that creates a system and project, compiles it,
@@ -313,6 +318,7 @@ def execute_quartus_workflow(target_system, custom_components, sys_clock_rate_hz
313318
working_dir : str, optional
314319
Working directory of the generation process, by default ""
315320
"""
321+
init_logging()
316322
target = None
317323

318324
if(target_system == "audiomini"):
@@ -322,7 +328,7 @@ def execute_quartus_workflow(target_system, custom_components, sys_clock_rate_hz
322328
else:
323329
raise ValueError(
324330
f"The provided target: {target_system} is not supported")
325-
331+
326332
abspath = os.path.abspath(__file__)
327333
dname = os.path.dirname(abspath)
328334
global RES_DIR

vhdl/quartus/res/Audiomini_System.vhd renamed to vhdl/quartus/res/Audiomini.vhd

+4-4
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ USE altera.altera_primitives_components.all;
1717
-- Signal Names are defined in the DE10-Nano User Manual
1818
-- http://de10-nano.terasic.com
1919
-----------------------------------------------------------
20-
entity DE10Nano_System is
20+
entity Audiomini is
2121
port(
2222
----------------------------------------
2323
-- CLOCK Inputs
@@ -198,11 +198,11 @@ USE altera.altera_primitives_components.all;
198198
HPs_USB_NXT : in STD_LOGIC
199199

200200
);
201-
end entity DE10Nano_System;
201+
end entity Audiomini;
202202

203203

204204

205-
architecture DE10Nano_arch of DE10Nano_System is
205+
architecture Audiomini_arch of Audiomini is
206206

207207

208208
--------------------------------------------------------------
@@ -560,4 +560,4 @@ begin
560560
ADC_CONVST <= '0';
561561
ADC_SCK <= '0';
562562
ADC_SDI <= '0';
563-
end architecture DE10Nano_arch;
563+
end architecture Audiomini_arch;

vhdl/quartus/res/audiomini_proj.tcl

+1-1
Original file line numberDiff line numberDiff line change
@@ -516,7 +516,7 @@ set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to Audio_Mini_GPIO_0[33
516516
set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to Audio_Mini_GPIO_1[12]
517517
set_global_assignment -name FAMILY "Cyclone V"
518518
set_global_assignment -name DEVICE 5CSEBA6U23I7
519-
set_global_assignment -name TOP_LEVEL_ENTITY Audiomini_System
519+
set_global_assignment -name TOP_LEVEL_ENTITY Audiomini
520520
set_global_assignment -name MIN_CORE_JUNCTION_TEMP "-40"
521521
set_global_assignment -name MAX_CORE_JUNCTION_TEMP 100
522522
set_global_assignment -name POWER_PRESET_COOLING_SOLUTION "23 MM HEAT SINK WITH 200 LFPM AIRFLOW"

vhdl/quartus/target.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77

88
Audiomini = Target(name='audiomini', system_name='audiomini_system', device_family='Cyclone V',
99
device='5CSEBA6U23I7', base_qsys_file='soc_base_system.qsys', base_proj_tcl_file='audiomini_proj.tcl',
10-
files_list=['audiominiNano_System.vhd',
10+
files_list=['Audiomini.vhd',
1111
'audiomini_system/synthesis/audiomini_system.qip'],
12-
top_level_vhdl_file='audiomini_System.vhd', original_system='soc_system', base_address='20', axi_master_name='hps.h2f_lw_axi_master',
12+
top_level_vhdl_file='Audiomini.vhd', original_system='soc_system', base_address='20', axi_master_name='hps.h2f_lw_axi_master',
1313
audio_in='FE_Qsys_AD1939_Audio_Mini_v1_0.Line_In', audio_out='FE_Qsys_AD1939_Audio_Mini_v1_0.Headphone_Out',
1414
clock_name='clk_hps'
1515
)

vhdl/vgenQuartus.m

-38
This file was deleted.

vhdl/vgen_process_simulink_model.m

+39-13
Original file line numberDiff line numberDiff line change
@@ -89,16 +89,44 @@
8989

9090
%% Generate the .tcl script to be used by Platform Designer in Quartus
9191
disp('vgen: Creating .tcl script for Platform Designer.')
92-
infile = [avalon.entity '.json'];
92+
config_file = [avalon.entity '.json'];
9393
% NOTE: platform designer only adds components if they have the _hw.tcl suffix
9494
outfile = [hdlpath filesep avalon.entity '_avalon_hw.tcl'];
95-
disp(['file ' infile ' out ' outfile ' path ' hdlpath])
96-
vgenHwTcl(infile, outfile, hdlpath)
95+
disp(['file ' config_file ' out ' outfile ' path ' hdlpath])
96+
vgenHwTcl(config_file, outfile, hdlpath)
9797

9898
disp([' created tcl file: ' outfile])
9999

100100
disp('vgen: Executing Quartus workflow')
101-
vgenQuartus(infile, hdlpath + "/quartus/")
101+
if ispc; second_cmd = "&"; else; second_cmd = ";"; end
102+
working_dir = hdlpath + "/quartus/";
103+
quartus_workflow_cmd = "python " + mp.vhdl_codegen_path + "/autogen_quartus.py -j " + config_file ...
104+
+ " -w " + working_dir + " -l " + second_cmd + " exit &";
105+
disp(quartus_workflow_cmd)
106+
system(quartus_workflow_cmd);
107+
108+
fid = fopen("autogen_quartus.log");
109+
if fid>0
110+
% loop until end of file is reached
111+
while 1
112+
% read the current line
113+
where = ftell(fid);
114+
line = fgetl(fid);
115+
% Print file until exit is encountered
116+
if line == -1
117+
pause(20/1000)
118+
fseek(fid, where, 'bof');
119+
elseif line == "exit"
120+
break
121+
else
122+
disp(line)
123+
end
124+
end
125+
% close the file
126+
fclose(fid);
127+
end
128+
129+
%disp("r: ---------------------------------------------------\n" + r)
102130
disp('Executed Quartus workflow')
103131

104132
%% Generate the device driver code
@@ -114,10 +142,6 @@
114142
disp([' created Kbuild: ' [hdlpath filesep 'Kbuild']])
115143

116144
%% Build kernel module
117-
% TODO: this needs to be platform independent, but how? Our Windows users
118-
% use a virtual machine to compile the device driver, but that
119-
% won't automate very well. Maybe we can build the kernel module
120-
% with Quartus' embedded command shell instead?
121145
disp('Building kernel module.')
122146
cd(hdlpath)
123147
if ispc
@@ -136,12 +160,14 @@
136160

137161
% TODO: this file now generates C code, but "vgen" make it seem like it is just VHDL still. This should be changed, and the repository should be reorganized a bit.
138162
% This file shouldn't live in the vhdl folder anymore.
163+
%% Build Device Tree blob
139164
project_revision = mp.model_name + "_" + mp.target_system;
140-
try
141-
py.generate.generate_device_tree_overlay(hdlpath + "/quartus/" + mp.target_system + '_system.sopcinfo', project_revision + '.rbf')
142-
catch e
143-
disp(getReport(e))
144-
end
165+
sopcinfo_file = hdlpath + "/quartus/" + mp.target_system + '_system.sopcinfo';
166+
disp("Generating device tree source file")
167+
disp("python " + mp.dtogen_path + filesep + "dtogen -s " + sopcinfo_file + " -r " + project_revision + " -o " + hdlpath)
168+
system("python " + mp.dtogen_path + filesep + "dtogen -s " + sopcinfo_file + " -r " + project_revision + " -o " + hdlpath);
169+
170+
disp("Compiling device tree source file")
145171

146172
if ispc
147173
if system('wsl.exe cd') == 0

0 commit comments

Comments
 (0)