blifutils 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/LICENSE +674 -0
- data/README.md +377 -0
- data/bin/blifutils +184 -0
- data/examples/zpu/compile_zpu_program/Makefile +114 -0
- data/examples/zpu/compile_zpu_program/README.md +10 -0
- data/examples/zpu/compile_zpu_program/main.c +68 -0
- data/examples/zpu/simulate_zpu.rb +23 -0
- data/examples/zpu/testbench_zpu.cc +132 -0
- data/examples/zpu/zpu_helloworld.bin +0 -0
- data/examples/zpu/zpu_mem16.blif +3519 -0
- data/examples/zpu/zpu_mem16.piccolo +351 -0
- data/lib/blifutils.rb +31 -0
- data/lib/blifutils/ast.rb +185 -0
- data/lib/blifutils/blif_to_vhdl.rb +180 -0
- data/lib/blifutils/elaborator.rb +257 -0
- data/lib/blifutils/layering.rb +406 -0
- data/lib/blifutils/level_analyzer.rb +143 -0
- data/lib/blifutils/lexer.rb +133 -0
- data/lib/blifutils/netlist.rb +808 -0
- data/lib/blifutils/parser.rb +251 -0
- data/lib/blifutils/simulator_generator.rb +342 -0
- data/share/blimulator_cpp_classes.cc +446 -0
- data/share/blimulator_cpp_classes.hh +136 -0
- data/test/sqrt8.blif +40 -0
- data/test/sqrt8.piccolo +132 -0
- data/test/sqrt8_PC.blif +43 -0
- data/test/sqrt8_PC_counter.blif +61 -0
- data/test/sqrt8_PC_done.blif +49 -0
- data/test/sqrt8_PC_state.blif +68 -0
- data/test/sqrt8_PO.blif +43 -0
- data/test/sqrt8_PO_output.blif +67 -0
- data/test/sqrt8_PO_sqrtr.blif +66 -0
- data/test/sqrt8_PO_work.blif +227 -0
- data/test/test_blifutils.rb +79 -0
- data/test/testbench_sqrt8.cc +48 -0
- metadata +102 -0
data/README.md
ADDED
@@ -0,0 +1,377 @@
|
|
1
|
+
|
2
|
+
BlifUtils
|
3
|
+
=========
|
4
|
+
|
5
|
+
BlifUtils is a library to handle BLIF netlists in Ruby.
|
6
|
+
The Berkeley Logic Interchange Format (BLIF) allows to describe logic-level
|
7
|
+
hierarchical circuits in textual form. Its specification can be found
|
8
|
+
[here](https://www.ece.cmu.edu/~ee760/760docs/blif.pdf). The BLIF format is
|
9
|
+
used by programs such as [ABC](http://people.eecs.berkeley.edu/~alanmi/abc/)
|
10
|
+
(logic synthesis) or [VPR](http://www.eecg.toronto.edu/~vaughn/papers/fpl97.pdf)
|
11
|
+
(placement and routing).
|
12
|
+
|
13
|
+
BlifUtils can read and write BLIF files,
|
14
|
+
elaborate internal representations of the netlists, analyze it, flattent modules,
|
15
|
+
write the modules as VHDL entities, and generate C++ code for fast
|
16
|
+
netlist simulation.
|
17
|
+
|
18
|
+
|
19
|
+
Installation
|
20
|
+
------------
|
21
|
+
|
22
|
+
To install BlifUtils from the git repository:
|
23
|
+
|
24
|
+
```lang-none
|
25
|
+
$ git clone https://github.com/TheotimeBollengier/blifutils
|
26
|
+
$ cd blifutils
|
27
|
+
$ gem build blifutils.gemspec
|
28
|
+
$ gem install blifutils.<version>.gem
|
29
|
+
```
|
30
|
+
|
31
|
+
Alternatively, the blifutils gem is also hosted on RubyGems
|
32
|
+
([https://rubygems.org/gems/blifutils](https://rubygems.org/gems/blifutils)).
|
33
|
+
So you can simply type:
|
34
|
+
|
35
|
+
```lang-none
|
36
|
+
$ gem install blifutils
|
37
|
+
```
|
38
|
+
|
39
|
+
BlifUtils uses the [RLTK](https://rubygems.org/gems/rltk) gem
|
40
|
+
([https://github.com/chriswailes/RLTK](https://github.com/chriswailes/RLTK)).
|
41
|
+
|
42
|
+
|
43
|
+
Example
|
44
|
+
-------
|
45
|
+
|
46
|
+
```ruby
|
47
|
+
require 'blifutils'
|
48
|
+
|
49
|
+
## Parse input file and sub-referenced files ##
|
50
|
+
netlist = BlifUtils::read('sqrt8.blif')
|
51
|
+
|
52
|
+
netlist.models.collect { |model| model.name }
|
53
|
+
#=> ["sqrt8",
|
54
|
+
# "sqrt8_PO",
|
55
|
+
# "sqrt8_PO_output",
|
56
|
+
# "sqrt8_PO_sqrtr",
|
57
|
+
# "sqrt8_PO_work",
|
58
|
+
# "sqrt8_PC",
|
59
|
+
# "sqrt8_PC_done",
|
60
|
+
# "sqrt8_PC_state",
|
61
|
+
# "sqrt8_PC_counter"]
|
62
|
+
|
63
|
+
puts netlist.get_model_by_name('sqrt8_PC').analyze
|
64
|
+
#=> "+----------------------------------------+
|
65
|
+
# | Model "sqrt8_PC" analysis |
|
66
|
+
# +----------------------------------------+
|
67
|
+
# Model "sqrt8_PC"
|
68
|
+
# Inputs: 2
|
69
|
+
# Outputs: 3
|
70
|
+
# Nets: 7
|
71
|
+
# Edges: 13
|
72
|
+
# Nodes: 3
|
73
|
+
# Latches: 0
|
74
|
+
# Logic gates: 0
|
75
|
+
# Sub circuits: 3
|
76
|
+
# Sub circuits repartition:
|
77
|
+
# sqrt8_PC_done: 1
|
78
|
+
# sqrt8_PC_state: 1
|
79
|
+
# sqrt8_PC_counter: 1"
|
80
|
+
|
81
|
+
sqrt8pc_flattened_model = netlist.flatten('sqrt8_PC')
|
82
|
+
|
83
|
+
sqrt8pc_flattened_model.analyze
|
84
|
+
#=> "+----------------------------------------+
|
85
|
+
# | Model "sqrt8_PC" analysis |
|
86
|
+
# +----------------------------------------+
|
87
|
+
# Model "sqrt8_PC"
|
88
|
+
# Inputs: 2
|
89
|
+
# Outputs: 3
|
90
|
+
# Nets: 21
|
91
|
+
# Edges: 38
|
92
|
+
# Nodes: 19
|
93
|
+
# Latches: 5
|
94
|
+
# Logic gates: 14
|
95
|
+
# Sub circuits: 0
|
96
|
+
# Gates repartition:
|
97
|
+
# 1 input: 7 50.0%
|
98
|
+
# 2 inputs: 3 21.4%
|
99
|
+
# 4 inputs: 3 21.4%
|
100
|
+
# 5 inputs: 1 7.1%
|
101
|
+
# Buffers: 3"
|
102
|
+
|
103
|
+
## Analyze the logic level of the module
|
104
|
+
## that is to say the maximum number of logic functions between two latches or IOs.
|
105
|
+
sqrt8pc_flattened_model.level #=> 4
|
106
|
+
|
107
|
+
sqrt8pc_flattened_model.to_blif
|
108
|
+
#=> ".model sqrt8_PC
|
109
|
+
# .inputs _clk_ go[0]
|
110
|
+
# .outputs done[0] state[1] state[0]
|
111
|
+
# .latch n1 n0 re _clk_ 0
|
112
|
+
# .latch n6 n2 re _clk_ 0
|
113
|
+
# .latch n7 n3 re _clk_ 0
|
114
|
+
# .latch nD nA re _clk_ 0
|
115
|
+
# .latch nE nB re _clk_ 0
|
116
|
+
# .names n2 n3 n1
|
117
|
+
# 11 1
|
118
|
+
# .names n8 n9 n4
|
119
|
+
# 1- 1
|
120
|
+
# -1 1
|
121
|
+
# .names n4 n5
|
122
|
+
# 0 1
|
123
|
+
# .names go[0] n2 n3 n2 n6
|
124
|
+
# 10-- 1
|
125
|
+
# -01- 1
|
126
|
+
# 0001 1
|
127
|
+
# .names go[0] n2 n3 n5 n3 n7
|
128
|
+
# -10-- 1
|
129
|
+
# -011- 1
|
130
|
+
# 000-1 1
|
131
|
+
# .names nA n8
|
132
|
+
# 0 1
|
133
|
+
# .names nB n9
|
134
|
+
# 0 1
|
135
|
+
# .names nB nA nC
|
136
|
+
# 10 1
|
137
|
+
# 01 1
|
138
|
+
# .names n2 n3 nA nF nD
|
139
|
+
# 1-1- 1
|
140
|
+
# 01-1 1
|
141
|
+
# .names n2 n3 nB nC nE
|
142
|
+
# 1-1- 1
|
143
|
+
# 01-1 1
|
144
|
+
# .names nA nF
|
145
|
+
# 0 1
|
146
|
+
# .names n0 done[0]
|
147
|
+
# 1 1
|
148
|
+
# .names n3 state[1]
|
149
|
+
# 1 1
|
150
|
+
# .names n2 state[0]
|
151
|
+
# 1 1
|
152
|
+
# .end"
|
153
|
+
|
154
|
+
sqrt8pc_flattened_model.to_vhdl
|
155
|
+
#=> "library IEEE;
|
156
|
+
# use IEEE.STD_LOGIC_1164.ALL;
|
157
|
+
#
|
158
|
+
#
|
159
|
+
# entity SQRT8_PC is
|
160
|
+
# port ( clk_in : in std_ulogic;
|
161
|
+
# go_0_in : in std_ulogic;
|
162
|
+
# done_0_out : out std_ulogic;
|
163
|
+
# state_1_out : out std_ulogic;
|
164
|
+
# state_0_out : out std_ulogic);
|
165
|
+
# end SQRT8_PC;
|
166
|
+
#
|
167
|
+
#
|
168
|
+
# architecture blif of SQRT8_PC is
|
169
|
+
#
|
170
|
+
# signal clk : std_ulogic;
|
171
|
+
# signal go_0 : std_ulogic;
|
172
|
+
# signal n0 : std_ulogic := '0';
|
173
|
+
# signal n1 : std_ulogic;
|
174
|
+
# signal n2 : std_ulogic := '0';
|
175
|
+
# signal n3 : std_ulogic := '0';
|
176
|
+
# signal n4 : std_ulogic;
|
177
|
+
# signal n5 : std_ulogic;
|
178
|
+
# signal n6 : std_ulogic;
|
179
|
+
# signal n7 : std_ulogic;
|
180
|
+
# signal n8 : std_ulogic;
|
181
|
+
# signal n9 : std_ulogic;
|
182
|
+
# signal nA : std_ulogic := '0';
|
183
|
+
# signal nB : std_ulogic := '0';
|
184
|
+
# signal nC : std_ulogic;
|
185
|
+
# signal nD : std_ulogic;
|
186
|
+
# signal nE : std_ulogic;
|
187
|
+
# signal nF : std_ulogic;
|
188
|
+
# signal done_0 : std_ulogic;
|
189
|
+
# signal state_1 : std_ulogic;
|
190
|
+
# signal state_0 : std_ulogic;
|
191
|
+
#
|
192
|
+
# begin
|
193
|
+
#
|
194
|
+
# clk <= clk_in;
|
195
|
+
# go_0 <= go_0_in;
|
196
|
+
#
|
197
|
+
# done_0_out <= done_0;
|
198
|
+
# state_1_out <= state_1;
|
199
|
+
# state_0_out <= state_0;
|
200
|
+
#
|
201
|
+
#
|
202
|
+
# process(clk)
|
203
|
+
# begin
|
204
|
+
# if rising_edge(clk) then
|
205
|
+
# n0 <= n1;
|
206
|
+
# n2 <= n6;
|
207
|
+
# n3 <= n7;
|
208
|
+
# nA <= nD;
|
209
|
+
# nB <= nE;
|
210
|
+
# end if;
|
211
|
+
# end process;
|
212
|
+
#
|
213
|
+
# n1 <= (n2 and n3);
|
214
|
+
# n4 <= (n8) or
|
215
|
+
# (n9);
|
216
|
+
# n5 <= (not(n4));
|
217
|
+
# n6 <= (go_0 and not(n2)) or
|
218
|
+
# (not(n2) and n3) or
|
219
|
+
# (not(go_0) and not(n2) and not(n3) and n2);
|
220
|
+
# n7 <= (n2 and not(n3)) or
|
221
|
+
# (not(n2) and n3 and n5) or
|
222
|
+
# (not(go_0) and not(n2) and not(n3) and n3);
|
223
|
+
# n8 <= (not(nA));
|
224
|
+
# n9 <= (not(nB));
|
225
|
+
# nC <= (nB and not(nA)) or
|
226
|
+
# (not(nB) and nA);
|
227
|
+
# nD <= (n2 and nA) or
|
228
|
+
# (not(n2) and n3 and nF);
|
229
|
+
# nE <= (n2 and nB) or
|
230
|
+
# (not(n2) and n3 and nC);
|
231
|
+
# nF <= (not(nA));
|
232
|
+
# done_0 <= (n0);
|
233
|
+
# state_1 <= (n3);
|
234
|
+
# state_0 <= (n2);
|
235
|
+
#
|
236
|
+
# end blif;
|
237
|
+
|
238
|
+
netlist.create_simulation_file_for_model('sqrt8')
|
239
|
+
# Creates files sqrt8_cpp_header.hh sqrt8_cpp_sim.cc
|
240
|
+
# and compiles to sqrt8_cpp_sim.o
|
241
|
+
```
|
242
|
+
|
243
|
+
You can then write a C++ testbench:
|
244
|
+
|
245
|
+
```C++
|
246
|
+
#include <cmath>
|
247
|
+
#include "sqrt8_cpp_header.hh"
|
248
|
+
|
249
|
+
int main(void)
|
250
|
+
{
|
251
|
+
uint64_t in, out, golden;
|
252
|
+
|
253
|
+
Sqrt8SimulationClass *dut = new Sqrt8SimulationClass();
|
254
|
+
|
255
|
+
dut->reset();
|
256
|
+
|
257
|
+
for (in = 0; in < 256; in++) {
|
258
|
+
iterations++;
|
259
|
+
|
260
|
+
dut->INPUT_VECTOR_radicand->setValue(in);
|
261
|
+
dut->INPUT_NET_go->setValue(1);
|
262
|
+
dut->cycle();
|
263
|
+
dut->INPUT_NET_go->setValue(0);
|
264
|
+
dut->cycle();
|
265
|
+
|
266
|
+
while (dut->OUTPUT_NET_done->getValue() != 1) {
|
267
|
+
dut->propagate();
|
268
|
+
dut->clock();
|
269
|
+
dut->propagate();
|
270
|
+
// equivalent to 'dut->cycle()'
|
271
|
+
}
|
272
|
+
|
273
|
+
out = dut->OUTPUT_VECTOR_squareRoot->getValue(NULL);
|
274
|
+
golden = (int)sqrt(in);
|
275
|
+
if (out != golden) {
|
276
|
+
std::cerr << "sqrt(" << in << ") => " << out << " (should be " << golden << ")" << std::endl;
|
277
|
+
}
|
278
|
+
}
|
279
|
+
|
280
|
+
delete dut;
|
281
|
+
|
282
|
+
return 0;
|
283
|
+
}
|
284
|
+
```
|
285
|
+
|
286
|
+
Compile and execute this testbench:
|
287
|
+
|
288
|
+
```lang-none
|
289
|
+
$ g++ -W -Wall -I. -o simu testbench.cc sqrt8_cpp_sim.o
|
290
|
+
$ ./simu
|
291
|
+
```
|
292
|
+
|
293
|
+
---
|
294
|
+
|
295
|
+
The `examples/zpu/` directory contains the necessary files to simulate
|
296
|
+
a ZPU ZPU processor [https://github.com/zylin/zpu](https://github.com/zylin/zpu)
|
297
|
+
executing a hello-world.
|
298
|
+
|
299
|
+
```lang-none
|
300
|
+
$ cd examples/zpu
|
301
|
+
$ ruby simulate_zpu.rb
|
302
|
+
|
303
|
+
Parsing file "zpu_mem16.blif"...
|
304
|
+
Elaborating model "zpu_mem16"...
|
305
|
+
WARNING: In model "zpu_mem16": net "_clk_" has no fanouts
|
306
|
+
------------------------------------------------------------
|
307
|
+
Model collection contains 1 models
|
308
|
+
+----------------------------------------+
|
309
|
+
| Model "zpu_mem16" analysis |
|
310
|
+
+----------------------------------------+
|
311
|
+
Model "zpu_mem16"
|
312
|
+
Inputs: 34
|
313
|
+
Outputs: 50
|
314
|
+
Nets: 1006
|
315
|
+
Edges: 4039
|
316
|
+
Nodes: 972
|
317
|
+
Latches: 156
|
318
|
+
Logic gates: 816
|
319
|
+
Sub circuits: 0
|
320
|
+
Gates repartition:
|
321
|
+
1 input: 51 6.3%
|
322
|
+
2 inputs: 33 4.0%
|
323
|
+
3 inputs: 95 11.6%
|
324
|
+
4 inputs: 108 13.2%
|
325
|
+
5 inputs: 175 21.4%
|
326
|
+
6 inputs: 354 43.4%
|
327
|
+
Buffers: 51
|
328
|
+
------------------------------------------------------------
|
329
|
+
Generating graph from model components...
|
330
|
+
Extracting connected subgraphs... 87 subgraphs found
|
331
|
+
Checking that there are no cycles in subgraphs... Ok
|
332
|
+
Layering subgraphs...
|
333
|
+
Maximum number of layers: 33
|
334
|
+
Writing static schedule for component simulation...
|
335
|
+
Written C++ simulation model in file "zpu_mem16_cpp_sim.cc"
|
336
|
+
Compiling model...
|
337
|
+
g++ -c -W -Wall -O3 -std=c++11 zpu_mem16_cpp_sim.cc -o zpu_mem16_cpp_sim.o
|
338
|
+
Written C++ model simulation header in file "zpu_mem16_cpp_header.hh"
|
339
|
+
Now you can write your testbench in a C++ file as 'testbench.cc' including '#include "zpu_mem16_cpp_header.hh"', then run:
|
340
|
+
g++ -W -Wall -O3 zpu_mem16_cpp_sim.o testbench.cc
|
341
|
+
-- Compiling testbench -------------------------------------
|
342
|
+
Executing: g++ -W -Wall -I. -o zpu_simulation testbench_zpu.cc zpu_mem16_cpp_sim.o
|
343
|
+
You can now execute the testbench with "./zpu_simulation <zpu_compiled_program>"
|
344
|
+
-- Executing simulation ------------------------------------
|
345
|
+
Executing: ./zpu_simulation zpu_helloworld.bin
|
346
|
+
Read 3284 bytes from file 'zpu_helloworld.bin' (memory filled 10.0%)
|
347
|
+
Starting simulation
|
348
|
+
Hello, world!
|
349
|
+
What you see is a processor simulated at a logic netlist level, executing a helloworld.
|
350
|
+
Simulation ended
|
351
|
+
80877 clock cycles in 1.271 s
|
352
|
+
Simulation average clock speed: 63637 Hzxecutable
|
353
|
+
```
|
354
|
+
|
355
|
+
|
356
|
+
Executable
|
357
|
+
----------
|
358
|
+
|
359
|
+
To use BlifUtils directly from a terminal or a Makefile,
|
360
|
+
this gem also include the `blifutils` executable script, which uses command line arguments.
|
361
|
+
|
362
|
+
```lang-none
|
363
|
+
$ blifutils --help
|
364
|
+
Usage: blifutils [options] -i file1 file2 ...
|
365
|
+
-i, --input FILES Input blif files
|
366
|
+
-o, --output [FILE] Output blif to FILE
|
367
|
+
-s, --simulation Create C++ simulation files
|
368
|
+
-v, --vhdl Create a vhdl file
|
369
|
+
-f, --flatten Flatten the model hierarchy in a single model
|
370
|
+
-m, --model NAME Name of the model to process
|
371
|
+
-p, --print-models Print model names
|
372
|
+
-a, --analyze [level] Print analysis, with optional level analysis (level)
|
373
|
+
-A, --analyze_with_graphviz Print analysis, with level analysis, wirting graphvis files
|
374
|
+
-q, --quiet Don't print messages
|
375
|
+
-h, --help Display this help
|
376
|
+
```
|
377
|
+
|
data/bin/blifutils
ADDED
@@ -0,0 +1,184 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
##
|
4
|
+
# Copyright (C) 2017 Théotime bollengier <theotime.bollengier@gmail.com>
|
5
|
+
#
|
6
|
+
# This file is part of Blifutils.
|
7
|
+
#
|
8
|
+
# Blifutils is free software: you can redistribute it and/or modify
|
9
|
+
# it under the terms of the GNU General Public License as published by
|
10
|
+
# the Free Software Foundation, either version 3 of the License, or
|
11
|
+
# (at your option) any later version.
|
12
|
+
#
|
13
|
+
# Blifutils is distributed in the hope that it will be useful,
|
14
|
+
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
15
|
+
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
16
|
+
# GNU General Public License for more details.
|
17
|
+
#
|
18
|
+
# You should have received a copy of the GNU General Public License
|
19
|
+
# along with Blifutils. If not, see <http://www.gnu.org/licenses/>.
|
20
|
+
#
|
21
|
+
|
22
|
+
require 'blifutils'
|
23
|
+
require 'optparse'
|
24
|
+
|
25
|
+
|
26
|
+
options = {}
|
27
|
+
inputFiles = []
|
28
|
+
|
29
|
+
optparse = OptionParser.new do |opts|
|
30
|
+
# Set a banner, displayed at the top
|
31
|
+
# of the help screen.
|
32
|
+
opts.banner = "Usage: #{$0} [options] -i file1 file2 ..."
|
33
|
+
|
34
|
+
opts.on('-i', '--input FILES', 'Input blif files') do |file|
|
35
|
+
inputFiles << file
|
36
|
+
end
|
37
|
+
|
38
|
+
options[:blif] = false
|
39
|
+
options[:outputBlifName] = nil
|
40
|
+
opts.on('-o', '--output [FILE]', 'Output blif to FILE') do |file|
|
41
|
+
options[:blif] = true
|
42
|
+
options[:outputBlifName] = file
|
43
|
+
end
|
44
|
+
|
45
|
+
options[:simulation] = false
|
46
|
+
opts.on('-s', '--simulation', "Create C++ simulation files") do
|
47
|
+
options[:simulation] = true
|
48
|
+
end
|
49
|
+
|
50
|
+
options[:vhdl] = false
|
51
|
+
opts.on('-v', '--vhdl', "Create a vhdl file") do
|
52
|
+
options[:vhdl] = true
|
53
|
+
end
|
54
|
+
|
55
|
+
options[:flatten] = false
|
56
|
+
opts.on('-f', '--flatten', 'Flatten the model hierarchy in a single model') do
|
57
|
+
options[:flatten] = true
|
58
|
+
end
|
59
|
+
|
60
|
+
options[:model] = nil
|
61
|
+
opts.on('-m', '--model NAME', 'Name of the model to process') do |mod|
|
62
|
+
options[:model] = mod
|
63
|
+
end
|
64
|
+
|
65
|
+
options[:printModels] = false
|
66
|
+
opts.on('-p', '--print-models', 'Print model names') do
|
67
|
+
options[:printModels] = true
|
68
|
+
end
|
69
|
+
|
70
|
+
options[:analyze] = false
|
71
|
+
options[:analyzeLevel] = false
|
72
|
+
opts.on('-a', '--analyze [level]', [:level], 'Print analysis, with optional level analysis (level)') do |ana|
|
73
|
+
options[:analyze] = true
|
74
|
+
options[:analyzeLevel] = true if ana == :level
|
75
|
+
end
|
76
|
+
|
77
|
+
options[:analyzeLevelWithGV] = false
|
78
|
+
opts.on('-A', '--analyze_with_graphviz', 'Print analysis, with level analysis, wirting graphvis files') do
|
79
|
+
options[:analyze] = true
|
80
|
+
options[:analyzeLevel] = true
|
81
|
+
options[:analyzeLevelWithGV] = true
|
82
|
+
end
|
83
|
+
|
84
|
+
|
85
|
+
options[:quiet] = false
|
86
|
+
opts.on('-q', '--quiet', "Don't print messages") do
|
87
|
+
options[:quiet] = true
|
88
|
+
end
|
89
|
+
|
90
|
+
# This displays the help screen, all programs are
|
91
|
+
# assumed to have this option.
|
92
|
+
opts.on( '-h', '--help', 'Display this help' ) do
|
93
|
+
puts opts
|
94
|
+
exit
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
optparse.parse!
|
99
|
+
|
100
|
+
ARGV.each{|f| inputFiles << f}
|
101
|
+
|
102
|
+
|
103
|
+
|
104
|
+
## Read blif inputs and add models to the netlist ##
|
105
|
+
netlist = BlifUtils::Netlist.new
|
106
|
+
inputFiles.each do |iFile|
|
107
|
+
elNetlist = BlifUtils::Elaborator.elaborate_netlist(BlifUtils::Parser.parse(iFile, quiet: options[:quiet]), quiet: options[:quiet])
|
108
|
+
elNetlist.models.each{|model| netlist.add_model(model)}
|
109
|
+
end
|
110
|
+
|
111
|
+
|
112
|
+
## Print model names ##
|
113
|
+
if options[:printModels] then
|
114
|
+
puts "List of models:"
|
115
|
+
netlist.model_names.each{|modName| puts " #{modName}"}
|
116
|
+
end
|
117
|
+
|
118
|
+
|
119
|
+
## Flatening model ##
|
120
|
+
if options[:flatten] then
|
121
|
+
flattenedmodel = netlist.flatten(options[:model], true, quiet: options[:quiet])
|
122
|
+
blackboxes = netlist.models.select{|m| m.is_blackbox?}
|
123
|
+
netlist.clear
|
124
|
+
netlist.add_model(flattenedmodel)
|
125
|
+
blackboxes.each{|blbx| netlist.add_model(blbx)}
|
126
|
+
end
|
127
|
+
|
128
|
+
|
129
|
+
## Output blif ##
|
130
|
+
if options[:blif] and netlist.length > 0 then
|
131
|
+
unless options[:outputBlifName].nil? then
|
132
|
+
netlistFileName = options[:outputBlifName]
|
133
|
+
else
|
134
|
+
if not(File.exist?(netlist.first_model.name + '.blif')) then
|
135
|
+
netlistFileName = netlist.first_model.name + '.blif'
|
136
|
+
elsif inputFiles.length == 1 then
|
137
|
+
netlistFileName = File.basename(inputFiles[0], '.*') + '.blif'
|
138
|
+
else
|
139
|
+
netlistFileName = 'output.blif'
|
140
|
+
end
|
141
|
+
end
|
142
|
+
|
143
|
+
netlist.update_clocks()
|
144
|
+
blifStr = netlist.models.collect{|model| model.to_blif}.join("\n")
|
145
|
+
|
146
|
+
File.write(netlistFileName, blifStr)
|
147
|
+
puts "Blif models written to file \"#{netlistFileName}\"." unless options[:quiet]
|
148
|
+
end
|
149
|
+
|
150
|
+
|
151
|
+
## Print analysis ##
|
152
|
+
if options[:analyze] then
|
153
|
+
unless options[:model].nil? then
|
154
|
+
model = netlist.get_model_by_name(options[:model])
|
155
|
+
if model.nil?
|
156
|
+
STDERR.puts "Cannot find a model named \"#{options[:model]}\""
|
157
|
+
STDERR.puts "Available models are:"
|
158
|
+
netlist.model_names.each{|modelname| STDERR.puts " #{modelname}"}
|
159
|
+
abort
|
160
|
+
end
|
161
|
+
puts model.analyze
|
162
|
+
if model.is_self_contained? and options[:analyzeLevel] then
|
163
|
+
model.level_analysis(withOutputGraphviz: options[:analyzeLevelWithGV], quiet: options[:quiet])
|
164
|
+
end
|
165
|
+
else
|
166
|
+
netlist.models.each do |model|
|
167
|
+
puts model.analyze
|
168
|
+
if model.is_self_contained? and options[:analyzeLevel] then
|
169
|
+
model.level_analysis(withOutputGraphviz: options[:analyzeLevelWithGV], quiet: options[:quiet])
|
170
|
+
end
|
171
|
+
end
|
172
|
+
end
|
173
|
+
end
|
174
|
+
|
175
|
+
|
176
|
+
if options[:simulation] then
|
177
|
+
netlist.create_simulation_file_for_model(options[:model], quiet: options[:quiet])
|
178
|
+
end
|
179
|
+
|
180
|
+
|
181
|
+
if options[:vhdl] then
|
182
|
+
netlist.create_vhdl_files(options[:model])
|
183
|
+
end
|
184
|
+
|