blifutils 0.0.1 → 0.0.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: beffcb8de20600c830e33e4940b630bcd5adf2d9
4
- data.tar.gz: 3f689ec7d8bb121f41ea36c7e9724f636d013a80
3
+ metadata.gz: b983d50091d1cdd6613589e30a03c7e660925aea
4
+ data.tar.gz: e919036b709395235ebde09cc7b32eea3f222874
5
5
  SHA512:
6
- metadata.gz: '0952b7ab1036587562224e0c46d4df0830c966e28a1d75c196768a288f8fa40ec3b670967fe3a74784116ddafdea2a2510de7a610eb0dde7264b6fe6343c34bc'
7
- data.tar.gz: 8b9aef1b9c0b798deaa2f9672bdad24023f98e8d2f037450000f202b519bd3158e7da1a79ad3fafcf43d853128e5bb7fab238235e9862cc252ee3364323ffbaf
6
+ metadata.gz: 5a4f0b845afaf9c2c9a91c9730b6e027d939e474a31a2f05f749c182cdde1d5d559d9d657c5b68b9072a4d50608273be3a2229c6a7342dcfe024f73ccc71c383
7
+ data.tar.gz: 1ea094b9a22b94e28c78a890836b55f3d21a77f8435ee5a9df321770cf832a807b5ca7b0b0fe152ef29c5361c505880a960b592dd777f4300d362c634c7a814e
@@ -29,27 +29,27 @@ inputFiles = []
29
29
  optparse = OptionParser.new do |opts|
30
30
  # Set a banner, displayed at the top
31
31
  # of the help screen.
32
- opts.banner = "Usage: #{$0} [options] -i file1 file2 ..."
32
+ opts.banner = "Usage: #{File.basename($0)} [options] -i file1 file2 ..."
33
33
 
34
- opts.on('-i', '--input FILES', 'Input blif files') do |file|
34
+ opts.on('-i', '--input FILES', 'Input BLIF files') do |file|
35
35
  inputFiles << file
36
36
  end
37
37
 
38
38
  options[:blif] = false
39
39
  options[:outputBlifName] = nil
40
- opts.on('-o', '--output [FILE]', 'Output blif to FILE') do |file|
40
+ opts.on('-o', '--output [FILE]', 'Output BLIF FILE') do |file|
41
41
  options[:blif] = true
42
42
  options[:outputBlifName] = file
43
43
  end
44
44
 
45
- options[:simulation] = false
46
- opts.on('-s', '--simulation', "Create C++ simulation files") do
47
- options[:simulation] = true
45
+ options[:printModels] = false
46
+ opts.on('-p', '--print-models', 'Print model names') do
47
+ options[:printModels] = true
48
48
  end
49
49
 
50
- options[:vhdl] = false
51
- opts.on('-v', '--vhdl', "Create a vhdl file") do
52
- options[:vhdl] = true
50
+ options[:model] = nil
51
+ opts.on('-m', '--model NAME', 'Name of the model to process') do |mod|
52
+ options[:model] = mod
53
53
  end
54
54
 
55
55
  options[:flatten] = false
@@ -57,14 +57,14 @@ optparse = OptionParser.new do |opts|
57
57
  options[:flatten] = true
58
58
  end
59
59
 
60
- options[:model] = nil
61
- opts.on('-m', '--model NAME', 'Name of the model to process') do |mod|
62
- options[:model] = mod
60
+ options[:simulation] = false
61
+ opts.on('-s', '--simulation', "Create C++ simulation files") do
62
+ options[:simulation] = true
63
63
  end
64
64
 
65
- options[:printModels] = false
66
- opts.on('-p', '--print-models', 'Print model names') do
67
- options[:printModels] = true
65
+ options[:vhdl] = false
66
+ opts.on('-v', '--vhdl', "Create a vhdl file") do
67
+ options[:vhdl] = true
68
68
  end
69
69
 
70
70
  options[:analyze] = false
@@ -81,6 +81,20 @@ optparse = OptionParser.new do |opts|
81
81
  options[:analyzeLevelWithGV] = true
82
82
  end
83
83
 
