Move last few modules to base dir

This commit is contained in:
Matt Guthaus
2018-02-09 10:29:37 -08:00
parent 7c83ef3f04
commit 84c798d9e4
3 changed files with 0 additions and 0 deletions
+115
View File
@@ -0,0 +1,115 @@
import gdsMill
import tech
import globals
import math
import debug
import datetime
from collections import defaultdict
class lef:
"""
SRAM LEF Class open GDS file, read pins information, obstruction
and write them to LEF file
"""
def __init__(self,layers):
# LEF db units per micron
self.lef_units = 1000
# These are the layers of the obstructions
self.lef_layers = layers
def lef_write(self, lef_name):
"""Write the entire lef of the object to the file."""
debug.info(3, "Writing to {0}".format(lef_name))
self.indent = "" # To maintain the indent level easily
self.lef = open(lef_name,"w")
self.lef_write_header()
for pin in self.pins:
self.lef_write_pin(pin)
self.lef_write_obstructions()
self.lef_write_footer()
self.lef.close()
def lef_write_header(self):
""" Header of LEF file """
self.lef.write("VERSION 5.4 ;\n")
self.lef.write("NAMESCASESENSITIVE ON ;\n")
self.lef.write("BUSBITCHARS \"[]\" ;\n")
self.lef.write("DIVIDERCHAR \"/\" ;\n")
self.lef.write("UNITS\n")
self.lef.write(" DATABASE MICRONS {0} ;\n".format(self.lef_units))
self.lef.write("END UNITS\n")
self.lef.write("SITE MacroSite\n")
self.indent += " "
self.lef.write("{0}CLASS Core ;\n".format(self.indent))
self.lef.write("{0}SIZE {1} by {2} ;\n".format(self.indent,
self.lef_units*self.width,
self.lef_units*self.height))
self.indent = self.indent[:-3]
self.lef.write("END MacroSite\n")
self.lef.write("{0}MACRO {1}\n".format(self.indent,self.name))
self.indent += " "
self.lef.write("{0}CLASS BLOCK ;\n".format(self.indent))
self.lef.write("{0}SIZE {1} BY {2} ;\n" .format(self.indent,
self.lef_units*self.width,
self.lef_units*self.height))
self.lef.write("{0}SYMMETRY X Y R90 ;\n".format(self.indent))
self.lef.write("{0}SITE MacroSite ;\n".format(self.indent))
def lef_write_footer(self):
self.lef.write("{0}END {1}\n".format(self.indent,self.name))
self.indent = self.indent[:-3]
self.lef.write("END LIBRARY\n")
def lef_write_pin(self, name):
pin_dir = self.get_pin_dir(name)
pin_type = self.get_pin_type(name)
self.lef.write("{0}PIN {1}\n".format(self.indent,name))
self.indent += " "
self.lef.write("{0}DIRECTION {1} ;\n".format(self.indent,pin_dir))
if pin_type in ["POWER","GROUND"]:
self.lef.write("{0}USE {1} ; \n".format(self.indent,pin_type))
self.lef.write("{0}SHAPE ABUTMENT ; \n".format(self.indent))
self.lef.write("{0}PORT\n".format(self.indent))
self.indent += " "
# We could sort these together to minimize different layer sections, but meh.
pin_list = self.get_pins(name)
for pin in pin_list:
self.lef.write("{0}LAYER {1} ;\n".format(self.indent,pin.layer))
self.lef_write_rect(pin.rect)
# End the PORT
self.indent = self.indent[:-3]
self.lef.write("{0}END\n".format(self.indent))
# End the PIN
self.indent = self.indent[:-3]
self.lef.write("{0}END {1}\n".format(self.indent,name))
def lef_write_obstructions(self):
""" Write all the obstructions on each layer """
self.lef.write("{0}OBS\n".format(self.indent))
for layer in self.lef_layers:
self.lef.write("{0}LAYER {1} ;\n".format(self.indent,layer))
self.indent += " "
blockages = self.get_blockages(layer,True)
for b in blockages:
self.lef_write_rect(b)
self.indent = self.indent[:-3]
self.lef.write("{0}END\n".format(self.indent))
def lef_write_rect(self, rect):
""" Write a LEF rectangle """
self.lef.write("{0}RECT ".format(self.indent))
for item in rect:
self.lef.write(" {0} {1}".format(self.lef_units*item[0], self.lef_units*item[1]))
self.lef.write(" ;\n")
+120
View File
@@ -0,0 +1,120 @@
from tech import drc
import debug
from contact import contact
from itertools import tee
from vector import vector
from vector3d import vector3d
class route():
"""
Object route (used by the router module)
Add a route of minimium metal width between a set of points.
The wire must be completely rectilinear and the
z-dimension of the points refers to the layers (plus via)
The points are the center of the wire.
This can have non-preferred direction routing.
"""
def __init__(self, obj, layer_stack, path):
name = "route_{0}".format(route.unique_route_id)
route.unique_route_id += 1
design.design.__init__(self, name)
debug.info(3, "create route obj {0}".format(name))
self.obj = obj
self.layer_stack = layer_stack
self.path = path
self.setup_layers()
self.create_wires()
def setup_layers(self):
(horiz_layer, via_layer, vert_layer) = self.layer_stack
self.via_layer_name = via_layer
self.vert_layer_name = vert_layer
self.vert_layer_width = drc["minwidth_{0}".format(vert_layer)]
self.horiz_layer_name = horiz_layer
self.horiz_layer_width = drc["minwidth_{0}".format(horiz_layer)]
# offset this by 1/2 the via size
self.c=contact(self.layer_stack, (1, 1))
def create_wires(self):
"""
Add the wire segments of the route.
"""
def pairwise(iterable):
"s -> (s0,s1), (s1,s2), (s2, s3), ..."
a, b = tee(iterable)
next(b, None)
return zip(a, b)
plist = pairwise(self.path)
for p0,p1 in plist:
if p0.z != p1.z: # via
# offset if not rotated
#via_offset = vector(p0.x+0.5*self.c.width,p0.y+0.5*self.c.height)
# offset if rotated
via_offset = vector(p0.x+0.5*self.c.height,p0.y-0.5*self.c.width)
self.obj.add_via(self.layer_stack,via_offset,rotate=90)
elif p0.x != p1.x and p0.y != p1.y: # diagonal!
debug.error("Non-changing direction!")
else:
# this will draw an extra corner at the end but that is ok
self.draw_corner_wire(p1)
# draw the point to point wire
self.draw_wire(p0,p1)
def draw_wire(self, p0, p1):
"""
This draws a straight wire with layer_minwidth
"""
layer_name = self.layer_stack[2*p0.z]
layer_width = drc["minwidth_{0}".format(layer_name)]
# always route left to right or bottom to top
if p0.z != p1.z:
self.error("Adding a via as a wire!")
elif p0.x < p1.x or p0.y < p1.y:
start = p0
end = p1
elif p0.x > p1.x or p0.y > p1.y:
start = p1
end = p0
else:
debug.error("Neither horizontal or vertical wire.")
# now determine the route geometry and offset
if start.x != end.x: # horizontal
offset = start + vector3d(0,-0.5*layer_width,0)
height = layer_width
width = end.x - start.x
elif start.y != end.y: # vertical
offset = start + vector3d(-0.5*layer_width,0,0)
height = end.y - start.y
width = layer_width
deisgn.add_rect(layer=layer_name,
offset=offset,
width=width,
height=height)
def draw_corner_wire(self, p0):
""" This function adds the corner squares since the center
line convention only draws to the center of the corner."""
layer_name = self.layer_stack[2*p0.z]
layer_width = drc["minwidth_{0}".format(layer_name)]
offset = vector(p0.x-0.5*layer_width,p0.y-0.5*layer_width)
self.obj.add_rect(layer=layer_name,
offset=offset,
width=layer_width,
height=layer_width)
+60
View File
@@ -0,0 +1,60 @@
import debug
class verilog:
""" Create a behavioral Verilog file for simulation."""
def verilog_write(self,verilog_name):
""" Write a behavioral Verilog model. """
self.vf = open(verilog_name, "w")
self.vf.write("// OpenRAM SRAM model\n")
self.vf.write("// Words: {0}\n".format(self.num_words))
self.vf.write("// Word size: {0}\n\n".format(self.word_size))
self.vf.write("module {0}(DATA,ADDR,CSb,WEb,OEb,clk);\n".format(self.name))
self.vf.write("\n")
self.vf.write(" parameter DATA_WIDTH = {0} ;\n".format(self.word_size))
self.vf.write(" parameter ADDR_WIDTH = {0} ;\n".format(self.addr_size))
self.vf.write(" parameter RAM_DEPTH = 1 << ADDR_WIDTH;\n")
self.vf.write(" parameter DELAY = 3 ;\n")
self.vf.write("\n")
self.vf.write(" inout [DATA_WIDTH-1:0] DATA;\n")
self.vf.write(" input [ADDR_WIDTH-1:0] ADDR;\n")
self.vf.write(" input CSb; // active low chip select\n")
self.vf.write(" input WEb; // active low write control\n")
self.vf.write(" input OEb; // active output enable\n")
self.vf.write(" input clk; // clock\n")
self.vf.write("\n")
self.vf.write(" reg [DATA_WIDTH-1:0] data_out ;\n")
self.vf.write(" reg [DATA_WIDTH-1:0] mem [0:RAM_DEPTH-1];\n")
self.vf.write("\n")
self.vf.write(" // Tri-State Buffer control\n")
self.vf.write(" // output : When WEb = 1, oeb = 0, csb = 0\n")
self.vf.write(" assign DATA = (!CSb && !OEb && WEb) ? data_out : {0}'bz;\n".format(self.word_size))
self.vf.write("\n")
self.vf.write(" // Memory Write Block\n")
self.vf.write(" // Write Operation : When WEb = 0, CSb = 0\n")
self.vf.write(" always @ (posedge clk)\n")
self.vf.write(" begin : MEM_WRITE\n")
self.vf.write(" if ( !CSb && !WEb ) begin\n")
self.vf.write(" mem[ADDR] = DATA;\n")
self.vf.write(" $display($time,\" Writing %m ABUS=%b DATA=%b\",ADDR,DATA);\n")
self.vf.write(" end\n")
self.vf.write(" end\n\n")
self.vf.write("\n")
self.vf.write(" // Memory Read Block\n")
self.vf.write(" // Read Operation : When WEb = 1, CSb = 0\n")
self.vf.write(" always @ (posedge clk)\n")
self.vf.write(" begin : MEM_READ\n")
self.vf.write(" if (!CSb && WEb) begin\n")
self.vf.write(" data_out <= #(DELAY) mem[ADDR];\n")
self.vf.write(" $display($time,\" Reading %m ABUS=%b DATA=%b\",ADDR,mem[ADDR]);\n")
self.vf.write(" end\n")
self.vf.write(" end\n")
self.vf.write("\n")
self.vf.write("endmodule\n")
self.vf.close()