Class: RTL::Placer

Inherits:
Object
  • Object
show all
Defined in:
lib/rtl/placer.rb

Constant Summary collapse

SVG_ELEMENT =
{
    "and"  => "and2",
    "nand" => "nand2",
    "or"   => "or2",
    "nor"  => "nor2",
    "xor"  => "xor2",
    "not"  => "not",
}

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#circuitObject

Returns the value of attribute circuit.



8
9
10
# File 'lib/rtl/placer.rb', line 8

def circuit
  @circuit
end

Instance Method Details

#gen_pnr_edges(circuit) ⇒ Object



73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
# File 'lib/rtl/placer.rb', line 73

def gen_pnr_edges circuit
  edges=[]
  circuit.inputs.each do |input|
    input.fanout.each do |wire|
      psource=wire.source
      if psource.circuit==circuit #psink is a port of current circuit
        source=psource
      else
        source=psource.circuit # one of the components
      end
      psink=wire.sink
      if psink.circuit==circuit #psink is a port of current circuit
        sink=psink
      else
        sink=psink.circuit # one of the components
      end
      id_source=source.object_id.to_s
      id_sink  =sink.object_id.to_s
      node_source=@sym[id_source]
      node_sink=@sym[id_sink]
      params={"source"    => node_source,
              "sink"      => node_sink
      }
      edges << Edge.new(params)
    end
  end
  circuit.signals.each do |sig|
    sig.fanout.each do |wire|
      psource=wire.source
      if psource.circuit==circuit #psink is a port of current circuit
        source=psource
      else
        source=psource.circuit # one of the components
      end
      psink=wire.sink
      if psink.circuit==circuit #psink is a port of current circuit
        sink=psink
      else
        sink=psink.circuit # one of the components
      end
      id_source=source.object_id.to_s
      id_sink  =sink.object_id.to_s
      node_source=@sym[id_source]
      node_sink=@sym[id_sink]
      params={"source"    => node_source,
              "sink"      => node_sink
      }
      edges << Edge.new(params)
    end
  end
  circuit.components.each do |comp|
    comp.outputs.each do |output|
      output.fanout.each do |wire|
        psource=wire.source
        if psource.circuit==circuit #psink is a port of current circuit
          source=psource
        else
          source=psource.circuit # one of the components
        end
        psink=wire.sink
        if psink.circuit==circuit #psink is a port of current circuit
          sink=psink
        else
          sink=psink.circuit # one of the components
        end
        id_source=source.object_id.to_s
        id_sink  =sink.object_id.to_s
        node_source=@sym[id_source]
        node_sink=@sym[id_sink]
        params={"source"    => node_source,
                "sink"      => node_sink
        }
        edges << Edge.new(params)
      end
    end
  end
  edges
end

#gen_pnr_nodes(circuit) ⇒ Object



26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/rtl/placer.rb', line 26

def gen_pnr_nodes circuit
  nodes=[]
  @sym={} # internal references for p&r
  @map={} # link to RTL::Circuit objects
  circuit.inputs.each_with_index do |port,idx|
    id=port.object_id.to_s
    dy=600.0/circuit.inputs.size
    params={"id"    => id,
            "pos"   => [10,idx*dy],
            "fixed" => [true,false],
    }
    nodes << node=Node.new(params)
    @sym[id]=node
    @map[node]=port
  end
  circuit.outputs.each_with_index do |port,idx|
    id=port.object_id.to_s
    dy=600.0/circuit.outputs.size
    params={"id"    => id,
            "pos"   => [500,dy*idx],
            "fixed" => [true,false],
    }
    nodes << node=Node.new(params)
    @sym[id]=node
    @map[node]=port
  end
  circuit.signals.each do |port|
    id=port.object_id.to_s
    params={"id"    => id,
            "pos"   => [rand(600),rand(600)]
    }
    nodes << node=Node.new(params)
    @sym[id]=node
    @map[node]=port
  end
  circuit.components.each do |comp|
    id=comp.object_id.to_s
    params={"id"    => id,
            "pos"   => [rand(300),rand(300)],
    }
    nodes << node=Node.new(params)
    @sym[id]=node
    @map[node]=comp
  end
  nodes
end

#gen_svg(graph) ⇒ Object



160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/rtl/placer.rb', line 160

def gen_svg graph
  svg=Code.new
  svg << "<svg width=\"600\" height=\"300\""
  svg << "     xmlns=\"http://www.w3.org/2000/svg\""
  svg << "     xmlns:xlink=\"http://www.w3.org/1999/xlink\">"
  svg << IO.read("/home/jcll/JCLL/dev/EDA-ESL/rtl/lib/rtl/def_gates.svg")
  graph.nodes.each do |node|
    circuit=@map[node]
    klass=circuit.class.to_s.split("::").last.downcase
    element=SVG_ELEMENT[klass] || "not"
    pos=node.pos
    x,y=pos.x,pos.y
    svg << "<use xlink:href=\"##{element}\"  x=\"#{x}\" y=\"#{y}\"/>"
  end
  svg << "</svg>"
  filename="#{circuit.name}_pnr.svg"
  svg.save_as filename
end

#place(circuit) ⇒ Object



10
11
12
13
14
15
16
17
18
19
20
21
22
23
# File 'lib/rtl/placer.rb', line 10

def place circuit
  puts "placing '#{circuit.name}'"
  @circuit=circuit
  puts "creating p&r graph"
  nodes=gen_pnr_nodes(circuit)
  edges=gen_pnr_edges(circuit)
  graph=Graph.new(circuit.name,nodes,edges)
  graph.print_info
  drawer=Fdgd.new(graph)
  drawer.run 100
  puts "final placement".center(40,'=')
  graph.write_file "#{circuit.name}.json"
  gen_svg graph
end