84
+ options[:default_latch_type] = nil
85
+ opts.on('--default-latch-type TYPE', 'Set undefined latch types to TYPE (re: rising edge, fe: falling edge, al: active low, ah: active high, as: asynchronous)') do |type|
86
+ options[:default_latch_type] = type.to_sym
87
+ end
88
+
89
+ options[:default_latch_clock] = nil
90
+ opts.on('--default-latch-clock NAME', 'Set undefined latch contol signals to NAME') do |name|
91
+ options[:default_latch_clock] = name
92
+ end
93
+
94
+ options[:default_latch_initial_value] = nil
95
+ opts.on('--default-latch-initial-value VALUE', "Set undefined latch initial value to VALUE (0, 1, 2: don't care, 3: undefine)") do |val|
96
+ options[:default_latch_initial_value] = val
97
+ end
84
98
 
85
99
  options[:quiet] = false
86
100
  opts.on('-q', '--quiet', "Don't print messages") do
@@ -90,21 +104,42 @@ optparse = OptionParser.new do |opts|
90
104
  # This displays the help screen, all programs are
91
105
  # assumed to have this option.
92
106
  opts.on( '-h', '--help', 'Display this help' ) do
93
- puts opts
107
+ puts opts.to_s
94
108
  exit
95
109
  end
96
110
  end
97
111
 
98
- optparse.parse!
112
+ begin
113
+ optparse.parse!
114
+ rescue OptionParser::MissingArgument => e
115
+ STDERR.puts e.message
116
+ abort optparse.to_s
117
+ end
99
118
 
100
119
  ARGV.each{|f| inputFiles << f}
101
120
 
121
+ unless [nil, :re, :fe, :al, :ah, :as].include?(options[:default_latch_type])
122
+ STDERR.puts "Default latch type must be either re, fe, al, ah or as."
123
+ abort optparse.to_s
124
+ end
125
+
126
+ unless options[:default_latch_initial_value].nil?
127
+ unless options[:default_latch_initial_value].match(/^[0123]$/) then
128
+ STDERR.puts "Default latch initial value must be either 0, 1, 2 or 3."
129
+ abort optparse.to_s
130
+ end
131
+ options[:default_latch_initial_value] = options[:default_latch_initial_value].to_i
132
+ end
102
133
 
103
134
 
104
135
  ## Read blif inputs and add models to the netlist ##
105
136
  netlist = BlifUtils::Netlist.new
106
137
  inputFiles.each do |iFile|
107
- elNetlist = BlifUtils::Elaborator.elaborate_netlist(BlifUtils::Parser.parse(iFile, quiet: options[:quiet]), quiet: options[:quiet])
138
+ elNetlist = BlifUtils::Elaborator.elaborate_netlist(BlifUtils::Parser.parse(iFile, quiet: options[:quiet]),
139
+ quiet: options[:quiet],
140
+ default_latch_type: options[:default_latch_type],
141
+ default_latch_clock: options[:default_latch_clock],
142
+ default_latch_initial_value: options[:default_latch_initial_value])
108
143
  elNetlist.models.each{|model| netlist.add_model(model)}
109
144
  end
110
145
 
@@ -18,7 +18,7 @@
18
18
 
19
19
 
20
20
  module BlifUtils
21
- VERSION = '0.0.1'
21
+ VERSION = '0.0.2'
22
22
  end
23
23
 
24
24
  require 'blifutils/parser'
@@ -123,7 +123,7 @@ module BlifUtils
123
123
  class GenericLatch
124
124
  attr_reader :input, :output, :initValue, :ctrlType, :ctrlSig
125
125
 
126
- def initialize (input, output, initValue: 3, ctrlType: :re, ctrlSig: nil)
126
+ def initialize (input, output, initValue: nil, ctrlType: nil, ctrlSig: nil)
127
127
  @input = input
128
128
  @output = output
129
129
  @initValue = initValue
@@ -135,9 +135,9 @@ module BlifUtils
135
135
  str = ' '*indent + "Latch:\n"
136
136
  str += ' '*(indent+1) + "Input: \"#{@input}\"\n"
137
137
  str += ' '*(indent+1) + "Output: \"#{@output}\"\n"
