bat 1.0.0
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.
- data/History.txt +4 -0
- data/Manifest.txt +37 -0
- data/README.txt +19 -0
- data/Rakefile +65 -0
- data/bin/bat +92 -0
- data/lib/Buf1.rb +27 -0
- data/lib/Bufz.rb +46 -0
- data/lib/Dffpc.rb +40 -0
- data/lib/FivePorts.rb +19 -0
- data/lib/FourPorts.rb +19 -0
- data/lib/Gnd.rb +10 -0
- data/lib/Input.rb +9 -0
- data/lib/Inst.rb +51 -0
- data/lib/Inv.rb +9 -0
- data/lib/Mux2.rb +25 -0
- data/lib/Nand2.rb +9 -0
- data/lib/Nand2c.rb +9 -0
- data/lib/Nand3.rb +9 -0
- data/lib/Nand3c.rb +9 -0
- data/lib/Nand4.rb +9 -0
- data/lib/Nand4c.rb +9 -0
- data/lib/Nor2.rb +9 -0
- data/lib/Nor2c.rb +9 -0
- data/lib/Nor3.rb +9 -0
- data/lib/OnePort.rb +11 -0
- data/lib/Output.rb +17 -0
- data/lib/ParseHelper.rb +80 -0
- data/lib/Parser.rb +137 -0
- data/lib/Port.rb +24 -0
- data/lib/ThreePorts.rb +17 -0
- data/lib/TwoPorts.rb +16 -0
- data/lib/Vdd.rb +10 -0
- data/lib/Xor2.rb +9 -0
- data/lib/version.rb +9 -0
- data/setup.rb +1585 -0
- data/test/test_bat.rb +222 -0
- data/test/test_helper.rb +7 -0
- metadata +84 -0
data/History.txt
ADDED
data/Manifest.txt
ADDED
@@ -0,0 +1,37 @@
|
|
1
|
+
History.txt
|
2
|
+
Manifest.txt
|
3
|
+
README.txt
|
4
|
+
Rakefile
|
5
|
+
lib/version.rb
|
6
|
+
lib/ParseHelper.rb
|
7
|
+
lib/Parser.rb
|
8
|
+
lib/Inst.rb
|
9
|
+
lib/Port.rb
|
10
|
+
lib/OnePort.rb
|
11
|
+
lib/TwoPorts.rb
|
12
|
+
lib/ThreePorts.rb
|
13
|
+
lib/FourPorts.rb
|
14
|
+
lib/FivePorts.rb
|
15
|
+
lib/Input.rb
|
16
|
+
lib/Output.rb
|
17
|
+
lib/Dffpc.rb
|
18
|
+
lib/Bufz.rb
|
19
|
+
lib/Mux2.rb
|
20
|
+
lib/Buf1.rb
|
21
|
+
lib/Gnd.rb
|
22
|
+
lib/Inv.rb
|
23
|
+
lib/Nand2.rb
|
24
|
+
lib/Nand2c.rb
|
25
|
+
lib/Nand3.rb
|
26
|
+
lib/Nand3c.rb
|
27
|
+
lib/Nand4.rb
|
28
|
+
lib/Nand4c.rb
|
29
|
+
lib/Nor2.rb
|
30
|
+
lib/Nor2c.rb
|
31
|
+
lib/Nor3.rb
|
32
|
+
lib/Vdd.rb
|
33
|
+
lib/Xor2.rb
|
34
|
+
bin/bat
|
35
|
+
setup.rb
|
36
|
+
test/test_bat.rb
|
37
|
+
test/test_helper.rb
|
data/README.txt
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
README for bat
|
2
|
+
==============
|
3
|
+
|
4
|
+
B^2 Logic Requirements
|
5
|
+
-BAT 1.0 is designed to work only with the BLT version of B^2 Logic 3.0, available at The University of Portland.
|
6
|
+
|
7
|
+
Design Considerations
|
8
|
+
-Inputs and Outputs
|
9
|
+
*B^2 Logic's EDF netlist does not make any distinction between active low input pad and active high input pads. Thus, all input pads are assumed to be active high. It is up to the designer to include inverters in the circuit itself, or assume that the inverted external signals will be available.
|
10
|
+
*Names of Input pads, Output pads and clocks must not contain any spaces or special characters. Valid names include only standard alphanumeric characters (A..Z, a..z, 0..9).
|
11
|
+
|
12
|
+
-BUFZ Implementation Details:
|
13
|
+
*If a BUFZ is used in a circuit, only the first (top) buffer on the BUFZ instance may be used. This is consistent with BLT implementation. One external pin is consumed per BUFZ and appears as instXpin in the final ABEL code. Tristated signals within the circuit will appear as an open input when in high impedance mode. Given this situation on CMOS technology, the signal will actually float to low rather than remain high impedance, as is typical of of any inputs that are left unconnected. TTL technology will float high in the same situation. Because of this, the designer must take care to ensure that the circuit is not designed expecting a true high impedance signal internal to the circuit (this is only achieved when the output is taken directly from the output pin consumed by the buffer).
|
14
|
+
|
15
|
+
-MUX2 Implementation Details:
|
16
|
+
*If a MUX2 is used in a circuit, only the first (top) MUX on the MUX2 package may be used. This is consistent with BLT implementation.
|
17
|
+
|
18
|
+
ABEL 7.0 Configuration
|
19
|
+
-Buffers are implemented by ORing the signal with itself to induce a single-gate propagation delay (4ns with Xilinx XC9536). Thus, if ABEL's preferences are set to reduce redundant logic the buffers will not work. If buffers are not included in a circuit, BAT designers recommend that ABEL bet set to reduce redundant logic, but ONLY if buffers are not used.
|
data/Rakefile
ADDED
@@ -0,0 +1,65 @@
|
|
1
|
+
require 'rubygems'
|
2
|
+
require 'rake'
|
3
|
+
require 'rake/clean'
|
4
|
+
require 'rake/testtask'
|
5
|
+
require 'rake/packagetask'
|
6
|
+
require 'rake/gempackagetask'
|
7
|
+
require 'rake/rdoctask'
|
8
|
+
require 'rake/contrib/rubyforgepublisher'
|
9
|
+
require 'fileutils'
|
10
|
+
require 'hoe'
|
11
|
+
include FileUtils
|
12
|
+
require File.join(File.dirname(__FILE__), 'lib', 'version')
|
13
|
+
|
14
|
+
AUTHOR = ['Jamie Quint','Ian Tagge'] # can also be an array of Authors
|
15
|
+
EMAIL = "jamiequint@gmail.com"
|
16
|
+
DESCRIPTION = "B2 Logic to ABEL Translator"
|
17
|
+
GEM_NAME = 'bat' # what ppl will type to install your gem
|
18
|
+
RUBYFORGE_PROJECT = 'bat' # The unix name for your project
|
19
|
+
HOMEPATH = "http://#{RUBYFORGE_PROJECT}.rubyforge.org"
|
20
|
+
DOWNLOAD_PATH = "http://rubyforge.org/projects/#{RUBYFORGE_PROJECT}"
|
21
|
+
|
22
|
+
NAME = "bat"
|
23
|
+
REV = nil # UNCOMMENT IF REQUIRED: File.read(".svn/entries")[/committed-rev="(d+)"/, 1] rescue nil
|
24
|
+
VERS = Bat::VERSION::STRING + (REV ? ".#{REV}" : "")
|
25
|
+
CLEAN.include ['**/.*.sw?', '*.gem', '.config', '**/.DS_Store']
|
26
|
+
RDOC_OPTS = ['--quiet', '--title', 'bat documentation',
|
27
|
+
"--opname", "index.html",
|
28
|
+
"--line-numbers",
|
29
|
+
"--main", "README",
|
30
|
+
"--inline-source"]
|
31
|
+
|
32
|
+
class Hoe
|
33
|
+
def extra_deps
|
34
|
+
@extra_deps.reject { |x| Array(x).first == 'hoe' }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
# Generate all the Rake tasks
|
39
|
+
# Run 'rake -T' to see list of generated tasks (from gem root directory)
|
40
|
+
hoe = Hoe.new(GEM_NAME, VERS) do |p|
|
41
|
+
p.author = AUTHOR
|
42
|
+
p.description = DESCRIPTION
|
43
|
+
p.email = EMAIL
|
44
|
+
p.summary = DESCRIPTION
|
45
|
+
p.url = HOMEPATH
|
46
|
+
p.rubyforge_name = RUBYFORGE_PROJECT if RUBYFORGE_PROJECT
|
47
|
+
p.test_globs = ["test/**/test_*.rb"]
|
48
|
+
p.clean_globs = CLEAN #An array of file patterns to delete on clean.
|
49
|
+
|
50
|
+
# == Optional
|
51
|
+
p.changes = p.paragraphs_of("History.txt", 0..1).join("\n\n")
|
52
|
+
#p.extra_deps = [] # An array of rubygem dependencies [name, version], e.g. [ ['active_support', '>= 1.3.1'] ]
|
53
|
+
#p.spec_extras = {} # A hash of extra values to set in the gemspec.
|
54
|
+
end
|
55
|
+
|
56
|
+
task :check_version do
|
57
|
+
unless ENV['VERSION']
|
58
|
+
puts 'Must pass a VERSION=x.y.z release version'
|
59
|
+
exit
|
60
|
+
end
|
61
|
+
unless ENV['VERSION'] == VERS
|
62
|
+
puts "Please update your version.rb to match the release version, currently #{VERS}"
|
63
|
+
exit
|
64
|
+
end
|
65
|
+
end
|
data/bin/bat
ADDED
@@ -0,0 +1,92 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
# The is the main executable for project BAT it handles the command line input and checks to see if it is valid.
|
4
|
+
# It reads the input file into an array and passes it to a Parser object which handles the parsing. Then it iterates
|
5
|
+
# through the created Inst objects and calls their output methods to produce the ABEL output code. This code is
|
6
|
+
# written to a file with the same name as the input file whose extension has been replaced with the .edf extension.
|
7
|
+
# add lib directory to load path
|
8
|
+
$:.unshift File.expand_path(File.join(File.dirname(__FILE__), "..", "lib"))
|
9
|
+
%w[ParseHelper Parser Inst Port OnePort TwoPorts ThreePorts FourPorts FivePorts
|
10
|
+
Input Output Dffpc Bufz Mux2 Buf1 Gnd Inv Nand2 Nand2c Nand3 Nand3c Nand4
|
11
|
+
Nand4c Nor2 Nor2c Nor3 Vdd Xor2].each do |r|
|
12
|
+
require r
|
13
|
+
end
|
14
|
+
|
15
|
+
# Format: [chipname, available pins]
|
16
|
+
# The available pins are not currently used but may be used in the future for
|
17
|
+
# checking whether the users design will fit on the given chip.
|
18
|
+
CHIPNAMES = [["xc9536",34],["gal16v8",14], ["pal16v8",14]]
|
19
|
+
|
20
|
+
# this is used to fake out command line input for testing
|
21
|
+
# ARGV = ["xc9536","../examples/FULLCNTR.EDF"]
|
22
|
+
|
23
|
+
# test command line for correct number of arguments
|
24
|
+
if ARGV.length != 2
|
25
|
+
puts "Too many arguments - usage: bat chipname inputfilepath" if ARGV.length > 2
|
26
|
+
puts "Too few arguments - usage: bat chipname inputfilepath" if ARGV.length < 2
|
27
|
+
exit
|
28
|
+
else
|
29
|
+
# if the chipname is wrong, print out a list of proper chipnames
|
30
|
+
if CHIPNAMES.assoc(ARGV[0].downcase).nil?
|
31
|
+
errstr = ""
|
32
|
+
print "Invalid Chipname - Chipnames: "
|
33
|
+
CHIPNAMES.each do |c|
|
34
|
+
errstr << "#{c[0]}, "
|
35
|
+
end
|
36
|
+
# chop off the extra comma, print it, and quit
|
37
|
+
puts errstr.slice(0,errstr.length - 2)
|
38
|
+
exit
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
# check if the file exists
|
43
|
+
if File.exist?(ARGV[1])
|
44
|
+
# read EDF file into an array of lines
|
45
|
+
input_file = IO.readlines(ARGV[1])
|
46
|
+
else
|
47
|
+
puts "No such file or directory - #{ARGV[1]}"
|
48
|
+
exit
|
49
|
+
end
|
50
|
+
|
51
|
+
# pass the input file array to the parser to parse
|
52
|
+
begin
|
53
|
+
p = Parser.new()
|
54
|
+
insts = p.parse(input_file)
|
55
|
+
# catch any errors with the EDF file
|
56
|
+
rescue
|
57
|
+
puts "Invalid EDF File"
|
58
|
+
exit
|
59
|
+
end
|
60
|
+
|
61
|
+
# kill the extension
|
62
|
+
# TODO - make this look for the "." then chop
|
63
|
+
oname = ARGV[1].slice(0,ARGV[1].length - 4)
|
64
|
+
# see if the file exists and prompt user to overwrite if it does
|
65
|
+
if File.exist?("#{oname}.abl")
|
66
|
+
print "File #{oname}.abl already exists, overwrite? (Y/N): "
|
67
|
+
overwrite = STDIN.gets
|
68
|
+
exit if overwrite.chomp.downcase != "y"
|
69
|
+
end
|
70
|
+
|
71
|
+
begin
|
72
|
+
# open file to write
|
73
|
+
f = File.new("#{oname}.abl","w+")
|
74
|
+
# output all data
|
75
|
+
f.puts "Module BATcode"
|
76
|
+
f.puts "\n\"inputs"
|
77
|
+
insts.each_value {|val| f.print val.inputs}
|
78
|
+
f.puts "\n\"outputs"
|
79
|
+
insts.each_value {|val| f.print val.outputs}
|
80
|
+
f.puts "\n\"nodes"
|
81
|
+
insts.each_value {|val| f.print val.nodes}
|
82
|
+
f.puts "\nequations"
|
83
|
+
insts.each_value {|val| f.print val.abelout}
|
84
|
+
f.puts "\nend BATcode"
|
85
|
+
puts "ABEL output to file #{oname}.abl successful"
|
86
|
+
# catch any output exception and print the proper error message
|
87
|
+
rescue Exception => e
|
88
|
+
puts e
|
89
|
+
# make sure to quit regardless of what happens
|
90
|
+
ensure
|
91
|
+
exit
|
92
|
+
end
|
data/lib/Buf1.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
# This class defines the Buffer part
|
2
|
+
class Buf1 < TwoPorts
|
3
|
+
|
4
|
+
# This method is called when a new object is instantiated, it takes the name of the Inst object (name) as its only argument.
|
5
|
+
# It is responsible for defining applicable nodes, then calling its superclass, TwoPorts, to complete other tasks.
|
6
|
+
def initialize(name)
|
7
|
+
super(name)
|
8
|
+
# set ABEL to not reduce redundant logic since this is a buffer
|
9
|
+
nodes << "#{name}p1\tnode;\n#{name}p1a\tnode;\n"
|
10
|
+
end
|
11
|
+
|
12
|
+
# This method returns the specific ABEL code to be output for this Inst object based on its connections on its input ports.
|
13
|
+
# These connections are defined in the abelout method of this object's superclass, TwoPorts.
|
14
|
+
def abelout
|
15
|
+
super
|
16
|
+
s = "#{self.name}p1a = #{@p0};\n"
|
17
|
+
s << "#{self.name}p1 = #{@p0} # #{self.name}p1a;\n"
|
18
|
+
end
|
19
|
+
|
20
|
+
# TODO test istype 'keep' in ABEL and make sure that this logic is not reduced
|
21
|
+
# TODO jamie - if you have not already figured out how to search for the '.' and then chop of the end try this:
|
22
|
+
# TODO index = port.name.rindex('p'
|
23
|
+
# TODO portnum = port.name[index..-1]
|
24
|
+
# TODO owner = port.name[0...index]
|
25
|
+
# TODO exactly this implementation obviously will not work, but that is the method I used a while ago...
|
26
|
+
|
27
|
+
end
|
data/lib/Bufz.rb
ADDED
@@ -0,0 +1,46 @@
|
|
1
|
+
# This class defines the Tri-State Buffer part
|
2
|
+
class Bufz < Inst
|
3
|
+
|
4
|
+
# This method is called when a new object is instantiated, it takes the name of the Inst object (name) as its only argument.
|
5
|
+
# Because of its unique functionality, this object does not call its superclass upon instantiation but rather handles all
|
6
|
+
# initialization procedures itself, it sets its attributes, defines the apropriate input and output pins, definines its nodes,
|
7
|
+
# and initializes the apropriate ports.
|
8
|
+
def initialize(name)
|
9
|
+
# TODO - it is retarted that this inherits from Inst since it never calls super
|
10
|
+
# make it so insts know their own name
|
11
|
+
self.name = name
|
12
|
+
self.inputs = ""
|
13
|
+
# create constant definitions for each output pin
|
14
|
+
self.nodes = "#{name}out\tnode;\n"
|
15
|
+
self.outputs = "#{name}pin\tpin;\n"
|
16
|
+
@iports = {}
|
17
|
+
|
18
|
+
# iterate to create input port(s)
|
19
|
+
(0..1).to_a.each do |d|
|
20
|
+
portname = "#{name}p#{d}"
|
21
|
+
@iports["#{portname}"] = Port.new(name, 'in', portname)
|
22
|
+
end
|
23
|
+
|
24
|
+
# Fake out an output port (we will act like we are connecting pins to this port, but really it references an output pin)
|
25
|
+
# ABEL doesn't know the difference since we have called our output pin the same name as this faked out port
|
26
|
+
@iports["#{name}out"] = Port.new(name, 'out', "#{name}out")
|
27
|
+
end
|
28
|
+
|
29
|
+
# This method defines the connections held by the ports of this object and returns the specific ABEL code to be output for this
|
30
|
+
# object based on the connections on its input ports.
|
31
|
+
def abelout
|
32
|
+
# create defs only for inputs to inst
|
33
|
+
# make these insts just for consistency's sake
|
34
|
+
@p0 = self.get_port("p0").connections.collect{|p| p.name}.to_s
|
35
|
+
@p1 = self.get_port("p1").connections.collect{|p| p.name}.to_s
|
36
|
+
|
37
|
+
# code for all tristate buffers on b2logic component
|
38
|
+
s = "\n\"tristate buffer - consumes one external pin\n#{self.name}pin.oe = 0;\n"
|
39
|
+
unless @p0.empty? || @p1.empty?
|
40
|
+
s << "WHEN (#{@p0}) THEN \n\t{#{self.name}pin.oe = 1;\n"
|
41
|
+
s << "\t#{self.name}pin = #{@p1};}\n"
|
42
|
+
end
|
43
|
+
s << "#{self.name}out = #{self.name}pin.pin;\n\n"
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
data/lib/Dffpc.rb
ADDED
@@ -0,0 +1,40 @@
|
|
1
|
+
# This class defines the D Flip-Flop part
|
2
|
+
class Dffpc < Inst
|
3
|
+
|
4
|
+
# This method is called when a new object is instantiated, it takes the name of the Inst object (name) as its only argument.
|
5
|
+
# It is responsible for defining applicable nodes, then calling its superclass, Inst, to complete other tasks.
|
6
|
+
def initialize(name)
|
7
|
+
# TODO - make this cleaner, should either override the whole superclass or pass it the type of the node
|
8
|
+
super(name,[0,1,2,3],[4,5],false)
|
9
|
+
[4,5].each do |d|
|
10
|
+
# define these nodes separately from super because they are of type reg
|
11
|
+
nodes<<"#{name}p#{d}\tnode istype 'reg';\n"
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
# This method defines the connections held by the ports of this object and returns the specific ABEL code to be output for this
|
16
|
+
# object based on the connections on its input ports.
|
17
|
+
def abelout
|
18
|
+
# make these class variables just for consistency's sake
|
19
|
+
@p0 = self.get_port("p0").connections.collect{|p| p.name}.to_s
|
20
|
+
@p1 = self.get_port("p1").connections.collect{|p| p.name}.to_s
|
21
|
+
@p2 = self.get_port("p2").connections.collect{|p| p.name}.to_s
|
22
|
+
@p3 = self.get_port("p3").connections.collect{|p| p.name}.to_s
|
23
|
+
@p4 = self.get_port("p4").connections.collect{|p| p.name}.to_s
|
24
|
+
@p5 = self.get_port("p5").connections.collect{|p| p.name}.to_s
|
25
|
+
@p4 = self.get_port("p4").connections.collect{|p| p.name}.to_s
|
26
|
+
@p5 = self.get_port("p5").connections.collect{|p| p.name}.to_s
|
27
|
+
|
28
|
+
s = "\n\"d-ff\n"
|
29
|
+
unless @p4.empty?
|
30
|
+
s << "#{self.name}p4.ap = !#{@p0};\n#{self.name}p4.ar = !#{@p3};\n#{self.name}p4.clk = #{@p1};\n"
|
31
|
+
s << "#{self.name}p4 := #{@p2};\n\n"
|
32
|
+
end
|
33
|
+
unless @p5.empty?
|
34
|
+
s << "#{self.name}p5.ap = !#{@p0};\n#{self.name}p5.ar = !#{@p3};\n#{self.name}p5.clk = #{@p1};\n"
|
35
|
+
s << "#{self.name}p5 := !#{@p2};\n\n"
|
36
|
+
end
|
37
|
+
s
|
38
|
+
end
|
39
|
+
|
40
|
+
end
|
data/lib/FivePorts.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# This class is the superclass for all five port Inst objects
|
2
|
+
# Nand4c and Nand4 inherit from this class
|
3
|
+
|
4
|
+
class FivePorts < Inst
|
5
|
+
# This method is called when a new object is instantiated, it takes the name of the Inst object (name) as its only argument.
|
6
|
+
# It is responsible for calling its superclass Inst and passing to it the correct number of input ports and output ports to
|
7
|
+
# be created.
|
8
|
+
def initialize(name)
|
9
|
+
super(name,[0,1,2,3],[4])
|
10
|
+
end
|
11
|
+
|
12
|
+
# This method defines the connections held by the ports for this object's subclasses.
|
13
|
+
def abelout
|
14
|
+
@p0 = self.get_port("p0").connections.collect{|p| p.name}.to_s
|
15
|
+
@p1 = self.get_port("p1").connections.collect{|p| p.name}.to_s
|
16
|
+
@p2 = self.get_port("p2").connections.collect{|p| p.name}.to_s
|
17
|
+
@p3 = self.get_port("p3").connections.collect{|p| p.name}.to_s
|
18
|
+
end
|
19
|
+
end
|
data/lib/FourPorts.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# This class is the superclass for all four port Inst objects
|
2
|
+
# Nand3, Nor3, and Nand3c inherit from this class
|
3
|
+
|
4
|
+
class FourPorts < Inst
|
5
|
+
# This method is called when a new object is instantiated, it takes the name of the Inst object (name) as its only argument.
|
6
|
+
# It is responsible for calling its superclass Inst and passing to it the correct number of input ports and output ports to
|
7
|
+
# be created.
|
8
|
+
def initialize(name)
|
9
|
+
super(name,[0,1,2],[3])
|
10
|
+
end
|
11
|
+
|
12
|
+
# This method defines the connections held by the ports for this object's subclasses.
|
13
|
+
def abelout
|
14
|
+
@p0 = self.get_port("p0").connections.collect{|p| p.name}.to_s
|
15
|
+
@p1 = self.get_port("p1").connections.collect{|p| p.name}.to_s
|
16
|
+
@p2 = self.get_port("p2").connections.collect{|p| p.name}.to_s
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
data/lib/Gnd.rb
ADDED
@@ -0,0 +1,10 @@
|
|
1
|
+
# This class defines the Ground part
|
2
|
+
class Gnd < OnePort
|
3
|
+
# This method is called when a new object is instantiated, it takes the name of the Inst object (name) as its only argument.
|
4
|
+
# It is responsible for defining applicable input pins, then calling its superclass, OnePort, to complete other tasks.
|
5
|
+
def initialize(name)
|
6
|
+
super(name)
|
7
|
+
# gnd is declared as a constant within the chip to save input pins
|
8
|
+
self.inputs = "#{self.name}p0 = 0;\n"
|
9
|
+
end
|
10
|
+
end
|
data/lib/Input.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
# This class defines the Input pad part
|
2
|
+
class Input < OnePort
|
3
|
+
# This method is called when a new object is instantiated, it takes the name of the Inst object (name) as its only argument.
|
4
|
+
# It is responsible for defining applicable input pins, then calling its superclass, OnePort, to complete other tasks.
|
5
|
+
def initialize(name)
|
6
|
+
super(name)
|
7
|
+
self.inputs = "#{self.name}p0\tpin;\n"
|
8
|
+
end
|
9
|
+
end
|
data/lib/Inst.rb
ADDED
@@ -0,0 +1,51 @@
|
|
1
|
+
# This class defines the Inst object. Inst is a superclass for many different subclasses.
|
2
|
+
# This class handles mostly generalizations of what happens in all of its subclasses. Inst objects are instantiated
|
3
|
+
# by the Parser component as they are found, and are connected to each other via their Port objects.
|
4
|
+
class Inst
|
5
|
+
|
6
|
+
attr_accessor :name, :nodes, :inputs, :outputs
|
7
|
+
# This method is responsible for creating the correct number of input ports and output ports for each Inst object based on the arguments
|
8
|
+
# it recieves (inputs and outputs). It is also responsible for generating nodes for each output pin (this is the default behavior)
|
9
|
+
# unless is is explicitly instructed not to do so via an argument (createnode).
|
10
|
+
def initialize(name,inputs = [], outputs = [], createnode = true)
|
11
|
+
# make it so insts know their own name
|
12
|
+
self.name = name
|
13
|
+
self.nodes = ""
|
14
|
+
self.inputs = ""
|
15
|
+
self.outputs = ""
|
16
|
+
@iports = {}
|
17
|
+
|
18
|
+
# iterate to create input port(s)
|
19
|
+
inputs.each do |d|
|
20
|
+
portname = "#{name}p#{d}"
|
21
|
+
@iports["#{portname}"] = Port.new(name, 'in', portname)
|
22
|
+
end
|
23
|
+
# iterate to create output port(s) and node(s) (for output pins)
|
24
|
+
outputs.each do |d|
|
25
|
+
portname = "#{name}p#{d}"
|
26
|
+
@iports["#{portname}"] = Port.new(name, 'out', portname)
|
27
|
+
nodes<<"#{name}p#{d}\tnode;\n" if createnode
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
# This method takes a port name as input (pname) and returns
|
32
|
+
# the port object corresponding to that port name
|
33
|
+
def get_port(pname)
|
34
|
+
# get the port from the iports hash
|
35
|
+
if pname =~ /p\d+/
|
36
|
+
@iports["#{self.name}#{pname}"]
|
37
|
+
elsif pname =~ /out/
|
38
|
+
@iports["#{self.name}out"]
|
39
|
+
else
|
40
|
+
[]
|
41
|
+
end
|
42
|
+
end
|
43
|
+
|
44
|
+
# Generally this method returns the specific ABEL code to be output for this Inst object based on its connections on its input ports.
|
45
|
+
# The inst superclass defaults this value to a blank string so that if abelout is not defined in the subclass there will not be a
|
46
|
+
# method not found error.
|
47
|
+
def abelout
|
48
|
+
""
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|