rtl_circuit 0.7

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: ee25e08cf291db2381c60746dd1d654d4931bd0742cdd12f1f85b55b4065f694
4
+ data.tar.gz: 6a39ac68ccf30ff37ab674dad83ff74686fe81d6e3cf6e1c8b1cca5d0d88c384
5
+ SHA512:
6
+ metadata.gz: c5af6786663be64b4ff0dff83e240732a48ba17e0980ae7585f7a8d8967f107a81cf106608049829330f6aa094fd777bf9c26543595501ee469b4015ed6eecd2
7
+ data.tar.gz: 6b633468fc83534bd1164ded8ed001154d378a37c4f37aecde60ec04b14c1ea5cdc762f21565f7291b09dd88eb070a89a7ed811a749a2463c10d905c0a815142
@@ -0,0 +1,136 @@
1
+ module RTL
2
+
3
+ class Circuit
4
+ attr_accessor :name
5
+ attr_accessor :iname
6
+ attr_accessor :ports
7
+ attr_accessor :components
8
+ attr_accessor :father
9
+ attr_accessor :signals
10
+ attr_accessor :properties
11
+
12
+ @@id=-1
13
+
14
+ def initialize name=nil
15
+ @name=name
16
+ @iname="#{name}_#{@@id+=1}"
17
+ @ports={in:[],out:[]}
18
+ @signals=[]
19
+ @components=[]
20
+ @properties={}
21
+ @color="cadetblue"
22
+ end
23
+
24
+ def add element
25
+ port=circuit=sig=element
26
+ case element
27
+ when Sig
28
+ @signals<< sig
29
+ sig.circuit=self
30
+ when Port
31
+ @ports[port.dir] << port
32
+ port.circuit=self
33
+ when Circuit
34
+ @components << circuit
35
+ circuit.father=self
36
+ else
37
+ raise "ERROR : when adding '#{element}'"
38
+ end
39
+ end
40
+
41
+ def port_named dir,name
42
+ @ports[dir].find{|p| p.name==name}
43
+ end
44
+
45
+ def port name
46
+ all=@ports[:in]+@ports[:out]
47
+ all.flatten.find{|p| p.name==name}
48
+ end
49
+
50
+ def component_named name
51
+ @components.find{|comp| comp.iname==name}
52
+ end
53
+
54
+ def inputs
55
+ @ports[:in]
56
+ end
57
+
58
+ def outputs
59
+ @ports[:out]
60
+ end
61
+
62
+ def wires
63
+ wires=[]
64
+ wires << inputs.map{|p| p.fanout}
65
+ wires << signals.map{|p| p.fanout}
66
+ wires << components.map{|comp| comp.outputs.map{|o| o.fanout}}
67
+ wires.flatten
68
+ end
69
+
70
+ def new_instance
71
+ @@clone_id||={}
72
+ @@clone_id[name]||=-1
73
+ @@clone_id[name]+=1
74
+ clone=Marshal.load(Marshal.dump(self))
75
+ clone.iname=self.name+"_#{@@clone_id[name]}"
76
+ clone
77
+ end
78
+
79
+ def make_lib
80
+ filename="#{name}.lib"
81
+ File.open(filename,'w') do |f|
82
+ f.puts Marshal.dump(self)
83
+ end
84
+ end
85
+
86
+ def to_dot
87
+ Printer.new.print self
88
+ end
89
+ end
90
+
91
+ class Port
92
+ attr_accessor :dir
93
+ attr_accessor :name
94
+ attr_accessor :circuit
95
+ attr_accessor :fanout
96
+ attr_accessor :properties
97
+ def initialize dir,name
98
+ @dir=dir
99
+ @name=name
100
+ @fanout=[]
101
+ @properties={}
102
+ end
103
+
104
+ def connect port
105
+ puts "connecting #{self.name}-> #{port.name}" if $verbose
106
+ @fanout << Wire.new(self,port)
107
+ end
108
+
109
+ def type=(t)
110
+ @properties[:type]=t
111
+ end
112
+
113
+ def type
114
+ @properties[:type]
115
+ end
116
+ end
117
+
118
+ class Sig < Port
119
+ def initialize name
120
+ super(:out,name)
121
+ end
122
+ end
123
+
124
+ class Wire
125
+ @@id=-1
126
+ attr_accessor :name
127
+ attr_accessor :source,:sink
128
+ attr_accessor :properties
129
+ def initialize source,sink
130
+ @name="w_#{@@id+=1}"
131
+ @source=source
132
+ @sink=sink
133
+ @properties={}
134
+ end
135
+ end
136
+ end
data/lib/rtl/code.rb ADDED
@@ -0,0 +1,47 @@
1
+ class Code
2
+
3
+ attr_accessor :indent,:lines
4
+
5
+ def initialize str=nil
6
+ @lines=[]
7
+ (@lines << str) if str
8
+ @indent=0
9
+ end
10
+
11
+ def <<(thing)
12
+ if (code=thing).is_a? Code
13
+ code.lines.each do |line|
14
+ @lines << " "*@indent+line.to_s
15
+ end
16
+ elsif thing.is_a? Array
17
+ thing.each do |kode|
18
+ @lines << kode
19
+ end
20
+ elsif thing.nil?
21
+ else
22
+ @lines << " "*@indent+thing.to_s
23
+ end
24
+ end
25
+
26
+ def finalize
27
+ return @lines.join("\n") if @lines.any?
28
+ ""
29
+ end
30
+
31
+ def newline
32
+ @lines << " "
33
+ end
34
+
35
+ def save_as filename,verbose=true
36
+ str=self.finalize
37
+ File.open(filename,'w'){|f| f.puts(str)}
38
+ puts "code saved as : #{filename}" if verbose
39
+ return filename
40
+ end
41
+
42
+ def size
43
+ @lines.size
44
+ end
45
+
46
+
47
+ end
@@ -0,0 +1,85 @@
1
+ require_relative "circuit"
2
+
3
+ module RTL
4
+
5
+ class UnaryGate < Circuit
6
+ def initialize
7
+ name=self.class.to_s.split("::").last
8
+ super(name)
9
+ add Port.new(:in,"i")
10
+ add Port.new(:out,"f")
11
+ end
12
+ end
13
+
14
+ class BinaryGate < Circuit
15
+ def initialize
16
+ name=self.class.to_s.split("::").last
17
+ super(name)
18
+ add Port.new(:in,"i1")
19
+ add Port.new(:in,"i2")
20
+ add Port.new(:out,"f")
21
+ end
22
+ end
23
+
24
+ class Not < UnaryGate
25
+ end
26
+
27
+ class Or < BinaryGate
28
+ end
29
+
30
+ class And < BinaryGate
31
+ end
32
+
33
+ class Nand < BinaryGate
34
+ end
35
+
36
+ class Nor < BinaryGate
37
+ end
38
+
39
+ class Xor < BinaryGate
40
+ end
41
+
42
+ class Reg < Circuit
43
+ def initialize
44
+ name="Reg"
45
+ super(name)
46
+ add Port.new(:in ,"d")
47
+ add Port.new(:out,"q")
48
+ @color="darkorange"
49
+ end
50
+ end
51
+
52
+ class Mux < Circuit
53
+ attr_accessor :arity
54
+ def initialize
55
+ name="Mux"
56
+ super(name)
57
+ @arity=0
58
+ add Port.new("i0",:in)
59
+ add Port.new("i1",:in)
60
+ add Port.new("sel",:in)
61
+ add Port.new("f",:out)
62
+ end
63
+
64
+ def add port
65
+ @arity+=1
66
+ super port
67
+ end
68
+ end
69
+
70
+ class Add < BinaryGate
71
+ end
72
+
73
+ class Sub < BinaryGate
74
+ end
75
+
76
+ class Mul < BinaryGate
77
+ end
78
+
79
+ class Div < BinaryGate
80
+ end
81
+
82
+ class Rem < BinaryGate
83
+ end
84
+
85
+ end
@@ -0,0 +1,82 @@
1
+ require_relative 'code'
2
+
3
+ module RTL
4
+
5
+ class Printer
6
+
7
+ def print circuit
8
+ dot=Code.new
9
+ dot << "digraph G {"
10
+ dot.indent=2
11
+ dot << "graph [rankdir = LR];"
12
+ circuit.components.each do |comp|
13
+ inputs_dot ="{"+comp.ports[:in].collect{|e| "<#{e.name}>#{e.name}"}.join("|")+"}"
14
+ outputs_dot="{"+comp.ports[:out].collect{|e| "<#{e.name}>#{e.name}"}.join("|")+"}"
15
+ p color=circuit.color
16
+ dot << "#{comp.iname}[ shape=record; style=filled ; color=#{color} ; label=\"{ #{inputs_dot}| #{comp.name} | #{outputs_dot} }\"];"
17
+ end
18
+ circuit.ports[:in].each do |p|
19
+ dot << "#{p.name}[shape=cds label=\"#{p.name}\"];"
20
+ end
21
+ circuit.ports[:out].each do |p|
22
+ dot << "#{p.name}[shape=cds label=\"#{p.name}\"];"
23
+ end
24
+ circuit.signals.each do |sig|
25
+ dot << "#{sig.name}[shape=point ; xlabel=\"#{sig.name}\"]; /* sig */"
26
+ end
27
+ circuit.ports[:in].each do |source|
28
+ source.fanout.each do |wire|
29
+ source_name=source.name
30
+ sink=wire.sink
31
+ sink_name=sink.name
32
+ if sink.circuit!=circuit
33
+ sink_name="#{sink.circuit.iname}:#{sink_name}"
34
+ end
35
+ wire_name=wire.name if $verbose
36
+ dot << "#{source_name} -> #{sink_name} [label=\"#{wire_name}\"]/* pin */"
37
+ end
38
+ end
39
+ circuit.signals.each do |sig|
40
+ sig.fanout.each do |wire|
41
+ source_name=sig.name
42
+ sink =wire.sink
43
+ sink_name=sink.name
44
+ if sink.circuit!=circuit
45
+ sink_name="#{sink.circuit.iname}:#{sink_name}"
46
+ end
47
+ wire_name=wire.name if $verbose
48
+ dot << "#{source_name} -> #{sink_name} [label=\"#{wire_name}\"] /* sig */"
49
+ end
50
+ end
51
+
52
+ circuit.components.each do |c|
53
+ c.ports[:out].each do |p|
54
+ p.fanout.each do |wire| #pin
55
+ pout=wire.sink
56
+ c=pout.circuit==circuit ? "#{pout.name}" : "#{pout.circuit.iname}:#{pout.name}"
57
+ if c!=p.circuit.iname+":"+p.name
58
+ wire_name=wire.name if $verbose
59
+ dot << "#{p.circuit.iname}:#{p.name} -> #{c}[label=\"#{wire_name}\"]; /* tag3 */"
60
+ end
61
+ end
62
+ end
63
+ end
64
+ dot.indent=0
65
+ dot << "}"
66
+ dot.save_as "#{circuit.name}.dot",verbose=false
67
+ end
68
+
69
+ def print_svg circuit
70
+ svg=Code.new
71
+ svg << "{"
72
+ svg.indent=2
73
+ svg << "creator: \"RTL::printer version #{version}\","
74
+ svg << "modules: "
75
+ svg.indent=4
76
+ svg.indent=2
77
+ svg.indent=0
78
+ svg << "}"
79
+ svg
80
+ end
81
+ end
82
+ end
data/lib/rtl.rb ADDED
@@ -0,0 +1,8 @@
1
+ require_relative "./rtl/circuit"
2
+ require_relative "./rtl/library"
3
+ require_relative "./rtl/printer"
4
+ require_relative "./rtl/placer"
5
+ require_relative "./rtl/json_parser"
6
+
7
+ module RTL
8
+ end
@@ -0,0 +1,4 @@
1
+ require_relative "../../lib/rtl"
2
+ puts "testing json".center(40,'=')
3
+ g=Parser.new.parse "ex_1.json"
4
+ g.print_info
@@ -0,0 +1,20 @@
1
+ #require "rtl_circuit"
2
+ require_relative "../../../rtl/lib/rtl.rb"
3
+
4
+ include RTL
5
+
6
+ top=Circuit.new("top_0")
7
+ top.add a=Port.new(:in,"a")
8
+ top.add b=Port.new(:in,"b")
9
+ top.add f=Port.new(:out,"f")
10
+ top.add g1=And.new
11
+ top.add g2=Xor.new
12
+
13
+ a.connect g1.port("i1")
14
+ b.connect g1.port("i2")
15
+ b.connect g2.port("i2")
16
+ g1.port("f").connect g2.port("i1")
17
+ g2.port("f").connect f
18
+ top.to_dot
19
+
20
+ Placer.new.place top
@@ -0,0 +1,32 @@
1
+ #require "rtl_circuit"
2
+ require_relative "../../../rtl/lib/rtl.rb"
3
+
4
+ include RTL
5
+
6
+ top=Circuit.new("top_1")
7
+ top.add a=Port.new(:in,"a")
8
+ top.add b=Port.new(:in,"b")
9
+ top.add c=Port.new(:in,"c")
10
+ top.add d=Port.new(:in,"d")
11
+ top.add f=Port.new(:out,"f")
12
+
13
+ top.add a1=And.new
14
+ top.add a2=Or.new
15
+ top.add a3=Nor.new
16
+ top.add a4=Nand.new
17
+ top.add a5=Xor.new
18
+
19
+ a.connect a1.port("i1")
20
+ b.connect a1.port("i2")
21
+ b.connect a2.port("i1")
22
+ c.connect a2.port("i2")
23
+ c.connect a3.port("i1")
24
+ d.connect a3.port("i2")
25
+ a2.port("f").connect a4.port("i1")
26
+ a3.port("f").connect a4.port("i2")
27
+ a1.port("f").connect a5.port("i1")
28
+ a4.port("f").connect a5.port("i2")
29
+ a5.port("f").connect f
30
+ top.to_dot
31
+
32
+ Placer.new.place top
@@ -0,0 +1,18 @@
1
+ require_relative "../../../synchrony/lib/synchrony"
2
+
3
+ puts "synchrony 1"
4
+
5
+ sync= %{
6
+ circuit sync1
7
+ input a,b,c,d,e,f,g,h,i,j
8
+ output o1,o2
9
+ sig s1
10
+ s1=(a and !b) or (c and d)
11
+ o1=((e and f) xor s1) and g
12
+ o2=(e and f) or (s1 and h) and reg(i or j)
13
+ end
14
+ }
15
+ filename="sync_0.syc"
16
+ File.open(filename,'w'){|f| f.puts(sync)}
17
+
18
+ Synchrony::Compiler.new.compile filename
metadata ADDED
@@ -0,0 +1,51 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rtl_circuit
3
+ version: !ruby/object:Gem::Version
4
+ version: '0.7'
5
+ platform: ruby
6
+ authors:
7
+ - Jean-Christophe Le Lann
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2021-02-16 00:00:00.000000000 Z
12
+ dependencies: []
13
+ description: simple digital circuit modeling, with hierarchy and graphviz output
14
+ email: jean-christophe.le_lann@ensta-bretagne.fr
15
+ executables: []
16
+ extensions: []
17
+ extra_rdoc_files: []
18
+ files:
19
+ - lib/rtl.rb
20
+ - lib/rtl/circuit.rb
21
+ - lib/rtl/code.rb
22
+ - lib/rtl/library.rb
23
+ - lib/rtl/printer.rb
24
+ - tests/json/testing_json.rb
25
+ - tests/pnr/pnr_0.rb
26
+ - tests/pnr/pnr_1.rb
27
+ - tests/pnr/sync_0.rb
28
+ homepage: http://www.github.com/JC-LL/rtl
29
+ licenses:
30
+ - GPL-2.0-only
31
+ metadata: {}
32
+ post_install_message:
33
+ rdoc_options: []
34
+ require_paths:
35
+ - lib
36
+ required_ruby_version: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
41
+ required_rubygems_version: !ruby/object:Gem::Requirement
42
+ requirements:
43
+ - - ">="
44
+ - !ruby/object:Gem::Version
45
+ version: '0'
46
+ requirements: []
47
+ rubygems_version: 3.0.6
48
+ signing_key:
49
+ specification_version: 4
50
+ summary: simple digital circuit modeling
51
+ test_files: []