Open jdanders opened 4 years ago
Hi, thanks for pitching your idea. Summarizing the problem, it sounds like you just want `include
dependency information (happens to be in make
form). In C/C++ compiler toolchains, this information is available through preprocessing (evaluating command-line define
s -I
/incdirs
, ifdef
conditionals, recursive include
s, etc). SystemVerilog is a little crazier in letting you synthesize file names from creating macro expansions and late-evaluation string-literals. If you had such a fully-featured standard-compliant preprocessor today, that would be your best bet for attaining that information, and it would be perfect and precise.
Verible doesn't have a proper preprocessor yet (we are looking for one, see #183 ), and there is a start of what I call a pseudo-preprocessor here: https://github.com/google/verible/tree/master/verilog/preprocessor. You might be able to find a suitable fully-featured preprocessor through tools like Verilator.
That said, if you're able to tolerate imperfect information from Verible's unpreprocessed token stream, you might be able to create something "good enough". If you limit/assume include
s to examine constant string literals, that will get you pretty far. If you can tolerate false-but-conservative dependencies (such as those that require evaluation of conditionals), your makedepend file will still be usable, just occasionally trigger unnecessary rebuilds. Currently verilog_syntax
doesn't expand includes, so you will miss recursive include dependencies, however, you could analyze your included files in a recursive worklist in a similar fashion.
Idea:
include
directives for their "files"Maybe the reference to gcc
confused things a bit because this does not need to be done like gcc
does it. The example doesn't require any preprocessing, just identification that there was an included file, but not processing that included file. If I want the dependencies of "my_incl.svh"
I would run verilog_syntax
on my_incl.svh
in a subsequent step (the recursive worklist you mention). To put it another way, I would want this a standalone command that works on just the input file without any expansion to other files. Part of the motivation for that is that this step is part of discovering the entire project, so that information isn't even available yet. The goal of the build system is to auto-discover both dependencies and the files so you don't have to maintain file lists.
This likely means the best I could hope for is "good enough" because it would not be able to apply any preprocessor define
or if
statements, unless maybe those were passed in as part of the command. So, yes, I am okay with the limitations you've called out.
I am afraid I don't understand your idea steps though. If you remove everything unrelated to preprocessing, then you would remove all the module instances and package calls. It looks like the idea would only get the include files.
Ah, so beyond include
s you want to build up symbolic dependencies (e.g. provides/requires/defines/uses). For that, we're looking at #185 . This isn't done yet, but there is a lot of interest in this (for linter analyses, code indexing, dependency extraction, design crawling).
One way to get started is to build up (per source file) definition and reference information (akin to a symbol database). You might even ignore preprocessing and evaluate all branches, or some other pseudo preprocessing strategy. You could walk the concrete syntax tree of every parsed file to extract this information.
I found verible searching for something to help me in my
make
-based build system. I'm looking for something that can function similarly togcc -M
.Consider this file,
testcase.sv
:If I ran
verilog_syntax -printmakedepend test.sv
, the result would be something like this:The format of the output isn't terribly important, as I can munge it to what I need, but the difficult problem without a full parser is identifying the module name(s) and dependencies. I think it is sufficient (in my style of SV coding at least) to classify includes, packages, and module/interface instances as dependencies.
I might be able to figure something out from the output of
verilog_syntax -printtokens
and I may even take a look and see if I can contribute here, but I thought I'd get the idea out there.Here's a helpful page describing the general
make
architecture I'm creating.