2 * yosys -- Yosys Open SYnthesis Suite
4 * Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
6 * Permission to use, copy, modify, and/or distribute this software for any
7 * purpose with or without fee is hereby granted, provided that the above
8 * copyright notice and this permission notice appear in all copies.
10 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
11 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
12 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
13 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
14 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
15 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
16 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
20 #include "kernel/rtlil.h"
21 #include "kernel/register.h"
22 #include "kernel/sigtools.h"
23 #include "kernel/celltypes.h"
24 #include "kernel/log.h"
29 static std::string
netname(std::set
<std::string
> &conntypes_code
, std::set
<std::string
> &celltypes_code
, std::set
<std::string
> &constcells_code
, RTLIL::SigSpec sig
)
33 if (sig
.chunks
.size() != 1)
35 log_error("Can't export composite or non-word-wide signal %s.\n", log_signal(sig
));
37 conntypes_code
.insert(stringf("conntype b%d %d 2 %d\n", sig
.width
, sig
.width
, sig
.width
));
39 if (sig
.chunks
[0].wire
== NULL
) {
40 celltypes_code
.insert(stringf("celltype const%d b%d *CONST cfg:%d VALUE\n", sig
.width
, sig
.width
));
41 constcells_code
.insert(stringf("node const%d_0x%x const%d CONST const%d_%x VALUE 0x%x\n", sig
.width
, sig
.chunks
[0].data
.as_int(),
42 sig
.width
, sig
.width
, sig
.chunks
[0].data
.as_int(), sig
.chunks
[0].data
.as_int()));
43 return stringf("const%d_0x%x", sig
.width
, sig
.chunks
[0].data
.as_int());
46 if (sig
.chunks
[0].offset
!= 0 || sig
.width
!= sig
.chunks
[0].wire
->width
)
49 return unescape_id(sig
.chunks
[0].wire
->name
);
52 struct IntersynthBackend
: public Backend
{
53 IntersynthBackend() : Backend("intersynth", "write design to InterSynth netlist file") { }
56 // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
58 log(" write_intersynth [filename]\n");
60 log("Write the current design to an 'intersynth' netlist file. InterSynth is\n");
61 log("a tool for Coarse-Grain Example-Driven Interconnect Synthesis.\n");
63 log("http://www.clifford.at/intersynth/\n");
66 virtual void execute(FILE *&f
, std::string filename
, std::vector
<std::string
> args
, RTLIL::Design
*design
)
68 log_header("Executing INTERSYNTH backend.\n");
69 extra_args(f
, filename
, args
, 1);
70 log("Output filename: %s\n", filename
.c_str());
72 std::set
<std::string
> conntypes_code
, celltypes_code
;
73 std::string netlists_code
;
76 for (auto module_it
: design
->modules
)
78 RTLIL::Module
*module
= module_it
.second
;
79 SigMap
sigmap(module
);
81 if (module
->memories
.size() == 0 && module
->processes
.size() == 0 && module
->cells
.size() == 0)
84 log("Generating netlist %s.\n", id2cstr(module
->name
));
86 if (module
->memories
.size() != 0 || module
->processes
.size() != 0)
87 log_error("Can't generate a netlist for a module with unprocessed memories or processes!\n");
89 std::set
<std::string
> constcells_code
;
90 netlists_code
+= stringf("netlist %s\n", id2cstr(module
->name
));
92 for (auto wire_it
: module
->wires
) {
93 RTLIL::Wire
*wire
= wire_it
.second
;
94 if (wire
->port_input
|| wire
->port_output
) {
95 celltypes_code
.insert(stringf("celltype !%s b%d %sPORT\n" "%s %s %d %s PORT\n",
96 id2cstr(wire
->name
), wire
->width
, wire
->port_input
? "*" : "",
97 wire
->port_input
? "input" : "output", id2cstr(wire
->name
), wire
->width
, id2cstr(wire
->name
)));
98 netlists_code
+= stringf("node %s %s PORT %s\n", id2cstr(wire
->name
), id2cstr(wire
->name
),
99 netname(conntypes_code
, celltypes_code
, constcells_code
, sigmap(wire
)).c_str());
103 for (auto cell_it
: module
->cells
)
105 RTLIL::Cell
*cell
= cell_it
.second
;
106 std::string celltype_code
, node_code
;
108 celltype_code
= stringf("celltype %s", id2cstr(cell
->type
));
109 node_code
= stringf("node %s %s", id2cstr(cell
->name
), id2cstr(cell
->type
));
110 for (auto &port
: cell
->connections
) {
111 RTLIL::SigSpec sig
= sigmap(port
.second
);
112 conntypes_code
.insert(stringf("conntype b%d %d 2 %d\n", sig
.width
, sig
.width
, sig
.width
));
113 celltype_code
+= stringf(" b%d %s%s", sig
.width
, ct
.cell_output(cell
->type
, port
.first
) ? "*" : "", id2cstr(port
.first
));
114 node_code
+= stringf(" %s %s", id2cstr(port
.first
), netname(conntypes_code
, celltypes_code
, constcells_code
, sig
).c_str());
116 for (auto ¶m
: cell
->parameters
) {
117 celltype_code
+= stringf(" cfg:%d %s", int(param
.second
.bits
.size()), id2cstr(param
.first
));
118 if (param
.second
.bits
.size() != 32) {
119 node_code
+= stringf(" %s '", id2cstr(param
.first
));
120 for (int i
= param
.second
.bits
.size()-1; i
>= 0; i
--)
121 node_code
+= param
.second
.bits
[i
] == RTLIL::S1
? "1" : "0";
123 node_code
+= stringf(" %s 0x%x", id2cstr(param
.first
), param
.second
.as_int());
126 celltypes_code
.insert(celltype_code
+ "\n");
127 netlists_code
+= node_code
+ "\n";
131 for (auto str
: conntypes_code
)
132 fprintf(f
, "%s", str
.c_str());
133 for (auto str
: celltypes_code
)
134 fprintf(f
, "%s", str
.c_str());
135 fprintf(f
, "%s", netlists_code
.c_str());