138
- str += ' '*(indent+1) + "Initial value: \"#{@initValue}\"\n"
139
- str += ' '*(indent+1) + "Type: \"#{@ctrlType}\"\n"
140
- str += ' '*(indent+1) + "Clock signal: #{@ctrlSig.nil? ? "nil" : "\"#{@ctrlSig}\""}\n"
138
+ str += ' '*(indent+1) + "Initial value: #{@initValue.nil? ? "undefined" : "\"#{@initValue}\""}\n"
139
+ str += ' '*(indent+1) + "Type: #{@ctrlType.nil? ? "undefined" : "\"#{@ctrlSig}\""}\n"
140
+ str += ' '*(indent+1) + "Clock signal: #{@ctrlSig.nil? ? "undefined" : "\"#{@ctrlSig}\""}\n"
141
141
  return str
142
142
  end
143
143
  end # BlifUtils::AST::GenericLatch
@@ -26,13 +26,13 @@ module BlifUtils
26
26
 
27
27
  module Elaborator
28
28
 
29
- def self.elaborate_netlist (ast, quiet: false)
29
+ def self.elaborate_netlist (ast, quiet: false, default_latch_type: nil, default_latch_clock: nil, default_latch_initial_value: nil)
30
30
  modelDeclarations = gather_model_declarations(ast)
31
31
 
32
32
  netlist = BlifUtils::Netlist.new
33
33
  models = ast.modelList.collect do |modelAst|
34
34
  puts "Elaborating model \"#{modelAst.name}\"..." unless quiet
35
- netlist.add_model(elaborate_model(modelAst, modelDeclarations, quiet: quiet))
35
+ netlist.add_model(elaborate_model(modelAst, modelDeclarations, quiet: quiet, default_latch_type: default_latch_type, default_latch_clock: default_latch_clock, default_latch_initial_value: default_latch_initial_value))
36
36
  end
37
37
 
38
38
  return netlist
@@ -94,7 +94,7 @@ module BlifUtils
94
94
  end # BlifUtils::Elaborator::gather_model_declarations
95
95
 
96
96
 
97
- def self.elaborate_model (modelAst, modelDeclarations, quiet: false)
97
+ def self.elaborate_model (modelAst, modelDeclarations, quiet: false, default_latch_type: nil, default_latch_clock: nil, default_latch_initial_value: nil)
98
98
  name = modelAst.name
99
99
  inputs = []
100
100
  outputs = []
@@ -154,26 +154,48 @@ module BlifUtils
154
154
  end
155
155
  end
156
156
 
157
+ if default_latch_type then
158
+ components.each do |c|
159
+ next unless c.isLatch? and c.ctrlType.nil?
160
+ c.set_type(default_latch_type)
161
+ end
162
+ end
163
+
164
+ if default_latch_clock then
165
+ components.each do |c|
166
+ next unless c.isLatch? and c.ctrlSig.nil?
167
+ c.set_clock(default_latch_clock)
168
+ end
169
+ end
170
+
171
+ if default_latch_initial_value then
172
+ components.each do |c|
173
+ next unless c.isLatch? and c.initValue.nil?
174
+ c.set_initial_value(default_latch_initial_value)
175
+ end
176
+ end
177
+
178
+
157
179
  # Create all nets from their drivers #
180
+ netnames = {}
158
181
  inputs.each do |iIO|
159
182
  newNet = BlifUtils::Netlist::Net.new(iIO.net, :input, [], true, false)
183
+ netnames[newNet.name] = newNet
160
184
  nets << newNet
161
185
  iIO.net = newNet
162
186
  end
163
187
  components.reject{|comp| comp.isSubcircuit?}.each do |component|
164
188
  newNet = BlifUtils::Netlist::Net.new(component.output, component, [], false, false)
165
- if nets.collect{|net| net.name}.include?(newNet.name) then
166
- abort "ERROR: In model \"#{name}\": net \"#{newNet.name}\" has more than one driver"
167
- end
189
+ abort "ERROR: In model \"#{name}\": net \"#{newNet.name}\" has more than one driver" if netnames[newNet.name]
190
+ netnames[newNet.name] = newNet
168
191
  nets << newNet
169
192
  component.output = newNet
170
193
  end
171
194
  components.select{|comp| comp.isSubcircuit?}.each do |subcircuit|
172
195
  subcircuit.outputFormalAcutalList.each do |outIO|
173
196
  newNet = BlifUtils::Netlist::Net.new(outIO.net, subcircuit, [], false, false)
