Merge 8428032d83 into 31d1850bc8
This commit is contained in:
commit
4f8323f27c
|
|
@ -21,3 +21,4 @@ Icarus Verilog. The code generator is selected by the "-t" command line flag.
|
||||||
tgt-sizer
|
tgt-sizer
|
||||||
tgt-verilog
|
tgt-verilog
|
||||||
tgt-blif
|
tgt-blif
|
||||||
|
tgt-flow
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,99 @@
|
||||||
|
The Flow Dataflow Exporter (-tflow)
|
||||||
|
===================================
|
||||||
|
|
||||||
|
The flow code generator exports the elaborated design as a JSON
|
||||||
|
*dataflow database* rather than a simulation or netlist artifact. The
|
||||||
|
output describes the module hierarchy, the ports/parameters/signals of
|
||||||
|
each module, and the dataflow graph (which processes and continuous
|
||||||
|
assignments read and drive which nets), so that IDEs and analysis tools
|
||||||
|
can render dataflow panels, browse the elaborated hierarchy, and trace
|
||||||
|
input-to-output continuity across the design.
|
||||||
|
|
||||||
|
The emitted schema (``flowtracer1.verilog.v0``) is the Verilog companion
|
||||||
|
to the GHDL ``--flow`` exporter (``flowtracer1.vhdl.v0``), so a single
|
||||||
|
consumer works across Verilog (via this target) and VHDL (via GHDL)
|
||||||
|
designs.
|
||||||
|
|
||||||
|
|
||||||
|
USAGE
|
||||||
|
-----
|
||||||
|
|
||||||
|
::
|
||||||
|
|
||||||
|
% iverilog -tflow -o<path>.flow <source files>...
|
||||||
|
|
||||||
|
The flow target runs at elaboration time; no simulation is performed.
|
||||||
|
The root module of the elaborated design becomes the ``top`` of the
|
||||||
|
exported database. Because the exporter reads the fully elaborated
|
||||||
|
netlist, parameter values, generate blocks, and instance bindings are
|
||||||
|
all resolved.
|
||||||
|
|
||||||
|
|
||||||
|
OUTPUT
|
||||||
|
------
|
||||||
|
|
||||||
|
The output is a single JSON object with these top-level fields:
|
||||||
|
|
||||||
|
``schema``
|
||||||
|
Always ``"flowtracer1.verilog.v0"``.
|
||||||
|
|
||||||
|
``top``
|
||||||
|
The basename of the root module instance.
|
||||||
|
|
||||||
|
``modules``
|
||||||
|
One entry per module *type*, each with ``ports`` (name/direction/
|
||||||
|
type), ``generics`` (parameters), ``signals``, the name-based
|
||||||
|
``processes`` and ``assignments`` (with ``reads``/``drives``/
|
||||||
|
``sensitivity`` given as signal names), and the ``instances`` it
|
||||||
|
contains (with ``port_map`` and resolved ``generic_map``).
|
||||||
|
|
||||||
|
``hierarchy``
|
||||||
|
The elaborated instance tree. Each node carries its ``port_map``
|
||||||
|
(formal-to-actual associations resolved through the shared net) and
|
||||||
|
``children``. Generate blocks appear as transparent frames marked
|
||||||
|
``"scope": true`` with a ``generate`` object describing the kind
|
||||||
|
(``for``/``if``), label, and index.
|
||||||
|
|
||||||
|
``nets`` and ``cells``
|
||||||
|
A secondary, integer-id dataflow graph: ``nets`` are the canonical
|
||||||
|
nexuses (with ``drivers``/``loads`` referring to cell ids) and
|
||||||
|
``cells`` are the processes, gates, LPM devices, and constants (with
|
||||||
|
``drives``/``reads`` referring to net ids, plus ``clocked`` and
|
||||||
|
``clock_net``).
|
||||||
|
|
||||||
|
|
||||||
|
POSITIONS
|
||||||
|
---------
|
||||||
|
|
||||||
|
Every ``pos`` / ``inst_pos`` is a compact string of byte offsets,
|
||||||
|
``"start:begin:end"``, to help source-scanning consumers (such as Perl
|
||||||
|
lexers) locate constructs:
|
||||||
|
|
||||||
|
* *start* -- byte offset of the construct (first non-blank character of
|
||||||
|
its line);
|
||||||
|
* *begin* -- byte offset of the ``begin`` keyword that opens a
|
||||||
|
procedural or generate block -- empty when there is none;
|
||||||
|
* *end* -- byte offset of the closing ``end``/``endmodule`` keyword or
|
||||||
|
the terminating ``;`` -- empty for a plain point.
|
||||||
|
|
||||||
|
So a port or signal is ``"start::"``, a module is ``"start::end"``
|
||||||
|
(``module`` .. ``endmodule``), an instance is ``"start::end"`` (.. ``;``),
|
||||||
|
and an ``always``/``initial`` block or generate frame is
|
||||||
|
``"start:begin:end"``. Because the ``ivl_target`` API exposes only line
|
||||||
|
numbers, the exporter reads the source files and scans them (comment- and
|
||||||
|
string-aware) to recover these byte offsets and spans.
|
||||||
|
|
||||||
|
|
||||||
|
LIMITATIONS
|
||||||
|
-----------
|
||||||
|
|
||||||
|
Continuity through bit- and part-selects (for example a generate that
|
||||||
|
connects ``.d(bus[i])``) is not yet represented at the individual-bit
|
||||||
|
level; whole-signal connections are tracked.
|
||||||
|
|
||||||
|
For a process sensitive to several edges (for example an
|
||||||
|
asynchronous-reset flip-flop ``@(posedge clk or posedge rst)``), the
|
||||||
|
``clock_net`` field reports the first edge signal.
|
||||||
|
|
||||||
|
Constant tie-offs and synthetic compiler temporaries are summarized
|
||||||
|
rather than reported individually.
|
||||||
|
|
@ -40,7 +40,7 @@ VERSION_MAJOR = @VERSION_MAJOR@
|
||||||
VERSION_MINOR = @VERSION_MINOR@
|
VERSION_MINOR = @VERSION_MINOR@
|
||||||
|
|
||||||
SUBDIRS = ivlpp vhdlpp vvp vpi tgt-null tgt-stub tgt-vvp \
|
SUBDIRS = ivlpp vhdlpp vvp vpi tgt-null tgt-stub tgt-vvp \
|
||||||
tgt-vhdl tgt-vlog95 tgt-pcb tgt-blif tgt-sizer driver \
|
tgt-vhdl tgt-vlog95 tgt-pcb tgt-blif tgt-sizer tgt-flow driver \
|
||||||
ivtest
|
ivtest
|
||||||
# Only run distclean for these directories.
|
# Only run distclean for these directories.
|
||||||
NOTUSED = tgt-fpga tgt-pal tgt-verilog
|
NOTUSED = tgt-fpga tgt-pal tgt-verilog
|
||||||
|
|
|
||||||
|
|
@ -453,6 +453,7 @@ AC_CONFIG_FILES([
|
||||||
ivtest/Makefile
|
ivtest/Makefile
|
||||||
libveriuser/Makefile
|
libveriuser/Makefile
|
||||||
tgt-blif/Makefile
|
tgt-blif/Makefile
|
||||||
|
tgt-flow/Makefile
|
||||||
tgt-fpga/Makefile
|
tgt-fpga/Makefile
|
||||||
tgt-null/Makefile
|
tgt-null/Makefile
|
||||||
tgt-pal/Makefile
|
tgt-pal/Makefile
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
# Test list for the flow (-tflow) dataflow exporter target.
|
||||||
|
#
|
||||||
|
# Each entry names a Verilog source under flow/<name>.v. The runner
|
||||||
|
# flow_reg.py compiles it with `iverilog -tflow`, parses the resulting
|
||||||
|
# .flow JSON, and checks structural expectations (schema, hierarchy,
|
||||||
|
# processes/assignments, generate frames). Run with: python3 flow_reg.py
|
||||||
|
#
|
||||||
|
flow_basic
|
||||||
|
flow_comb
|
||||||
|
flow_generate
|
||||||
|
flow_genpath
|
||||||
|
|
@ -0,0 +1,3 @@
|
||||||
|
*.flow
|
||||||
|
*.log
|
||||||
|
log/
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
// Phase 0 test design: a counter instantiated inside a top module,
|
||||||
|
// to exercise scope hierarchy + nexus reachability in tgt-flow.
|
||||||
|
|
||||||
|
module counter #(parameter WIDTH = 4) (
|
||||||
|
input wire clk,
|
||||||
|
input wire rst,
|
||||||
|
input wire en,
|
||||||
|
output reg [WIDTH-1:0] count
|
||||||
|
);
|
||||||
|
always @(posedge clk or posedge rst) begin
|
||||||
|
if (rst)
|
||||||
|
count <= {WIDTH{1'b0}};
|
||||||
|
else if (en)
|
||||||
|
count <= count + 1'b1;
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module top (
|
||||||
|
input wire clk,
|
||||||
|
input wire rst,
|
||||||
|
output wire [3:0] q
|
||||||
|
);
|
||||||
|
wire enable = 1'b1;
|
||||||
|
counter #(.WIDTH(4)) u_cnt (
|
||||||
|
.clk (clk),
|
||||||
|
.rst (rst),
|
||||||
|
.en (enable),
|
||||||
|
.count (q)
|
||||||
|
);
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
// Richer Phase 2 test: comb always with case, ternary, continuous
|
||||||
|
// assign, and two levels of hierarchy.
|
||||||
|
|
||||||
|
module alu (
|
||||||
|
input wire [1:0] op,
|
||||||
|
input wire [7:0] a,
|
||||||
|
input wire [7:0] b,
|
||||||
|
output reg [7:0] y
|
||||||
|
);
|
||||||
|
always @(*) begin
|
||||||
|
case (op)
|
||||||
|
2'b00: y = a + b;
|
||||||
|
2'b01: y = a - b;
|
||||||
|
2'b10: y = a & b;
|
||||||
|
default: y = a ^ b;
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module datapath (
|
||||||
|
input wire [1:0] sel,
|
||||||
|
input wire [7:0] x,
|
||||||
|
input wire [7:0] z,
|
||||||
|
output wire [7:0] result,
|
||||||
|
output wire is_zero
|
||||||
|
);
|
||||||
|
wire [7:0] alu_out;
|
||||||
|
alu u_alu (.op(sel), .a(x), .b(z), .y(alu_out));
|
||||||
|
assign result = alu_out;
|
||||||
|
assign is_zero = (alu_out == 8'b0) ? 1'b1 : 1'b0;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module chip (
|
||||||
|
input wire [1:0] mode,
|
||||||
|
input wire [7:0] in0,
|
||||||
|
input wire [7:0] in1,
|
||||||
|
output wire [7:0] out,
|
||||||
|
output wire zero
|
||||||
|
);
|
||||||
|
datapath u_dp (
|
||||||
|
.sel (mode),
|
||||||
|
.x (in0),
|
||||||
|
.z (in1),
|
||||||
|
.result (out),
|
||||||
|
.is_zero(zero)
|
||||||
|
);
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,28 @@
|
||||||
|
// Phase 3 test: for-generate replicating a sub-module, plus an
|
||||||
|
// if-generate, to exercise generate-frame emission.
|
||||||
|
|
||||||
|
module inv #(parameter ID = 0) (
|
||||||
|
input wire d,
|
||||||
|
output wire q
|
||||||
|
);
|
||||||
|
assign q = ~d;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module gen_top #(parameter N = 3) (
|
||||||
|
input wire [2:0] din,
|
||||||
|
output wire [2:0] dout
|
||||||
|
);
|
||||||
|
genvar i;
|
||||||
|
generate
|
||||||
|
for (i = 0; i < 3; i = i + 1) begin : row
|
||||||
|
inv #(.ID(i)) u_cell (.d(din[i]), .q(dout[i]));
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
generate
|
||||||
|
if (N > 0) begin : opt
|
||||||
|
wire tap;
|
||||||
|
assign tap = din[0];
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
// Generate frame with WHOLE-signal port connections (isolates frame
|
||||||
|
// transparency from bit-select handling).
|
||||||
|
module inv8 (input wire [7:0] d, output wire [7:0] q);
|
||||||
|
assign q = ~d;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module wrap (input wire [7:0] din, output wire [7:0] dout);
|
||||||
|
generate
|
||||||
|
if (1) begin : blk
|
||||||
|
inv8 u_inv (.d(din), .q(dout));
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,210 @@
|
||||||
|
''' Regression runner for the flow (-tflow) dataflow exporter target.
|
||||||
|
|
||||||
|
For each test named in flow.list, this compiles flow/<name>.v with
|
||||||
|
`iverilog -tflow` and validates the resulting flowtracer1.verilog.v0
|
||||||
|
JSON: every output must be well-formed and carry the expected schema,
|
||||||
|
a top, and a non-empty module/hierarchy set; per-test checks then
|
||||||
|
assert the dataflow facts the exporter is meant to capture (clocked
|
||||||
|
processes, port-map continuity, continuous-assign cone reads, and
|
||||||
|
generate frames).
|
||||||
|
|
||||||
|
Run with: python3 flow_reg.py '''
|
||||||
|
|
||||||
|
import os
|
||||||
|
import re
|
||||||
|
import json
|
||||||
|
import subprocess
|
||||||
|
|
||||||
|
# Name of the iverilog command. May vary in different installations.
|
||||||
|
IVERILOG = "iverilog"
|
||||||
|
|
||||||
|
|
||||||
|
def get_tests() -> list:
|
||||||
|
'''Read the test names from flow.list (first word of each line).'''
|
||||||
|
match_prog = re.compile(r"^([a-zA-Z0-9_.]+).*$")
|
||||||
|
tests = []
|
||||||
|
with open("flow.list", encoding='ascii') as fd:
|
||||||
|
for line in fd:
|
||||||
|
if line[0] == "#":
|
||||||
|
continue
|
||||||
|
match = match_prog.search(line)
|
||||||
|
if match:
|
||||||
|
tests.append(match.group(1))
|
||||||
|
return tests
|
||||||
|
|
||||||
|
|
||||||
|
# ---- per-test structural checks ----------------------------------------
|
||||||
|
# Each returns (ok, message). `d` is the parsed .flow document.
|
||||||
|
|
||||||
|
def _module(d, name):
|
||||||
|
for m in d["modules"]:
|
||||||
|
if m["name"] == name:
|
||||||
|
return m
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def _find_in_hier(d, pred):
|
||||||
|
'''Depth-first search of hierarchy[] for a node matching pred.'''
|
||||||
|
stack = list(d["hierarchy"])
|
||||||
|
while stack:
|
||||||
|
n = stack.pop()
|
||||||
|
if pred(n):
|
||||||
|
return n
|
||||||
|
stack.extend(n.get("children", []))
|
||||||
|
return None
|
||||||
|
|
||||||
|
|
||||||
|
def check_basic(d):
|
||||||
|
if d["top"] != "top":
|
||||||
|
return False, "top != 'top'"
|
||||||
|
cnt = _module(d, "counter")
|
||||||
|
if not cnt:
|
||||||
|
return False, "no 'counter' module"
|
||||||
|
proc = [p for p in cnt["processes"]
|
||||||
|
if "count" in p["drives"] and p.get("sensitivity")]
|
||||||
|
if not proc:
|
||||||
|
return False, "no clocked process driving count"
|
||||||
|
# port_map continuity: u_cnt.count maps to parent net q
|
||||||
|
node = _find_in_hier(d, lambda n: n.get("module") == "counter")
|
||||||
|
if not node:
|
||||||
|
return False, "counter instance not in hierarchy"
|
||||||
|
pm = {a["formal"]: a["actuals"] for a in node["port_map"]}
|
||||||
|
if "q" not in pm.get("count", []):
|
||||||
|
return False, "port_map count->q missing"
|
||||||
|
return True, "clocked process + port_map ok"
|
||||||
|
|
||||||
|
|
||||||
|
def check_comb(d):
|
||||||
|
if d["top"] != "chip":
|
||||||
|
return False, "top != 'chip'"
|
||||||
|
dp = _module(d, "datapath")
|
||||||
|
if not dp:
|
||||||
|
return False, "no 'datapath' module"
|
||||||
|
res = [a for a in dp["assignments"]
|
||||||
|
if a["target"] == "result" and "alu_out" in a["reads"]]
|
||||||
|
if not res:
|
||||||
|
return False, "assign result<-alu_out (cone) missing"
|
||||||
|
return True, "continuous-assign cone read ok"
|
||||||
|
|
||||||
|
|
||||||
|
def check_generate(d):
|
||||||
|
frame = _find_in_hier(d, lambda n: n.get("scope") is True
|
||||||
|
and "generate" in n)
|
||||||
|
if not frame:
|
||||||
|
return False, "no generate frame in hierarchy"
|
||||||
|
kind = frame["generate"].get("kind")
|
||||||
|
if kind not in ("for", "if"):
|
||||||
|
return False, "generate.kind not for/if"
|
||||||
|
return True, "generate frame ({}) ok".format(kind)
|
||||||
|
|
||||||
|
|
||||||
|
def check_genpath(d):
|
||||||
|
# if-generate with whole-signal connection: the instance under the
|
||||||
|
# frame must resolve its actuals to the parent nets.
|
||||||
|
inst = _find_in_hier(d, lambda n: n.get("module") == "inv8")
|
||||||
|
if not inst:
|
||||||
|
return False, "inv8 instance not found under frame"
|
||||||
|
pm = {a["formal"]: a["actuals"] for a in inst["port_map"]}
|
||||||
|
if "din" not in pm.get("d", []) or "dout" not in pm.get("q", []):
|
||||||
|
return False, "port_map through frame not resolved"
|
||||||
|
return True, "generate-frame port_map ok"
|
||||||
|
|
||||||
|
|
||||||
|
CHECKS = {
|
||||||
|
"flow_basic": check_basic,
|
||||||
|
"flow_comb": check_comb,
|
||||||
|
"flow_generate": check_generate,
|
||||||
|
"flow_genpath": check_genpath,
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
def run_test(test_name: str) -> bool:
|
||||||
|
'''Compile one test with -tflow and validate its JSON.'''
|
||||||
|
src = "flow/" + test_name + ".v"
|
||||||
|
out = "flow/" + test_name + ".flow"
|
||||||
|
|
||||||
|
cmd = IVERILOG + " -g2012 -tflow -o" + out + " " + src
|
||||||
|
rc = subprocess.call(cmd + " > log/" + test_name + ".log 2>&1", shell=True)
|
||||||
|
if rc != 0:
|
||||||
|
return False
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(out, encoding='ascii') as fd:
|
||||||
|
doc = json.load(fd)
|
||||||
|
except (OSError, ValueError):
|
||||||
|
return False
|
||||||
|
|
||||||
|
# Invariants common to every well-formed output.
|
||||||
|
if doc.get("schema") != "flowtracer1.verilog.v0":
|
||||||
|
return False
|
||||||
|
if not doc.get("top") or not doc.get("modules") or not doc.get("hierarchy"):
|
||||||
|
return False
|
||||||
|
# Every position is the compact "start:begin:end" byte-offset string.
|
||||||
|
if not _positions_well_formed(doc):
|
||||||
|
return False
|
||||||
|
|
||||||
|
check = CHECKS.get(test_name)
|
||||||
|
if check:
|
||||||
|
ok, _msg = check(doc)
|
||||||
|
return ok
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
_POS_RE = re.compile(r"^[0-9]*:[0-9]*:[0-9]*$")
|
||||||
|
|
||||||
|
|
||||||
|
def _positions_well_formed(node) -> bool:
|
||||||
|
'''Every "pos"/"inst_pos" value, anywhere in the document, must be the
|
||||||
|
compact "start:begin:end" byte-offset string (parts may be empty).'''
|
||||||
|
if isinstance(node, dict):
|
||||||
|
for key, val in node.items():
|
||||||
|
if key in ("pos", "inst_pos"):
|
||||||
|
if not (isinstance(val, str) and _POS_RE.match(val)):
|
||||||
|
return False
|
||||||
|
elif not _positions_well_formed(val):
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
if isinstance(node, list):
|
||||||
|
return all(_positions_well_formed(x) for x in node)
|
||||||
|
return True
|
||||||
|
|
||||||
|
|
||||||
|
def get_ivl_version() -> list:
|
||||||
|
'''Get the iverilog version.'''
|
||||||
|
text = subprocess.check_output([IVERILOG, "-V"])
|
||||||
|
match = re.search(b'Icarus Verilog version ([0-9]+)\\.([0-9]+)', text)
|
||||||
|
if not match:
|
||||||
|
return None
|
||||||
|
items = match.groups()
|
||||||
|
return [str(items[0], 'ascii'), str(items[1], 'ascii')]
|
||||||
|
|
||||||
|
|
||||||
|
def run_tests(tests: list):
|
||||||
|
'''Run all tests in the list.'''
|
||||||
|
ivl_ver = get_ivl_version()
|
||||||
|
print("Running flow tests for Icarus Verilog version: {}.{}".format(
|
||||||
|
ivl_ver[0], ivl_ver[1]))
|
||||||
|
print("=" * 50)
|
||||||
|
|
||||||
|
if not os.path.exists("log"):
|
||||||
|
os.mkdir("log")
|
||||||
|
|
||||||
|
count_passed = 0
|
||||||
|
count_failed = 0
|
||||||
|
width = max(len(name) for name in tests)
|
||||||
|
for test in tests:
|
||||||
|
passed = run_test(test)
|
||||||
|
if passed:
|
||||||
|
count_passed += 1
|
||||||
|
res = "Passed"
|
||||||
|
else:
|
||||||
|
count_failed += 1
|
||||||
|
res = "Failed"
|
||||||
|
print("{name:>{width}}: {res}.".format(name=test, width=width, res=res))
|
||||||
|
|
||||||
|
print("=" * 50)
|
||||||
|
print("Tests results: Passed {}, Failed {}".format(count_passed, count_failed))
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
run_tests(get_tests())
|
||||||
|
|
@ -0,0 +1,106 @@
|
||||||
|
#
|
||||||
|
# This source code is free software; you can redistribute it
|
||||||
|
# and/or modify it in source code form under the terms of the GNU
|
||||||
|
# Library General Public License as published by the Free Software
|
||||||
|
# Foundation; either version 2 of the License, or (at your option)
|
||||||
|
# any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Library General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Library General Public
|
||||||
|
# License along with this program; if not, write to the Free
|
||||||
|
# Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
# Boston, MA 02110-1301, USA.
|
||||||
|
#
|
||||||
|
SHELL = /bin/sh
|
||||||
|
|
||||||
|
suffix = @install_suffix@
|
||||||
|
|
||||||
|
prefix = @prefix@
|
||||||
|
exec_prefix = @exec_prefix@
|
||||||
|
srcdir = @srcdir@
|
||||||
|
|
||||||
|
VPATH = $(srcdir)
|
||||||
|
|
||||||
|
bindir = @bindir@
|
||||||
|
libdir = @libdir@
|
||||||
|
includedir = $(prefix)/include
|
||||||
|
|
||||||
|
CC = @CC@
|
||||||
|
INSTALL = @INSTALL@
|
||||||
|
INSTALL_PROGRAM = @INSTALL_PROGRAM@
|
||||||
|
INSTALL_DATA = @INSTALL_DATA@
|
||||||
|
|
||||||
|
ifeq (@srcdir@,.)
|
||||||
|
INCLUDE_PATH = -I. -I..
|
||||||
|
else
|
||||||
|
INCLUDE_PATH = -I. -I.. -I$(srcdir) -I$(srcdir)/..
|
||||||
|
endif
|
||||||
|
|
||||||
|
CPPFLAGS = $(INCLUDE_PATH) @CPPFLAGS@ @DEFS@ @PICFLAG@
|
||||||
|
CFLAGS = @WARNING_FLAGS@ @WARNING_FLAGS_CC@ @CFLAGS@
|
||||||
|
LDFLAGS = @LDFLAGS@
|
||||||
|
|
||||||
|
O = flow.o
|
||||||
|
|
||||||
|
all: dep flow.tgt
|
||||||
|
|
||||||
|
check: all
|
||||||
|
|
||||||
|
clean:
|
||||||
|
rm -rf *.o dep flow.tgt
|
||||||
|
|
||||||
|
distclean: clean
|
||||||
|
rm -f Makefile config.log
|
||||||
|
|
||||||
|
cppcheck: $(O:.o=.c)
|
||||||
|
cppcheck --enable=all --std=c99 --std=c++11 -f \
|
||||||
|
--check-level=exhaustive \
|
||||||
|
--suppressions-list=$(srcdir)/../cppcheck-global.sup \
|
||||||
|
--relative-paths=$(srcdir) $(INCLUDE_PATH) $^
|
||||||
|
|
||||||
|
Makefile: $(srcdir)/Makefile.in ../config.status
|
||||||
|
cd ..; ./config.status --file=tgt-flow/$@
|
||||||
|
|
||||||
|
dep:
|
||||||
|
mkdir dep
|
||||||
|
|
||||||
|
%.o: %.c | dep
|
||||||
|
$(CC) $(CPPFLAGS) $(CFLAGS) @DEPENDENCY_FLAG@ -c $< -o $*.o
|
||||||
|
mv $*.d dep
|
||||||
|
|
||||||
|
ifeq (@WIN32@,yes)
|
||||||
|
TGTLDFLAGS=-L.. -livl
|
||||||
|
TGTDEPLIBS=../libivl.a
|
||||||
|
else
|
||||||
|
TGTLDFLAGS=
|
||||||
|
TGTDEPLIBS=
|
||||||
|
endif
|
||||||
|
|
||||||
|
flow.tgt: $O $(TGTDEPLIBS)
|
||||||
|
$(CC) @shared@ $(LDFLAGS) -o $@ $O $(TGTLDFLAGS)
|
||||||
|
|
||||||
|
install: all installdirs installfiles
|
||||||
|
|
||||||
|
F = ./flow.tgt \
|
||||||
|
$(srcdir)/flow.conf \
|
||||||
|
$(srcdir)/flow-s.conf
|
||||||
|
|
||||||
|
installfiles: $(F) | installdirs
|
||||||
|
$(INSTALL_PROGRAM) ./flow.tgt "$(DESTDIR)$(libdir)/ivl$(suffix)/flow.tgt"
|
||||||
|
$(INSTALL_DATA) $(srcdir)/flow.conf "$(DESTDIR)$(libdir)/ivl$(suffix)/flow.conf"
|
||||||
|
$(INSTALL_DATA) $(srcdir)/flow-s.conf "$(DESTDIR)$(libdir)/ivl$(suffix)/flow-s.conf"
|
||||||
|
|
||||||
|
installdirs: $(srcdir)/../mkinstalldirs
|
||||||
|
$(srcdir)/../mkinstalldirs "$(DESTDIR)$(libdir)/ivl$(suffix)"
|
||||||
|
|
||||||
|
uninstall:
|
||||||
|
rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/flow.tgt"
|
||||||
|
rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/flow.conf"
|
||||||
|
rm -f "$(DESTDIR)$(libdir)/ivl$(suffix)/flow-s.conf"
|
||||||
|
|
||||||
|
|
||||||
|
-include $(patsubst %.o, dep/%.d, $O)
|
||||||
|
|
@ -0,0 +1,6 @@
|
||||||
|
functor:synth2
|
||||||
|
functor:synth
|
||||||
|
functor:syn-rules
|
||||||
|
functor:cprop
|
||||||
|
functor:nodangle
|
||||||
|
flag:DLL=flow.tgt
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,3 @@
|
||||||
|
functor:cprop
|
||||||
|
functor:nodangle
|
||||||
|
flag:DLL=flow.tgt
|
||||||
Loading…
Reference in New Issue