Skip to content

Commit

Permalink
Added UPF Support (#775)
Browse files Browse the repository at this point in the history
* Added UPF Support

* "test"

* Added fstrings & updated documentation & fixed problems

* See previous commit

---------

Co-authored-by: Derrick Qi <derrickqi2003@bwrcrdsl-1.eecs.berkeley.edu>
  • Loading branch information
derrickqi2003 and Derrick Qi committed Apr 5, 2023
1 parent 1247f2c commit 34d2866
Show file tree
Hide file tree
Showing 2 changed files with 56 additions and 27 deletions.
2 changes: 1 addition & 1 deletion hammer/config/defaults.yml
Original file line number Diff line number Diff line change
Expand Up @@ -294,7 +294,7 @@ vlsi.inputs:
# Specifies what kind/version/type of power specification to use
# Valid options:
# cpf - Use the common power format commonly used in Cadence tools
# upf - Use the universal power format, IEEE 1801-2015
# upf - Use the universal power format, IEEE 1801-2009
power_spec_contents: null # Optional: Contents of a power specification in the above type (str)

sram_parameters: [] # SRAM Parameters
Expand Down
81 changes: 55 additions & 26 deletions hammer/vlsi/hammer_vlsi_impl.py
Original file line number Diff line number Diff line change
Expand Up @@ -2059,11 +2059,51 @@ def sdf_file(self, value: Optional[str]) -> None:
### END Generated interface HammerTimingTool ###

class HasUPFSupport(HammerTool):
"""Mix-in trait with functions useful for tools with UPF style power
constraints"""
@property
def upf_power_specification(self) -> str:
raise NotImplementedError("Automatic generation of UPF power specifications is not supported yet.")
"""Mix-in trait with functions useful for tools with UPF style power constraints"""
@property
def upf_power_specification(self) -> str:
output = [] # type: List[str]
domain = "AO"
#Header
output.append('upf_version 2.0')
output.append(f'set_design_top {self.top_module}')
vdd = VoltageValue(self.get_setting("vlsi.inputs.supplies.VDD"))
#Create Single Power Domain
output.append(f'create_power_domain {domain} \\')
output.append(f'\t-elements {{.}}')
#Get Supply Nets
power_nets = self.get_all_power_nets()
ground_nets = self.get_all_ground_nets()
#Create Supply Ports
for pg_net in (power_nets+ground_nets):
if(pg_net.pin != None):
#Create Supply Nets
output.append(f'create_supply_net {pg_net.name} -domain {domain}')
output.append(f'create_supply_port {pg_net.name} -domain {domain} \\')
output.append(f'\t-direction in')
#Connect Supply Net
output.append(f'connect_supply_net {pg_net.name} -ports {pg_net.name}')
#Set Domain Supply Net
output.append(f'set_domain_supply_net {domain} \\')
output.append(f'\t-primary_power_net {power_nets[0].name} \\')
output.append(f'\t-primary_ground_net {ground_nets[0].name}')
#Add Port States
for p_net in power_nets:
if(p_net.pin != None):
output.append(f'add_port_state {p_net.name} \\')
output.append(f'\t-state {{default {vdd.value}}}')
for g_net in ground_nets:
if(g_net.pin != None):
output.append(f'add_port_state {g_net.name} \\')
output.append(f'\t-state {{default 0.0}}')
#Create Power State Table
output.append('create_pst pwr_state_table \\')
output.append(f'\t-supplies {{{" ".join(map(lambda x: x.name, power_nets))} {" ".join(map(lambda x: x.name, ground_nets))}}}')
#Add Power States
output.append(f'add_pst_state aon \\')
output.append(f'\t-pst {{pwr_state_table}} \\')
output.append(f'\t-state {{{" ".join(map(lambda x: "default", power_nets+ground_nets))}}}')
return "\n".join(output)


class HasCPFSupport(HammerTool):
Expand All @@ -2079,37 +2119,26 @@ def cpf_power_specification(self) -> str:
# Header
output.append("set_cpf_version 1.0e")
output.append("set_hierarchy_separator /")

output.append("set_design {t}".format(t=self.top_module))
# Define power and ground nets
output.append(f'set_design {self.top_module}')
# Define power and ground nets (HARD CODE)
power_nets = self.get_all_power_nets() # type: List[Supply]
ground_nets = self.get_all_ground_nets() # type: List[Supply]
ground_nets = self.get_all_ground_nets()# type: List[Supply]
vdd = VoltageValue(self.get_setting("vlsi.inputs.supplies.VDD")) # type: VoltageValue
output.append("create_power_nets -nets {{ {p} }} -voltage {v}".
format(p=" ".join(map(lambda x: x.name, power_nets)), v=vdd.value))
output.append("create_ground_nets -nets {{ {g} }}".
format(g=" ".join(map(lambda x: x.name, ground_nets))))

output.append(f'create_power_nets -nets {{ {" ".join(map(lambda x: x.name, power_nets))} }} -voltage {vdd.value}')
output.append(f'create_ground_nets -nets {{ {" ".join(map(lambda x: x.name, ground_nets))} }}')
# Define power domain and connections
output.append("create_power_domain -name {d} -default".format(d=domain))
output.append(f'create_power_domain -name {domain} -default')
# Assume primary power are first in list
output.append("update_power_domain -name {d} -primary_power_net {pp} -primary_ground_net {pg}".
format(d=domain, pp=power_nets[0].name, pg=ground_nets[0].name))
output.append(f'update_power_domain -name {domain} -primary_power_net {power_nets[0].name} -primary_ground_net {ground_nets[0].name}')
# Assuming that all power/ground nets correspond to pins
for pg_net in (power_nets+ground_nets):
if(pg_net.pin != None):
output.append("create_global_connection -domain {d} -net {n} -pins {p}".
format(d=domain, n=pg_net.name, p=pg_net.pin))

output.append(f'create_global_connection -domain {domain} -net {pg_net.name} -pins {pg_net.pin}')
# Create nominal operation condtion and power mode
output.append("create_nominal_condition -name {c} -voltage {v}".
format(c=condition, v=vdd.value))
output.append("create_power_mode -name {m} -default -domain_conditions {{{d}@{c}}}".
format(m=mode, d=domain, c=condition))

output.append(f'create_nominal_condition -name {condition} -voltage {vdd.value}')
output.append(f'create_power_mode -name {mode} -default -domain_conditions {{{domain}@{condition}}}')
# Footer
output.append("end_design")

return "\n".join(output)

class HasSDCSupport(HammerTool):
Expand Down

0 comments on commit 34d2866

Please sign in to comment.