174
- if nets.collect{|net| net.name}.include?(newNet.name) then
175
- abort "ERROR: In model \"#{name}\": net \"#{newNet.name}\" has more than one driver"
176
- end
197
+ abort "ERROR: In model \"#{name}\": net \"#{newNet.name}\" has more than one driver" if netnames[newNet.name]
198
+ netnames[newNet.name] = newNet
177
199
  nets << newNet
178
200
  outIO.net = newNet
179
201
  end
@@ -181,49 +203,43 @@ module BlifUtils
181
203
 
182
204
  # Update nets fanouts #
183
205
  outputs.each_with_index do |oIO, i|
184
- index = nets.index{|net| net.name == oIO.name}
185
- if index.nil? then
186
- abort "ERROR: In model \"#{name}\": output \"#{oIO.name}\" has no driver"
187
- end
188
- nets[index].fanouts << BlifUtils::Netlist::Fanout.new(:output, i)
189
- nets[index].isOutput = true
190
- oIO.net = nets[index]
206
+ theNet = netnames[oIO.name]
207
+ abort "ERROR: In model \"#{name}\": output \"#{oIO.name}\" has no driver" if theNet.nil?
208
+ theNet.fanouts << BlifUtils::Netlist::Fanout.new(:output, i)
209
+ theNet.isOutput = true
210
+ oIO.net = theNet
191
211
  end
192
212
  components.select{|comp| comp.isLatch?}.each do |latch|
193
- index = nets.index{|net| net.name == latch.input}
194
- if index.nil? then
195
- abort "ERROR: In model \"#{name}\": input \"#{latch.input}\" from latch \"#{latch.output.name}\" has no driver"
196
- end
197
- nets[index].fanouts << BlifUtils::Netlist::Fanout.new(latch, 0)
198
- latch.input = nets[index]
213
+ theNet = netnames[latch.input]
214
+ abort "ERROR: In model \"#{name}\": input \"#{latch.input}\" from latch \"#{latch.output.name}\" has no driver" if theNet.nil?
215
+ theNet.fanouts << BlifUtils::Netlist::Fanout.new(latch, 0)
216
+ latch.input = theNet
199
217
  end
200
218
  components.select{|comp| comp.isGate?}.each do |gate|
201
219
  gate.inputs.each_with_index do |gin, i|
202
- index = nets.index{|net| net.name == gin}
203
- if index.nil? then
204
- abort "ERROR: In model \"#{name}\": input \"#{gin}\" from gate \"#{gate.output.name}\" has no driver"
205
- end
206
- nets[index].fanouts << BlifUtils::Netlist::Fanout.new(gate, i)
207
- gate.inputs[i] = nets[index]
220
+ theNet = netnames[gin]
221
+ abort "ERROR: In model \"#{name}\": input \"#{gin}\" from gate \"#{gate.output.name}\" has no driver" if theNet.nil?
222
+ theNet.fanouts << BlifUtils::Netlist::Fanout.new(gate, i)
223
+ gate.inputs[i] = theNet
208
224
  end
209
225
  end
210
226
  components.select{|comp| comp.isSubcircuit?}.each do |subcircuit|
211
227
  subcircuit.inputFormalAcutalList.each_with_index do |iIO, i|
212
- index = nets.index{|net| net.name == iIO.net}
213
- if index.nil? then
214
- abort "ERROR: In model \"#{name}\": input \"#{iIO}\" (formal \"#{iIO.name}\" from reference model \"#{subcircuit.modelName}\" has no driver"
215
- end
216
- nets[index].fanouts << BlifUtils::Netlist::Fanout.new(subcircuit, i)
217
- iIO.net = nets[index]
228
+ theNet = netnames[iIO.net]
229
+ abort "ERROR: In model \"#{name}\": input \"#{iIO}\" (formal \"#{iIO.name}\" from reference model \"#{subcircuit.modelName}\" has no driver" if theNet.nil?
230
+ theNet.fanouts << BlifUtils::Netlist::Fanout.new(subcircuit, i)
231
+ iIO.net = theNet
218
232
  end
219
233
  end
220
234
 
221
235
  clocks = components.select{|comp| comp.isLatch?}.collect{|latch| latch.ctrlSig}.reject{|el| el.nil?}.uniq
