Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

diode placement to solve antenna violations #93

Merged
merged 2 commits into from
Jun 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 5 additions & 2 deletions dffram.py
Original file line number Diff line number Diff line change
Expand Up @@ -191,6 +191,7 @@ def synthesis(build_folder, design, widths_supported, word_width_bytes, out_file
set vtop {design}
set SCL $env(LIBERTY)
read_liberty -lib -ignore_miss_dir -setattr blackbox $SCL
read_verilog ./platforms/sky130A/sky130_fd_sc_hd/diode_blackbox.v
read_verilog {bb_used}
{chparam}
hierarchy -check -top {design}
Expand Down Expand Up @@ -378,6 +379,7 @@ def pdngen(build_folder, width, height, in_file, out_file):
connect {{
{{ met1 met4 }}
}}
pins {{ met4 }}
}}
""".format(pitch=pitch, offset=offset)

Expand Down Expand Up @@ -624,11 +626,12 @@ def antenna_check(build_folder, def_file, out_file):
@click.option("--skip", default=None, help="Skip these comma;delimited;steps")
@click.option("-p", "--pdk_root", required=os.getenv("PDK_ROOT") is not None, default=os.getenv("PDK_ROOT"), help="path to sky130A pdk")
@click.option("-s", "--size", required=True, help="Size")
@click.option("-sfx", "--suffix", default="", help="suffix added to the end of the project folder name")
@click.option("-b", "--building-blocks", default="sky130A:ram", help="Format <pdk>:<name>: Name of the building blocks to use.")
@click.option("-cp", "--clk_period", default=3, type=float, help="clk period for sta")
@click.option("-v", "--variant", default=None, help="Use design variants (such as 1RW1R)")
@click.option("--drc/--no-drc", default=True, help="Perform DRC on latest generated def file. (Default: True)")
def flow(frm, to, only, pdk_root, skip, size, building_blocks, clk_period, variant, drc):
def flow(frm, to, only, pdk_root, skip, size, suffix, building_blocks, clk_period, variant, drc):
global bb_used, last_def, last_image

subprocess.run([
Expand Down Expand Up @@ -679,7 +682,7 @@ def flow(frm, to, only, pdk_root, skip, size, building_blocks, clk_period, varia
"width_bytes": word_width_bytes,
"variant": variant_string
})
build_folder = "./build/%s_SIZE%i" % (design, word_width)
build_folder = "./build/%s_SIZE%i%s" % (design, word_width, suffix)

ensure_dir(build_folder)

Expand Down
48 changes: 33 additions & 15 deletions placeram/data.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,8 @@ class Bit(Placeable):
def __init__(self, instances: List[Instance]):
self.store = None
self.obufs = None

self.diodes = []

raw_obufs: Dict[int, Instance] = {}

m = NS()
Expand All @@ -53,6 +54,8 @@ def __init__(self, instances: List[Instance]):
raw_obufs[port] = instance
elif sarv(m, "latch_match", re.search(r.latch, n)):
self.store = instance
elif sarv(m, "diode_match", re.search(r.diode, n)):
self.diode = instance
else:
raise DataError("Unknown element in %s: %s" % (type(self).__name__, n))

Expand All @@ -68,8 +71,9 @@ def place(self, row_list: List[Row], start_row: int = 0):
r = row_list[start_row]

r.place(self.store)
for obuf in self.obufs:
r.place(obuf)
r.place(self.diode)
for idx in range(len(self.obufs)):
r.place(self.obufs[idx])

return start_row

Expand All @@ -80,7 +84,7 @@ def __init__(self, instances: List[Instance]):
self.clkinv: Instance = None
self.bits: List[Bit] = None
self.selinvs: List[Instance] = None

raw_bits: Dict[int, List[Instance]] = {}
raw_selinvs: Dict[int, Instance] = {}

Expand Down Expand Up @@ -396,7 +400,7 @@ def lrplace(self, row_list: List[Row], start_row: int, addresses: int, common: L
column += chunks[i // 2]
target.append(column)
right = not right

final_rows = []

# Act 1. Place Left Vertical Elements
Expand Down Expand Up @@ -452,7 +456,7 @@ def __init__(self, instances: List[Instance]):
self.fbufenbufs: List[List[Instance]] = None
## Floatbufs are grouped further: there are a couple of floatbufs per tie cell.
self.ties: List[List[Instance]] = None
self.floatbufs: List[List[List[Instance]]] = None
self.floatbufs: List[List[List[Instance]]] = None

raw_enbufs: Dict[int, Instance] = {}

Expand All @@ -461,6 +465,7 @@ def __init__(self, instances: List[Instance]):

raw_dibufs: Dict[int, Instance] = {}
raw_dobufs: Dict[int, Dict[int, Instance]] = {}
raw_diodes_dobufs: Dict[int, Dict[int, Instance]] = {}

raw_webufs: Dict[int, Instance] = {}

Expand Down Expand Up @@ -520,6 +525,11 @@ def __init__(self, instances: List[Instance]):
i = int(m.dobuf_match[2])
raw_dobufs[port] = raw_dobufs.get(port) or {}
raw_dobufs[port][i] = instance
elif sarv(m, "diode_dobuf_match", re.search(r.diode_dobuf, n)):
port = int(m.diode_dobuf_match[1] or "0")
i = int(m.diode_dobuf_match[2])
raw_diodes_dobufs[port] = raw_diodes_dobufs.get(port) or {}
raw_diodes_dobufs[port][i] = instance
else:
raise DataError("Unknown element in %s: %s" % (type(self).__name__, n))

Expand All @@ -530,6 +540,7 @@ def __init__(self, instances: List[Instance]):
self.enbufs = d2a(raw_enbufs)
self.dibufs = d2a(raw_dibufs)
self.dobufs = d2a({k: d2a(v) for k, v in raw_dobufs.items()})
self.diodes_dobufs = d2a({k: d2a(v) for k, v in raw_diodes_dobufs.items()})

self.webufs = d2a(raw_webufs)
self.abufs = d2a({k: d2a(v) for k, v in raw_abufs.items()})
Expand Down Expand Up @@ -570,7 +581,6 @@ def place_horizontal_elements(start_row: int):

for slice in self.slices:
current_row = slice.place(row_list, current_row)

for i, port in enumerate(self.ties):
r = row_list[current_row]
for j, tie in enumerate(port):
Expand All @@ -579,14 +589,22 @@ def place_horizontal_elements(start_row: int):
r.place(floatbuf)
current_row += 1

for port in self.dobufs:
# for port in self.dobufs:
# r = row_list[current_row]
# for dobuf in port:
# r.place(dobuf)
# current_row += 1

for idx in range(len(self.dobufs)):
r = row_list[current_row]
for dobuf in port:
r.place(dobuf)
for sidx in range(len(self.dobufs[idx])):
r.place(self.dobufs[idx][sidx])
r.place(self.diodes_dobufs[idx][sidx])
current_row += 1


return current_row

return self.lrplace(
row_list=row_list,
start_row=start_row,
Expand Down Expand Up @@ -662,7 +680,7 @@ def __init__(self, instances: List[Instance], block_size: int):
self.webufs: List[Instance] = None

self.blocks: List[Union[Block, HigherLevelPlaceable]] = None

# These sets of buffers are duplicated once per read port,
# so the first access always picks the port.
self.decoder_ands: List[List[Instance]] = None
Expand Down Expand Up @@ -718,7 +736,7 @@ def __init__(self, instances: List[Instance], block_size: int):
else:
raise DataError("Unknown element in %s: %s" % (type(self).__name__, n))


self.dibufs = d2a(raw_dibufs)
self.webufs = d2a(raw_webufs)

Expand Down Expand Up @@ -751,7 +769,7 @@ def ra(n, a, **kwargs):
def place(self, row_list: List[Row], start_row: int = 0):
def symmetrically_placeable():
return self.word_count() > 128

current_row = start_row

def place_horizontal_elements(start_row: int):
Expand Down Expand Up @@ -824,4 +842,4 @@ def f(x):
return 32 * (4 ** math.ceil(math.log2(x / 128) / 2))
block_size = f(word_count)
hierarchy = HigherLevelPlaceable(instances, block_size)
return hierarchy
return hierarchy
4 changes: 3 additions & 1 deletion placeram/rx.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ Bit:
latch: "\\bLATCH\\b"
ff: "\\bFF\\b"
obuf: "\\bOBUF(\\d*)?\\b"
diode: "DIODE"
Byte:
bit: "\\BIT\\\\\\[(\\d+)\\\\\\]"
cg: "\\bCG\\b"
Expand All @@ -26,6 +27,7 @@ Block:
decoder_and: "\\bDEC(\\d*)\\.AND(\\d+)\\b"
dibuf: "\\bDIBUF\\\\\\[(\\d+)\\\\\\]"
dobuf: "\\bDo(\\d*)_FF\\\\\\[(\\d+)\\\\\\]"
diode_dobuf: "\\bDIODE_Do(\\d*)_FF\\\\\\[(\\d+)\\\\\\]"
webuf: "\\bWEBUF\\\\\\[(\\d+)\\\\\\]"
clkbuf: "\\bCLKBUF\\b"
abuf: "\\bA(\\d*)BUF\\\\\\[(\\d+)\\\\\\]"
Expand All @@ -46,4 +48,4 @@ HigherLevelPlaceable:
dibuf: "\\bDIBUF\\\\\\[(\\d+)\\\\\\]"
domux: "\\bDo(\\d*)MUX\\b"
webuf: "\\bWEBUF\\\\\\[(\\d+)\\\\\\]"
abuf: "\\bA(\\d*)BUF\\\\\\[(\\d+)\\\\\\]"
abuf: "\\bA(\\d*)BUF\\\\\\[(\\d+)\\\\\\]"
12 changes: 11 additions & 1 deletion platforms/sky130A/BB/ram/model.v
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,8 @@ module BYTE #( parameter USE_LATCH=1)(
sky130_fd_sc_hd__and2_1 CGAND( .A(SEL0), .B(WE0), .X(WE0_WIRE) );

for(i=0; i<8; i=i+1) begin : BIT
(* keep = "true" *)
sky130_fd_sc_hd__diode_2 DIODEi0 (.DIODE(Di0[i]));
if(USE_LATCH == 0)
sky130_fd_sc_hd__dfxtp_1 FF ( .D(Di0[i]), .Q(Q_WIRE[i]), .CLK(GCLK) );
else
Expand Down Expand Up @@ -173,6 +175,8 @@ module BYTE_1RW1R #( parameter USE_LATCH=1)(
sky130_fd_sc_hd__and2_1 CGAND( .A(SEL0), .B(WE0), .X(WE0_WIRE) );

for(i=0; i<8; i=i+1) begin : BIT
(* keep = "true" *)
sky130_fd_sc_hd__diode_2 DIODEi0 (.DIODE(Di0[i]));
if(USE_LATCH == 0)
sky130_fd_sc_hd__dfxtp_1 FF ( .D(Di0[i]), .Q(Q_WIRE[i]), .CLK(GCLK) );
else
Expand Down Expand Up @@ -360,7 +364,9 @@ module RAM32 #( parameter USE_LATCH=1,
end
endgenerate

sky130_fd_sc_hd__dfxtp_1 Do_FF[WSIZE*8-1:0] ( .D(Do0_pre), .Q(Do0), .CLK(CLK) );
(* keep = "true" *)
sky130_fd_sc_hd__diode_2 DIODE_Do_FF [WSIZE*8-1:0] (.DIODE(Do0_pre));
sky130_fd_sc_hd__dfxtp_1 Do_FF [WSIZE*8-1:0] ( .D(Do0_pre), .Q(Do0), .CLK(CLK) );

endmodule

Expand Down Expand Up @@ -437,6 +443,10 @@ module RAM32_1RW1R #( parameter USE_LATCH=1,
end
endgenerate

(* keep = "true" *)
sky130_fd_sc_hd__diode_2 DIODE_Do0_FF [WSIZE*8-1:0] (.DIODE(Do0_pre));
(* keep = "true" *)
sky130_fd_sc_hd__diode_2 DIODE_Do1_FF [WSIZE*8-1:0] (.DIODE(Do1_pre));
sky130_fd_sc_hd__dfxtp_1 Do0_FF[WSIZE*8-1:0] ( .D(Do0_pre), .Q(Do0), .CLK(CLK) );
sky130_fd_sc_hd__dfxtp_1 Do1_FF[WSIZE*8-1:0] ( .D(Do1_pre), .Q(Do1), .CLK(CLK) );

Expand Down
4 changes: 4 additions & 0 deletions platforms/sky130A/sky130_fd_sc_hd/diode_blackbox.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
(* blackbox *)
module sky130_fd_sc_hd__diode_2 (DIODE);
input DIODE;
endmodule