Module: VerilogGen
- Defined in:
- lib/verilog_gen/proxy.rb,
lib/verilog_gen/pin.rb,
lib/verilog_gen/port.rb,
lib/verilog_gen/hookup.rb,
lib/verilog_gen/version.rb,
lib/verilog_gen/hdl_module.rb
Overview
Wrapper routines to import design into ruby.
Defined Under Namespace
Constant Summary collapse
- VERSION =
"0.0.2"
- @@verilog_leaf_created =
Return the created class for subsequent access.
{}
Class Method Summary collapse
-
.add_new_connect_port(klass, pin_name, port_lst) ⇒ Object
Adds a connect port to the hdl module class.
-
.create_connect_ports(klass) ⇒ Fixnum
Create ports to provide connectivity to the child instances.
-
.create_missing_pins(instance) ⇒ Fixnum
Create pins for unconnected ports in current instance.
-
.create_missing_pins_depth_first(instance) ⇒ nil
Create missing pins for all children below the instance.
-
.get_child_pins_connectivity(klass) ⇒ Hash
Create connectivity map for children of a hdl module.
-
.hookup(top_level_class) ⇒ Object
Connect child instances and create hookup ports.
-
.leaf(klass, params = {}) ⇒ Object
Invoke vscan to create the leaf proxy.
-
.super_port_width(port_lst) ⇒ Array
Find the super width from a list of ports.
-
.unconnected_input_ports?(port_lst) ⇒ Boolean
Check if all the ports in the list are inputs.
-
.unconnected_output_ports?(port_lst) ⇒ Boolean
Check if all the ports in the list are outputs.
Class Method Details
.add_new_connect_port(klass, pin_name, port_lst) ⇒ Object
The name of the connect port is the name of the pin and the width of the port is the super width.
Adds a connect port to the hdl module class.
51 52 53 54 55 |
# File 'lib/verilog_gen/hookup.rb', line 51 def self.add_new_connect_port(klass, pin_name, port_lst) lhs, rhs = super_port_width(port_lst) p = port_lst[0].create_connect_port(pin_name, lhs, rhs) klass.ports[pin_name] = p end |
.create_connect_ports(klass) ⇒ Fixnum
An input port is created if the children pins are inputs. A output port is created if the children pins are output. If mixture of input and output pins, then no ports are created. The width of the port is the superset of the width.
Create ports to provide connectivity to the child instances.
121 122 123 124 125 126 127 128 129 130 131 132 133 134 |
# File 'lib/verilog_gen/hookup.rb', line 121 def self.create_connect_ports(klass) num_connect_ports = 0 pin_connections = get_child_pins_connectivity(klass) pin_connections.each do |pin_name, port_lst| if unconnected_input_ports?(port_lst) add_new_connect_port(klass, pin_name, port_lst) num_connect_ports += 1 elsif unconnected_output_ports?(port_lst) add_new_connect_port(klass, pin_name, port_lst) num_connect_ports += 1 end end num_connect_ports end |
.create_missing_pins(instance) ⇒ Fixnum
Ports with existing pins are skippped.
Create pins for unconnected ports in current instance.
61 62 63 64 65 66 67 68 69 70 |
# File 'lib/verilog_gen/hookup.rb', line 61 def self.create_missing_pins(instance) num_pins_created = 0 instance.class.ports.each do |port_name, port| unless instance.pins.key? port_name instance.pins[port_name] = Pin.new(port) num_pins_created += 1 end end num_pins_created end |
.create_missing_pins_depth_first(instance) ⇒ nil
Idempotent since port that have pins are skipped.
Create missing pins for all children below the instance. Use depth first to build all the leaf and then the rest of the modules.
78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 |
# File 'lib/verilog_gen/hookup.rb', line 78 def self.create_missing_pins_depth_first(instance) if instance.class.proxy # Leaf do not change the ports. hence we don't need to do it again. # But it is harmless if all ports are already connected. create_missing_pins instance else instance.class.child_instances.each do |child_name, child| create_missing_pins_depth_first child end # If new pins are created then we would need to create the connect ports # in the current class. num_new_ports = create_connect_ports(instance.class) # Run custom user connect instance.class.connect # If we added new ports to the class then all instantiaton must get new pins. create_missing_pins instance if num_new_ports > 0 end end |
.get_child_pins_connectivity(klass) ⇒ Hash
Create connectivity map for children of a hdl module.
103 104 105 106 107 108 109 110 111 |
# File 'lib/verilog_gen/hookup.rb', line 103 def self.get_child_pins_connectivity(klass) pin_connections = Hash.new {|hash, key| hash[key] = Array.new } klass.child_instances.each do |child_name, child| child.pins.each do |port_name, pin| pin_connections[pin.name].push pin.port end end pin_connections end |
.hookup(top_level_class) ⇒ Object
Start with each child instance.
Connect child instances and create hookup ports.
141 142 143 144 145 146 147 148 149 150 151 |
# File 'lib/verilog_gen/hookup.rb', line 141 def self.hookup(top_level_class) top_level_class.child_instances.each do |instance_name, instance| create_missing_pins_depth_first(instance) end # Run custom user connect top_level_class.connect # Create the primary connect ports create_connect_ports(top_level_class) end |
.leaf(klass, params = {}) ⇒ Object
Invoke vscan to create the leaf proxy. Once a class is created then subsequent access will return prev value.
14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
# File 'lib/verilog_gen/proxy.rb', line 14 def self.leaf(klass, params = {}) = { parameter: "", file_name: klass.snakecase + ".v" } params.each do |key, value| raise ArgumentError, "invalid valid value of leaf '#{key}'" \ unless .key? key [key] = params[key] end key = klass + [:parameter] unless @@verilog_leaf_created.key?(key) puts "Running vscan #{[:parameter]} -class #{klass} #{[:file_name]}" output = `vscan #{[:parameter]} -class #{klass} \ #{[:file_name]}` eval output, binding, __FILE__, __LINE__ @@verilog_leaf_created[key] = Object.const_get("VerilogGen::#{klass}") end @@verilog_leaf_created[key] end |
.super_port_width(port_lst) ⇒ Array
Find the super width from a list of ports. @note:
Assumes that all ports in the list are of same endiannes..
FIXME: For this it looks at the port in the middle.
Should scan all the ports to detect it.
32 33 34 35 36 37 38 39 40 41 42 43 44 45 |
# File 'lib/verilog_gen/hookup.rb', line 32 def self.super_port_width(port_lst) sample_port = port_lst[port_lst.size/2] lhs_values = [] rhs_values = [] port_lst.each do |port| lhs_values << port.lhs rhs_values << port.rhs end if sample_port.lhs > sample_port.rhs return lhs_values.max, rhs_values.min else return lhs_values.min, rhs_values.max end end |
.unconnected_input_ports?(port_lst) ⇒ Boolean
Check if all the ports in the list are inputs.
6 7 8 9 10 11 12 |
# File 'lib/verilog_gen/hookup.rb', line 6 def self.unconnected_input_ports?(port_lst) return false if port_lst.empty? port_lst.each do |port| return false unless port.direction == "input" end return true end |
.unconnected_output_ports?(port_lst) ⇒ Boolean
Check if all the ports in the list are outputs.
17 18 19 20 21 22 23 |
# File 'lib/verilog_gen/hookup.rb', line 17 def self.unconnected_output_ports?(port_lst) return false if port_lst.empty? port_lst.each do |port| return false unless port.direction == "output" end return true end |