From 7a6140fd78cad7304fd0d01f4e026ae908d9eb20 Mon Sep 17 00:00:00 2001 From: Donn Date: Wed, 9 Jun 2021 19:16:17 +0200 Subject: [PATCH] Improved support for >128 sizes (#78) * Initial adjustments to hierarchy creation * Verified legacy as working with new variable names * Fix for experimental >128 --- dffram.py | 2 ++ placeram/cli.py | 29 +++--------------- placeram/data.py | 35 +++++++++++++++------- placeram/rx.yml | 5 +++- platforms/sky130A/BB/ram/legacy/config.yml | 1 + platforms/sky130A/BB/ram/legacy/model.v | 26 ++++++++-------- platforms/sky130A/BB/ram/model.v | 24 +++++++-------- 7 files changed, 61 insertions(+), 61 deletions(-) diff --git a/dffram.py b/dffram.py index 095bf9b..ae09e3c 100755 --- a/dffram.py +++ b/dffram.py @@ -858,6 +858,8 @@ def main(): flow() except subprocess.CalledProcessError as e: print("A step has failed:", e) + print("Invokable:") + print(' '.join(e.cmd)) exit(69) except Exception: print("An unhandled exception has occurred.", traceback.format_exc()) diff --git a/placeram/cli.py b/placeram/cli.py index 7807b68..160910f 100644 --- a/placeram/cli.py +++ b/placeram/cli.py @@ -38,11 +38,11 @@ print("You need to install pyyaml: python3 -m pip install pyyank") exit(78) -from .util import eprint -from .placeable import override_regex_dict -from .data import Block, Slice, Word, HigherLevelPlaceable +from . import data from .row import Row +from .util import eprint from .reg_data import DFFRF +from .placeable import override_regex_dict import os import re @@ -109,28 +109,7 @@ def create_fill(name, sites=1): if regFile: self.hierarchy = DFFRF(self.instances) else: - includes = {32:r"\bBANK_B(\d+)\b", - 128: r"\bBANK128_B(\d+)\b", - 512: r"\bBANK512_B(\d+)\b"} - - if word_count == 1: - self.hierarchy = Word(self.instances) - elif word_count == 8: - self.hierarchy = Slice(self.instances) - elif word_count == 32: - self.hierarchy = Block(self.instances) - elif word_count == 128: - self.hierarchy = \ - HigherLevelPlaceable(includes[32], self.instances) - elif word_count == 512: - self.hierarchy = \ - HigherLevelPlaceable(includes[128], self.instances) - elif word_count == 1024: - self.hierarchy = \ - HigherLevelPlaceable(includes[512], self.instances) - elif word_count == 2048: - self.hierarchy = \ - HigherLevelPlaceable(includes[512], self.instances) + self.hierarchy = data.create_hierarchy(self.instances, word_count) def represent(self, file): self.hierarchy.represent(file=file) diff --git a/placeram/data.py b/placeram/data.py index ea51408..770a6c9 100644 --- a/placeram/data.py +++ b/placeram/data.py @@ -628,7 +628,7 @@ def place(self, row_list: List[Row], start_row: int = 0): class HigherLevelPlaceable(Placeable): # TODO: Dual ported higher level placeables. - def __init__(self, inner_re: RegExp, instances: List[Instance]): + def __init__(self, instances: List[Instance], block_size: int): self.clkbuf: Instance = None self.enbuf: Instance = None self.blocks: List[Union[Block, HigherLevelPlaceable]] = None @@ -646,14 +646,12 @@ def __init__(self, inner_re: RegExp, instances: List[Instance]): raw_domux: List[Instance] = [] - r_block = inner_re - m = NS() r = self.regexes() for instance in instances: n = instance.getName() - if sarv(m, "block_match", re.search(r_block, n)): + if sarv(m, "block_match", re.search(getattr(r, str(block_size)), n)): i = int(m.block_match[1]) raw_blocks[i] = raw_blocks.get(i) or [] raw_blocks[i].append(instance) @@ -677,7 +675,9 @@ def __init__(self, inner_re: RegExp, instances: List[Instance]): raw_domux.append(instance) else: raise DataError("Unknown element in %s: %s" % (type(self).__name__, n)) - self.blocks = d2a({k: constructor[inner_re](v) for k, v in + + + self.blocks = d2a({k: create_hierarchy(v, block_size) for k, v in raw_blocks.items()}) self.decoder_ands = d2a(raw_decoder_ands) self.dibufs = d2a(raw_dibufs) @@ -772,8 +772,23 @@ def symmetrically_placeable(obj): def word_count(self): return len(self.blocks) * (self.blocks[0].word_count()) -constructor = { - r"\bBANK_B(\d+)\b": Block, - r"\bBANK128_B(\d+)\b": partial(HigherLevelPlaceable, r"\bBANK_B(\d+)\b"), - r"\bBANK512_B(\d+)\b": partial(HigherLevelPlaceable, r"\bBANK128_B(\d+)\b") -} +def create_hierarchy(instances, word_count): + hierarchy = None + if word_count == 1: + hierarchy = Word(instances) + elif word_count == 8: + hierarchy = Slice(instances) + elif word_count == 32: + hierarchy = Block(instances) + else: + """ + I derived this equation based on the structure we have. + Feel free to independently verify it. + + Valid for 128 <= 𝒙 <= 2048: + + 𝒚 = 32 * 4 ^ ⌈log2(𝒙 / 128) / 2⌉ + """ + block_size = 32 * (4 ** math.ceil(math.log2(word_count / 128) / 2)) + hierarchy = HigherLevelPlaceable(instances, block_size) + return hierarchy \ No newline at end of file diff --git a/placeram/rx.yml b/placeram/rx.yml index b3f475b..16599c2 100644 --- a/placeram/rx.yml +++ b/placeram/rx.yml @@ -35,8 +35,11 @@ Block: floatbuf: "\\bBYTE\\\\\\[(\\d+)\\\\\\]\\.FLOATBUF(\\d*)\\\\\\[(\\d+)\\\\\\]" Mux: selbuf: "\\bSEL(\\d*)?BUF\\\\\\[(\\d+)\\\\\\]" - mux: "\\bMUX(\\d+)\\\\\\[(\\d+)\\\\\\]" + mux: "\\bM\\\\\\[(\\d+)\\\\\\]\\.MUX\\\\\\[(\\d+)\\\\\\]" HigherLevelPlaceable: + "32": "\\bBLOCK\\\\\\[(\\d+)\\\\\\]" + "128": "\\bBANK128\\\\\\[(\\d+)\\\\\\]" + "512": "\\bBANK512\\\\\\[(\\d+)\\\\\\]" clkbuf: "\\bCLKBUF\\b" enbuf: "\\bENBUF\\b" decoder_and: "\\bDEC\\.AND(\\d+)\\b" diff --git a/platforms/sky130A/BB/ram/legacy/config.yml b/platforms/sky130A/BB/ram/legacy/config.yml index cfbf076..e5c8a2f 100644 --- a/platforms/sky130A/BB/ram/legacy/config.yml +++ b/platforms/sky130A/BB/ram/legacy/config.yml @@ -6,4 +6,5 @@ variants: - null rx_overrides: Block.floatbuf: "\\bFLOATBUF_B(\\d+)\\\\(\\d*)\\[(\\d+)\\\\]" + Mux.mux: "\\bMUX(\\d+)\\\\\\[(\\d+)\\\\\\]" Word.byte: "\\bB(\\d+)\\b" \ No newline at end of file diff --git a/platforms/sky130A/BB/ram/legacy/model.v b/platforms/sky130A/BB/ram/legacy/model.v index 32d31d4..64c2fd6 100644 --- a/platforms/sky130A/BB/ram/legacy/model.v +++ b/platforms/sky130A/BB/ram/legacy/model.v @@ -239,7 +239,7 @@ module RAM32 #(parameter USE_LATCH=1) ( generate genvar i; for (i=0; i< 4; i=i+1) begin : SLICE - RAM8 #(.USE_LATCH(USE_LATCH)) RAM8x32 (.CLK(CLK_buf), .WE(WE_buf),.EN(SEL[i]), .Di(Di_buf), .Do(Do_pre), .A(A_buf[2:0]) ); + RAM8 #(.USE_LATCH(USE_LATCH)) RAM8 (.CLK(CLK_buf), .WE(WE_buf),.EN(SEL[i]), .Di(Di_buf), .Do(Do_pre), .A(A_buf[2:0]) ); end endgenerate @@ -289,10 +289,10 @@ module RAM128 #(parameter USE_LATCH=1) ( DEC2x4 DEC (.EN(EN_buf), .A(A_buf[6:5]), .SEL(SEL)); // 32x32 RAM Banks - RAM32 #(.USE_LATCH(USE_LATCH)) BANK_B0 (.CLK(CLK_buf), .EN(SEL[0]), .WE(WE_buf), .Di(Di_buf), .Do(Do_0), .A(A_buf[4:0]) ); - RAM32 #(.USE_LATCH(USE_LATCH)) BANK_B1 (.CLK(CLK_buf), .EN(SEL[1]), .WE(WE_buf), .Di(Di_buf), .Do(Do_1), .A(A_buf[4:0]) ); - RAM32 #(.USE_LATCH(USE_LATCH)) BANK_B2 (.CLK(CLK_buf), .EN(SEL[2]), .WE(WE_buf), .Di(Di_buf), .Do(Do_2), .A(A_buf[4:0]) ); - RAM32 #(.USE_LATCH(USE_LATCH)) BANK_B3 (.CLK(CLK_buf), .EN(SEL[3]), .WE(WE_buf), .Di(Di_buf), .Do(Do_3), .A(A_buf[4:0]) ); + RAM32 #(.USE_LATCH(USE_LATCH)) \BLOCK[0].RAM32 (.CLK(CLK_buf), .EN(SEL[0]), .WE(WE_buf), .Di(Di_buf), .Do(Do_0), .A(A_buf[4:0]) ); + RAM32 #(.USE_LATCH(USE_LATCH)) \BLOCK[1].RAM32 (.CLK(CLK_buf), .EN(SEL[1]), .WE(WE_buf), .Di(Di_buf), .Do(Do_1), .A(A_buf[4:0]) ); + RAM32 #(.USE_LATCH(USE_LATCH)) \BLOCK[2].RAM32 (.CLK(CLK_buf), .EN(SEL[2]), .WE(WE_buf), .Di(Di_buf), .Do(Do_2), .A(A_buf[4:0]) ); + RAM32 #(.USE_LATCH(USE_LATCH)) \BLOCK[3].RAM32 (.CLK(CLK_buf), .EN(SEL[3]), .WE(WE_buf), .Di(Di_buf), .Do(Do_3), .A(A_buf[4:0]) ); // Output MUX MUX4x1_32 DoMUX ( .A0(Do_0), .A1(Do_1), .A2(Do_2), .A3(Do_3), .S(A_buf[6:5]), .X(Do) ); @@ -328,10 +328,10 @@ module RAM512 #(parameter USE_LATCH=1) ( DEC2x4 DEC (.EN(EN_buf), .A(A_buf[8:7]), .SEL(SEL)); // 128x32 RAM Banks - RAM128 #(.USE_LATCH(USE_LATCH)) BANK128_B0 (.CLK(CLK_buf), .EN(SEL[0]), .WE(WE_buf), .Di(Di_buf), .Do(Do_0), .A(A_buf[6:0]) ); - RAM128 #(.USE_LATCH(USE_LATCH)) BANK128_B1 (.CLK(CLK_buf), .EN(SEL[1]), .WE(WE_buf), .Di(Di_buf), .Do(Do_1), .A(A_buf[6:0]) ); - RAM128 #(.USE_LATCH(USE_LATCH)) BANK128_B2 (.CLK(CLK_buf), .EN(SEL[2]), .WE(WE_buf), .Di(Di_buf), .Do(Do_2), .A(A_buf[6:0]) ); - RAM128 #(.USE_LATCH(USE_LATCH)) BANK128_B3 (.CLK(CLK_buf), .EN(SEL[3]), .WE(WE_buf), .Di(Di_buf), .Do(Do_3), .A(A_buf[6:0]) ); + RAM128 #(.USE_LATCH(USE_LATCH)) \BANK128[0].RAM128 (.CLK(CLK_buf), .EN(SEL[0]), .WE(WE_buf), .Di(Di_buf), .Do(Do_0), .A(A_buf[6:0]) ); + RAM128 #(.USE_LATCH(USE_LATCH)) \BANK128[1].RAM128 (.CLK(CLK_buf), .EN(SEL[1]), .WE(WE_buf), .Di(Di_buf), .Do(Do_1), .A(A_buf[6:0]) ); + RAM128 #(.USE_LATCH(USE_LATCH)) \BANK128[2].RAM128 (.CLK(CLK_buf), .EN(SEL[2]), .WE(WE_buf), .Di(Di_buf), .Do(Do_2), .A(A_buf[6:0]) ); + RAM128 #(.USE_LATCH(USE_LATCH)) \BANK128[3].RAM128 (.CLK(CLK_buf), .EN(SEL[3]), .WE(WE_buf), .Di(Di_buf), .Do(Do_3), .A(A_buf[6:0]) ); // Output MUX MUX4x1_32 DoMUX ( .A0(Do_0), .A1(Do_1), .A2(Do_2), .A3(Do_3), .S(A_buf[8:7]), .X(Do) ); @@ -382,10 +382,10 @@ module RAM2048 #(parameter USE_LATCH=1) ( DEC2x4 DEC (.EN(EN), .A(A[10:9]), .SEL(SEL)); // 32x32 RAM Banks - RAM512 #(.USE_LATCH(USE_LATCH)) BANK512_B0 (.CLK(CLK), .EN(SEL[0]), .WE(WE), .Di(Di), .Do(Do_0), .A(A[8:0]) ); - RAM512 #(.USE_LATCH(USE_LATCH)) BANK512_B1 (.CLK(CLK), .EN(SEL[1]), .WE(WE), .Di(Di), .Do(Do_1), .A(A[8:0]) ); - RAM512 #(.USE_LATCH(USE_LATCH)) BANK512_B2 (.CLK(CLK), .EN(SEL[2]), .WE(WE), .Di(Di), .Do(Do_2), .A(A[8:0]) ); - RAM512 #(.USE_LATCH(USE_LATCH)) BANK512_B3 (.CLK(CLK), .EN(SEL[3]), .WE(WE), .Di(Di), .Do(Do_3), .A(A[8:0]) ); + RAM512 #(.USE_LATCH(USE_LATCH)) \BANK512[0].RAM512 (.CLK(CLK), .EN(SEL[0]), .WE(WE), .Di(Di), .Do(Do_0), .A(A[8:0]) ); + RAM512 #(.USE_LATCH(USE_LATCH)) \BANK512[1].RAM512 (.CLK(CLK), .EN(SEL[1]), .WE(WE), .Di(Di), .Do(Do_1), .A(A[8:0]) ); + RAM512 #(.USE_LATCH(USE_LATCH)) \BANK512[2].RAM512 (.CLK(CLK), .EN(SEL[2]), .WE(WE), .Di(Di), .Do(Do_2), .A(A[8:0]) ); + RAM512 #(.USE_LATCH(USE_LATCH)) \BANK512[3].RAM512 (.CLK(CLK), .EN(SEL[3]), .WE(WE), .Di(Di), .Do(Do_3), .A(A[8:0]) ); // Output MUX MUX4x1_32 DoMUX ( .A0(Do_0), .A1(Do_1), .A2(Do_2), .A3(Do_3), .S(A[10:9]), .X(Do) ); diff --git a/platforms/sky130A/BB/ram/model.v b/platforms/sky130A/BB/ram/model.v index b30c514..3fe8827 100644 --- a/platforms/sky130A/BB/ram/model.v +++ b/platforms/sky130A/BB/ram/model.v @@ -563,7 +563,7 @@ module RAM256 #(parameter USE_LATCH=1, generate genvar i; - for (i=0; i< 2; i=i+1) begin : BLOCK + for (i=0; i< 2; i=i+1) begin : BANK128 RAM128 #(.USE_LATCH(USE_LATCH), .WSIZE(WSIZE)) RAM128 (.CLK(CLK), .EN0(SEL0[i]), .WE0(WE0), .Di0(Di0), .Do0(Do0_pre[i]), .A0(A0[6:0]) ); end endgenerate @@ -597,7 +597,7 @@ module RAM256_1RW1R #(parameter USE_LATCH=1, generate genvar i; - for (i=0; i< 2; i=i+1) begin : BLOCK + for (i=0; i< 2; i=i+1) begin : BANK128 RAM128_1RW1R #(.USE_LATCH(USE_LATCH), .WSIZE(WSIZE)) RAM128 (.CLK(CLK), .EN0(SEL0[i]), .EN1(SEL1[i]), .WE0(WE0), .Di0(Di0), .Do0(Do0_pre[i]), .Do1(Do1_pre[i]), .A0(A0[6:0]), .A1(A1[6:0]) ); end endgenerate @@ -628,7 +628,7 @@ module RAM512 #(parameter USE_LATCH=1, generate genvar i; - for (i=0; i< 4; i=i+1) begin : BLOCK + for (i=0; i< 4; i=i+1) begin : BANK128 RAM128 #(.USE_LATCH(USE_LATCH), .WSIZE(WSIZE)) RAM128 (.CLK(CLK), .EN0(SEL0[i]), .WE0(WE0), @@ -673,7 +673,7 @@ module RAM512_1RW1R #(parameter USE_LATCH=1, generate genvar i; - for (i=0; i< 4; i=i+1) begin : BLOCK + for (i=0; i< 4; i=i+1) begin : BANK128 RAM128_1RW1R #(.USE_LATCH(USE_LATCH), .WSIZE(WSIZE)) RAM128 (.CLK(CLK), .EN0(SEL0[i]), .EN1(SEL1[i]), .WE0(WE0), .Di0(Di0), .Do0(Do0_pre[i]), .Do1(Do1_pre[i]), .A0(A0[6:0]), .A1(A1[6:0]) ); end endgenerate @@ -717,8 +717,8 @@ module RAM1024 #(parameter USE_LATCH=1, generate genvar i; - for (i=0; i< 2; i=i+1) begin : BLOCK - RAM512 #(.USE_LATCH(USE_LATCH), .WSIZE(WSIZE)) RAM32 (.CLK(CLK_buf), .EN0(SEL0[i]), .WE0(WE0_buf), .Di0(Di0_buf), .Do0(Do0_pre[i]), .A0(A0_buf[8:0]) ); + for (i=0; i< 2; i=i+1) begin : BANK512 + RAM512 #(.USE_LATCH(USE_LATCH), .WSIZE(WSIZE)) RAM512 (.CLK(CLK_buf), .EN0(SEL0[i]), .WE0(WE0_buf), .Di0(Di0_buf), .Do0(Do0_pre[i]), .A0(A0_buf[8:0]) ); end endgenerate @@ -768,8 +768,8 @@ module RAM1024_1RW1R #(parameter USE_LATCH=1, generate genvar i; - for (i=0; i< 2; i=i+1) begin : BLOCK - RAM512_1RW1R #(.USE_LATCH(USE_LATCH), .WSIZE(WSIZE)) RAM32 (.CLK(CLK_buf), .EN0(SEL0[i]), .EN1(SEL1[i]), .WE0(WE0_buf), .Di0(Di0_buf), .Do0(Do0_pre[i]), .Do1(Do1_pre[i]), .A0(A0_buf[8:0]), .A1(A1_buf[8:0]) ); + for (i=0; i< 2; i=i+1) begin : BANK512 + RAM512_1RW1R #(.USE_LATCH(USE_LATCH), .WSIZE(WSIZE)) RAM512 (.CLK(CLK_buf), .EN0(SEL0[i]), .EN1(SEL1[i]), .WE0(WE0_buf), .Di0(Di0_buf), .Do0(Do0_pre[i]), .Do1(Do1_pre[i]), .A0(A0_buf[8:0]), .A1(A1_buf[8:0]) ); end endgenerate @@ -811,8 +811,8 @@ module RAM2048 #(parameter USE_LATCH=1, generate genvar i; - for (i=0; i< 4; i=i+1) begin : BLOCK - RAM512 #(.USE_LATCH(USE_LATCH), .WSIZE(WSIZE)) RAM32 (.CLK(CLK_buf), .EN0(SEL0[i]), .WE0(WE0_buf), .Di0(Di0_buf), .Do0(Do0_pre[i]), .A0(A0_buf[8:0]) ); + for (i=0; i< 4; i=i+1) begin : BANK512 + RAM512 #(.USE_LATCH(USE_LATCH), .WSIZE(WSIZE)) RAM512 (.CLK(CLK_buf), .EN0(SEL0[i]), .WE0(WE0_buf), .Di0(Di0_buf), .Do0(Do0_pre[i]), .A0(A0_buf[8:0]) ); end endgenerate @@ -861,8 +861,8 @@ module RAM2048_1RW1R #(parameter USE_LATCH=1, generate genvar i; - for (i=0; i< 4; i=i+1) begin : BLOCK - RAM512_1RW1R #(.USE_LATCH(USE_LATCH), .WSIZE(WSIZE)) RAM32_1RW1R (.CLK(CLK_buf), .EN0(SEL0[i]), .EN1(SEL1[i]), .WE0(WE0_buf), .Di0(Di0_buf), .Do0(Do0_pre[i]), .Do1(Do1_pre[i]), .A0(A0_buf[8:0]), .A1(A1_buf[8:0]) ); + for (i=0; i< 4; i=i+1) begin : BANK512 + RAM512_1RW1R #(.USE_LATCH(USE_LATCH), .WSIZE(WSIZE)) RAM512 (.CLK(CLK_buf), .EN0(SEL0[i]), .EN1(SEL1[i]), .WE0(WE0_buf), .Di0(Di0_buf), .Do0(Do0_pre[i]), .Do1(Do1_pre[i]), .A0(A0_buf[8:0]), .A1(A1_buf[8:0]) ); end endgenerate