diff --git a/example_cfgs/sky130.cfg b/example_cfgs/sky130.cfg index 717110a..2c53116 100644 --- a/example_cfgs/sky130.cfg +++ b/example_cfgs/sky130.cfg @@ -10,16 +10,19 @@ "metalPrefix": "met", # The pin width for signal pins. - "pinWidth_nm": 800, + "pinWidth_nm": 300, + + # The pin length for the signal pins. + "pinHeight_nm": 800, # The minimum pin pitch for signal pins (all pins will have a pitch that is a # multuple of this pitch. The first pin will be a multiple of this pitch from # the bottom edge of the macro too. - "pinPitch_nm": 1700, + "pinPitch_nm": 600, # Optional: snap the width and height of the sram to a multiple value. - "snapWidth_nm": 190, - "snapHeight_nm": 1400, + "snapWidth_nm": 460, + "snapHeight_nm": 2720, # Flips the pin orientations. Non-fliped assumes metal1 is vertical therefore # supply pins on metal4 will be horizontal and signal pins will also be on diff --git a/scripts/utils/class_memory.py b/scripts/utils/class_memory.py index 6d6a1bf..8887f15 100644 --- a/scripts/utils/class_memory.py +++ b/scripts/utils/class_memory.py @@ -61,6 +61,7 @@ def __init__( self, process, sram_data , output_dir = None, cacti_dir = None): self.tech_node_um = self.tech_node_nm / 1000.0 + print(f'Original {self.name} size = {self.width_um} x {self.height_um}') # Adjust to snap self.width_um = (math.ceil((self.width_um*1000.0)/self.process.snapWidth_nm)*self.process.snapWidth_nm)/1000.0 self.height_um = (math.ceil((self.height_um*1000.0)/self.process.snapHeight_nm)*self.process.snapHeight_nm)/1000.0 diff --git a/scripts/utils/class_process.py b/scripts/utils/class_process.py index 7f6f177..2fc6255 100644 --- a/scripts/utils/class_process.py +++ b/scripts/utils/class_process.py @@ -22,9 +22,11 @@ def __init__(self, json_data): self.snapWidth_nm = int(json_data['snapWidth_nm']) if 'snapWidth_nm' in json_data else 1 self.snapHeight_nm = int(json_data['snapHeight_nm']) if 'snapHeight_nm' in json_data else 1 self.flipPins = str(json_data['flipPins']) if 'flipPins' in json_data else 'false' + self.pinHeight_nm = int(json_data['pinHeight_nm']) if 'pinHeight_nm' in json_data else (self.pinWidth_nm) # Default to square pins # Converted values self.tech_um = self.tech_nm / 1000.0 self.pinWidth_um = self.pinWidth_nm / 1000.0 + self.pinHeight_um = self.pinHeight_nm / 1000.0 self.pinPitch_um = self.pinPitch_nm / 1000.0 diff --git a/scripts/utils/generate_lef.py b/scripts/utils/generate_lef.py index fe8db71..ff81b42 100644 --- a/scripts/utils/generate_lef.py +++ b/scripts/utils/generate_lef.py @@ -24,6 +24,7 @@ def generate_lef( mem ): # Process parameters min_pin_width = mem.process.pinWidth_um + pin_height = mem.process.pinHeight_um min_pin_pitch = mem.process.pinPitch_um metalPrefix = mem.process.metalPrefix flip = mem.process.flipPins.lower() == 'true' @@ -40,9 +41,11 @@ def generate_lef( mem ): number_of_tracks_available = math.floor((h - 2*y_offset) / min_pin_pitch) number_of_spare_tracks = number_of_tracks_available - number_of_pins + print(f'Final {name} size = {w} x {h}') + print(f'num pins: {number_of_pins}, available tracks: {number_of_tracks_available}') if number_of_spare_tracks < 0: - print("Error: not enough tracks (num pins: %d, available tracks: %d)." % (number_of_pins, number_of_tracks_available)) - sys.exit(1) + print("ERROR: not enough tracks!") + sys.exit(1) track_count = 1 while number_of_spare_tracks > 0: @@ -183,39 +186,39 @@ def generate_lef( mem ): if flip: # Rect from top to bottom, just right of pins to right edge - fid.write(' RECT %.3f 0 %.3f %.3f ;\n' % (min_pin_width,w,h)) + fid.write(' RECT %.3f 0 %.3f %.3f ;\n' % (pin_height,w,h)) # Walk through same calculation as pins and draw from bottom of the # current pin to the top of last pin (start with bottom edge) prev_y = 0 y_step = y_offset for i in range(int(bits)) : - fid.write(' RECT 0 %.3f %.3f %.3f ;\n' % (prev_y,min_pin_width,y_step-min_pin_width/2)) + fid.write(' RECT 0 %.3f %.3f %.3f ;\n' % (prev_y,pin_height,y_step-min_pin_width/2)) prev_y = y_step+min_pin_width/2 y_step += pin_pitch y_step += group_pitch-pin_pitch for i in range(int(bits)) : - fid.write(' RECT 0 %.3f %.3f %.3f ;\n' % (prev_y,min_pin_width,y_step-min_pin_width/2)) + fid.write(' RECT 0 %.3f %.3f %.3f ;\n' % (prev_y,pin_height,y_step-min_pin_width/2)) prev_y = y_step+min_pin_width/2 y_step += pin_pitch y_step += group_pitch-pin_pitch for i in range(int(bits)) : - fid.write(' RECT 0 %.3f %.3f %.3f ;\n' % (prev_y,min_pin_width,y_step-min_pin_width/2)) + fid.write(' RECT 0 %.3f %.3f %.3f ;\n' % (prev_y,pin_height,y_step-min_pin_width/2)) prev_y = y_step+min_pin_width/2 y_step += pin_pitch y_step += group_pitch-pin_pitch for i in range(int(addr_width)) : - fid.write(' RECT 0 %.3f %.3f %.3f ;\n' % (prev_y,min_pin_width,y_step-min_pin_width/2)) + fid.write(' RECT 0 %.3f %.3f %.3f ;\n' % (prev_y,pin_height,y_step-min_pin_width/2)) prev_y = y_step+min_pin_width/2 y_step += pin_pitch y_step += group_pitch-pin_pitch for i in range(3): - fid.write(' RECT 0 %.3f %.3f %.3f ;\n' % (prev_y,min_pin_width,y_step-min_pin_width/2)) + fid.write(' RECT 0 %.3f %.3f %.3f ;\n' % (prev_y,pin_height,y_step-min_pin_width/2)) prev_y = y_step+min_pin_width/2 y_step += pin_pitch # Final shapre from top of last pin to top edge - fid.write(' RECT 0 %.3f %.3f %.3f ;\n' % (prev_y,min_pin_width,h)) + fid.write(' RECT 0 %.3f %.3f %.3f ;\n' % (prev_y,pin_height,h)) # Not flipped therefore no pins on M3 (Full rect) else: @@ -318,7 +321,8 @@ def lef_add_pin( fid, mem, pin_name, is_input, y, pitch ): layer = mem.process.metalPrefix + ('3' if mem.process.flipPins.lower() == 'true' else '4') pw = mem.process.pinWidth_um - hpw = (mem.process.pinWidth_um/2.0) ;# half pin width + hpw = (mem.process.pinWidth_um/2.0) # half pin width + ph = mem.process.pinHeight_um fid.write(' PIN %s\n' % pin_name) fid.write(' DIRECTION %s ;\n' % ('INPUT' if is_input else 'OUTPUT')) @@ -326,7 +330,7 @@ def lef_add_pin( fid, mem, pin_name, is_input, y, pitch ): fid.write(' SHAPE ABUTMENT ;\n') fid.write(' PORT\n') fid.write(' LAYER %s ;\n' % layer) - fid.write(' RECT %.3f %.3f %.3f %.3f ;\n' % (0, y-hpw, pw, y+hpw)) + fid.write(' RECT %.3f %.3f %.3f %.3f ;\n' % (0, y-hpw, ph, y+hpw)) fid.write(' END\n') fid.write(' END %s\n' % pin_name)