Reputation: 1290
To enable me to have text based graphical documentation that is as auto-generated as possible, I would like to be able to define several node types, and have those definitions be importable
I am working on a project where I auto generate a Graphviz dot RTL diagram for a hardware design written in VHDL. The definition for the nodes I am defining is complicated and gross and should be hidden from the user. I would like to be able to define several node types, and have those definitions be importable and easily instantiated. I am starting to get the feeling graphviz/dot may not be the correct solution, and I'll happily abandon Graphviz for something better. I just want to generate text based graphical documentation that is as auto-generated as possible. Currently I generate a complicated node definition like:
Full_Adder_1bit [shape=plaintext, label=<
<table border='1' cellborder='0' cellspacing='0'>
<tr><td>Full_Adder_1bit</td></tr>
<tr>
<td><table border='0' cellborder='1' cellspacing='0' color='green'>
<tr><td port='A'> A </td></tr>
<tr><td port='B'> B </td></tr>
<tr><td port='Cin'> Cin </td></tr>
</table></td>
<td><table border='0' cellborder='1' cellspacing='0' color='red'>
<tr><td port='Sum'> Sum </td></tr>
<tr><td port='Cout'> Cout </td></tr>
</table></td>
</tr>
</table> >]
And in order for a user to make use of this to document their design they would have to use the node keyword properly and then create the nodes/ports to connect.
node [shape=plaintext, label=<
<table border='1' cellborder='0' cellspacing='0'>
<tr><td>Full_Adder_1bit</td></tr>
<tr>
<td><table border='0' cellborder='1' cellspacing='0' color='green'>
<tr><td port='A'> A </td></tr>
<tr><td port='B'> B </td></tr>
<tr><td port='Cin'> Cin </td></tr>
</table></td>
<td><table border='0' cellborder='1' cellspacing='0' color='red'>
<tr><td port='Sum'> Sum </td></tr>
<tr><td port='Cout'> Cout </td></tr>
</table></td>
</tr>
</table> >]
// -- MAIN --
add1:Cout -> add2:Cin
add2:Cout -> add3:Cin
add3:Cout -> add4:Cin
This question does not answer my question because what I would like to do is this:
Full_Adder_1bit [shape=plaintext, label=<
<table border='1' cellborder='0' cellspacing='0'>
<tr><td>Full_Adder_1bit</td></tr>
<tr>
<td><table border='0' cellborder='1' cellspacing='0' color='green'>
<tr><td port='A'> A </td></tr>
<tr><td port='B'> B </td></tr>
<tr><td port='Cin'> Cin </td></tr>
</table></td>
<td><table border='0' cellborder='1' cellspacing='0' color='red'>
<tr><td port='Sum'> Sum </td></tr>
<tr><td port='Cout'> Cout </td></tr>
</table></td>
</tr>
</table> >]
include(`lib.dot')
add1 : instance of (Full_Adder_1bit)
add2 : instance of (Full_Adder_1bit)
add3 : instance of (Full_Adder_1bit)
add4 : instance of (Full_Adder_1bit)
// -- MAIN --
add1:Cout -> add2:Cin
add2:Cout -> add3:Cin
add3:Cout -> add4:Cin
Upvotes: 1
Views: 237
Reputation: 2637
You could use a c-preprocessor
or use subgraph's to control which nodes get which label label (added some gates to get a more illustrative example)
e.g.
digraph G {
rankdir=LR
// definitions
subgraph Full_Adder_1bit { node [shape=plaintext, label=<
<table border='1' cellborder='0' cellspacing='0'>
<tr><td>Full_Adder_1bit</td></tr>
<tr>
<td><table border='0' cellborder='1' cellspacing='0' color='green'>
<tr><td port='A'> A </td></tr>
<tr><td port='B'> B </td></tr>
<tr><td port='Cin'> Cin </td></tr>
</table></td>
<td><table border='0' cellborder='1' cellspacing='0' color='red'>
<tr><td port='Sum'> Sum </td></tr>
<tr><td port='Cout'> Cout </td></tr>
</table></td>
</tr>
</table> >]
}
subgraph NAND {
node[label=<<table border="0" cellspacing="0" cellborder="1">
<tr><td port='A'>A</td><td port='out' rowspan="2">NAND</td></tr>
<tr><td port='B'>B</td></tr>
</table>> shape=none margin=0]
}
subgraph AND {
node[label=<<table border="0" cellspacing="0" cellborder="1">
<tr><td port='A'>A</td><td port='out' rowspan="2">AND</td></tr>
<tr><td port='B'>B</td></tr>
</table>> shape=none margin=0]
}
subgraph NOR {
node[label=<<table border="0" cellspacing="0" cellborder="1">
<tr><td port='A'>A</td><td port='out' rowspan="2">NOR</td></tr>
<tr><td port='B'>B</td></tr>
</table>> shape=none margin=0]
}
subgraph OR {
node[label=<<table border="0" cellspacing="0" cellborder="1">
<tr><td port='A'>A</td><td port='out' rowspan="2">OR</td></tr>
<tr><td port='B'>B</td></tr>
</table>> shape=none margin=0]
}
subgraph NOT {
node[label=<<table border="0" cellspacing="0" cellborder="1">
<tr><td port='A'>A</td><td port='out' >NOT</td></tr>
</table>> shape=none margin=0]
}
subgraph Point { node[shape=point xlabel="\N"] }
// declarations
subgraph Point { A_xor B_xor out_xor }
subgraph AND { and1 and2 }
subgraph NOT { not1 not2 }
subgraph OR { or1 }
// connections
A_xor->and1:A
A_xor->not1:A not1:out->and2:A
B_xor->and2:B
B_xor->not2:A not2:out->and1:B
and1:out->or1:A
and2:out->or1:B
or1:out->out_xor
subgraph Full_Adder_1bit {
add1:Cout -> add2:Cin
add2:Cout -> add3:Cin
add3:Cout -> add4:Cin
}
}
Upvotes: 1