Skip to content

Commit e71ace5

Browse files
authored
Merge pull request #344 from antmicro/separate-comp
Systemverilog: Add separate compilation flow
2 parents 9d3f0b6 + 3bf2010 commit e71ace5

File tree

9 files changed

+153
-16
lines changed

9 files changed

+153
-16
lines changed

systemverilog-plugin/README.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,3 +100,18 @@ yosys> write_edif counter.edif
100100
101101
```
102102
As a result we get a `counter.edif` file that can be further processed to get the bitstream.
103+
104+
### Parsing multiple files
105+
When parsing multiple files you can either pass them together to the `read_systemverilog` command
106+
or read them one by one using `-defer` flag. In the latter case, you will need to call
107+
`readsystemverilog -link` after processing all files to elaborate them. An example flow would
108+
look like below:
109+
```
110+
plugin -i systemverilog
111+
# Read each file separately
112+
read_systemverilog -defer dut.sv
113+
read_systemverilog -defer top.sv
114+
# Finish reading files, elaborate the design
115+
read_systemverilog -link
116+
# Continue Yosys flow...
117+
```

systemverilog-plugin/tests/Makefile

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,12 @@
1414
#
1515
# SPDX-License-Identifier: Apache-2.0
1616

17-
TESTS = counter break_continue
17+
TESTS = counter \
18+
break_continue \
19+
separate-compilation
1820

1921
include $(shell pwd)/../../Makefile_test.common
2022

2123
counter_verify = true
2224
break_continue_verify = $(call diff_test,break_continue,out)
25+
separate-compilation_verify = true
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
// Copyright 2020-2022 F4PGA Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
//
15+
// SPDX-License-Identifier: Apache-2.0
16+
module BUF (
17+
input I,
18+
output O
19+
);
20+
assign O = I;
21+
endmodule;
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
// Copyright 2020-2022 F4PGA Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
//
15+
// SPDX-License-Identifier: Apache-2.0
16+
package pkg;
17+
parameter BITS = 4;
18+
parameter LOG2DELAY = 22;
19+
endpackage
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
yosys -import
2+
if { [info procs read_uhdm] == {} } { plugin -i systemverilog }
3+
yosys -import ;# ingest plugin commands
4+
5+
set TMP_DIR /tmp
6+
if { [info exists ::env(TMPDIR) ] } {
7+
set TMP_DIR $::env(TMPDIR)
8+
}
9+
10+
# Testing simple round-trip
11+
read_systemverilog -odir $TMP_DIR/separate-compilation-test -defer $::env(DESIGN_TOP)-pkg.sv
12+
read_systemverilog -odir $TMP_DIR/separate-compilation-test -defer $::env(DESIGN_TOP)-buf.sv
13+
read_systemverilog -odir $TMP_DIR/separate-compilation-test -defer $::env(DESIGN_TOP).v
14+
read_systemverilog -odir $TMP_DIR/separate-compilation-test -link
15+
hierarchy
16+
write_verilog
Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2020-2022 F4PGA Authors
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
//
15+
// SPDX-License-Identifier: Apache-2.0
16+
module top (
17+
input clk,
18+
output [3:0] led
19+
);
20+
21+
wire bufg;
22+
BUF bufgctrl (
23+
.I(clk),
24+
.O(bufg)
25+
);
26+
reg [pkg::BITS + pkg::LOG2DELAY-1 : 0] counter = 0;
27+
always @(posedge bufg) begin
28+
counter <= counter + 1;
29+
end
30+
assign led[3:0] = counter >> pkg::LOG2DELAY;
31+
endmodule

systemverilog-plugin/uhdmastshared.h

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,14 @@ class UhdmAstShared
4242
// applies only to read_systemverilog command
4343
bool parse_only = false;
4444

45+
// Flag that determines whether we should defer the elaboration
46+
// applies only to read_systemverilog command
47+
bool defer = false;
48+
49+
// Flag that determines whether we should perform the elaboration now
50+
// applies only to read_systemverilog command
51+
bool link = false;
52+
4553
// Top nodes of the design (modules, interfaces)
4654
std::unordered_map<std::string, AST::AstNode *> top_nodes;
4755

systemverilog-plugin/uhdmcommonfrontend.cc

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ void UhdmCommonFrontend::print_read_options()
3333
log(" ignore assert() statements");
3434
log("\n");
3535
log(" -debug\n");
36-
log(" alias for -dump_ast1 -dump_ast2 -dump_vlog1 -dump_vlog2 -yydebug\n");
36+
log(" alias for -dump_ast1 -dump_ast2 -dump_vlog1 -dump_vlog2\n");
3737
log("\n");
3838
log(" -dump_ast1\n");
3939
log(" dump abstract syntax tree (before simplification)\n");
@@ -53,16 +53,17 @@ void UhdmCommonFrontend::print_read_options()
5353
log(" -dump_rtlil\n");
5454
log(" dump generated RTLIL netlist\n");
5555
log("\n");
56-
log(" -yydebug\n");
57-
log(" enable parser debug output\n");
58-
log("\n");
5956
log(" -report [directory]\n");
6057
log(" write a coverage report for the UHDM file\n");
6158
log("\n");
6259
log(" -defer\n");
6360
log(" only read the abstract syntax tree and defer actual compilation\n");
6461
log(" to a later 'hierarchy' command. Useful in cases where the default\n");
6562
log(" parameters of modules yield invalid or not synthesizable code.\n");
63+
log(" Needs to be followed by read_systemverilog -link after reading\n");
64+
log(" all files.\n");
65+
log(" -link\n");
66+
log(" performs linking and elaboration of the files read with -defer\n");
6667
log(" -parse-only\n");
6768
log(" this parameter only applies to read_systemverilog command,\n");
6869
log(" it runs only Surelog to parse design, but doesn't load generated\n");
@@ -97,7 +98,7 @@ void UhdmCommonFrontend::execute(std::istream *&f, std::string filename, std::ve
9798
} else if (args[i] == "-noassert") {
9899
this->shared.no_assert = true;
99100
} else if (args[i] == "-defer") {
100-
defer = true;
101+
this->shared.defer = true;
101102
} else if (args[i] == "-dump_ast1") {
102103
dump_ast1 = true;
103104
} else if (args[i] == "-dump_ast2") {
@@ -110,15 +111,20 @@ void UhdmCommonFrontend::execute(std::istream *&f, std::string filename, std::ve
110111
no_dump_ptr = true;
111112
} else if (args[i] == "-dump_rtlil") {
112113
dump_rtlil = true;
113-
} else if (args[i] == "-yydebug") {
114-
this->shared.debug_flag = true;
115114
} else if (args[i] == "-parse-only") {
116115
this->shared.parse_only = true;
116+
} else if (args[i] == "-link") {
117+
this->shared.link = true;
118+
// Surelog needs it in the command line to link correctly
119+
unhandled_args.push_back(args[i]);
117120
} else {
118121
unhandled_args.push_back(args[i]);
119122
}
120123
}
121-
extra_args(f, filename, args, args.size() - 1);
124+
// Yosys gets confused when extra_args are passed with -link or no option
125+
// It's done fully by Surelog, so skip it in this case
126+
if (!this->shared.link)
127+
extra_args(f, filename, args, args.size() - 1);
122128
// pass only unhandled args to Surelog
123129
// unhandled args starts with command name,
124130
// but Surelog expects args[0] to be program name

systemverilog-plugin/uhdmsurelogastfrontend.cc

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -108,9 +108,19 @@ struct UhdmSurelogAstFrontend : public UhdmCommonFrontend {
108108
// Force -parse flag settings even if it wasn't specified
109109
clp->setwritePpOutput(true);
110110
clp->setParse(true);
111-
clp->setCompile(true);
112-
clp->setElaborate(true);
113111
clp->fullSVMode(true);
112+
clp->setCacheAllowed(true);
113+
if (this->shared.defer) {
114+
clp->setCompile(false);
115+
clp->setElaborate(false);
116+
clp->setSepComp(true);
117+
} else {
118+
clp->setCompile(true);
119+
clp->setElaborate(true);
120+
}
121+
if (this->shared.link) {
122+
clp->setLink(true);
123+
}
114124

115125
SURELOG::scompiler *compiler = nullptr;
116126
const std::vector<vpiHandle> uhdm_design = executeCompilation(symbolTable, errors, clp, compiler);
@@ -121,11 +131,6 @@ struct UhdmSurelogAstFrontend : public UhdmCommonFrontend {
121131
}
122132
}
123133

124-
UHDM::Serializer serializer;
125-
UHDM::SynthSubset *synthSubset = new UHDM::SynthSubset(&serializer, this->shared.nonSynthesizableObjects, false);
126-
synthSubset->listenDesigns(uhdm_design);
127-
delete synthSubset;
128-
129134
SURELOG::shutdown_compiler(compiler);
130135
delete clp;
131136
delete symbolTable;
@@ -136,6 +141,19 @@ struct UhdmSurelogAstFrontend : public UhdmCommonFrontend {
136141
return nullptr;
137142

138143
UhdmAst uhdm_ast(this->shared);
144+
if (this->shared.defer && !this->shared.link)
145+
return nullptr;
146+
147+
// FIXME: SynthSubset annotation is incompatible with separate compilation
148+
// `-defer` turns elaboration off, so check for it
149+
// Should be called 1. for normal flow 2. after finishing with `-link`
150+
if (!this->shared.defer) {
151+
UHDM::Serializer serializer;
152+
UHDM::SynthSubset *synthSubset = new UHDM::SynthSubset(&serializer, this->shared.nonSynthesizableObjects, false);
153+
synthSubset->listenDesigns(uhdm_design);
154+
delete synthSubset;
155+
}
156+
139157
AST::AstNode *current_ast = uhdm_ast.visit_designs(uhdm_design);
140158
if (!this->report_directory.empty()) {
141159
this->shared.report.write(this->report_directory);

0 commit comments

Comments
 (0)