222
236
 
223
237
  # Check that each net has at least one fanout #
224
- nets.each do |net|
225
- if net.fanouts.empty? and not(clocks.include?(net.name)) then
226
- STDERR.puts "WARNING: In model \"#{name}\": net \"#{net.name}\" has no fanouts" unless quiet
238
+ unless quiet then
239
+ nets.each do |net|
240
+ if net.fanouts.empty? and not(clocks.include?(net.name)) then
241
+ STDERR.puts "WARNING: In model \"#{name}\": net \"#{net.name}\" has no fanouts"
242
+ end
227
243
  end
228
244
  end
229
245
 
@@ -233,9 +249,9 @@ module BlifUtils
233
249
  end # BlifUtils::Elaborator
234
250
 
235
251
 
236
- def self.read(fileName, quiet: false)
252
+ def self.read(fileName, quiet: false, default_latch_type: nil, default_latch_clock: nil, default_latch_initial_value: nil)
237
253
  ast = BlifUtils::Parser.parse(fileName, quiet: quiet)
238
- netlist = BlifUtils::Elaborator.elaborate_netlist(ast, quiet: quiet)
254
+ netlist = BlifUtils::Elaborator.elaborate_netlist(ast, quiet: quiet, default_latch_type: nil, default_latch_clock: nil, default_latch_initial_value: nil)
239
255
  return netlist
240
256
  end # BlifUtils::read
241
257
 
@@ -160,7 +160,23 @@ module BlifUtils
160
160
 
161
161
 
162
162
  def to_blif
163
- return ".latch #{@input.name} #{@output.name} #{@ctrlType} #{@ctrlSig.nil? ? 'NIL' : @ctrlSig} #{@initValue}\n"
163
+ res = ".latch #{@input.name} #{@output.name}"
164
+ if @ctrlType
165
+ res += " #{@ctrlType} "
166
+ if @ctrlSig.nil?
167
+ res += "NIL"
168
+ elsif @ctrlSig.kind_of?(BlifUtils::Netlist::Net)
169
+ res += @ctrlSig.name
170
+ else
171
+ res += @ctrlSig
172
+ end
173
+ end
174
+ if @initValue
175
+ res += " #{@initValue} "
176
+ end
177
+ res += "\n"
178
+
179
+ return res
164
180
  end
165
181
 
166
182
 
@@ -178,6 +194,22 @@ module BlifUtils
178
194
  return "Latch \"#{@output.name}\""
179
195
  end
180
196
 
197
+
198
+ def set_type (type)
199
+ raise "Type must be one of [nil, :fe, :re, :ah, :al, :as]" unless [nil, :fe, :re, :ah, :al, :as].include?(type)
200
+ @ctrlType = type
201
+ end
202
+
203
+
204
+ def set_clock (net_or_name)
205
+ @ctrlSig = net_or_name
206
+ end
207
+
208
+
209
+ def set_initial_value (value)
210
+ raise "Initial value must be an integer in the range 0..3" unless (value.kind_of?(Integer) and value >= 0 and value <= 3)
211
+ @initValue = value
212
+ end
181
213
  end # BlifUtils::Netlist::Latch
182
214
 
183
215
 
@@ -299,6 +331,30 @@ module BlifUtils
299
331
  end
300
332
 
301
333
 
334
+ def set_undefined_latches_type (type)
335
+ @components.each do |c|
336
+ next unless c.isLatch? and c.ctrlType.nil?
337
+ c.set_type(type)
338
+ end
339
+ end
340
+
341
+
342
+ def set_undefined_latches_clock (clk)
343
+ @components.each do |c|
344
+ next unless c.isLatch? and c.ctrlSig.nil?
345
+ c.set_clock(clk)
346
+ end
347
+ end
348
+
349
+
350
+ def set_undefined_latches_initial_value (value)
351
+ @components.each do |c|
352
+ next unless c.isLatch? and c.initValue.nil?
353
+ c.set_initial_value(value)
354
+ end
355
+ end
356
+
357
+
302
358
  def analyze
303
359
  bannerTitle = " #{@isBlackBox ? 'Black box' : 'Model'} \"#{@name}\" analysis "
304
360
  bannerSize = [40, bannerTitle.length].max
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: blifutils
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Théotime Bollengier