From de1551a7dce132c1afd1bed070adbd03f113127a Mon Sep 17 00:00:00 2001 From: Thinh Nguyen Date: Tue, 17 Mar 2026 11:57:09 -0400 Subject: [PATCH 1/7] add column mux support with flag -mux_col_ratio parameter --- src/ram/include/ram/ram.h | 24 +- src/ram/src/ram.cpp | 458 ++++++++++++++++++++++++------ src/ram/src/ram.i | 3 +- src/ram/src/ram.tcl | 29 +- src/ram/test/make_8x8_mux2.tcl | 37 +++ src/ram/test/make_8x8_mux4.tcl | 37 +++ src/ram/test/regression_tests.tcl | 2 + 7 files changed, 493 insertions(+), 97 deletions(-) create mode 100644 src/ram/test/make_8x8_mux2.tcl create mode 100644 src/ram/test/make_8x8_mux4.tcl diff --git a/src/ram/include/ram/ram.h b/src/ram/include/ram/ram.h index ffec08e4421..8c9bd9c1eba 100644 --- a/src/ram/include/ram/ram.h +++ b/src/ram/include/ram/ram.h @@ -68,6 +68,7 @@ class RamGen void generate(int bytes_per_word, int word_count, + int mux_col_ratio, int read_ports, odb::dbMaster* storage_cell, odb::dbMaster* tristate_cell, @@ -120,14 +121,28 @@ class RamGen std::vector& data_output); void makeCellByte( Grid& ram_grid, - int byte_number, + int byte_idx, + int col_group, + int bytes_per_word_total, const std::string& prefix, int read_ports, odb::dbNet* clock, odb::dbNet* write_enable, const std::vector& selects, + odb::dbNet* col_select, const std::array& data_input, - const std::vector>& data_output); + const std::vector>& data_output); + + // Builds the AOI-gate column mux for one logical byte. + // For mux_col_ratio=2: AOI22 + INV per bit. + // For mux_col_ratio=4: AOI22 + AOI22 + AND2 + INV per bit. + // Returns a Cell to be placed in the sel-cell track buffer row. + std::unique_ptr makeColMux( + const std::string& prefix, + int mux_col_ratio, + const std::vector>& col_q_nets, + const std::vector& col_sel_nets, + const std::array& q_out_nets); odb::dbBTerm* makeBTerm(const std::string& name, odb::dbIoType io_type); @@ -156,10 +171,15 @@ class RamGen odb::dbMaster* tristate_cell_{nullptr}; odb::dbMaster* inv_cell_{nullptr}; odb::dbMaster* and2_cell_{nullptr}; + odb::dbMaster* aoi22_cell_{nullptr}; odb::dbMaster* clock_gate_cell_{nullptr}; odb::dbMaster* buffer_cell_{nullptr}; odb::dbMaster* tapcell_{nullptr}; + // Port names for the AOI22 cell, discovered at findMasters() time. + std::string aoi22_in_a1_, aoi22_in_a2_, aoi22_in_b1_, aoi22_in_b2_, + aoi22_out_; + std::vector addr_inputs_; std::vector data_inputs_; std::vector> q_outputs_; diff --git a/src/ram/src/ram.cpp b/src/ram/src/ram.cpp index 434f7e11193..25f447ea85f 100644 --- a/src/ram/src/ram.cpp +++ b/src/ram/src/ram.cpp @@ -139,16 +139,36 @@ std::unique_ptr RamGen::makeCellBit(const std::string& prefix, void RamGen::makeCellByte(Grid& ram_grid, const int byte_idx, + const int col_group, + const int bytes_per_word_total, const std::string& prefix, const int read_ports, dbNet* clock, dbNet* write_enable, const vector& selects, + dbNet* col_select, const array& data_input, - const vector>& data_output) + const vector>& data_output) { + auto sel_cell = std::make_unique(); + + // Write path: AND row_select with col_select so the clock gate only fires + // for the addressed column group. The read path is handled by the AOI mux + // in makeColMux, so the tristate enable remains row_select only. + dbNet* write_sel = selects[0]; + if (col_select) { + write_sel = makeNet(prefix, "write_sel"); + makeCellInst(sel_cell.get(), + prefix, + "col_and", + and2_cell_, + {{"A", selects[0]}, {"B", col_select}, {"X", write_sel}}); + } + + // Tristate enable is row_select only (inverted): the AOI mux downstream + // selects which column group's tristate bus drives the final Q output. vector select_b_nets(selects.size()); - for (int i = 0; i < selects.size(); ++i) { + for (int i = 0; i < (int) selects.size(); ++i) { select_b_nets[i] = makeNet(prefix, fmt::format("select{}_b", i)); } @@ -158,21 +178,18 @@ void RamGen::makeCellByte(Grid& ram_grid, // For naming bits: 0, 8, 16,... const int logical_bit_base = byte_idx * 8; - // For placement taking into acount select bit of each byte: 0, 9, 18, 27... - const int physical_col_base = byte_idx * 9; + // Physical column base accounts for which column group this byte is in. + const int physical_col_base = (col_group * bytes_per_word_total + byte_idx) * 9; for (int local_bit = 0; local_bit < 8; ++local_bit) { - // For naming const int global_logical_bit_idx = logical_bit_base + local_bit; - - // For placement const int physical_col_idx = physical_col_base + local_bit; auto name = fmt::format("{}.bit{}", prefix, global_logical_bit_idx); vector outs; outs.reserve(read_ports); for (int read_port = 0; read_port < read_ports; ++read_port) { - outs.push_back(data_output[read_port][local_bit]->getNet()); + outs.push_back(data_output[read_port][local_bit]); } ram_grid.addCell(makeCellBit(name, read_ports, @@ -183,25 +200,22 @@ void RamGen::makeCellByte(Grid& ram_grid, physical_col_idx); } - auto sel_cell = std::make_unique(); - // Make clock gate + // Clock gate makeCellInst(sel_cell.get(), prefix, "cg", clock_gate_cell_, {{"CLK", clock}, {"GATE", we0_net}, {"GCLK", gclock_net}}); - // Make clock and - // this AND gate needs to be fed a net created by a decoder - // adding any net will automatically connect with any port + // WE AND gate: write_sel already combines row+col for the write path makeCellInst(sel_cell.get(), prefix, "gcand", and2_cell_, - {{"A", selects[0]}, {"B", write_enable}, {"X", we0_net}}); + {{"A", write_sel}, {"B", write_enable}, {"X", we0_net}}); - // Make select inverters - for (int i = 0; i < selects.size(); ++i) { + // Select inverters: invert row_select only for tristate enable + for (int i = 0; i < (int) selects.size(); ++i) { makeCellInst(sel_cell.get(), prefix, fmt::format("select_inv_{}", i), @@ -209,7 +223,67 @@ void RamGen::makeCellByte(Grid& ram_grid, {{"A", selects[i]}, {"Y", select_b_nets[i]}}); } - ram_grid.addCell(std::move(sel_cell), (byte_idx * 9) + 8); + ram_grid.addCell(std::move(sel_cell), physical_col_base + 8); +} + +std::unique_ptr RamGen::makeColMux( + const std::string& prefix, + const int mux_col_ratio, + const vector>& col_q_nets, + const vector& col_sel_nets, + const array& q_out_nets) +{ + auto mux_cell = std::make_unique(); + + for (int bit = 0; bit < 8; ++bit) { + auto aoi_lo_net = makeNet(prefix, fmt::format("aoi_lo_bit{}", bit)); + auto inv_in_net = aoi_lo_net; // default for mux=2; overridden for mux=4 + + // First AOI22: NOT((col_sel[0] & col_q[0]) | (col_sel[1] & col_q[1])) + makeCellInst(mux_cell.get(), + prefix, + fmt::format("aoi_lo_bit{}", bit), + aoi22_cell_, + {{aoi22_in_a1_, col_sel_nets[0]}, + {aoi22_in_a2_, col_q_nets[0][bit]}, + {aoi22_in_b1_, col_sel_nets[1]}, + {aoi22_in_b2_, col_q_nets[1][bit]}, + {aoi22_out_, aoi_lo_net}}); + + if (mux_col_ratio == 4) { + // Second AOI22: NOT((col_sel[2] & col_q[2]) | (col_sel[3] & col_q[3])) + auto aoi_hi_net = makeNet(prefix, fmt::format("aoi_hi_bit{}", bit)); + makeCellInst(mux_cell.get(), + prefix, + fmt::format("aoi_hi_bit{}", bit), + aoi22_cell_, + {{aoi22_in_a1_, col_sel_nets[2]}, + {aoi22_in_a2_, col_q_nets[2][bit]}, + {aoi22_in_b1_, col_sel_nets[3]}, + {aoi22_in_b2_, col_q_nets[3][bit]}, + {aoi22_out_, aoi_hi_net}}); + + // AND2(aoi_lo, aoi_hi): De Morgan gives us the OR of all four AND terms + // NOT(aoi_lo AND aoi_hi) = (cs0&q0|cs1&q1) OR (cs2&q2|cs3&q3) + // so we still need to invert — use AND2 then INV below. + auto and_net = makeNet(prefix, fmt::format("mux_and_bit{}", bit)); + makeCellInst(mux_cell.get(), + prefix, + fmt::format("mux_and_bit{}", bit), + and2_cell_, + {{"A", aoi_lo_net}, {"B", aoi_hi_net}, {"X", and_net}}); + inv_in_net = and_net; + } + + // Final INV to un-invert the AOI output and drive Q + makeCellInst(mux_cell.get(), + prefix, + fmt::format("mux_inv_bit{}", bit), + inv_cell_, + {{"A", inv_in_net}, {"Y", q_out_nets[bit]}}); + } + + return mux_cell; } std::unique_ptr RamGen::generateTapColumn(const int word_count, @@ -430,6 +504,55 @@ void RamGen::findMasters() [](sta::LibertyPort* port) { return port->libertyCell()->isBuffer(); }, "buffer"); } + + if (!aoi22_cell_) { + // AOI22: Y = NOT((A AND B) OR (C AND D)) + // FuncExpr tree: not_ → or_ → [ and_(port, port), and_(port, port) ] + aoi22_cell_ = findMaster( + [](sta::LibertyPort* port) { + if (!port->direction()->isOutput()) { + return false; + } + auto f = port->function(); + if (!f || f->op() != sta::FuncExpr::Op::not_) { + return false; + } + auto inner = f->left(); + if (!inner || inner->op() != sta::FuncExpr::Op::or_) { + return false; + } + auto L = inner->left(); + auto R = inner->right(); + return L && L->op() == sta::FuncExpr::Op::and_ + && L->left() && L->left()->op() == sta::FuncExpr::Op::port + && L->right() && L->right()->op() == sta::FuncExpr::Op::port + && R && R->op() == sta::FuncExpr::Op::and_ + && R->left() && R->left()->op() == sta::FuncExpr::Op::port + && R->right() && R->right()->op() == sta::FuncExpr::Op::port; + }, + "aoi22"); + + // Extract the actual port names from the liberty function tree so we can + // wire up the cell generically regardless of naming convention. + auto cell = network_->libertyCell(network_->dbToSta(aoi22_cell_)); + auto port_iter = cell->portIterator(); + while (port_iter->hasNext()) { + auto p = static_cast(port_iter->next()); + if (p->direction()->isAnyOutput()) { + auto f = p->libertyPort()->function(); + auto or_expr = f->left(); + auto and_a = or_expr->left(); + auto and_b = or_expr->right(); + aoi22_in_a1_ = and_a->left()->port()->name(); + aoi22_in_a2_ = and_a->right()->port()->name(); + aoi22_in_b1_ = and_b->left()->port()->name(); + aoi22_in_b2_ = and_b->right()->port()->name(); + aoi22_out_ = p->name(); + break; + } + } + delete port_iter; + } } void RamGen::ramPdngen(const char* power_pin, @@ -586,6 +709,7 @@ void RamGen::ramRouting(int thread_count) void RamGen::generate(const int bytes_per_word, const int word_count, + const int mux_col_ratio, const int read_ports, dbMaster* storage_cell, dbMaster* tristate_cell, @@ -605,6 +729,33 @@ void RamGen::generate(const int bytes_per_word, return; } + if (mux_col_ratio != 1 && mux_col_ratio != 2 && mux_col_ratio != 4) { + logger_->error(RAM, 26, "mux_col_ratio must be 1, 2, or 4."); + return; + } + if (word_count % mux_col_ratio != 0) { + logger_->error(RAM, + 27, + "word_count ({}) must be divisible by mux_col_ratio ({}).", + word_count, + mux_col_ratio); + return; + } + if (mux_col_ratio > 1 && word_count / mux_col_ratio < 2) { + logger_->error( + RAM, + 28, + "word_count / mux_col_ratio must be at least 2 (got {}).", + word_count / mux_col_ratio); + return; + } + + // Number of physical rows and address bit split between row and column. + const int num_rows = word_count / mux_col_ratio; + const int num_col_bits = (mux_col_ratio > 1) + ? static_cast(std::log2(mux_col_ratio)) + : 0; + logger_->info(RAM, 3, "Generating {}", ram_name); storage_cell_ = storage_cell; @@ -612,6 +763,7 @@ void RamGen::generate(const int bytes_per_word, inv_cell_ = inv_cell; tapcell_ = tapcell; and2_cell_ = nullptr; + aoi22_cell_ = nullptr; clock_gate_cell_ = nullptr; buffer_cell_ = nullptr; findMasters(); @@ -627,10 +779,9 @@ void RamGen::generate(const int bytes_per_word, block_ = odb::dbBlock::create(chip, ram_name.c_str()); } - // 9 columns for 8 bits per word plus - // cell for WE AND gate/inverter - // extra column is for decoder cells - int col_cell_count = bytes_per_word * 9; + // 9 columns per byte (8 bit cells + 1 sel cell), replicated mux_col_ratio + // times horizontally. Extra column at the end is for row decoder cells. + int col_cell_count = bytes_per_word * 9 * mux_col_ratio; Grid ram_grid(odb::horizontal, col_cell_count + 1); auto clock = makeBTerm("clk", dbIoType::INPUT); @@ -641,71 +792,143 @@ void RamGen::generate(const int bytes_per_word, write_enable[byte] = makeBTerm(in_name, dbIoType::INPUT); } - // input bterms + // Total address bits cover the full word_count. + // Lower num_col_bits select the physical column group (mux select). + // Upper bits select the physical row (row decoder). int num_inputs = std::ceil(std::log2(word_count)); + const int num_row_bits = num_inputs - num_col_bits; + for (int i = 0; i < num_inputs; ++i) { addr_inputs_.push_back( makeBTerm(fmt::format("addr[{}]", i), dbIoType::INPUT)); } - // vector of nets storing inverter nets + // Inverted address nets (one per address bit, covers all bits) vector inv_addr(num_inputs); for (int i = 0; i < num_inputs; ++i) { inv_addr[i] = makeNet("inv", fmt::format("addr[{}]", i)); } - // decoder_layer nets - vector> decoder_input_nets(word_count, - vector(num_inputs)); - for (int word = 0; word < word_count; ++word) { - int word_num = word; - // start at right most bit - for (int input = 0; input < num_inputs; ++input) { - if (word_num % 2 == 0) { - // places inverted address for each input - decoder_input_nets[word][input] = inv_addr[input]; - } else { // puts original input in invert nets - decoder_input_nets[word][input] = addr_inputs_[input]->getNet(); + // Column select nets: derived from the lower num_col_bits of address. + // mux_col_ratio=1: unused (nullptr throughout) + // mux_col_ratio=2: col_sel[0]=~addr[0], col_sel[1]=addr[0] + // mux_col_ratio=4: col_sel[c] = AND of addr[1:0] combination for column c + vector col_sel_nets(mux_col_ratio, nullptr); + if (mux_col_ratio == 2) { + col_sel_nets[0] = inv_addr[0]; + col_sel_nets[1] = addr_inputs_[0]->getNet(); + } else if (mux_col_ratio == 4) { + for (int c = 0; c < 4; ++c) { + col_sel_nets[c] = makeNet("col_sel", fmt::format("{}", c)); + } + } + + // Row decoder input nets: for each physical row, determine whether each + // upper address bit (addr[num_col_bits..num_inputs-1]) is true or inverted. + vector> decoder_input_nets(num_rows, + vector(num_row_bits)); + for (int row = 0; row < num_rows; ++row) { + int row_num = row; + for (int input = 0; input < num_row_bits; ++input) { + if (row_num % 2 == 0) { + decoder_input_nets[row][input] = inv_addr[num_col_bits + input]; + } else { + decoder_input_nets[row][input] + = addr_inputs_[num_col_bits + input]->getNet(); } - word_num /= 2; + row_num /= 2; } } - // word decoder signals to have one deccoder per word, shared between all - // bytes of a word - vector> word_decoder_nets(word_count); + // Row decoder: one select net per physical row, shared across all bytes and + // column groups in that row. + vector> row_decoder_nets(num_rows); - for (int row = 0; row < word_count; ++row) { + for (int row = 0; row < num_rows; ++row) { auto decoder_name = fmt::format("decoder_{}", row); - if (word_count == 2) { - dbNet* addr_net = (row == 0 ? inv_addr[0] : addr_inputs_[0]->getNet()); + if (num_rows == 2) { + // Special case: single upper address bit, no AND gates needed. + dbNet* addr_net = (row == 0 ? inv_addr[num_col_bits] + : addr_inputs_[num_col_bits]->getNet()); for (int i = 0; i < read_ports; ++i) { - word_decoder_nets[row].push_back(addr_net); + row_decoder_nets[row].push_back(addr_net); } } else { - word_decoder_nets[row] = selectNets(decoder_name, read_ports); + row_decoder_nets[row] = selectNets(decoder_name, read_ports); auto decoder_and_cell = makeDecoder(decoder_name, - word_count, + num_rows, read_ports, - word_decoder_nets[row], + row_decoder_nets[row], decoder_input_nets[row]); ram_grid.addCell(std::move(decoder_and_cell), col_cell_count); } } - // create bytes within a word, shared decoder net for each word + // For mux_col_ratio=4, build the column-select AND gates and place them in + // the decoder column at the buffer-row position (after all row decoder cells). + if (mux_col_ratio == 4) { + // If num_rows==2 the special case left the decoder column empty; pad so + // the col-select cell lands in the correct buffer-row slot. + if (num_rows == 2) { + for (int r = 0; r < num_rows; ++r) { + ram_grid.addCell(std::unique_ptr(), col_cell_count); + } + } + auto col_sel_cell = std::make_unique(); + // col c is selected when addr[1:0] == c + // c=0: ~addr[1] & ~addr[0] + // c=1: ~addr[1] & addr[0] + // c=2: addr[1] & ~addr[0] + // c=3: addr[1] & addr[0] + makeCellInst(col_sel_cell.get(), + "col_sel", + "and_0", + and2_cell_, + {{"A", inv_addr[1]}, + {"B", inv_addr[0]}, + {"X", col_sel_nets[0]}}); + makeCellInst(col_sel_cell.get(), + "col_sel", + "and_1", + and2_cell_, + {{"A", inv_addr[1]}, + {"B", addr_inputs_[0]->getNet()}, + {"X", col_sel_nets[1]}}); + makeCellInst(col_sel_cell.get(), + "col_sel", + "and_2", + and2_cell_, + {{"A", addr_inputs_[1]->getNet()}, + {"B", inv_addr[0]}, + {"X", col_sel_nets[2]}}); + makeCellInst(col_sel_cell.get(), + "col_sel", + "and_3", + and2_cell_, + {{"A", addr_inputs_[1]->getNet()}, + {"B", addr_inputs_[0]->getNet()}, + {"X", col_sel_nets[3]}}); + ram_grid.addCell(std::move(col_sel_cell), col_cell_count); + } + + // Build the storage array: iterate over logical bytes, then column groups, + // then physical rows. + // + // For mux=1: each bit cell's tristate drives the Q BTerm net directly. + // For mux>1: each col_group gets its own intermediate tristate bus + // (col_q_nets[col_group][bit]). After all col_groups are built, an AOI + // mux selects the addressed col_group and drives the actual Q BTerm net. for (int col = 0; col < bytes_per_word; ++col) { - array D_nets; // net for buffers + array D_nets; for (int bit = 0; bit < 8; ++bit) { data_inputs_.push_back( makeBTerm(fmt::format("D[{}]", bit + col * 8), dbIoType::INPUT)); D_nets[bit] = makeNet(fmt::format("D_nets[{}]", bit + col * 8), "net"); } - // if readports == 1, only have Q outputs if (read_ports == 1) { array q_bTerms; for (int bit = 0; bit < 8; ++bit) { @@ -724,34 +947,109 @@ void RamGen::generate(const int bytes_per_word, } } - for (int row = 0; row < word_count; ++row) { - auto cell_name = fmt::format("storage_{}_{}", row, col); - - makeCellByte(ram_grid, - col, - cell_name, - read_ports, - clock->getNet(), - write_enable[col]->getNet(), - word_decoder_nets[row], - D_nets, - q_outputs_); + // The Q BTerm net for this byte (read_port 0, which is the only port for + // now). For mux=1 this is used directly. For mux>1 the AOI mux drives it. + const int q_idx = (read_ports == 1) ? col : col * read_ports; + array q_out_nets; + for (int bit = 0; bit < 8; ++bit) { + q_out_nets[bit] = q_outputs_[q_idx][bit]->getNet(); + } + + // Intermediate tristate bus per col_group. For mux=1, just alias Q BTerm + // nets directly (no intermediate wires, same as before). + vector> col_q_nets(mux_col_ratio); + if (mux_col_ratio == 1) { + col_q_nets[0] = q_out_nets; + } else { + for (int cg = 0; cg < mux_col_ratio; ++cg) { + for (int bit = 0; bit < 8; ++bit) { + col_q_nets[cg][bit] = makeNet( + fmt::format("col{}_q[{}]", cg, bit + col * 8), "net"); + } + } + } + + for (int col_group = 0; col_group < mux_col_ratio; ++col_group) { + // data_output for this col_group: one entry per read port. + vector> col_group_output(read_ports); + col_group_output[0] = col_q_nets[col_group]; + + for (int row = 0; row < num_rows; ++row) { + auto cell_name = fmt::format("storage_{}_{}_{}", col_group, row, col); + + makeCellByte(ram_grid, + col, + col_group, + bytes_per_word, + cell_name, + read_ports, + clock->getNet(), + write_enable[col]->getNet(), + row_decoder_nets[row], + col_sel_nets[col_group], + D_nets, + col_group_output); + } + } + + // For mux>1, place the AOI column mux in the sel-cell track of col_group=0 + // (track col*9+8). That track has exactly num_rows sel_cells already, so + // this cell lands in the buffer-row slot. + if (mux_col_ratio > 1) { + auto mux_cell = makeColMux(fmt::format("col_mux_{}", col), + mux_col_ratio, + col_q_nets, + col_sel_nets, + q_out_nets); + ram_grid.addCell(std::move(mux_cell), col * 9 + 8); } + // Input buffers for this logical byte are placed in col_group=0's physical + // columns (same track indices as before). The D_nets wire is shared across + // all column groups so the router connects them. for (int bit = 0; bit < 8; ++bit) { auto buffer_grid_cell = std::make_unique(); makeCellInst(buffer_grid_cell.get(), "buffer", fmt::format("in[{}]", bit + col * 8), buffer_cell_, - {{"A", data_inputs_[bit]->getNet()}, {"X", D_nets[bit]}}); + {{"A", data_inputs_[bit + col * 8]->getNet()}, + {"X", D_nets[bit]}}); ram_grid.addCell(std::move(buffer_grid_cell), col * 9 + bit); } } + // Address inverter column: one inverter per address bit, compact for mux>1. auto cell_inv_layout = std::make_unique(odb::vertical); - // check for AND gate, specific case for 2 words - if (num_inputs > 1) { + if (mux_col_ratio == 1) { + // Original spaced pattern: each inverter is separated by (num_inputs-1) + // filler rows so the inverters spread evenly over the array height. + if (num_inputs > 1) { + for (int i = num_inputs - 1; i >= 0; --i) { + auto inv_grid_cell = std::make_unique(); + makeCellInst(inv_grid_cell.get(), + "decoder", + fmt::format("inv_{}", i), + inv_cell_, + {{"A", addr_inputs_[i]->getNet()}, {"Y", inv_addr[i]}}); + cell_inv_layout->addCell(std::move(inv_grid_cell)); + for (int filler_count = 0; filler_count < num_inputs - 1; + ++filler_count) { + cell_inv_layout->addCell(nullptr); + } + } + } else { + auto inv_grid_cell = std::make_unique(); + makeCellInst(inv_grid_cell.get(), + "decoder", + fmt::format("inv_{}", 0), + inv_cell_, + {{"A", addr_inputs_[0]->getNet()}, {"Y", inv_addr[0]}}); + cell_inv_layout->addCell(std::move(inv_grid_cell)); + } + } else { + // Compact pattern for mux>1: place inverters without spacing and pad the + // remaining slots with nullptr to stay within the array height. for (int i = num_inputs - 1; i >= 0; --i) { auto inv_grid_cell = std::make_unique(); makeCellInst(inv_grid_cell.get(), @@ -760,19 +1058,10 @@ void RamGen::generate(const int bytes_per_word, inv_cell_, {{"A", addr_inputs_[i]->getNet()}, {"Y", inv_addr[i]}}); cell_inv_layout->addCell(std::move(inv_grid_cell)); - for (int filler_count = 0; filler_count < num_inputs - 1; - ++filler_count) { - cell_inv_layout->addCell(nullptr); - } } - } else { - auto inv_grid_cell = std::make_unique(); - makeCellInst(inv_grid_cell.get(), - "decoder", - fmt::format("inv_{}", 0), - inv_cell_, - {{"A", addr_inputs_[0]->getNet()}, {"Y", inv_addr[0]}}); - cell_inv_layout->addCell(std::move(inv_grid_cell)); + for (int pad = num_inputs; pad <= num_rows; ++pad) { + cell_inv_layout->addCell(nullptr); + } } ram_grid.addLayout(std::move(cell_inv_layout)); @@ -783,30 +1072,25 @@ void RamGen::generate(const int bytes_per_word, ram_grid.gridInit(); if (tapcell_) { - // max tap distance specified is greater than the length of ram if (ram_grid.getRowWidth() <= max_tap_dist) { - auto tapcell_layout = generateTapColumn(word_count, 0); + auto tapcell_layout = generateTapColumn(num_rows, 0); ram_grid.insertLayout(std::move(tapcell_layout), 0); } else { - // needed this calculation so first cells have right distance int nearest_tap = (max_tap_dist / ram_grid.getWidth()) * ram_grid.getLayoutWidth(0); int tapcell_count = 0; - // iterates through each of the columns for (int col = 0; col < ram_grid.numLayouts(); ++col) { if (nearest_tap + ram_grid.getLayoutWidth(col) >= max_tap_dist) { - // if the nearest_tap is too far, generate tap column - auto tapcell_layout = generateTapColumn(word_count, tapcell_count); + auto tapcell_layout = generateTapColumn(num_rows, tapcell_count); ram_grid.insertLayout(std::move(tapcell_layout), col); - ++col; // col adjustment after insertion + ++col; nearest_tap = 0; ++tapcell_count; } nearest_tap += ram_grid.getLayoutWidth(col); } - // check for last column in the grid if (nearest_tap >= max_tap_dist) { - auto tapcell_layout = generateTapColumn(word_count, tapcell_count); + auto tapcell_layout = generateTapColumn(num_rows, tapcell_count); ram_grid.addLayout(std::move(tapcell_layout)); } } @@ -819,7 +1103,7 @@ void RamGen::generate(const int bytes_per_word, auto sites_width = db_sites->getWidth(); int num_sites = ram_grid.getRowWidth() / db_sites->getWidth(); - for (int i = 0; i <= word_count; ++i) { // extra for the layer of buffers + for (int i = 0; i <= num_rows; ++i) { // extra for the layer of buffers auto row_name = fmt::format("RAM_ROW{}", i); auto y_coord = i * ram_grid.getHeight(); auto row_orient = odb::dbOrientType::R0; @@ -839,7 +1123,7 @@ void RamGen::generate(const int bytes_per_word, ram_grid.placeGrid(); - int max_y_coord = ram_grid.getHeight() * (word_count + 1); + int max_y_coord = ram_grid.getHeight() * (num_rows + 1); int max_x_coord = ram_grid.getRowWidth(); block_->setDieArea(odb::Rect(0, 0, max_x_coord, max_y_coord)); diff --git a/src/ram/src/ram.i b/src/ram/src/ram.i index b3b931d9fe8..1fc1949d466 100644 --- a/src/ram/src/ram.i +++ b/src/ram/src/ram.i @@ -31,6 +31,7 @@ namespace ram { void generate_ram_netlist_cmd(int bytes_per_word, int word_count, + int mux_col_ratio, const char* storage_cell_name, const char* tristate_cell_name, const char* inv_cell_name, @@ -86,7 +87,7 @@ generate_ram_netlist_cmd(int bytes_per_word, } } - ram_gen->generate(bytes_per_word, word_count, read_ports, + ram_gen->generate(bytes_per_word, word_count, mux_col_ratio, read_ports, storage_cell, tristate_cell, inv_cell, tapcell, max_tap_dist); } diff --git a/src/ram/src/ram.tcl b/src/ram/src/ram.tcl index 5d09828a9a5..619c21b0d5a 100644 --- a/src/ram/src/ram.tcl +++ b/src/ram/src/ram.tcl @@ -3,6 +3,7 @@ sta::define_cmd_args "generate_ram_netlist" {-bytes_per_word bits -word_count words + [-mux_col_ratio ratio] [-storage_cell name] [-tristate_cell name] [-inv_cell name] @@ -12,8 +13,8 @@ sta::define_cmd_args "generate_ram_netlist" {-bytes_per_word bits proc generate_ram_netlist { args } { sta::parse_key_args "generate_ram_netlist" args \ - keys { -bytes_per_word -word_count -storage_cell -tristate_cell -inv_cell - -read_ports -tapcell -max_tap_dist } flags {} + keys { -bytes_per_word -word_count -mux_col_ratio -storage_cell + -tristate_cell -inv_cell -read_ports -tapcell -max_tap_dist } flags {} if { [info exists keys(-bytes_per_word)] } { set bytes_per_word $keys(-bytes_per_word) @@ -27,6 +28,14 @@ proc generate_ram_netlist { args } { utl::error RAM 2 "The -word_count argument must be specified." } + set mux_col_ratio 1 + if { [info exists keys(-mux_col_ratio)] } { + set mux_col_ratio $keys(-mux_col_ratio) + if { $mux_col_ratio != 1 && $mux_col_ratio != 2 && $mux_col_ratio != 4 } { + utl::error RAM 29 "The -mux_col_ratio must be 1, 2, or 4." + } + } + set storage_cell "" if { [info exists keys(-storage_cell)] } { set storage_cell $keys(-storage_cell) @@ -62,12 +71,13 @@ proc generate_ram_netlist { args } { The generated layout may not pass Design Rule Checks." } - ram::generate_ram_netlist_cmd $bytes_per_word $word_count $storage_cell \ - $tristate_cell $inv_cell $read_ports $tapcell $max_tap_dist + ram::generate_ram_netlist_cmd $bytes_per_word $word_count $mux_col_ratio \ + $storage_cell $tristate_cell $inv_cell $read_ports $tapcell $max_tap_dist } sta::define_cmd_args "generate_ram" {-bytes_per_word bits -word_count words + [-mux_col_ratio ratio] [-read_ports count] [-storage_cell name] [-tristate_cell name] @@ -86,9 +96,10 @@ sta::define_cmd_args "generate_ram" {-bytes_per_word bits # user arguments for generate ram arguments proc generate_ram { args } { sta::parse_key_args "generate_ram" args \ - keys { -bytes_per_word -word_count -storage_cell -tristate_cell -inv_cell -read_ports - -power_pin -ground_pin -routing_layer -ver_layer -hor_layer -filler_cells - -tapcell -max_tap_dist -write_behavioral_verilog } flags {} + keys { -bytes_per_word -word_count -mux_col_ratio -storage_cell + -tristate_cell -inv_cell -read_ports -power_pin -ground_pin + -routing_layer -ver_layer -hor_layer -filler_cells + -tapcell -max_tap_dist -write_behavioral_verilog } flags {} sta::check_argc_eq0 "generate_ram" $args @@ -101,6 +112,10 @@ proc generate_ram { args } { -bytes_per_word $keys(-bytes_per_word) \ -word_count $keys(-word_count)] + if { [info exists keys(-mux_col_ratio)] } { + lappend ram_netlist_args -mux_col_ratio $keys(-mux_col_ratio) + } + if { [info exists keys(-read_ports)] } { lappend ram_netlist_args -read_ports $keys(-read_ports) } diff --git a/src/ram/test/make_8x8_mux2.tcl b/src/ram/test/make_8x8_mux2.tcl new file mode 100644 index 00000000000..9ba9f83c078 --- /dev/null +++ b/src/ram/test/make_8x8_mux2.tcl @@ -0,0 +1,37 @@ +source "helpers.tcl" + +set_thread_count [expr [cpu_count] / 4] + +read_liberty sky130hd/sky130_fd_sc_hd__tt_025C_1v80.lib + +read_lef sky130hd/sky130hd.tlef +read_lef sky130hd/sky130_fd_sc_hd_merged.lef + +set behavioral_file [make_result_file make_8x8_mux2_behavioral.v] + +generate_ram \ + -bytes_per_word 1 \ + -word_count 8 \ + -mux_col_ratio 2 \ + -read_ports 1 \ + -storage_cell sky130_fd_sc_hd__dfxtp_1 \ + -power_pin VPWR \ + -ground_pin VGND \ + -routing_layer {met1 0.48} \ + -ver_layer {met2 0.48 40} \ + -hor_layer {met3 0.48 20} \ + -filler_cells {sky130_fd_sc_hd__fill_1 sky130_fd_sc_hd__fill_2 \ + sky130_fd_sc_hd__fill_4 sky130_fd_sc_hd__fill_8} \ + -tapcell sky130_fd_sc_hd__tap_1 \ + -max_tap_dist 15 \ + -write_behavioral_verilog $behavioral_file + +set lef_file [make_result_file make_8x8_mux2.lef] +write_abstract_lef $lef_file +diff_files make_8x8_mux2.lefok $lef_file + +set def_file [make_result_file make_8x8_mux2.def] +write_def $def_file +diff_files make_8x8_mux2.defok $def_file + +diff_files make_8x8_mux2_behavioral.vok $behavioral_file diff --git a/src/ram/test/make_8x8_mux4.tcl b/src/ram/test/make_8x8_mux4.tcl new file mode 100644 index 00000000000..be98c4c387e --- /dev/null +++ b/src/ram/test/make_8x8_mux4.tcl @@ -0,0 +1,37 @@ +source "helpers.tcl" + +set_thread_count [expr [cpu_count] / 4] + +read_liberty sky130hd/sky130_fd_sc_hd__tt_025C_1v80.lib + +read_lef sky130hd/sky130hd.tlef +read_lef sky130hd/sky130_fd_sc_hd_merged.lef + +set behavioral_file [make_result_file make_8x8_mux4_behavioral.v] + +generate_ram \ + -bytes_per_word 1 \ + -word_count 8 \ + -mux_col_ratio 4 \ + -read_ports 1 \ + -storage_cell sky130_fd_sc_hd__dfxtp_1 \ + -power_pin VPWR \ + -ground_pin VGND \ + -routing_layer {met1 0.48} \ + -ver_layer {met2 0.48 40} \ + -hor_layer {met3 0.48 20} \ + -filler_cells {sky130_fd_sc_hd__fill_1 sky130_fd_sc_hd__fill_2 \ + sky130_fd_sc_hd__fill_4 sky130_fd_sc_hd__fill_8} \ + -tapcell sky130_fd_sc_hd__tap_1 \ + -max_tap_dist 15 \ + -write_behavioral_verilog $behavioral_file + +set lef_file [make_result_file make_8x8_mux4.lef] +write_abstract_lef $lef_file +diff_files make_8x8_mux4.lefok $lef_file + +set def_file [make_result_file make_8x8_mux4.def] +write_def $def_file +diff_files make_8x8_mux4.defok $def_file + +diff_files make_8x8_mux4_behavioral.vok $behavioral_file diff --git a/src/ram/test/regression_tests.tcl b/src/ram/test/regression_tests.tcl index e37ce75db9f..eab2e72ef8a 100644 --- a/src/ram/test/regression_tests.tcl +++ b/src/ram/test/regression_tests.tcl @@ -1,3 +1,5 @@ record_tests { make_8x8 + make_8x8_mux2 + make_8x8_mux4 } From ec7e9ee9b024884728dbb3aa729e6f5458faa306 Mon Sep 17 00:00:00 2001 From: Thinh Nguyen Date: Tue, 17 Mar 2026 13:56:31 -0400 Subject: [PATCH 2/7] add check to only search for aoi master when mux_col_ratio > 1 Signed-off-by: Thinh Nguyen --- src/ram/include/ram/ram.h | 2 +- src/ram/src/ram.cpp | 6 +++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/ram/include/ram/ram.h b/src/ram/include/ram/ram.h index 8c9bd9c1eba..0d1ea00114d 100644 --- a/src/ram/include/ram/ram.h +++ b/src/ram/include/ram/ram.h @@ -97,7 +97,7 @@ class RamGen int read_ports); private: - void findMasters(); + void findMasters(int mux_col_ratio); odb::dbMaster* findMaster(const std::function& match, const char* name); odb::dbNet* makeNet(const std::string& prefix, const std::string& name); diff --git a/src/ram/src/ram.cpp b/src/ram/src/ram.cpp index 25f447ea85f..b686ea4ce96 100644 --- a/src/ram/src/ram.cpp +++ b/src/ram/src/ram.cpp @@ -440,7 +440,7 @@ dbMaster* RamGen::findMaster( return best; } -void RamGen::findMasters() +void RamGen::findMasters(int mux_col_ratio) { if (!inv_cell_) { inv_cell_ = findMaster( @@ -505,7 +505,7 @@ void RamGen::findMasters() "buffer"); } - if (!aoi22_cell_) { + if (mux_col_ratio > 1 && !aoi22_cell_) { // AOI22: Y = NOT((A AND B) OR (C AND D)) // FuncExpr tree: not_ → or_ → [ and_(port, port), and_(port, port) ] aoi22_cell_ = findMaster( @@ -766,7 +766,7 @@ void RamGen::generate(const int bytes_per_word, aoi22_cell_ = nullptr; clock_gate_cell_ = nullptr; buffer_cell_ = nullptr; - findMasters(); + findMasters(mux_col_ratio); auto chip = db_->getChip(); if (!chip) { From 315d88aab7fdcb378063e351920efa1438634b4f Mon Sep 17 00:00:00 2001 From: Thinh Nguyen Date: Tue, 17 Mar 2026 14:22:31 -0400 Subject: [PATCH 3/7] Fix AOI22 FuncExpr matcher to handle SOP expanded form Signed-off-by: Thinh Nguyen --- src/ram/src/ram.cpp | 93 +++++++++++++++++++++++++++++++++------------ 1 file changed, 68 insertions(+), 25 deletions(-) diff --git a/src/ram/src/ram.cpp b/src/ram/src/ram.cpp index b686ea4ce96..3a99378b32c 100644 --- a/src/ram/src/ram.cpp +++ b/src/ram/src/ram.cpp @@ -506,47 +506,90 @@ void RamGen::findMasters(int mux_col_ratio) } if (mux_col_ratio > 1 && !aoi22_cell_) { - // AOI22: Y = NOT((A AND B) OR (C AND D)) - // FuncExpr tree: not_ → or_ → [ and_(port, port), and_(port, port) ] + // AOI22: Y = NOT((A1 AND A2) OR (B1 AND B2)) + // Libraries may express this in two forms: + // Compact: not_(or_(and_(port,port), and_(port,port))) + // SOP expanded (e.g. sky130hd): or_(or_(or_(and_(not_(port),not_(port)), + // and_(not_(port),not_(port))), and_(not_(port),not_(port))), + // and_(not_(port),not_(port))) + auto isNotPort = [](const sta::FuncExpr* e) { + return e && e->op() == sta::FuncExpr::Op::not_ && e->left() + && e->left()->op() == sta::FuncExpr::Op::port; + }; + auto isAndOfNots = [&isNotPort](const sta::FuncExpr* e) { + return e && e->op() == sta::FuncExpr::Op::and_ + && isNotPort(e->left()) && isNotPort(e->right()); + }; aoi22_cell_ = findMaster( - [](sta::LibertyPort* port) { + [&isNotPort, &isAndOfNots](sta::LibertyPort* port) { if (!port->direction()->isOutput()) { return false; } auto f = port->function(); - if (!f || f->op() != sta::FuncExpr::Op::not_) { - return false; + if (!f) return false; + // Compact form + if (f->op() == sta::FuncExpr::Op::not_) { + auto inner = f->left(); + if (!inner || inner->op() != sta::FuncExpr::Op::or_) return false; + auto L = inner->left(); + auto R = inner->right(); + return L && L->op() == sta::FuncExpr::Op::and_ + && L->left() + && L->left()->op() == sta::FuncExpr::Op::port + && L->right() + && L->right()->op() == sta::FuncExpr::Op::port + && R && R->op() == sta::FuncExpr::Op::and_ + && R->left() + && R->left()->op() == sta::FuncExpr::Op::port + && R->right() + && R->right()->op() == sta::FuncExpr::Op::port; } - auto inner = f->left(); - if (!inner || inner->op() != sta::FuncExpr::Op::or_) { - return false; + // SOP expanded form + if (f->op() == sta::FuncExpr::Op::or_) { + auto l1 = f->left(); + auto t4 = f->right(); + if (!isAndOfNots(t4) || !l1 + || l1->op() != sta::FuncExpr::Op::or_) + return false; + auto l2 = l1->left(); + auto t3 = l1->right(); + if (!isAndOfNots(t3) || !l2 + || l2->op() != sta::FuncExpr::Op::or_) + return false; + return isAndOfNots(l2->left()) && isAndOfNots(l2->right()); } - auto L = inner->left(); - auto R = inner->right(); - return L && L->op() == sta::FuncExpr::Op::and_ - && L->left() && L->left()->op() == sta::FuncExpr::Op::port - && L->right() && L->right()->op() == sta::FuncExpr::Op::port - && R && R->op() == sta::FuncExpr::Op::and_ - && R->left() && R->left()->op() == sta::FuncExpr::Op::port - && R->right() && R->right()->op() == sta::FuncExpr::Op::port; + return false; }, "aoi22"); - // Extract the actual port names from the liberty function tree so we can - // wire up the cell generically regardless of naming convention. + // Extract port names from the liberty function tree. auto cell = network_->libertyCell(network_->dbToSta(aoi22_cell_)); auto port_iter = cell->portIterator(); while (port_iter->hasNext()) { auto p = static_cast(port_iter->next()); if (p->direction()->isAnyOutput()) { auto f = p->libertyPort()->function(); - auto or_expr = f->left(); - auto and_a = or_expr->left(); - auto and_b = or_expr->right(); - aoi22_in_a1_ = and_a->left()->port()->name(); - aoi22_in_a2_ = and_a->right()->port()->name(); - aoi22_in_b1_ = and_b->left()->port()->name(); - aoi22_in_b2_ = and_b->right()->port()->name(); + if (f->op() == sta::FuncExpr::Op::not_) { + // Compact form: not_(or_(and_(A1,A2), and_(B1,B2))) + auto or_expr = f->left(); + auto and_a = or_expr->left(); + auto and_b = or_expr->right(); + aoi22_in_a1_ = and_a->left()->port()->name(); + aoi22_in_a2_ = and_a->right()->port()->name(); + aoi22_in_b1_ = and_b->left()->port()->name(); + aoi22_in_b2_ = and_b->right()->port()->name(); + } else { + // SOP form: or_(or_(or_(and_(not_(A1),not_(B1)), + // and_(not_(A1),not_(B2))), and_(not_(A2),not_(B1))), + // and_(not_(A2),not_(B2))) + auto t1 = f->left()->left()->left(); + auto t2 = f->left()->left()->right(); + auto t3 = f->left()->right(); + aoi22_in_a1_ = t1->left()->left()->port()->name(); + aoi22_in_a2_ = t3->left()->left()->port()->name(); + aoi22_in_b1_ = t1->right()->left()->port()->name(); + aoi22_in_b2_ = t2->right()->left()->port()->name(); + } aoi22_out_ = p->name(); break; } From cb55753c09409dec0ef91e72b57b5b5c0d604235 Mon Sep 17 00:00:00 2001 From: Thinh Nguyen Date: Thu, 26 Mar 2026 12:40:06 -0400 Subject: [PATCH 4/7] ram: add PDN strap pitch vs die size error check to prevent segfault Signed-off-by: Thinh Nguyen --- src/ram/src/ram.cpp | 24 ++++++++++++++++---- src/ram/test/make_8x8_mux2.tcl | 37 ------------------------------- src/ram/test/make_8x8_mux4.tcl | 37 ------------------------------- src/ram/test/regression_tests.tcl | 4 ++-- 4 files changed, 22 insertions(+), 80 deletions(-) delete mode 100644 src/ram/test/make_8x8_mux2.tcl delete mode 100644 src/ram/test/make_8x8_mux4.tcl diff --git a/src/ram/src/ram.cpp b/src/ram/src/ram.cpp index 3a99378b32c..6208a858b1e 100644 --- a/src/ram/src/ram.cpp +++ b/src/ram/src/ram.cpp @@ -236,7 +236,7 @@ std::unique_ptr RamGen::makeColMux( auto mux_cell = std::make_unique(); for (int bit = 0; bit < 8; ++bit) { - auto aoi_lo_net = makeNet(prefix, fmt::format("aoi_lo_bit{}", bit)); + auto aoi_lo_net = dbNet::create(block_, fmt::format("{}_aoi_lo_bit{}", prefix, bit).c_str()); auto inv_in_net = aoi_lo_net; // default for mux=2; overridden for mux=4 // First AOI22: NOT((col_sel[0] & col_q[0]) | (col_sel[1] & col_q[1])) @@ -252,7 +252,7 @@ std::unique_ptr RamGen::makeColMux( if (mux_col_ratio == 4) { // Second AOI22: NOT((col_sel[2] & col_q[2]) | (col_sel[3] & col_q[3])) - auto aoi_hi_net = makeNet(prefix, fmt::format("aoi_hi_bit{}", bit)); + auto aoi_hi_net = dbNet::create(block_, fmt::format("{}_aoi_hi_bit{}", prefix, bit).c_str()); makeCellInst(mux_cell.get(), prefix, fmt::format("aoi_hi_bit{}", bit), @@ -266,7 +266,7 @@ std::unique_ptr RamGen::makeColMux( // AND2(aoi_lo, aoi_hi): De Morgan gives us the OR of all four AND terms // NOT(aoi_lo AND aoi_hi) = (cs0&q0|cs1&q1) OR (cs2&q2|cs3&q3) // so we still need to invert — use AND2 then INV below. - auto and_net = makeNet(prefix, fmt::format("mux_and_bit{}", bit)); + auto and_net = dbNet::create(block_, fmt::format("{}_aoi_bit{}", prefix, bit).c_str()); makeCellInst(mux_cell.get(), prefix, fmt::format("mux_and_bit{}", bit), @@ -609,6 +609,22 @@ void RamGen::ramPdngen(const char* power_pin, int hor_width, int hor_pitch) { + + // check for die size vs pitch to avoid pdngen segmentation fault errors + const odb::Rect& die = block_->getDieArea(); + if (die.dy() < hor_pitch) { + logger_->error(RAM, 31, + "Die height ({} DBU) is less than horizontal strap pitch ({} DBU). " + "Use a smaller -hor_layer pitch.", + die.dy(), hor_pitch); + } + if (die.dx() < ver_pitch) { + logger_->error(RAM, 32, + "Die width ({} DBU) is less than vertical strap pitch ({} DBU). " + "Use a smaller -ver_layer pitch.", + die.dx(), ver_pitch); + } + // need parameters for power and ground nets auto power_net = dbNet::create(block_, "VDD"); auto ground_net = dbNet::create(block_, "VSS"); @@ -843,7 +859,7 @@ void RamGen::generate(const int bytes_per_word, for (int i = 0; i < num_inputs; ++i) { addr_inputs_.push_back( - makeBTerm(fmt::format("addr[{}]", i), dbIoType::INPUT)); + makeBTerm(fmt::format("addr_rw[{}]", i), dbIoType::INPUT)); } // Inverted address nets (one per address bit, covers all bits) diff --git a/src/ram/test/make_8x8_mux2.tcl b/src/ram/test/make_8x8_mux2.tcl deleted file mode 100644 index 9ba9f83c078..00000000000 --- a/src/ram/test/make_8x8_mux2.tcl +++ /dev/null @@ -1,37 +0,0 @@ -source "helpers.tcl" - -set_thread_count [expr [cpu_count] / 4] - -read_liberty sky130hd/sky130_fd_sc_hd__tt_025C_1v80.lib - -read_lef sky130hd/sky130hd.tlef -read_lef sky130hd/sky130_fd_sc_hd_merged.lef - -set behavioral_file [make_result_file make_8x8_mux2_behavioral.v] - -generate_ram \ - -bytes_per_word 1 \ - -word_count 8 \ - -mux_col_ratio 2 \ - -read_ports 1 \ - -storage_cell sky130_fd_sc_hd__dfxtp_1 \ - -power_pin VPWR \ - -ground_pin VGND \ - -routing_layer {met1 0.48} \ - -ver_layer {met2 0.48 40} \ - -hor_layer {met3 0.48 20} \ - -filler_cells {sky130_fd_sc_hd__fill_1 sky130_fd_sc_hd__fill_2 \ - sky130_fd_sc_hd__fill_4 sky130_fd_sc_hd__fill_8} \ - -tapcell sky130_fd_sc_hd__tap_1 \ - -max_tap_dist 15 \ - -write_behavioral_verilog $behavioral_file - -set lef_file [make_result_file make_8x8_mux2.lef] -write_abstract_lef $lef_file -diff_files make_8x8_mux2.lefok $lef_file - -set def_file [make_result_file make_8x8_mux2.def] -write_def $def_file -diff_files make_8x8_mux2.defok $def_file - -diff_files make_8x8_mux2_behavioral.vok $behavioral_file diff --git a/src/ram/test/make_8x8_mux4.tcl b/src/ram/test/make_8x8_mux4.tcl deleted file mode 100644 index be98c4c387e..00000000000 --- a/src/ram/test/make_8x8_mux4.tcl +++ /dev/null @@ -1,37 +0,0 @@ -source "helpers.tcl" - -set_thread_count [expr [cpu_count] / 4] - -read_liberty sky130hd/sky130_fd_sc_hd__tt_025C_1v80.lib - -read_lef sky130hd/sky130hd.tlef -read_lef sky130hd/sky130_fd_sc_hd_merged.lef - -set behavioral_file [make_result_file make_8x8_mux4_behavioral.v] - -generate_ram \ - -bytes_per_word 1 \ - -word_count 8 \ - -mux_col_ratio 4 \ - -read_ports 1 \ - -storage_cell sky130_fd_sc_hd__dfxtp_1 \ - -power_pin VPWR \ - -ground_pin VGND \ - -routing_layer {met1 0.48} \ - -ver_layer {met2 0.48 40} \ - -hor_layer {met3 0.48 20} \ - -filler_cells {sky130_fd_sc_hd__fill_1 sky130_fd_sc_hd__fill_2 \ - sky130_fd_sc_hd__fill_4 sky130_fd_sc_hd__fill_8} \ - -tapcell sky130_fd_sc_hd__tap_1 \ - -max_tap_dist 15 \ - -write_behavioral_verilog $behavioral_file - -set lef_file [make_result_file make_8x8_mux4.lef] -write_abstract_lef $lef_file -diff_files make_8x8_mux4.lefok $lef_file - -set def_file [make_result_file make_8x8_mux4.def] -write_def $def_file -diff_files make_8x8_mux4.defok $def_file - -diff_files make_8x8_mux4_behavioral.vok $behavioral_file diff --git a/src/ram/test/regression_tests.tcl b/src/ram/test/regression_tests.tcl index eab2e72ef8a..8a7c361fe17 100644 --- a/src/ram/test/regression_tests.tcl +++ b/src/ram/test/regression_tests.tcl @@ -1,5 +1,5 @@ record_tests { make_8x8 - make_8x8_mux2 - make_8x8_mux4 + make_16x8_mux2 + make_32x8_mux4 } From cfefab101248d026c814d6715a0649395c6e926f Mon Sep 17 00:00:00 2001 From: Thinh Nguyen Date: Fri, 27 Mar 2026 16:24:48 -0400 Subject: [PATCH 5/7] add code to make mux for col/mux featureand findMaster function for AOI22 Signed-off-by: Thinh Nguyen --- src/ram/include/ram/ram.h | 12 +++ src/ram/src/ram.cpp | 178 ++++++++++++++++++++++++++++++++++++++ 2 files changed, 190 insertions(+) diff --git a/src/ram/include/ram/ram.h b/src/ram/include/ram/ram.h index f75acf44526..d2f14a45fb8 100644 --- a/src/ram/include/ram/ram.h +++ b/src/ram/include/ram/ram.h @@ -66,6 +66,7 @@ class RamGen void generate(int mask_size, int word_size, int num_words, + int column_mux_ratio, int read_ports, odb::dbMaster* storage_cell, odb::dbMaster* tristate_cell, @@ -137,6 +138,14 @@ class RamGen const std::vector& data_input, const std::vector>& data_output); + std::unique_ptr makeColMux( + const std::string& prefix, + int column_mux_ratio, + int mask_size, + const std::vector>& col_q_nets, + const std::vector& col_sel_nets, + const std::vector& q_out_nets); + odb::dbBTerm* makeBTerm(const std::string& name, odb::dbIoType io_type); std::unique_ptr generateTapColumn(int word_count, int tapcell_col); @@ -166,12 +175,15 @@ class RamGen odb::dbMaster* and2_cell_{nullptr}; odb::dbMaster* clock_gate_cell_{nullptr}; odb::dbMaster* buffer_cell_{nullptr}; + odb::dbMaster* aoi22_cell_{nullptr}; odb::dbMaster* tapcell_{nullptr}; std::vector addr_inputs_; std::vector data_inputs_; std::vector> q_outputs_; std::string behavioral_verilog_filename_; + std::string aoi22_in_a1_, aoi22_in_a2_, aoi22_in_b1_, aoi22_in_b2_, + aoi22_out_; Grid ram_grid_; }; diff --git a/src/ram/src/ram.cpp b/src/ram/src/ram.cpp index e63ec076a2a..21eca7dd1e0 100644 --- a/src/ram/src/ram.cpp +++ b/src/ram/src/ram.cpp @@ -236,6 +236,90 @@ void RamGen::makeWord(const int slices_per_word, } } +// mux made out of AOI22 cells used for col/mux feature. currently support only +// even mux ratios (1,2,4,8) +std::unique_ptr RamGen::makeColMux( + const std::string& prefix, + const int column_mux_ratio, + const int mask_size, + const vector>& col_q_nets, + const vector& col_sel_nets, + const vector& q_out_nets) +{ + auto mux_cell = std::make_unique(); + const int num_stages = static_cast(std::log2(column_mux_ratio)); + const bool need_final_inv = (num_stages % 2 == 1); + + for (int bit = 0; bit < mask_size; ++bit) { + // Stage 1: one AOI22 per pair of sub columns determined by column_mux_ratio + // value using select signal S0 with output polarity: inverted (~mux) + int num_pairs = column_mux_ratio / 2; + vector prev_nets(num_pairs); + + for (int i = 0; i < num_pairs; ++i) { + // for ratio=2 with no INV needed (num_stages=1 is odd so + // need_final_inv=true), stage 1 output always goes to intermediate wire, + // never directly to Q here + prev_nets[i] = dbNet::create( + block_, fmt::format("{}_aoi_s1_g{}_bit{}", prefix, i, bit).c_str()); + makeInst(mux_cell.get(), + prefix, + fmt::format("aoi_s1_g{}_bit{}", i, bit), + aoi22_cell_, + {{aoi22_in_a1_, col_sel_nets[0]}, + {aoi22_in_a2_, col_q_nets[i * 2][bit]}, + {aoi22_in_b1_, col_sel_nets[1]}, + {aoi22_in_b2_, col_q_nets[i * 2 + 1][bit]}, + {aoi22_out_, prev_nets[i]}}); + } + + // Stages 2 to N: each stage halves the number of signals + // sel index increases by 2 per stage (~Sn at sel_idx, Sn at sel_idx+1) + for (int stage = 1; stage < num_stages; ++stage) { + int num_out = static_cast(prev_nets.size()) / 2; + vector curr_nets(num_out); + int sel_idx = stage * 2; + bool is_last_stage = (stage == num_stages - 1); + for (int i = 0; i < num_out; ++i) { + // if this is the last stage and no INV needed, drive Q directly + // to avoid adding an unnecessary buffer gate + if (is_last_stage && !needs_final_inv) { + curr_nets[i] = q_out_nets[bit]; + } else { + curr_nets[i] = dbNet::create( + block_, + fmt::format("{}_aoi_s{}_g{}_bit{}", prefix, stage + 1, i, bit) + .c_str()); + } + makeInst(mux_cell.get(), + prefix, + fmt::format("aoi_s{}_g{}_bit{}", stage + 1, i, bit), + aoi22_cell_, + {{aoi22_in_a1_, col_sel_nets[sel_idx]}, + {aoi22_in_a2_, prev_nets[i * 2]}, + {aoi22_in_b1_, col_sel_nets[sel_idx + 1]}, + {aoi22_in_b2_, prev_nets[i * 2 + 1]}, + {aoi22_out_, curr_nets[i]}}); + } + prev_nets = curr_nets; + } + + // Final stage/output: + // "odd" stages (ratio = 2,8 meaning num_stages = 1,3): output inverted, add + // inverter "even" stages (ratio = 4 meaning num_stages = 2): Q driven + // directly by last AOI22 output, no inverter needed + if (need_final_inv) { + makeInst(mux_cell.get(), + prefix, + fmt::format("mux_inv_bit{}", bit), + inv_cell_, + {{"A", prev_nets[0]}, {"Y", q_out_nets[bit]}}); + } + } + + return mux_cell; +} + std::unique_ptr RamGen::generateTapColumn(const int num_words, const int tapcell_col) { @@ -452,6 +536,99 @@ void RamGen::findMasters() [](sta::LibertyPort* port) { return port->libertyCell()->isBuffer(); }, "buffer"); } + + // aoi cells used for column mux functionality when column_mux_ratio > 1 + if (!aoi22_cell_) { + auto isNotPort = [](const sta::FuncExpr* e) { + return e && e->op() == sta::FuncExpr::Op::not_ && e->left() + && e->left()->op() == sta::FuncExpr::Op::port; + }; + auto isAndOfNots = [&isNotPort](const sta::FuncExpr* e) { + return e && e->op() == sta::FuncExpr::Op::and_ && isNotPort(e->left()) + && isNotPort(e->right()); + }; + aoi22_cell_ = findMaster( + [&isNotPort, &isAndOfNots](sta::LibertyPort* port) { + if (!port->direction()->isOutput()) { + return false; + } + auto f = port->function(); + if (!f) { + return false; + } + if (f->op() == sta::FuncExpr::Op::not_) { + auto inner = f->left(); + if (!inner || inner->op() != sta::FuncExpr::Op::or_) { + return false; + } + auto L = inner->left(); + auto R = inner->right(); + return L && L->op() == sta::FuncExpr::Op::and_ && L->left() + && L->left()->op() == sta::FuncExpr::Op::port && L->right() + && L->right()->op() == sta::FuncExpr::Op::port && R + && R->op() == sta::FuncExpr::Op::and_ && R->left() + && R->left()->op() == sta::FuncExpr::Op::port && R->right() + && R->right()->op() == sta::FuncExpr::Op::port; + } + if (f->op() == sta::FuncExpr::Op::or_) { + auto l1 = f->left(); + auto t4 = f->right(); + if (!isAndOfNots(t4) || !l1 || l1->op() != sta::FuncExpr::Op::or_) { + return false; + } + auto l2 = l1->left(); + auto t3 = l1->right(); + if (!isAndOfNots(t3) || !l2 || l2->op() != sta::FuncExpr::Op::or_) { + return false; + } + return isAndOfNots(l2->left()) && isAndOfNots(l2->right()); + } + return false; + }, + "aoi22"); + + // extract port names from the liberty function tree + auto cell = network_->libertyCell(network_->dbToSta(aoi22_cell_)); + auto port_iter = cell->portIterator(); + while (port_iter->hasNext()) { + auto p = static_cast(port_iter->next()); + if (p->direction()->isAnyOutput()) { + auto f = p->libertyPort()->function(); + if (f->op() == sta::FuncExpr::Op::not_) { + // Compact form: not_(or_(and_(A1,A2), and_(B1,B2))) + auto or_expr = f->left(); + auto and_a = or_expr->left(); + auto and_b = or_expr->right(); + aoi22_in_a1_ = and_a->left()->port()->name(); + aoi22_in_a2_ = and_a->right()->port()->name(); + aoi22_in_b1_ = and_b->left()->port()->name(); + aoi22_in_b2_ = and_b->right()->port()->name(); + } else { + // SOP expanded form used by sky130hd: + // or_(or_(or_(and_(not_(A1),not_(B1)), and_(not_(A1),not_(B2))), + // and_(not_(A2),not_(B1))), + // and_(not_(A2),not_(B2))) + // Port names are inside not_() wrappers, requiring an extra + // ->left() to reach the actual port compared to the compact form. + // e.g. and_(not_(A1), not_(B1))->left()->left()->port() gives A1 + // NOTE: this branch is PDK-specific to sky130hd's liberty + // representation. If adding support for other PDKs, verify their + // AOI22 function expression form and extend this extraction + // accordingly. + auto t1 = f->left()->left()->left(); + auto t2 = f->left()->left()->right(); + auto t3 = f->left()->right(); + aoi22_in_a1_ = t1->left()->left()->port()->name(); + aoi22_in_a2_ = t3->left()->left()->port()->name(); + aoi22_in_b1_ = t1->right()->left()->port()->name(); + aoi22_in_b2_ = t2->right()->left()->port()->name(); + } + aoi22_out_ = p->name(); + break; + } + } + delete port_iter; + } } void RamGen::ramPdngen(const char* power_pin, @@ -636,6 +813,7 @@ void RamGen::generate(const int mask_size, and2_cell_ = nullptr; clock_gate_cell_ = nullptr; buffer_cell_ = nullptr; + aoi22_cell_ = nullptr; findMasters(); auto chip = db_->getChip(); From 1268bd1e85d5779505876072c9bf4a4920d1208e Mon Sep 17 00:00:00 2001 From: Thinh Nguyen Date: Mon, 30 Mar 2026 10:47:47 -0400 Subject: [PATCH 6/7] add column_mux_ratio support Signed-off-by: Thinh Nguyen --- src/ram/include/ram/ram.h | 16 +- src/ram/src/ram.cpp | 386 +++++++++++++++++++++++++++----------- src/ram/src/ram.i | 3 +- src/ram/src/ram.tcl | 17 +- 4 files changed, 304 insertions(+), 118 deletions(-) diff --git a/src/ram/include/ram/ram.h b/src/ram/include/ram/ram.h index d2f14a45fb8..2e950f8ce82 100644 --- a/src/ram/include/ram/ram.h +++ b/src/ram/include/ram/ram.h @@ -121,30 +121,34 @@ class RamGen void makeSlice(int slice_idx, int mask_size, int row_idx, + int word_idx, int read_ports, + int column_mux_ratio, odb::dbNet* clock, odb::dbNet* write_enable, const std::vector& selects, const std::vector& data_input, - const std::vector>& data_output); + const std::vector>& data_output); void makeWord(int slices_per_word, int mask_size, int row_idx, + int word_idx, int read_ports, + int column_mux_ratio, odb::dbNet* clock, + odb::dbNet* word_select, std::vector& write_enable, const std::vector& selects, const std::vector& data_input, - const std::vector>& data_output); + const std::vector>& data_output); std::unique_ptr makeColMux( const std::string& prefix, int column_mux_ratio, - int mask_size, - const std::vector>& col_q_nets, - const std::vector& col_sel_nets, - const std::vector& q_out_nets); + const std::vector& word_q_nets, + const std::vector& word_sel_nets, + odb::dbNet* q_out_net); odb::dbBTerm* makeBTerm(const std::string& name, odb::dbIoType io_type); diff --git a/src/ram/src/ram.cpp b/src/ram/src/ram.cpp index 21eca7dd1e0..c7a942c4b0a 100644 --- a/src/ram/src/ram.cpp +++ b/src/ram/src/ram.cpp @@ -140,12 +140,15 @@ std::unique_ptr RamGen::makeBit(const std::string& prefix, void RamGen::makeSlice(const int slice_idx, const int mask_size, const int row_idx, + const int word_idx, const int read_ports, + const int column_mux_ratio, dbNet* clock, dbNet* write_enable, + dbNet* word_select, const vector& selects, const vector& data_input, - const vector>& data_output) + const vector>& data_output) { const int start_bit_idx = slice_idx * mask_size; std::string prefix = fmt::format("storage_{}_{}", row_idx, start_bit_idx); @@ -161,15 +164,18 @@ void RamGen::makeSlice(const int slice_idx, auto name = fmt::format("{}.bit{}", prefix, start_bit_idx + local_bit); vector outs(read_ports); for (int read_port = 0; read_port < read_ports; ++read_port) { - outs[read_port] = data_output[read_port][local_bit]->getNet(); + outs[read_port] = data_output[read_port][local_bit]; } + + int bit_col = slice_idx * (mask_size * column_mux_ratio + column_mux_ratio) + + local_bit * column_mux_ratio + word_idx; ram_grid_.addCell(makeBit(name, read_ports, gclock_net, select_b_nets, data_input[local_bit], outs), - start_bit_idx + local_bit + slice_idx); + bit_col); } auto sel_cell = std::make_unique(); @@ -180,6 +186,19 @@ void RamGen::makeSlice(const int slice_idx, clock_gate_cell_, {{"CLK", clock}, {"GATE", we0_net}, {"GCLK", gclock_net}}); + // Write path: this net is row_select AND with word_select so clock gate only + // fires for the addressed word within the row. Read path handled by AOI mux. + // word_select is nullptr when column_mux_ratio=1 (no mux needed). + dbNet* write_sel = selects[0]; + if (word_select) { + write_sel = makeNet(prefix, "write_sel"); + makeInst(sel_cell.get(), + prefix, + "word_and", + and2_cell_, + {{"A", selects[0]}, {"B", word_select}, {"X", write_sel}}); + } + // Make clock and // this AND gate needs to be fed a net created by a decoder // adding any net will automatically connect with any port @@ -187,7 +206,7 @@ void RamGen::makeSlice(const int slice_idx, prefix, "gcand", and2_cell_, - {{"A", selects[0]}, {"B", write_enable}, {"X", we0_net}}); + {{"A", write_sel}, {"B", write_enable}, {"X", we0_net}}); // Make select inverters for (int i = 0; i < selects.size(); ++i) { @@ -197,26 +216,30 @@ void RamGen::makeSlice(const int slice_idx, inv_cell_, {{"A", selects[i]}, {"Y", select_b_nets[i]}}); } - - ram_grid_.addCell(std::move(sel_cell), start_bit_idx + mask_size + slice_idx); + int sel_col = slice_idx * (mask_size * column_mux_ratio + column_mux_ratio) + + mask_size * column_mux_ratio + word_idx; + ram_grid_.addCell(std::move(sel_cell), sel_col); } void RamGen::makeWord(const int slices_per_word, const int mask_size, const int row_idx, + const int word_idx, const int read_ports, + const int column_mux_ratio, dbNet* clock, + dbNet* word_select, vector& write_enable, const vector& selects, const vector& data_input, - const vector>& data_output) + const vector>& data_output) { for (int slice = 0; slice < slices_per_word; ++slice) { int start_idx = slice * mask_size; vector slice_inputs(data_input.begin() + start_idx, data_input.begin() + start_idx + mask_size); - std::vector> slice_outputs; + std::vector> slice_outputs; slice_outputs.reserve(read_ports); for (int port = 0; port < read_ports; ++port) { const auto& port_outputs = data_output[port]; @@ -227,9 +250,12 @@ void RamGen::makeWord(const int slices_per_word, makeSlice(slice, mask_size, row_idx, + word_idx, read_ports, + column_mux_ratio, clock, write_enable[slice]->getNet(), + word_select, selects, slice_inputs, slice_outputs); @@ -237,84 +263,86 @@ void RamGen::makeWord(const int slices_per_word, } // mux made out of AOI22 cells used for col/mux feature. currently support only -// even mux ratios (1,2,4,8) -std::unique_ptr RamGen::makeColMux( - const std::string& prefix, - const int column_mux_ratio, - const int mask_size, - const vector>& col_q_nets, - const vector& col_sel_nets, - const vector& q_out_nets) +// col_mux_ratio = 1,2,4 NOTE: ratio =1 mean no muxing so this function is not +// called in that case called once per bit by generate(), it will mux between +// every corresponding pair of bits of column_mux_ratio words +std::unique_ptr RamGen::makeColMux(const std::string& prefix, + const int column_mux_ratio, + const vector& word_q_nets, + const vector& word_sel_nets, + dbNet* q_out_net) { + // NOTE: word_sel_nets must be in strict alternating 'ascending' order of + // select signal i.e. [S0', S0, S1', S1, S2', S2, etc] auto mux_cell = std::make_unique(); const int num_stages = static_cast(std::log2(column_mux_ratio)); const bool need_final_inv = (num_stages % 2 == 1); - for (int bit = 0; bit < mask_size; ++bit) { - // Stage 1: one AOI22 per pair of sub columns determined by column_mux_ratio - // value using select signal S0 with output polarity: inverted (~mux) - int num_pairs = column_mux_ratio / 2; - vector prev_nets(num_pairs); - - for (int i = 0; i < num_pairs; ++i) { - // for ratio=2 with no INV needed (num_stages=1 is odd so - // need_final_inv=true), stage 1 output always goes to intermediate wire, - // never directly to Q here - prev_nets[i] = dbNet::create( - block_, fmt::format("{}_aoi_s1_g{}_bit{}", prefix, i, bit).c_str()); - makeInst(mux_cell.get(), - prefix, - fmt::format("aoi_s1_g{}_bit{}", i, bit), - aoi22_cell_, - {{aoi22_in_a1_, col_sel_nets[0]}, - {aoi22_in_a2_, col_q_nets[i * 2][bit]}, - {aoi22_in_b1_, col_sel_nets[1]}, - {aoi22_in_b2_, col_q_nets[i * 2 + 1][bit]}, - {aoi22_out_, prev_nets[i]}}); - } + // Stage 1: one AOI22 per pair of word bits determined by column_mux_ratio + int num_pairs = column_mux_ratio / 2; + vector prev_nets(num_pairs); + + for (int i = 0; i < num_pairs; ++i) { + prev_nets[i] = dbNet::create( + block_, fmt::format("{}_aoi_s1_g{}", prefix, i).c_str()); + + // AOI boolean function: Y = (S0'I0 + S0I1)' = AOI22(S0', I0, S0, I1) + // AOI has inverted output so need an inverter if num_stage is odd + makeInst( + mux_cell.get(), + prefix, + fmt::format("aoi_s1_g{}", i), + aoi22_cell_, + {{aoi22_in_a1_, word_sel_nets[0]}, // S0' + {aoi22_in_a2_, word_q_nets[i * 2]}, // I0 = bit from word i*2 + {aoi22_in_b1_, word_sel_nets[1]}, // S0 + {aoi22_in_b2_, word_q_nets[i * 2 + 1]}, // I1 = bit from word i*2+1 + {aoi22_out_, prev_nets[i]}}); // output to next stage + } - // Stages 2 to N: each stage halves the number of signals - // sel index increases by 2 per stage (~Sn at sel_idx, Sn at sel_idx+1) - for (int stage = 1; stage < num_stages; ++stage) { - int num_out = static_cast(prev_nets.size()) / 2; - vector curr_nets(num_out); - int sel_idx = stage * 2; - bool is_last_stage = (stage == num_stages - 1); - for (int i = 0; i < num_out; ++i) { - // if this is the last stage and no INV needed, drive Q directly - // to avoid adding an unnecessary buffer gate - if (is_last_stage && !needs_final_inv) { - curr_nets[i] = q_out_nets[bit]; - } else { - curr_nets[i] = dbNet::create( - block_, - fmt::format("{}_aoi_s{}_g{}_bit{}", prefix, stage + 1, i, bit) - .c_str()); - } - makeInst(mux_cell.get(), - prefix, - fmt::format("aoi_s{}_g{}_bit{}", stage + 1, i, bit), - aoi22_cell_, - {{aoi22_in_a1_, col_sel_nets[sel_idx]}, - {aoi22_in_a2_, prev_nets[i * 2]}, - {aoi22_in_b1_, col_sel_nets[sel_idx + 1]}, - {aoi22_in_b2_, prev_nets[i * 2 + 1]}, - {aoi22_out_, curr_nets[i]}}); + // Stages 2 to N: each stage halves the number of signals + // sel index increases by 2 per stage (Sn' at sel_idx, Sn at sel_idx+1) + for (int stage = 1; stage < num_stages; ++stage) { + int num_out = static_cast(prev_nets.size()) / 2; + vector curr_nets(num_out); + int sel_idx = stage * 2; + bool is_last_stage = (stage == num_stages - 1); + + for (int i = 0; i < num_out; ++i) { + // if this is the last stage and no INV needed, drive Q directly + // else create intermediate net for next stage or for final inverter + if (is_last_stage && !need_final_inv) { + curr_nets[i] = q_out_net; + } else { + curr_nets[i] = dbNet::create( + block_, + fmt::format("{}_aoi_s{}_g{}", prefix, stage + 1, i).c_str()); } - prev_nets = curr_nets; - } - // Final stage/output: - // "odd" stages (ratio = 2,8 meaning num_stages = 1,3): output inverted, add - // inverter "even" stages (ratio = 4 meaning num_stages = 2): Q driven - // directly by last AOI22 output, no inverter needed - if (need_final_inv) { makeInst(mux_cell.get(), prefix, - fmt::format("mux_inv_bit{}", bit), - inv_cell_, - {{"A", prev_nets[0]}, {"Y", q_out_nets[bit]}}); + fmt::format("aoi_s{}_g{}", stage + 1, i), + aoi22_cell_, + {{aoi22_in_a1_, word_sel_nets[sel_idx]}, + {aoi22_in_a2_, prev_nets[i * 2]}, + {aoi22_in_b1_, word_sel_nets[sel_idx + 1]}, + {aoi22_in_b2_, prev_nets[i * 2 + 1]}, + {aoi22_out_, curr_nets[i]}}); } + prev_nets = curr_nets; // output net of current stage becomes input net of + // next stage + } + + // Final stage/output: + // If "odd" stages (ratio = 2,8 meaning num_stages = 1,3): output inverted, + // add inverter If "even" stages (ratio = 4 meaning num_stages = 2): Q driven + // directly by last AOI22 output, no inverter needed + if (need_final_inv) { + makeInst(mux_cell.get(), + prefix, + "mux_inv", + inv_cell_, + {{"A", prev_nets[0]}, {"Y", q_out_net}}); } return mux_cell; @@ -786,6 +814,7 @@ void RamGen::ramRouting(int thread_count) void RamGen::generate(const int mask_size, const int word_size, const int num_words, + const int column_mux_ratio, const int read_ports, dbMaster* storage_cell, dbMaster* tristate_cell, @@ -804,6 +833,33 @@ void RamGen::generate(const int mask_size, return; } + // error checking for column_mux_ratio + if (column_mux_ratio != 1 && column_mux_ratio != 2 && column_mux_ratio != 4) { + logger_->error(RAM, + 33, + "The ram generator currently only supports column_mux_ratio " + "values of 1, 2, or 4."); + } + + if (num_words % column_mux_ratio != 0) { + logger_->error(RAM, + 34, + "num_words ({}) must be divisible by column_mux_ratio ({}).", + num_words, + column_mux_ratio); + } + + int num_inputs = std::ceil(std::log2(num_words)); + // compute information to support col/mux ratio feature + int num_rows = num_words / column_mux_ratio; + // if column mux ratio > 1, then the lower log2(column_mux_ratio) bits are + // used to select the word within a row + int num_word_bits = (column_mux_ratio > 1) + ? static_cast(std::log2(column_mux_ratio)) + : 0; + // the remaining upper bits are used to select the row + int num_row_bits = num_inputs - num_word_bits; + logger_->info(RAM, 3, "Generating {}", ram_name); storage_cell_ = storage_cell; @@ -827,9 +883,13 @@ void RamGen::generate(const int mask_size, block_ = odb::dbBlock::create(chip, ram_name.c_str()); } - // One column per bit plus one select/control column per slice, - // plus one extra decoder column. - int col_cell_count = slices_per_word * (mask_size + 1); + // With column_mux_ratio = 1: One column per bit plus one select/control + // column per slice, plus one extra decoder column With column_mux_ratio > 1: + // Each slice has (mask_size * column_mux_ratio) columns (one per bit per word + // in the row), plus one select/control column per slice (one per word), plus + // one extra decoder column at far right shared across all row + int col_cell_count + = slices_per_word * (mask_size * column_mux_ratio + column_mux_ratio); ram_grid_.setNumLayouts(col_cell_count + 1); auto clock = makeBTerm("clk", dbIoType::INPUT); @@ -841,7 +901,6 @@ void RamGen::generate(const int mask_size, } // input bterms - int num_inputs = std::ceil(std::log2(num_words)); for (int i = 0; i < num_inputs; ++i) { addr_inputs_.push_back( makeBTerm(fmt::format("addr[{}]", i), dbIoType::INPUT)); @@ -853,20 +912,69 @@ void RamGen::generate(const int mask_size, inv_addr[i] = makeNet("inv", fmt::format("addr[{}]", i)); } + // word select nets: one per word_idx (word within a row) shared between all + // rows, derived from lower num_word_bits of address inputs used to determine + // word selection within a row for column muxing. word_sel_nets[word_idx] = + // HIGH when this word_idx is addressed. word_idx starts at 0 for the leftmost + // bit of the row, i.e. word 3 on row 1 with column_mux_ratio =2 will have + // word_idx = 1 nullptr for all entries when column_mux_ratio = 1 (no column + // muxing) + vector word_sel_nets(column_mux_ratio, nullptr); + + if (column_mux_ratio == 2) { + word_sel_nets[0] = inv_addr[0]; + word_sel_nets[1] = addr_inputs_[0]->getNet(); + } else if (column_mux_ratio == 4) { + auto word_sel_cell = std::make_unique(); + for (int c = 0; c < 4; ++c) { + word_sel_nets[c] = makeNet("word_sel", fmt::format("{}", c)); + } + makeInst(word_sel_cell.get(), + "word_sel", + "and_0", + and2_cell_, + {{"A", inv_addr[1]}, {"B", inv_addr[0]}, {"X", word_sel_nets[0]}}); + makeInst(word_sel_cell.get(), + "word_sel", + "and_1", + and2_cell_, + {{"A", inv_addr[1]}, + {"B", addr_inputs_[0]->getNet()}, + {"X", word_sel_nets[1]}}); + makeInst(word_sel_cell.get(), + "word_sel", + "and_2", + and2_cell_, + {{"A", addr_inputs_[1]->getNet()}, + {"B", inv_addr[0]}, + {"X", word_sel_nets[2]}}); + makeInst(word_sel_cell.get(), + "word_sel", + "and_3", + and2_cell_, + {{"A", addr_inputs_[1]->getNet()}, + {"B", addr_inputs_[0]->getNet()}, + {"X", word_sel_nets[3]}}); + ram_grid_.addCell(std::move(word_sel_cell), col_cell_count); + } + // decoder_layer nets - vector> decoder_input_nets(num_words, - vector(num_inputs)); - for (int word = 0; word < num_words; ++word) { - int word_num = word; + // for column muxing, deocder input nets uses only the upper address bits + // (num_row_bits) to determine row + vector> decoder_input_nets(num_rows, + vector(num_row_bits)); + for (int row = 0; row < num_rows; ++row) { + int row_num = row; // start at right most bit - for (int input = 0; input < num_inputs; ++input) { - if (word_num % 2 == 0) { + for (int input = 0; input < num_row_bits; ++input) { + if (row_num % 2 == 0) { // places inverted address for each input - decoder_input_nets[word][input] = inv_addr[input]; + decoder_input_nets[row][input] = inv_addr[num_word_bits + input]; } else { // puts original input in invert nets - decoder_input_nets[word][input] = addr_inputs_[input]->getNet(); + decoder_input_nets[row][input] + = addr_inputs_[num_word_bits + input]->getNet(); } - word_num /= 2; + row_num /= 2; } } @@ -874,11 +982,12 @@ void RamGen::generate(const int mask_size, // slices of a word vector> word_decoder_nets(num_words); - for (int row = 0; row < num_words; ++row) { + for (int row = 0; row < num_rows; ++row) { auto decoder_name = fmt::format("decoder_{}", row); - if (num_words == 2) { - dbNet* addr_net = (row == 0 ? inv_addr[0] : addr_inputs_[0]->getNet()); + if (num_rows == 2) { + dbNet* addr_net = (row == 0 ? inv_addr[num_word_bits] + : addr_inputs_[num_word_bits]->getNet()); for (int i = 0; i < read_ports; ++i) { word_decoder_nets[row].push_back(addr_net); } @@ -886,7 +995,7 @@ void RamGen::generate(const int mask_size, word_decoder_nets[row] = selectNets(decoder_name, read_ports); auto decoder_and_cell = makeDecoder(decoder_name, - num_words, + num_rows, read_ports, word_decoder_nets[row], decoder_input_nets[row]); @@ -915,16 +1024,77 @@ void RamGen::generate(const int mask_size, } } - for (int row = 0; row < num_words; ++row) { - makeWord(slices_per_word, - mask_size, - row, - read_ports, - clock->getNet(), - write_enable, - word_decoder_nets[row], - D_nets, - q_outputs_); + // Intermediate nets between tristate outputs and Q BTerms + // When column_mux_ratio = 1: tristate drives Q directly, so reuse Q BTerm + // nets When column_mux_ratio > 1: tristate drives intermediate net, AOI mux + // selects correct net based on lower address bits (word_select net) + // word_q_nets[word_idx][bit] = intermed. net for that word and bit pair + vector> word_q_nets(column_mux_ratio, + vector(word_size)); + if (column_mux_ratio == 1) { + for (int bit = 0; bit < word_size; ++bit) { + word_q_nets[0][bit] = q_outputs_[0][bit]->getNet(); + } + } else { + for (int w = 0; w < column_mux_ratio; ++w) { + for (int bit = 0; bit < word_size; ++bit) { + word_q_nets[w][bit] + = makeNet(fmt::format("word{}_q", w), fmt::format("[{}]", bit)); + } + } + } + + for (int row = 0; row < num_rows; ++row) { + for (int word_idx = 0; word_idx < column_mux_ratio; ++word_idx) { + vector> word_output_nets(read_ports); + for (int port = 0; port < read_ports; ++port) { + for (int bit = 0; bit < word_size; ++bit) { + word_output_nets[port].push_back(word_q_nets[word_idx][bit]); + } + } + + makeWord(slices_per_word, + mask_size, + row, + word_idx, + read_ports, + column_mux_ratio, + clock->getNet(), + word_sel_nets[word_idx], + write_enable, + word_decoder_nets[row], + D_nets, + word_output_nets); + } + } + + if (column_mux_ratio > 1) { + // build select nets once to be used for every bit and every slice + // NOTE: must be in exact alternating format: [S0', S0, S1', S1, ...] + vector mux_word_sel_nets; + for (int bit_idx = 0; bit_idx < num_word_bits; ++bit_idx) { + mux_word_sel_nets.push_back(inv_addr[bit_idx]); + mux_word_sel_nets.push_back(addr_inputs_[bit_idx]->getNet()); + } + + for (int slice = 0; slice < slices_per_word; ++slice) { + for (int bit = 0; bit < mask_size; ++bit) { + const int global_bit = slice * mask_size + bit; + vector bit_word_q_nets(column_mux_ratio); + for (int word_idx = 0; word_idx < column_mux_ratio; ++word_idx) { + bit_word_q_nets[word_idx] = word_q_nets[word_idx][global_bit]; + } + int mux_col = slice * (mask_size * column_mux_ratio + column_mux_ratio) + + bit * column_mux_ratio; + ram_grid_.addCell( + makeColMux(fmt::format("mux_slice{}_bit{}", slice, bit), + column_mux_ratio, + bit_word_q_nets, + mux_word_sel_nets, + q_outputs_[0][global_bit]->getNet()), + mux_col); + } + } } for (int slice = 0; slice < slices_per_word; ++slice) { @@ -977,7 +1147,7 @@ void RamGen::generate(const int mask_size, if (tapcell_) { // max tap distance specified is greater than the length of ram if (ram_grid_.getRowWidth() <= max_tap_dist) { - auto tapcell_layout = generateTapColumn(num_words, 0); + auto tapcell_layout = generateTapColumn(num_rows, 0); ram_grid_.insertLayout(std::move(tapcell_layout), 0); } else { // needed this calculation so first cells have right distance @@ -988,7 +1158,7 @@ void RamGen::generate(const int mask_size, for (int col = 0; col < ram_grid_.numLayouts(); ++col) { if (nearest_tap + ram_grid_.getLayoutWidth(col) >= max_tap_dist) { // if the nearest_tap is too far, generate tap column - auto tapcell_layout = generateTapColumn(num_words, tapcell_count); + auto tapcell_layout = generateTapColumn(num_rows, tapcell_count); ram_grid_.insertLayout(std::move(tapcell_layout), col); ++col; // col adjustment after insertion nearest_tap = 0; @@ -998,7 +1168,7 @@ void RamGen::generate(const int mask_size, } // check for last column in the grid if (nearest_tap >= max_tap_dist) { - auto tapcell_layout = generateTapColumn(num_words, tapcell_count); + auto tapcell_layout = generateTapColumn(num_rows, tapcell_count); ram_grid_.addLayout(std::move(tapcell_layout)); } } @@ -1013,8 +1183,8 @@ void RamGen::generate(const int mask_size, int num_sites = ram_grid_.getRowWidth() / db_sites->getWidth(); // One extra row at the top for placing input buffers - const int num_rows = num_words + 1; - for (int i = 0; i < num_rows; ++i) { + const int num_rows_grid = num_rows + 1; + for (int i = 0; i < num_rows_grid; ++i) { auto row_name = fmt::format("RAM_ROW{}", i); auto y_coord = i * ram_grid_.getHeight(); auto row_orient = odb::dbOrientType::R0; @@ -1034,7 +1204,7 @@ void RamGen::generate(const int mask_size, ram_grid_.placeGrid(); - int max_y_coord = ram_grid_.getHeight() * (num_rows); + int max_y_coord = ram_grid_.getHeight() * (num_rows_grid); int max_x_coord = ram_grid_.getRowWidth(); block_->setDieArea(odb::Rect(0, 0, max_x_coord, max_y_coord)); diff --git a/src/ram/src/ram.i b/src/ram/src/ram.i index 37e475e1c42..41bb7046635 100644 --- a/src/ram/src/ram.i +++ b/src/ram/src/ram.i @@ -32,6 +32,7 @@ void generate_ram_netlist_cmd(int mask_size, int word_size, int num_words, + int column_mux_ratio, const char* storage_cell_name, const char* tristate_cell_name, const char* inv_cell_name, @@ -87,7 +88,7 @@ generate_ram_netlist_cmd(int mask_size, } } - ram_gen->generate(mask_size, word_size, num_words, read_ports, + ram_gen->generate(mask_size, word_size, num_words, column_mux_ratio, read_ports, storage_cell, tristate_cell, inv_cell, tapcell, max_tap_dist); } diff --git a/src/ram/src/ram.tcl b/src/ram/src/ram.tcl index 86c08b8bf63..acc1850cc67 100644 --- a/src/ram/src/ram.tcl +++ b/src/ram/src/ram.tcl @@ -4,6 +4,7 @@ sta::define_cmd_args "generate_ram_netlist" {-mask_size bits -word_size bits -num_words words + [-column_mux_ratio ratio] [-storage_cell name] [-tristate_cell name] [-inv_cell name] @@ -13,8 +14,13 @@ sta::define_cmd_args "generate_ram_netlist" {-mask_size bits proc generate_ram_netlist { args } { sta::parse_key_args "generate_ram_netlist" args \ - keys { -mask_size -word_size -num_words -storage_cell -tristate_cell -inv_cell + keys { -mask_size -word_size -num_words -column_mux_ratio -storage_cell -tristate_cell -inv_cell -read_ports -tapcell -max_tap_dist } flags {} + + set column_mux_ratio 1 + if { [info exists keys(-column_mux_ratio)] } { + set column_mux_ratio $keys(-column_mux_ratio) + } if { [info exists keys(-mask_size)] } { set mask_size $keys(-mask_size) @@ -73,13 +79,14 @@ proc generate_ram_netlist { args } { The generated layout may not pass Design Rule Checks." } - ram::generate_ram_netlist_cmd $mask_size $word_size $num_words $storage_cell \ + ram::generate_ram_netlist_cmd $mask_size $word_size $num_words $column_mux_ratio $storage_cell \ $tristate_cell $inv_cell $read_ports $tapcell $max_tap_dist } sta::define_cmd_args "generate_ram" {-mask_size bits -word_size bits -num_words words + [-column_mux_ratio ratio] [-read_ports count] [-storage_cell name] [-tristate_cell name] @@ -98,7 +105,7 @@ sta::define_cmd_args "generate_ram" {-mask_size bits # user arguments for generate ram arguments proc generate_ram { args } { sta::parse_key_args "generate_ram" args \ - keys { -mask_size -word_size -num_words -storage_cell -tristate_cell -inv_cell -read_ports + keys { -mask_size -word_size -num_words -column_mux_ratio -storage_cell -tristate_cell -inv_cell -read_ports -power_pin -ground_pin -routing_layer -ver_layer -hor_layer -filler_cells -tapcell -max_tap_dist -write_behavioral_verilog } flags {} @@ -138,6 +145,10 @@ proc generate_ram { args } { lappend ram_netlist_args -max_tap_dist $keys(-max_tap_dist) } + if { [info exists keys(-column_mux_ratio)] } { + lappend ram_netlist_args -column_mux_ratio $keys(-column_mux_ratio) + } + if { [info exists keys(-write_behavioral_verilog)] } { set behavioral_verilog_file $keys(-write_behavioral_verilog) ram::set_behavioral_verilog_filename $behavioral_verilog_file From 5dd52789cce4b1457bd903b2f4100fd6708f056a Mon Sep 17 00:00:00 2001 From: Thinh Nguyen Date: Tue, 31 Mar 2026 19:25:19 -0400 Subject: [PATCH 7/7] ram: add column_mux_ratio feature 1. Add -column_mux_ratio flag to generate_ram and generate_ram_netlist (default=1) 2. Mux created from inline AOI22 mux placement for ratio=2 (single AOI22+INV per bit) and ratio=4 (2-stage AOI22 tree) 3. Fix addr BTerm naming: addr[i] -> addr_rw[i] 4. Fix makeSlice prefix to include word_idx: storage_{row}_{word}_{bit} 5. Use num_rows for column generation instead of num_words 6. Update make_8x8.ok with new naming convention for cells 7. Add make_8x8_mux2.ok for test with col_mux_ratio=2 Signed-off-by: Thinh Nguyen --- include/ord/OpenRoad.hh | 2 - src/OpenRoad.cc | 1 - src/dbSta/test/read_verilog6.ok | 1 - src/dbSta/test/read_verilog6.tcl | 2 +- src/drt/src/db/drObj/drNet.h | 13 +- src/drt/src/db/obj/frBlockObject.h | 14 +- src/drt/src/db/obj/frMarker.h | 6 +- src/drt/src/dr/FlexDR.h | 8 +- src/drt/src/dr/FlexDR_init.cpp | 51 +- src/drt/src/dr/FlexDR_maze.cpp | 1 - src/drt/src/dr/FlexWavefront.h | 26 +- src/drt/src/gc/FlexGC.cpp | 86 + src/drt/src/gc/FlexGC.h | 2 +- src/drt/src/gc/FlexGC_impl.h | 1 + src/drt/src/gc/FlexGC_main.cpp | 1 + src/drt/src/io/GuideProcessor.cpp | 44 +- src/drt/src/io/GuideProcessor.h | 2 + src/drt/test/BUILD | 70 +- src/drt/test/aes_nangate45.py | 7 +- src/drt/test/down_access_term.defok | 18 +- src/drt/test/drt_aux.py | 13 +- src/drt/test/ispd18_sample.defok | 48 +- src/drt/test/ispd18_sample.py | 13 +- src/drt/test/ndr_vias1.defok | 394 ++-- src/drt/test/ndr_vias2.defok | 369 ++-- src/drt/test/ndr_vias3.defok | 183 +- src/drt/test/obstruction.defok | 8 +- src/drt/test/single_step.py | 10 +- src/drt/test/top_level_term.defok | 26 +- src/drt/test/top_level_term.py | 3 + src/drt/test/top_level_term2.defok | 16 +- src/drt/test/top_level_term2.py | 3 + src/drt/test/via_access_layer.defok | 14 +- src/gui/README.md | 24 - src/gui/src/gui.tcl | 65 - src/gui/test/gui_readme_msgs_check.ok | 2 +- .../test/unfixed_cells_dont_fit_in_core.ok | 1 - .../test/unfixed_cells_dont_fit_in_core.tcl | 2 +- src/odb/include/odb/3dblox.h | 1 + src/odb/include/odb/geom.h | 33 + src/odb/include/odb/geom_boost.h | 51 + src/odb/src/3dblox/3dblox.cpp | 14 + src/odb/src/3dblox/CMakeLists.txt | 1 + src/odb/src/3dblox/dbxWriter.cpp | 2 + src/odb/src/3dblox/verilogWriter.cpp | 118 + src/odb/src/3dblox/verilogWriter.h | 24 + src/odb/test/cpp/BUILD | 19 + src/odb/test/cpp/CMakeLists.txt | 3 + src/odb/test/cpp/Test3DBloxVerilogWriter.cpp | 186 ++ src/odb/test/write_3dbx.3dbxok | 2 + src/pad/src/RDLRoute.cpp | 3 +- src/pad/src/RDLRoute.h | 16 +- src/pad/src/RDLRouter.cpp | 94 +- src/pad/src/RDLRouter.h | 7 +- src/pdn/test/core_grid_existing_ports.ok | 1 - src/pdn/test/core_grid_existing_ports.tcl | 2 +- src/ram/include/ram/ram.h | 8 +- src/ram/src/ram.cpp | 233 +- src/ram/src/ram.tcl | 8 +- src/ram/test/make_8x8.defok | 1930 +++++++++-------- src/ram/test/make_8x8.lefok | 27 +- src/ram/test/make_8x8.ok | 5 +- src/ram/test/make_8x8.tcl | 1 + src/ram/test/make_8x8_mux2.lefok | 373 ++++ src/ram/test/make_8x8_mux2.ok | 69 + src/ram/test/make_8x8_mux2.tcl | 20 + src/ram/test/regression_tests.tcl | 3 +- src/rcx/test/net_name_consistency.ok | 6 +- src/rcx/test/net_name_consistency.spefok | 34 +- src/rsz/test/report_buffers_ihp.ok | 1 - src/rsz/test/report_buffers_ihp.tcl | 2 +- src/web/README.md | 76 + src/web/include/web/web.h | 9 + src/web/src/coordinates.js | 22 +- src/web/src/display-controls.js | 13 +- src/web/src/inspector.js | 6 +- src/web/src/main.js | 29 +- src/web/src/request_handler.cpp | 1 + src/web/src/ruler.js | 30 +- src/web/src/tile_generator.cpp | 607 +++++- src/web/src/tile_generator.h | 33 + src/web/src/web.cpp | 23 + src/web/src/web.i | 11 + src/web/src/web.tcl | 106 + src/web/test/BUILD | 21 + src/web/test/cpp/TestSaveImage.cpp | 278 +++ test/aes_sky130hs.metrics | 94 +- test/aes_sky130hs.metrics_limits | 14 +- test/jpeg_sky130hd.metrics | 173 +- test/jpeg_sky130hd.metrics_limits | 22 +- test/regression_test.sh | 1 + 91 files changed, 4302 insertions(+), 2114 deletions(-) create mode 100644 src/odb/src/3dblox/verilogWriter.cpp create mode 100644 src/odb/src/3dblox/verilogWriter.h create mode 100644 src/odb/test/cpp/Test3DBloxVerilogWriter.cpp create mode 100644 src/ram/test/make_8x8_mux2.lefok create mode 100644 src/ram/test/make_8x8_mux2.ok create mode 100644 src/ram/test/make_8x8_mux2.tcl create mode 100644 src/web/test/cpp/TestSaveImage.cpp diff --git a/include/ord/OpenRoad.hh b/include/ord/OpenRoad.hh index 546d4803432..35b6ad067a1 100644 --- a/include/ord/OpenRoad.hh +++ b/include/ord/OpenRoad.hh @@ -3,8 +3,6 @@ #pragma once -#include -#include #include #include diff --git a/src/OpenRoad.cc b/src/OpenRoad.cc index 0922c026b61..eef476375e0 100644 --- a/src/OpenRoad.cc +++ b/src/OpenRoad.cc @@ -79,7 +79,6 @@ #include "rsz/MakeResizer.hh" #include "rsz/Resizer.hh" #include "sta/VerilogReader.hh" -#include "sta/VerilogWriter.hh" #include "stt/MakeSteinerTreeBuilder.h" #include "tap/MakeTapcell.h" #include "tap/tapcell.h" diff --git a/src/dbSta/test/read_verilog6.ok b/src/dbSta/test/read_verilog6.ok index a230a2ae9c6..942b38ff2a0 100644 --- a/src/dbSta/test/read_verilog6.ok +++ b/src/dbSta/test/read_verilog6.ok @@ -3,4 +3,3 @@ [WARNING STA-0198] read_verilog6.v line 11, module AND2_X10 not found. Creating black box for u2. [WARNING ORD-2011] LEF master BUF_X10 has no liberty cell. [ERROR ORD-2013] instance u2 LEF master AND2_X10 not found. -Error: read_verilog6.tcl, 9 ORD-2013 diff --git a/src/dbSta/test/read_verilog6.tcl b/src/dbSta/test/read_verilog6.tcl index 99897fb1f96..7b6024b0e82 100644 --- a/src/dbSta/test/read_verilog6.tcl +++ b/src/dbSta/test/read_verilog6.tcl @@ -6,4 +6,4 @@ read_lef read_verilog6.lef read_liberty Nangate45/Nangate45_typ.lib # uses BUF_X10 (no liberty) and AND2_X10 (no lef or liberty) read_verilog read_verilog6.v -link_design top +catch { link_design top } diff --git a/src/drt/src/db/drObj/drNet.h b/src/drt/src/db/drObj/drNet.h index 21e070e0086..072df4f136b 100644 --- a/src/drt/src/db/drObj/drNet.h +++ b/src/drt/src/db/drObj/drNet.h @@ -20,6 +20,7 @@ #include "db/infra/frPoint.h" #include "db/infra/frSegStyle.h" #include "db/obj/frAccess.h" +#include "db/obj/frBlockObject.h" #include "frBaseTypes.h" #include "global.h" @@ -59,7 +60,10 @@ class drNet : public drBlockObject void clearRouteConnFigs() { routeConnFigs_.clear(); } frNet* getFrNet() const { return fNet_; } void setFrNet(frNet* net) { fNet_ = net; } - const std::set& getFrNetTerms() const { return fNetTerms_; } + const frOrderedIdSet& getFrNetTerms() const + { + return fNetTerms_; + } bool isModified() const { return modified_; } int getNumMarkers() const { return numMarkers_; } int getNumPinsIn() const { return numPinsIn_; } @@ -117,7 +121,10 @@ class drNet : public drBlockObject // TODO; return false; } - void setFrNetTerms(const std::set& in) { fNetTerms_ = in; } + void setFrNetTerms(const frOrderedIdSet& in) + { + fNetTerms_ = in; + } void addFrNetTerm(frBlockObject* in) { fNetTerms_.insert(in); } void setModified(bool in) { modified_ = in; } @@ -207,7 +214,7 @@ class drNet : public drBlockObject std::vector> extConnFigs_; std::vector> routeConnFigs_; std::vector> bestRouteConnFigs_; - std::set fNetTerms_; + frOrderedIdSet fNetTerms_; frNet* fNet_{nullptr}; // old bool modified_{false}; diff --git a/src/drt/src/db/obj/frBlockObject.h b/src/drt/src/db/obj/frBlockObject.h index 799c0dc3345..861852cb2ac 100644 --- a/src/drt/src/db/obj/frBlockObject.h +++ b/src/drt/src/db/obj/frBlockObject.h @@ -39,7 +39,19 @@ struct frBlockObjectComp { bool operator()(const frBlockObject* lhs, const frBlockObject* rhs) const { - return *lhs < *rhs; + if (lhs == rhs) { + return false; + } + if (lhs == nullptr || rhs == nullptr) { + return lhs < rhs; + } + if (lhs->typeId() != rhs->typeId()) { + return lhs->typeId() < rhs->typeId(); + } + if (lhs->getId() != rhs->getId()) { + return lhs->getId() < rhs->getId(); + } + return lhs < rhs; } }; } // namespace internal diff --git a/src/drt/src/db/obj/frMarker.h b/src/drt/src/db/obj/frMarker.h index c8be835ec26..097c3f43f98 100644 --- a/src/drt/src/db/obj/frMarker.h +++ b/src/drt/src/db/obj/frMarker.h @@ -64,9 +64,9 @@ class frMarker : public frFig odb::Rect getBBox() const override { return bbox_; } frLayerNum getLayerNum() const { return layerNum_; } - const std::set& getSrcs() const { return srcs_; } + const frOrderedIdSet& getSrcs() const { return srcs_; } - void setSrcs(const std::set& srcs) { srcs_ = srcs; } + void setSrcs(const frOrderedIdSet& srcs) { srcs_ = srcs; } std::vector< std::pair>>& @@ -104,7 +104,7 @@ class frMarker : public frFig frConstraint* constraint_{nullptr}; odb::Rect bbox_; frLayerNum layerNum_{0}; - std::set srcs_; + frOrderedIdSet srcs_; std::vector< std::pair>> victims_; // obj, isFixed diff --git a/src/drt/src/dr/FlexDR.h b/src/drt/src/dr/FlexDR.h index c4c84e8aabb..b074e3dad55 100644 --- a/src/drt/src/dr/FlexDR.h +++ b/src/drt/src/dr/FlexDR.h @@ -764,7 +764,7 @@ class FlexDRWorker void initMazeCost_planarTerm(const frDesign* design); void initMazeCost_pin(drNet* net, bool isAddPathCost); void initMazeCost_fixedObj(const frDesign* design); - void initMazeCost_terms(const std::set& objs, + void initMazeCost_terms(const frOrderedIdSet& objs, bool isAddPathCost, bool isSkipVia = false); void modBlockedEdgesForMacroPin(frInstTerm* instTerm, @@ -810,13 +810,13 @@ class FlexDRWorker void route_queue_init_queue(std::queue& rerouteQueue); void route_queue_update_from_marker( frMarker* marker, - std::set& uniqueVictims, - std::set& uniqueAggressors, + frOrderedIdSet& uniqueVictims, + frOrderedIdSet& uniqueAggressors, std::vector& checks, std::vector& routes, frBlockObject* checkingObj); void getRipUpNetsFromMarker(frMarker* marker, - std::set& nets, + frOrderedIdSet& nets, frCoord bloatDist = 0); void route_queue_update_queue(const std::vector& checks, const std::vector& routes, diff --git a/src/drt/src/dr/FlexDR_init.cpp b/src/drt/src/dr/FlexDR_init.cpp index 7b55fdccff8..6d86c8a07e7 100644 --- a/src/drt/src/dr/FlexDR_init.cpp +++ b/src/drt/src/dr/FlexDR_init.cpp @@ -1533,7 +1533,7 @@ void FlexDRWorker::initNets_boundaryArea() void FlexDRWorker::initRipUpNetsFromMarkers() { - std::set ripUpNets; + frOrderedIdSet ripUpNets; for (auto& marker : markers_) { const auto bloatDist = getTech()->getLayer(marker.getLayerNum())->getWidth() * 2; @@ -2052,8 +2052,8 @@ void FlexDRWorker::initMazeCost_ap() void FlexDRWorker::initMazeCost_marker_route_queue_addHistoryCost( const frMarker& marker) { - std::set vioNets; // for self-violation, only add cost for one side - // (experiment with self cut spacing) + frOrderedIdSet vioNets; // for self-violation, only add cost for one + // side (experiment with self cut spacing) const odb::Rect mBox = marker.getBBox(); const auto lNum = marker.getLayerNum(); @@ -2284,8 +2284,8 @@ void FlexDRWorker::route_queue_addMarkerCost() void FlexDRWorker::route_queue_init_queue( std::queue& rerouteQueue) { - std::set uniqueVictims; - std::set uniqueAggressors; + frOrderedIdSet uniqueVictims; + frOrderedIdSet uniqueAggressors; std::vector checks; std::vector routes; @@ -2324,7 +2324,7 @@ void FlexDRWorker::route_queue_init_queue( } } int currId = ripupNets.size(); - std::set addedNets; + frOrderedIdSet addedNets; for (auto& marker : markers_) { for (auto net : ripupNets) { if (marker.getSrcs().find(net->getFrNet()) != marker.getSrcs().end()) { @@ -2399,8 +2399,8 @@ void FlexDRWorker::route_queue_update_queue( //*****************************************************************************************// void FlexDRWorker::route_queue_update_from_marker( frMarker* marker, - std::set& uniqueVictims, - std::set& uniqueAggressors, + frOrderedIdSet& uniqueVictims, + frOrderedIdSet& uniqueAggressors, std::vector& checks, std::vector& routes, frBlockObject* checkingObj) @@ -2430,8 +2430,8 @@ void FlexDRWorker::route_queue_update_from_marker( std::vector uniqueAggressorOwners; // to maintain order auto& markerAggressors = marker->getAggressors(); - std::set movableAggressorNets; - std::set movableAggressorOwners; + frOrderedIdSet movableAggressorNets; + frOrderedIdSet movableAggressorOwners; for (auto& aggressorPair : markerAggressors) { auto& aggressor = aggressorPair.first; @@ -2475,7 +2475,7 @@ void FlexDRWorker::route_queue_update_from_marker( } if (hasRerouteNet) { - std::set checkDRCOwners; + frOrderedIdSet checkDRCOwners; for (auto& src : marker->getSrcs()) { if (movableAggressorOwners.find(src) == movableAggressorOwners.end()) { if (src) { @@ -2493,7 +2493,7 @@ void FlexDRWorker::route_queue_update_from_marker( } } } else { - std::set owners, otherOwners, routeOwners; + frOrderedIdSet owners, otherOwners, routeOwners; auto& srcs = marker->getSrcs(); for (auto& src : srcs) { if (src) { @@ -2525,7 +2525,7 @@ void FlexDRWorker::route_queue_update_from_marker( } } if (hasRerouteNet) { - std::set checkDRCOwners; + frOrderedIdSet checkDRCOwners; for (auto& src : marker->getSrcs()) { if (routeOwners.find(src) == routeOwners.end()) { if (src) { @@ -2585,7 +2585,7 @@ void FlexDRWorker::route_queue_update_from_marker( } void FlexDRWorker::getRipUpNetsFromMarker(frMarker* marker, - std::set& nets, + frOrderedIdSet& nets, const frCoord bloatDist) { // if shapes don't overlap routeBox, ignore violation @@ -2633,8 +2633,8 @@ void FlexDRWorker::route_queue_update_queue( std::queue& rerouteQueue, frBlockObject* checkingObj) { - std::set uniqueVictims; - std::set uniqueAggressors; + frOrderedIdSet uniqueVictims; + frOrderedIdSet uniqueAggressors; std::vector checks; std::vector routes; if (checkingObj != nullptr @@ -2681,7 +2681,7 @@ void FlexDRWorker::initMazeCost_fixedObj(const frDesign* design) { frRegionQuery::Objects result; frMIdx zIdx = 0; - std::map> frNet2Terms; + frOrderedIdMap> frNet2Terms; for (auto layerNum = getTech()->getBottomLayerNum(); layerNum <= getTech()->getTopLayerNum(); ++layerNum) { @@ -2731,11 +2731,17 @@ void FlexDRWorker::initMazeCost_fixedObj(const frDesign* design) for (auto& [box, obj] : result) { switch (obj->typeId()) { case frcBTerm: { // term no bloat - frNet2Terms[static_cast(obj)->getNet()].insert(obj); + auto* net = static_cast(obj)->getNet(); + if (net != nullptr) { + frNet2Terms[net].insert(obj); + } break; } case frcInstTerm: { - frNet2Terms[static_cast(obj)->getNet()].insert(obj); + auto* net = static_cast(obj)->getNet(); + if (net != nullptr) { + frNet2Terms[net].insert(obj); + } if (isRoutingLayer) { // unblock planar edge for obs over pin, ap will unblock via edge // for legal pin access @@ -2832,9 +2838,10 @@ void FlexDRWorker::modBlockedEdgesForMacroPin(frInstTerm* instTerm, } } -void FlexDRWorker::initMazeCost_terms(const std::set& objs, - const bool isAddPathCost, - const bool isSkipVia) +void FlexDRWorker::initMazeCost_terms( + const frOrderedIdSet& objs, + const bool isAddPathCost, + const bool isSkipVia) { for (auto& obj : objs) { if (obj->typeId() == frcBTerm) { diff --git a/src/drt/src/dr/FlexDR_maze.cpp b/src/drt/src/dr/FlexDR_maze.cpp index b26b7e8009c..d2b0074d5ff 100644 --- a/src/drt/src/dr/FlexDR_maze.cpp +++ b/src/drt/src/dr/FlexDR_maze.cpp @@ -3215,7 +3215,6 @@ bool FlexDRWorker::routeNet(drNet* net, std::vector& paths) // Verify if net has jumpers const bool route_with_jumpers = net->getFrNet()->hasJumpers(); - if (net->getPins().size() <= 1) { return true; } diff --git a/src/drt/src/dr/FlexWavefront.h b/src/drt/src/dr/FlexWavefront.h index f4d048a6776..34c3482842e 100644 --- a/src/drt/src/dr/FlexWavefront.h +++ b/src/drt/src/dr/FlexWavefront.h @@ -52,7 +52,31 @@ class FlexWavefrontGrid if (zIdx_ != b.zIdx_) { return zIdx_ < b.zIdx_; // prefer upper layer } - return pathCost_ < b.pathCost_; // prefer larger pathcost, DFS-style + if (pathCost_ != b.pathCost_) { + return pathCost_ < b.pathCost_; // prefer larger pathcost, DFS-style + } + if (xIdx_ != b.xIdx_) { + return xIdx_ > b.xIdx_; // prefer smaller x for stable tie-breaking + } + if (yIdx_ != b.yIdx_) { + return yIdx_ > b.yIdx_; // prefer smaller y for stable tie-breaking + } + if (getLastDir() != b.getLastDir()) { + return getLastDir() > b.getLastDir(); + } + if (prevViaUp_ != b.prevViaUp_) { + return prevViaUp_ > b.prevViaUp_; + } + if (tLength_ != b.tLength_) { + return tLength_ > b.tLength_; + } + if (vLengthX_ != b.vLengthX_) { + return vLengthX_ > b.vLengthX_; + } + if (vLengthY_ != b.vLengthY_) { + return vLengthY_ > b.vLengthY_; + } + return backTraceBuffer_.to_ulong() > b.backTraceBuffer_.to_ulong(); } // getters frMIdx x() const { return xIdx_; } diff --git a/src/drt/src/gc/FlexGC.cpp b/src/drt/src/gc/FlexGC.cpp index 7acd1fba3a1..e4d65f647c8 100644 --- a/src/drt/src/gc/FlexGC.cpp +++ b/src/drt/src/gc/FlexGC.cpp @@ -3,9 +3,12 @@ #include "gc/FlexGC.h" +#include +#include #include #include #include +#include #include #include @@ -24,6 +27,47 @@ namespace drt { +namespace { + +std::vector getMarkerSourceKey(const frMarker* marker) +{ + std::vector keys; + keys.reserve(marker->getSrcs().size()); + for (auto* src : marker->getSrcs()) { + if (src == nullptr) { + keys.emplace_back(); + continue; + } + switch (src->typeId()) { + case frcNet: + keys.push_back(static_cast(src)->getName()); + break; + case frcInstTerm: { + auto* inst_term = static_cast(src); + keys.push_back(inst_term->getInst()->getName() + "/" + + inst_term->getTerm()->getName()); + break; + } + case frcBTerm: + keys.push_back(static_cast(src)->getName()); + break; + case frcInstBlockage: + keys.push_back(static_cast(src)->getInst()->getName()); + break; + case frcInst: + keys.push_back(static_cast(src)->getName()); + break; + default: + keys.push_back(std::to_string(static_cast(src->typeId())) + ":" + + std::to_string(src->getId())); + break; + } + } + return keys; +} + +} // namespace + FlexGCWorker::FlexGCWorker(frTechObject* techIn, utl::Logger* logger, RouterConfiguration* router_cfg, @@ -75,6 +119,48 @@ void FlexGCWorker::Impl::addMarker(std::unique_ptr in) markers_.push_back(std::move(in)); } +void FlexGCWorker::Impl::normalizeMarkerOrder() +{ + auto same_run = [](const frMarker* lhs, const frMarker* rhs) { + const auto lhs_bbox = lhs->getBBox(); + const auto rhs_bbox = rhs->getBBox(); + const auto lhs_constraint_id + = lhs->getConstraint() == nullptr ? -1 : lhs->getConstraint()->getId(); + const auto rhs_constraint_id + = rhs->getConstraint() == nullptr ? -1 : rhs->getConstraint()->getId(); + return lhs->getLayerNum() == rhs->getLayerNum() + && lhs_constraint_id == rhs_constraint_id + && lhs_bbox.xMin() == rhs_bbox.xMin() + && lhs_bbox.xMax() == rhs_bbox.xMax() + && getMarkerSourceKey(lhs) == getMarkerSourceKey(rhs); + }; + + auto less_in_run = [](const std::unique_ptr& lhs, + const std::unique_ptr& rhs) { + const auto lhs_bbox = lhs->getBBox(); + const auto rhs_bbox = rhs->getBBox(); + if (lhs_bbox.yMin() != rhs_bbox.yMin()) { + return lhs_bbox.yMin() < rhs_bbox.yMin(); + } + if (lhs_bbox.yMax() != rhs_bbox.yMax()) { + return lhs_bbox.yMax() > rhs_bbox.yMax(); + } + return lhs_bbox.area() > rhs_bbox.area(); + }; + + auto begin = markers_.begin(); + while (begin != markers_.end()) { + auto end = std::next(begin); + while (end != markers_.end() && same_run(begin->get(), end->get())) { + ++end; + } + if (std::distance(begin, end) > 1) { + std::stable_sort(begin, end, less_in_run); + } + begin = end; + } +} + void FlexGCWorker::addPAObj(frConnFig* obj, frBlockObject* owner) { impl_->addPAObj(obj, owner); diff --git a/src/drt/src/gc/FlexGC.h b/src/drt/src/gc/FlexGC.h index 3f3076858c6..2f55874f77f 100644 --- a/src/drt/src/gc/FlexGC.h +++ b/src/drt/src/gc/FlexGC.h @@ -74,7 +74,7 @@ struct MarkerId odb::Rect box; frLayerNum lNum; frConstraint* con; - std::set srcs; + frOrderedIdSet srcs; bool operator<(const MarkerId& rhs) const { return std::tie(box, lNum, con, srcs) diff --git a/src/drt/src/gc/FlexGC_impl.h b/src/drt/src/gc/FlexGC_impl.h index 7c6867c2010..6afca773085 100644 --- a/src/drt/src/gc/FlexGC_impl.h +++ b/src/drt/src/gc/FlexGC_impl.h @@ -164,6 +164,7 @@ class FlexGCWorker::Impl FlexGCWorkerRegionQuery& getWorkerRegionQuery() { return rq_; } void modifyMarkers(); + void normalizeMarkerOrder(); // init gcNet* getNet(frBlockObject* obj); gcNet* getNet(frNet* net); diff --git a/src/drt/src/gc/FlexGC_main.cpp b/src/drt/src/gc/FlexGC_main.cpp index c502e177ffe..4741c7e2296 100644 --- a/src/drt/src/gc/FlexGC_main.cpp +++ b/src/drt/src/gc/FlexGC_main.cpp @@ -4204,6 +4204,7 @@ int FlexGCWorker::Impl::main() checkMetalWidthViaTable(); // modify markers for pwires modifyMarkers(); + normalizeMarkerOrder(); return 0; } diff --git a/src/drt/src/io/GuideProcessor.cpp b/src/drt/src/io/GuideProcessor.cpp index 1b9813df282..f5e8948052a 100644 --- a/src/drt/src/io/GuideProcessor.cpp +++ b/src/drt/src/io/GuideProcessor.cpp @@ -1406,8 +1406,16 @@ std::vector> GuideProcessor::genGuides( std::map gcell_pin_map; frBlockObjectMap> pin_gcell_map; + std::vector pins; initGCellPinMap(net, gcell_pin_map); initPinGCellMap(net, pin_gcell_map); + pins.reserve(net->getInstTerms().size() + net->getBTerms().size()); + for (auto& inst_term : net->getInstTerms()) { + pins.push_back(inst_term); + } + for (auto& bterm : net->getBTerms()) { + pins.push_back(bterm); + } // Run for 3 iterations max for (int i = 0; i < 4; i++) { @@ -1463,6 +1471,7 @@ std::vector> GuideProcessor::genGuides( net, force_pin_feed_through, rects, + pins, pin_gcell_map); path_finder.setAllowWarnings(i != 0); if (path_finder.traverseGraph()) { @@ -1484,12 +1493,14 @@ GuidePathFinder::GuidePathFinder( frNet* net, const bool force_feed_through, const std::vector& rects, + const std::vector& pins, const frBlockObjectMap>& pin_gcell_map) : design_(design), logger_(logger), router_cfg_(router_cfg), net_(net), force_feed_through_(force_feed_through), + pins_(pins), pin_gcell_map_(pin_gcell_map), rects_(rects) { @@ -1513,8 +1524,12 @@ void GuidePathFinder::buildNodeMap( } guide_count_ = rects.size(); // total guide cnt int node_idx = rects.size(); - for (const auto& [obj, gcells] : pin_gcell_map) { - for (const auto& gcell : gcells) { + for (auto* pin : pins_) { + const auto it = pin_gcell_map.find(pin); + if (it == pin_gcell_map.end()) { + continue; + } + for (const auto& gcell : it->second) { node_map_[gcell].insert(node_idx); } ++node_idx; @@ -1686,41 +1701,42 @@ GuidePathFinder::commitPathToGuides( std::vector& rects, const frBlockObjectMap>& pin_gcell_map) { - std::vector pins; - pins.reserve(getPinCount()); - for (const auto& [pin, _] : pin_gcell_map) { - pins.emplace_back(pin); - } // find pin in which guide std::vector> pin_to_gcell - = getPinToGCellList(rects, pin_gcell_map, pins); + = getPinToGCellList(rects, pin_gcell_map, pins_); int pin_idx = 0; for (auto& guides : pin_to_gcell) { if (guides.empty()) { logger_->error(DRT, 222, "Pin {} is not visited by any guide", - getPinName(pins[pin_idx])); + getPinName(pins_[pin_idx])); } ++pin_idx; } updateNodeMap(rects, pin_to_gcell); std::vector> gr_pins - = getGRPins(pins, pin_to_gcell); + = getGRPins(pins_, pin_to_gcell); clipGuides(rects); mergeGuides(rects); + std::vector> final_guides; + final_guides.reserve(getGuideCount()); for (int i = 0; i < getGuideCount(); i++) { if (!visited_[i]) { continue; } - auto& rect = rects[i]; - odb::Rect box = rect.getBBox(); + final_guides.emplace_back(rects[i].getLayerNum(), rects[i].getBBox()); + } + std::sort(final_guides.begin(), final_guides.end()); + final_guides.erase(std::unique(final_guides.begin(), final_guides.end()), + final_guides.end()); + for (const auto& [layer_num, box] : final_guides) { auto guide = std::make_unique(); odb::Point begin = getDesign()->getTopBlock()->getGCellCenter(box.ll()); odb::Point end = getDesign()->getTopBlock()->getGCellCenter(box.ur()); guide->setPoints(begin, end); - guide->setBeginLayerNum(rect.getLayerNum()); - guide->setEndLayerNum(rect.getLayerNum()); + guide->setBeginLayerNum(layer_num); + guide->setEndLayerNum(layer_num); guide->addToNet(net_); net_->addGuide(std::move(guide)); } diff --git a/src/drt/src/io/GuideProcessor.h b/src/drt/src/io/GuideProcessor.h index bb34a7c14d5..cb0bfa1292b 100644 --- a/src/drt/src/io/GuideProcessor.h +++ b/src/drt/src/io/GuideProcessor.h @@ -286,6 +286,7 @@ class GuidePathFinder frNet* net, bool force_feed_through, const std::vector& rects, + const std::vector& pins, const frBlockObjectMap>& pin_gcell_map); int getNodeCount() const { return node_count_; } int getGuideCount() const { return guide_count_; } @@ -467,6 +468,7 @@ class GuidePathFinder std::vector visited_; std::vector is_on_path_; std::vector prev_idx_; + std::vector pins_; frBlockObjectMap> pin_gcell_map_; std::vector rects_; }; diff --git a/src/drt/test/BUILD b/src/drt/test/BUILD index c76f9e4170a..5336aa156aa 100644 --- a/src/drt/test/BUILD +++ b/src/drt/test/BUILD @@ -1,4 +1,3 @@ -load("@rules_python//python:defs.bzl", "py_test") # SPDX-License-Identifier: BSD-3-Clause # Copyright (c) 2022-2025, The OpenROAD Authors @@ -6,11 +5,11 @@ load("@rules_python//python:defs.bzl", "py_test") # No tests are intentionally excluded. See .kiro/specs/bazel-cmake-test-parity/intentional_exclusions.md load("@rules_cc//cc:cc_test.bzl", "cc_test") -load("//test:regression.bzl", "doc_check_test", "regression_test") +load("@rules_python//python:defs.bzl", "py_library", "py_test") +load("//test:regression.bzl", "doc_check_test", "regression_rule_test", "regression_test") package(features = ["layering_check"]) -# From CMakeLists.txt or_integration_tests(TESTS COMPULSORY_TESTS = [ "down_access_term", "drc_test", @@ -28,28 +27,15 @@ COMPULSORY_TESTS = [ "via_access_layer", ] -# From CMakeLists.txt or_integration_tests(PASSFAIL_TESTS -PASSFAIL_TESTS = [ - # NOTE: gc_test excluded - CMake build directory wrapper that runs trTest executable - # from build/src/drt/. The underlying C++ test (gc_unittest) is already in BUILD. - # "gc_test", -] +ALL_TESTS = COMPULSORY_TESTS -# TODO: Enable once difference between bazel and ctest is resolved. -MANUAL_FOR_BAZEL_TESTS = [ - "down_access_term", - "drc_test", +PY_TESTS = [ "ispd18_sample", - "ispd18_sample_incr", - "ndr_vias1", - "ndr_vias2", - "ndr_vias3", "single_step", + "top_level_term", "top_level_term2", ] -ALL_TESTS = COMPULSORY_TESTS + PASSFAIL_TESTS - filegroup( name = "regression_resources", # Dependencies could be specified more narrowly per test case, @@ -58,6 +44,7 @@ filegroup( srcs = [ "Nangate45/Nangate45_stdcell.lef", "Nangate45/Nangate45_tech.lef", + "drt_aux.py", "gcd_nangate45.route_guide", "gcd_nangate45.tcl", "gcd_nangate45_distributed.tcl", @@ -66,6 +53,7 @@ filegroup( "gcd_nangate45_test_worker.tcl", "gcd_sky130hd.def", "gcd_sky130hd.guide", + "helpers.py", "helpers.tcl", "sky130hd/sky130_fd_sc_hd__ff_n40C_1v95.lib", "sky130hd/sky130_fd_sc_hd__ss_n40C_1v40.lib", @@ -120,14 +108,37 @@ filegroup( [ regression_test( name = test_name, - check_passfail = True if test_name in PASSFAIL_TESTS else False, data = [":" + test_name + "_resources"], - tags = ["manual"] if test_name in MANUAL_FOR_BAZEL_TESTS else [], visibility = ["//visibility:public"], ) for test_name in ALL_TESTS ] +py_library( + name = "helpers", + srcs = [ + "drt_aux.py", + "helpers.py", + ], + imports = ["."], + deps = [ + "//python/openroad:openroadpy", + ], +) + +[ + py_test( + name = test_name, + srcs = [test_name + ".py"], + data = [":" + test_name + "_resources"], + deps = [ + ":helpers", + "//python/openroad:openroadpy", + ], + ) + for test_name in PY_TESTS +] + cc_test( name = "gc_unittest", srcs = [ @@ -165,3 +176,20 @@ doc_check_test( ], visibility = ["//visibility:public"], ) + +regression_rule_test( + name = "aes_nangate45-py_test", + bazel_test_sh = "//test:bazel_test.sh", + check_log = False, + data = [ + "aes_nangate45.route_guide", + "aes_nangate45_preroute.def", + ":regression_resources", + ], + openroad = "//:openroad", + regression_test = "//test:regression_test.sh", + tags = ["manual"], + test_file = "aes_nangate45.py", + test_name = "aes_nangate45", + visibility = ["//visibility:public"], +) diff --git a/src/drt/test/aes_nangate45.py b/src/drt/test/aes_nangate45.py index 20eca850f71..381c2cdce55 100644 --- a/src/drt/test/aes_nangate45.py +++ b/src/drt/test/aes_nangate45.py @@ -20,10 +20,13 @@ gr.readGuides("aes_nangate45.route_guide") set_thread_count(4) +drc_file = helpers.make_result_file("aes_nangate45.output.drc.rpt") +maze_file = helpers.make_result_file("aes_nangate45.output.maze.log") + drt_aux.detailed_route( design, - output_drc="results/aes_nangate45.output.drc-py.rpt", - output_maze="results/aes_nangate45.output.maze-py.log", + output_drc=drc_file, + output_maze=maze_file, verbose=1, ) diff --git a/src/drt/test/down_access_term.defok b/src/drt/test/down_access_term.defok index 30d022351bc..53c1cc5d0bf 100644 --- a/src/drt/test/down_access_term.defok +++ b/src/drt/test/down_access_term.defok @@ -35,24 +35,24 @@ NETS 1 ; + ROUTED met3 ( 1440 155030 ) ( 1680 * ) NEW met2 ( 1680 155030 ) ( * 155215 ) NEW met1 ( 112080 154845 ) ( * 155215 ) - NEW met1 ( 131280 158175 ) ( 135600 * ) - NEW met1 ( 131280 155955 ) ( * 158175 ) - NEW met1 ( 112080 155955 ) ( 131280 * ) + NEW met1 ( 135120 158175 ) ( 135600 * ) + NEW met1 ( 135120 155955 ) ( * 158175 ) + NEW met1 ( 112080 155955 ) ( 135120 * ) NEW met1 ( 112080 155215 ) ( * 155955 ) - NEW met1 ( 135600 158175 ) ( 144240 * ) - NEW met1 ( 144240 158175 ) ( 145200 * ) - NEW met2 ( 145200 144855 ) ( * 158175 ) NEW met1 ( 1680 155215 ) ( 112080 * ) - NEW li1 ( 145200 144855 ) L1M1_PR_MR - NEW met1 ( 145200 144855 ) M1M2_PR + NEW met1 ( 144720 158175 ) ( 145200 * ) + NEW met2 ( 145200 144855 ) ( * 158175 ) + NEW met1 ( 135600 158175 ) ( 144720 * ) NEW met3 ( 1440 155030 ) M3M4_PR NEW met4 ( 1440 155030 ) M4M5_PR NEW met2 ( 1680 155030 ) M2M3_PR NEW met1 ( 1680 155215 ) M1M2_PR NEW li1 ( 112080 154845 ) L1M1_PR_MR NEW li1 ( 135600 158175 ) L1M1_PR_MR - NEW li1 ( 144240 158175 ) L1M1_PR_MR + NEW li1 ( 144720 158175 ) L1M1_PR_MR NEW met1 ( 145200 158175 ) M1M2_PR + NEW li1 ( 145200 144855 ) L1M1_PR_MR + NEW met1 ( 145200 144855 ) M1M2_PR NEW met3 ( 1440 155030 ) RECT ( -380 -150 0 150 ) ; END NETS END DESIGN diff --git a/src/drt/test/drt_aux.py b/src/drt/test/drt_aux.py index 076fd1b8749..44cbcf6ecd4 100644 --- a/src/drt/test/drt_aux.py +++ b/src/drt/test/drt_aux.py @@ -1,4 +1,4 @@ -import drt +import os import utl import openroad @@ -35,7 +35,12 @@ def detailed_route( save_guide_updates=False ): router = design.getTritonRoute() - params = drt.ParamStruct() + if os.environ.get("TEST_SRCDIR"): + params = openroad.ParamStruct() + else: + import drt + + params = drt.ParamStruct() params.outputMazeFile = output_maze params.outputDrcFile = output_drc params.outputCmapFile = output_cmap @@ -53,7 +58,9 @@ def detailed_route( params.singleStepDR = single_step_dr params.minAccessPoints = min_access_points params.saveGuideUpdates = save_guide_updates - params.num_threads = openroad.thread_count() + # The standalone Bazel Python binding does not initialize the global + # thread-count helper used by the embedded openroad -python path. + params.num_threads = 1 if os.environ.get("TEST_SRCDIR") else openroad.thread_count() router.setParams(params) router.main() diff --git a/src/drt/test/ispd18_sample.defok b/src/drt/test/ispd18_sample.defok index f3766bd2a8f..4369272bcf6 100644 --- a/src/drt/test/ispd18_sample.defok +++ b/src/drt/test/ispd18_sample.defok @@ -63,22 +63,22 @@ NETS 11 ; NEW Metal2 ( 95800 77710 ) VIA23_1C NEW Metal1 ( 95800 83790 ) VIA12_1C_V ; - net1231 ( inst5821 B ) ( inst5275 Y ) + USE SIGNAL - + ROUTED Metal3 ( 85800 77710 ) ( 91000 * ) - NEW Metal2 ( 85800 77710 ) ( * 86450 ) - NEW Metal2 ( 85400 86450 ) ( 85800 * ) + + ROUTED Metal2 ( 91000 77710 ) ( * 79610 ) + NEW Metal3 ( 91000 79610 ) ( * 79990 ) + NEW Metal3 ( 85400 79990 ) ( 91000 * ) + NEW Metal2 ( 85400 79990 ) ( * 86450 ) NEW Metal1 ( 91000 77710 ) VIA12_1C_V - NEW Metal2 ( 91000 77710 ) VIA23_1C - NEW Metal2 ( 85800 77710 ) VIA23_1C - NEW Metal1 ( 85400 86450 ) VIA12_1C_V - NEW Metal2 ( 91000 77710 ) RECT ( -70 -442 70 0 ) ; - - net1232 ( inst4382 C ) ( inst4062 Y ) + USE SIGNAL - + ROUTED Metal3 ( 85400 79990 ) ( 98200 * ) - NEW Metal2 ( 98200 79990 ) ( * 86450 ) - NEW Metal1 ( 85400 79990 ) VIA12_1C_V + NEW Metal2 ( 91000 79610 ) VIA23_1C NEW Metal2 ( 85400 79990 ) VIA23_1C - NEW Metal2 ( 98200 79990 ) VIA23_1C + NEW Metal1 ( 85400 86450 ) VIA12_1C_V ; + - net1232 ( inst4382 C ) ( inst4062 Y ) + USE SIGNAL + + ROUTED Metal3 ( 85400 79230 ) ( 98200 * ) + NEW Metal2 ( 98200 79230 ) ( * 86450 ) + NEW Metal1 ( 85400 79230 ) VIA12_1C_V + NEW Metal2 ( 85400 79230 ) VIA23_1C + NEW Metal2 ( 98200 79230 ) VIA23_1C NEW Metal1 ( 98200 86450 ) VIA12_1C - NEW Metal2 ( 85400 79990 ) RECT ( -70 -442 70 0 ) ; + NEW Metal2 ( 85400 79230 ) RECT ( -70 -442 70 0 ) ; - net1233 ( inst6050 A ) ( inst4189 Y ) + USE SIGNAL + ROUTED Metal2 ( 88200 72770 ) ( * 73150 ) NEW Metal3 ( 88200 73150 ) ( 97800 * ) @@ -128,20 +128,20 @@ NETS 11 ; NEW Metal2 ( 87800 83410 ) RECT ( -70 -442 70 0 ) NEW Metal2 ( 97400 83410 ) RECT ( -70 -442 70 0 ) ; - net1239 ( inst6286 Y ) ( inst5333 C0 ) + USE SIGNAL - + ROUTED Metal3 ( 91800 80370 ) ( 102600 * ) - NEW Metal2 ( 91800 80370 ) ( * 86830 ) + + ROUTED Metal2 ( 102600 80370 ) ( * 81130 ) + NEW Metal3 ( 91800 81130 ) ( 102600 * ) + NEW Metal2 ( 91800 81130 ) ( * 86830 ) NEW Metal1 ( 102600 80370 ) VIA12_1C_V - NEW Metal2 ( 102600 80370 ) VIA23_1C - NEW Metal2 ( 91800 80370 ) VIA23_1C - NEW Metal1 ( 91800 86830 ) VIA12_1C_V - NEW Metal2 ( 102600 80370 ) RECT ( -70 -442 70 0 ) ; + NEW Metal2 ( 102600 81130 ) VIA23_1C + NEW Metal2 ( 91800 81130 ) VIA23_1C + NEW Metal1 ( 91800 86830 ) VIA12_1C_V ; - net1240 ( inst3502 A ) ( inst2015 Y ) + USE SIGNAL - + ROUTED Metal2 ( 91000 78470 ) ( * 80750 ) - NEW Metal3 ( 91000 78470 ) ( 96200 * ) - NEW Metal2 ( 96200 76950 ) ( * 78470 ) + + ROUTED Metal2 ( 91000 80370 ) ( * 80750 ) + NEW Metal3 ( 91000 80370 ) ( 96200 * ) + NEW Metal2 ( 96200 76950 ) ( * 80370 ) NEW Metal1 ( 91000 80750 ) VIA12_1C - NEW Metal2 ( 91000 78470 ) VIA23_1C - NEW Metal2 ( 96200 78470 ) VIA23_1C + NEW Metal2 ( 91000 80370 ) VIA23_1C + NEW Metal2 ( 96200 80370 ) VIA23_1C NEW Metal1 ( 96200 76950 ) VIA12_1C_V ; END NETS END DESIGN diff --git a/src/drt/test/ispd18_sample.py b/src/drt/test/ispd18_sample.py index 16e51735d37..4f7a6c5678d 100644 --- a/src/drt/test/ispd18_sample.py +++ b/src/drt/test/ispd18_sample.py @@ -2,6 +2,9 @@ import helpers import drt_aux +bazel_working_dir = "/_main/src/drt/test/" +helpers.if_bazel_change_working_dir_to(bazel_working_dir) + tech = Tech() tech.readLef("testcase/ispd18_sample/ispd18_sample.input.lef") design = helpers.make_design(tech) @@ -10,11 +13,15 @@ gr = design.getGlobalRouter() gr.readGuides("testcase/ispd18_sample/ispd18_sample.input.guide") +drc_file = helpers.make_result_file("ispd18_sample.output.drc.rpt") +maze_file = helpers.make_result_file("ispd18_sample.output.maze.log") +guide_coverage_file = helpers.make_result_file("ispd18_sample.coverage.csv") + drt_aux.detailed_route( design, - output_drc="results/ispd18_sample.output.drc.rpt", - output_maze="results/ispd18_sample.output.maze.log", - output_guide_coverage="results/ispd18_sample.coverage.csv", + output_drc=drc_file, + output_maze=maze_file, + output_guide_coverage=guide_coverage_file, verbose=0, ) diff --git a/src/drt/test/ndr_vias1.defok b/src/drt/test/ndr_vias1.defok index 3d3f73c8499..38b7a5c2639 100644 --- a/src/drt/test/ndr_vias1.defok +++ b/src/drt/test/ndr_vias1.defok @@ -214,138 +214,128 @@ PINS 1 ; END PINS NETS 8 ; - clk ( PIN clk ) ( clkbuf_0_clk A ) + USE CLOCK + NONDEFAULTRULE NDR_3W_3S - + ROUTED met1 ( 89470 148410 210 ) ( 107870 * 210 ) - NEW met1 ( 107870 148410 210 ) ( * 150790 210 ) - NEW met2 ( 89470 340 0 ) ( * 148410 210 ) - NEW met1 ( 107870 150790 210 ) ( 110400 * 210 ) - NEW met1 ( 110400 150790 210 ) ( * 151130 210 ) - NEW met1 ( 110400 151130 210 ) ( 149500 * 210 ) + + ROUTED met1 ( 89470 145010 210 ) ( 105570 * 210 ) + NEW met2 ( 105570 145010 210 ) ( * 151130 210 ) + NEW met1 ( 105570 151130 210 ) ( 149500 * 210 ) NEW met1 TAPER ( 149500 151130 ) ( 151110 * ) - NEW met1 ( 89470 148410 ) M1M2_PR_R + NEW met2 ( 89470 340 0 ) ( * 145010 210 ) + NEW met1 ( 89470 145010 ) M1M2_PR_R + NEW met1 ( 105570 145010 ) M1M2_PR_R + NEW met1 ( 105570 151130 ) M1M2_PR_R NEW li1 TAPER ( 151110 151130 ) L1M1_PR_R ; - clknet_0_clk ( clkbuf_2_3__f_clk A ) ( clkbuf_2_2__f_clk A ) ( clkbuf_2_1__f_clk A ) ( clkbuf_2_0__f_clk A ) ( clkbuf_0_clk X ) + USE CLOCK + NONDEFAULTRULE NDR_3W_3S + ROUTED met1 TAPER ( 167900 169830 ) ( 169510 * ) NEW met1 TAPER ( 167900 118490 ) ( 169510 * ) NEW met2 ( 146970 169830 210 ) ( * 172890 210 ) + NEW met1 TAPER ( 130870 172890 ) ( 132710 * ) + NEW met1 ( 132710 172890 210 ) ( 146970 * 210 ) NEW met1 ( 146970 169830 210 ) ( 167900 * 210 ) - NEW met2 ( 151110 158700 210 ) ( * 169830 210 ) - NEW met2 ( 147890 118490 210 ) ( * 123590 210 ) - NEW met1 ( 117990 123590 210 ) ( 147890 * 210 ) - NEW met2 ( 117990 118830 210 ) ( * 123590 210 ) - NEW met1 TAPER ( 116610 118830 ) ( 117990 * ) - NEW met1 TAPER ( 150650 150450 ) ( 152030 * ) - NEW met2 ( 150650 123590 210 ) ( * 150450 210 ) - NEW met1 ( 147890 123590 210 ) ( 150650 * 210 ) - NEW met2 ( 150650 158700 210 ) ( 151110 * 210 ) - NEW met2 ( 150650 150450 210 ) ( * 158700 210 ) - NEW met1 ( 147890 118490 210 ) ( 167900 * 210 ) - NEW met1 TAPER ( 130870 172890 ) ( 131100 * ) - NEW met1 ( 131100 172890 210 ) ( 131790 * 210 ) - NEW met2 ( 131790 172890 210 ) ( * 173060 210 ) - NEW met3 ( 131790 173060 450 ) ( 134550 * 450 ) - NEW met2 ( 134550 172890 210 ) ( * 173060 210 ) - NEW met1 ( 134550 172890 210 ) ( 146970 * 210 ) + NEW met1 TAPER ( 116610 118490 ) ( 118220 * ) + NEW met1 TAPER ( 151570 150450 ) ( 152490 * ) + NEW met2 ( 151570 118490 210 ) ( * 150450 210 ) + NEW met2 ( 151570 150450 210 ) ( * 169830 210 ) + NEW met1 ( 118220 118490 210 ) ( 167900 * 210 ) NEW li1 TAPER ( 169510 169830 ) L1M1_PR_R NEW li1 TAPER ( 169510 118490 ) L1M1_PR_R NEW met1 ( 146970 169830 ) M1M2_PR_R NEW met1 ( 146970 172890 ) M1M2_PR_R NEW li1 TAPER ( 130870 172890 ) L1M1_PR_R - NEW met1 ( 151110 169830 ) M1M2_PR_R - NEW met1 ( 147890 118490 ) M1M2_PR_R - NEW met1 ( 147890 123590 ) M1M2_PR_R - NEW met1 ( 117990 123590 ) M1M2_PR_R - NEW met1 TAPER ( 117990 118830 ) M1M2_PR_R - NEW li1 TAPER ( 116610 118830 ) L1M1_PR_R - NEW li1 TAPER ( 152030 150450 ) L1M1_PR_R - NEW met1 TAPER ( 150650 150450 ) M1M2_PR_R - NEW met1 ( 150650 123590 ) M1M2_PR_R - NEW met1 ( 131790 172890 ) M1M2_PR_R - NEW met2 ( 131790 173060 ) M2M3_PR - NEW met2 ( 134550 173060 ) M2M3_PR - NEW met1 ( 134550 172890 ) M1M2_PR_R ; + NEW met1 ( 151570 169830 ) M1M2_PR_R + NEW li1 TAPER ( 116610 118490 ) L1M1_PR_R + NEW li1 TAPER ( 152490 150450 ) L1M1_PR_R + NEW met1 TAPER ( 151570 150450 ) M1M2_PR_R + NEW met1 ( 151570 118490 ) M1M2_PR_R ; - clknet_2_0__leaf_clk ( _414_ CLK ) ( _418_ CLK ) ( _428_ CLK ) ( _429_ CLK ) ( _432_ CLK ) ( _434_ CLK ) ( _444_ CLK ) ( _445_ CLK ) ( clkbuf_2_0__f_clk X ) + USE CLOCK + NONDEFAULTRULE NDR_3W_3S - + ROUTED met1 ( 88550 120870 210 ) ( 91540 * 210 ) - NEW met1 TAPER ( 91540 120870 ) ( 93150 * ) - NEW met2 ( 88550 104890 210 ) ( * 120870 210 ) - NEW met1 TAPER ( 88550 104890 ) ( 89470 * ) + + ROUTED met1 TAPER ( 88550 104890 ) ( 89470 * ) NEW met1 ( 143750 88570 210 ) ( 144900 * 210 ) NEW met1 TAPER ( 144900 88570 ) ( 146510 * ) - NEW met1 ( 88550 118490 210 ) ( 110400 * 210 ) - NEW met1 ( 117070 121210 210 ) ( 123740 * 210 ) - NEW met1 TAPER ( 123740 121210 ) ( 125350 * ) - NEW met2 ( 117070 121210 210 ) ( * 148070 210 ) + NEW met1 ( 88550 120870 210 ) ( 91540 * 210 ) + NEW met1 TAPER ( 91540 120870 ) ( 93150 * ) + NEW met2 ( 88550 104890 210 ) ( * 120870 210 ) NEW met1 ( 117070 148070 210 ) ( 135010 * 210 ) NEW met1 TAPER ( 135010 148070 ) ( 136850 * ) - NEW met1 TAPER ( 117070 117810 ) ( 117990 * ) - NEW met2 ( 117070 117810 210 ) ( * 121210 210 ) - NEW met1 ( 110400 117810 210 ) ( * 118490 210 ) - NEW met1 ( 110400 117810 210 ) ( 115460 * 210 ) - NEW met1 TAPER ( 115460 117810 ) ( 117070 * ) - NEW met2 ( 111090 117810 210 ) ( * 120870 210 ) - NEW met2 ( 111090 134810 210 ) ( * 137190 210 ) - NEW met1 ( 111090 137190 210 ) ( 117070 * 210 ) - NEW met1 TAPER ( 142830 115770 ) ( 143750 * ) - NEW met2 ( 142830 115770 210 ) ( * 117810 210 ) - NEW met1 TAPER ( 117990 117810 ) ( 120060 * ) - NEW met1 ( 120060 117810 210 ) ( 142830 * 210 ) - NEW met2 ( 143750 88570 210 ) ( * 115770 210 ) - NEW li1 TAPER ( 93150 120870 ) L1M1_PR_R - NEW met1 ( 88550 120870 ) M1M2_PR_R + NEW met2 ( 143750 88570 210 ) ( * 115430 210 ) + NEW met2 ( 125350 120700 210 ) ( * 120870 210 ) + NEW met3 ( 125350 120700 450 ) ( 143750 * 450 ) + NEW met2 ( 117070 124200 210 ) ( 117530 * 210 ) + NEW met2 ( 117530 120870 210 ) ( * 124200 210 ) + NEW met1 ( 117530 120870 210 ) ( 123740 * 210 ) + NEW met1 TAPER ( 123740 120870 ) ( 125350 * ) + NEW met2 ( 117530 117810 210 ) ( * 117980 210 ) + NEW met2 ( 117530 117980 210 ) ( 117990 * 210 ) + NEW met2 ( 117990 117980 210 ) ( * 120870 210 ) + NEW met2 ( 117530 120870 210 ) ( 117990 * 210 ) + NEW met2 ( 111090 120700 210 ) ( * 120870 210 ) + NEW met3 ( 111090 120700 450 ) ( 117990 * 450 ) + NEW met2 ( 111090 117810 210 ) ( * 120700 210 ) + NEW met1 ( 88550 117810 210 ) ( 111090 * 210 ) + NEW met2 ( 143750 115430 210 ) ( * 120700 210 ) + NEW met2 ( 111090 134810 210 ) ( * 134980 210 ) + NEW met3 ( 111090 134980 450 ) ( 117070 * 450 ) + NEW met2 ( 117070 124200 210 ) ( * 148070 210 ) NEW met1 TAPER ( 88550 104890 ) M1M2_PR_R NEW li1 TAPER ( 89470 104890 ) L1M1_PR_R - NEW met1 ( 88550 118490 ) M1M2_PR_R NEW met1 ( 143750 88570 ) M1M2_PR_R NEW li1 TAPER ( 146510 88570 ) L1M1_PR_R - NEW li1 TAPER ( 125350 121210 ) L1M1_PR_R - NEW met1 ( 117070 121210 ) M1M2_PR_R + NEW li1 TAPER ( 93150 120870 ) L1M1_PR_R + NEW met1 ( 88550 120870 ) M1M2_PR_R + NEW met1 ( 88550 117810 ) M1M2_PR_R NEW met1 ( 117070 148070 ) M1M2_PR_R NEW li1 TAPER ( 136850 148070 ) L1M1_PR_R - NEW li1 TAPER ( 117990 117810 ) L1M1_PR_R - NEW met1 TAPER ( 117070 117810 ) M1M2_PR_R + NEW li1 TAPER ( 143750 115430 ) L1M1_PR_R + NEW met1 TAPER ( 143750 115430 ) M1M2_PR_R + NEW li1 TAPER ( 125350 120870 ) L1M1_PR_R + NEW met1 TAPER ( 125350 120870 ) M1M2_PR_R + NEW met2 ( 125350 120700 ) M2M3_PR + NEW met2 ( 143750 120700 ) M2M3_PR + NEW met1 ( 117530 120870 ) M1M2_PR_R + NEW li1 TAPER ( 117530 117810 ) L1M1_PR_R + NEW met1 TAPER ( 117530 117810 ) M1M2_PR_R NEW li1 TAPER ( 111090 120870 ) L1M1_PR_R NEW met1 TAPER ( 111090 120870 ) M1M2_PR_R + NEW met2 ( 111090 120700 ) M2M3_PR + NEW met2 ( 117990 120700 ) M2M3_PR NEW met1 ( 111090 117810 ) M1M2_PR_R NEW li1 TAPER ( 111090 134810 ) L1M1_PR_R NEW met1 TAPER ( 111090 134810 ) M1M2_PR_R - NEW met1 ( 111090 137190 ) M1M2_PR_R - NEW met1 ( 117070 137190 ) M1M2_PR_R - NEW li1 TAPER ( 143750 115770 ) L1M1_PR_R - NEW met1 TAPER ( 142830 115770 ) M1M2_PR_R - NEW met1 ( 142830 117810 ) M1M2_PR_R - NEW met1 TAPER ( 143750 115770 ) M1M2_PR_R ; + NEW met2 ( 111090 134980 ) M2M3_PR + NEW met2 ( 117070 134980 ) M2M3_PR ; - clknet_2_1__leaf_clk ( _423_ CLK ) ( _424_ CLK ) ( _425_ CLK ) ( _426_ CLK ) ( _427_ CLK ) ( _440_ CLK ) ( _441_ CLK ) ( _442_ CLK ) ( _443_ CLK ) ( clkbuf_2_1__f_clk X ) + USE CLOCK + NONDEFAULTRULE NDR_3W_3S - + ROUTED met1 ( 199410 96390 210 ) ( 204010 * 210 ) + + ROUTED met2 ( 158010 90100 210 ) ( * 102170 210 ) NEW met1 TAPER ( 204010 96390 ) ( 205850 * ) - NEW met1 TAPER ( 178710 90950 ) ( * 91970 ) - NEW met1 TAPER ( 177790 91970 ) ( 178710 * ) - NEW met1 TAPER ( 177790 91970 ) ( * 92990 ) - NEW met1 ( 177790 92990 210 ) ( * 93670 210 ) - NEW met1 ( 177790 93670 210 ) ( 199410 * 210 ) - NEW met2 ( 199410 93670 210 ) ( * 96390 210 ) - NEW met1 TAPER ( 177100 90950 ) ( 178710 * ) NEW met1 ( 199410 129370 210 ) ( 204700 * 210 ) NEW met1 TAPER ( 204700 129370 ) ( 206310 * ) NEW met2 ( 199410 129370 210 ) ( * 137190 210 ) NEW met1 ( 199410 113050 210 ) ( 204700 * 210 ) NEW met1 TAPER ( 204700 113050 ) ( 206310 * ) NEW met2 ( 199410 113050 210 ) ( * 129370 210 ) - NEW met2 ( 199410 96390 210 ) ( * 113050 210 ) + NEW met2 ( 199410 110400 210 ) ( 199870 * 210 ) + NEW met2 ( 199410 110400 210 ) ( * 113050 210 ) NEW met1 ( 152950 129370 210 ) ( 154330 * 210 ) NEW met1 TAPER ( 154330 129370 ) ( 156170 * ) - NEW met2 ( 171350 118830 210 ) ( * 120870 210 ) - NEW met1 ( 156170 120870 210 ) ( 171350 * 210 ) - NEW met2 ( 156170 120870 210 ) ( * 129370 210 ) - NEW met2 ( 158010 102170 210 ) ( * 120870 210 ) - NEW met2 ( 158010 90950 210 ) ( * 102170 210 ) NEW met2 ( 152950 129370 210 ) ( * 148070 210 ) + NEW met1 ( 158930 90950 210 ) ( 164450 * 210 ) + NEW met2 ( 158930 90100 210 ) ( * 90950 210 ) + NEW met1 ( 164450 90950 210 ) ( 177100 * 210 ) + NEW met1 TAPER ( 177100 90950 ) ( 178710 * ) + NEW met1 ( 178710 96390 210 ) ( 199870 * 210 ) + NEW met2 ( 178710 90950 210 ) ( * 96390 210 ) + NEW met2 ( 158010 90100 210 ) ( 158930 * 210 ) NEW met2 ( 164450 88230 210 ) ( * 90950 210 ) - NEW met1 ( 158010 90950 210 ) ( 177100 * 210 ) + NEW met2 ( 199870 96390 210 ) ( * 110400 210 ) + NEW met1 ( 199870 96390 210 ) ( 204010 * 210 ) + NEW met1 ( 158010 117470 210 ) ( 168130 * 210 ) + NEW met1 TAPER ( 168130 117470 ) ( 169510 * ) + NEW met1 TAPER ( 169510 117470 ) ( * 117810 ) + NEW met1 TAPER ( 169510 117810 ) ( 170430 * ) + NEW met1 ( 156170 117470 210 ) ( 158010 * 210 ) + NEW met2 ( 156170 117470 210 ) ( * 129370 210 ) + NEW met2 ( 158010 102170 210 ) ( * 117470 210 ) + NEW li1 TAPER ( 158010 102170 ) L1M1_PR_R + NEW met1 TAPER ( 158010 102170 ) M1M2_PR_R NEW li1 TAPER ( 205850 96390 ) L1M1_PR_R - NEW met1 ( 199410 96390 ) M1M2_PR_R - NEW li1 TAPER ( 178710 90950 ) L1M1_PR_R - NEW met1 ( 199410 93670 ) M1M2_PR_R NEW li1 TAPER ( 164450 88230 ) L1M1_PR_R NEW met1 TAPER ( 164450 88230 ) M1M2_PR_R NEW li1 TAPER ( 206310 129370 ) L1M1_PR_R @@ -354,156 +344,164 @@ NETS 8 ; NEW met1 TAPER ( 199410 137190 ) M1M2_PR_R NEW li1 TAPER ( 206310 113050 ) L1M1_PR_R NEW met1 ( 199410 113050 ) M1M2_PR_R - NEW li1 TAPER ( 152950 148070 ) L1M1_PR_R - NEW met1 TAPER ( 152950 148070 ) M1M2_PR_R NEW li1 TAPER ( 156170 129370 ) L1M1_PR_R NEW met1 ( 152950 129370 ) M1M2_PR_R - NEW li1 TAPER ( 171350 118830 ) L1M1_PR_R - NEW met1 TAPER ( 171350 118830 ) M1M2_PR_R - NEW met1 ( 171350 120870 ) M1M2_PR_R - NEW met1 ( 156170 120870 ) M1M2_PR_R + NEW li1 TAPER ( 152950 148070 ) L1M1_PR_R + NEW met1 TAPER ( 152950 148070 ) M1M2_PR_R NEW met1 TAPER ( 156170 129370 ) M1M2_PR_R - NEW li1 TAPER ( 158010 102170 ) L1M1_PR_R - NEW met1 TAPER ( 158010 102170 ) M1M2_PR_R - NEW met1 ( 158010 120870 ) M1M2_PR_R - NEW met1 ( 158010 90950 ) M1M2_PR_R - NEW met1 ( 164450 90950 ) M1M2_PR_R ; + NEW met1 ( 164450 90950 ) M1M2_PR_R + NEW met1 ( 158930 90950 ) M1M2_PR_R + NEW li1 TAPER ( 178710 90950 ) L1M1_PR_R + NEW met1 ( 199870 96390 ) M1M2_PR_R + NEW met1 ( 178710 96390 ) M1M2_PR_R + NEW met1 TAPER ( 178710 90950 ) M1M2_PR_R + NEW met1 ( 158010 117470 ) M1M2_PR_R + NEW li1 TAPER ( 170430 117810 ) L1M1_PR_R + NEW met1 ( 156170 117470 ) M1M2_PR_R ; - clknet_2_2__leaf_clk ( _411_ CLK ) ( _413_ CLK ) ( _415_ CLK ) ( _416_ CLK ) ( _417_ CLK ) ( _421_ CLK ) ( _430_ CLK ) ( _431_ CLK ) ( _433_ CLK ) ( _437_ CLK ) ( clkbuf_2_2__f_clk X ) + USE CLOCK + NONDEFAULTRULE NDR_3W_3S - + ROUTED met1 TAPER ( 108330 183770 ) ( 109250 * ) - NEW met1 TAPER ( 108330 183770 ) ( * 185470 ) - NEW met1 ( 108330 185470 210 ) ( * 186150 210 ) - NEW met2 ( 96830 183770 210 ) ( * 186150 210 ) - NEW met1 ( 96830 183770 210 ) ( 107410 * 210 ) - NEW met1 TAPER ( 107410 183770 ) ( 108330 * ) - NEW met1 TAPER ( 98210 151130 ) ( 100050 * ) - NEW met2 ( 98210 151130 210 ) ( * 183770 210 ) - NEW met1 TAPER ( 136850 210630 ) ( 137770 * ) - NEW met1 ( 136850 208250 210 ) ( * 209100 210 ) - NEW met1 TAPER ( 136850 209100 ) ( * 210630 ) - NEW met1 ( 136850 208250 210 ) ( 146970 * 210 ) - NEW met1 ( 146970 208250 210 ) ( * 210630 210 ) - NEW met1 ( 146970 210630 210 ) ( 148810 * 210 ) - NEW met1 TAPER ( 148810 210630 ) ( 150595 * ) - NEW met1 ( 126270 208250 210 ) ( 136850 * 210 ) + + ROUTED met1 ( 137770 175270 210 ) ( 139380 * 210 ) NEW met1 TAPER ( 139380 175270 ) ( 140990 * ) + NEW met1 ( 137770 159290 210 ) ( 142140 * 210 ) NEW met1 TAPER ( 142140 159290 ) ( 143750 * ) - NEW met2 ( 125810 181050 210 ) ( * 183770 210 ) - NEW met1 ( 125810 181050 210 ) ( 131790 * 210 ) NEW met2 ( 125810 206380 210 ) ( 126270 * 210 ) - NEW met2 ( 125810 183770 210 ) ( * 206380 210 ) - NEW met2 ( 111550 197370 210 ) ( * 200090 210 ) - NEW met1 ( 111550 197370 210 ) ( 125810 * 210 ) - NEW met1 TAPER ( 125810 199750 ) ( 126270 * ) - NEW met1 ( 108330 186150 210 ) ( 125810 * 210 ) - NEW met2 ( 126270 206380 210 ) ( * 208250 210 ) + NEW met1 ( 126270 210630 210 ) ( 135930 * 210 ) + NEW met1 TAPER ( 135930 210630 ) ( 137770 * ) + NEW met1 TAPER ( 150190 210630 ) ( 150650 * ) + NEW met2 ( 150190 210460 210 ) ( * 210630 210 ) + NEW met3 ( 137770 210460 450 ) ( 150190 * 450 ) + NEW met2 ( 137770 210460 210 ) ( * 210630 210 ) + NEW met2 ( 126270 206380 210 ) ( * 210630 210 ) + NEW met3 ( 131790 172380 450 ) ( 137770 * 450 ) + NEW met2 ( 131790 172210 210 ) ( * 172380 210 ) NEW met2 ( 137770 159290 210 ) ( * 175270 210 ) - NEW met1 ( 131790 175270 210 ) ( 137770 * 210 ) - NEW met1 TAPER ( 132710 173230 ) ( 133630 * ) - NEW met1 TAPER ( 133630 173230 ) ( * 175270 ) - NEW met2 ( 131790 175270 210 ) ( * 181050 210 ) - NEW met1 ( 137770 159290 210 ) ( 142140 * 210 ) - NEW met1 ( 137770 175270 210 ) ( 139380 * 210 ) - NEW met1 ( 126270 208250 ) M1M2_PR_R - NEW li1 TAPER ( 109250 183770 ) L1M1_PR_R - NEW li1 TAPER ( 96830 186150 ) L1M1_PR_R - NEW met1 TAPER ( 96830 186150 ) M1M2_PR_R - NEW met1 ( 96830 183770 ) M1M2_PR_R - NEW met1 ( 98210 183770 ) M1M2_PR_R - NEW met1 ( 98210 151130 ) M1M2_PR_R - NEW li1 TAPER ( 100050 151130 ) L1M1_PR_R - NEW li1 TAPER ( 137770 210630 ) L1M1_PR_R - NEW li1 TAPER ( 150595 210630 ) L1M1_PR_R + NEW met1 ( 96830 183090 210 ) ( 100050 * 210 ) + NEW met2 ( 96830 183090 210 ) ( * 186150 210 ) + NEW met1 ( 100050 183430 210 ) ( 107410 * 210 ) + NEW met1 TAPER ( 107410 183430 ) ( 109250 * ) + NEW met1 ( 100050 183090 210 ) ( * 183430 210 ) + NEW met1 ( 109250 186150 210 ) ( 125810 * 210 ) + NEW met2 ( 109250 183430 210 ) ( * 186150 210 ) + NEW met2 ( 125810 183770 210 ) ( * 186150 210 ) + NEW met1 ( 125810 179690 210 ) ( 131790 * 210 ) + NEW met2 ( 125810 179690 210 ) ( * 183770 210 ) + NEW met2 ( 100050 151130 210 ) ( * 183090 210 ) + NEW met2 ( 131790 172380 210 ) ( * 179690 210 ) + NEW met3 ( 111550 199580 450 ) ( 125810 * 450 ) + NEW met2 ( 111550 199580 210 ) ( * 199750 210 ) + NEW met1 TAPER ( 125810 199750 ) ( 126270 * ) + NEW met2 ( 125810 186150 210 ) ( * 199580 210 ) + NEW met2 ( 125810 199580 210 ) ( * 206380 210 ) NEW li1 TAPER ( 140990 175270 ) L1M1_PR_R + NEW met1 ( 137770 175270 ) M1M2_PR_R + NEW met1 ( 137770 159290 ) M1M2_PR_R NEW li1 TAPER ( 143750 159290 ) L1M1_PR_R + NEW li1 TAPER ( 100050 151130 ) L1M1_PR_R + NEW met1 TAPER ( 100050 151130 ) M1M2_PR_R + NEW li1 TAPER ( 137770 210630 ) L1M1_PR_R + NEW met1 ( 126270 210630 ) M1M2_PR_R + NEW li1 TAPER ( 150650 210630 ) L1M1_PR_R + NEW met1 TAPER ( 150190 210630 ) M1M2_PR_R + NEW met2 ( 150190 210460 ) M2M3_PR + NEW met2 ( 137770 210460 ) M2M3_PR + NEW met1 TAPER ( 137770 210630 ) M1M2_PR_R + NEW met2 ( 131790 172380 ) M2M3_PR + NEW met2 ( 137770 172380 ) M2M3_PR + NEW li1 TAPER ( 131790 172210 ) L1M1_PR_R + NEW met1 TAPER ( 131790 172210 ) M1M2_PR_R + NEW met1 ( 100050 183090 ) M1M2_PR_R + NEW met1 ( 96830 183090 ) M1M2_PR_R + NEW li1 TAPER ( 96830 186150 ) L1M1_PR_R + NEW met1 TAPER ( 96830 186150 ) M1M2_PR_R + NEW li1 TAPER ( 109250 183430 ) L1M1_PR_R + NEW met1 ( 125810 186150 ) M1M2_PR_R + NEW met1 ( 109250 186150 ) M1M2_PR_R + NEW met1 TAPER ( 109250 183430 ) M1M2_PR_R NEW li1 TAPER ( 125810 183770 ) L1M1_PR_R NEW met1 TAPER ( 125810 183770 ) M1M2_PR_R - NEW met1 ( 125810 181050 ) M1M2_PR_R - NEW met1 ( 131790 181050 ) M1M2_PR_R - NEW li1 TAPER ( 111550 200090 ) L1M1_PR_R - NEW met1 TAPER ( 111550 200090 ) M1M2_PR_R - NEW met1 ( 111550 197370 ) M1M2_PR_R - NEW met1 ( 125810 197370 ) M1M2_PR_R + NEW met1 ( 131790 179690 ) M1M2_PR_R + NEW met1 ( 125810 179690 ) M1M2_PR_R + NEW met2 ( 125810 199580 ) M2M3_PR + NEW met2 ( 111550 199580 ) M2M3_PR + NEW li1 TAPER ( 111550 199750 ) L1M1_PR_R + NEW met1 TAPER ( 111550 199750 ) M1M2_PR_R NEW li1 TAPER ( 126270 199750 ) L1M1_PR_R - NEW met1 TAPER ( 125810 199750 ) M1M2_PR_R - NEW met1 ( 125810 186150 ) M1M2_PR_R - NEW met1 ( 137770 175270 ) M1M2_PR_R - NEW met1 ( 137770 159290 ) M1M2_PR_R - NEW met1 ( 131790 175270 ) M1M2_PR_R - NEW li1 TAPER ( 132710 173230 ) L1M1_PR_R ; + NEW met1 TAPER ( 125810 199750 ) M1M2_PR_R ; - clknet_2_3__leaf_clk ( _412_ CLK ) ( _419_ CLK ) ( _420_ CLK ) ( _422_ CLK ) ( _435_ CLK ) ( _436_ CLK ) ( _438_ CLK ) ( _439_ CLK ) ( clkbuf_2_3__f_clk X ) + USE CLOCK + NONDEFAULTRULE NDR_3W_3S - + ROUTED met2 ( 192050 191590 210 ) ( * 194310 210 ) + + ROUTED met1 ( 192050 164730 210 ) ( 199410 * 210 ) + NEW met1 TAPER ( 199410 164730 ) ( 201250 * ) NEW met1 ( 192050 194310 210 ) ( 204010 * 210 ) NEW met1 TAPER ( 204010 194310 ) ( 205850 * ) - NEW met1 ( 192050 177990 210 ) ( 205620 * 210 ) - NEW met1 TAPER ( 205620 177990 ) ( 207230 * ) - NEW met1 ( 192050 164730 210 ) ( 199535 * 210 ) - NEW met1 TAPER ( 199535 164730 ) ( 201250 * ) - NEW met2 ( 192050 164730 210 ) ( * 177990 210 ) - NEW met2 ( 192050 177990 210 ) ( * 191590 210 ) + NEW met2 ( 192050 191590 210 ) ( * 194310 210 ) + NEW met1 TAPER ( 207000 178330 ) ( 207230 * ) + NEW met3 ( 154790 178500 450 ) ( 165830 * 450 ) + NEW met2 ( 154790 178330 210 ) ( * 178500 210 ) NEW met1 ( 165830 175610 210 ) ( 171580 * 210 ) NEW met1 TAPER ( 171580 175610 ) ( 173190 * ) - NEW met2 ( 170430 170510 210 ) ( * 175610 210 ) - NEW met2 ( 170430 175610 210 ) ( * 177990 210 ) - NEW met1 ( 170430 177990 210 ) ( 192050 * 210 ) - NEW met2 ( 192050 153850 210 ) ( * 164730 210 ) - NEW met1 ( 153870 175610 210 ) ( * 176460 210 ) - NEW met1 TAPER ( 153870 176460 ) ( * 177990 ) - NEW met1 TAPER ( 153870 177990 ) ( 154790 * ) - NEW met1 ( 153870 175610 210 ) ( 165830 * 210 ) - NEW met2 ( 165830 175610 210 ) ( * 207000 210 ) + NEW met2 ( 165830 175610 210 ) ( * 178500 210 ) + NEW met1 ( 170890 172550 210 ) ( 192050 * 210 ) + NEW met2 ( 170890 170510 210 ) ( * 175610 210 ) + NEW met2 ( 192050 153850 210 ) ( * 172550 210 ) + NEW met2 ( 192050 172550 210 ) ( * 191590 210 ) + NEW met1 ( 192050 178330 210 ) ( 207000 * 210 ) + NEW met2 ( 165830 178500 210 ) ( * 207000 210 ) NEW met2 ( 163990 207000 210 ) ( 165830 * 210 ) NEW met2 ( 163990 207000 210 ) ( * 210630 210 ) + NEW li1 TAPER ( 170890 170510 ) L1M1_PR_R + NEW met1 TAPER ( 170890 170510 ) M1M2_PR_R NEW li1 TAPER ( 192050 191590 ) L1M1_PR_R NEW met1 TAPER ( 192050 191590 ) M1M2_PR_R - NEW met1 ( 192050 194310 ) M1M2_PR_R - NEW li1 TAPER ( 205850 194310 ) L1M1_PR_R - NEW met1 ( 192050 177990 ) M1M2_PR_R - NEW li1 TAPER ( 207230 177990 ) L1M1_PR_R NEW li1 TAPER ( 201250 164730 ) L1M1_PR_R NEW met1 ( 192050 164730 ) M1M2_PR_R - NEW met1 ( 165830 175610 ) M1M2_PR_R - NEW li1 TAPER ( 173190 175610 ) L1M1_PR_R - NEW li1 TAPER ( 170430 170510 ) L1M1_PR_R - NEW met1 TAPER ( 170430 170510 ) M1M2_PR_R - NEW met1 ( 170430 175610 ) M1M2_PR_R - NEW met1 ( 170430 177990 ) M1M2_PR_R + NEW li1 TAPER ( 205850 194310 ) L1M1_PR_R + NEW met1 ( 192050 194310 ) M1M2_PR_R NEW li1 TAPER ( 192050 153850 ) L1M1_PR_R NEW met1 TAPER ( 192050 153850 ) M1M2_PR_R - NEW li1 TAPER ( 154790 177990 ) L1M1_PR_R + NEW li1 TAPER ( 207230 178330 ) L1M1_PR_R + NEW met2 ( 165830 178500 ) M2M3_PR + NEW met2 ( 154790 178500 ) M2M3_PR + NEW li1 TAPER ( 154790 178330 ) L1M1_PR_R + NEW met1 TAPER ( 154790 178330 ) M1M2_PR_R + NEW li1 TAPER ( 173190 175610 ) L1M1_PR_R + NEW met1 ( 165830 175610 ) M1M2_PR_R + NEW met1 ( 170890 175610 ) M1M2_PR_R + NEW met1 ( 192050 172550 ) M1M2_PR_R + NEW met1 ( 170890 172550 ) M1M2_PR_R + NEW met1 ( 192050 178330 ) M1M2_PR_R NEW li1 TAPER ( 163990 210630 ) L1M1_PR_R NEW met1 TAPER ( 163990 210630 ) M1M2_PR_R ; - ctrl.state.out\[1\] ( _412_ Q ) ( _290_ B2 ) ( _285_ A ) + USE SIGNAL - + ROUTED met1 ( 167670 208250 ) ( 170890 * ) - NEW met2 ( 170890 208250 ) ( * 209950 ) - NEW met2 ( 170890 205530 ) ( * 208250 ) + + ROUTED met2 ( 170890 205530 ) ( * 209950 ) + NEW met1 ( 167670 207910 ) ( 170890 * ) NEW li1 ( 170890 205530 ) L1M1_PR_MR NEW met1 ( 170890 205530 ) M1M2_PR - NEW li1 ( 167670 208250 ) L1M1_PR_MR - NEW met1 ( 170890 208250 ) M1M2_PR NEW li1 ( 170890 209950 ) L1M1_PR_MR - NEW met1 ( 170890 209950 ) M1M2_PR ; + NEW met1 ( 170890 209950 ) M1M2_PR + NEW li1 ( 167670 207910 ) L1M1_PR_MR + NEW met1 ( 170890 207910 ) M1M2_PR ; - ctrl.state.out\[2\] ( _413_ Q ) ( _297_ A ) ( _293_ A ) ( _290_ A1 ) ( _284_ A ) ( _279_ A ) + USE SIGNAL - + ROUTED met1 ( 158010 209950 ) ( 158470 * ) - NEW met2 ( 158010 207570 ) ( * 209950 ) - NEW met2 ( 158010 209950 ) ( * 213350 ) - NEW met1 ( 158010 207570 ) ( 166290 * ) - NEW met2 ( 158010 194650 ) ( * 200090 ) + + ROUTED met2 ( 158010 194650 ) ( * 200090 ) NEW met2 ( 158010 191590 ) ( * 194650 ) - NEW met2 ( 158010 200090 ) ( * 207570 ) NEW met1 ( 158010 194650 ) ( 167210 * ) + NEW met2 ( 158010 200090 ) ( * 207000 ) + NEW met2 ( 158470 207910 ) ( * 209950 ) + NEW met1 ( 158470 207910 ) ( 166290 * ) + NEW met2 ( 158010 207000 ) ( 158470 * ) + NEW met2 ( 158470 207000 ) ( * 207910 ) + NEW met1 ( 158010 213350 ) ( 158470 * ) + NEW met2 ( 158470 209950 ) ( * 213350 ) NEW li1 ( 167210 194650 ) L1M1_PR_MR - NEW met1 ( 158010 207570 ) M1M2_PR - NEW li1 ( 158470 209950 ) L1M1_PR_MR - NEW met1 ( 158010 209950 ) M1M2_PR - NEW li1 ( 158010 213350 ) L1M1_PR_MR - NEW met1 ( 158010 213350 ) M1M2_PR - NEW li1 ( 166290 207570 ) L1M1_PR_MR NEW li1 ( 158010 200090 ) L1M1_PR_MR NEW met1 ( 158010 200090 ) M1M2_PR NEW met1 ( 158010 194650 ) M1M2_PR NEW li1 ( 158010 191590 ) L1M1_PR_MR - NEW met1 ( 158010 191590 ) M1M2_PR ; + NEW met1 ( 158010 191590 ) M1M2_PR + NEW li1 ( 158470 209950 ) L1M1_PR_MR + NEW met1 ( 158470 209950 ) M1M2_PR + NEW met1 ( 158470 207910 ) M1M2_PR + NEW li1 ( 166290 207910 ) L1M1_PR_MR + NEW li1 ( 158010 213350 ) L1M1_PR_MR + NEW met1 ( 158470 213350 ) M1M2_PR ; END NETS END DESIGN diff --git a/src/drt/test/ndr_vias2.defok b/src/drt/test/ndr_vias2.defok index 706f5c44c5d..0bfa170bfe9 100644 --- a/src/drt/test/ndr_vias2.defok +++ b/src/drt/test/ndr_vias2.defok @@ -228,123 +228,116 @@ NETS 8 ; + ROUTED met1 TAPER ( 167900 169830 ) ( 169510 * ) NEW met1 TAPER ( 167900 118490 ) ( 169510 * ) NEW met2 ( 146970 169830 210 ) ( * 172890 210 ) + NEW met1 TAPER ( 130870 172890 ) ( 132710 * ) + NEW met1 ( 132710 172890 210 ) ( 146970 * 210 ) NEW met1 ( 146970 169830 210 ) ( 167900 * 210 ) - NEW met2 ( 151110 158700 210 ) ( * 169830 210 ) - NEW met1 ( 152950 118150 210 ) ( * 118490 210 ) - NEW met1 ( 118910 118150 210 ) ( 152950 * 210 ) - NEW met1 ( 118910 118150 210 ) ( * 118490 210 ) - NEW met1 TAPER ( 116610 118490 ) ( 118220 * ) - NEW met1 ( 118220 118490 210 ) ( 118910 * 210 ) NEW met1 TAPER ( 151570 150450 ) ( 152490 * ) - NEW met2 ( 151570 118150 210 ) ( * 150450 210 ) - NEW met2 ( 151110 158700 210 ) ( 151570 * 210 ) - NEW met2 ( 151570 150450 210 ) ( * 158700 210 ) - NEW met1 ( 152950 118490 210 ) ( 167900 * 210 ) - NEW met1 TAPER ( 130870 172890 ) ( 131100 * ) - NEW met1 ( 131100 172890 210 ) ( 131790 * 210 ) - NEW met2 ( 131790 172890 210 ) ( * 173060 210 ) - NEW met3 ( 131790 173060 450 ) ( 134550 * 450 ) - NEW met2 ( 134550 172890 210 ) ( * 173060 210 ) - NEW met1 ( 134550 172890 210 ) ( 146970 * 210 ) + NEW met2 ( 151570 118490 210 ) ( * 150450 210 ) + NEW met2 ( 151570 150450 210 ) ( * 169830 210 ) + NEW met2 ( 139150 118490 210 ) ( * 120020 210 ) + NEW met3 ( 116610 120020 450 ) ( 139150 * 450 ) + NEW met2 ( 116610 118830 210 ) ( * 120020 210 ) + NEW met1 ( 139150 118490 210 ) ( 167900 * 210 ) NEW li1 TAPER ( 169510 169830 ) L1M1_PR_R NEW li1 TAPER ( 169510 118490 ) L1M1_PR_R NEW met1 ( 146970 169830 ) M1M2_PR_R NEW met1 ( 146970 172890 ) M1M2_PR_R NEW li1 TAPER ( 130870 172890 ) L1M1_PR_R - NEW met1 ( 151110 169830 ) M1M2_PR_R - NEW li1 TAPER ( 116610 118490 ) L1M1_PR_R + NEW met1 ( 151570 169830 ) M1M2_PR_R NEW li1 TAPER ( 152490 150450 ) L1M1_PR_R NEW met1 TAPER ( 151570 150450 ) M1M2_PR_R - NEW met1 ( 151570 118150 ) M1M2_PR_R - NEW met1 ( 131790 172890 ) M1M2_PR_R - NEW met2 ( 131790 173060 ) M2M3_PR_R - NEW met2 ( 134550 173060 ) M2M3_PR_R - NEW met1 ( 134550 172890 ) M1M2_PR_R ; + NEW met1 ( 151570 118490 ) M1M2_PR_R + NEW met1 ( 139150 118490 ) M1M2_PR_R + NEW met2 ( 139150 120020 ) M2M3_PR_R + NEW met2 ( 116610 120020 ) M2M3_PR_R + NEW li1 TAPER ( 116610 118830 ) L1M1_PR_R + NEW met1 TAPER ( 116610 118830 ) M1M2_PR_R ; - clknet_2_0__leaf_clk ( _414_ CLK ) ( _418_ CLK ) ( _428_ CLK ) ( _429_ CLK ) ( _432_ CLK ) ( _434_ CLK ) ( _444_ CLK ) ( _445_ CLK ) ( clkbuf_2_0__f_clk X ) + USE CLOCK + NONDEFAULTRULE NDR_3W_3S - + ROUTED met1 ( 88550 120870 210 ) ( 91540 * 210 ) - NEW met1 TAPER ( 91540 120870 ) ( 93150 * ) - NEW met2 ( 88550 104890 210 ) ( * 120870 210 ) - NEW met1 TAPER ( 88550 104890 ) ( 89470 * ) + + ROUTED met1 TAPER ( 88550 104890 ) ( 89470 * ) NEW met1 ( 143750 88570 210 ) ( 144900 * 210 ) NEW met1 TAPER ( 144900 88570 ) ( 146510 * ) - NEW met1 ( 88550 118490 210 ) ( 110400 * 210 ) - NEW met1 TAPER ( 125350 120870 ) ( * 121890 ) - NEW met1 TAPER ( 124430 121890 ) ( 125350 * ) - NEW met1 TAPER ( 124430 121890 ) ( * 122910 ) - NEW met1 ( 124430 122910 210 ) ( * 123590 210 ) - NEW met1 ( 124430 123590 210 ) ( 138230 * 210 ) - NEW met2 ( 117530 117810 210 ) ( * 117980 210 ) - NEW met2 ( 117070 117980 210 ) ( 117530 * 210 ) - NEW met2 ( 117070 117980 210 ) ( * 120870 210 ) - NEW met1 ( 117070 120870 210 ) ( 123740 * 210 ) - NEW met1 TAPER ( 123740 120870 ) ( 125350 * ) - NEW met1 ( 110400 117810 210 ) ( * 118490 210 ) - NEW met1 ( 110400 117810 210 ) ( 115460 * 210 ) - NEW met1 TAPER ( 115460 117810 ) ( 117530 * ) - NEW met2 ( 111090 117810 210 ) ( * 120870 210 ) - NEW met2 ( 111090 120870 210 ) ( * 134810 210 ) + NEW met2 ( 88550 104890 210 ) ( * 120870 210 ) NEW met1 ( 138230 115770 210 ) ( 142140 * 210 ) NEW met1 TAPER ( 142140 115770 ) ( 143750 * ) - NEW met2 ( 138230 115770 210 ) ( * 123590 210 ) NEW met2 ( 143750 88570 210 ) ( * 115770 210 ) - NEW met2 ( 138230 123590 210 ) ( * 144900 210 ) NEW met2 ( 136850 144900 210 ) ( 138230 * 210 ) NEW met2 ( 136850 144900 210 ) ( * 148410 210 ) - NEW li1 TAPER ( 93150 120870 ) L1M1_PR_R - NEW met1 ( 88550 120870 ) M1M2_PR_R + NEW met2 ( 111090 124200 210 ) ( * 134810 210 ) + NEW met1 TAPER ( 91540 120870 ) ( 93150 * ) + NEW met2 ( 110630 124200 210 ) ( 111090 * 210 ) + NEW met2 ( 110630 117810 210 ) ( * 124200 210 ) + NEW met2 ( 117990 117980 210 ) ( * 118150 210 ) + NEW met3 ( 110630 117980 450 ) ( 117990 * 450 ) + NEW met2 ( 125350 118150 210 ) ( * 120870 210 ) + NEW met1 TAPER ( 117990 118150 ) ( 120060 * ) + NEW met1 ( 120060 118150 210 ) ( 125350 * 210 ) + NEW met1 ( 125350 118150 210 ) ( 138230 * 210 ) + NEW met1 TAPER ( 110630 121210 ) ( 111090 * ) + NEW met1 ( 88550 117810 210 ) ( 110630 * 210 ) + NEW met1 ( 88550 120870 210 ) ( 91540 * 210 ) + NEW met2 ( 138230 115770 210 ) ( * 118150 210 ) + NEW met2 ( 138230 118150 210 ) ( * 144900 210 ) NEW met1 TAPER ( 88550 104890 ) M1M2_PR_R NEW li1 TAPER ( 89470 104890 ) L1M1_PR_R - NEW met1 ( 88550 118490 ) M1M2_PR_R NEW met1 ( 143750 88570 ) M1M2_PR_R NEW li1 TAPER ( 146510 88570 ) L1M1_PR_R - NEW li1 TAPER ( 125350 120870 ) L1M1_PR_R - NEW met1 ( 138230 123590 ) M1M2_PR_R - NEW li1 TAPER ( 117530 117810 ) L1M1_PR_R - NEW met1 TAPER ( 117530 117810 ) M1M2_PR_R - NEW met1 ( 117070 120870 ) M1M2_PR_R - NEW li1 TAPER ( 111090 120870 ) L1M1_PR_R - NEW met1 TAPER ( 111090 120870 ) M1M2_PR_R - NEW met1 ( 111090 117810 ) M1M2_PR_R + NEW met1 ( 88550 120870 ) M1M2_PR_R + NEW met1 ( 88550 117810 ) M1M2_PR_R NEW li1 TAPER ( 111090 134810 ) L1M1_PR_R NEW met1 TAPER ( 111090 134810 ) M1M2_PR_R NEW li1 TAPER ( 143750 115770 ) L1M1_PR_R NEW met1 ( 138230 115770 ) M1M2_PR_R NEW met1 TAPER ( 143750 115770 ) M1M2_PR_R NEW li1 TAPER ( 136850 148410 ) L1M1_PR_R - NEW met1 TAPER ( 136850 148410 ) M1M2_PR_R ; + NEW met1 TAPER ( 136850 148410 ) M1M2_PR_R + NEW li1 TAPER ( 93150 120870 ) L1M1_PR_R + NEW met1 ( 110630 117810 ) M1M2_PR_R + NEW li1 TAPER ( 117990 118150 ) L1M1_PR_R + NEW met1 TAPER ( 117990 118150 ) M1M2_PR_R + NEW met2 ( 117990 117980 ) M2M3_PR_R + NEW met2 ( 110630 117980 ) M2M3_PR_R + NEW li1 TAPER ( 125350 120870 ) L1M1_PR_R + NEW met1 TAPER ( 125350 120870 ) M1M2_PR_R + NEW met1 ( 125350 118150 ) M1M2_PR_R + NEW met1 ( 138230 118150 ) M1M2_PR_R + NEW li1 TAPER ( 111090 121210 ) L1M1_PR_R + NEW met1 TAPER ( 110630 121210 ) M1M2_PR_R ; - clknet_2_1__leaf_clk ( _423_ CLK ) ( _424_ CLK ) ( _425_ CLK ) ( _426_ CLK ) ( _427_ CLK ) ( _440_ CLK ) ( _441_ CLK ) ( _442_ CLK ) ( _443_ CLK ) ( clkbuf_2_1__f_clk X ) + USE CLOCK + NONDEFAULTRULE NDR_3W_3S - + ROUTED met1 ( 199410 96390 210 ) ( 204010 * 210 ) + + ROUTED met2 ( 158010 90100 210 ) ( * 102170 210 ) NEW met1 TAPER ( 204010 96390 ) ( 205850 * ) - NEW met1 TAPER ( 178710 90950 ) ( * 91970 ) - NEW met1 TAPER ( 177790 91970 ) ( 178710 * ) - NEW met1 TAPER ( 177790 91970 ) ( * 92990 ) - NEW met1 ( 177790 92990 210 ) ( * 93670 210 ) - NEW met1 ( 177790 93670 210 ) ( 199410 * 210 ) - NEW met2 ( 199410 93670 210 ) ( * 96390 210 ) - NEW met1 TAPER ( 177100 90950 ) ( 178710 * ) NEW met1 ( 199410 129370 210 ) ( 204700 * 210 ) NEW met1 TAPER ( 204700 129370 ) ( 206310 * ) NEW met2 ( 199410 129370 210 ) ( * 137190 210 ) NEW met1 ( 199410 113050 210 ) ( 204700 * 210 ) NEW met1 TAPER ( 204700 113050 ) ( 206310 * ) NEW met2 ( 199410 113050 210 ) ( * 129370 210 ) - NEW met2 ( 199410 96390 210 ) ( * 113050 210 ) + NEW met2 ( 199410 110400 210 ) ( 199870 * 210 ) + NEW met2 ( 199410 110400 210 ) ( * 113050 210 ) NEW met1 ( 152950 129370 210 ) ( 154330 * 210 ) NEW met1 TAPER ( 154330 129370 ) ( 156170 * ) - NEW met2 ( 171350 118830 210 ) ( * 120870 210 ) - NEW met1 ( 156170 120870 210 ) ( 171350 * 210 ) - NEW met2 ( 156170 120870 210 ) ( * 129370 210 ) - NEW met2 ( 158010 102170 210 ) ( * 120870 210 ) - NEW met2 ( 158010 90950 210 ) ( * 102170 210 ) NEW met2 ( 152950 129370 210 ) ( * 148070 210 ) + NEW met1 ( 158930 90950 210 ) ( 164450 * 210 ) + NEW met2 ( 158930 90100 210 ) ( * 90950 210 ) + NEW met1 ( 164450 90950 210 ) ( 177100 * 210 ) + NEW met1 TAPER ( 177100 90950 ) ( 178710 * ) + NEW met1 ( 178710 96390 210 ) ( 199870 * 210 ) + NEW met2 ( 178710 90950 210 ) ( * 96390 210 ) + NEW met2 ( 158010 90100 210 ) ( 158930 * 210 ) NEW met2 ( 164450 88230 210 ) ( * 90950 210 ) - NEW met1 ( 158010 90950 210 ) ( 177100 * 210 ) + NEW met2 ( 199870 96390 210 ) ( * 110400 210 ) + NEW met1 ( 199870 96390 210 ) ( 204010 * 210 ) + NEW met1 ( 158010 117470 210 ) ( 168130 * 210 ) + NEW met1 TAPER ( 168130 117470 ) ( 169510 * ) + NEW met1 TAPER ( 169510 117470 ) ( * 117810 ) + NEW met1 TAPER ( 169510 117810 ) ( 170430 * ) + NEW met1 ( 156170 117470 210 ) ( 158010 * 210 ) + NEW met2 ( 156170 117470 210 ) ( * 129370 210 ) + NEW met2 ( 158010 102170 210 ) ( * 117470 210 ) + NEW li1 TAPER ( 158010 102170 ) L1M1_PR_R + NEW met1 TAPER ( 158010 102170 ) M1M2_PR_R NEW li1 TAPER ( 205850 96390 ) L1M1_PR_R - NEW met1 ( 199410 96390 ) M1M2_PR_R - NEW li1 TAPER ( 178710 90950 ) L1M1_PR_R - NEW met1 ( 199410 93670 ) M1M2_PR_R NEW li1 TAPER ( 164450 88230 ) L1M1_PR_R NEW met1 TAPER ( 164450 88230 ) M1M2_PR_R NEW li1 TAPER ( 206310 129370 ) L1M1_PR_R @@ -353,156 +346,164 @@ NETS 8 ; NEW met1 TAPER ( 199410 137190 ) M1M2_PR_R NEW li1 TAPER ( 206310 113050 ) L1M1_PR_R NEW met1 ( 199410 113050 ) M1M2_PR_R - NEW li1 TAPER ( 152950 148070 ) L1M1_PR_R - NEW met1 TAPER ( 152950 148070 ) M1M2_PR_R NEW li1 TAPER ( 156170 129370 ) L1M1_PR_R NEW met1 ( 152950 129370 ) M1M2_PR_R - NEW li1 TAPER ( 171350 118830 ) L1M1_PR_R - NEW met1 TAPER ( 171350 118830 ) M1M2_PR_R - NEW met1 ( 171350 120870 ) M1M2_PR_R - NEW met1 ( 156170 120870 ) M1M2_PR_R + NEW li1 TAPER ( 152950 148070 ) L1M1_PR_R + NEW met1 TAPER ( 152950 148070 ) M1M2_PR_R NEW met1 TAPER ( 156170 129370 ) M1M2_PR_R - NEW li1 TAPER ( 158010 102170 ) L1M1_PR_R - NEW met1 TAPER ( 158010 102170 ) M1M2_PR_R - NEW met1 ( 158010 120870 ) M1M2_PR_R - NEW met1 ( 158010 90950 ) M1M2_PR_R - NEW met1 ( 164450 90950 ) M1M2_PR_R ; + NEW met1 ( 164450 90950 ) M1M2_PR_R + NEW met1 ( 158930 90950 ) M1M2_PR_R + NEW li1 TAPER ( 178710 90950 ) L1M1_PR_R + NEW met1 ( 199870 96390 ) M1M2_PR_R + NEW met1 ( 178710 96390 ) M1M2_PR_R + NEW met1 TAPER ( 178710 90950 ) M1M2_PR_R + NEW met1 ( 158010 117470 ) M1M2_PR_R + NEW li1 TAPER ( 170430 117810 ) L1M1_PR_R + NEW met1 ( 156170 117470 ) M1M2_PR_R ; - clknet_2_2__leaf_clk ( _411_ CLK ) ( _413_ CLK ) ( _415_ CLK ) ( _416_ CLK ) ( _417_ CLK ) ( _421_ CLK ) ( _430_ CLK ) ( _431_ CLK ) ( _433_ CLK ) ( _437_ CLK ) ( clkbuf_2_2__f_clk X ) + USE CLOCK + NONDEFAULTRULE NDR_3W_3S - + ROUTED met1 TAPER ( 108330 183770 ) ( 109250 * ) - NEW met1 TAPER ( 108330 183770 ) ( * 185470 ) - NEW met1 ( 108330 185470 210 ) ( * 186150 210 ) - NEW met2 ( 96830 183770 210 ) ( * 186150 210 ) - NEW met1 ( 96830 183770 210 ) ( 107410 * 210 ) - NEW met1 TAPER ( 107410 183770 ) ( 108330 * ) - NEW met1 TAPER ( 98210 151130 ) ( 100050 * ) - NEW met2 ( 98210 151130 210 ) ( * 183770 210 ) - NEW met1 TAPER ( 136850 210630 ) ( 137770 * ) - NEW met1 ( 136850 208250 210 ) ( * 209100 210 ) - NEW met1 TAPER ( 136850 209100 ) ( * 210630 ) - NEW met1 ( 136850 208250 210 ) ( 146970 * 210 ) - NEW met1 ( 146970 208250 210 ) ( * 210630 210 ) - NEW met1 ( 146970 210630 210 ) ( 148810 * 210 ) - NEW met1 TAPER ( 148810 210630 ) ( 150595 * ) - NEW met1 ( 126270 208250 210 ) ( 136850 * 210 ) + + ROUTED met1 ( 137770 175270 210 ) ( 139380 * 210 ) NEW met1 TAPER ( 139380 175270 ) ( 140990 * ) + NEW met1 ( 137770 159290 210 ) ( 142140 * 210 ) NEW met1 TAPER ( 142140 159290 ) ( 143750 * ) - NEW met2 ( 125810 181050 210 ) ( * 183770 210 ) - NEW met1 ( 125810 181050 210 ) ( 131790 * 210 ) NEW met2 ( 125810 206380 210 ) ( 126270 * 210 ) - NEW met2 ( 125810 183770 210 ) ( * 206380 210 ) - NEW met2 ( 111550 197370 210 ) ( * 200090 210 ) - NEW met1 ( 111550 197370 210 ) ( 125810 * 210 ) - NEW met1 TAPER ( 125810 199750 ) ( 126270 * ) - NEW met1 ( 108330 186150 210 ) ( 125810 * 210 ) - NEW met2 ( 126270 206380 210 ) ( * 208250 210 ) + NEW met1 ( 126270 210630 210 ) ( 135930 * 210 ) + NEW met1 TAPER ( 135930 210630 ) ( 137770 * ) + NEW met1 TAPER ( 150190 210630 ) ( 150650 * ) + NEW met2 ( 150190 210460 210 ) ( * 210630 210 ) + NEW met3 ( 137770 210460 450 ) ( 150190 * 450 ) + NEW met2 ( 137770 210460 210 ) ( * 210630 210 ) + NEW met2 ( 126270 206380 210 ) ( * 210630 210 ) + NEW met3 ( 131790 172380 450 ) ( 137770 * 450 ) + NEW met2 ( 131790 172210 210 ) ( * 172380 210 ) NEW met2 ( 137770 159290 210 ) ( * 175270 210 ) - NEW met1 ( 131790 175270 210 ) ( 137770 * 210 ) - NEW met1 TAPER ( 132710 173230 ) ( 133630 * ) - NEW met1 TAPER ( 133630 173230 ) ( * 175270 ) - NEW met2 ( 131790 175270 210 ) ( * 181050 210 ) - NEW met1 ( 137770 159290 210 ) ( 142140 * 210 ) - NEW met1 ( 137770 175270 210 ) ( 139380 * 210 ) - NEW met1 ( 126270 208250 ) M1M2_PR_R - NEW li1 TAPER ( 109250 183770 ) L1M1_PR_R - NEW li1 TAPER ( 96830 186150 ) L1M1_PR_R - NEW met1 TAPER ( 96830 186150 ) M1M2_PR_R - NEW met1 ( 96830 183770 ) M1M2_PR_R - NEW met1 ( 98210 183770 ) M1M2_PR_R - NEW met1 ( 98210 151130 ) M1M2_PR_R - NEW li1 TAPER ( 100050 151130 ) L1M1_PR_R - NEW li1 TAPER ( 137770 210630 ) L1M1_PR_R - NEW li1 TAPER ( 150595 210630 ) L1M1_PR_R + NEW met1 ( 96830 183090 210 ) ( 100050 * 210 ) + NEW met2 ( 96830 183090 210 ) ( * 186150 210 ) + NEW met1 ( 100050 183430 210 ) ( 107410 * 210 ) + NEW met1 TAPER ( 107410 183430 ) ( 109250 * ) + NEW met1 ( 100050 183090 210 ) ( * 183430 210 ) + NEW met1 ( 109250 186150 210 ) ( 125810 * 210 ) + NEW met2 ( 109250 183430 210 ) ( * 186150 210 ) + NEW met2 ( 125810 183770 210 ) ( * 186150 210 ) + NEW met1 ( 125810 179690 210 ) ( 131790 * 210 ) + NEW met2 ( 125810 179690 210 ) ( * 183770 210 ) + NEW met2 ( 100050 151130 210 ) ( * 183090 210 ) + NEW met2 ( 131790 172380 210 ) ( * 179690 210 ) + NEW met3 ( 111550 199580 450 ) ( 125810 * 450 ) + NEW met2 ( 111550 199580 210 ) ( * 199750 210 ) + NEW met1 TAPER ( 125810 199750 ) ( 126270 * ) + NEW met2 ( 125810 186150 210 ) ( * 199580 210 ) + NEW met2 ( 125810 199580 210 ) ( * 206380 210 ) NEW li1 TAPER ( 140990 175270 ) L1M1_PR_R + NEW met1 ( 137770 175270 ) M1M2_PR_R + NEW met1 ( 137770 159290 ) M1M2_PR_R NEW li1 TAPER ( 143750 159290 ) L1M1_PR_R + NEW li1 TAPER ( 100050 151130 ) L1M1_PR_R + NEW met1 TAPER ( 100050 151130 ) M1M2_PR_R + NEW li1 TAPER ( 137770 210630 ) L1M1_PR_R + NEW met1 ( 126270 210630 ) M1M2_PR_R + NEW li1 TAPER ( 150650 210630 ) L1M1_PR_R + NEW met1 TAPER ( 150190 210630 ) M1M2_PR_R + NEW met2 ( 150190 210460 ) M2M3_PR_R + NEW met2 ( 137770 210460 ) M2M3_PR_R + NEW met1 TAPER ( 137770 210630 ) M1M2_PR_R + NEW met2 ( 131790 172380 ) M2M3_PR_R + NEW met2 ( 137770 172380 ) M2M3_PR_R + NEW li1 TAPER ( 131790 172210 ) L1M1_PR_R + NEW met1 TAPER ( 131790 172210 ) M1M2_PR_R + NEW met1 ( 100050 183090 ) M1M2_PR_R + NEW met1 ( 96830 183090 ) M1M2_PR_R + NEW li1 TAPER ( 96830 186150 ) L1M1_PR_R + NEW met1 TAPER ( 96830 186150 ) M1M2_PR_R + NEW li1 TAPER ( 109250 183430 ) L1M1_PR_R + NEW met1 ( 125810 186150 ) M1M2_PR_R + NEW met1 ( 109250 186150 ) M1M2_PR_R + NEW met1 TAPER ( 109250 183430 ) M1M2_PR_R NEW li1 TAPER ( 125810 183770 ) L1M1_PR_R NEW met1 TAPER ( 125810 183770 ) M1M2_PR_R - NEW met1 ( 125810 181050 ) M1M2_PR_R - NEW met1 ( 131790 181050 ) M1M2_PR_R - NEW li1 TAPER ( 111550 200090 ) L1M1_PR_R - NEW met1 TAPER ( 111550 200090 ) M1M2_PR_R - NEW met1 ( 111550 197370 ) M1M2_PR_R - NEW met1 ( 125810 197370 ) M1M2_PR_R + NEW met1 ( 131790 179690 ) M1M2_PR_R + NEW met1 ( 125810 179690 ) M1M2_PR_R + NEW met2 ( 125810 199580 ) M2M3_PR_R + NEW met2 ( 111550 199580 ) M2M3_PR_R + NEW li1 TAPER ( 111550 199750 ) L1M1_PR_R + NEW met1 TAPER ( 111550 199750 ) M1M2_PR_R NEW li1 TAPER ( 126270 199750 ) L1M1_PR_R - NEW met1 TAPER ( 125810 199750 ) M1M2_PR_R - NEW met1 ( 125810 186150 ) M1M2_PR_R - NEW met1 ( 137770 175270 ) M1M2_PR_R - NEW met1 ( 137770 159290 ) M1M2_PR_R - NEW met1 ( 131790 175270 ) M1M2_PR_R - NEW li1 TAPER ( 132710 173230 ) L1M1_PR_R ; + NEW met1 TAPER ( 125810 199750 ) M1M2_PR_R ; - clknet_2_3__leaf_clk ( _412_ CLK ) ( _419_ CLK ) ( _420_ CLK ) ( _422_ CLK ) ( _435_ CLK ) ( _436_ CLK ) ( _438_ CLK ) ( _439_ CLK ) ( clkbuf_2_3__f_clk X ) + USE CLOCK + NONDEFAULTRULE NDR_3W_3S - + ROUTED met2 ( 192050 191590 210 ) ( * 194310 210 ) + + ROUTED met1 ( 192050 164730 210 ) ( 199410 * 210 ) + NEW met1 TAPER ( 199410 164730 ) ( 201250 * ) NEW met1 ( 192050 194310 210 ) ( 204010 * 210 ) NEW met1 TAPER ( 204010 194310 ) ( 205850 * ) - NEW met1 ( 192050 177990 210 ) ( 205620 * 210 ) - NEW met1 TAPER ( 205620 177990 ) ( 207230 * ) - NEW met1 ( 192050 164730 210 ) ( 199535 * 210 ) - NEW met1 TAPER ( 199535 164730 ) ( 201250 * ) - NEW met2 ( 192050 164730 210 ) ( * 177990 210 ) - NEW met2 ( 192050 177990 210 ) ( * 191590 210 ) + NEW met2 ( 192050 191590 210 ) ( * 194310 210 ) + NEW met1 TAPER ( 207000 178330 ) ( 207230 * ) + NEW met3 ( 154790 178500 450 ) ( 165830 * 450 ) + NEW met2 ( 154790 178330 210 ) ( * 178500 210 ) NEW met1 ( 165830 175610 210 ) ( 171580 * 210 ) NEW met1 TAPER ( 171580 175610 ) ( 173190 * ) - NEW met2 ( 170430 170510 210 ) ( * 175610 210 ) - NEW met2 ( 170430 175610 210 ) ( * 177990 210 ) - NEW met1 ( 170430 177990 210 ) ( 192050 * 210 ) - NEW met2 ( 192050 153850 210 ) ( * 164730 210 ) - NEW met1 ( 153870 175610 210 ) ( * 176460 210 ) - NEW met1 TAPER ( 153870 176460 ) ( * 177990 ) - NEW met1 TAPER ( 153870 177990 ) ( 154790 * ) - NEW met1 ( 153870 175610 210 ) ( 165830 * 210 ) - NEW met2 ( 165830 175610 210 ) ( * 207000 210 ) + NEW met2 ( 165830 175610 210 ) ( * 178500 210 ) + NEW met1 ( 170890 172550 210 ) ( 192050 * 210 ) + NEW met2 ( 170890 170510 210 ) ( * 175610 210 ) + NEW met2 ( 192050 153850 210 ) ( * 172550 210 ) + NEW met2 ( 192050 172550 210 ) ( * 191590 210 ) + NEW met1 ( 192050 178330 210 ) ( 207000 * 210 ) + NEW met2 ( 165830 178500 210 ) ( * 207000 210 ) NEW met2 ( 163990 207000 210 ) ( 165830 * 210 ) NEW met2 ( 163990 207000 210 ) ( * 210630 210 ) + NEW li1 TAPER ( 170890 170510 ) L1M1_PR_R + NEW met1 TAPER ( 170890 170510 ) M1M2_PR_R NEW li1 TAPER ( 192050 191590 ) L1M1_PR_R NEW met1 TAPER ( 192050 191590 ) M1M2_PR_R - NEW met1 ( 192050 194310 ) M1M2_PR_R - NEW li1 TAPER ( 205850 194310 ) L1M1_PR_R - NEW met1 ( 192050 177990 ) M1M2_PR_R - NEW li1 TAPER ( 207230 177990 ) L1M1_PR_R NEW li1 TAPER ( 201250 164730 ) L1M1_PR_R NEW met1 ( 192050 164730 ) M1M2_PR_R - NEW met1 ( 165830 175610 ) M1M2_PR_R - NEW li1 TAPER ( 173190 175610 ) L1M1_PR_R - NEW li1 TAPER ( 170430 170510 ) L1M1_PR_R - NEW met1 TAPER ( 170430 170510 ) M1M2_PR_R - NEW met1 ( 170430 175610 ) M1M2_PR_R - NEW met1 ( 170430 177990 ) M1M2_PR_R + NEW li1 TAPER ( 205850 194310 ) L1M1_PR_R + NEW met1 ( 192050 194310 ) M1M2_PR_R NEW li1 TAPER ( 192050 153850 ) L1M1_PR_R NEW met1 TAPER ( 192050 153850 ) M1M2_PR_R - NEW li1 TAPER ( 154790 177990 ) L1M1_PR_R + NEW li1 TAPER ( 207230 178330 ) L1M1_PR_R + NEW met2 ( 165830 178500 ) M2M3_PR_R + NEW met2 ( 154790 178500 ) M2M3_PR_R + NEW li1 TAPER ( 154790 178330 ) L1M1_PR_R + NEW met1 TAPER ( 154790 178330 ) M1M2_PR_R + NEW li1 TAPER ( 173190 175610 ) L1M1_PR_R + NEW met1 ( 165830 175610 ) M1M2_PR_R + NEW met1 ( 170890 175610 ) M1M2_PR_R + NEW met1 ( 192050 172550 ) M1M2_PR_R + NEW met1 ( 170890 172550 ) M1M2_PR_R + NEW met1 ( 192050 178330 ) M1M2_PR_R NEW li1 TAPER ( 163990 210630 ) L1M1_PR_R NEW met1 TAPER ( 163990 210630 ) M1M2_PR_R ; - ctrl.state.out\[1\] ( _412_ Q ) ( _290_ B2 ) ( _285_ A ) + USE SIGNAL - + ROUTED met1 ( 167670 208250 ) ( 170890 * ) - NEW met2 ( 170890 208250 ) ( * 209950 ) - NEW met2 ( 170890 205530 ) ( * 208250 ) + + ROUTED met2 ( 170890 205530 ) ( * 209950 ) + NEW met1 ( 167670 207910 ) ( 170890 * ) NEW li1 ( 170890 205530 ) L1M1_PR_MR NEW met1 ( 170890 205530 ) M1M2_PR - NEW li1 ( 167670 208250 ) L1M1_PR_MR - NEW met1 ( 170890 208250 ) M1M2_PR NEW li1 ( 170890 209950 ) L1M1_PR_MR - NEW met1 ( 170890 209950 ) M1M2_PR ; + NEW met1 ( 170890 209950 ) M1M2_PR + NEW li1 ( 167670 207910 ) L1M1_PR_MR + NEW met1 ( 170890 207910 ) M1M2_PR ; - ctrl.state.out\[2\] ( _413_ Q ) ( _297_ A ) ( _293_ A ) ( _290_ A1 ) ( _284_ A ) ( _279_ A ) + USE SIGNAL - + ROUTED met1 ( 158010 209950 ) ( 158470 * ) - NEW met2 ( 158010 207570 ) ( * 209950 ) - NEW met2 ( 158010 209950 ) ( * 213350 ) - NEW met1 ( 158010 207570 ) ( 166290 * ) - NEW met2 ( 158010 194650 ) ( * 200090 ) + + ROUTED met2 ( 158010 194650 ) ( * 200090 ) NEW met2 ( 158010 191590 ) ( * 194650 ) - NEW met2 ( 158010 200090 ) ( * 207570 ) NEW met1 ( 158010 194650 ) ( 167210 * ) + NEW met2 ( 158010 200090 ) ( * 207000 ) + NEW met2 ( 158470 207910 ) ( * 209950 ) + NEW met1 ( 158470 207910 ) ( 166290 * ) + NEW met2 ( 158010 207000 ) ( 158470 * ) + NEW met2 ( 158470 207000 ) ( * 207910 ) + NEW met1 ( 158010 213350 ) ( 158470 * ) + NEW met2 ( 158470 209950 ) ( * 213350 ) NEW li1 ( 167210 194650 ) L1M1_PR_MR - NEW met1 ( 158010 207570 ) M1M2_PR - NEW li1 ( 158470 209950 ) L1M1_PR_MR - NEW met1 ( 158010 209950 ) M1M2_PR - NEW li1 ( 158010 213350 ) L1M1_PR_MR - NEW met1 ( 158010 213350 ) M1M2_PR - NEW li1 ( 166290 207570 ) L1M1_PR_MR NEW li1 ( 158010 200090 ) L1M1_PR_MR NEW met1 ( 158010 200090 ) M1M2_PR NEW met1 ( 158010 194650 ) M1M2_PR NEW li1 ( 158010 191590 ) L1M1_PR_MR - NEW met1 ( 158010 191590 ) M1M2_PR ; + NEW met1 ( 158010 191590 ) M1M2_PR + NEW li1 ( 158470 209950 ) L1M1_PR_MR + NEW met1 ( 158470 209950 ) M1M2_PR + NEW met1 ( 158470 207910 ) M1M2_PR + NEW li1 ( 166290 207910 ) L1M1_PR_MR + NEW li1 ( 158010 213350 ) L1M1_PR_MR + NEW met1 ( 158470 213350 ) M1M2_PR ; END NETS END DESIGN diff --git a/src/drt/test/ndr_vias3.defok b/src/drt/test/ndr_vias3.defok index c1e9c3b8f62..3a8a08a0a03 100644 --- a/src/drt/test/ndr_vias3.defok +++ b/src/drt/test/ndr_vias3.defok @@ -215,135 +215,134 @@ END PINS NETS 8 ; - clk ( PIN clk ) ( clkbuf_0_clk A ) + USE CLOCK + NONDEFAULTRULE NDR_3W_3S + ROUTED met2 ( 89470 340 0 ) ( * 150110 ) - NEW met1 ( 89470 150110 ) ( 131100 * ) - NEW met1 ( 131100 150110 ) ( * 151130 ) - NEW met1 ( 131100 151130 ) ( 149500 * ) + NEW met1 ( 89470 150110 ) ( 110400 * ) + NEW met1 ( 110400 150110 ) ( * 151130 ) + NEW met1 ( 110400 151130 ) ( 149500 * ) NEW met1 TAPER ( 149500 151130 ) ( 151110 * ) NEW met1 ( 89470 150110 ) M1M2_PR_R NEW li1 TAPER ( 151110 151130 ) L1M1_PR_R ; - clknet_0_clk ( clkbuf_2_3__f_clk A ) ( clkbuf_2_2__f_clk A ) ( clkbuf_2_1__f_clk A ) ( clkbuf_2_0__f_clk A ) ( clkbuf_0_clk X ) + USE CLOCK + NONDEFAULTRULE NDR_3W_3S - + ROUTED met1 TAPER ( 116610 118490 ) ( 118220 * ) - NEW met1 ( 118220 118490 ) ( 131100 * ) - NEW met1 ( 151570 118830 ) ( 167900 * ) - NEW met1 TAPER ( 167900 118830 ) ( 169510 * ) - NEW met1 ( 131100 118490 ) ( * 118830 ) - NEW met1 ( 131100 118830 ) ( 151570 * ) + + ROUTED met1 TAPER ( 167900 118830 ) ( 169510 * ) NEW met1 TAPER ( 130870 172890 ) ( 131100 * ) - NEW met1 ( 151110 169830 ) ( 167900 * ) + NEW met1 ( 151570 169830 ) ( 167900 * ) NEW met1 TAPER ( 167900 169830 ) ( 169510 * ) - NEW met2 ( 151110 169830 ) ( * 172890 ) - NEW met1 ( 131100 172890 ) ( 151110 * ) + NEW met2 ( 151570 169830 ) ( * 172890 ) + NEW met1 ( 131100 172890 ) ( 151570 * ) + NEW met1 ( 158700 118830 ) ( 167900 * ) + NEW met1 ( 158700 118490 ) ( * 118830 ) + NEW met1 TAPER ( 116610 118490 ) ( 118220 * ) + NEW met1 ( 118220 118490 ) ( 158700 * ) NEW met1 TAPER ( 151570 150450 ) ( 152030 * ) - NEW met2 ( 151570 150450 ) ( * 150620 ) - NEW met2 ( 151110 150620 ) ( 151570 * ) - NEW met2 ( 151110 150620 ) ( * 169830 ) - NEW met2 ( 151570 118830 ) ( * 150450 ) - NEW li1 TAPER ( 116610 118490 ) L1M1_PR_R + NEW met2 ( 151570 118490 ) ( * 150450 ) + NEW met2 ( 151570 150450 ) ( * 169830 ) NEW li1 TAPER ( 130870 172890 ) L1M1_PR_R - NEW met1 ( 151570 118830 ) M1M2_PR_R NEW li1 TAPER ( 169510 118830 ) L1M1_PR_R NEW li1 TAPER ( 169510 169830 ) L1M1_PR_R - NEW met1 ( 151110 169830 ) M1M2_PR_R - NEW met1 ( 151110 172890 ) M1M2_PR_R + NEW met1 ( 151570 169830 ) M1M2_PR_R + NEW met1 ( 151570 172890 ) M1M2_PR_R + NEW li1 TAPER ( 116610 118490 ) L1M1_PR_R NEW li1 TAPER ( 152030 150450 ) L1M1_PR_R - NEW met1 TAPER ( 151570 150450 ) M1M2_PR_R ; + NEW met1 TAPER ( 151570 150450 ) M1M2_PR_R + NEW met1 ( 151570 118490 ) M1M2_PR_R ; - clknet_2_0__leaf_clk ( _414_ CLK ) ( _418_ CLK ) ( _428_ CLK ) ( _429_ CLK ) ( _432_ CLK ) ( _434_ CLK ) ( _444_ CLK ) ( _445_ CLK ) ( clkbuf_2_0__f_clk X ) + USE CLOCK + NONDEFAULTRULE NDR_3W_3S - + ROUTED met1 ( 89010 120870 ) ( 91540 * ) - NEW met1 TAPER ( 91540 120870 ) ( 93150 * ) - NEW met2 ( 89010 104890 ) ( * 120870 ) + + ROUTED met2 ( 89010 104890 ) ( * 120870 ) NEW met1 TAPER ( 89010 104890 ) ( 89470 * ) + NEW met1 ( 143750 88570 ) ( 144900 * ) + NEW met1 TAPER ( 144900 88570 ) ( 146510 * ) + NEW met1 ( 117070 148070 ) ( 135010 * ) + NEW met1 TAPER ( 135010 148070 ) ( 136850 * ) + NEW met1 TAPER ( 111090 134810 ) ( 112930 * ) + NEW met1 ( 112930 134810 ) ( 117070 * ) + NEW met2 ( 143750 115770 ) ( * 120870 ) + NEW met2 ( 143750 88570 ) ( * 115770 ) + NEW met2 ( 117070 124200 ) ( * 148070 ) + NEW met1 TAPER ( 91540 120870 ) ( 93150 * ) NEW met1 TAPER ( 93150 120870 ) ( 95220 * ) NEW met1 ( 95220 120870 ) ( 109250 * ) NEW met1 TAPER ( 109250 120870 ) ( 111090 * ) - NEW met1 ( 111090 117810 ) ( 115460 * ) - NEW met1 TAPER ( 115460 117810 ) ( 117530 * ) - NEW met2 ( 111090 117810 ) ( * 120870 ) + NEW met2 ( 117530 117810 ) ( * 120870 ) NEW met1 TAPER ( 111090 120870 ) ( 112930 * ) - NEW met1 ( 112930 120870 ) ( 123740 * ) + NEW met1 ( 112930 120870 ) ( 117530 * ) + NEW met2 ( 117070 124200 ) ( 117530 * ) + NEW met2 ( 117530 120870 ) ( * 124200 ) + NEW met1 ( 117530 120870 ) ( 123740 * ) NEW met1 TAPER ( 123740 120870 ) ( 125350 * ) NEW met1 TAPER ( 125350 120870 ) ( 127420 * ) - NEW met2 ( 111090 134810 ) ( * 148070 ) - NEW met2 ( 111090 120870 ) ( * 134810 ) - NEW met2 ( 143750 88570 ) ( * 115430 ) - NEW met1 ( 143750 88570 ) ( 144900 * ) - NEW met1 TAPER ( 144900 88570 ) ( 146510 * ) - NEW met2 ( 143750 115430 ) ( * 120870 ) + NEW met1 ( 89010 120870 ) ( 91540 * ) NEW met1 ( 127420 120870 ) ( 143750 * ) - NEW met1 TAPER ( 135010 148070 ) ( 136850 * ) - NEW met1 ( 111090 148070 ) ( 135010 * ) - NEW li1 TAPER ( 93150 120870 ) L1M1_PR_R NEW met1 ( 89010 120870 ) M1M2_PR_R NEW met1 TAPER ( 89010 104890 ) M1M2_PR_R NEW li1 TAPER ( 89470 104890 ) L1M1_PR_R - NEW li1 TAPER ( 111090 120870 ) L1M1_PR_R - NEW li1 TAPER ( 117530 117810 ) L1M1_PR_R - NEW met1 ( 111090 117810 ) M1M2_PR_R - NEW met1 TAPER ( 111090 120870 ) M1M2_PR_R - NEW li1 TAPER ( 125350 120870 ) L1M1_PR_R - NEW li1 TAPER ( 111090 134810 ) L1M1_PR_R - NEW met1 TAPER ( 111090 134810 ) M1M2_PR_R - NEW met1 ( 111090 148070 ) M1M2_PR_R - NEW li1 TAPER ( 143750 115430 ) L1M1_PR_R - NEW met1 TAPER ( 143750 115430 ) M1M2_PR_R NEW met1 ( 143750 88570 ) M1M2_PR_R NEW li1 TAPER ( 146510 88570 ) L1M1_PR_R + NEW met1 ( 117070 148070 ) M1M2_PR_R + NEW li1 TAPER ( 136850 148070 ) L1M1_PR_R + NEW li1 TAPER ( 111090 134810 ) L1M1_PR_R + NEW met1 ( 117070 134810 ) M1M2_PR_R + NEW li1 TAPER ( 143750 115770 ) L1M1_PR_R + NEW met1 TAPER ( 143750 115770 ) M1M2_PR_R NEW met1 ( 143750 120870 ) M1M2_PR_R - NEW li1 TAPER ( 136850 148070 ) L1M1_PR_R ; + NEW li1 TAPER ( 93150 120870 ) L1M1_PR_R + NEW li1 TAPER ( 111090 120870 ) L1M1_PR_R + NEW li1 TAPER ( 117530 117810 ) L1M1_PR_R + NEW met1 TAPER ( 117530 117810 ) M1M2_PR_R + NEW met1 ( 117530 120870 ) M1M2_PR_R + NEW li1 TAPER ( 125350 120870 ) L1M1_PR_R ; - clknet_2_1__leaf_clk ( _423_ CLK ) ( _424_ CLK ) ( _425_ CLK ) ( _426_ CLK ) ( _427_ CLK ) ( _440_ CLK ) ( _441_ CLK ) ( _442_ CLK ) ( _443_ CLK ) ( clkbuf_2_1__f_clk X ) + USE CLOCK + NONDEFAULTRULE NDR_3W_3S - + ROUTED met1 ( 199410 96390 ) ( 204010 * ) + + ROUTED met1 ( 199870 96390 ) ( 204010 * ) NEW met1 TAPER ( 204010 96390 ) ( 205850 * ) - NEW met2 ( 199410 91290 ) ( * 96390 ) - NEW met1 ( 199410 112710 ) ( 204700 * ) + NEW met2 ( 199870 91290 ) ( * 96390 ) + NEW met1 ( 199870 112710 ) ( 204700 * ) NEW met1 TAPER ( 204700 112710 ) ( 206310 * ) - NEW met2 ( 199410 96390 ) ( * 112710 ) - NEW met1 ( 199410 129030 ) ( 204700 * ) + NEW met2 ( 199870 96390 ) ( * 112710 ) + NEW met1 ( 199870 129030 ) ( 204700 * ) NEW met1 TAPER ( 204700 129030 ) ( 206310 * ) - NEW met2 ( 199410 112710 ) ( * 129030 ) - NEW met2 ( 199410 129030 ) ( * 137190 ) - NEW met1 ( 179400 91290 ) ( 199410 * ) - NEW met1 ( 156170 117810 ) ( 168130 * ) + NEW met2 ( 199870 112710 ) ( * 129030 ) + NEW met1 TAPER ( 199410 137190 ) ( 199870 * ) + NEW met2 ( 199870 129030 ) ( * 137190 ) + NEW met1 ( 179400 91290 ) ( 199870 * ) NEW met1 TAPER ( 168130 117810 ) ( 170430 * ) - NEW met2 ( 156170 117810 ) ( * 129370 ) - NEW met2 ( 158010 102170 ) ( * 117810 ) NEW met1 ( 158930 88570 ) ( 162610 * ) NEW met1 TAPER ( 162610 88570 ) ( 164450 * ) - NEW met2 ( 158930 88570 ) ( * 94860 ) - NEW met2 ( 158010 94860 ) ( 158930 * ) - NEW met2 ( 158010 94860 ) ( * 102170 ) + NEW met2 ( 158930 88570 ) ( * 90100 ) + NEW met2 ( 158010 90100 ) ( 158930 * ) + NEW met2 ( 158010 90100 ) ( * 102170 ) NEW met1 ( 164450 91290 ) ( 177100 * ) NEW met1 TAPER ( 177100 91290 ) ( 178710 * ) NEW met2 ( 164450 88570 ) ( * 91290 ) NEW met1 TAPER ( 178710 91290 ) ( 179400 * ) - NEW met1 ( 155710 147730 ) ( 156170 * ) - NEW met1 ( 155710 147730 ) ( * 148070 ) - NEW met1 TAPER ( 153075 148070 ) ( 154790 * ) - NEW met1 ( 154790 148070 ) ( 155710 * ) - NEW met2 ( 156170 129370 ) ( * 147730 ) + NEW met1 ( 152950 129370 ) ( 154330 * ) + NEW met1 TAPER ( 154330 129370 ) ( 156170 * ) + NEW met2 ( 152950 129370 ) ( * 148070 ) + NEW met2 ( 156170 117810 ) ( * 129370 ) + NEW met2 ( 158010 102170 ) ( * 117810 ) + NEW met1 ( 156170 117810 ) ( 168130 * ) NEW li1 TAPER ( 205850 96390 ) L1M1_PR_R - NEW met1 ( 199410 96390 ) M1M2_PR_R - NEW met1 ( 199410 91290 ) M1M2_PR_R + NEW met1 ( 199870 96390 ) M1M2_PR_R + NEW met1 ( 199870 91290 ) M1M2_PR_R NEW li1 TAPER ( 206310 112710 ) L1M1_PR_R - NEW met1 ( 199410 112710 ) M1M2_PR_R + NEW met1 ( 199870 112710 ) M1M2_PR_R NEW li1 TAPER ( 206310 129030 ) L1M1_PR_R - NEW met1 ( 199410 129030 ) M1M2_PR_R + NEW met1 ( 199870 129030 ) M1M2_PR_R + NEW met1 TAPER ( 199870 137190 ) M1M2_PR_R NEW li1 TAPER ( 199410 137190 ) L1M1_PR_R - NEW met1 TAPER ( 199410 137190 ) M1M2_PR_R - NEW li1 TAPER ( 156170 129370 ) L1M1_PR_R - NEW met1 TAPER ( 156170 129370 ) M1M2_PR_R NEW li1 TAPER ( 170430 117810 ) L1M1_PR_R - NEW met1 ( 156170 117810 ) M1M2_PR_R NEW li1 TAPER ( 158010 102170 ) L1M1_PR_R NEW met1 TAPER ( 158010 102170 ) M1M2_PR_R - NEW met1 ( 158010 117810 ) M1M2_PR_R NEW li1 TAPER ( 164450 88570 ) L1M1_PR_R NEW met1 ( 158930 88570 ) M1M2_PR_R NEW li1 TAPER ( 178710 91290 ) L1M1_PR_R NEW met1 ( 164450 91290 ) M1M2_PR_R NEW met1 TAPER ( 164450 88570 ) M1M2_PR_R - NEW met1 ( 156170 147730 ) M1M2_PR_R - NEW li1 TAPER ( 153075 148070 ) L1M1_PR_R ; + NEW li1 TAPER ( 156170 129370 ) L1M1_PR_R + NEW met1 ( 152950 129370 ) M1M2_PR_R + NEW li1 TAPER ( 152950 148070 ) L1M1_PR_R + NEW met1 TAPER ( 152950 148070 ) M1M2_PR_R + NEW met1 ( 156170 117810 ) M1M2_PR_R + NEW met1 TAPER ( 156170 129370 ) M1M2_PR_R + NEW met1 ( 158010 117810 ) M1M2_PR_R ; - clknet_2_2__leaf_clk ( _411_ CLK ) ( _413_ CLK ) ( _415_ CLK ) ( _416_ CLK ) ( _417_ CLK ) ( _421_ CLK ) ( _430_ CLK ) ( _431_ CLK ) ( _433_ CLK ) ( _437_ CLK ) ( clkbuf_2_2__f_clk X ) + USE CLOCK + NONDEFAULTRULE NDR_3W_3S + ROUTED met2 ( 126270 200090 ) ( * 210630 ) @@ -359,14 +358,15 @@ NETS 8 ; NEW met2 ( 96830 183770 ) ( * 186150 ) NEW met1 ( 96830 183770 ) ( 107410 * ) NEW met1 TAPER ( 107410 183770 ) ( 109250 * ) - NEW met1 ( 96830 151130 ) ( 98210 * ) + NEW met2 ( 96830 183770 ) ( 97290 * ) + NEW met1 ( 97290 151130 ) ( 98210 * ) NEW met1 TAPER ( 98210 151130 ) ( 100050 * ) - NEW met2 ( 96830 151130 ) ( * 183770 ) + NEW met2 ( 97290 151130 ) ( * 183770 ) NEW met1 TAPER ( 137770 210630 ) ( 139610 * ) NEW met1 ( 139610 210630 ) ( 148810 * ) NEW met1 TAPER ( 148810 210630 ) ( 150650 * ) NEW met1 TAPER ( 135930 210630 ) ( 137770 * ) - NEW met1 ( 127650 183770 ) ( 131790 * ) + NEW met1 ( 127650 183770 ) ( 131330 * ) NEW met1 ( 126270 210630 ) ( 135930 * ) NEW met1 ( 137770 175270 ) ( 139380 * ) NEW met1 TAPER ( 139380 175270 ) ( 140990 * ) @@ -375,8 +375,8 @@ NETS 8 ; NEW met1 TAPER ( 142140 159290 ) ( 143750 * ) NEW met1 TAPER ( 132250 172210 ) ( 134550 * ) NEW met1 ( 134550 172210 ) ( 137770 * ) - NEW met1 TAPER ( 131790 172210 ) ( 132250 * ) - NEW met2 ( 131790 172210 ) ( * 183770 ) + NEW met1 TAPER ( 131330 172210 ) ( 132250 * ) + NEW met2 ( 131330 172210 ) ( * 183770 ) NEW li1 TAPER ( 126270 200090 ) L1M1_PR_R NEW met1 TAPER ( 126270 200090 ) M1M2_PR_R NEW met1 ( 126270 210630 ) M1M2_PR_R @@ -387,18 +387,18 @@ NETS 8 ; NEW li1 TAPER ( 96830 186150 ) L1M1_PR_R NEW met1 TAPER ( 96830 186150 ) M1M2_PR_R NEW met1 ( 96830 183770 ) M1M2_PR_R - NEW met1 ( 96830 151130 ) M1M2_PR_R + NEW met1 ( 97290 151130 ) M1M2_PR_R NEW li1 TAPER ( 100050 151130 ) L1M1_PR_R NEW li1 TAPER ( 137770 210630 ) L1M1_PR_R NEW li1 TAPER ( 150650 210630 ) L1M1_PR_R - NEW met1 ( 131790 183770 ) M1M2_PR_R + NEW met1 ( 131330 183770 ) M1M2_PR_R NEW li1 TAPER ( 140990 175270 ) L1M1_PR_R NEW met1 ( 137770 175270 ) M1M2_PR_R NEW met1 ( 137770 159290 ) M1M2_PR_R NEW li1 TAPER ( 143750 159290 ) L1M1_PR_R NEW li1 TAPER ( 132250 172210 ) L1M1_PR_R NEW met1 ( 137770 172210 ) M1M2_PR_R - NEW met1 TAPER ( 131790 172210 ) M1M2_PR_R ; + NEW met1 TAPER ( 131330 172210 ) M1M2_PR_R ; - clknet_2_3__leaf_clk ( _412_ CLK ) ( _419_ CLK ) ( _420_ CLK ) ( _422_ CLK ) ( _435_ CLK ) ( _436_ CLK ) ( _438_ CLK ) ( _439_ CLK ) ( clkbuf_2_3__f_clk X ) + USE CLOCK + NONDEFAULTRULE NDR_3W_3S + ROUTED met2 ( 192050 191930 ) ( * 194310 ) @@ -448,15 +448,14 @@ NETS 8 ; NEW met1 TAPER ( 165830 211310 ) M1M2_PR_R NEW li1 TAPER ( 164025 210630 ) L1M1_PR_R ; - ctrl.state.out\[1\] ( _412_ Q ) ( _290_ B2 ) ( _285_ A ) + USE SIGNAL - + ROUTED met1 ( 167670 208250 ) ( 170890 * ) - NEW met2 ( 170890 208250 ) ( * 209950 ) - NEW met2 ( 170890 205530 ) ( * 208250 ) + + ROUTED met2 ( 170890 205530 ) ( * 209950 ) + NEW met1 ( 167670 207910 ) ( 170890 * ) NEW li1 ( 170890 205530 ) L1M1_PR_MR NEW met1 ( 170890 205530 ) M1M2_PR - NEW li1 ( 167670 208250 ) L1M1_PR_MR - NEW met1 ( 170890 208250 ) M1M2_PR NEW li1 ( 170890 209950 ) L1M1_PR_MR - NEW met1 ( 170890 209950 ) M1M2_PR ; + NEW met1 ( 170890 209950 ) M1M2_PR + NEW li1 ( 167670 207910 ) L1M1_PR_MR + NEW met1 ( 170890 207910 ) M1M2_PR ; - ctrl.state.out\[2\] ( _413_ Q ) ( _297_ A ) ( _293_ A ) ( _290_ A1 ) ( _284_ A ) ( _279_ A ) + USE SIGNAL + ROUTED met2 ( 158010 191590 ) ( * 194650 ) NEW met1 ( 158010 194650 ) ( 167210 * ) diff --git a/src/drt/test/obstruction.defok b/src/drt/test/obstruction.defok index e467afe317a..ecc4e9655ad 100644 --- a/src/drt/test/obstruction.defok +++ b/src/drt/test/obstruction.defok @@ -35,18 +35,18 @@ BLOCKAGES 1 ; END BLOCKAGES NETS 1 ; - clk ( PIN clk ) ( clkbuf_0_clk A ) ( clkbuf_2_3__f_clk A ) ( clkbuf_2_2__f_clk A ) ( clkbuf_2_1__f_clk A ) + USE SIGNAL - + ROUTED met5 ( 2400 155030 0 ) ( 21600 * ) + + ROUTED met5 ( 2400 155030 0 ) ( 14880 * ) NEW met2 ( 112080 154845 ) ( * 155030 ) NEW met1 ( 112080 158175 ) ( 135600 * ) NEW met2 ( 112080 155030 ) ( * 158175 ) NEW met1 ( 135600 158175 ) ( 144240 * ) NEW met1 ( 144240 158175 ) ( 145200 * ) NEW met2 ( 145200 144855 ) ( * 158175 ) - NEW met3 ( 21600 155030 ) ( 112080 * ) + NEW met3 ( 14880 155030 ) ( 112080 * ) NEW li1 ( 145200 144855 ) L1M1_PR_MR NEW met1 ( 145200 144855 ) M1M2_PR - NEW met3 ( 21600 155030 ) M3M4_PR - NEW met4 ( 21600 155030 ) M4M5_PR + NEW met3 ( 14880 155030 ) M3M4_PR + NEW met4 ( 14880 155030 ) M4M5_PR NEW li1 ( 112080 154845 ) L1M1_PR_MR NEW met1 ( 112080 154845 ) M1M2_PR NEW met2 ( 112080 155030 ) M2M3_PR diff --git a/src/drt/test/single_step.py b/src/drt/test/single_step.py index 06c4c866b18..6661d9c2194 100644 --- a/src/drt/test/single_step.py +++ b/src/drt/test/single_step.py @@ -2,6 +2,9 @@ import helpers import drt_aux +bazel_working_dir = "/_main/src/drt/test/" +helpers.if_bazel_change_working_dir_to(bazel_working_dir) + tech = Tech() tech.readLef("testcase/ispd18_sample/ispd18_sample.input.lef") design = helpers.make_design(tech) @@ -10,10 +13,13 @@ gr = design.getGlobalRouter() gr.readGuides("testcase/ispd18_sample/ispd18_sample.input.guide") +drc_file = helpers.make_result_file("single_step.output.drc.rpt") +maze_file = helpers.make_result_file("single_step.output.maze.log") + drt_aux.detailed_route( design, - output_drc="results/single_step.output.drc.rpt", - output_maze="results/single_step.output.maze.log", + output_drc=drc_file, + output_maze=maze_file, verbose=0, single_step_dr=True, ) diff --git a/src/drt/test/top_level_term.defok b/src/drt/test/top_level_term.defok index f82d8c58701..6a8ca55e058 100644 --- a/src/drt/test/top_level_term.defok +++ b/src/drt/test/top_level_term.defok @@ -32,25 +32,25 @@ PINS 1 ; END PINS NETS 1 ; - clk ( PIN clk ) ( clkbuf_0_clk A ) ( clkbuf_2_3__f_clk A ) ( clkbuf_2_2__f_clk A ) ( clkbuf_2_1__f_clk A ) + USE SIGNAL - + ROUTED met3 ( 1440 155030 0 ) ( 6960 * ) - NEW met2 ( 6960 155030 ) ( * 155215 ) + + ROUTED met3 ( 1440 155030 0 ) ( 2160 * ) + NEW met2 ( 2160 155030 ) ( * 155215 ) NEW met1 ( 112080 154845 ) ( * 155215 ) - NEW met1 ( 127440 158175 ) ( 135600 * ) - NEW met1 ( 127440 155955 ) ( * 158175 ) - NEW met1 ( 112080 155955 ) ( 127440 * ) + NEW met1 ( 135120 158175 ) ( 135600 * ) + NEW met1 ( 135120 155955 ) ( * 158175 ) + NEW met1 ( 112080 155955 ) ( 135120 * ) NEW met1 ( 112080 155215 ) ( * 155955 ) - NEW met1 ( 135600 158175 ) ( 144240 * ) - NEW met1 ( 144240 158175 ) ( 145200 * ) + NEW met1 ( 2160 155215 ) ( 112080 * ) + NEW met1 ( 144720 158175 ) ( 145200 * ) NEW met2 ( 145200 144855 ) ( * 158175 ) - NEW met1 ( 6960 155215 ) ( 112080 * ) - NEW li1 ( 145200 144855 ) L1M1_PR_MR - NEW met1 ( 145200 144855 ) M1M2_PR - NEW met2 ( 6960 155030 ) M2M3_PR - NEW met1 ( 6960 155215 ) M1M2_PR + NEW met1 ( 135600 158175 ) ( 144720 * ) + NEW met2 ( 2160 155030 ) M2M3_PR + NEW met1 ( 2160 155215 ) M1M2_PR NEW li1 ( 112080 154845 ) L1M1_PR_MR NEW li1 ( 135600 158175 ) L1M1_PR_MR - NEW li1 ( 144240 158175 ) L1M1_PR_MR + NEW li1 ( 144720 158175 ) L1M1_PR_MR NEW met1 ( 145200 158175 ) M1M2_PR + NEW li1 ( 145200 144855 ) L1M1_PR_MR + NEW met1 ( 145200 144855 ) M1M2_PR NEW met3 ( 1250 155030 ) M3M4_PR M4M5_PR ; END NETS END DESIGN diff --git a/src/drt/test/top_level_term.py b/src/drt/test/top_level_term.py index 40c1347cbe3..afa3372a9b9 100644 --- a/src/drt/test/top_level_term.py +++ b/src/drt/test/top_level_term.py @@ -2,6 +2,9 @@ import helpers import drt_aux +bazel_working_dir = "/_main/src/drt/test/" +helpers.if_bazel_change_working_dir_to(bazel_working_dir) + tech = Tech() tech.readLef("sky130hs/sky130hs.tlef") tech.readLef("sky130hs/sky130hs_std_cell.lef") diff --git a/src/drt/test/top_level_term2.defok b/src/drt/test/top_level_term2.defok index 3a478d0f691..e14ab9d275e 100644 --- a/src/drt/test/top_level_term2.defok +++ b/src/drt/test/top_level_term2.defok @@ -42,17 +42,12 @@ NETS 1 ; - clk ( PIN reg ) ( PIN pin ) ( PIN clk ) ( clkbuf_0_clk A ) ( clkbuf_2_3__f_clk A ) ( clkbuf_2_2__f_clk A ) ( clkbuf_2_1__f_clk A ) + USE SIGNAL + ROUTED met3 ( 1440 155030 0 ) ( 2160 * ) NEW met2 ( 2160 155030 ) ( * 155215 ) - NEW met3 ( 480 148370 ) ( 1440 * 0 ) - NEW met3 ( 480 148370 ) ( * 149110 ) - NEW met3 ( 480 149110 ) ( 1440 * ) - NEW met3 ( 1440 149110 ) ( * 154290 ) - NEW met3 ( 1440 154290 ) ( 2400 * ) - NEW met3 ( 2400 154290 ) ( * 155030 ) - NEW met3 ( 2160 155030 ) ( 2400 * ) + NEW met3 ( 1440 148370 0 ) ( 2160 * ) + NEW met2 ( 2160 148370 ) ( * 155030 ) NEW met1 ( 112080 154845 ) ( * 155215 ) - NEW met1 ( 117360 158175 ) ( 135600 * ) - NEW met1 ( 117360 155955 ) ( * 158175 ) - NEW met1 ( 112080 155955 ) ( 117360 * ) + NEW met1 ( 135120 158175 ) ( 135600 * ) + NEW met1 ( 135120 155955 ) ( * 158175 ) + NEW met1 ( 112080 155955 ) ( 135120 * ) NEW met1 ( 112080 155215 ) ( * 155955 ) NEW met3 ( 149280 370 0 ) ( 149520 * ) NEW met1 ( 2160 155215 ) ( 112080 * ) @@ -63,6 +58,7 @@ NETS 1 ; NEW met2 ( 149520 370 ) ( * 144855 ) NEW met2 ( 2160 155030 ) M2M3_PR NEW met1 ( 2160 155215 ) M1M2_PR + NEW met2 ( 2160 148370 ) M2M3_PR NEW li1 ( 112080 154845 ) L1M1_PR_MR NEW li1 ( 135600 158175 ) L1M1_PR_MR NEW met2 ( 149520 370 ) M2M3_PR diff --git a/src/drt/test/top_level_term2.py b/src/drt/test/top_level_term2.py index d71afb8abe6..ab1ed8a4beb 100644 --- a/src/drt/test/top_level_term2.py +++ b/src/drt/test/top_level_term2.py @@ -2,6 +2,9 @@ import helpers import drt_aux +bazel_working_dir = "/_main/src/drt/test/" +helpers.if_bazel_change_working_dir_to(bazel_working_dir) + tech = Tech() tech.readLef("sky130hs/sky130hs.tlef") tech.readLef("sky130hs/sky130hs_std_cell.lef") diff --git a/src/drt/test/via_access_layer.defok b/src/drt/test/via_access_layer.defok index 4934f3bfc08..2583a9de29b 100644 --- a/src/drt/test/via_access_layer.defok +++ b/src/drt/test/via_access_layer.defok @@ -26,29 +26,29 @@ COMPONENTS 4 ; END COMPONENTS NETS 2 ; - net1 ( comp1 A ) ( comp2 A ) + USE SIGNAL - + ROUTED met3 ( 21120 21460 ) ( 23520 * ) - NEW met3 ( 23520 21090 ) ( * 21460 ) - NEW met3 ( 23520 21090 ) ( 75360 * ) + + ROUTED met3 ( 20880 21460 ) ( 21600 * ) + NEW met3 ( 21600 21090 ) ( * 21460 ) + NEW met3 ( 21600 21090 ) ( 75360 * ) NEW met3 ( 75360 80290 ) ( 77280 * ) NEW met3 ( 77280 80290 ) ( * 81400 ) NEW met3 ( 77280 81400 ) ( 80400 * ) NEW met4 ( 75360 21090 ) ( * 80290 ) - NEW met2 ( 21120 21460 ) M2M3_PR_M + NEW met2 ( 20880 21460 ) M2M3_PR_MR NEW met3 ( 75360 21090 ) M3M4_PR NEW met3 ( 75360 80290 ) M3M4_PR NEW met2 ( 80400 81400 ) M2M3_PR_M ; - net2 ( comp3 A ) ( comp4 A ) + USE SIGNAL + ROUTED met3 ( 19680 81030 ) ( 20640 * ) NEW met3 ( 20640 81030 ) ( * 81215 ) - NEW met3 ( 20400 81215 ) ( 20640 * ) + NEW met3 ( 20640 81215 ) ( 20880 * ) NEW met4 ( 19680 20350 ) ( * 81030 ) NEW met3 ( 80160 20350 ) ( * 21275 ) NEW met3 ( 80160 21275 ) ( 80400 * ) NEW met3 ( 19680 20350 ) ( 80160 * ) NEW met3 ( 19680 20350 ) M3M4_PR NEW met3 ( 19680 81030 ) M3M4_PR - NEW met1 ( 20400 81215 ) M1M2_PR - NEW met2 ( 20400 81215 ) M2M3_PR + NEW met1 ( 20880 81215 ) M1M2_PR + NEW met2 ( 20880 81215 ) M2M3_PR NEW met1 ( 80400 21275 ) M1M2_PR NEW met2 ( 80400 21275 ) M2M3_PR ; END NETS diff --git a/src/gui/README.md b/src/gui/README.md index 0f28309945a..eabe13f5639 100644 --- a/src/gui/README.md +++ b/src/gui/README.md @@ -91,30 +91,6 @@ gui::remove_menu_item | ---- | ---- | | `-name` | name of the item, used when deleting the item.| -### Save Image - -This command can be both be used when the GUI is active and not active -to save a screenshot with various options. - -```tcl -save_image - [-resolution microns_per_pixel] - [-area {x0 y0 x1 y1}] - [-width width] - [-display_option {option value}] - filename -``` - -#### Options - -| Switch Name | Description | -| ---- | ---- | -| `filename` | path to save the image to. | -| `-area` | x0, y0 - first corner of the layout area (in microns) to be saved, default is to save what is visible on the screen unless called when gui is not active and then it selected the whole block. x1, y1 - second corner of the layout area (in microns) to be saved, default is to save what is visible on the screen unless called when gui is not active and then it selected the whole block.| -| `-resolution`| resolution in microns per pixel to use when saving the image, default will match what the GUI has selected.| -| `-width`| width of the output image in pixels, default will be computed from the resolution. Cannot be used with ``-resolution``.| -| `-display_option`| specific setting for a display option to show or hide specific elements. For example, to hide metal1 ``-display_option {Layers/metal1 false}``, to show routing tracks ``-display_option {Tracks/Pref true}``, or to show everthing ``-display_option {* true}``.| - ### Save Clocktree Image This command saves the screenshot of clocktree given options diff --git a/src/gui/src/gui.tcl b/src/gui/src/gui.tcl index 811849269b2..cbf604ed315 100644 --- a/src/gui/src/gui.tcl +++ b/src/gui/src/gui.tcl @@ -69,71 +69,6 @@ proc create_menu_item { args } { return [gui::create_menu_item $name $path $action_text $tcl_script $shortcut $echo] } -sta::define_cmd_args "save_image" {[-area {x0 y0 x1 y1}] \ - [-width width] \ - [-resolution microns_per_pixel] \ - [-display_option option] \ - path -} - -proc save_image { args } { - ord::parse_list_args "save_image" args list {-display_option} - sta::parse_key_args "save_image" args \ - keys {-area -width -resolution} flags {} - - set options [gui::DisplayControlMap] - foreach opt $list(-display_option) { - if { [llength $opt] != 2 } { - utl::error GUI 19 "Display option must have 2 elements {control name} {value}." - } - - set key [lindex $opt 0] - set val [lindex $opt 1] - - $options set $key $val - } - - set resolution 0 - if { [info exists keys(-resolution)] } { - sta::check_positive_float "-resolution" $keys(-resolution) - set db [ord::get_db] - set resolution [expr $keys(-resolution) * [$db getDbuPerMicron]] - if { $resolution < 1 } { - set resolution 1.0 - set res_per_pixel [expr $resolution / [$db getDbuPerMicron]] - utl::warn GUI 31 "Resolution too high for design, defaulting to ${res_per_pixel}um per pixel" - } - } - - set area "0 0 0 0" - if { [info exists keys(-area)] } { - set area $keys(-area) - if { [llength $area] != 4 } { - utl::error GUI 18 "Area must contain 4 elements." - } - } - - set width 0 - if { [info exists keys(-width)] } { - if { $resolution != 0 } { - utl::error GUI 96 "Cannot set -width if -resolution has already been specified." - } - sta::check_positive_int "-width" $keys(-width) - set width $keys(-width) - if { $width == 0 } { - utl::error GUI 98 "Specified -width cannot be zero." - } - } - - sta::check_argc_eq1 "save_image" $args - set path [lindex $args 0] - - gui::save_image $path {*}$area $width $resolution $options - - # delete map - rename $options "" -} - sta::define_cmd_args "save_animated_gif" {-start|-add|-end \ [-area {x0 y0 x1 y1}] \ [-width width] \ diff --git a/src/gui/test/gui_readme_msgs_check.ok b/src/gui/test/gui_readme_msgs_check.ok index 9d63c5eea1a..09b69496c81 100644 --- a/src/gui/test/gui_readme_msgs_check.ok +++ b/src/gui/test/gui_readme_msgs_check.ok @@ -1,5 +1,5 @@ README.md -Names: 60, Desc: 60, Syn: 60, Options: 60, Args: 60 +Names: 59, Desc: 59, Syn: 59, Options: 59, Args: 59 Global Examples: None Global See Also: None Man2 successfully compiled. diff --git a/src/mpl/test/unfixed_cells_dont_fit_in_core.ok b/src/mpl/test/unfixed_cells_dont_fit_in_core.ok index 7114a3cede0..1548d6fcdf6 100644 --- a/src/mpl/test/unfixed_cells_dont_fit_in_core.ok +++ b/src/mpl/test/unfixed_cells_dont_fit_in_core.ok @@ -4,4 +4,3 @@ [INFO ODB-0130] Created 3 pins. [INFO ODB-0131] Created 151 components and 902 component-terminals. [ERROR MPL-0065] The movable cells do not fit in the macro placement area. -Error: unfixed_cells_dont_fit_in_core.tcl, 10 MPL-0065 diff --git a/src/mpl/test/unfixed_cells_dont_fit_in_core.tcl b/src/mpl/test/unfixed_cells_dont_fit_in_core.tcl index b0436259f15..d5cc0b5e223 100644 --- a/src/mpl/test/unfixed_cells_dont_fit_in_core.tcl +++ b/src/mpl/test/unfixed_cells_dont_fit_in_core.tcl @@ -7,4 +7,4 @@ read_lef "./testcases/macro_only.lef" read_def "./testcases/unfixed_cells_dont_fit_in_core.def" set_thread_count 0 -rtl_macro_placer -report_directory [make_result_dir] +catch { rtl_macro_placer -report_directory [make_result_dir] } diff --git a/src/odb/include/odb/3dblox.h b/src/odb/include/odb/3dblox.h index 61873bb8aa4..b6e07ff5626 100644 --- a/src/odb/include/odb/3dblox.h +++ b/src/odb/include/odb/3dblox.h @@ -46,6 +46,7 @@ class ThreeDBlox void writeDbv(const std::string& dbv_file, odb::dbChip* chip); void writeDbx(const std::string& dbx_file, odb::dbChip* chip); void writeBMap(const std::string& bmap_file, odb::dbChipRegion* region); + void writeVerilog(const std::string& verilog_file, odb::dbChip* chip); private: void createChiplet(const ChipletDef& chiplet); diff --git a/src/odb/include/odb/geom.h b/src/odb/include/odb/geom.h index 6f0aa896973..8e2606449c9 100644 --- a/src/odb/include/odb/geom.h +++ b/src/odb/include/odb/geom.h @@ -9,6 +9,7 @@ #include #include #include +#include #include #include #include @@ -518,6 +519,9 @@ class Line void addX(int value); void addY(int value); + void setPt0(const Point& pt); + void setPt1(const Point& pt); + friend dbIStream& operator>>(dbIStream& stream, Line& l); friend dbOStream& operator<<(dbOStream& stream, const Line& l); @@ -1121,6 +1125,16 @@ inline void Line::addY(int value) pt1_.setY(pt1_.getY() + value); } +inline void Line::setPt0(const Point& pt) +{ + pt0_ = pt; +} + +inline void Line::setPt1(const Point& pt) +{ + pt1_ = pt; +} + inline std::vector Line::getPoints() const { std::vector pts{pt0_, pt1_}; @@ -1422,4 +1436,23 @@ inline void Cuboid::print(const char* prefix) using utl::format_as; #endif +inline void hash_combine(size_t& seed, size_t value) +{ + seed ^= value + 0x9e3779b9 + (seed << 6) + (seed >> 2); +} + } // namespace odb + +namespace std { +template <> +struct hash +{ + size_t operator()(const odb::Point& p) const noexcept + { + size_t seed = 0; + odb::hash_combine(seed, std::hash{}(p.x())); + odb::hash_combine(seed, std::hash{}(p.y())); + return seed; + } +}; +} // namespace std diff --git a/src/odb/include/odb/geom_boost.h b/src/odb/include/odb/geom_boost.h index 9d0ccb43938..0124ca0ded9 100644 --- a/src/odb/include/odb/geom_boost.h +++ b/src/odb/include/odb/geom_boost.h @@ -293,4 +293,55 @@ struct interior_rings } }; +// +// Make odb's Line work with boost geometry. +// + +template <> +struct tag +{ + using type = segment_tag; +}; + +template <> +struct point_type +{ + using type = odb::Point; +}; + +template +struct indexed_access +{ + using coordinate_type = int; + + static constexpr coordinate_type get(const odb::Line& line) + { + if (Index == 0) { + return Dimension == 0 ? line.pt0().getX() : line.pt0().getY(); + } + return Dimension == 0 ? line.pt1().getX() : line.pt1().getY(); + } + + static void set(odb::Line& line, const int value) + { + if (Index == 0) { + odb::Point pt = line.pt0(); + if (Dimension == 0) { + pt.setX(value); + } else { + pt.setY(value); + } + line.setPt0(pt); + } else { + odb::Point pt = line.pt1(); + if (Dimension == 0) { + pt.setX(value); + } else { + pt.setY(value); + } + line.setPt1(pt); + } + } +}; + } // namespace boost::geometry::traits diff --git a/src/odb/src/3dblox/3dblox.cpp b/src/odb/src/3dblox/3dblox.cpp index 11c34ddb602..7fac6ab5ac1 100644 --- a/src/odb/src/3dblox/3dblox.cpp +++ b/src/odb/src/3dblox/3dblox.cpp @@ -37,6 +37,7 @@ #include "sta/VerilogReader.hh" #include "utl/Logger.h" #include "utl/ScopedTemporaryFile.h" +#include "verilogWriter.h" namespace odb { static std::map dup_orient_map @@ -301,10 +302,23 @@ void ThreeDBlox::writeDbx(const std::string& dbx_file, odb::dbChip* chip) writeDbv(current_dir_path + chip->getName() + ".3dbv", chip); + // Write the Verilog connectivity file for this HIER chiplet. + writeVerilog(current_dir_path + chip->getName() + ".v", chip); + DbxWriter writer(logger_, db_); writer.writeChiplet(dbx_file, chip); } +void ThreeDBlox::writeVerilog(const std::string& verilog_file, + odb::dbChip* chip) +{ + if (chip == nullptr) { + return; + } + VerilogWriter writer(logger_); + writer.writeChiplet(verilog_file, chip); +} + void ThreeDBlox::writeBMap(const std::string& bmap_file, odb::dbChipRegion* region) { diff --git a/src/odb/src/3dblox/CMakeLists.txt b/src/odb/src/3dblox/CMakeLists.txt index b6423b687de..dde022f4aa3 100644 --- a/src/odb/src/3dblox/CMakeLists.txt +++ b/src/odb/src/3dblox/CMakeLists.txt @@ -12,6 +12,7 @@ add_library(3dblox bmapWriter.cpp dbvWriter.cpp dbxWriter.cpp + verilogWriter.cpp 3dblox.cpp checker.cpp ) diff --git a/src/odb/src/3dblox/dbxWriter.cpp b/src/odb/src/3dblox/dbxWriter.cpp index c777e5a41cc..39684afd5f8 100644 --- a/src/odb/src/3dblox/dbxWriter.cpp +++ b/src/odb/src/3dblox/dbxWriter.cpp @@ -49,6 +49,8 @@ void DbxWriter::writeYamlContent(YAML::Node& root, odb::dbChip* chiplet) void DbxWriter::writeDesign(YAML::Node& design_node, odb::dbChip* chiplet) { design_node["name"] = chiplet->getName(); + YAML::Node external_node = design_node["external"]; + external_node["verilog_file"] = std::string(chiplet->getName()) + ".v"; } void DbxWriter::writeChipletInsts(YAML::Node& instances_node, diff --git a/src/odb/src/3dblox/verilogWriter.cpp b/src/odb/src/3dblox/verilogWriter.cpp new file mode 100644 index 00000000000..e2e183e1913 --- /dev/null +++ b/src/odb/src/3dblox/verilogWriter.cpp @@ -0,0 +1,118 @@ +// SPDX-License-Identifier: BSD-3-Clause +// Copyright (c) 2019-2025, The OpenROAD Authors + +#include "verilogWriter.h" + +#include +#include +#include +#include +#include +#include +#include +#include + +#include "odb/db.h" +#include "utl/Logger.h" + +namespace odb { + +VerilogWriter::VerilogWriter(utl::Logger* logger) : logger_(logger) +{ +} + +void VerilogWriter::writeChiplet(const std::string& filename, odb::dbChip* chip) +{ + std::ofstream verilog_file(filename); + if (!verilog_file.is_open()) { + logger_->error( + utl::ODB, 563, "Unable to open Verilog file for writing: {}", filename); + return; + } + + // chip_inst -> list of (port_name, net_name) + std::map>> + inst_connections; + + for (dbChipNet* net : chip->getChipNets()) { + const std::string net_name = net->getName(); + const uint32_t num_bumps = net->getNumBumpInsts(); + for (uint32_t i = 0; i < num_bumps; i++) { + std::vector path; + dbChipBumpInst* bump_inst = net->getBumpInst(i, path); + if (bump_inst == nullptr || path.size() != 1) { + continue; + } + // Only handle direct children (path length 1) — "single bump + // connections". + dbChipInst* chip_inst = path[0]; + dbChipBump* bump = bump_inst->getChipBump(); + if (bump == nullptr) { + continue; + } + dbBTerm* bterm = bump->getBTerm(); + if (bterm == nullptr) { + continue; + } + inst_connections[chip_inst].emplace_back(bterm->getName(), net_name); + } + } + + // Sort each instance's port connections alphabetically by port name. + for (std::pair>>& entry : + inst_connections) { + std::ranges::sort(entry.second); + } + + // Write module header. + fmt::print(verilog_file, "module {} ();\n", chip->getName()); + + // Collect and sort net names alphabetically for deterministic wire order. + std::vector net_names; + for (dbChipNet* net : chip->getChipNets()) { + net_names.push_back(net->getName()); + } + std::ranges::sort(net_names); + + // Write wire declarations in sorted order. + for (const std::string& name : net_names) { + fmt::print(verilog_file, " wire {};\n", name); + } + + // Collect and sort instances alphabetically by instance name. + std::vector chip_insts; + for (dbChipInst* chip_inst : chip->getChipInsts()) { + chip_insts.push_back(chip_inst); + } + std::ranges::sort(chip_insts, [](dbChipInst* a, dbChipInst* b) { + return a->getName() < b->getName(); + }); + + // Write instance declarations in sorted order. + for (dbChipInst* chip_inst : chip_insts) { + fmt::print(verilog_file, + " {} {} (\n", + chip_inst->getMasterChip()->getName(), + chip_inst->getName()); + auto it = inst_connections.find(chip_inst); + if (it != inst_connections.end()) { + const std::vector>& conns + = it->second; + for (size_t j = 0; j < conns.size(); j++) { + const bool is_last = (j + 1 == conns.size()); + fmt::print(verilog_file, + " .{}({}){}\n", + conns[j].first, + conns[j].second, + is_last ? "" : ","); + } + } + fmt::print(verilog_file, " );\n"); + } + + fmt::print(verilog_file, "endmodule\n"); + verilog_file.close(); +} + +} // namespace odb diff --git a/src/odb/src/3dblox/verilogWriter.h b/src/odb/src/3dblox/verilogWriter.h new file mode 100644 index 00000000000..73fe78bb5b2 --- /dev/null +++ b/src/odb/src/3dblox/verilogWriter.h @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: BSD-3-Clause +// Copyright (c) 2019-2025, The OpenROAD Authors + +#pragma once + +#include + +namespace utl { +class Logger; +} +namespace odb { +class dbChip; + +class VerilogWriter +{ + public: + VerilogWriter(utl::Logger* logger); + void writeChiplet(const std::string& filename, odb::dbChip* chip); + + private: + utl::Logger* logger_ = nullptr; +}; + +} // namespace odb diff --git a/src/odb/test/cpp/BUILD b/src/odb/test/cpp/BUILD index 979ebaf1e3e..6d5fa2e2bdc 100644 --- a/src/odb/test/cpp/BUILD +++ b/src/odb/test/cpp/BUILD @@ -293,6 +293,25 @@ cc_test( ], ) +cc_test( + name = "Test3DBloxVerilogWriter", + srcs = [ + "Test3DBloxVerilogWriter.cpp", + ], + data = [ + "//src/odb/test:regression_resources", + ], + deps = [ + "//src/odb", + "//src/odb/test/cpp/helper", + "//src/tst", + "//src/tst:nangate45_fixture", + "//src/utl", + "@googletest//:gtest", + "@googletest//:gtest_main", + ], +) + cc_test( name = "TestWriteReadDbHier", srcs = [ diff --git a/src/odb/test/cpp/CMakeLists.txt b/src/odb/test/cpp/CMakeLists.txt index 2b16ec39287..f4f9c231aac 100644 --- a/src/odb/test/cpp/CMakeLists.txt +++ b/src/odb/test/cpp/CMakeLists.txt @@ -37,6 +37,7 @@ add_executable(TestGDSIn TestGDSIn.cpp) add_executable(TestChips TestChips.cpp) add_executable(Test3DBloxParser Test3DBloxParser.cpp) add_executable(Test3DBloxChecker Test3DBloxChecker.cpp Test3DBloxCheckerLogicalConn.cpp Test3DBloxCheckerBumps.cpp) +add_executable(Test3DBloxVerilogWriter Test3DBloxVerilogWriter.cpp) add_executable(TestSwapMaster TestSwapMaster.cpp) add_executable(TestSwapMasterUnusedPort TestSwapMasterUnusedPort.cpp) add_executable(TestWriteReadDbHier TestWriteReadDbHier.cpp) @@ -58,6 +59,7 @@ target_link_libraries(TestGDSIn ${TEST_LIBS}) target_link_libraries(TestChips ${TEST_LIBS}) target_link_libraries(Test3DBloxParser ${TEST_LIBS}) target_link_libraries(Test3DBloxChecker ${TEST_LIBS}) +target_link_libraries(Test3DBloxVerilogWriter ${TEST_LIBS}) target_link_libraries(TestSwapMaster ${TEST_LIBS}) target_link_libraries(TestSwapMasterUnusedPort ${TEST_LIBS}) target_link_libraries(TestWriteReadDbHier ${TEST_LIBS}) @@ -87,6 +89,7 @@ add_dependencies(build_and_test TestChips Test3DBloxParser Test3DBloxChecker + Test3DBloxVerilogWriter TestSwapMaster TestSwapMasterUnusedPort TestWriteReadDbHier diff --git a/src/odb/test/cpp/Test3DBloxVerilogWriter.cpp b/src/odb/test/cpp/Test3DBloxVerilogWriter.cpp new file mode 100644 index 00000000000..63190891478 --- /dev/null +++ b/src/odb/test/cpp/Test3DBloxVerilogWriter.cpp @@ -0,0 +1,186 @@ +// SPDX-License-Identifier: BSD-3-Clause +// Copyright (c) 2023-2026, The OpenROAD Authors +// +// Tests for VerilogWriter path-length filtering: +// - bumps with path.size() == 1 (direct child) must appear in output +// - bumps with path.size() > 1 (nested child) must be silently skipped + +#include +#include +#include + +#include "gtest/gtest.h" +#include "odb/3dblox.h" +#include "odb/db.h" +#include "odb/geom.h" +#include "tst/fixture.h" + +namespace odb { +namespace { + +// Helper to read an entire file into a string. +static std::string readFileContent(const std::string& path) +{ + std::ifstream file(path); + return std::string(std::istreambuf_iterator(file), + std::istreambuf_iterator()); +} + +class VerilogWriterFixture : public tst::Fixture +{ + protected: + VerilogWriterFixture() + { + tech_ = dbTech::create(db_.get(), "tech"); + dbTechLayer::create(tech_, "layer1", dbTechLayerType::ROUTING); + + // HIER top chip (the module being written). + top_chip_ + = dbChip::create(db_.get(), nullptr, "TopChip", dbChip::ChipType::HIER); + + // DIE chip used as the master for instances. + chip1_ = dbChip::create(db_.get(), tech_, "Chip1", dbChip::ChipType::DIE); + chip1_->setWidth(2000); + chip1_->setHeight(2000); + chip1_->setThickness(500); + dbBlock::create(chip1_, "block1"); + + // A second DIE chip, only needed to form multi-element path vectors. + chip2_ = dbChip::create(db_.get(), tech_, "Chip2", dbChip::ChipType::DIE); + chip2_->setWidth(1500); + chip2_->setHeight(1500); + chip2_->setThickness(500); + dbBlock::create(chip2_, "block2"); + + // Front region on chip1 where bumps will be placed. + dbChipRegion* r1_fr = dbChipRegion::create( + chip1_, "r1_fr", dbChipRegion::Side::FRONT, nullptr); + r1_fr->setBox(Rect(0, 0, 2000, 2000)); + + // Shared bump master for physical bump cells. + lib_ = dbLib::create(db_.get(), "bump_lib", tech_, ','); + bump_master_ = dbMaster::create(lib_, "bump_pad"); + bump_master_->setWidth(100); + bump_master_->setHeight(100); + bump_master_->setType(dbMasterType::CORE); + dbMTerm::create(bump_master_, "pad", dbIoType::INOUT, dbSigType::SIGNAL); + bump_master_->setFrozen(); + } + + // Create a bump on a chip region and attach a named BTerm (Verilog port). + // Must be called BEFORE creating any dbChipInst that uses this chip, + // so the bump inst is propagated into the region inst at create time. + dbChipBump* createBump(dbChip* chip, + dbChipRegion* region, + const char* bump_name, + int x, + int y) + { + dbBlock* block = chip->getBlock(); + dbTechLayer* layer = tech_->findLayer("layer1"); + + // Physical placement cell for the bump. + dbInst* inst = dbInst::create(block, bump_master_, bump_name); + inst->setOrigin(x, y); + inst->setPlacementStatus(dbPlacementStatus::PLACED); + + // Chip-level bump object. + dbChipBump* chip_bump = dbChipBump::create(region, inst); + + // Net + BTerm — the BTerm name becomes the Verilog port name. + const std::string net_name = std::string(bump_name) + "_net"; + dbNet* net = dbNet::create(block, net_name.c_str()); + dbBTerm* bterm = dbBTerm::create(net, bump_name); + bterm->setIoType(dbIoType::INOUT); + + // BPin geometry required for placement checks. + dbBPin* bpin = dbBPin::create(bterm); + bpin->setPlacementStatus(dbPlacementStatus::PLACED); + dbBox::create(bpin, layer, x, y, x + 100, y + 100); + + chip_bump->setNet(net); + chip_bump->setBTerm(bterm); + return chip_bump; + } + + // Write the top chip's Verilog to a fixed temp file and return the path. + std::string writeVerilog() + { + const std::string filename = "/tmp/odb_test_verilog_writer.v"; + ThreeDBlox writer(&logger_, db_.get()); + writer.writeVerilog(filename, top_chip_); + return filename; + } + + dbTech* tech_; + dbChip* top_chip_; + dbChip* chip1_; + dbChip* chip2_; + dbLib* lib_; + dbMaster* bump_master_; +}; + +// A bump registered with path.size() == 1 (direct child of the HIER chip) +// must produce a port connection in the Verilog output. +TEST_F(VerilogWriterFixture, test_direct_child_written) +{ + // Create bump BEFORE the chip inst so it is propagated into the region inst. + dbChipRegion* r1_fr = chip1_->findChipRegion("r1_fr"); + createBump(chip1_, r1_fr, "port_a", 100, 100); + + dbChipInst* inst1 = dbChipInst::create(top_chip_, chip1_, "inst1"); + inst1->setLoc(Point3D(0, 0, 0)); + inst1->setOrient(dbOrientType3D(dbOrientType::R0, false)); + + // Retrieve the bump inst auto-created on the region inst. + dbChipRegionInst* ri1 = inst1->findChipRegionInst("r1_fr"); + ASSERT_NE(ri1, nullptr); + dbChipBumpInst* bump_inst = *ri1->getChipBumpInsts().begin(); + ASSERT_NE(bump_inst, nullptr); + + // Wire the bump to a net via a direct (path length 1) path. + dbChipNet* chip_net = dbChipNet::create(top_chip_, "net_signal"); + chip_net->addBumpInst(bump_inst, {inst1}); + + const std::string filename = writeVerilog(); + const std::string content = readFileContent(filename); + + // The port connection must appear in the output. + EXPECT_NE(content.find(".port_a(net_signal)"), std::string::npos); +} + +// A bump registered with path.size() > 1 (nested child) must be silently +// skipped; no port connection should appear in the Verilog output. +TEST_F(VerilogWriterFixture, test_nested_child_skipped) +{ + // Create bump BEFORE the chip inst so it is propagated into the region inst. + dbChipRegion* r1_fr = chip1_->findChipRegion("r1_fr"); + createBump(chip1_, r1_fr, "port_b", 200, 200); + + dbChipInst* inst1 = dbChipInst::create(top_chip_, chip1_, "inst1"); + inst1->setLoc(Point3D(0, 0, 0)); + inst1->setOrient(dbOrientType3D(dbOrientType::R0, false)); + + // inst2 is used only to form a path vector of length 2. + dbChipInst* inst2 = dbChipInst::create(top_chip_, chip2_, "inst2"); + inst2->setLoc(Point3D(0, 0, 500)); + inst2->setOrient(dbOrientType3D(dbOrientType::R0, false)); + + dbChipRegionInst* ri1 = inst1->findChipRegionInst("r1_fr"); + ASSERT_NE(ri1, nullptr); + dbChipBumpInst* bump_inst = *ri1->getChipBumpInsts().begin(); + ASSERT_NE(bump_inst, nullptr); + + // Path of length 2 — nested child; writer must skip this bump. + dbChipNet* chip_net = dbChipNet::create(top_chip_, "net_deep"); + chip_net->addBumpInst(bump_inst, {inst1, inst2}); + + const std::string filename = writeVerilog(); + const std::string content = readFileContent(filename); + + // No port connection should appear for the skipped bump. + EXPECT_EQ(content.find(".port_b"), std::string::npos); +} + +} // namespace +} // namespace odb diff --git a/src/odb/test/write_3dbx.3dbxok b/src/odb/test/write_3dbx.3dbxok index 89a2e28b8d7..f3725612e82 100644 --- a/src/odb/test/write_3dbx.3dbxok +++ b/src/odb/test/write_3dbx.3dbxok @@ -6,6 +6,8 @@ Header: - TopDesign.3dbv Design: name: TopDesign + external: + verilog_file: TopDesign.v ChipletInst: soc_inst_duplicate: reference: SoC diff --git a/src/pad/src/RDLRoute.cpp b/src/pad/src/RDLRoute.cpp index 2bd8afe41c9..0ac8a21b730 100644 --- a/src/pad/src/RDLRoute.cpp +++ b/src/pad/src/RDLRoute.cpp @@ -9,6 +9,7 @@ #include #include #include +#include #include #include @@ -95,7 +96,7 @@ bool RDLRoute::compare(const std::shared_ptr& other) const } void RDLRoute::setRoute( - const std::map& vertex_point_map, + const std::unordered_map& vertex_point_map, const std::vector& vertex, const std::vector& removed_edges, const RouteTarget* source, diff --git a/src/pad/src/RDLRoute.h b/src/pad/src/RDLRoute.h index 560e2643a7c..637dd16e514 100644 --- a/src/pad/src/RDLRoute.h +++ b/src/pad/src/RDLRoute.h @@ -6,6 +6,7 @@ #include #include #include +#include #include #include "RDLRouter.h" @@ -23,13 +24,14 @@ class RDLRoute public: RDLRoute(odb::dbITerm* source, const std::vector& dests); - void setRoute(const std::map& vertex_point_map, - const std::vector& vertex, - const std::vector& removed_edges, - const RouteTarget* source, - const RouteTarget* target, - const RDLRouter::TerminalAccess& access_source, - const RDLRouter::TerminalAccess& access_dest); + void setRoute( + const std::unordered_map& vertex_point_map, + const std::vector& vertex, + const std::vector& removed_edges, + const RouteTarget* source, + const RouteTarget* target, + const RDLRouter::TerminalAccess& access_source, + const RDLRouter::TerminalAccess& access_dest); void resetRoute(); bool isRouted() const { return routed_; } diff --git a/src/pad/src/RDLRouter.cpp b/src/pad/src/RDLRouter.cpp index f56daf07fd2..5f96f53306c 100644 --- a/src/pad/src/RDLRouter.cpp +++ b/src/pad/src/RDLRouter.cpp @@ -14,6 +14,7 @@ #include #include #include +#include #include #include @@ -30,6 +31,7 @@ #include "odb/dbTransform.h" #include "odb/dbTypes.h" #include "odb/geom.h" +#include "odb/geom_boost.h" #include "pad/ICeWall.h" #include "utl/Logger.h" @@ -40,7 +42,7 @@ class RDLRouterDistanceHeuristic { public: RDLRouterDistanceHeuristic( - const std::map& vertex_map, + const std::unordered_map& vertex_map, const std::vector& predecessor, const GridGraphVertex& start_vertex, const odb::Point& goal, @@ -85,7 +87,7 @@ class RDLRouterDistanceHeuristic } private: - const std::map& vertex_map_; + const std::unordered_map& vertex_map_; const std::vector& predecessor_; const GridGraphVertex& start_vertex_; odb::Point goal_; @@ -775,17 +777,17 @@ void RDLRouter::populateTerminalAccessPoints(RouteTarget& target) const // insersects another edge for (auto snap_itr = snap_pts.begin(); snap_itr != snap_pts.end();) { const odb::Line line(target.center, *snap_itr); - bool erase = obstructions_.qbegin( - boost::geometry::index::intersects(line.getPoints()) - && boost::geometry::index::satisfies( - [&target](const ObsValue& value) { - return std::get<3>(value) != target.terminal; - })) + bool erase = obstructions_.qbegin(boost::geometry::index::intersects(line) + && boost::geometry::index::satisfies( + [&target](const ObsValue& value) { + return std::get<3>(value) + != target.terminal; + })) != obstructions_.qend(); if (!erase) { - for (auto itr = vertex_grid_tree_.qbegin( - boost::geometry::index::intersects(line.getPoints())); + for (auto itr + = vertex_grid_tree_.qbegin(boost::geometry::index::intersects(line)); itr != vertex_grid_tree_.qend(); itr++) { const odb::Point& pt = vertex_point_map_.at(itr->second); @@ -806,8 +808,7 @@ void RDLRouter::populateTerminalAccessPoints(RouteTarget& target) const } const odb::Line edge_line(pt0, pt1); - if (boost::geometry::intersects(line.getPoints(), - edge_line.getPoints())) { + if (boost::geometry::intersects(line, edge_line)) { erase = true; break; } @@ -1079,12 +1080,11 @@ std::vector RDLRouter::commitRoute( } // remove intersecting edges - using Line = boost::geometry::model::segment; auto handle_rect_edge = [this, &edges](const odb::Rect& rect, const GridGraphEdge& edge) { const odb::Point& lpt0 = vertex_point_map_[edge.m_source]; const odb::Point& lpt1 = vertex_point_map_[edge.m_target]; - if (boost::geometry::intersects(rect, Line(lpt0, lpt1))) { + if (boost::geometry::intersects(rect, odb::Line(lpt0, lpt1))) { edges.insert(edge); } }; @@ -1106,12 +1106,11 @@ std::vector RDLRouter::commitRoute( if (allow45_) { // remove intersecting edges on 45 degrees - auto handle_poly_edge = [this, &edges](const odb::Polygon& poly, const GridGraphEdge& edge) { const odb::Point& lpt0 = vertex_point_map_[edge.m_source]; const odb::Point& lpt1 = vertex_point_map_[edge.m_target]; - if (boost::geometry::intersects(poly, Line(lpt0, lpt1))) { + if (boost::geometry::intersects(poly, odb::Line(lpt0, lpt1))) { edges.insert(edge); } }; @@ -1306,8 +1305,16 @@ void RDLRouter::makeGraph() } } + // Create a deterministic ordering of map entries to ensure consistent R-tree + // structure + std::vector> sorted_entries( + point_vertex_map_.begin(), point_vertex_map_.end()); + std::ranges::sort(sorted_entries); + std::vector grid_tree; - for (const auto& [point, vertex] : point_vertex_map_) { + grid_tree.reserve(sorted_entries.size()); + + for (const auto& [point, vertex] : sorted_entries) { odb::Rect rect(point, point); for (const auto& edge : getVertexEdges(vertex)) { rect.merge(odb::Rect(vertex_point_map_[edge.m_source], @@ -1329,20 +1336,27 @@ bool RDLRouter::isEdgeObstructed(const odb::Point& pt0, const odb::Point& pt1, bool use_routes) const { - using Line = boost::geometry::model::segment; - const Line line(pt0, pt1); + const odb::Line line(pt0, pt1); + + // Create a bounding box from the line for more efficient R-tree queries + // Rect-rect intersection (for R-tree filtering) is cheaper than line-rect + const odb::Rect bbox(pt0, pt1); + + // Query using bbox (more efficient R-tree filtering) then verify with + // line-polygon for (auto itr - = obstructions_.qbegin(boost::geometry::index::intersects(line)); + = obstructions_.qbegin(boost::geometry::index::intersects(bbox)); itr != obstructions_.qend(); itr++) { const ObsValue& obs = *itr; + // Check polygon with actual line segment for precise intersection if (boost::geometry::intersects(line, std::get<1>(obs))) { return true; } } if (use_routes) { for (const auto& route : routes_) { - if (route->isIntersecting(odb::Line(pt0, pt1), 0)) { + if (route->isIntersecting(line, 0)) { return true; } } @@ -1441,15 +1455,13 @@ bool RDLRouter::addGraphEdge(const odb::Point& point0, bool added; GridGraphEdge edge; + // For undirected graphs, we only need to check one direction + // since edge (v0, v1) is the same as edge (v1, v0) bool exists; boost::tie(edge, exists) = boost::lookup_edge(v0, v1, graph_); if (exists) { return true; } - boost::tie(edge, exists) = boost::lookup_edge(v1, v0, graph_); - if (exists) { - return true; - } boost::tie(edge, added) = boost::add_edge(v0, v1, graph_); if (!added) { @@ -1755,6 +1767,9 @@ void RDLRouter::populateObstructions(const std::vector& nets) auto& master_obs = master_obstruction_map[master]; if (master_obs.empty()) { BoostPolygonSet master_obstruction; + + // Collect all polygons to add (obstructions) + std::vector polys_to_add; for (auto* obs : master->getPolygonObstructions()) { if (obs->getTechLayer() != layer_) { continue; @@ -1762,9 +1777,7 @@ void RDLRouter::populateObstructions(const std::vector& nets) const odb::Polygon bloat_poly = obs->getPolygon().bloat(bloat); const auto pts = bloat_poly.getPoints(); - - const BoostPolygon polygon_in(pts.begin(), pts.end()); - master_obstruction += polygon_in; + polys_to_add.emplace_back(pts.begin(), pts.end()); } for (auto* obs : master->getObstructions(false)) { if (obs->getTechLayer() != layer_) { @@ -1774,12 +1787,18 @@ void RDLRouter::populateObstructions(const std::vector& nets) odb::Rect bloated; obs->getBox().bloat(bloat, bloated); const auto pts = bloated.getPoints(); + polys_to_add.emplace_back(pts.begin(), pts.end()); + } - const BoostPolygon polygon_in(pts.begin(), pts.end()); - master_obstruction += polygon_in; + // Build temporary set for all additions, then assign to + // master_obstruction + if (!polys_to_add.empty()) { + master_obstruction + = BoostPolygonSet(polys_to_add.begin(), polys_to_add.end()); } - // remove iterm shapes from master obstructions + // Collect all polygons to subtract (iterm shapes) + std::vector polys_to_subtract; for (auto* mterm : master->getMTerms()) { for (auto* mpin : mterm->getMPins()) { for (auto* geom : mpin->getPolygonGeometry()) { @@ -1789,8 +1808,7 @@ void RDLRouter::populateObstructions(const std::vector& nets) const odb::Polygon bloat_poly = geom->getPolygon().bloat(bloat); const auto pts = bloat_poly.getPoints(); - const BoostPolygon polygon_in(pts.begin(), pts.end()); - master_obstruction -= polygon_in; + polys_to_subtract.emplace_back(pts.begin(), pts.end()); } for (auto* geom : mpin->getGeometry(false)) { if (geom->getTechLayer() != layer_) { @@ -1799,12 +1817,18 @@ void RDLRouter::populateObstructions(const std::vector& nets) odb::Rect bloated; geom->getBox().bloat(bloat, bloated); const auto pts = bloated.getPoints(); - const BoostPolygon polygon_in(pts.begin(), pts.end()); - master_obstruction -= polygon_in; + polys_to_subtract.emplace_back(pts.begin(), pts.end()); } } } + // Build temporary set for all subtractions, then subtract from + // master_obstruction + if (!polys_to_subtract.empty()) { + master_obstruction -= BoostPolygonSet(polys_to_subtract.begin(), + polys_to_subtract.end()); + } + std::vector output_polygons; master_obstruction.get(output_polygons); for (const auto& polygon_out : output_polygons) { diff --git a/src/pad/src/RDLRouter.h b/src/pad/src/RDLRouter.h index 09c920e1b83..3e6ff8966df 100644 --- a/src/pad/src/RDLRouter.h +++ b/src/pad/src/RDLRouter.h @@ -8,6 +8,7 @@ #include #include #include +#include #include #include @@ -135,7 +136,7 @@ class RDLRouter boost::geometry::index::quadratic<16>>; const GridGraph& getGraph() const { return graph_; }; - const std::map& getVertexMap() const + const std::unordered_map& getVertexMap() const { return vertex_point_map_; } @@ -232,9 +233,9 @@ class RDLRouter ObsTree obstructions_; // Lookup tables - std::map point_vertex_map_; + std::unordered_map point_vertex_map_; GridTree vertex_grid_tree_; - std::map vertex_point_map_; + std::unordered_map vertex_point_map_; std::map> iterm_edges_; // Routing grid diff --git a/src/pdn/test/core_grid_existing_ports.ok b/src/pdn/test/core_grid_existing_ports.ok index 129bf8f47e2..18e7db6e624 100644 --- a/src/pdn/test/core_grid_existing_ports.ok +++ b/src/pdn/test/core_grid_existing_ports.ok @@ -5,4 +5,3 @@ [INFO ODB-0133] Created 385 nets and 1110 connections. [INFO PDN-0001] Inserting grid: Core [ERROR PDN-0214] BTerm VSS already exists for a different net (_000_) -Error: core_grid_existing_ports.tcl, 26 PDN-0214 diff --git a/src/pdn/test/core_grid_existing_ports.tcl b/src/pdn/test/core_grid_existing_ports.tcl index 1f5bb3f11cc..001ed0d5878 100644 --- a/src/pdn/test/core_grid_existing_ports.tcl +++ b/src/pdn/test/core_grid_existing_ports.tcl @@ -23,4 +23,4 @@ add_pdn_connect -layers {metal1 metal2} add_pdn_connect -layers {metal2 metal4} add_pdn_connect -layers {metal4 metal7} -pdngen +catch { pdngen } diff --git a/src/ram/include/ram/ram.h b/src/ram/include/ram/ram.h index 2e950f8ce82..1d79bc66110 100644 --- a/src/ram/include/ram/ram.h +++ b/src/ram/include/ram/ram.h @@ -126,6 +126,7 @@ class RamGen int column_mux_ratio, odb::dbNet* clock, odb::dbNet* write_enable, + odb::dbNet* word_select, const std::vector& selects, const std::vector& data_input, const std::vector>& data_output); @@ -143,13 +144,6 @@ class RamGen const std::vector& data_input, const std::vector>& data_output); - std::unique_ptr makeColMux( - const std::string& prefix, - int column_mux_ratio, - const std::vector& word_q_nets, - const std::vector& word_sel_nets, - odb::dbNet* q_out_net); - odb::dbBTerm* makeBTerm(const std::string& name, odb::dbIoType io_type); std::unique_ptr generateTapColumn(int word_count, int tapcell_col); diff --git a/src/ram/src/ram.cpp b/src/ram/src/ram.cpp index c7a942c4b0a..dceadffa607 100644 --- a/src/ram/src/ram.cpp +++ b/src/ram/src/ram.cpp @@ -151,7 +151,8 @@ void RamGen::makeSlice(const int slice_idx, const vector>& data_output) { const int start_bit_idx = slice_idx * mask_size; - std::string prefix = fmt::format("storage_{}_{}", row_idx, start_bit_idx); + std::string prefix + = fmt::format("storage_{}_{}_{}", row_idx, word_idx, start_bit_idx); vector select_b_nets(selects.size()); for (int i = 0; i < selects.size(); ++i) { select_b_nets[i] = makeNet(prefix, fmt::format("select{}_b", i)); @@ -262,92 +263,6 @@ void RamGen::makeWord(const int slices_per_word, } } -// mux made out of AOI22 cells used for col/mux feature. currently support only -// col_mux_ratio = 1,2,4 NOTE: ratio =1 mean no muxing so this function is not -// called in that case called once per bit by generate(), it will mux between -// every corresponding pair of bits of column_mux_ratio words -std::unique_ptr RamGen::makeColMux(const std::string& prefix, - const int column_mux_ratio, - const vector& word_q_nets, - const vector& word_sel_nets, - dbNet* q_out_net) -{ - // NOTE: word_sel_nets must be in strict alternating 'ascending' order of - // select signal i.e. [S0', S0, S1', S1, S2', S2, etc] - auto mux_cell = std::make_unique(); - const int num_stages = static_cast(std::log2(column_mux_ratio)); - const bool need_final_inv = (num_stages % 2 == 1); - - // Stage 1: one AOI22 per pair of word bits determined by column_mux_ratio - int num_pairs = column_mux_ratio / 2; - vector prev_nets(num_pairs); - - for (int i = 0; i < num_pairs; ++i) { - prev_nets[i] = dbNet::create( - block_, fmt::format("{}_aoi_s1_g{}", prefix, i).c_str()); - - // AOI boolean function: Y = (S0'I0 + S0I1)' = AOI22(S0', I0, S0, I1) - // AOI has inverted output so need an inverter if num_stage is odd - makeInst( - mux_cell.get(), - prefix, - fmt::format("aoi_s1_g{}", i), - aoi22_cell_, - {{aoi22_in_a1_, word_sel_nets[0]}, // S0' - {aoi22_in_a2_, word_q_nets[i * 2]}, // I0 = bit from word i*2 - {aoi22_in_b1_, word_sel_nets[1]}, // S0 - {aoi22_in_b2_, word_q_nets[i * 2 + 1]}, // I1 = bit from word i*2+1 - {aoi22_out_, prev_nets[i]}}); // output to next stage - } - - // Stages 2 to N: each stage halves the number of signals - // sel index increases by 2 per stage (Sn' at sel_idx, Sn at sel_idx+1) - for (int stage = 1; stage < num_stages; ++stage) { - int num_out = static_cast(prev_nets.size()) / 2; - vector curr_nets(num_out); - int sel_idx = stage * 2; - bool is_last_stage = (stage == num_stages - 1); - - for (int i = 0; i < num_out; ++i) { - // if this is the last stage and no INV needed, drive Q directly - // else create intermediate net for next stage or for final inverter - if (is_last_stage && !need_final_inv) { - curr_nets[i] = q_out_net; - } else { - curr_nets[i] = dbNet::create( - block_, - fmt::format("{}_aoi_s{}_g{}", prefix, stage + 1, i).c_str()); - } - - makeInst(mux_cell.get(), - prefix, - fmt::format("aoi_s{}_g{}", stage + 1, i), - aoi22_cell_, - {{aoi22_in_a1_, word_sel_nets[sel_idx]}, - {aoi22_in_a2_, prev_nets[i * 2]}, - {aoi22_in_b1_, word_sel_nets[sel_idx + 1]}, - {aoi22_in_b2_, prev_nets[i * 2 + 1]}, - {aoi22_out_, curr_nets[i]}}); - } - prev_nets = curr_nets; // output net of current stage becomes input net of - // next stage - } - - // Final stage/output: - // If "odd" stages (ratio = 2,8 meaning num_stages = 1,3): output inverted, - // add inverter If "even" stages (ratio = 4 meaning num_stages = 2): Q driven - // directly by last AOI22 output, no inverter needed - if (need_final_inv) { - makeInst(mux_cell.get(), - prefix, - "mux_inv", - inv_cell_, - {{"A", prev_nets[0]}, {"Y", q_out_net}}); - } - - return mux_cell; -} - std::unique_ptr RamGen::generateTapColumn(const int num_words, const int tapcell_col) { @@ -903,13 +818,13 @@ void RamGen::generate(const int mask_size, // input bterms for (int i = 0; i < num_inputs; ++i) { addr_inputs_.push_back( - makeBTerm(fmt::format("addr[{}]", i), dbIoType::INPUT)); + makeBTerm(fmt::format("addr_rw[{}]", i), dbIoType::INPUT)); } // vector of nets storing inverter nets vector inv_addr(num_inputs); for (int i = 0; i < num_inputs; ++i) { - inv_addr[i] = makeNet("inv", fmt::format("addr[{}]", i)); + inv_addr[i] = makeNet("inv", fmt::format("addr{}", i)); } // word select nets: one per word_idx (word within a row) shared between all @@ -924,6 +839,14 @@ void RamGen::generate(const int mask_size, if (column_mux_ratio == 2) { word_sel_nets[0] = inv_addr[0]; word_sel_nets[1] = addr_inputs_[0]->getNet(); + // place inv_addr[0] inverter in sel column + auto inv_sel_cell = std::make_unique(); + makeInst(inv_sel_cell.get(), + "word_sel", + "inv_addr_0", + inv_cell_, + {{"A", addr_inputs_[0]->getNet()}, {"Y", inv_addr[0]}}); + ram_grid_.addCell(std::move(inv_sel_cell), col_cell_count); } else if (column_mux_ratio == 4) { auto word_sel_cell = std::make_unique(); for (int c = 0; c < 4; ++c) { @@ -955,6 +878,16 @@ void RamGen::generate(const int mask_size, {{"A", addr_inputs_[1]->getNet()}, {"B", addr_inputs_[0]->getNet()}, {"X", word_sel_nets[3]}}); + makeInst(word_sel_cell.get(), + "word_sel", + "inv_addr_0", + inv_cell_, + {{"A", addr_inputs_[0]->getNet()}, {"Y", inv_addr[0]}}); + makeInst(word_sel_cell.get(), + "word_sel", + "inv_addr_1", + inv_cell_, + {{"A", addr_inputs_[1]->getNet()}, {"Y", inv_addr[1]}}); ram_grid_.addCell(std::move(word_sel_cell), col_cell_count); } @@ -980,7 +913,7 @@ void RamGen::generate(const int mask_size, // word decoder signals to have one deccoder per word, shared between all // slices of a word - vector> word_decoder_nets(num_words); + vector> word_decoder_nets(num_rows); for (int row = 0; row < num_rows; ++row) { auto decoder_name = fmt::format("decoder_{}", row); @@ -1010,7 +943,7 @@ void RamGen::generate(const int mask_size, for (int bit = 0; bit < word_size; ++bit) { data_inputs_.push_back( makeBTerm(fmt::format("D[{}]", bit), dbIoType::INPUT)); - D_nets[bit] = makeNet(fmt::format("D_nets[{}]", bit), "net"); + D_nets[bit] = makeNet("D_nets", fmt::format("b{}", bit)); // if readports == 1, only have Q outputs if (read_ports == 1) { @@ -1038,8 +971,7 @@ void RamGen::generate(const int mask_size, } else { for (int w = 0; w < column_mux_ratio; ++w) { for (int bit = 0; bit < word_size; ++bit) { - word_q_nets[w][bit] - = makeNet(fmt::format("word{}_q", w), fmt::format("[{}]", bit)); + word_q_nets[w][bit] = makeNet("word_q", fmt::format("w{}_b{}", w, bit)); } } } @@ -1068,31 +1000,96 @@ void RamGen::generate(const int mask_size, } } + // cell placement for mux made of AOI22 (and inverter if needed) for column + // muxing if (column_mux_ratio > 1) { - // build select nets once to be used for every bit and every slice - // NOTE: must be in exact alternating format: [S0', S0, S1', S1, ...] - vector mux_word_sel_nets; - for (int bit_idx = 0; bit_idx < num_word_bits; ++bit_idx) { - mux_word_sel_nets.push_back(inv_addr[bit_idx]); - mux_word_sel_nets.push_back(addr_inputs_[bit_idx]->getNet()); - } - for (int slice = 0; slice < slices_per_word; ++slice) { for (int bit = 0; bit < mask_size; ++bit) { const int global_bit = slice * mask_size + bit; + const int base_col + = slice * (mask_size * column_mux_ratio + column_mux_ratio) + + bit * column_mux_ratio; + const std::string prefix = fmt::format("mux_slice{}_bit{}", slice, bit); + + // collect this bit's net from each word vector bit_word_q_nets(column_mux_ratio); for (int word_idx = 0; word_idx < column_mux_ratio; ++word_idx) { bit_word_q_nets[word_idx] = word_q_nets[word_idx][global_bit]; } - int mux_col = slice * (mask_size * column_mux_ratio + column_mux_ratio) - + bit * column_mux_ratio; - ram_grid_.addCell( - makeColMux(fmt::format("mux_slice{}_bit{}", slice, bit), - column_mux_ratio, - bit_word_q_nets, - mux_word_sel_nets, - q_outputs_[0][global_bit]->getNet()), - mux_col); + + if (column_mux_ratio == 2) { + // mux placement + // col base_col+0: buffer + // col base_col+1: AOI22 + inverter side by side in same cell/column + auto aoi_out = makeNet(prefix, "aoi_out"); + auto mux_cell = std::make_unique(); + makeInst(mux_cell.get(), + prefix, + "aoi", + aoi22_cell_, + {{aoi22_in_a1_, inv_addr[0]}, + {aoi22_in_a2_, bit_word_q_nets[0]}, + {aoi22_in_b1_, addr_inputs_[0]->getNet()}, + {aoi22_in_b2_, bit_word_q_nets[1]}, + {aoi22_out_, aoi_out}}); + makeInst( + mux_cell.get(), + prefix, + "inv", + inv_cell_, + {{"A", aoi_out}, {"Y", q_outputs_[0][global_bit]->getNet()}}); + ram_grid_.addCell(std::move(mux_cell), base_col + 1); + + } else if (column_mux_ratio == 4) { + // mux placement: + // col base_col+0: buffer + // col base_col+1: s1_AOI_0 (w0+w1) + // col base_col+2: s2_AOI final (even stages so no inverter needed) + // col base_col+3: s1_AOI_1 (w2+w3) + auto s1_out_0 = makeNet(prefix, "s1_out_0"); + auto s1_out_1 = makeNet(prefix, "s1_out_1"); + + // col base_col+1: stage1 AOI for word0+word1 + auto s1_cell_0 = std::make_unique(); + makeInst(s1_cell_0.get(), + prefix, + "s1_aoi_0", + aoi22_cell_, + {{aoi22_in_a1_, inv_addr[0]}, + {aoi22_in_a2_, bit_word_q_nets[0]}, + {aoi22_in_b1_, addr_inputs_[0]->getNet()}, + {aoi22_in_b2_, bit_word_q_nets[1]}, + {aoi22_out_, s1_out_0}}); + ram_grid_.addCell(std::move(s1_cell_0), base_col + 1); + + // col base_col+3: stage1 AOI for word2 + word3 + // NOTE: must be placed before s2 so s1_out_1 net exists for s2 input + auto s1_cell_1 = std::make_unique(); + makeInst(s1_cell_1.get(), + prefix, + "s1_aoi_1", + aoi22_cell_, + {{aoi22_in_a1_, inv_addr[0]}, + {aoi22_in_a2_, bit_word_q_nets[2]}, + {aoi22_in_b1_, addr_inputs_[0]->getNet()}, + {aoi22_in_b2_, bit_word_q_nets[3]}, + {aoi22_out_, s1_out_1}}); + ram_grid_.addCell(std::move(s1_cell_1), base_col + 3); + + // col base_col+2: stage2 AOI combining stage 1 outputs and drives Q + // directly + auto s2_cell = std::make_unique(); + makeInst(s2_cell.get(), + prefix, + "s2_aoi", + aoi22_cell_, + {{aoi22_in_a1_, inv_addr[1]}, + {aoi22_in_a2_, s1_out_0}, + {aoi22_in_b1_, addr_inputs_[1]->getNet()}, + {aoi22_in_b2_, s1_out_1}, + {aoi22_out_, q_outputs_[0][global_bit]->getNet()}}); + ram_grid_.addCell(std::move(s2_cell), base_col + 2); + } } } } @@ -1107,14 +1104,17 @@ void RamGen::generate(const int mask_size, fmt::format("in[{}]", bit_idx), buffer_cell_, {{"A", data_inputs_[bit_idx]->getNet()}, {"X", D_nets[bit_idx]}}); - ram_grid_.addCell(std::move(buffer_grid_cell), bit_idx + slice); + int buf_col = slice * (mask_size * column_mux_ratio + column_mux_ratio) + + bit * column_mux_ratio; + + ram_grid_.addCell(std::move(buffer_grid_cell), buf_col); } } auto cell_inv_layout = std::make_unique(odb::vertical); // check for AND gate, specific case for 2 words - if (num_inputs > 1) { - for (int i = num_inputs - 1; i >= 0; --i) { + if (num_row_bits > 1) { + for (int i = num_inputs - 1; i >= num_word_bits; --i) { auto inv_grid_cell = std::make_unique(); makeInst(inv_grid_cell.get(), "decoder", @@ -1122,7 +1122,7 @@ void RamGen::generate(const int mask_size, inv_cell_, {{"A", addr_inputs_[i]->getNet()}, {"Y", inv_addr[i]}}); cell_inv_layout->addCell(std::move(inv_grid_cell)); - for (int filler_count = 0; filler_count < num_inputs - 1; + for (int filler_count = 0; filler_count < num_row_bits - 1; ++filler_count) { cell_inv_layout->addCell(nullptr); } @@ -1131,9 +1131,10 @@ void RamGen::generate(const int mask_size, auto inv_grid_cell = std::make_unique(); makeInst(inv_grid_cell.get(), "decoder", - fmt::format("inv_{}", 0), + fmt::format("inv_{}", num_word_bits), inv_cell_, - {{"A", addr_inputs_[0]->getNet()}, {"Y", inv_addr[0]}}); + {{"A", addr_inputs_[num_word_bits]->getNet()}, + {"Y", inv_addr[num_word_bits]}}); cell_inv_layout->addCell(std::move(inv_grid_cell)); } diff --git a/src/ram/src/ram.tcl b/src/ram/src/ram.tcl index acc1850cc67..24c3f360155 100644 --- a/src/ram/src/ram.tcl +++ b/src/ram/src/ram.tcl @@ -15,8 +15,8 @@ sta::define_cmd_args "generate_ram_netlist" {-mask_size bits proc generate_ram_netlist { args } { sta::parse_key_args "generate_ram_netlist" args \ keys { -mask_size -word_size -num_words -column_mux_ratio -storage_cell -tristate_cell -inv_cell - -read_ports -tapcell -max_tap_dist } flags {} - + -read_ports -tapcell -max_tap_dist -write_behavioral_verilog } flags {} + set column_mux_ratio 1 if { [info exists keys(-column_mux_ratio)] } { set column_mux_ratio $keys(-column_mux_ratio) @@ -79,6 +79,10 @@ proc generate_ram_netlist { args } { The generated layout may not pass Design Rule Checks." } + if { [info exists keys(-write_behavioral_verilog)] } { + ram::set_behavioral_verilog_filename $keys(-write_behavioral_verilog) + } + ram::generate_ram_netlist_cmd $mask_size $word_size $num_words $column_mux_ratio $storage_cell \ $tristate_cell $inv_cell $read_ports $tapcell $max_tap_dist } diff --git a/src/ram/test/make_8x8.defok b/src/ram/test/make_8x8.defok index 94aac718615..8544d0759a9 100644 --- a/src/ram/test/make_8x8.defok +++ b/src/ram/test/make_8x8.defok @@ -115,158 +115,158 @@ COMPONENTS 325 ; - decoder_7.and_layer0 sky130_fd_sc_hd__and2_0 + PLACED ( 10304 1904 ) FS ; - decoder_7.and_layer1 sky130_fd_sc_hd__and2_0 + PLACED ( 10534 1904 ) FS ; - decoder_7.buf_port0 sky130_fd_sc_hd__buf_1 + PLACED ( 10764 1904 ) FS ; - - storage_0_0.bit0.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 46 0 ) N ; - - storage_0_0.bit0.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 782 0 ) N ; - - storage_0_0.bit1.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 1196 0 ) N ; - - storage_0_0.bit1.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 1932 0 ) N ; - - storage_0_0.bit2.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 2346 0 ) N ; - - storage_0_0.bit2.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 3082 0 ) N ; - - storage_0_0.bit3.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 3496 0 ) N ; - - storage_0_0.bit3.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 4232 0 ) N ; - - storage_0_0.bit4.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 4646 0 ) N ; - - storage_0_0.bit4.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 5382 0 ) N ; - - storage_0_0.bit5.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 5796 0 ) N ; - - storage_0_0.bit5.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 6532 0 ) N ; - - storage_0_0.bit6.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 6946 0 ) N ; - - storage_0_0.bit6.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 7682 0 ) N ; - - storage_0_0.bit7.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 8096 0 ) N ; - - storage_0_0.bit7.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 8832 0 ) N ; - - storage_0_0.cg sky130_fd_sc_hd__dlclkp_1 + PLACED ( 9246 0 ) N ; - - storage_0_0.gcand sky130_fd_sc_hd__and2_0 + PLACED ( 9890 0 ) N ; - - storage_0_0.select_inv_0 sky130_fd_sc_hd__clkinv_1 + PLACED ( 10120 0 ) N ; - - storage_1_0.bit0.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 46 272 ) FS ; - - storage_1_0.bit0.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 782 272 ) FS ; - - storage_1_0.bit1.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 1196 272 ) FS ; - - storage_1_0.bit1.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 1932 272 ) FS ; - - storage_1_0.bit2.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 2346 272 ) FS ; - - storage_1_0.bit2.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 3082 272 ) FS ; - - storage_1_0.bit3.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 3496 272 ) FS ; - - storage_1_0.bit3.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 4232 272 ) FS ; - - storage_1_0.bit4.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 4646 272 ) FS ; - - storage_1_0.bit4.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 5382 272 ) FS ; - - storage_1_0.bit5.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 5796 272 ) FS ; - - storage_1_0.bit5.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 6532 272 ) FS ; - - storage_1_0.bit6.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 6946 272 ) FS ; - - storage_1_0.bit6.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 7682 272 ) FS ; - - storage_1_0.bit7.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 8096 272 ) FS ; - - storage_1_0.bit7.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 8832 272 ) FS ; - - storage_1_0.cg sky130_fd_sc_hd__dlclkp_1 + PLACED ( 9246 272 ) FS ; - - storage_1_0.gcand sky130_fd_sc_hd__and2_0 + PLACED ( 9890 272 ) FS ; - - storage_1_0.select_inv_0 sky130_fd_sc_hd__clkinv_1 + PLACED ( 10120 272 ) FS ; - - storage_2_0.bit0.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 46 544 ) N ; - - storage_2_0.bit0.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 782 544 ) N ; - - storage_2_0.bit1.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 1196 544 ) N ; - - storage_2_0.bit1.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 1932 544 ) N ; - - storage_2_0.bit2.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 2346 544 ) N ; - - storage_2_0.bit2.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 3082 544 ) N ; - - storage_2_0.bit3.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 3496 544 ) N ; - - storage_2_0.bit3.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 4232 544 ) N ; - - storage_2_0.bit4.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 4646 544 ) N ; - - storage_2_0.bit4.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 5382 544 ) N ; - - storage_2_0.bit5.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 5796 544 ) N ; - - storage_2_0.bit5.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 6532 544 ) N ; - - storage_2_0.bit6.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 6946 544 ) N ; - - storage_2_0.bit6.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 7682 544 ) N ; - - storage_2_0.bit7.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 8096 544 ) N ; - - storage_2_0.bit7.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 8832 544 ) N ; - - storage_2_0.cg sky130_fd_sc_hd__dlclkp_1 + PLACED ( 9246 544 ) N ; - - storage_2_0.gcand sky130_fd_sc_hd__and2_0 + PLACED ( 9890 544 ) N ; - - storage_2_0.select_inv_0 sky130_fd_sc_hd__clkinv_1 + PLACED ( 10120 544 ) N ; - - storage_3_0.bit0.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 46 816 ) FS ; - - storage_3_0.bit0.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 782 816 ) FS ; - - storage_3_0.bit1.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 1196 816 ) FS ; - - storage_3_0.bit1.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 1932 816 ) FS ; - - storage_3_0.bit2.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 2346 816 ) FS ; - - storage_3_0.bit2.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 3082 816 ) FS ; - - storage_3_0.bit3.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 3496 816 ) FS ; - - storage_3_0.bit3.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 4232 816 ) FS ; - - storage_3_0.bit4.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 4646 816 ) FS ; - - storage_3_0.bit4.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 5382 816 ) FS ; - - storage_3_0.bit5.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 5796 816 ) FS ; - - storage_3_0.bit5.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 6532 816 ) FS ; - - storage_3_0.bit6.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 6946 816 ) FS ; - - storage_3_0.bit6.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 7682 816 ) FS ; - - storage_3_0.bit7.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 8096 816 ) FS ; - - storage_3_0.bit7.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 8832 816 ) FS ; - - storage_3_0.cg sky130_fd_sc_hd__dlclkp_1 + PLACED ( 9246 816 ) FS ; - - storage_3_0.gcand sky130_fd_sc_hd__and2_0 + PLACED ( 9890 816 ) FS ; - - storage_3_0.select_inv_0 sky130_fd_sc_hd__clkinv_1 + PLACED ( 10120 816 ) FS ; - - storage_4_0.bit0.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 46 1088 ) N ; - - storage_4_0.bit0.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 782 1088 ) N ; - - storage_4_0.bit1.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 1196 1088 ) N ; - - storage_4_0.bit1.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 1932 1088 ) N ; - - storage_4_0.bit2.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 2346 1088 ) N ; - - storage_4_0.bit2.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 3082 1088 ) N ; - - storage_4_0.bit3.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 3496 1088 ) N ; - - storage_4_0.bit3.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 4232 1088 ) N ; - - storage_4_0.bit4.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 4646 1088 ) N ; - - storage_4_0.bit4.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 5382 1088 ) N ; - - storage_4_0.bit5.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 5796 1088 ) N ; - - storage_4_0.bit5.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 6532 1088 ) N ; - - storage_4_0.bit6.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 6946 1088 ) N ; - - storage_4_0.bit6.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 7682 1088 ) N ; - - storage_4_0.bit7.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 8096 1088 ) N ; - - storage_4_0.bit7.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 8832 1088 ) N ; - - storage_4_0.cg sky130_fd_sc_hd__dlclkp_1 + PLACED ( 9246 1088 ) N ; - - storage_4_0.gcand sky130_fd_sc_hd__and2_0 + PLACED ( 9890 1088 ) N ; - - storage_4_0.select_inv_0 sky130_fd_sc_hd__clkinv_1 + PLACED ( 10120 1088 ) N ; - - storage_5_0.bit0.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 46 1360 ) FS ; - - storage_5_0.bit0.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 782 1360 ) FS ; - - storage_5_0.bit1.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 1196 1360 ) FS ; - - storage_5_0.bit1.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 1932 1360 ) FS ; - - storage_5_0.bit2.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 2346 1360 ) FS ; - - storage_5_0.bit2.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 3082 1360 ) FS ; - - storage_5_0.bit3.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 3496 1360 ) FS ; - - storage_5_0.bit3.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 4232 1360 ) FS ; - - storage_5_0.bit4.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 4646 1360 ) FS ; - - storage_5_0.bit4.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 5382 1360 ) FS ; - - storage_5_0.bit5.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 5796 1360 ) FS ; - - storage_5_0.bit5.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 6532 1360 ) FS ; - - storage_5_0.bit6.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 6946 1360 ) FS ; - - storage_5_0.bit6.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 7682 1360 ) FS ; - - storage_5_0.bit7.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 8096 1360 ) FS ; - - storage_5_0.bit7.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 8832 1360 ) FS ; - - storage_5_0.cg sky130_fd_sc_hd__dlclkp_1 + PLACED ( 9246 1360 ) FS ; - - storage_5_0.gcand sky130_fd_sc_hd__and2_0 + PLACED ( 9890 1360 ) FS ; - - storage_5_0.select_inv_0 sky130_fd_sc_hd__clkinv_1 + PLACED ( 10120 1360 ) FS ; - - storage_6_0.bit0.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 46 1632 ) N ; - - storage_6_0.bit0.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 782 1632 ) N ; - - storage_6_0.bit1.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 1196 1632 ) N ; - - storage_6_0.bit1.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 1932 1632 ) N ; - - storage_6_0.bit2.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 2346 1632 ) N ; - - storage_6_0.bit2.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 3082 1632 ) N ; - - storage_6_0.bit3.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 3496 1632 ) N ; - - storage_6_0.bit3.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 4232 1632 ) N ; - - storage_6_0.bit4.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 4646 1632 ) N ; - - storage_6_0.bit4.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 5382 1632 ) N ; - - storage_6_0.bit5.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 5796 1632 ) N ; - - storage_6_0.bit5.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 6532 1632 ) N ; - - storage_6_0.bit6.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 6946 1632 ) N ; - - storage_6_0.bit6.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 7682 1632 ) N ; - - storage_6_0.bit7.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 8096 1632 ) N ; - - storage_6_0.bit7.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 8832 1632 ) N ; - - storage_6_0.cg sky130_fd_sc_hd__dlclkp_1 + PLACED ( 9246 1632 ) N ; - - storage_6_0.gcand sky130_fd_sc_hd__and2_0 + PLACED ( 9890 1632 ) N ; - - storage_6_0.select_inv_0 sky130_fd_sc_hd__clkinv_1 + PLACED ( 10120 1632 ) N ; - - storage_7_0.bit0.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 46 1904 ) FS ; - - storage_7_0.bit0.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 782 1904 ) FS ; - - storage_7_0.bit1.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 1196 1904 ) FS ; - - storage_7_0.bit1.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 1932 1904 ) FS ; - - storage_7_0.bit2.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 2346 1904 ) FS ; - - storage_7_0.bit2.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 3082 1904 ) FS ; - - storage_7_0.bit3.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 3496 1904 ) FS ; - - storage_7_0.bit3.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 4232 1904 ) FS ; - - storage_7_0.bit4.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 4646 1904 ) FS ; - - storage_7_0.bit4.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 5382 1904 ) FS ; - - storage_7_0.bit5.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 5796 1904 ) FS ; - - storage_7_0.bit5.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 6532 1904 ) FS ; - - storage_7_0.bit6.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 6946 1904 ) FS ; - - storage_7_0.bit6.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 7682 1904 ) FS ; - - storage_7_0.bit7.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 8096 1904 ) FS ; - - storage_7_0.bit7.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 8832 1904 ) FS ; - - storage_7_0.cg sky130_fd_sc_hd__dlclkp_1 + PLACED ( 9246 1904 ) FS ; - - storage_7_0.gcand sky130_fd_sc_hd__and2_0 + PLACED ( 9890 1904 ) FS ; - - storage_7_0.select_inv_0 sky130_fd_sc_hd__clkinv_1 + PLACED ( 10120 1904 ) FS ; + - storage_0_0_0.bit0.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 46 0 ) N ; + - storage_0_0_0.bit0.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 782 0 ) N ; + - storage_0_0_0.bit1.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 1196 0 ) N ; + - storage_0_0_0.bit1.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 1932 0 ) N ; + - storage_0_0_0.bit2.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 2346 0 ) N ; + - storage_0_0_0.bit2.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 3082 0 ) N ; + - storage_0_0_0.bit3.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 3496 0 ) N ; + - storage_0_0_0.bit3.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 4232 0 ) N ; + - storage_0_0_0.bit4.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 4646 0 ) N ; + - storage_0_0_0.bit4.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 5382 0 ) N ; + - storage_0_0_0.bit5.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 5796 0 ) N ; + - storage_0_0_0.bit5.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 6532 0 ) N ; + - storage_0_0_0.bit6.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 6946 0 ) N ; + - storage_0_0_0.bit6.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 7682 0 ) N ; + - storage_0_0_0.bit7.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 8096 0 ) N ; + - storage_0_0_0.bit7.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 8832 0 ) N ; + - storage_0_0_0.cg sky130_fd_sc_hd__dlclkp_1 + PLACED ( 9246 0 ) N ; + - storage_0_0_0.gcand sky130_fd_sc_hd__and2_0 + PLACED ( 9890 0 ) N ; + - storage_0_0_0.select_inv_0 sky130_fd_sc_hd__clkinv_1 + PLACED ( 10120 0 ) N ; + - storage_1_0_0.bit0.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 46 272 ) FS ; + - storage_1_0_0.bit0.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 782 272 ) FS ; + - storage_1_0_0.bit1.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 1196 272 ) FS ; + - storage_1_0_0.bit1.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 1932 272 ) FS ; + - storage_1_0_0.bit2.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 2346 272 ) FS ; + - storage_1_0_0.bit2.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 3082 272 ) FS ; + - storage_1_0_0.bit3.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 3496 272 ) FS ; + - storage_1_0_0.bit3.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 4232 272 ) FS ; + - storage_1_0_0.bit4.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 4646 272 ) FS ; + - storage_1_0_0.bit4.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 5382 272 ) FS ; + - storage_1_0_0.bit5.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 5796 272 ) FS ; + - storage_1_0_0.bit5.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 6532 272 ) FS ; + - storage_1_0_0.bit6.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 6946 272 ) FS ; + - storage_1_0_0.bit6.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 7682 272 ) FS ; + - storage_1_0_0.bit7.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 8096 272 ) FS ; + - storage_1_0_0.bit7.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 8832 272 ) FS ; + - storage_1_0_0.cg sky130_fd_sc_hd__dlclkp_1 + PLACED ( 9246 272 ) FS ; + - storage_1_0_0.gcand sky130_fd_sc_hd__and2_0 + PLACED ( 9890 272 ) FS ; + - storage_1_0_0.select_inv_0 sky130_fd_sc_hd__clkinv_1 + PLACED ( 10120 272 ) FS ; + - storage_2_0_0.bit0.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 46 544 ) N ; + - storage_2_0_0.bit0.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 782 544 ) N ; + - storage_2_0_0.bit1.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 1196 544 ) N ; + - storage_2_0_0.bit1.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 1932 544 ) N ; + - storage_2_0_0.bit2.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 2346 544 ) N ; + - storage_2_0_0.bit2.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 3082 544 ) N ; + - storage_2_0_0.bit3.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 3496 544 ) N ; + - storage_2_0_0.bit3.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 4232 544 ) N ; + - storage_2_0_0.bit4.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 4646 544 ) N ; + - storage_2_0_0.bit4.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 5382 544 ) N ; + - storage_2_0_0.bit5.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 5796 544 ) N ; + - storage_2_0_0.bit5.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 6532 544 ) N ; + - storage_2_0_0.bit6.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 6946 544 ) N ; + - storage_2_0_0.bit6.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 7682 544 ) N ; + - storage_2_0_0.bit7.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 8096 544 ) N ; + - storage_2_0_0.bit7.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 8832 544 ) N ; + - storage_2_0_0.cg sky130_fd_sc_hd__dlclkp_1 + PLACED ( 9246 544 ) N ; + - storage_2_0_0.gcand sky130_fd_sc_hd__and2_0 + PLACED ( 9890 544 ) N ; + - storage_2_0_0.select_inv_0 sky130_fd_sc_hd__clkinv_1 + PLACED ( 10120 544 ) N ; + - storage_3_0_0.bit0.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 46 816 ) FS ; + - storage_3_0_0.bit0.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 782 816 ) FS ; + - storage_3_0_0.bit1.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 1196 816 ) FS ; + - storage_3_0_0.bit1.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 1932 816 ) FS ; + - storage_3_0_0.bit2.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 2346 816 ) FS ; + - storage_3_0_0.bit2.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 3082 816 ) FS ; + - storage_3_0_0.bit3.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 3496 816 ) FS ; + - storage_3_0_0.bit3.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 4232 816 ) FS ; + - storage_3_0_0.bit4.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 4646 816 ) FS ; + - storage_3_0_0.bit4.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 5382 816 ) FS ; + - storage_3_0_0.bit5.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 5796 816 ) FS ; + - storage_3_0_0.bit5.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 6532 816 ) FS ; + - storage_3_0_0.bit6.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 6946 816 ) FS ; + - storage_3_0_0.bit6.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 7682 816 ) FS ; + - storage_3_0_0.bit7.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 8096 816 ) FS ; + - storage_3_0_0.bit7.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 8832 816 ) FS ; + - storage_3_0_0.cg sky130_fd_sc_hd__dlclkp_1 + PLACED ( 9246 816 ) FS ; + - storage_3_0_0.gcand sky130_fd_sc_hd__and2_0 + PLACED ( 9890 816 ) FS ; + - storage_3_0_0.select_inv_0 sky130_fd_sc_hd__clkinv_1 + PLACED ( 10120 816 ) FS ; + - storage_4_0_0.bit0.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 46 1088 ) N ; + - storage_4_0_0.bit0.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 782 1088 ) N ; + - storage_4_0_0.bit1.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 1196 1088 ) N ; + - storage_4_0_0.bit1.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 1932 1088 ) N ; + - storage_4_0_0.bit2.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 2346 1088 ) N ; + - storage_4_0_0.bit2.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 3082 1088 ) N ; + - storage_4_0_0.bit3.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 3496 1088 ) N ; + - storage_4_0_0.bit3.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 4232 1088 ) N ; + - storage_4_0_0.bit4.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 4646 1088 ) N ; + - storage_4_0_0.bit4.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 5382 1088 ) N ; + - storage_4_0_0.bit5.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 5796 1088 ) N ; + - storage_4_0_0.bit5.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 6532 1088 ) N ; + - storage_4_0_0.bit6.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 6946 1088 ) N ; + - storage_4_0_0.bit6.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 7682 1088 ) N ; + - storage_4_0_0.bit7.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 8096 1088 ) N ; + - storage_4_0_0.bit7.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 8832 1088 ) N ; + - storage_4_0_0.cg sky130_fd_sc_hd__dlclkp_1 + PLACED ( 9246 1088 ) N ; + - storage_4_0_0.gcand sky130_fd_sc_hd__and2_0 + PLACED ( 9890 1088 ) N ; + - storage_4_0_0.select_inv_0 sky130_fd_sc_hd__clkinv_1 + PLACED ( 10120 1088 ) N ; + - storage_5_0_0.bit0.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 46 1360 ) FS ; + - storage_5_0_0.bit0.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 782 1360 ) FS ; + - storage_5_0_0.bit1.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 1196 1360 ) FS ; + - storage_5_0_0.bit1.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 1932 1360 ) FS ; + - storage_5_0_0.bit2.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 2346 1360 ) FS ; + - storage_5_0_0.bit2.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 3082 1360 ) FS ; + - storage_5_0_0.bit3.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 3496 1360 ) FS ; + - storage_5_0_0.bit3.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 4232 1360 ) FS ; + - storage_5_0_0.bit4.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 4646 1360 ) FS ; + - storage_5_0_0.bit4.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 5382 1360 ) FS ; + - storage_5_0_0.bit5.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 5796 1360 ) FS ; + - storage_5_0_0.bit5.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 6532 1360 ) FS ; + - storage_5_0_0.bit6.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 6946 1360 ) FS ; + - storage_5_0_0.bit6.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 7682 1360 ) FS ; + - storage_5_0_0.bit7.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 8096 1360 ) FS ; + - storage_5_0_0.bit7.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 8832 1360 ) FS ; + - storage_5_0_0.cg sky130_fd_sc_hd__dlclkp_1 + PLACED ( 9246 1360 ) FS ; + - storage_5_0_0.gcand sky130_fd_sc_hd__and2_0 + PLACED ( 9890 1360 ) FS ; + - storage_5_0_0.select_inv_0 sky130_fd_sc_hd__clkinv_1 + PLACED ( 10120 1360 ) FS ; + - storage_6_0_0.bit0.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 46 1632 ) N ; + - storage_6_0_0.bit0.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 782 1632 ) N ; + - storage_6_0_0.bit1.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 1196 1632 ) N ; + - storage_6_0_0.bit1.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 1932 1632 ) N ; + - storage_6_0_0.bit2.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 2346 1632 ) N ; + - storage_6_0_0.bit2.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 3082 1632 ) N ; + - storage_6_0_0.bit3.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 3496 1632 ) N ; + - storage_6_0_0.bit3.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 4232 1632 ) N ; + - storage_6_0_0.bit4.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 4646 1632 ) N ; + - storage_6_0_0.bit4.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 5382 1632 ) N ; + - storage_6_0_0.bit5.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 5796 1632 ) N ; + - storage_6_0_0.bit5.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 6532 1632 ) N ; + - storage_6_0_0.bit6.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 6946 1632 ) N ; + - storage_6_0_0.bit6.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 7682 1632 ) N ; + - storage_6_0_0.bit7.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 8096 1632 ) N ; + - storage_6_0_0.bit7.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 8832 1632 ) N ; + - storage_6_0_0.cg sky130_fd_sc_hd__dlclkp_1 + PLACED ( 9246 1632 ) N ; + - storage_6_0_0.gcand sky130_fd_sc_hd__and2_0 + PLACED ( 9890 1632 ) N ; + - storage_6_0_0.select_inv_0 sky130_fd_sc_hd__clkinv_1 + PLACED ( 10120 1632 ) N ; + - storage_7_0_0.bit0.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 46 1904 ) FS ; + - storage_7_0_0.bit0.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 782 1904 ) FS ; + - storage_7_0_0.bit1.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 1196 1904 ) FS ; + - storage_7_0_0.bit1.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 1932 1904 ) FS ; + - storage_7_0_0.bit2.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 2346 1904 ) FS ; + - storage_7_0_0.bit2.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 3082 1904 ) FS ; + - storage_7_0_0.bit3.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 3496 1904 ) FS ; + - storage_7_0_0.bit3.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 4232 1904 ) FS ; + - storage_7_0_0.bit4.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 4646 1904 ) FS ; + - storage_7_0_0.bit4.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 5382 1904 ) FS ; + - storage_7_0_0.bit5.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 5796 1904 ) FS ; + - storage_7_0_0.bit5.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 6532 1904 ) FS ; + - storage_7_0_0.bit6.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 6946 1904 ) FS ; + - storage_7_0_0.bit6.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 7682 1904 ) FS ; + - storage_7_0_0.bit7.bit sky130_fd_sc_hd__dfxtp_1 + PLACED ( 8096 1904 ) FS ; + - storage_7_0_0.bit7.obuf0 sky130_fd_sc_hd__ebufn_1 + PLACED ( 8832 1904 ) FS ; + - storage_7_0_0.cg sky130_fd_sc_hd__dlclkp_1 + PLACED ( 9246 1904 ) FS ; + - storage_7_0_0.gcand sky130_fd_sc_hd__and2_0 + PLACED ( 9890 1904 ) FS ; + - storage_7_0_0.select_inv_0 sky130_fd_sc_hd__clkinv_1 + PLACED ( 10120 1904 ) FS ; - tapcell.cell0_0 sky130_fd_sc_hd__tap_1 + PLACED ( 0 0 ) N ; - tapcell.cell0_1 sky130_fd_sc_hd__tap_1 + PLACED ( 0 272 ) FS ; - tapcell.cell0_2 sky130_fd_sc_hd__tap_1 + PLACED ( 0 544 ) N ; @@ -463,15 +463,15 @@ PINS 23 ; + LAYER met1 ( 1 -2024 ) ( 15 -1976 ) + LAYER met1 ( -11025 -2024 ) ( -11011 -1976 ) + FIXED ( 11025 2000 ) N ; - - addr[0] + NET addr[0] + DIRECTION INPUT + USE SIGNAL + - addr_rw[0] + NET addr_rw[0] + DIRECTION INPUT + USE SIGNAL + PORT + LAYER met3 ( -40 -15 ) ( 40 15 ) + PLACED ( 11000 442 ) N ; - - addr[1] + NET addr[1] + DIRECTION INPUT + USE SIGNAL + - addr_rw[1] + NET addr_rw[1] + DIRECTION INPUT + USE SIGNAL + PORT + LAYER met3 ( -40 -15 ) ( 40 15 ) + PLACED ( 11000 714 ) N ; - - addr[2] + NET addr[2] + DIRECTION INPUT + USE SIGNAL + - addr_rw[2] + NET addr_rw[2] + DIRECTION INPUT + USE SIGNAL + PORT + LAYER met3 ( -40 -15 ) ( 40 15 ) + PLACED ( 11000 578 ) N ; @@ -497,26 +497,26 @@ SPECIALNETS 2 ; ( tapcell.cell2_1 VPWR ) ( tapcell.cell2_0 VPWR ) ( tapcell.cell1_8 VPWR ) ( tapcell.cell1_7 VPWR ) ( tapcell.cell1_6 VPWR ) ( tapcell.cell1_5 VPWR ) ( tapcell.cell1_4 VPWR ) ( tapcell.cell1_3 VPWR ) ( tapcell.cell1_2 VPWR ) ( tapcell.cell1_1 VPWR ) ( tapcell.cell1_0 VPWR ) ( tapcell.cell0_8 VPWR ) ( tapcell.cell0_7 VPWR ) ( tapcell.cell0_6 VPWR ) ( tapcell.cell0_5 VPWR ) ( tapcell.cell0_4 VPWR ) ( tapcell.cell0_3 VPWR ) ( tapcell.cell0_2 VPWR ) ( tapcell.cell0_1 VPWR ) ( tapcell.cell0_0 VPWR ) ( decoder.inv_0 VPWR ) ( decoder.inv_1 VPWR ) ( decoder.inv_2 VPWR ) ( buffer.in[7] VPWR ) - ( buffer.in[6] VPWR ) ( buffer.in[5] VPWR ) ( buffer.in[4] VPWR ) ( buffer.in[3] VPWR ) ( buffer.in[2] VPWR ) ( buffer.in[1] VPWR ) ( buffer.in[0] VPWR ) ( storage_7_0.select_inv_0 VPWR ) - ( storage_7_0.gcand VPWR ) ( storage_7_0.cg VPWR ) ( storage_7_0.bit7.obuf0 VPWR ) ( storage_7_0.bit7.bit VPWR ) ( storage_7_0.bit6.obuf0 VPWR ) ( storage_7_0.bit6.bit VPWR ) ( storage_7_0.bit5.obuf0 VPWR ) ( storage_7_0.bit5.bit VPWR ) - ( storage_7_0.bit4.obuf0 VPWR ) ( storage_7_0.bit4.bit VPWR ) ( storage_7_0.bit3.obuf0 VPWR ) ( storage_7_0.bit3.bit VPWR ) ( storage_7_0.bit2.obuf0 VPWR ) ( storage_7_0.bit2.bit VPWR ) ( storage_7_0.bit1.obuf0 VPWR ) ( storage_7_0.bit1.bit VPWR ) - ( storage_7_0.bit0.obuf0 VPWR ) ( storage_7_0.bit0.bit VPWR ) ( storage_6_0.select_inv_0 VPWR ) ( storage_6_0.gcand VPWR ) ( storage_6_0.cg VPWR ) ( storage_6_0.bit7.obuf0 VPWR ) ( storage_6_0.bit7.bit VPWR ) ( storage_6_0.bit6.obuf0 VPWR ) - ( storage_6_0.bit6.bit VPWR ) ( storage_6_0.bit5.obuf0 VPWR ) ( storage_6_0.bit5.bit VPWR ) ( storage_6_0.bit4.obuf0 VPWR ) ( storage_6_0.bit4.bit VPWR ) ( storage_6_0.bit3.obuf0 VPWR ) ( storage_6_0.bit3.bit VPWR ) ( storage_6_0.bit2.obuf0 VPWR ) - ( storage_6_0.bit2.bit VPWR ) ( storage_6_0.bit1.obuf0 VPWR ) ( storage_6_0.bit1.bit VPWR ) ( storage_6_0.bit0.obuf0 VPWR ) ( storage_6_0.bit0.bit VPWR ) ( storage_5_0.select_inv_0 VPWR ) ( storage_5_0.gcand VPWR ) ( storage_5_0.cg VPWR ) - ( storage_5_0.bit7.obuf0 VPWR ) ( storage_5_0.bit7.bit VPWR ) ( storage_5_0.bit6.obuf0 VPWR ) ( storage_5_0.bit6.bit VPWR ) ( storage_5_0.bit5.obuf0 VPWR ) ( storage_5_0.bit5.bit VPWR ) ( storage_5_0.bit4.obuf0 VPWR ) ( storage_5_0.bit4.bit VPWR ) - ( storage_5_0.bit3.obuf0 VPWR ) ( storage_5_0.bit3.bit VPWR ) ( storage_5_0.bit2.obuf0 VPWR ) ( storage_5_0.bit2.bit VPWR ) ( storage_5_0.bit1.obuf0 VPWR ) ( storage_5_0.bit1.bit VPWR ) ( storage_5_0.bit0.obuf0 VPWR ) ( storage_5_0.bit0.bit VPWR ) - ( storage_4_0.select_inv_0 VPWR ) ( storage_4_0.gcand VPWR ) ( storage_4_0.cg VPWR ) ( storage_4_0.bit7.obuf0 VPWR ) ( storage_4_0.bit7.bit VPWR ) ( storage_4_0.bit6.obuf0 VPWR ) ( storage_4_0.bit6.bit VPWR ) ( storage_4_0.bit5.obuf0 VPWR ) - ( storage_4_0.bit5.bit VPWR ) ( storage_4_0.bit4.obuf0 VPWR ) ( storage_4_0.bit4.bit VPWR ) ( storage_4_0.bit3.obuf0 VPWR ) ( storage_4_0.bit3.bit VPWR ) ( storage_4_0.bit2.obuf0 VPWR ) ( storage_4_0.bit2.bit VPWR ) ( storage_4_0.bit1.obuf0 VPWR ) - ( storage_4_0.bit1.bit VPWR ) ( storage_4_0.bit0.obuf0 VPWR ) ( storage_4_0.bit0.bit VPWR ) ( storage_3_0.select_inv_0 VPWR ) ( storage_3_0.gcand VPWR ) ( storage_3_0.cg VPWR ) ( storage_3_0.bit7.obuf0 VPWR ) ( storage_3_0.bit7.bit VPWR ) - ( storage_3_0.bit6.obuf0 VPWR ) ( storage_3_0.bit6.bit VPWR ) ( storage_3_0.bit5.obuf0 VPWR ) ( storage_3_0.bit5.bit VPWR ) ( storage_3_0.bit4.obuf0 VPWR ) ( storage_3_0.bit4.bit VPWR ) ( storage_3_0.bit3.obuf0 VPWR ) ( storage_3_0.bit3.bit VPWR ) - ( storage_3_0.bit2.obuf0 VPWR ) ( storage_3_0.bit2.bit VPWR ) ( storage_3_0.bit1.obuf0 VPWR ) ( storage_3_0.bit1.bit VPWR ) ( storage_3_0.bit0.obuf0 VPWR ) ( storage_3_0.bit0.bit VPWR ) ( storage_2_0.select_inv_0 VPWR ) ( storage_2_0.gcand VPWR ) - ( storage_2_0.cg VPWR ) ( storage_2_0.bit7.obuf0 VPWR ) ( storage_2_0.bit7.bit VPWR ) ( storage_2_0.bit6.obuf0 VPWR ) ( storage_2_0.bit6.bit VPWR ) ( storage_2_0.bit5.obuf0 VPWR ) ( storage_2_0.bit5.bit VPWR ) ( storage_2_0.bit4.obuf0 VPWR ) - ( storage_2_0.bit4.bit VPWR ) ( storage_2_0.bit3.obuf0 VPWR ) ( storage_2_0.bit3.bit VPWR ) ( storage_2_0.bit2.obuf0 VPWR ) ( storage_2_0.bit2.bit VPWR ) ( storage_2_0.bit1.obuf0 VPWR ) ( storage_2_0.bit1.bit VPWR ) ( storage_2_0.bit0.obuf0 VPWR ) - ( storage_2_0.bit0.bit VPWR ) ( storage_1_0.select_inv_0 VPWR ) ( storage_1_0.gcand VPWR ) ( storage_1_0.cg VPWR ) ( storage_1_0.bit7.obuf0 VPWR ) ( storage_1_0.bit7.bit VPWR ) ( storage_1_0.bit6.obuf0 VPWR ) ( storage_1_0.bit6.bit VPWR ) - ( storage_1_0.bit5.obuf0 VPWR ) ( storage_1_0.bit5.bit VPWR ) ( storage_1_0.bit4.obuf0 VPWR ) ( storage_1_0.bit4.bit VPWR ) ( storage_1_0.bit3.obuf0 VPWR ) ( storage_1_0.bit3.bit VPWR ) ( storage_1_0.bit2.obuf0 VPWR ) ( storage_1_0.bit2.bit VPWR ) - ( storage_1_0.bit1.obuf0 VPWR ) ( storage_1_0.bit1.bit VPWR ) ( storage_1_0.bit0.obuf0 VPWR ) ( storage_1_0.bit0.bit VPWR ) ( storage_0_0.select_inv_0 VPWR ) ( storage_0_0.gcand VPWR ) ( storage_0_0.cg VPWR ) ( storage_0_0.bit7.obuf0 VPWR ) - ( storage_0_0.bit7.bit VPWR ) ( storage_0_0.bit6.obuf0 VPWR ) ( storage_0_0.bit6.bit VPWR ) ( storage_0_0.bit5.obuf0 VPWR ) ( storage_0_0.bit5.bit VPWR ) ( storage_0_0.bit4.obuf0 VPWR ) ( storage_0_0.bit4.bit VPWR ) ( storage_0_0.bit3.obuf0 VPWR ) - ( storage_0_0.bit3.bit VPWR ) ( storage_0_0.bit2.obuf0 VPWR ) ( storage_0_0.bit2.bit VPWR ) ( storage_0_0.bit1.obuf0 VPWR ) ( storage_0_0.bit1.bit VPWR ) ( storage_0_0.bit0.obuf0 VPWR ) ( storage_0_0.bit0.bit VPWR ) ( decoder_7.buf_port0 VPWR ) + ( buffer.in[6] VPWR ) ( buffer.in[5] VPWR ) ( buffer.in[4] VPWR ) ( buffer.in[3] VPWR ) ( buffer.in[2] VPWR ) ( buffer.in[1] VPWR ) ( buffer.in[0] VPWR ) ( storage_7_0_0.select_inv_0 VPWR ) + ( storage_7_0_0.gcand VPWR ) ( storage_7_0_0.cg VPWR ) ( storage_7_0_0.bit7.obuf0 VPWR ) ( storage_7_0_0.bit7.bit VPWR ) ( storage_7_0_0.bit6.obuf0 VPWR ) ( storage_7_0_0.bit6.bit VPWR ) ( storage_7_0_0.bit5.obuf0 VPWR ) ( storage_7_0_0.bit5.bit VPWR ) + ( storage_7_0_0.bit4.obuf0 VPWR ) ( storage_7_0_0.bit4.bit VPWR ) ( storage_7_0_0.bit3.obuf0 VPWR ) ( storage_7_0_0.bit3.bit VPWR ) ( storage_7_0_0.bit2.obuf0 VPWR ) ( storage_7_0_0.bit2.bit VPWR ) ( storage_7_0_0.bit1.obuf0 VPWR ) ( storage_7_0_0.bit1.bit VPWR ) + ( storage_7_0_0.bit0.obuf0 VPWR ) ( storage_7_0_0.bit0.bit VPWR ) ( storage_6_0_0.select_inv_0 VPWR ) ( storage_6_0_0.gcand VPWR ) ( storage_6_0_0.cg VPWR ) ( storage_6_0_0.bit7.obuf0 VPWR ) ( storage_6_0_0.bit7.bit VPWR ) ( storage_6_0_0.bit6.obuf0 VPWR ) + ( storage_6_0_0.bit6.bit VPWR ) ( storage_6_0_0.bit5.obuf0 VPWR ) ( storage_6_0_0.bit5.bit VPWR ) ( storage_6_0_0.bit4.obuf0 VPWR ) ( storage_6_0_0.bit4.bit VPWR ) ( storage_6_0_0.bit3.obuf0 VPWR ) ( storage_6_0_0.bit3.bit VPWR ) ( storage_6_0_0.bit2.obuf0 VPWR ) + ( storage_6_0_0.bit2.bit VPWR ) ( storage_6_0_0.bit1.obuf0 VPWR ) ( storage_6_0_0.bit1.bit VPWR ) ( storage_6_0_0.bit0.obuf0 VPWR ) ( storage_6_0_0.bit0.bit VPWR ) ( storage_5_0_0.select_inv_0 VPWR ) ( storage_5_0_0.gcand VPWR ) ( storage_5_0_0.cg VPWR ) + ( storage_5_0_0.bit7.obuf0 VPWR ) ( storage_5_0_0.bit7.bit VPWR ) ( storage_5_0_0.bit6.obuf0 VPWR ) ( storage_5_0_0.bit6.bit VPWR ) ( storage_5_0_0.bit5.obuf0 VPWR ) ( storage_5_0_0.bit5.bit VPWR ) ( storage_5_0_0.bit4.obuf0 VPWR ) ( storage_5_0_0.bit4.bit VPWR ) + ( storage_5_0_0.bit3.obuf0 VPWR ) ( storage_5_0_0.bit3.bit VPWR ) ( storage_5_0_0.bit2.obuf0 VPWR ) ( storage_5_0_0.bit2.bit VPWR ) ( storage_5_0_0.bit1.obuf0 VPWR ) ( storage_5_0_0.bit1.bit VPWR ) ( storage_5_0_0.bit0.obuf0 VPWR ) ( storage_5_0_0.bit0.bit VPWR ) + ( storage_4_0_0.select_inv_0 VPWR ) ( storage_4_0_0.gcand VPWR ) ( storage_4_0_0.cg VPWR ) ( storage_4_0_0.bit7.obuf0 VPWR ) ( storage_4_0_0.bit7.bit VPWR ) ( storage_4_0_0.bit6.obuf0 VPWR ) ( storage_4_0_0.bit6.bit VPWR ) ( storage_4_0_0.bit5.obuf0 VPWR ) + ( storage_4_0_0.bit5.bit VPWR ) ( storage_4_0_0.bit4.obuf0 VPWR ) ( storage_4_0_0.bit4.bit VPWR ) ( storage_4_0_0.bit3.obuf0 VPWR ) ( storage_4_0_0.bit3.bit VPWR ) ( storage_4_0_0.bit2.obuf0 VPWR ) ( storage_4_0_0.bit2.bit VPWR ) ( storage_4_0_0.bit1.obuf0 VPWR ) + ( storage_4_0_0.bit1.bit VPWR ) ( storage_4_0_0.bit0.obuf0 VPWR ) ( storage_4_0_0.bit0.bit VPWR ) ( storage_3_0_0.select_inv_0 VPWR ) ( storage_3_0_0.gcand VPWR ) ( storage_3_0_0.cg VPWR ) ( storage_3_0_0.bit7.obuf0 VPWR ) ( storage_3_0_0.bit7.bit VPWR ) + ( storage_3_0_0.bit6.obuf0 VPWR ) ( storage_3_0_0.bit6.bit VPWR ) ( storage_3_0_0.bit5.obuf0 VPWR ) ( storage_3_0_0.bit5.bit VPWR ) ( storage_3_0_0.bit4.obuf0 VPWR ) ( storage_3_0_0.bit4.bit VPWR ) ( storage_3_0_0.bit3.obuf0 VPWR ) ( storage_3_0_0.bit3.bit VPWR ) + ( storage_3_0_0.bit2.obuf0 VPWR ) ( storage_3_0_0.bit2.bit VPWR ) ( storage_3_0_0.bit1.obuf0 VPWR ) ( storage_3_0_0.bit1.bit VPWR ) ( storage_3_0_0.bit0.obuf0 VPWR ) ( storage_3_0_0.bit0.bit VPWR ) ( storage_2_0_0.select_inv_0 VPWR ) ( storage_2_0_0.gcand VPWR ) + ( storage_2_0_0.cg VPWR ) ( storage_2_0_0.bit7.obuf0 VPWR ) ( storage_2_0_0.bit7.bit VPWR ) ( storage_2_0_0.bit6.obuf0 VPWR ) ( storage_2_0_0.bit6.bit VPWR ) ( storage_2_0_0.bit5.obuf0 VPWR ) ( storage_2_0_0.bit5.bit VPWR ) ( storage_2_0_0.bit4.obuf0 VPWR ) + ( storage_2_0_0.bit4.bit VPWR ) ( storage_2_0_0.bit3.obuf0 VPWR ) ( storage_2_0_0.bit3.bit VPWR ) ( storage_2_0_0.bit2.obuf0 VPWR ) ( storage_2_0_0.bit2.bit VPWR ) ( storage_2_0_0.bit1.obuf0 VPWR ) ( storage_2_0_0.bit1.bit VPWR ) ( storage_2_0_0.bit0.obuf0 VPWR ) + ( storage_2_0_0.bit0.bit VPWR ) ( storage_1_0_0.select_inv_0 VPWR ) ( storage_1_0_0.gcand VPWR ) ( storage_1_0_0.cg VPWR ) ( storage_1_0_0.bit7.obuf0 VPWR ) ( storage_1_0_0.bit7.bit VPWR ) ( storage_1_0_0.bit6.obuf0 VPWR ) ( storage_1_0_0.bit6.bit VPWR ) + ( storage_1_0_0.bit5.obuf0 VPWR ) ( storage_1_0_0.bit5.bit VPWR ) ( storage_1_0_0.bit4.obuf0 VPWR ) ( storage_1_0_0.bit4.bit VPWR ) ( storage_1_0_0.bit3.obuf0 VPWR ) ( storage_1_0_0.bit3.bit VPWR ) ( storage_1_0_0.bit2.obuf0 VPWR ) ( storage_1_0_0.bit2.bit VPWR ) + ( storage_1_0_0.bit1.obuf0 VPWR ) ( storage_1_0_0.bit1.bit VPWR ) ( storage_1_0_0.bit0.obuf0 VPWR ) ( storage_1_0_0.bit0.bit VPWR ) ( storage_0_0_0.select_inv_0 VPWR ) ( storage_0_0_0.gcand VPWR ) ( storage_0_0_0.cg VPWR ) ( storage_0_0_0.bit7.obuf0 VPWR ) + ( storage_0_0_0.bit7.bit VPWR ) ( storage_0_0_0.bit6.obuf0 VPWR ) ( storage_0_0_0.bit6.bit VPWR ) ( storage_0_0_0.bit5.obuf0 VPWR ) ( storage_0_0_0.bit5.bit VPWR ) ( storage_0_0_0.bit4.obuf0 VPWR ) ( storage_0_0_0.bit4.bit VPWR ) ( storage_0_0_0.bit3.obuf0 VPWR ) + ( storage_0_0_0.bit3.bit VPWR ) ( storage_0_0_0.bit2.obuf0 VPWR ) ( storage_0_0_0.bit2.bit VPWR ) ( storage_0_0_0.bit1.obuf0 VPWR ) ( storage_0_0_0.bit1.bit VPWR ) ( storage_0_0_0.bit0.obuf0 VPWR ) ( storage_0_0_0.bit0.bit VPWR ) ( decoder_7.buf_port0 VPWR ) ( decoder_7.and_layer1 VPWR ) ( decoder_7.and_layer0 VPWR ) ( decoder_6.buf_port0 VPWR ) ( decoder_6.and_layer1 VPWR ) ( decoder_6.and_layer0 VPWR ) ( decoder_5.buf_port0 VPWR ) ( decoder_5.and_layer1 VPWR ) ( decoder_5.and_layer0 VPWR ) ( decoder_4.buf_port0 VPWR ) ( decoder_4.and_layer1 VPWR ) ( decoder_4.and_layer0 VPWR ) ( decoder_3.buf_port0 VPWR ) ( decoder_3.and_layer1 VPWR ) ( decoder_3.and_layer0 VPWR ) ( decoder_2.buf_port0 VPWR ) ( decoder_2.and_layer1 VPWR ) ( decoder_2.and_layer0 VPWR ) ( decoder_1.buf_port0 VPWR ) ( decoder_1.and_layer1 VPWR ) ( decoder_1.and_layer0 VPWR ) ( decoder_0.buf_port0 VPWR ) ( decoder_0.and_layer1 VPWR ) ( decoder_0.and_layer0 VPWR ) + USE POWER @@ -559,26 +559,26 @@ SPECIALNETS 2 ; ( tapcell.cell2_1 VGND ) ( tapcell.cell2_0 VGND ) ( tapcell.cell1_8 VGND ) ( tapcell.cell1_7 VGND ) ( tapcell.cell1_6 VGND ) ( tapcell.cell1_5 VGND ) ( tapcell.cell1_4 VGND ) ( tapcell.cell1_3 VGND ) ( tapcell.cell1_2 VGND ) ( tapcell.cell1_1 VGND ) ( tapcell.cell1_0 VGND ) ( tapcell.cell0_8 VGND ) ( tapcell.cell0_7 VGND ) ( tapcell.cell0_6 VGND ) ( tapcell.cell0_5 VGND ) ( tapcell.cell0_4 VGND ) ( tapcell.cell0_3 VGND ) ( tapcell.cell0_2 VGND ) ( tapcell.cell0_1 VGND ) ( tapcell.cell0_0 VGND ) ( decoder.inv_0 VGND ) ( decoder.inv_1 VGND ) ( decoder.inv_2 VGND ) ( buffer.in[7] VGND ) - ( buffer.in[6] VGND ) ( buffer.in[5] VGND ) ( buffer.in[4] VGND ) ( buffer.in[3] VGND ) ( buffer.in[2] VGND ) ( buffer.in[1] VGND ) ( buffer.in[0] VGND ) ( storage_7_0.select_inv_0 VGND ) - ( storage_7_0.gcand VGND ) ( storage_7_0.cg VGND ) ( storage_7_0.bit7.obuf0 VGND ) ( storage_7_0.bit7.bit VGND ) ( storage_7_0.bit6.obuf0 VGND ) ( storage_7_0.bit6.bit VGND ) ( storage_7_0.bit5.obuf0 VGND ) ( storage_7_0.bit5.bit VGND ) - ( storage_7_0.bit4.obuf0 VGND ) ( storage_7_0.bit4.bit VGND ) ( storage_7_0.bit3.obuf0 VGND ) ( storage_7_0.bit3.bit VGND ) ( storage_7_0.bit2.obuf0 VGND ) ( storage_7_0.bit2.bit VGND ) ( storage_7_0.bit1.obuf0 VGND ) ( storage_7_0.bit1.bit VGND ) - ( storage_7_0.bit0.obuf0 VGND ) ( storage_7_0.bit0.bit VGND ) ( storage_6_0.select_inv_0 VGND ) ( storage_6_0.gcand VGND ) ( storage_6_0.cg VGND ) ( storage_6_0.bit7.obuf0 VGND ) ( storage_6_0.bit7.bit VGND ) ( storage_6_0.bit6.obuf0 VGND ) - ( storage_6_0.bit6.bit VGND ) ( storage_6_0.bit5.obuf0 VGND ) ( storage_6_0.bit5.bit VGND ) ( storage_6_0.bit4.obuf0 VGND ) ( storage_6_0.bit4.bit VGND ) ( storage_6_0.bit3.obuf0 VGND ) ( storage_6_0.bit3.bit VGND ) ( storage_6_0.bit2.obuf0 VGND ) - ( storage_6_0.bit2.bit VGND ) ( storage_6_0.bit1.obuf0 VGND ) ( storage_6_0.bit1.bit VGND ) ( storage_6_0.bit0.obuf0 VGND ) ( storage_6_0.bit0.bit VGND ) ( storage_5_0.select_inv_0 VGND ) ( storage_5_0.gcand VGND ) ( storage_5_0.cg VGND ) - ( storage_5_0.bit7.obuf0 VGND ) ( storage_5_0.bit7.bit VGND ) ( storage_5_0.bit6.obuf0 VGND ) ( storage_5_0.bit6.bit VGND ) ( storage_5_0.bit5.obuf0 VGND ) ( storage_5_0.bit5.bit VGND ) ( storage_5_0.bit4.obuf0 VGND ) ( storage_5_0.bit4.bit VGND ) - ( storage_5_0.bit3.obuf0 VGND ) ( storage_5_0.bit3.bit VGND ) ( storage_5_0.bit2.obuf0 VGND ) ( storage_5_0.bit2.bit VGND ) ( storage_5_0.bit1.obuf0 VGND ) ( storage_5_0.bit1.bit VGND ) ( storage_5_0.bit0.obuf0 VGND ) ( storage_5_0.bit0.bit VGND ) - ( storage_4_0.select_inv_0 VGND ) ( storage_4_0.gcand VGND ) ( storage_4_0.cg VGND ) ( storage_4_0.bit7.obuf0 VGND ) ( storage_4_0.bit7.bit VGND ) ( storage_4_0.bit6.obuf0 VGND ) ( storage_4_0.bit6.bit VGND ) ( storage_4_0.bit5.obuf0 VGND ) - ( storage_4_0.bit5.bit VGND ) ( storage_4_0.bit4.obuf0 VGND ) ( storage_4_0.bit4.bit VGND ) ( storage_4_0.bit3.obuf0 VGND ) ( storage_4_0.bit3.bit VGND ) ( storage_4_0.bit2.obuf0 VGND ) ( storage_4_0.bit2.bit VGND ) ( storage_4_0.bit1.obuf0 VGND ) - ( storage_4_0.bit1.bit VGND ) ( storage_4_0.bit0.obuf0 VGND ) ( storage_4_0.bit0.bit VGND ) ( storage_3_0.select_inv_0 VGND ) ( storage_3_0.gcand VGND ) ( storage_3_0.cg VGND ) ( storage_3_0.bit7.obuf0 VGND ) ( storage_3_0.bit7.bit VGND ) - ( storage_3_0.bit6.obuf0 VGND ) ( storage_3_0.bit6.bit VGND ) ( storage_3_0.bit5.obuf0 VGND ) ( storage_3_0.bit5.bit VGND ) ( storage_3_0.bit4.obuf0 VGND ) ( storage_3_0.bit4.bit VGND ) ( storage_3_0.bit3.obuf0 VGND ) ( storage_3_0.bit3.bit VGND ) - ( storage_3_0.bit2.obuf0 VGND ) ( storage_3_0.bit2.bit VGND ) ( storage_3_0.bit1.obuf0 VGND ) ( storage_3_0.bit1.bit VGND ) ( storage_3_0.bit0.obuf0 VGND ) ( storage_3_0.bit0.bit VGND ) ( storage_2_0.select_inv_0 VGND ) ( storage_2_0.gcand VGND ) - ( storage_2_0.cg VGND ) ( storage_2_0.bit7.obuf0 VGND ) ( storage_2_0.bit7.bit VGND ) ( storage_2_0.bit6.obuf0 VGND ) ( storage_2_0.bit6.bit VGND ) ( storage_2_0.bit5.obuf0 VGND ) ( storage_2_0.bit5.bit VGND ) ( storage_2_0.bit4.obuf0 VGND ) - ( storage_2_0.bit4.bit VGND ) ( storage_2_0.bit3.obuf0 VGND ) ( storage_2_0.bit3.bit VGND ) ( storage_2_0.bit2.obuf0 VGND ) ( storage_2_0.bit2.bit VGND ) ( storage_2_0.bit1.obuf0 VGND ) ( storage_2_0.bit1.bit VGND ) ( storage_2_0.bit0.obuf0 VGND ) - ( storage_2_0.bit0.bit VGND ) ( storage_1_0.select_inv_0 VGND ) ( storage_1_0.gcand VGND ) ( storage_1_0.cg VGND ) ( storage_1_0.bit7.obuf0 VGND ) ( storage_1_0.bit7.bit VGND ) ( storage_1_0.bit6.obuf0 VGND ) ( storage_1_0.bit6.bit VGND ) - ( storage_1_0.bit5.obuf0 VGND ) ( storage_1_0.bit5.bit VGND ) ( storage_1_0.bit4.obuf0 VGND ) ( storage_1_0.bit4.bit VGND ) ( storage_1_0.bit3.obuf0 VGND ) ( storage_1_0.bit3.bit VGND ) ( storage_1_0.bit2.obuf0 VGND ) ( storage_1_0.bit2.bit VGND ) - ( storage_1_0.bit1.obuf0 VGND ) ( storage_1_0.bit1.bit VGND ) ( storage_1_0.bit0.obuf0 VGND ) ( storage_1_0.bit0.bit VGND ) ( storage_0_0.select_inv_0 VGND ) ( storage_0_0.gcand VGND ) ( storage_0_0.cg VGND ) ( storage_0_0.bit7.obuf0 VGND ) - ( storage_0_0.bit7.bit VGND ) ( storage_0_0.bit6.obuf0 VGND ) ( storage_0_0.bit6.bit VGND ) ( storage_0_0.bit5.obuf0 VGND ) ( storage_0_0.bit5.bit VGND ) ( storage_0_0.bit4.obuf0 VGND ) ( storage_0_0.bit4.bit VGND ) ( storage_0_0.bit3.obuf0 VGND ) - ( storage_0_0.bit3.bit VGND ) ( storage_0_0.bit2.obuf0 VGND ) ( storage_0_0.bit2.bit VGND ) ( storage_0_0.bit1.obuf0 VGND ) ( storage_0_0.bit1.bit VGND ) ( storage_0_0.bit0.obuf0 VGND ) ( storage_0_0.bit0.bit VGND ) ( decoder_7.buf_port0 VGND ) + ( buffer.in[6] VGND ) ( buffer.in[5] VGND ) ( buffer.in[4] VGND ) ( buffer.in[3] VGND ) ( buffer.in[2] VGND ) ( buffer.in[1] VGND ) ( buffer.in[0] VGND ) ( storage_7_0_0.select_inv_0 VGND ) + ( storage_7_0_0.gcand VGND ) ( storage_7_0_0.cg VGND ) ( storage_7_0_0.bit7.obuf0 VGND ) ( storage_7_0_0.bit7.bit VGND ) ( storage_7_0_0.bit6.obuf0 VGND ) ( storage_7_0_0.bit6.bit VGND ) ( storage_7_0_0.bit5.obuf0 VGND ) ( storage_7_0_0.bit5.bit VGND ) + ( storage_7_0_0.bit4.obuf0 VGND ) ( storage_7_0_0.bit4.bit VGND ) ( storage_7_0_0.bit3.obuf0 VGND ) ( storage_7_0_0.bit3.bit VGND ) ( storage_7_0_0.bit2.obuf0 VGND ) ( storage_7_0_0.bit2.bit VGND ) ( storage_7_0_0.bit1.obuf0 VGND ) ( storage_7_0_0.bit1.bit VGND ) + ( storage_7_0_0.bit0.obuf0 VGND ) ( storage_7_0_0.bit0.bit VGND ) ( storage_6_0_0.select_inv_0 VGND ) ( storage_6_0_0.gcand VGND ) ( storage_6_0_0.cg VGND ) ( storage_6_0_0.bit7.obuf0 VGND ) ( storage_6_0_0.bit7.bit VGND ) ( storage_6_0_0.bit6.obuf0 VGND ) + ( storage_6_0_0.bit6.bit VGND ) ( storage_6_0_0.bit5.obuf0 VGND ) ( storage_6_0_0.bit5.bit VGND ) ( storage_6_0_0.bit4.obuf0 VGND ) ( storage_6_0_0.bit4.bit VGND ) ( storage_6_0_0.bit3.obuf0 VGND ) ( storage_6_0_0.bit3.bit VGND ) ( storage_6_0_0.bit2.obuf0 VGND ) + ( storage_6_0_0.bit2.bit VGND ) ( storage_6_0_0.bit1.obuf0 VGND ) ( storage_6_0_0.bit1.bit VGND ) ( storage_6_0_0.bit0.obuf0 VGND ) ( storage_6_0_0.bit0.bit VGND ) ( storage_5_0_0.select_inv_0 VGND ) ( storage_5_0_0.gcand VGND ) ( storage_5_0_0.cg VGND ) + ( storage_5_0_0.bit7.obuf0 VGND ) ( storage_5_0_0.bit7.bit VGND ) ( storage_5_0_0.bit6.obuf0 VGND ) ( storage_5_0_0.bit6.bit VGND ) ( storage_5_0_0.bit5.obuf0 VGND ) ( storage_5_0_0.bit5.bit VGND ) ( storage_5_0_0.bit4.obuf0 VGND ) ( storage_5_0_0.bit4.bit VGND ) + ( storage_5_0_0.bit3.obuf0 VGND ) ( storage_5_0_0.bit3.bit VGND ) ( storage_5_0_0.bit2.obuf0 VGND ) ( storage_5_0_0.bit2.bit VGND ) ( storage_5_0_0.bit1.obuf0 VGND ) ( storage_5_0_0.bit1.bit VGND ) ( storage_5_0_0.bit0.obuf0 VGND ) ( storage_5_0_0.bit0.bit VGND ) + ( storage_4_0_0.select_inv_0 VGND ) ( storage_4_0_0.gcand VGND ) ( storage_4_0_0.cg VGND ) ( storage_4_0_0.bit7.obuf0 VGND ) ( storage_4_0_0.bit7.bit VGND ) ( storage_4_0_0.bit6.obuf0 VGND ) ( storage_4_0_0.bit6.bit VGND ) ( storage_4_0_0.bit5.obuf0 VGND ) + ( storage_4_0_0.bit5.bit VGND ) ( storage_4_0_0.bit4.obuf0 VGND ) ( storage_4_0_0.bit4.bit VGND ) ( storage_4_0_0.bit3.obuf0 VGND ) ( storage_4_0_0.bit3.bit VGND ) ( storage_4_0_0.bit2.obuf0 VGND ) ( storage_4_0_0.bit2.bit VGND ) ( storage_4_0_0.bit1.obuf0 VGND ) + ( storage_4_0_0.bit1.bit VGND ) ( storage_4_0_0.bit0.obuf0 VGND ) ( storage_4_0_0.bit0.bit VGND ) ( storage_3_0_0.select_inv_0 VGND ) ( storage_3_0_0.gcand VGND ) ( storage_3_0_0.cg VGND ) ( storage_3_0_0.bit7.obuf0 VGND ) ( storage_3_0_0.bit7.bit VGND ) + ( storage_3_0_0.bit6.obuf0 VGND ) ( storage_3_0_0.bit6.bit VGND ) ( storage_3_0_0.bit5.obuf0 VGND ) ( storage_3_0_0.bit5.bit VGND ) ( storage_3_0_0.bit4.obuf0 VGND ) ( storage_3_0_0.bit4.bit VGND ) ( storage_3_0_0.bit3.obuf0 VGND ) ( storage_3_0_0.bit3.bit VGND ) + ( storage_3_0_0.bit2.obuf0 VGND ) ( storage_3_0_0.bit2.bit VGND ) ( storage_3_0_0.bit1.obuf0 VGND ) ( storage_3_0_0.bit1.bit VGND ) ( storage_3_0_0.bit0.obuf0 VGND ) ( storage_3_0_0.bit0.bit VGND ) ( storage_2_0_0.select_inv_0 VGND ) ( storage_2_0_0.gcand VGND ) + ( storage_2_0_0.cg VGND ) ( storage_2_0_0.bit7.obuf0 VGND ) ( storage_2_0_0.bit7.bit VGND ) ( storage_2_0_0.bit6.obuf0 VGND ) ( storage_2_0_0.bit6.bit VGND ) ( storage_2_0_0.bit5.obuf0 VGND ) ( storage_2_0_0.bit5.bit VGND ) ( storage_2_0_0.bit4.obuf0 VGND ) + ( storage_2_0_0.bit4.bit VGND ) ( storage_2_0_0.bit3.obuf0 VGND ) ( storage_2_0_0.bit3.bit VGND ) ( storage_2_0_0.bit2.obuf0 VGND ) ( storage_2_0_0.bit2.bit VGND ) ( storage_2_0_0.bit1.obuf0 VGND ) ( storage_2_0_0.bit1.bit VGND ) ( storage_2_0_0.bit0.obuf0 VGND ) + ( storage_2_0_0.bit0.bit VGND ) ( storage_1_0_0.select_inv_0 VGND ) ( storage_1_0_0.gcand VGND ) ( storage_1_0_0.cg VGND ) ( storage_1_0_0.bit7.obuf0 VGND ) ( storage_1_0_0.bit7.bit VGND ) ( storage_1_0_0.bit6.obuf0 VGND ) ( storage_1_0_0.bit6.bit VGND ) + ( storage_1_0_0.bit5.obuf0 VGND ) ( storage_1_0_0.bit5.bit VGND ) ( storage_1_0_0.bit4.obuf0 VGND ) ( storage_1_0_0.bit4.bit VGND ) ( storage_1_0_0.bit3.obuf0 VGND ) ( storage_1_0_0.bit3.bit VGND ) ( storage_1_0_0.bit2.obuf0 VGND ) ( storage_1_0_0.bit2.bit VGND ) + ( storage_1_0_0.bit1.obuf0 VGND ) ( storage_1_0_0.bit1.bit VGND ) ( storage_1_0_0.bit0.obuf0 VGND ) ( storage_1_0_0.bit0.bit VGND ) ( storage_0_0_0.select_inv_0 VGND ) ( storage_0_0_0.gcand VGND ) ( storage_0_0_0.cg VGND ) ( storage_0_0_0.bit7.obuf0 VGND ) + ( storage_0_0_0.bit7.bit VGND ) ( storage_0_0_0.bit6.obuf0 VGND ) ( storage_0_0_0.bit6.bit VGND ) ( storage_0_0_0.bit5.obuf0 VGND ) ( storage_0_0_0.bit5.bit VGND ) ( storage_0_0_0.bit4.obuf0 VGND ) ( storage_0_0_0.bit4.bit VGND ) ( storage_0_0_0.bit3.obuf0 VGND ) + ( storage_0_0_0.bit3.bit VGND ) ( storage_0_0_0.bit2.obuf0 VGND ) ( storage_0_0_0.bit2.bit VGND ) ( storage_0_0_0.bit1.obuf0 VGND ) ( storage_0_0_0.bit1.bit VGND ) ( storage_0_0_0.bit0.obuf0 VGND ) ( storage_0_0_0.bit0.bit VGND ) ( decoder_7.buf_port0 VGND ) ( decoder_7.and_layer1 VGND ) ( decoder_7.and_layer0 VGND ) ( decoder_6.buf_port0 VGND ) ( decoder_6.and_layer1 VGND ) ( decoder_6.and_layer0 VGND ) ( decoder_5.buf_port0 VGND ) ( decoder_5.and_layer1 VGND ) ( decoder_5.and_layer0 VGND ) ( decoder_4.buf_port0 VGND ) ( decoder_4.and_layer1 VGND ) ( decoder_4.and_layer0 VGND ) ( decoder_3.buf_port0 VGND ) ( decoder_3.and_layer1 VGND ) ( decoder_3.and_layer0 VGND ) ( decoder_2.buf_port0 VGND ) ( decoder_2.and_layer1 VGND ) ( decoder_2.and_layer0 VGND ) ( decoder_1.buf_port0 VGND ) ( decoder_1.and_layer1 VGND ) ( decoder_1.and_layer0 VGND ) ( decoder_0.buf_port0 VGND ) ( decoder_0.and_layer1 VGND ) ( decoder_0.and_layer0 VGND ) + USE GROUND @@ -640,8 +640,8 @@ NETS 152 ; + ROUTED met2 ( 8119 2295 ) ( * 2414 0 ) NEW li1 ( 8119 2295 ) L1M1_PR_MR NEW met1 ( 8119 2295 ) M1M2_PR ; - - D_nets[0].net ( buffer.in[0] X ) ( storage_7_0.bit0.bit D ) ( storage_6_0.bit0.bit D ) ( storage_5_0.bit0.bit D ) ( storage_4_0.bit0.bit D ) ( storage_3_0.bit0.bit D ) ( storage_2_0.bit0.bit D ) - ( storage_1_0.bit0.bit D ) ( storage_0_0.bit0.bit D ) + USE SIGNAL + - D_nets.b0 ( buffer.in[0] X ) ( storage_7_0_0.bit0.bit D ) ( storage_6_0_0.bit0.bit D ) ( storage_5_0_0.bit0.bit D ) ( storage_4_0_0.bit0.bit D ) ( storage_3_0_0.bit0.bit D ) ( storage_2_0_0.bit0.bit D ) + ( storage_1_0_0.bit0.bit D ) ( storage_0_0_0.bit0.bit D ) + USE SIGNAL + ROUTED met1 ( 202 2057 ) ( 207 * ) NEW met2 ( 207 2057 ) ( * 2227 ) NEW met1 ( 161 2227 ) ( 207 * ) @@ -685,195 +685,189 @@ NETS 152 ; NEW met1 ( 202 663 ) RECT ( -31 -7 0 7 ) NEW met1 ( 202 459 ) RECT ( -31 -7 0 7 ) NEW met1 ( 202 119 ) RECT ( -31 -7 0 7 ) ; - - D_nets[1].net ( buffer.in[1] X ) ( storage_7_0.bit1.bit D ) ( storage_6_0.bit1.bit D ) ( storage_5_0.bit1.bit D ) ( storage_4_0.bit1.bit D ) ( storage_3_0.bit1.bit D ) ( storage_2_0.bit1.bit D ) - ( storage_1_0.bit1.bit D ) ( storage_0_0.bit1.bit D ) + USE SIGNAL + - D_nets.b1 ( buffer.in[1] X ) ( storage_7_0_0.bit1.bit D ) ( storage_6_0_0.bit1.bit D ) ( storage_5_0_0.bit1.bit D ) ( storage_4_0_0.bit1.bit D ) ( storage_3_0_0.bit1.bit D ) ( storage_2_0_0.bit1.bit D ) + ( storage_1_0_0.bit1.bit D ) ( storage_0_0_0.bit1.bit D ) + USE SIGNAL + ROUTED met1 ( 1352 2057 ) ( 1357 * ) NEW met2 ( 1357 2057 ) ( * 2227 ) NEW met1 ( 1311 2227 ) ( 1357 * ) - NEW met1 ( 1352 1751 ) ( 1357 * ) - NEW met2 ( 1357 1751 ) ( * 2057 ) + NEW met1 ( 1352 1717 ) ( 1357 * ) + NEW met2 ( 1357 1717 ) ( * 2057 ) NEW met1 ( 1352 1547 ) ( 1357 * ) - NEW met2 ( 1357 1547 ) ( * 1751 ) - NEW met1 ( 1352 1173 ) ( 1357 * ) - NEW met2 ( 1357 1173 ) ( * 1547 ) + NEW met2 ( 1357 1547 ) ( * 1717 ) + NEW met1 ( 1352 1207 ) ( 1357 * ) + NEW met2 ( 1357 1207 ) ( * 1547 ) NEW met1 ( 1352 1003 ) ( 1357 * ) - NEW met2 ( 1357 1003 ) ( * 1173 ) + NEW met2 ( 1357 1003 ) ( * 1207 ) NEW met1 ( 1352 663 ) ( 1357 * ) NEW met2 ( 1357 663 ) ( * 1003 ) NEW met1 ( 1352 459 ) ( 1357 * ) NEW met2 ( 1357 459 ) ( * 663 ) - NEW met1 ( 1352 85 ) ( 1357 * ) - NEW met2 ( 1357 85 ) ( * 459 ) + NEW met1 ( 1352 119 ) ( 1357 * ) + NEW met2 ( 1357 119 ) ( * 459 ) NEW li1 ( 1352 2057 ) L1M1_PR_MR NEW met1 ( 1357 2057 ) M1M2_PR NEW met1 ( 1357 2227 ) M1M2_PR NEW li1 ( 1311 2227 ) L1M1_PR_MR - NEW li1 ( 1352 1751 ) L1M1_PR_MR - NEW met1 ( 1357 1751 ) M1M2_PR + NEW li1 ( 1352 1717 ) L1M1_PR_MR + NEW met1 ( 1357 1717 ) M1M2_PR NEW li1 ( 1352 1547 ) L1M1_PR_MR NEW met1 ( 1357 1547 ) M1M2_PR - NEW li1 ( 1352 1173 ) L1M1_PR_MR - NEW met1 ( 1357 1173 ) M1M2_PR + NEW li1 ( 1352 1207 ) L1M1_PR_MR + NEW met1 ( 1357 1207 ) M1M2_PR NEW li1 ( 1352 1003 ) L1M1_PR_MR NEW met1 ( 1357 1003 ) M1M2_PR NEW li1 ( 1352 663 ) L1M1_PR_MR NEW met1 ( 1357 663 ) M1M2_PR NEW li1 ( 1352 459 ) L1M1_PR_MR NEW met1 ( 1357 459 ) M1M2_PR - NEW li1 ( 1352 85 ) L1M1_PR_MR - NEW met1 ( 1357 85 ) M1M2_PR + NEW li1 ( 1352 119 ) L1M1_PR_MR + NEW met1 ( 1357 119 ) M1M2_PR NEW met1 ( 1352 2057 ) RECT ( -31 -7 0 7 ) - NEW met1 ( 1352 1751 ) RECT ( -31 -7 0 7 ) + NEW met1 ( 1352 1717 ) RECT ( -31 -7 0 7 ) NEW met1 ( 1352 1547 ) RECT ( -31 -7 0 7 ) - NEW met1 ( 1352 1173 ) RECT ( -31 -7 0 7 ) + NEW met1 ( 1352 1207 ) RECT ( -31 -7 0 7 ) NEW met1 ( 1352 1003 ) RECT ( -31 -7 0 7 ) NEW met1 ( 1352 663 ) RECT ( -31 -7 0 7 ) NEW met1 ( 1352 459 ) RECT ( -31 -7 0 7 ) - NEW met1 ( 1352 85 ) RECT ( -31 -7 0 7 ) ; - - D_nets[2].net ( buffer.in[2] X ) ( storage_7_0.bit2.bit D ) ( storage_6_0.bit2.bit D ) ( storage_5_0.bit2.bit D ) ( storage_4_0.bit2.bit D ) ( storage_3_0.bit2.bit D ) ( storage_2_0.bit2.bit D ) - ( storage_1_0.bit2.bit D ) ( storage_0_0.bit2.bit D ) + USE SIGNAL - + ROUTED met1 ( 2502 2057 ) ( 2507 * ) + NEW met1 ( 1352 119 ) RECT ( -31 -7 0 7 ) ; + - D_nets.b2 ( buffer.in[2] X ) ( storage_7_0_0.bit2.bit D ) ( storage_6_0_0.bit2.bit D ) ( storage_5_0_0.bit2.bit D ) ( storage_4_0_0.bit2.bit D ) ( storage_3_0_0.bit2.bit D ) ( storage_2_0_0.bit2.bit D ) + ( storage_1_0_0.bit2.bit D ) ( storage_0_0_0.bit2.bit D ) + USE SIGNAL + + ROUTED met1 ( 2502 1207 ) ( 2507 * ) + NEW met1 ( 2502 1003 ) ( 2507 * ) + NEW met2 ( 2507 1003 ) ( * 1207 ) + NEW met1 ( 2502 629 ) ( 2507 * ) + NEW met2 ( 2507 629 ) ( * 1003 ) + NEW met1 ( 2502 459 ) ( 2507 * ) + NEW met2 ( 2507 459 ) ( * 629 ) + NEW met1 ( 2502 119 ) ( 2507 * ) + NEW met2 ( 2507 119 ) ( * 459 ) + NEW met1 ( 2502 2057 ) ( 2507 * ) NEW met2 ( 2507 2057 ) ( * 2227 ) NEW met1 ( 2461 2227 ) ( 2507 * ) NEW met1 ( 2502 1751 ) ( 2507 * ) NEW met2 ( 2507 1751 ) ( * 2057 ) NEW met1 ( 2502 1547 ) ( 2507 * ) NEW met2 ( 2507 1547 ) ( * 1751 ) - NEW met1 ( 2502 1207 ) ( 2507 * ) - NEW met1 ( 2502 1003 ) ( 2507 * ) - NEW met2 ( 2507 1003 ) ( * 1207 ) - NEW met1 ( 2502 663 ) ( 2507 * ) - NEW met2 ( 2507 663 ) ( * 1003 ) - NEW met1 ( 2502 459 ) ( 2507 * ) - NEW met2 ( 2507 459 ) ( * 663 ) - NEW met1 ( 2502 119 ) ( 2507 * ) - NEW met2 ( 2507 119 ) ( * 459 ) NEW met2 ( 2507 1207 ) ( * 1547 ) - NEW li1 ( 2502 2057 ) L1M1_PR_MR - NEW met1 ( 2507 2057 ) M1M2_PR - NEW met1 ( 2507 2227 ) M1M2_PR - NEW li1 ( 2461 2227 ) L1M1_PR_MR - NEW li1 ( 2502 1751 ) L1M1_PR_MR - NEW met1 ( 2507 1751 ) M1M2_PR - NEW li1 ( 2502 1547 ) L1M1_PR_MR - NEW met1 ( 2507 1547 ) M1M2_PR NEW li1 ( 2502 1207 ) L1M1_PR_MR NEW met1 ( 2507 1207 ) M1M2_PR NEW li1 ( 2502 1003 ) L1M1_PR_MR NEW met1 ( 2507 1003 ) M1M2_PR - NEW li1 ( 2502 663 ) L1M1_PR_MR - NEW met1 ( 2507 663 ) M1M2_PR + NEW li1 ( 2502 629 ) L1M1_PR_MR + NEW met1 ( 2507 629 ) M1M2_PR NEW li1 ( 2502 459 ) L1M1_PR_MR NEW met1 ( 2507 459 ) M1M2_PR NEW li1 ( 2502 119 ) L1M1_PR_MR NEW met1 ( 2507 119 ) M1M2_PR - NEW met1 ( 2502 2057 ) RECT ( -31 -7 0 7 ) - NEW met1 ( 2502 1751 ) RECT ( -31 -7 0 7 ) - NEW met1 ( 2502 1547 ) RECT ( -31 -7 0 7 ) + NEW li1 ( 2502 2057 ) L1M1_PR_MR + NEW met1 ( 2507 2057 ) M1M2_PR + NEW met1 ( 2507 2227 ) M1M2_PR + NEW li1 ( 2461 2227 ) L1M1_PR_MR + NEW li1 ( 2502 1751 ) L1M1_PR_MR + NEW met1 ( 2507 1751 ) M1M2_PR + NEW li1 ( 2502 1547 ) L1M1_PR_MR + NEW met1 ( 2507 1547 ) M1M2_PR NEW met1 ( 2502 1207 ) RECT ( -31 -7 0 7 ) NEW met1 ( 2502 1003 ) RECT ( -31 -7 0 7 ) - NEW met1 ( 2502 663 ) RECT ( -31 -7 0 7 ) + NEW met1 ( 2507 629 ) RECT ( 0 -7 31 7 ) NEW met1 ( 2502 459 ) RECT ( -31 -7 0 7 ) - NEW met1 ( 2502 119 ) RECT ( -31 -7 0 7 ) ; - - D_nets[3].net ( buffer.in[3] X ) ( storage_7_0.bit3.bit D ) ( storage_6_0.bit3.bit D ) ( storage_5_0.bit3.bit D ) ( storage_4_0.bit3.bit D ) ( storage_3_0.bit3.bit D ) ( storage_2_0.bit3.bit D ) - ( storage_1_0.bit3.bit D ) ( storage_0_0.bit3.bit D ) + USE SIGNAL - + ROUTED met1 ( 3652 2057 ) ( 3657 * ) + NEW met1 ( 2502 119 ) RECT ( -31 -7 0 7 ) + NEW met1 ( 2502 2057 ) RECT ( -31 -7 0 7 ) + NEW met1 ( 2502 1751 ) RECT ( -31 -7 0 7 ) + NEW met1 ( 2502 1547 ) RECT ( -31 -7 0 7 ) ; + - D_nets.b3 ( buffer.in[3] X ) ( storage_7_0_0.bit3.bit D ) ( storage_6_0_0.bit3.bit D ) ( storage_5_0_0.bit3.bit D ) ( storage_4_0_0.bit3.bit D ) ( storage_3_0_0.bit3.bit D ) ( storage_2_0_0.bit3.bit D ) + ( storage_1_0_0.bit3.bit D ) ( storage_0_0_0.bit3.bit D ) + USE SIGNAL + + ROUTED met1 ( 3652 1207 ) ( 3657 * ) + NEW met1 ( 3652 1003 ) ( 3657 * ) + NEW met2 ( 3657 1003 ) ( * 1207 ) + NEW met1 ( 3652 629 ) ( 3657 * ) + NEW met2 ( 3657 629 ) ( * 1003 ) + NEW met1 ( 3652 459 ) ( 3657 * ) + NEW met2 ( 3657 459 ) ( * 629 ) + NEW met1 ( 3652 119 ) ( 3657 * ) + NEW met2 ( 3657 119 ) ( * 459 ) + NEW met1 ( 3652 2057 ) ( 3657 * ) NEW met2 ( 3657 2057 ) ( * 2227 ) NEW met1 ( 3611 2227 ) ( 3657 * ) NEW met1 ( 3652 1751 ) ( 3657 * ) NEW met2 ( 3657 1751 ) ( * 2057 ) NEW met1 ( 3652 1547 ) ( 3657 * ) NEW met2 ( 3657 1547 ) ( * 1751 ) - NEW met1 ( 3652 1207 ) ( 3657 * ) - NEW met1 ( 3652 1003 ) ( 3657 * ) - NEW met2 ( 3657 1003 ) ( * 1207 ) - NEW met1 ( 3652 663 ) ( 3657 * ) - NEW met2 ( 3657 663 ) ( * 1003 ) - NEW met1 ( 3652 459 ) ( 3657 * ) - NEW met2 ( 3657 459 ) ( * 663 ) - NEW met1 ( 3652 119 ) ( 3657 * ) - NEW met2 ( 3657 119 ) ( * 459 ) NEW met2 ( 3657 1207 ) ( * 1547 ) - NEW li1 ( 3652 2057 ) L1M1_PR_MR - NEW met1 ( 3657 2057 ) M1M2_PR - NEW met1 ( 3657 2227 ) M1M2_PR - NEW li1 ( 3611 2227 ) L1M1_PR_MR - NEW li1 ( 3652 1751 ) L1M1_PR_MR - NEW met1 ( 3657 1751 ) M1M2_PR - NEW li1 ( 3652 1547 ) L1M1_PR_MR - NEW met1 ( 3657 1547 ) M1M2_PR NEW li1 ( 3652 1207 ) L1M1_PR_MR NEW met1 ( 3657 1207 ) M1M2_PR NEW li1 ( 3652 1003 ) L1M1_PR_MR NEW met1 ( 3657 1003 ) M1M2_PR - NEW li1 ( 3652 663 ) L1M1_PR_MR - NEW met1 ( 3657 663 ) M1M2_PR + NEW li1 ( 3652 629 ) L1M1_PR_MR + NEW met1 ( 3657 629 ) M1M2_PR NEW li1 ( 3652 459 ) L1M1_PR_MR NEW met1 ( 3657 459 ) M1M2_PR NEW li1 ( 3652 119 ) L1M1_PR_MR NEW met1 ( 3657 119 ) M1M2_PR - NEW met1 ( 3652 2057 ) RECT ( -31 -7 0 7 ) - NEW met1 ( 3652 1751 ) RECT ( -31 -7 0 7 ) - NEW met1 ( 3652 1547 ) RECT ( -31 -7 0 7 ) + NEW li1 ( 3652 2057 ) L1M1_PR_MR + NEW met1 ( 3657 2057 ) M1M2_PR + NEW met1 ( 3657 2227 ) M1M2_PR + NEW li1 ( 3611 2227 ) L1M1_PR_MR + NEW li1 ( 3652 1751 ) L1M1_PR_MR + NEW met1 ( 3657 1751 ) M1M2_PR + NEW li1 ( 3652 1547 ) L1M1_PR_MR + NEW met1 ( 3657 1547 ) M1M2_PR NEW met1 ( 3652 1207 ) RECT ( -31 -7 0 7 ) NEW met1 ( 3652 1003 ) RECT ( -31 -7 0 7 ) - NEW met1 ( 3652 663 ) RECT ( -31 -7 0 7 ) + NEW met1 ( 3657 629 ) RECT ( 0 -7 31 7 ) NEW met1 ( 3652 459 ) RECT ( -31 -7 0 7 ) - NEW met1 ( 3652 119 ) RECT ( -31 -7 0 7 ) ; - - D_nets[4].net ( buffer.in[4] X ) ( storage_7_0.bit4.bit D ) ( storage_6_0.bit4.bit D ) ( storage_5_0.bit4.bit D ) ( storage_4_0.bit4.bit D ) ( storage_3_0.bit4.bit D ) ( storage_2_0.bit4.bit D ) - ( storage_1_0.bit4.bit D ) ( storage_0_0.bit4.bit D ) + USE SIGNAL - + ROUTED met1 ( 4802 2057 ) ( 4807 * ) + NEW met1 ( 3652 119 ) RECT ( -31 -7 0 7 ) + NEW met1 ( 3652 2057 ) RECT ( -31 -7 0 7 ) + NEW met1 ( 3652 1751 ) RECT ( -31 -7 0 7 ) + NEW met1 ( 3652 1547 ) RECT ( -31 -7 0 7 ) ; + - D_nets.b4 ( buffer.in[4] X ) ( storage_7_0_0.bit4.bit D ) ( storage_6_0_0.bit4.bit D ) ( storage_5_0_0.bit4.bit D ) ( storage_4_0_0.bit4.bit D ) ( storage_3_0_0.bit4.bit D ) ( storage_2_0_0.bit4.bit D ) + ( storage_1_0_0.bit4.bit D ) ( storage_0_0_0.bit4.bit D ) + USE SIGNAL + + ROUTED met1 ( 4802 1207 ) ( 4807 * ) + NEW met1 ( 4802 1003 ) ( 4807 * ) + NEW met2 ( 4807 1003 ) ( * 1207 ) + NEW met1 ( 4802 629 ) ( 4807 * ) + NEW met2 ( 4807 629 ) ( * 1003 ) + NEW met1 ( 4802 459 ) ( 4807 * ) + NEW met2 ( 4807 459 ) ( * 629 ) + NEW met1 ( 4802 119 ) ( 4807 * ) + NEW met2 ( 4807 119 ) ( * 459 ) + NEW met1 ( 4802 2057 ) ( 4807 * ) NEW met2 ( 4807 2057 ) ( * 2227 ) NEW met1 ( 4761 2227 ) ( 4807 * ) NEW met1 ( 4802 1751 ) ( 4807 * ) NEW met2 ( 4807 1751 ) ( * 2057 ) NEW met1 ( 4802 1547 ) ( 4807 * ) NEW met2 ( 4807 1547 ) ( * 1751 ) - NEW met1 ( 4802 1207 ) ( 4807 * ) - NEW met1 ( 4802 1003 ) ( 4807 * ) - NEW met2 ( 4807 1003 ) ( * 1207 ) - NEW met1 ( 4802 663 ) ( 4807 * ) - NEW met2 ( 4807 663 ) ( * 1003 ) - NEW met1 ( 4802 459 ) ( 4807 * ) - NEW met2 ( 4807 459 ) ( * 663 ) - NEW met1 ( 4802 119 ) ( 4807 * ) - NEW met2 ( 4807 119 ) ( * 459 ) NEW met2 ( 4807 1207 ) ( * 1547 ) - NEW li1 ( 4802 2057 ) L1M1_PR_MR - NEW met1 ( 4807 2057 ) M1M2_PR - NEW met1 ( 4807 2227 ) M1M2_PR - NEW li1 ( 4761 2227 ) L1M1_PR_MR - NEW li1 ( 4802 1751 ) L1M1_PR_MR - NEW met1 ( 4807 1751 ) M1M2_PR - NEW li1 ( 4802 1547 ) L1M1_PR_MR - NEW met1 ( 4807 1547 ) M1M2_PR NEW li1 ( 4802 1207 ) L1M1_PR_MR NEW met1 ( 4807 1207 ) M1M2_PR NEW li1 ( 4802 1003 ) L1M1_PR_MR NEW met1 ( 4807 1003 ) M1M2_PR - NEW li1 ( 4802 663 ) L1M1_PR_MR - NEW met1 ( 4807 663 ) M1M2_PR + NEW li1 ( 4802 629 ) L1M1_PR_MR + NEW met1 ( 4807 629 ) M1M2_PR NEW li1 ( 4802 459 ) L1M1_PR_MR NEW met1 ( 4807 459 ) M1M2_PR NEW li1 ( 4802 119 ) L1M1_PR_MR NEW met1 ( 4807 119 ) M1M2_PR - NEW met1 ( 4802 2057 ) RECT ( -31 -7 0 7 ) - NEW met1 ( 4802 1751 ) RECT ( -31 -7 0 7 ) - NEW met1 ( 4802 1547 ) RECT ( -31 -7 0 7 ) + NEW li1 ( 4802 2057 ) L1M1_PR_MR + NEW met1 ( 4807 2057 ) M1M2_PR + NEW met1 ( 4807 2227 ) M1M2_PR + NEW li1 ( 4761 2227 ) L1M1_PR_MR + NEW li1 ( 4802 1751 ) L1M1_PR_MR + NEW met1 ( 4807 1751 ) M1M2_PR + NEW li1 ( 4802 1547 ) L1M1_PR_MR + NEW met1 ( 4807 1547 ) M1M2_PR NEW met1 ( 4802 1207 ) RECT ( -31 -7 0 7 ) NEW met1 ( 4802 1003 ) RECT ( -31 -7 0 7 ) - NEW met1 ( 4802 663 ) RECT ( -31 -7 0 7 ) + NEW met1 ( 4807 629 ) RECT ( 0 -7 31 7 ) NEW met1 ( 4802 459 ) RECT ( -31 -7 0 7 ) - NEW met1 ( 4802 119 ) RECT ( -31 -7 0 7 ) ; - - D_nets[5].net ( buffer.in[5] X ) ( storage_7_0.bit5.bit D ) ( storage_6_0.bit5.bit D ) ( storage_5_0.bit5.bit D ) ( storage_4_0.bit5.bit D ) ( storage_3_0.bit5.bit D ) ( storage_2_0.bit5.bit D ) - ( storage_1_0.bit5.bit D ) ( storage_0_0.bit5.bit D ) + USE SIGNAL - + ROUTED met1 ( 5865 1751 ) ( 5947 * ) - NEW met2 ( 5865 1751 ) ( * 2227 ) - NEW met1 ( 5865 2227 ) ( 5911 * ) - NEW met1 ( 5865 2091 ) ( 5941 * ) - NEW met1 ( 5865 1547 ) ( 5941 * ) - NEW met2 ( 5865 1547 ) ( * 1751 ) - NEW met1 ( 5865 1207 ) ( 5947 * ) + NEW met1 ( 4802 119 ) RECT ( -31 -7 0 7 ) + NEW met1 ( 4802 2057 ) RECT ( -31 -7 0 7 ) + NEW met1 ( 4802 1751 ) RECT ( -31 -7 0 7 ) + NEW met1 ( 4802 1547 ) RECT ( -31 -7 0 7 ) ; + - D_nets.b5 ( buffer.in[5] X ) ( storage_7_0_0.bit5.bit D ) ( storage_6_0_0.bit5.bit D ) ( storage_5_0_0.bit5.bit D ) ( storage_4_0_0.bit5.bit D ) ( storage_3_0_0.bit5.bit D ) ( storage_2_0_0.bit5.bit D ) + ( storage_1_0_0.bit5.bit D ) ( storage_0_0_0.bit5.bit D ) + USE SIGNAL + + ROUTED met1 ( 5865 1207 ) ( 5947 * ) NEW met1 ( 5865 1003 ) ( 5941 * ) NEW met2 ( 5865 1003 ) ( * 1207 ) NEW met1 ( 5865 663 ) ( 5947 * ) @@ -882,15 +876,14 @@ NETS 152 ; NEW met2 ( 5865 459 ) ( * 663 ) NEW met1 ( 5865 119 ) ( 5947 * ) NEW met2 ( 5865 119 ) ( * 459 ) - NEW met2 ( 5865 1207 ) ( * 1547 ) - NEW li1 ( 5947 1751 ) L1M1_PR_MR - NEW met1 ( 5865 1751 ) M1M2_PR - NEW met1 ( 5865 2227 ) M1M2_PR - NEW li1 ( 5911 2227 ) L1M1_PR_MR - NEW li1 ( 5941 2091 ) L1M1_PR_MR - NEW met1 ( 5865 2091 ) M1M2_PR - NEW li1 ( 5941 1547 ) L1M1_PR_MR - NEW met1 ( 5865 1547 ) M1M2_PR + NEW met1 ( 5865 1513 ) ( 5947 * ) + NEW met1 ( 5865 1717 ) ( 5941 * ) + NEW met2 ( 5865 1513 ) ( * 1717 ) + NEW met1 ( 5865 2057 ) ( 5947 * ) + NEW met2 ( 5865 1717 ) ( * 2057 ) + NEW met1 ( 5865 2227 ) ( 5911 * ) + NEW met2 ( 5865 2057 ) ( * 2227 ) + NEW met2 ( 5865 1207 ) ( * 1513 ) NEW li1 ( 5947 1207 ) L1M1_PR_MR NEW met1 ( 5865 1207 ) M1M2_PR NEW li1 ( 5941 1003 ) L1M1_PR_MR @@ -900,16 +893,24 @@ NETS 152 ; NEW li1 ( 5941 459 ) L1M1_PR_MR NEW met1 ( 5865 459 ) M1M2_PR NEW li1 ( 5947 119 ) L1M1_PR_MR - NEW met1 ( 5865 119 ) M1M2_PR ; - - D_nets[6].net ( buffer.in[6] X ) ( storage_7_0.bit6.bit D ) ( storage_6_0.bit6.bit D ) ( storage_5_0.bit6.bit D ) ( storage_4_0.bit6.bit D ) ( storage_3_0.bit6.bit D ) ( storage_2_0.bit6.bit D ) - ( storage_1_0.bit6.bit D ) ( storage_0_0.bit6.bit D ) + USE SIGNAL + NEW met1 ( 5865 119 ) M1M2_PR + NEW li1 ( 5947 1513 ) L1M1_PR_MR + NEW met1 ( 5865 1513 ) M1M2_PR + NEW li1 ( 5941 1717 ) L1M1_PR_MR + NEW met1 ( 5865 1717 ) M1M2_PR + NEW li1 ( 5947 2057 ) L1M1_PR_MR + NEW met1 ( 5865 2057 ) M1M2_PR + NEW li1 ( 5911 2227 ) L1M1_PR_MR + NEW met1 ( 5865 2227 ) M1M2_PR ; + - D_nets.b6 ( buffer.in[6] X ) ( storage_7_0_0.bit6.bit D ) ( storage_6_0_0.bit6.bit D ) ( storage_5_0_0.bit6.bit D ) ( storage_4_0_0.bit6.bit D ) ( storage_3_0_0.bit6.bit D ) ( storage_2_0_0.bit6.bit D ) + ( storage_1_0_0.bit6.bit D ) ( storage_0_0_0.bit6.bit D ) + USE SIGNAL + ROUTED met1 ( 7102 1207 ) ( 7107 * ) NEW met1 ( 7102 1003 ) ( 7107 * ) NEW met2 ( 7107 1003 ) ( * 1207 ) - NEW met1 ( 7102 629 ) ( 7107 * ) - NEW met2 ( 7107 629 ) ( * 1003 ) + NEW met1 ( 7102 663 ) ( 7107 * ) + NEW met2 ( 7107 663 ) ( * 1003 ) NEW met1 ( 7102 459 ) ( 7107 * ) - NEW met2 ( 7107 459 ) ( * 629 ) + NEW met2 ( 7107 459 ) ( * 663 ) NEW met1 ( 7102 119 ) ( 7107 * ) NEW met2 ( 7107 119 ) ( * 459 ) NEW met1 ( 7102 2057 ) ( 7107 * ) @@ -924,8 +925,8 @@ NETS 152 ; NEW met1 ( 7107 1207 ) M1M2_PR NEW li1 ( 7102 1003 ) L1M1_PR_MR NEW met1 ( 7107 1003 ) M1M2_PR - NEW li1 ( 7102 629 ) L1M1_PR_MR - NEW met1 ( 7107 629 ) M1M2_PR + NEW li1 ( 7102 663 ) L1M1_PR_MR + NEW met1 ( 7107 663 ) M1M2_PR NEW li1 ( 7102 459 ) L1M1_PR_MR NEW met1 ( 7107 459 ) M1M2_PR NEW li1 ( 7102 119 ) L1M1_PR_MR @@ -940,14 +941,14 @@ NETS 152 ; NEW met1 ( 7107 1547 ) M1M2_PR NEW met1 ( 7102 1207 ) RECT ( -31 -7 0 7 ) NEW met1 ( 7102 1003 ) RECT ( -31 -7 0 7 ) - NEW met1 ( 7102 629 ) RECT ( -31 -7 0 7 ) + NEW met1 ( 7102 663 ) RECT ( -31 -7 0 7 ) NEW met1 ( 7102 459 ) RECT ( -31 -7 0 7 ) NEW met1 ( 7102 119 ) RECT ( -31 -7 0 7 ) NEW met1 ( 7102 2057 ) RECT ( -31 -7 0 7 ) NEW met1 ( 7102 1751 ) RECT ( -31 -7 0 7 ) NEW met1 ( 7102 1547 ) RECT ( -31 -7 0 7 ) ; - - D_nets[7].net ( buffer.in[7] X ) ( storage_7_0.bit7.bit D ) ( storage_6_0.bit7.bit D ) ( storage_5_0.bit7.bit D ) ( storage_4_0.bit7.bit D ) ( storage_3_0.bit7.bit D ) ( storage_2_0.bit7.bit D ) - ( storage_1_0.bit7.bit D ) ( storage_0_0.bit7.bit D ) + USE SIGNAL + - D_nets.b7 ( buffer.in[7] X ) ( storage_7_0_0.bit7.bit D ) ( storage_6_0_0.bit7.bit D ) ( storage_5_0_0.bit7.bit D ) ( storage_4_0_0.bit7.bit D ) ( storage_3_0_0.bit7.bit D ) ( storage_2_0_0.bit7.bit D ) + ( storage_1_0_0.bit7.bit D ) ( storage_0_0_0.bit7.bit D ) + USE SIGNAL + ROUTED met1 ( 8252 2057 ) ( 8257 * ) NEW met2 ( 8257 2057 ) ( * 2227 ) NEW met1 ( 8211 2227 ) ( 8257 * ) @@ -991,8 +992,8 @@ NETS 152 ; NEW met1 ( 8252 663 ) RECT ( -31 -7 0 7 ) NEW met1 ( 8252 459 ) RECT ( -31 -7 0 7 ) NEW met1 ( 8252 119 ) RECT ( -31 -7 0 7 ) ; - - Q[0] ( PIN Q[0] ) ( storage_7_0.bit0.obuf0 Z ) ( storage_6_0.bit0.obuf0 Z ) ( storage_5_0.bit0.obuf0 Z ) ( storage_4_0.bit0.obuf0 Z ) ( storage_3_0.bit0.obuf0 Z ) ( storage_2_0.bit0.obuf0 Z ) - ( storage_1_0.bit0.obuf0 Z ) ( storage_0_0.bit0.obuf0 Z ) + USE SIGNAL + - Q[0] ( PIN Q[0] ) ( storage_7_0_0.bit0.obuf0 Z ) ( storage_6_0_0.bit0.obuf0 Z ) ( storage_5_0_0.bit0.obuf0 Z ) ( storage_4_0_0.bit0.obuf0 Z ) ( storage_3_0_0.bit0.obuf0 Z ) ( storage_2_0_0.bit0.obuf0 Z ) + ( storage_1_0_0.bit0.obuf0 Z ) ( storage_0_0_0.bit0.obuf0 Z ) + USE SIGNAL + ROUTED met2 ( 1127 2125 ) ( * 2414 0 ) NEW met2 ( 1127 1853 ) ( * 2125 ) NEW met2 ( 1127 1581 ) ( * 1853 ) @@ -1017,26 +1018,20 @@ NETS 152 ; NEW met1 ( 1127 493 ) M1M2_PR NEW li1 ( 1127 221 ) L1M1_PR_MR NEW met1 ( 1127 221 ) M1M2_PR ; - - Q[1] ( PIN Q[1] ) ( storage_7_0.bit1.obuf0 Z ) ( storage_6_0.bit1.obuf0 Z ) ( storage_5_0.bit1.obuf0 Z ) ( storage_4_0.bit1.obuf0 Z ) ( storage_3_0.bit1.obuf0 Z ) ( storage_2_0.bit1.obuf0 Z ) - ( storage_1_0.bit1.obuf0 Z ) ( storage_0_0.bit1.obuf0 Z ) + USE SIGNAL - + ROUTED met1 ( 2231 2125 ) ( 2277 * ) - NEW met2 ( 2231 2125 ) ( * 2414 0 ) - NEW met2 ( 2231 1853 ) ( * 2125 ) - NEW met1 ( 2231 1581 ) ( 2277 * ) - NEW met2 ( 2231 1581 ) ( * 1853 ) - NEW met1 ( 2231 1037 ) ( 2277 * ) + - Q[1] ( PIN Q[1] ) ( storage_7_0_0.bit1.obuf0 Z ) ( storage_6_0_0.bit1.obuf0 Z ) ( storage_5_0_0.bit1.obuf0 Z ) ( storage_4_0_0.bit1.obuf0 Z ) ( storage_3_0_0.bit1.obuf0 Z ) ( storage_2_0_0.bit1.obuf0 Z ) + ( storage_1_0_0.bit1.obuf0 Z ) ( storage_0_0_0.bit1.obuf0 Z ) + USE SIGNAL + + ROUTED met1 ( 2231 1037 ) ( 2277 * ) NEW met2 ( 2231 1037 ) ( * 1309 ) NEW met2 ( 2231 765 ) ( * 1037 ) NEW met1 ( 2231 493 ) ( 2277 * ) NEW met2 ( 2231 493 ) ( * 765 ) NEW met2 ( 2231 221 ) ( * 493 ) + NEW met1 ( 2231 2125 ) ( 2277 * ) + NEW met2 ( 2231 2125 ) ( * 2414 0 ) + NEW met2 ( 2231 1853 ) ( * 2125 ) + NEW met1 ( 2231 1581 ) ( 2277 * ) + NEW met2 ( 2231 1581 ) ( * 1853 ) NEW met2 ( 2231 1309 ) ( * 1581 ) - NEW li1 ( 2277 2125 ) L1M1_PR_MR - NEW met1 ( 2231 2125 ) M1M2_PR - NEW li1 ( 2231 1853 ) L1M1_PR_MR - NEW met1 ( 2231 1853 ) M1M2_PR - NEW li1 ( 2277 1581 ) L1M1_PR_MR - NEW met1 ( 2231 1581 ) M1M2_PR NEW li1 ( 2231 1309 ) L1M1_PR_MR NEW met1 ( 2231 1309 ) M1M2_PR NEW li1 ( 2277 1037 ) L1M1_PR_MR @@ -1046,23 +1041,23 @@ NETS 152 ; NEW li1 ( 2277 493 ) L1M1_PR_MR NEW met1 ( 2231 493 ) M1M2_PR NEW li1 ( 2231 221 ) L1M1_PR_MR - NEW met1 ( 2231 221 ) M1M2_PR ; - - Q[2] ( PIN Q[2] ) ( storage_7_0.bit2.obuf0 Z ) ( storage_6_0.bit2.obuf0 Z ) ( storage_5_0.bit2.obuf0 Z ) ( storage_4_0.bit2.obuf0 Z ) ( storage_3_0.bit2.obuf0 Z ) ( storage_2_0.bit2.obuf0 Z ) - ( storage_1_0.bit2.obuf0 Z ) ( storage_0_0.bit2.obuf0 Z ) + USE SIGNAL - + ROUTED met2 ( 3427 2125 ) ( * 2414 0 ) - NEW met2 ( 3427 1853 ) ( * 2125 ) - NEW met2 ( 3427 1581 ) ( * 1853 ) - NEW met2 ( 3427 1037 ) ( * 1309 ) + NEW met1 ( 2231 221 ) M1M2_PR + NEW li1 ( 2277 2125 ) L1M1_PR_MR + NEW met1 ( 2231 2125 ) M1M2_PR + NEW li1 ( 2231 1853 ) L1M1_PR_MR + NEW met1 ( 2231 1853 ) M1M2_PR + NEW li1 ( 2277 1581 ) L1M1_PR_MR + NEW met1 ( 2231 1581 ) M1M2_PR ; + - Q[2] ( PIN Q[2] ) ( storage_7_0_0.bit2.obuf0 Z ) ( storage_6_0_0.bit2.obuf0 Z ) ( storage_5_0_0.bit2.obuf0 Z ) ( storage_4_0_0.bit2.obuf0 Z ) ( storage_3_0_0.bit2.obuf0 Z ) ( storage_2_0_0.bit2.obuf0 Z ) + ( storage_1_0_0.bit2.obuf0 Z ) ( storage_0_0_0.bit2.obuf0 Z ) + USE SIGNAL + + ROUTED met2 ( 3427 1037 ) ( * 1309 ) NEW met2 ( 3427 765 ) ( * 1037 ) NEW met2 ( 3427 493 ) ( * 765 ) NEW met2 ( 3427 221 ) ( * 493 ) + NEW met2 ( 3427 2125 ) ( * 2414 0 ) + NEW met2 ( 3427 1853 ) ( * 2125 ) + NEW met2 ( 3427 1581 ) ( * 1853 ) NEW met2 ( 3427 1309 ) ( * 1581 ) - NEW li1 ( 3427 2125 ) L1M1_PR_MR - NEW met1 ( 3427 2125 ) M1M2_PR - NEW li1 ( 3427 1853 ) L1M1_PR_MR - NEW met1 ( 3427 1853 ) M1M2_PR - NEW li1 ( 3427 1581 ) L1M1_PR_MR - NEW met1 ( 3427 1581 ) M1M2_PR NEW li1 ( 3427 1309 ) L1M1_PR_MR NEW met1 ( 3427 1309 ) M1M2_PR NEW li1 ( 3427 1037 ) L1M1_PR_MR @@ -1072,27 +1067,27 @@ NETS 152 ; NEW li1 ( 3427 493 ) L1M1_PR_MR NEW met1 ( 3427 493 ) M1M2_PR NEW li1 ( 3427 221 ) L1M1_PR_MR - NEW met1 ( 3427 221 ) M1M2_PR ; - - Q[3] ( PIN Q[3] ) ( storage_7_0.bit3.obuf0 Z ) ( storage_6_0.bit3.obuf0 Z ) ( storage_5_0.bit3.obuf0 Z ) ( storage_4_0.bit3.obuf0 Z ) ( storage_3_0.bit3.obuf0 Z ) ( storage_2_0.bit3.obuf0 Z ) - ( storage_1_0.bit3.obuf0 Z ) ( storage_0_0.bit3.obuf0 Z ) + USE SIGNAL - + ROUTED met1 ( 4531 2125 ) ( 4577 * ) - NEW met2 ( 4531 2125 ) ( * 2414 0 ) - NEW met2 ( 4531 1853 ) ( * 2125 ) - NEW met1 ( 4531 1581 ) ( 4577 * ) - NEW met2 ( 4531 1581 ) ( * 1853 ) - NEW met1 ( 4531 1037 ) ( 4577 * ) + NEW met1 ( 3427 221 ) M1M2_PR + NEW li1 ( 3427 2125 ) L1M1_PR_MR + NEW met1 ( 3427 2125 ) M1M2_PR + NEW li1 ( 3427 1853 ) L1M1_PR_MR + NEW met1 ( 3427 1853 ) M1M2_PR + NEW li1 ( 3427 1581 ) L1M1_PR_MR + NEW met1 ( 3427 1581 ) M1M2_PR ; + - Q[3] ( PIN Q[3] ) ( storage_7_0_0.bit3.obuf0 Z ) ( storage_6_0_0.bit3.obuf0 Z ) ( storage_5_0_0.bit3.obuf0 Z ) ( storage_4_0_0.bit3.obuf0 Z ) ( storage_3_0_0.bit3.obuf0 Z ) ( storage_2_0_0.bit3.obuf0 Z ) + ( storage_1_0_0.bit3.obuf0 Z ) ( storage_0_0_0.bit3.obuf0 Z ) + USE SIGNAL + + ROUTED met1 ( 4531 1037 ) ( 4577 * ) NEW met2 ( 4531 1037 ) ( * 1309 ) NEW met2 ( 4531 765 ) ( * 1037 ) NEW met1 ( 4531 493 ) ( 4577 * ) NEW met2 ( 4531 493 ) ( * 765 ) NEW met2 ( 4531 221 ) ( * 493 ) + NEW met1 ( 4531 2125 ) ( 4577 * ) + NEW met2 ( 4531 2125 ) ( * 2414 0 ) + NEW met2 ( 4531 1853 ) ( * 2125 ) + NEW met1 ( 4531 1581 ) ( 4577 * ) + NEW met2 ( 4531 1581 ) ( * 1853 ) NEW met2 ( 4531 1309 ) ( * 1581 ) - NEW li1 ( 4577 2125 ) L1M1_PR_MR - NEW met1 ( 4531 2125 ) M1M2_PR - NEW li1 ( 4531 1853 ) L1M1_PR_MR - NEW met1 ( 4531 1853 ) M1M2_PR - NEW li1 ( 4577 1581 ) L1M1_PR_MR - NEW met1 ( 4531 1581 ) M1M2_PR NEW li1 ( 4531 1309 ) L1M1_PR_MR NEW met1 ( 4531 1309 ) M1M2_PR NEW li1 ( 4577 1037 ) L1M1_PR_MR @@ -1102,23 +1097,23 @@ NETS 152 ; NEW li1 ( 4577 493 ) L1M1_PR_MR NEW met1 ( 4531 493 ) M1M2_PR NEW li1 ( 4531 221 ) L1M1_PR_MR - NEW met1 ( 4531 221 ) M1M2_PR ; - - Q[4] ( PIN Q[4] ) ( storage_7_0.bit4.obuf0 Z ) ( storage_6_0.bit4.obuf0 Z ) ( storage_5_0.bit4.obuf0 Z ) ( storage_4_0.bit4.obuf0 Z ) ( storage_3_0.bit4.obuf0 Z ) ( storage_2_0.bit4.obuf0 Z ) - ( storage_1_0.bit4.obuf0 Z ) ( storage_0_0.bit4.obuf0 Z ) + USE SIGNAL - + ROUTED met2 ( 5727 2125 ) ( * 2414 0 ) - NEW met2 ( 5727 1853 ) ( * 2125 ) - NEW met2 ( 5727 1581 ) ( * 1853 ) - NEW met2 ( 5727 1037 ) ( * 1309 ) + NEW met1 ( 4531 221 ) M1M2_PR + NEW li1 ( 4577 2125 ) L1M1_PR_MR + NEW met1 ( 4531 2125 ) M1M2_PR + NEW li1 ( 4531 1853 ) L1M1_PR_MR + NEW met1 ( 4531 1853 ) M1M2_PR + NEW li1 ( 4577 1581 ) L1M1_PR_MR + NEW met1 ( 4531 1581 ) M1M2_PR ; + - Q[4] ( PIN Q[4] ) ( storage_7_0_0.bit4.obuf0 Z ) ( storage_6_0_0.bit4.obuf0 Z ) ( storage_5_0_0.bit4.obuf0 Z ) ( storage_4_0_0.bit4.obuf0 Z ) ( storage_3_0_0.bit4.obuf0 Z ) ( storage_2_0_0.bit4.obuf0 Z ) + ( storage_1_0_0.bit4.obuf0 Z ) ( storage_0_0_0.bit4.obuf0 Z ) + USE SIGNAL + + ROUTED met2 ( 5727 1037 ) ( * 1309 ) NEW met2 ( 5727 765 ) ( * 1037 ) NEW met2 ( 5727 493 ) ( * 765 ) NEW met2 ( 5727 221 ) ( * 493 ) + NEW met2 ( 5727 2125 ) ( * 2414 0 ) + NEW met2 ( 5727 1853 ) ( * 2125 ) + NEW met2 ( 5727 1581 ) ( * 1853 ) NEW met2 ( 5727 1309 ) ( * 1581 ) - NEW li1 ( 5727 2125 ) L1M1_PR_MR - NEW met1 ( 5727 2125 ) M1M2_PR - NEW li1 ( 5727 1853 ) L1M1_PR_MR - NEW met1 ( 5727 1853 ) M1M2_PR - NEW li1 ( 5727 1581 ) L1M1_PR_MR - NEW met1 ( 5727 1581 ) M1M2_PR NEW li1 ( 5727 1309 ) L1M1_PR_MR NEW met1 ( 5727 1309 ) M1M2_PR NEW li1 ( 5727 1037 ) L1M1_PR_MR @@ -1128,9 +1123,15 @@ NETS 152 ; NEW li1 ( 5727 493 ) L1M1_PR_MR NEW met1 ( 5727 493 ) M1M2_PR NEW li1 ( 5727 221 ) L1M1_PR_MR - NEW met1 ( 5727 221 ) M1M2_PR ; - - Q[5] ( PIN Q[5] ) ( storage_7_0.bit5.obuf0 Z ) ( storage_6_0.bit5.obuf0 Z ) ( storage_5_0.bit5.obuf0 Z ) ( storage_4_0.bit5.obuf0 Z ) ( storage_3_0.bit5.obuf0 Z ) ( storage_2_0.bit5.obuf0 Z ) - ( storage_1_0.bit5.obuf0 Z ) ( storage_0_0.bit5.obuf0 Z ) + USE SIGNAL + NEW met1 ( 5727 221 ) M1M2_PR + NEW li1 ( 5727 2125 ) L1M1_PR_MR + NEW met1 ( 5727 2125 ) M1M2_PR + NEW li1 ( 5727 1853 ) L1M1_PR_MR + NEW met1 ( 5727 1853 ) M1M2_PR + NEW li1 ( 5727 1581 ) L1M1_PR_MR + NEW met1 ( 5727 1581 ) M1M2_PR ; + - Q[5] ( PIN Q[5] ) ( storage_7_0_0.bit5.obuf0 Z ) ( storage_6_0_0.bit5.obuf0 Z ) ( storage_5_0_0.bit5.obuf0 Z ) ( storage_4_0_0.bit5.obuf0 Z ) ( storage_3_0_0.bit5.obuf0 Z ) ( storage_2_0_0.bit5.obuf0 Z ) + ( storage_1_0_0.bit5.obuf0 Z ) ( storage_0_0_0.bit5.obuf0 Z ) + USE SIGNAL + ROUTED met1 ( 6831 1037 ) ( 6877 * ) NEW met2 ( 6831 1037 ) ( * 1309 ) NEW met2 ( 6831 765 ) ( * 1037 ) @@ -1159,8 +1160,8 @@ NETS 152 ; NEW met1 ( 6831 1853 ) M1M2_PR NEW li1 ( 6877 1581 ) L1M1_PR_MR NEW met1 ( 6831 1581 ) M1M2_PR ; - - Q[6] ( PIN Q[6] ) ( storage_7_0.bit6.obuf0 Z ) ( storage_6_0.bit6.obuf0 Z ) ( storage_5_0.bit6.obuf0 Z ) ( storage_4_0.bit6.obuf0 Z ) ( storage_3_0.bit6.obuf0 Z ) ( storage_2_0.bit6.obuf0 Z ) - ( storage_1_0.bit6.obuf0 Z ) ( storage_0_0.bit6.obuf0 Z ) + USE SIGNAL + - Q[6] ( PIN Q[6] ) ( storage_7_0_0.bit6.obuf0 Z ) ( storage_6_0_0.bit6.obuf0 Z ) ( storage_5_0_0.bit6.obuf0 Z ) ( storage_4_0_0.bit6.obuf0 Z ) ( storage_3_0_0.bit6.obuf0 Z ) ( storage_2_0_0.bit6.obuf0 Z ) + ( storage_1_0_0.bit6.obuf0 Z ) ( storage_0_0_0.bit6.obuf0 Z ) + USE SIGNAL + ROUTED met1 ( 8027 2125 ) ( 8073 * ) NEW met2 ( 8073 2125 ) ( * 2414 ) NEW met2 ( 8027 2414 0 ) ( 8073 * ) @@ -1194,8 +1195,8 @@ NETS 152 ; NEW met1 ( 8073 493 ) M1M2_PR NEW li1 ( 8027 221 ) L1M1_PR_MR NEW met1 ( 8073 221 ) M1M2_PR ; - - Q[7] ( PIN Q[7] ) ( storage_7_0.bit7.obuf0 Z ) ( storage_6_0.bit7.obuf0 Z ) ( storage_5_0.bit7.obuf0 Z ) ( storage_4_0.bit7.obuf0 Z ) ( storage_3_0.bit7.obuf0 Z ) ( storage_2_0.bit7.obuf0 Z ) - ( storage_1_0.bit7.obuf0 Z ) ( storage_0_0.bit7.obuf0 Z ) + USE SIGNAL + - Q[7] ( PIN Q[7] ) ( storage_7_0_0.bit7.obuf0 Z ) ( storage_6_0_0.bit7.obuf0 Z ) ( storage_5_0_0.bit7.obuf0 Z ) ( storage_4_0_0.bit7.obuf0 Z ) ( storage_3_0_0.bit7.obuf0 Z ) ( storage_2_0_0.bit7.obuf0 Z ) + ( storage_1_0_0.bit7.obuf0 Z ) ( storage_0_0_0.bit7.obuf0 Z ) + USE SIGNAL + ROUTED met1 ( 9131 2125 ) ( 9177 * ) NEW met2 ( 9131 2125 ) ( * 2414 0 ) NEW met2 ( 9131 1853 ) ( * 2125 ) @@ -1224,7 +1225,7 @@ NETS 152 ; NEW met1 ( 9131 493 ) M1M2_PR NEW li1 ( 9131 221 ) L1M1_PR_MR NEW met1 ( 9131 221 ) M1M2_PR ; - - addr[0] ( PIN addr[0] ) ( decoder.inv_0 A ) ( decoder_7.and_layer0 A ) ( decoder_5.and_layer0 A ) ( decoder_3.and_layer0 A ) ( decoder_1.and_layer0 A ) + USE SIGNAL + - addr_rw[0] ( PIN addr_rw[0] ) ( decoder.inv_0 A ) ( decoder_7.and_layer0 A ) ( decoder_5.and_layer0 A ) ( decoder_3.and_layer0 A ) ( decoder_1.and_layer0 A ) + USE SIGNAL + ROUTED met1 ( 10327 391 ) ( 10373 * ) NEW met2 ( 10373 391 ) ( * 442 ) NEW met3 ( 10373 442 ) ( 10994 * 0 ) @@ -1249,7 +1250,7 @@ NETS 152 ; NEW met1 ( 10925 1411 ) M1M2_PR NEW li1 ( 10327 1989 ) L1M1_PR_MR NEW met1 ( 10373 1989 ) M1M2_PR ; - - addr[1] ( PIN addr[1] ) ( decoder.inv_1 A ) ( decoder_7.and_layer1 A ) ( decoder_6.and_layer1 A ) ( decoder_3.and_layer1 A ) ( decoder_2.and_layer1 A ) + USE SIGNAL + - addr_rw[1] ( PIN addr_rw[1] ) ( decoder.inv_1 A ) ( decoder_7.and_layer1 A ) ( decoder_6.and_layer1 A ) ( decoder_3.and_layer1 A ) ( decoder_2.and_layer1 A ) + USE SIGNAL + ROUTED met2 ( 10925 714 ) ( * 969 ) NEW met3 ( 10925 714 ) ( 10994 * 0 ) NEW met1 ( 10557 697 ) ( 10925 * ) @@ -1271,7 +1272,7 @@ NETS 152 ; NEW met1 ( 10603 901 ) M1M2_PR NEW li1 ( 10557 1989 ) L1M1_PR_MR NEW met1 ( 10603 1989 ) M1M2_PR ; - - addr[2] ( PIN addr[2] ) ( decoder.inv_2 A ) ( decoder_7.and_layer1 B ) ( decoder_6.and_layer1 B ) ( decoder_5.and_layer1 B ) ( decoder_4.and_layer1 B ) + USE SIGNAL + - addr_rw[2] ( PIN addr_rw[2] ) ( decoder.inv_2 A ) ( decoder_7.and_layer1 B ) ( decoder_6.and_layer1 B ) ( decoder_5.and_layer1 B ) ( decoder_4.and_layer1 B ) + USE SIGNAL + ROUTED met3 ( 10925 578 ) ( 10994 * 0 ) NEW met2 ( 10925 119 ) ( * 578 ) NEW met1 ( 10649 1207 ) ( 10695 * ) @@ -1295,8 +1296,8 @@ NETS 152 ; NEW met1 ( 10695 1751 ) M1M2_PR NEW li1 ( 10649 2023 ) L1M1_PR_MR NEW met1 ( 10695 2023 ) M1M2_PR ; - - clk ( PIN clk ) ( storage_7_0.cg CLK ) ( storage_6_0.cg CLK ) ( storage_5_0.cg CLK ) ( storage_4_0.cg CLK ) ( storage_3_0.cg CLK ) ( storage_2_0.cg CLK ) - ( storage_1_0.cg CLK ) ( storage_0_0.cg CLK ) + USE SIGNAL + - clk ( PIN clk ) ( storage_7_0_0.cg CLK ) ( storage_6_0_0.cg CLK ) ( storage_5_0_0.cg CLK ) ( storage_4_0_0.cg CLK ) ( storage_3_0_0.cg CLK ) ( storage_2_0_0.cg CLK ) + ( storage_1_0_0.cg CLK ) ( storage_0_0_0.cg CLK ) + USE SIGNAL + ROUTED met2 ( 9775 119 ) ( * 170 ) NEW met3 ( 9775 170 ) ( 10994 * 0 ) NEW met2 ( 9775 170 ) ( * 425 ) @@ -1304,9 +1305,9 @@ NETS 152 ; NEW met2 ( 9775 663 ) ( * 969 ) NEW met2 ( 9775 969 ) ( * 1207 ) NEW met2 ( 9775 1207 ) ( * 1513 ) - NEW met2 ( 9729 1530 ) ( * 1751 ) - NEW met2 ( 9729 1530 ) ( 9775 * ) - NEW met2 ( 9775 1513 ) ( * 1530 ) + NEW met2 ( 9729 1734 ) ( * 1751 ) + NEW met2 ( 9729 1734 ) ( 9775 * ) + NEW met2 ( 9775 1513 ) ( * 1734 ) NEW met2 ( 9729 1751 ) ( * 2057 ) NEW met1 ( 9775 119 ) M1M2_PR_MR NEW met2 ( 9775 170 ) M2M3_PR @@ -1317,10 +1318,10 @@ NETS 152 ; NEW met1 ( 9775 1513 ) M1M2_PR_MR NEW met1 ( 9729 1751 ) M1M2_PR NEW met1 ( 9729 2057 ) M1M2_PR ; - - decoder_0.decoder0 ( storage_0_0.select_inv_0 A ) ( storage_0_0.gcand A ) ( decoder_0.buf_port0 X ) + USE SIGNAL - + ROUTED met1 ( 10143 85 ) ( 10327 * ) - NEW met1 ( 10327 51 ) ( * 85 ) - NEW met1 ( 10327 51 ) ( 10879 * ) + - decoder_0.decoder0 ( storage_0_0_0.select_inv_0 A ) ( storage_0_0_0.gcand A ) ( decoder_0.buf_port0 X ) + USE SIGNAL + + ROUTED met1 ( 10143 85 ) ( 10235 * ) + NEW met1 ( 10235 51 ) ( * 85 ) + NEW met1 ( 10235 51 ) ( 10879 * ) NEW met1 ( 9913 153 ) ( 10143 * ) NEW met1 ( 10143 85 ) ( * 153 ) NEW li1 ( 10143 85 ) L1M1_PR_MR @@ -1337,7 +1338,7 @@ NETS 152 ; NEW li1 ( 10419 153 ) L1M1_PR_MR NEW li1 ( 10741 187 ) L1M1_PR_MR ; - decoder_0.layer_in1 + USE SIGNAL ; - - decoder_1.decoder0 ( storage_1_0.select_inv_0 A ) ( storage_1_0.gcand A ) ( decoder_1.buf_port0 X ) + USE SIGNAL + - decoder_1.decoder0 ( storage_1_0_0.select_inv_0 A ) ( storage_1_0_0.gcand A ) ( decoder_1.buf_port0 X ) + USE SIGNAL + ROUTED met1 ( 10143 493 ) ( 10879 * ) NEW met1 ( 9913 391 ) ( * 425 ) NEW met1 ( 9913 425 ) ( 10143 * ) @@ -1355,10 +1356,10 @@ NETS 152 ; NEW li1 ( 10419 425 ) L1M1_PR_MR NEW li1 ( 10741 425 ) L1M1_PR_MR ; - decoder_1.layer_in1 + USE SIGNAL ; - - decoder_2.decoder0 ( storage_2_0.select_inv_0 A ) ( storage_2_0.gcand A ) ( decoder_2.buf_port0 X ) + USE SIGNAL - + ROUTED met1 ( 10143 629 ) ( 10327 * ) - NEW met1 ( 10327 595 ) ( * 629 ) - NEW met1 ( 10327 595 ) ( 10879 * ) + - decoder_2.decoder0 ( storage_2_0_0.select_inv_0 A ) ( storage_2_0_0.gcand A ) ( decoder_2.buf_port0 X ) + USE SIGNAL + + ROUTED met1 ( 10143 629 ) ( 10235 * ) + NEW met1 ( 10235 595 ) ( * 629 ) + NEW met1 ( 10235 595 ) ( 10879 * ) NEW met1 ( 9913 697 ) ( 10143 * ) NEW met1 ( 10143 629 ) ( * 697 ) NEW li1 ( 10143 629 ) L1M1_PR_MR @@ -1375,7 +1376,7 @@ NETS 152 ; NEW li1 ( 10419 697 ) L1M1_PR_MR NEW li1 ( 10741 731 ) L1M1_PR_MR ; - decoder_2.layer_in1 + USE SIGNAL ; - - decoder_3.decoder0 ( storage_3_0.select_inv_0 A ) ( storage_3_0.gcand A ) ( decoder_3.buf_port0 X ) + USE SIGNAL + - decoder_3.decoder0 ( storage_3_0_0.select_inv_0 A ) ( storage_3_0_0.gcand A ) ( decoder_3.buf_port0 X ) + USE SIGNAL + ROUTED met1 ( 10143 1037 ) ( 10879 * ) NEW met1 ( 9913 935 ) ( * 969 ) NEW met1 ( 9913 969 ) ( 10143 * ) @@ -1393,10 +1394,10 @@ NETS 152 ; NEW li1 ( 10419 969 ) L1M1_PR_MR NEW li1 ( 10741 969 ) L1M1_PR_MR ; - decoder_3.layer_in1 + USE SIGNAL ; - - decoder_4.decoder0 ( storage_4_0.select_inv_0 A ) ( storage_4_0.gcand A ) ( decoder_4.buf_port0 X ) + USE SIGNAL - + ROUTED met1 ( 10143 1173 ) ( 10327 * ) - NEW met1 ( 10327 1139 ) ( * 1173 ) - NEW met1 ( 10327 1139 ) ( 10879 * ) + - decoder_4.decoder0 ( storage_4_0_0.select_inv_0 A ) ( storage_4_0_0.gcand A ) ( decoder_4.buf_port0 X ) + USE SIGNAL + + ROUTED met1 ( 10143 1173 ) ( 10235 * ) + NEW met1 ( 10235 1139 ) ( * 1173 ) + NEW met1 ( 10235 1139 ) ( 10879 * ) NEW met1 ( 9913 1241 ) ( 10143 * ) NEW met1 ( 10143 1173 ) ( * 1241 ) NEW li1 ( 10143 1173 ) L1M1_PR_MR @@ -1413,7 +1414,7 @@ NETS 152 ; NEW li1 ( 10419 1241 ) L1M1_PR_MR NEW li1 ( 10741 1275 ) L1M1_PR_MR ; - decoder_4.layer_in1 + USE SIGNAL ; - - decoder_5.decoder0 ( storage_5_0.select_inv_0 A ) ( storage_5_0.gcand A ) ( decoder_5.buf_port0 X ) + USE SIGNAL + - decoder_5.decoder0 ( storage_5_0_0.select_inv_0 A ) ( storage_5_0_0.gcand A ) ( decoder_5.buf_port0 X ) + USE SIGNAL + ROUTED met1 ( 10143 1581 ) ( 10879 * ) NEW met1 ( 9913 1479 ) ( * 1513 ) NEW met1 ( 9913 1513 ) ( 10143 * ) @@ -1431,10 +1432,10 @@ NETS 152 ; NEW li1 ( 10419 1513 ) L1M1_PR_MR NEW li1 ( 10741 1513 ) L1M1_PR_MR ; - decoder_5.layer_in1 + USE SIGNAL ; - - decoder_6.decoder0 ( storage_6_0.select_inv_0 A ) ( storage_6_0.gcand A ) ( decoder_6.buf_port0 X ) + USE SIGNAL - + ROUTED met1 ( 10143 1717 ) ( 10327 * ) - NEW met1 ( 10327 1683 ) ( * 1717 ) - NEW met1 ( 10327 1683 ) ( 10879 * ) + - decoder_6.decoder0 ( storage_6_0_0.select_inv_0 A ) ( storage_6_0_0.gcand A ) ( decoder_6.buf_port0 X ) + USE SIGNAL + + ROUTED met1 ( 10143 1717 ) ( 10235 * ) + NEW met1 ( 10235 1683 ) ( * 1717 ) + NEW met1 ( 10235 1683 ) ( 10879 * ) NEW met1 ( 9913 1785 ) ( 10143 * ) NEW met1 ( 10143 1717 ) ( * 1785 ) NEW li1 ( 10143 1717 ) L1M1_PR_MR @@ -1451,7 +1452,7 @@ NETS 152 ; NEW li1 ( 10419 1785 ) L1M1_PR_MR NEW li1 ( 10741 1819 ) L1M1_PR_MR ; - decoder_6.layer_in1 + USE SIGNAL ; - - decoder_7.decoder0 ( storage_7_0.select_inv_0 A ) ( storage_7_0.gcand A ) ( decoder_7.buf_port0 X ) + USE SIGNAL + - decoder_7.decoder0 ( storage_7_0_0.select_inv_0 A ) ( storage_7_0_0.gcand A ) ( decoder_7.buf_port0 X ) + USE SIGNAL + ROUTED met1 ( 10143 2125 ) ( 10879 * ) NEW met1 ( 9913 2023 ) ( * 2057 ) NEW met1 ( 9913 2057 ) ( 10143 * ) @@ -1469,7 +1470,7 @@ NETS 152 ; NEW li1 ( 10419 2057 ) L1M1_PR_MR NEW li1 ( 10741 2057 ) L1M1_PR_MR ; - decoder_7.layer_in1 + USE SIGNAL ; - - inv.addr[0] ( decoder.inv_0 Y ) ( decoder_6.and_layer0 A ) ( decoder_4.and_layer0 A ) ( decoder_2.and_layer0 A ) ( decoder_0.and_layer0 A ) + USE SIGNAL + - inv.addr0 ( decoder.inv_0 Y ) ( decoder_6.and_layer0 A ) ( decoder_4.and_layer0 A ) ( decoder_2.and_layer0 A ) ( decoder_0.and_layer0 A ) + USE SIGNAL + ROUTED met1 ( 10327 1819 ) ( * 1853 ) NEW met1 ( 10327 1853 ) ( 10971 * ) NEW met2 ( 10327 1275 ) ( * 1819 ) @@ -1484,7 +1485,7 @@ NETS 152 ; NEW met1 ( 10327 731 ) M1M2_PR NEW li1 ( 10327 187 ) L1M1_PR_MR NEW met1 ( 10327 187 ) M1M2_PR ; - - inv.addr[1] ( decoder.inv_1 Y ) ( decoder_5.and_layer1 A ) ( decoder_4.and_layer1 A ) ( decoder_1.and_layer1 A ) ( decoder_0.and_layer1 A ) + USE SIGNAL + - inv.addr1 ( decoder.inv_1 Y ) ( decoder_5.and_layer1 A ) ( decoder_4.and_layer1 A ) ( decoder_1.and_layer1 A ) ( decoder_0.and_layer1 A ) + USE SIGNAL + ROUTED met2 ( 10557 1241 ) ( * 1445 ) NEW met2 ( 10971 1037 ) ( * 1241 ) NEW met1 ( 10557 1241 ) ( 10971 * ) @@ -1501,7 +1502,7 @@ NETS 152 ; NEW met1 ( 10557 391 ) M1M2_PR NEW li1 ( 10557 153 ) L1M1_PR_MR NEW met1 ( 10557 153 ) M1M2_PR ; - - inv.addr[2] ( decoder.inv_2 Y ) ( decoder_3.and_layer1 B ) ( decoder_2.and_layer1 B ) ( decoder_1.and_layer1 B ) ( decoder_0.and_layer1 B ) + USE SIGNAL + - inv.addr2 ( decoder.inv_2 Y ) ( decoder_3.and_layer1 B ) ( decoder_2.and_layer1 B ) ( decoder_1.and_layer1 B ) ( decoder_0.and_layer1 B ) + USE SIGNAL + ROUTED met1 ( 10649 153 ) ( 10971 * ) NEW met2 ( 10649 153 ) ( * 391 ) NEW met2 ( 10649 391 ) ( * 663 ) @@ -1515,273 +1516,297 @@ NETS 152 ; NEW met1 ( 10649 663 ) M1M2_PR NEW li1 ( 10649 935 ) L1M1_PR_MR NEW met1 ( 10649 935 ) M1M2_PR ; - - storage_0_0.bit0.storage ( storage_0_0.bit0.obuf0 A ) ( storage_0_0.bit0.bit Q ) + USE SIGNAL + - storage_0_0_0.bit0.storage ( storage_0_0_0.bit0.obuf0 A ) ( storage_0_0_0.bit0.bit Q ) + USE SIGNAL + ROUTED met1 ( 805 153 ) ( * 187 ) NEW met1 ( 759 187 ) ( 805 * ) NEW li1 ( 805 153 ) L1M1_PR_MR NEW li1 ( 759 187 ) L1M1_PR_MR ; - - storage_0_0.bit1.storage ( storage_0_0.bit1.obuf0 A ) ( storage_0_0.bit1.bit Q ) + USE SIGNAL + - storage_0_0_0.bit1.storage ( storage_0_0_0.bit1.obuf0 A ) ( storage_0_0_0.bit1.bit Q ) + USE SIGNAL + ROUTED met1 ( 1955 153 ) ( * 187 ) NEW met1 ( 1909 187 ) ( 1955 * ) NEW li1 ( 1955 153 ) L1M1_PR_MR NEW li1 ( 1909 187 ) L1M1_PR_MR ; - - storage_0_0.bit2.storage ( storage_0_0.bit2.obuf0 A ) ( storage_0_0.bit2.bit Q ) + USE SIGNAL + - storage_0_0_0.bit2.storage ( storage_0_0_0.bit2.obuf0 A ) ( storage_0_0_0.bit2.bit Q ) + USE SIGNAL + ROUTED met1 ( 3105 153 ) ( * 187 ) NEW met1 ( 3059 187 ) ( 3105 * ) NEW li1 ( 3105 153 ) L1M1_PR_MR NEW li1 ( 3059 187 ) L1M1_PR_MR ; - - storage_0_0.bit3.storage ( storage_0_0.bit3.obuf0 A ) ( storage_0_0.bit3.bit Q ) + USE SIGNAL + - storage_0_0_0.bit3.storage ( storage_0_0_0.bit3.obuf0 A ) ( storage_0_0_0.bit3.bit Q ) + USE SIGNAL + ROUTED met1 ( 4255 153 ) ( * 187 ) NEW met1 ( 4209 187 ) ( 4255 * ) NEW li1 ( 4255 153 ) L1M1_PR_MR NEW li1 ( 4209 187 ) L1M1_PR_MR ; - - storage_0_0.bit4.storage ( storage_0_0.bit4.obuf0 A ) ( storage_0_0.bit4.bit Q ) + USE SIGNAL + - storage_0_0_0.bit4.storage ( storage_0_0_0.bit4.obuf0 A ) ( storage_0_0_0.bit4.bit Q ) + USE SIGNAL + ROUTED met1 ( 5405 153 ) ( * 187 ) NEW met1 ( 5359 187 ) ( 5405 * ) NEW li1 ( 5405 153 ) L1M1_PR_MR NEW li1 ( 5359 187 ) L1M1_PR_MR ; - - storage_0_0.bit5.storage ( storage_0_0.bit5.obuf0 A ) ( storage_0_0.bit5.bit Q ) + USE SIGNAL + - storage_0_0_0.bit5.storage ( storage_0_0_0.bit5.obuf0 A ) ( storage_0_0_0.bit5.bit Q ) + USE SIGNAL + ROUTED met1 ( 6555 153 ) ( * 187 ) NEW met1 ( 6509 187 ) ( 6555 * ) NEW li1 ( 6555 153 ) L1M1_PR_MR NEW li1 ( 6509 187 ) L1M1_PR_MR ; - - storage_0_0.bit6.storage ( storage_0_0.bit6.obuf0 A ) ( storage_0_0.bit6.bit Q ) + USE SIGNAL + - storage_0_0_0.bit6.storage ( storage_0_0_0.bit6.obuf0 A ) ( storage_0_0_0.bit6.bit Q ) + USE SIGNAL + ROUTED met1 ( 7705 153 ) ( * 187 ) NEW met1 ( 7659 187 ) ( 7705 * ) NEW li1 ( 7705 153 ) L1M1_PR_MR NEW li1 ( 7659 187 ) L1M1_PR_MR ; - - storage_0_0.bit7.storage ( storage_0_0.bit7.obuf0 A ) ( storage_0_0.bit7.bit Q ) + USE SIGNAL + - storage_0_0_0.bit7.storage ( storage_0_0_0.bit7.obuf0 A ) ( storage_0_0_0.bit7.bit Q ) + USE SIGNAL + ROUTED met1 ( 8855 153 ) ( * 187 ) NEW met1 ( 8809 187 ) ( 8855 * ) NEW li1 ( 8855 153 ) L1M1_PR_MR NEW li1 ( 8809 187 ) L1M1_PR_MR ; - - storage_0_0.gclock ( storage_0_0.cg GCLK ) ( storage_0_0.bit7.bit CLK ) ( storage_0_0.bit6.bit CLK ) ( storage_0_0.bit5.bit CLK ) ( storage_0_0.bit4.bit CLK ) ( storage_0_0.bit3.bit CLK ) ( storage_0_0.bit2.bit CLK ) - ( storage_0_0.bit1.bit CLK ) ( storage_0_0.bit0.bit CLK ) + USE SIGNAL - + ROUTED met1 ( 69 85 ) ( * 119 ) - NEW met1 ( 4301 153 ) ( 4669 * ) - NEW met1 ( 4301 153 ) ( * 221 ) - NEW met1 ( 5451 153 ) ( * 221 ) - NEW met1 ( 4669 221 ) ( 5451 * ) - NEW met1 ( 4669 153 ) ( * 221 ) - NEW met2 ( 6969 51 ) ( * 119 ) - NEW met2 ( 5819 51 ) ( * 119 ) - NEW met1 ( 5819 51 ) ( 6969 * ) - NEW met1 ( 5819 119 ) ( * 153 ) - NEW met1 ( 5451 153 ) ( 5819 * ) - NEW met1 ( 69 85 ) ( 690 * ) - NEW met1 ( 3519 153 ) ( * 221 ) - NEW met1 ( 2369 153 ) ( * 221 ) - NEW met1 ( 2369 221 ) ( 3151 * ) - NEW met1 ( 3151 187 ) ( * 221 ) - NEW met1 ( 3151 187 ) ( 3519 * ) - NEW met2 ( 1219 119 ) ( * 221 ) - NEW met1 ( 1219 221 ) ( 2001 * ) - NEW met1 ( 2001 187 ) ( * 221 ) - NEW met1 ( 2001 187 ) ( 2369 * ) - NEW met1 ( 690 85 ) ( * 119 ) - NEW met1 ( 690 119 ) ( 1219 * ) - NEW met1 ( 3519 221 ) ( 4301 * ) + - storage_0_0_0.gclock ( storage_0_0_0.cg GCLK ) ( storage_0_0_0.bit7.bit CLK ) ( storage_0_0_0.bit6.bit CLK ) ( storage_0_0_0.bit5.bit CLK ) ( storage_0_0_0.bit4.bit CLK ) ( storage_0_0_0.bit3.bit CLK ) ( storage_0_0_0.bit2.bit CLK ) + ( storage_0_0_0.bit1.bit CLK ) ( storage_0_0_0.bit0.bit CLK ) + USE SIGNAL + + ROUTED met1 ( 1219 153 ) ( * 221 ) + NEW met1 ( 69 85 ) ( * 119 ) + NEW met1 ( 69 85 ) ( 851 * ) + NEW met1 ( 851 85 ) ( * 153 ) + NEW met1 ( 851 153 ) ( 1219 * ) + NEW met1 ( 2369 153 ) ( * 187 ) + NEW met1 ( 2185 187 ) ( 2369 * ) + NEW met1 ( 2185 187 ) ( * 221 ) + NEW met1 ( 3105 119 ) ( 3519 * ) + NEW met1 ( 3105 85 ) ( * 119 ) + NEW met1 ( 2369 85 ) ( 3105 * ) + NEW met1 ( 2369 85 ) ( * 153 ) + NEW met1 ( 4669 85 ) ( * 119 ) + NEW met1 ( 3519 85 ) ( 4669 * ) + NEW met1 ( 3519 85 ) ( * 119 ) + NEW met1 ( 5727 153 ) ( 5819 * ) + NEW met2 ( 5727 51 ) ( * 153 ) + NEW met1 ( 4669 51 ) ( 5727 * ) + NEW met1 ( 4669 51 ) ( * 85 ) + NEW met1 ( 6785 153 ) ( 6969 * ) + NEW met1 ( 6785 153 ) ( * 221 ) + NEW met1 ( 5819 221 ) ( 6785 * ) + NEW met1 ( 5819 153 ) ( * 221 ) + NEW met1 ( 6969 153 ) ( * 221 ) + NEW met1 ( 1219 221 ) ( 2185 * ) NEW met1 ( 8119 51 ) ( * 119 ) NEW met1 ( 8119 51 ) ( 9867 * ) - NEW met1 ( 6969 51 ) ( 8119 * ) + NEW met1 ( 7751 187 ) ( * 221 ) + NEW met1 ( 7751 187 ) ( 8119 * ) + NEW met1 ( 8119 119 ) ( * 187 ) + NEW met1 ( 6969 221 ) ( 7751 * ) + NEW li1 ( 1219 153 ) L1M1_PR_MR NEW li1 ( 69 119 ) L1M1_PR_MR - NEW li1 ( 4669 153 ) L1M1_PR_MR - NEW li1 ( 6969 119 ) L1M1_PR_MR - NEW met1 ( 6969 119 ) M1M2_PR - NEW met1 ( 6969 51 ) M1M2_PR - NEW li1 ( 5819 119 ) L1M1_PR_MR - NEW met1 ( 5819 119 ) M1M2_PR - NEW met1 ( 5819 51 ) M1M2_PR - NEW li1 ( 3519 153 ) L1M1_PR_MR NEW li1 ( 2369 153 ) L1M1_PR_MR - NEW li1 ( 1219 119 ) L1M1_PR_MR - NEW met1 ( 1219 119 ) M1M2_PR - NEW met1 ( 1219 221 ) M1M2_PR + NEW li1 ( 3519 119 ) L1M1_PR_MR + NEW li1 ( 4669 119 ) L1M1_PR_MR + NEW li1 ( 5819 153 ) L1M1_PR_MR + NEW met1 ( 5727 153 ) M1M2_PR + NEW met1 ( 5727 51 ) M1M2_PR + NEW li1 ( 6969 153 ) L1M1_PR_MR NEW li1 ( 8119 119 ) L1M1_PR_MR NEW li1 ( 9867 51 ) L1M1_PR_MR ; - - storage_0_0.select0_b ( storage_0_0.select_inv_0 Y ) ( storage_0_0.bit7.obuf0 TE_B ) ( storage_0_0.bit6.obuf0 TE_B ) ( storage_0_0.bit5.obuf0 TE_B ) ( storage_0_0.bit4.obuf0 TE_B ) ( storage_0_0.bit3.obuf0 TE_B ) ( storage_0_0.bit2.obuf0 TE_B ) - ( storage_0_0.bit1.obuf0 TE_B ) ( storage_0_0.bit0.obuf0 TE_B ) + USE SIGNAL - + ROUTED met1 ( 5497 85 ) ( * 119 ) - NEW met1 ( 4347 85 ) ( * 119 ) - NEW met1 ( 4347 85 ) ( 5497 * ) + - storage_0_0_0.select0_b ( storage_0_0_0.select_inv_0 Y ) ( storage_0_0_0.bit7.obuf0 TE_B ) ( storage_0_0_0.bit6.obuf0 TE_B ) ( storage_0_0_0.bit5.obuf0 TE_B ) ( storage_0_0_0.bit4.obuf0 TE_B ) ( storage_0_0_0.bit3.obuf0 TE_B ) ( storage_0_0_0.bit2.obuf0 TE_B ) + ( storage_0_0_0.bit1.obuf0 TE_B ) ( storage_0_0_0.bit0.obuf0 TE_B ) + USE SIGNAL + + ROUTED met1 ( 897 85 ) ( * 119 ) NEW met1 ( 6647 85 ) ( * 119 ) - NEW met1 ( 5497 85 ) ( 6647 * ) - NEW met1 ( 1265 119 ) ( 2047 * ) - NEW met1 ( 1265 119 ) ( * 153 ) - NEW met1 ( 897 153 ) ( 1265 * ) - NEW met1 ( 3197 85 ) ( * 119 ) - NEW met1 ( 2047 85 ) ( 3197 * ) - NEW met1 ( 2047 85 ) ( * 119 ) - NEW met1 ( 3197 85 ) ( 4347 * ) + NEW met1 ( 5497 119 ) ( 5773 * ) + NEW met2 ( 5773 34 ) ( * 119 ) + NEW met2 ( 5773 34 ) ( 5865 * ) + NEW met2 ( 5865 34 ) ( * 51 ) + NEW met1 ( 5865 51 ) ( 6647 * ) + NEW met1 ( 6647 51 ) ( * 85 ) + NEW met1 ( 4347 153 ) ( 4715 * ) + NEW met1 ( 4715 85 ) ( * 153 ) + NEW met1 ( 4715 85 ) ( 5497 * ) + NEW met1 ( 5497 85 ) ( * 119 ) + NEW met1 ( 3197 153 ) ( 3473 * ) + NEW met1 ( 3473 153 ) ( * 221 ) + NEW met1 ( 3473 221 ) ( 4347 * ) + NEW met1 ( 4347 153 ) ( * 221 ) + NEW met1 ( 2047 153 ) ( 2277 * ) + NEW met2 ( 2277 153 ) ( * 221 ) + NEW met1 ( 2277 221 ) ( 3197 * ) + NEW met1 ( 3197 153 ) ( * 221 ) + NEW met1 ( 2047 85 ) ( * 153 ) + NEW met1 ( 897 85 ) ( 2047 * ) NEW met1 ( 8947 153 ) ( * 187 ) NEW met1 ( 8947 187 ) ( 10189 * ) - NEW met1 ( 7797 153 ) ( 8119 * ) - NEW met1 ( 8119 153 ) ( * 221 ) + NEW met1 ( 7797 153 ) ( 8073 * ) + NEW met2 ( 8073 153 ) ( * 170 ) + NEW met2 ( 8073 170 ) ( 8119 * ) + NEW met2 ( 8119 170 ) ( * 221 ) NEW met1 ( 8119 221 ) ( 8947 * ) NEW met1 ( 8947 187 ) ( * 221 ) NEW met1 ( 7797 85 ) ( * 153 ) NEW met1 ( 6647 85 ) ( 7797 * ) - NEW li1 ( 5497 119 ) L1M1_PR_MR - NEW li1 ( 4347 119 ) L1M1_PR_MR + NEW li1 ( 897 119 ) L1M1_PR_MR NEW li1 ( 6647 119 ) L1M1_PR_MR - NEW li1 ( 2047 119 ) L1M1_PR_MR - NEW li1 ( 897 153 ) L1M1_PR_MR - NEW li1 ( 3197 119 ) L1M1_PR_MR + NEW li1 ( 5497 119 ) L1M1_PR_MR + NEW met1 ( 5773 119 ) M1M2_PR + NEW met1 ( 5865 51 ) M1M2_PR + NEW li1 ( 4347 153 ) L1M1_PR_MR + NEW li1 ( 3197 153 ) L1M1_PR_MR + NEW li1 ( 2047 153 ) L1M1_PR_MR + NEW met1 ( 2277 153 ) M1M2_PR + NEW met1 ( 2277 221 ) M1M2_PR NEW li1 ( 8947 153 ) L1M1_PR_MR NEW li1 ( 10189 187 ) L1M1_PR_MR - NEW li1 ( 7797 153 ) L1M1_PR_MR ; - - storage_0_0.we0 ( storage_0_0.gcand X ) ( storage_0_0.cg GATE ) + USE SIGNAL + NEW li1 ( 7797 153 ) L1M1_PR_MR + NEW met1 ( 8073 153 ) M1M2_PR + NEW met1 ( 8119 221 ) M1M2_PR ; + - storage_0_0_0.we0 ( storage_0_0_0.gcand X ) ( storage_0_0_0.cg GATE ) + USE SIGNAL + ROUTED met2 ( 9453 153 ) ( * 221 ) NEW met1 ( 9453 221 ) ( 10097 * ) NEW li1 ( 9453 153 ) L1M1_PR_MR NEW met1 ( 9453 153 ) M1M2_PR NEW met1 ( 9453 221 ) M1M2_PR NEW li1 ( 10097 221 ) L1M1_PR_MR ; - - storage_1_0.bit0.storage ( storage_1_0.bit0.obuf0 A ) ( storage_1_0.bit0.bit Q ) + USE SIGNAL - + ROUTED met1 ( 805 357 ) ( * 391 ) - NEW met1 ( 759 357 ) ( 805 * ) + - storage_1_0_0.bit0.storage ( storage_1_0_0.bit0.obuf0 A ) ( storage_1_0_0.bit0.bit Q ) + USE SIGNAL + + ROUTED met1 ( 759 391 ) ( 805 * ) + NEW met1 ( 759 357 ) ( * 391 ) NEW li1 ( 805 391 ) L1M1_PR_MR NEW li1 ( 759 357 ) L1M1_PR_MR ; - - storage_1_0.bit1.storage ( storage_1_0.bit1.obuf0 A ) ( storage_1_0.bit1.bit Q ) + USE SIGNAL - + ROUTED met1 ( 1955 357 ) ( * 391 ) - NEW met1 ( 1909 357 ) ( 1955 * ) + - storage_1_0_0.bit1.storage ( storage_1_0_0.bit1.obuf0 A ) ( storage_1_0_0.bit1.bit Q ) + USE SIGNAL + + ROUTED met1 ( 1909 391 ) ( 1955 * ) + NEW met1 ( 1909 357 ) ( * 391 ) NEW li1 ( 1955 391 ) L1M1_PR_MR NEW li1 ( 1909 357 ) L1M1_PR_MR ; - - storage_1_0.bit2.storage ( storage_1_0.bit2.obuf0 A ) ( storage_1_0.bit2.bit Q ) + USE SIGNAL - + ROUTED met1 ( 3105 357 ) ( * 391 ) - NEW met1 ( 3059 357 ) ( 3105 * ) + - storage_1_0_0.bit2.storage ( storage_1_0_0.bit2.obuf0 A ) ( storage_1_0_0.bit2.bit Q ) + USE SIGNAL + + ROUTED met1 ( 3059 391 ) ( 3105 * ) + NEW met1 ( 3059 357 ) ( * 391 ) NEW li1 ( 3105 391 ) L1M1_PR_MR NEW li1 ( 3059 357 ) L1M1_PR_MR ; - - storage_1_0.bit3.storage ( storage_1_0.bit3.obuf0 A ) ( storage_1_0.bit3.bit Q ) + USE SIGNAL - + ROUTED met1 ( 4255 357 ) ( * 391 ) - NEW met1 ( 4209 357 ) ( 4255 * ) + - storage_1_0_0.bit3.storage ( storage_1_0_0.bit3.obuf0 A ) ( storage_1_0_0.bit3.bit Q ) + USE SIGNAL + + ROUTED met1 ( 4209 391 ) ( 4255 * ) + NEW met1 ( 4209 357 ) ( * 391 ) NEW li1 ( 4255 391 ) L1M1_PR_MR NEW li1 ( 4209 357 ) L1M1_PR_MR ; - - storage_1_0.bit4.storage ( storage_1_0.bit4.obuf0 A ) ( storage_1_0.bit4.bit Q ) + USE SIGNAL - + ROUTED met1 ( 5405 357 ) ( * 391 ) - NEW met1 ( 5359 357 ) ( 5405 * ) + - storage_1_0_0.bit4.storage ( storage_1_0_0.bit4.obuf0 A ) ( storage_1_0_0.bit4.bit Q ) + USE SIGNAL + + ROUTED met1 ( 5359 391 ) ( 5405 * ) + NEW met1 ( 5359 357 ) ( * 391 ) NEW li1 ( 5405 391 ) L1M1_PR_MR NEW li1 ( 5359 357 ) L1M1_PR_MR ; - - storage_1_0.bit5.storage ( storage_1_0.bit5.obuf0 A ) ( storage_1_0.bit5.bit Q ) + USE SIGNAL - + ROUTED met1 ( 6555 357 ) ( * 391 ) - NEW met1 ( 6509 357 ) ( 6555 * ) + - storage_1_0_0.bit5.storage ( storage_1_0_0.bit5.obuf0 A ) ( storage_1_0_0.bit5.bit Q ) + USE SIGNAL + + ROUTED met1 ( 6509 391 ) ( 6555 * ) + NEW met1 ( 6509 357 ) ( * 391 ) NEW li1 ( 6555 391 ) L1M1_PR_MR NEW li1 ( 6509 357 ) L1M1_PR_MR ; - - storage_1_0.bit6.storage ( storage_1_0.bit6.obuf0 A ) ( storage_1_0.bit6.bit Q ) + USE SIGNAL - + ROUTED met1 ( 7705 357 ) ( * 391 ) - NEW met1 ( 7659 357 ) ( 7705 * ) + - storage_1_0_0.bit6.storage ( storage_1_0_0.bit6.obuf0 A ) ( storage_1_0_0.bit6.bit Q ) + USE SIGNAL + + ROUTED met1 ( 7659 391 ) ( 7705 * ) + NEW met1 ( 7659 357 ) ( * 391 ) NEW li1 ( 7705 391 ) L1M1_PR_MR NEW li1 ( 7659 357 ) L1M1_PR_MR ; - - storage_1_0.bit7.storage ( storage_1_0.bit7.obuf0 A ) ( storage_1_0.bit7.bit Q ) + USE SIGNAL - + ROUTED met1 ( 8855 357 ) ( * 391 ) - NEW met1 ( 8809 357 ) ( 8855 * ) + - storage_1_0_0.bit7.storage ( storage_1_0_0.bit7.obuf0 A ) ( storage_1_0_0.bit7.bit Q ) + USE SIGNAL + + ROUTED met1 ( 8809 391 ) ( 8855 * ) + NEW met1 ( 8809 357 ) ( * 391 ) NEW li1 ( 8855 391 ) L1M1_PR_MR NEW li1 ( 8809 357 ) L1M1_PR_MR ; - - storage_1_0.gclock ( storage_1_0.cg GCLK ) ( storage_1_0.bit7.bit CLK ) ( storage_1_0.bit6.bit CLK ) ( storage_1_0.bit5.bit CLK ) ( storage_1_0.bit4.bit CLK ) ( storage_1_0.bit3.bit CLK ) ( storage_1_0.bit2.bit CLK ) - ( storage_1_0.bit1.bit CLK ) ( storage_1_0.bit0.bit CLK ) + USE SIGNAL - + ROUTED met1 ( 1219 323 ) ( * 391 ) - NEW met1 ( 69 425 ) ( 851 * ) - NEW met1 ( 851 391 ) ( * 425 ) - NEW met1 ( 851 391 ) ( 1219 * ) - NEW met1 ( 2369 323 ) ( * 391 ) - NEW met1 ( 3519 323 ) ( * 391 ) - NEW met1 ( 2369 323 ) ( 3519 * ) - NEW met1 ( 4669 323 ) ( * 391 ) - NEW met1 ( 3519 323 ) ( 4669 * ) - NEW met1 ( 1219 323 ) ( 2369 * ) + - storage_1_0_0.gclock ( storage_1_0_0.cg GCLK ) ( storage_1_0_0.bit7.bit CLK ) ( storage_1_0_0.bit6.bit CLK ) ( storage_1_0_0.bit5.bit CLK ) ( storage_1_0_0.bit4.bit CLK ) ( storage_1_0_0.bit3.bit CLK ) ( storage_1_0_0.bit2.bit CLK ) + ( storage_1_0_0.bit1.bit CLK ) ( storage_1_0_0.bit0.bit CLK ) + USE SIGNAL + + ROUTED met1 ( 69 425 ) ( 1219 * ) + NEW met1 ( 3519 425 ) ( * 459 ) + NEW met1 ( 3473 459 ) ( 3519 * ) + NEW met1 ( 3473 425 ) ( * 459 ) + NEW met1 ( 2369 425 ) ( 3473 * ) + NEW met1 ( 4485 391 ) ( 4669 * ) + NEW met2 ( 4485 391 ) ( * 493 ) + NEW met1 ( 3519 493 ) ( 4485 * ) + NEW met1 ( 3519 459 ) ( * 493 ) NEW met1 ( 5819 323 ) ( * 391 ) - NEW met1 ( 5819 323 ) ( 6969 * ) - NEW met1 ( 6969 323 ) ( * 425 ) NEW met1 ( 4669 323 ) ( 5819 * ) - NEW met1 ( 8119 425 ) ( 8993 * ) - NEW met2 ( 8993 323 ) ( * 425 ) - NEW met1 ( 8993 323 ) ( 9867 * ) - NEW met1 ( 6969 425 ) ( 8119 * ) - NEW li1 ( 1219 391 ) L1M1_PR_MR + NEW met1 ( 4669 323 ) ( * 391 ) + NEW met1 ( 6969 323 ) ( * 391 ) + NEW met1 ( 5819 323 ) ( 6969 * ) + NEW met1 ( 1219 425 ) ( 2369 * ) + NEW met1 ( 8119 323 ) ( * 391 ) + NEW met1 ( 8119 323 ) ( 9867 * ) + NEW met1 ( 6969 323 ) ( 8119 * ) + NEW li1 ( 1219 425 ) L1M1_PR_MR NEW li1 ( 69 425 ) L1M1_PR_MR - NEW li1 ( 2369 391 ) L1M1_PR_MR - NEW li1 ( 3519 391 ) L1M1_PR_MR + NEW li1 ( 2369 425 ) L1M1_PR_MR + NEW li1 ( 3519 425 ) L1M1_PR_MR NEW li1 ( 4669 391 ) L1M1_PR_MR - NEW li1 ( 6969 425 ) L1M1_PR_MR + NEW met1 ( 4485 391 ) M1M2_PR + NEW met1 ( 4485 493 ) M1M2_PR NEW li1 ( 5819 391 ) L1M1_PR_MR - NEW li1 ( 8119 425 ) L1M1_PR_MR - NEW met1 ( 8993 425 ) M1M2_PR - NEW met1 ( 8993 323 ) M1M2_PR + NEW li1 ( 6969 391 ) L1M1_PR_MR + NEW li1 ( 8119 391 ) L1M1_PR_MR NEW li1 ( 9867 323 ) L1M1_PR_MR ; - - storage_1_0.select0_b ( storage_1_0.select_inv_0 Y ) ( storage_1_0.bit7.obuf0 TE_B ) ( storage_1_0.bit6.obuf0 TE_B ) ( storage_1_0.bit5.obuf0 TE_B ) ( storage_1_0.bit4.obuf0 TE_B ) ( storage_1_0.bit3.obuf0 TE_B ) ( storage_1_0.bit2.obuf0 TE_B ) - ( storage_1_0.bit1.obuf0 TE_B ) ( storage_1_0.bit0.obuf0 TE_B ) + USE SIGNAL - + ROUTED met1 ( 4347 425 ) ( 5497 * ) - NEW met1 ( 3197 425 ) ( 4347 * ) - NEW met1 ( 2047 425 ) ( 3197 * ) - NEW met1 ( 897 425 ) ( 2047 * ) - NEW met1 ( 6647 425 ) ( 6923 * ) - NEW met1 ( 6923 425 ) ( * 493 ) + - storage_1_0_0.select0_b ( storage_1_0_0.select_inv_0 Y ) ( storage_1_0_0.bit7.obuf0 TE_B ) ( storage_1_0_0.bit6.obuf0 TE_B ) ( storage_1_0_0.bit5.obuf0 TE_B ) ( storage_1_0_0.bit4.obuf0 TE_B ) ( storage_1_0_0.bit3.obuf0 TE_B ) ( storage_1_0_0.bit2.obuf0 TE_B ) + ( storage_1_0_0.bit1.obuf0 TE_B ) ( storage_1_0_0.bit0.obuf0 TE_B ) + USE SIGNAL + + ROUTED met1 ( 897 323 ) ( * 391 ) NEW met1 ( 5497 425 ) ( 6647 * ) + NEW met1 ( 4347 425 ) ( 5497 * ) + NEW met1 ( 3197 391 ) ( 3565 * ) + NEW met1 ( 3565 391 ) ( * 425 ) + NEW met1 ( 3565 425 ) ( 4347 * ) + NEW met1 ( 2047 323 ) ( * 391 ) + NEW met1 ( 2047 323 ) ( 3197 * ) + NEW met1 ( 3197 323 ) ( * 391 ) + NEW met1 ( 897 323 ) ( 2047 * ) NEW met1 ( 8947 357 ) ( * 391 ) NEW met1 ( 8947 357 ) ( 10189 * ) - NEW met1 ( 7797 323 ) ( * 391 ) - NEW met1 ( 7797 323 ) ( 8947 * ) - NEW met1 ( 8947 323 ) ( * 357 ) - NEW met2 ( 7797 391 ) ( * 493 ) - NEW met1 ( 6923 493 ) ( 7797 * ) - NEW li1 ( 897 425 ) L1M1_PR_MR + NEW met1 ( 7797 425 ) ( * 459 ) + NEW met1 ( 7797 459 ) ( 8119 * ) + NEW met1 ( 8119 459 ) ( * 493 ) + NEW met1 ( 8119 493 ) ( 8947 * ) + NEW met2 ( 8947 391 ) ( * 493 ) + NEW met1 ( 6647 425 ) ( 7797 * ) + NEW li1 ( 897 391 ) L1M1_PR_MR + NEW li1 ( 6647 425 ) L1M1_PR_MR NEW li1 ( 5497 425 ) L1M1_PR_MR NEW li1 ( 4347 425 ) L1M1_PR_MR - NEW li1 ( 3197 425 ) L1M1_PR_MR - NEW li1 ( 2047 425 ) L1M1_PR_MR - NEW li1 ( 6647 425 ) L1M1_PR_MR + NEW li1 ( 3197 391 ) L1M1_PR_MR + NEW li1 ( 2047 391 ) L1M1_PR_MR NEW li1 ( 8947 391 ) L1M1_PR_MR NEW li1 ( 10189 357 ) L1M1_PR_MR - NEW li1 ( 7797 391 ) L1M1_PR_MR - NEW met1 ( 7797 493 ) M1M2_PR - NEW met1 ( 7797 391 ) M1M2_PR ; - - storage_1_0.we0 ( storage_1_0.gcand X ) ( storage_1_0.cg GATE ) + USE SIGNAL + NEW li1 ( 7797 425 ) L1M1_PR_MR + NEW met1 ( 8947 493 ) M1M2_PR + NEW met1 ( 8947 391 ) M1M2_PR ; + - storage_1_0_0.we0 ( storage_1_0_0.gcand X ) ( storage_1_0_0.cg GATE ) + USE SIGNAL + ROUTED met1 ( 9453 493 ) ( 10097 * ) NEW li1 ( 9453 493 ) L1M1_PR_MR NEW li1 ( 10097 493 ) L1M1_PR_MR ; - - storage_2_0.bit0.storage ( storage_2_0.bit0.obuf0 A ) ( storage_2_0.bit0.bit Q ) + USE SIGNAL + - storage_2_0_0.bit0.storage ( storage_2_0_0.bit0.obuf0 A ) ( storage_2_0_0.bit0.bit Q ) + USE SIGNAL + ROUTED met1 ( 759 663 ) ( 805 * ) NEW met1 ( 759 595 ) ( * 663 ) NEW li1 ( 805 663 ) L1M1_PR_MR NEW li1 ( 759 595 ) L1M1_PR_MR ; - - storage_2_0.bit1.storage ( storage_2_0.bit1.obuf0 A ) ( storage_2_0.bit1.bit Q ) + USE SIGNAL - + ROUTED met1 ( 1909 663 ) ( 1955 * ) - NEW met1 ( 1909 663 ) ( * 731 ) + - storage_2_0_0.bit1.storage ( storage_2_0_0.bit1.obuf0 A ) ( storage_2_0_0.bit1.bit Q ) + USE SIGNAL + + ROUTED met1 ( 1955 663 ) ( * 731 ) + NEW met1 ( 1909 731 ) ( 1955 * ) NEW li1 ( 1955 663 ) L1M1_PR_MR NEW li1 ( 1909 731 ) L1M1_PR_MR ; - - storage_2_0.bit2.storage ( storage_2_0.bit2.obuf0 A ) ( storage_2_0.bit2.bit Q ) + USE SIGNAL - + ROUTED met1 ( 3105 663 ) ( * 731 ) - NEW met1 ( 3059 731 ) ( 3105 * ) + - storage_2_0_0.bit2.storage ( storage_2_0_0.bit2.obuf0 A ) ( storage_2_0_0.bit2.bit Q ) + USE SIGNAL + + ROUTED met1 ( 3059 663 ) ( 3105 * ) + NEW met1 ( 3059 595 ) ( * 663 ) NEW li1 ( 3105 663 ) L1M1_PR_MR - NEW li1 ( 3059 731 ) L1M1_PR_MR ; - - storage_2_0.bit3.storage ( storage_2_0.bit3.obuf0 A ) ( storage_2_0.bit3.bit Q ) + USE SIGNAL - + ROUTED met1 ( 4209 663 ) ( 4255 * ) - NEW met1 ( 4209 663 ) ( * 731 ) - NEW li1 ( 4255 663 ) L1M1_PR_MR - NEW li1 ( 4209 731 ) L1M1_PR_MR ; - - storage_2_0.bit4.storage ( storage_2_0.bit4.obuf0 A ) ( storage_2_0.bit4.bit Q ) + USE SIGNAL - + ROUTED met1 ( 5405 663 ) ( * 731 ) - NEW met1 ( 5359 731 ) ( 5405 * ) + NEW li1 ( 3059 595 ) L1M1_PR_MR ; + - storage_2_0_0.bit3.storage ( storage_2_0_0.bit3.obuf0 A ) ( storage_2_0_0.bit3.bit Q ) + USE SIGNAL + + ROUTED met1 ( 4209 595 ) ( 4255 * ) + NEW met2 ( 4255 595 ) ( * 663 ) + NEW met1 ( 4254 663 ) ( 4255 * ) + NEW li1 ( 4209 595 ) L1M1_PR_MR + NEW met1 ( 4255 595 ) M1M2_PR + NEW met1 ( 4255 663 ) M1M2_PR + NEW li1 ( 4254 663 ) L1M1_PR_MR ; + - storage_2_0_0.bit4.storage ( storage_2_0_0.bit4.obuf0 A ) ( storage_2_0_0.bit4.bit Q ) + USE SIGNAL + + ROUTED met1 ( 5359 663 ) ( 5405 * ) + NEW met1 ( 5359 595 ) ( * 663 ) NEW li1 ( 5405 663 ) L1M1_PR_MR - NEW li1 ( 5359 731 ) L1M1_PR_MR ; - - storage_2_0.bit5.storage ( storage_2_0.bit5.obuf0 A ) ( storage_2_0.bit5.bit Q ) + USE SIGNAL - + ROUTED met1 ( 6555 651 ) ( * 663 ) - NEW met1 ( 6509 651 ) ( 6555 * ) - NEW met1 ( 6509 595 ) ( * 651 ) + NEW li1 ( 5359 595 ) L1M1_PR_MR ; + - storage_2_0_0.bit5.storage ( storage_2_0_0.bit5.obuf0 A ) ( storage_2_0_0.bit5.bit Q ) + USE SIGNAL + + ROUTED met1 ( 6509 663 ) ( 6555 * ) + NEW met1 ( 6509 663 ) ( * 731 ) NEW li1 ( 6555 663 ) L1M1_PR_MR - NEW li1 ( 6509 595 ) L1M1_PR_MR ; - - storage_2_0.bit6.storage ( storage_2_0.bit6.obuf0 A ) ( storage_2_0.bit6.bit Q ) + USE SIGNAL + NEW li1 ( 6509 731 ) L1M1_PR_MR ; + - storage_2_0_0.bit6.storage ( storage_2_0_0.bit6.obuf0 A ) ( storage_2_0_0.bit6.bit Q ) + USE SIGNAL + ROUTED met1 ( 7705 697 ) ( * 731 ) NEW met1 ( 7659 731 ) ( 7705 * ) NEW li1 ( 7705 697 ) L1M1_PR_MR NEW li1 ( 7659 731 ) L1M1_PR_MR ; - - storage_2_0.bit7.storage ( storage_2_0.bit7.obuf0 A ) ( storage_2_0.bit7.bit Q ) + USE SIGNAL + - storage_2_0_0.bit7.storage ( storage_2_0_0.bit7.obuf0 A ) ( storage_2_0_0.bit7.bit Q ) + USE SIGNAL + ROUTED met1 ( 8855 697 ) ( * 731 ) NEW met1 ( 8809 731 ) ( 8855 * ) NEW li1 ( 8855 697 ) L1M1_PR_MR NEW li1 ( 8809 731 ) L1M1_PR_MR ; - - storage_2_0.gclock ( storage_2_0.cg GCLK ) ( storage_2_0.bit7.bit CLK ) ( storage_2_0.bit6.bit CLK ) ( storage_2_0.bit5.bit CLK ) ( storage_2_0.bit4.bit CLK ) ( storage_2_0.bit3.bit CLK ) ( storage_2_0.bit2.bit CLK ) - ( storage_2_0.bit1.bit CLK ) ( storage_2_0.bit0.bit CLK ) + USE SIGNAL + - storage_2_0_0.gclock ( storage_2_0_0.cg GCLK ) ( storage_2_0_0.bit7.bit CLK ) ( storage_2_0_0.bit6.bit CLK ) ( storage_2_0_0.bit5.bit CLK ) ( storage_2_0_0.bit4.bit CLK ) ( storage_2_0_0.bit3.bit CLK ) ( storage_2_0_0.bit2.bit CLK ) + ( storage_2_0_0.bit1.bit CLK ) ( storage_2_0_0.bit0.bit CLK ) + USE SIGNAL + ROUTED met1 ( 943 663 ) ( 1219 * ) NEW met1 ( 943 663 ) ( * 697 ) NEW met1 ( 713 697 ) ( 943 * ) @@ -1789,305 +1814,297 @@ NETS 152 ; NEW met1 ( 69 629 ) ( 713 * ) NEW met1 ( 69 629 ) ( * 663 ) NEW met1 ( 1219 629 ) ( * 663 ) - NEW met1 ( 6969 629 ) ( * 663 ) - NEW met1 ( 6969 629 ) ( 7015 * ) - NEW met1 ( 7015 595 ) ( * 629 ) - NEW met1 ( 7015 595 ) ( 7153 * ) - NEW met1 ( 7153 595 ) ( * 629 ) - NEW met2 ( 6417 629 ) ( * 646 ) - NEW met2 ( 6417 646 ) ( 6555 * ) - NEW met2 ( 6555 595 ) ( * 646 ) - NEW met1 ( 6555 595 ) ( 7015 * ) + NEW met2 ( 6969 493 ) ( * 663 ) + NEW met1 ( 6969 493 ) ( 7153 * ) + NEW met1 ( 7153 459 ) ( * 493 ) + NEW met1 ( 6969 459 ) ( * 493 ) + NEW met1 ( 6210 459 ) ( 6969 * ) NEW met1 ( 2093 663 ) ( 2369 * ) NEW met1 ( 2093 663 ) ( * 697 ) NEW met1 ( 2001 697 ) ( 2093 * ) NEW met1 ( 2001 629 ) ( * 697 ) NEW met1 ( 3243 663 ) ( 3519 * ) - NEW met1 ( 3243 663 ) ( * 697 ) - NEW met1 ( 3151 697 ) ( 3243 * ) - NEW met1 ( 3151 629 ) ( * 697 ) - NEW met1 ( 2369 629 ) ( 3151 * ) - NEW met1 ( 2369 629 ) ( * 663 ) + NEW met1 ( 3243 663 ) ( * 765 ) + NEW met1 ( 2369 765 ) ( 3243 * ) + NEW met1 ( 2369 663 ) ( * 765 ) NEW met1 ( 4393 663 ) ( 4669 * ) NEW met1 ( 4393 663 ) ( * 697 ) - NEW met1 ( 4301 697 ) ( 4393 * ) - NEW met1 ( 4301 629 ) ( * 697 ) - NEW met1 ( 3519 629 ) ( 4301 * ) - NEW met1 ( 3519 629 ) ( * 663 ) + NEW met1 ( 4163 697 ) ( 4393 * ) + NEW met1 ( 4163 663 ) ( * 697 ) + NEW met1 ( 3519 663 ) ( 4163 * ) NEW met1 ( 5543 663 ) ( 5819 * ) - NEW met1 ( 5543 663 ) ( * 697 ) - NEW met1 ( 5451 697 ) ( 5543 * ) - NEW met1 ( 5451 629 ) ( * 697 ) - NEW met1 ( 4669 629 ) ( 5451 * ) - NEW met1 ( 4669 629 ) ( * 663 ) - NEW met1 ( 5819 629 ) ( * 663 ) + NEW met1 ( 5543 663 ) ( * 765 ) + NEW met1 ( 4669 765 ) ( 5543 * ) + NEW met1 ( 4669 663 ) ( * 765 ) + NEW met1 ( 6210 459 ) ( * 493 ) + NEW met1 ( 5819 493 ) ( 6210 * ) + NEW met2 ( 5819 493 ) ( * 663 ) NEW met1 ( 1219 629 ) ( 2001 * ) - NEW met1 ( 5819 629 ) ( 6417 * ) NEW met1 ( 8119 595 ) ( * 663 ) NEW met1 ( 8119 595 ) ( 9867 * ) - NEW met1 ( 7153 629 ) ( 8119 * ) + NEW met2 ( 7613 459 ) ( * 595 ) + NEW met1 ( 7613 595 ) ( 8119 * ) + NEW met1 ( 7153 459 ) ( 7613 * ) NEW li1 ( 1219 663 ) L1M1_PR_MR NEW li1 ( 69 663 ) L1M1_PR_MR NEW li1 ( 6969 663 ) L1M1_PR_MR - NEW met1 ( 6417 629 ) M1M2_PR - NEW met1 ( 6555 595 ) M1M2_PR + NEW met1 ( 6969 663 ) M1M2_PR + NEW met1 ( 6969 493 ) M1M2_PR NEW li1 ( 2369 663 ) L1M1_PR_MR NEW li1 ( 3519 663 ) L1M1_PR_MR NEW li1 ( 4669 663 ) L1M1_PR_MR NEW li1 ( 5819 663 ) L1M1_PR_MR + NEW met1 ( 5819 493 ) M1M2_PR + NEW met1 ( 5819 663 ) M1M2_PR NEW li1 ( 8119 663 ) L1M1_PR_MR - NEW li1 ( 9867 595 ) L1M1_PR_MR ; - - storage_2_0.select0_b ( storage_2_0.select_inv_0 Y ) ( storage_2_0.bit7.obuf0 TE_B ) ( storage_2_0.bit6.obuf0 TE_B ) ( storage_2_0.bit5.obuf0 TE_B ) ( storage_2_0.bit4.obuf0 TE_B ) ( storage_2_0.bit3.obuf0 TE_B ) ( storage_2_0.bit2.obuf0 TE_B ) - ( storage_2_0.bit1.obuf0 TE_B ) ( storage_2_0.bit0.obuf0 TE_B ) + USE SIGNAL + NEW li1 ( 9867 595 ) L1M1_PR_MR + NEW met1 ( 7613 459 ) M1M2_PR + NEW met1 ( 7613 595 ) M1M2_PR ; + - storage_2_0_0.select0_b ( storage_2_0_0.select_inv_0 Y ) ( storage_2_0_0.bit7.obuf0 TE_B ) ( storage_2_0_0.bit6.obuf0 TE_B ) ( storage_2_0_0.bit5.obuf0 TE_B ) ( storage_2_0_0.bit4.obuf0 TE_B ) ( storage_2_0_0.bit3.obuf0 TE_B ) ( storage_2_0_0.bit2.obuf0 TE_B ) + ( storage_2_0_0.bit1.obuf0 TE_B ) ( storage_2_0_0.bit0.obuf0 TE_B ) + USE SIGNAL + ROUTED met1 ( 897 595 ) ( * 663 ) - NEW met1 ( 6647 663 ) ( 6923 * ) - NEW met1 ( 6923 663 ) ( * 697 ) - NEW met1 ( 6923 697 ) ( 7015 * ) - NEW met1 ( 7015 663 ) ( * 697 ) - NEW met1 ( 6463 595 ) ( * 697 ) - NEW met1 ( 6463 697 ) ( 6601 * ) - NEW met1 ( 6601 663 ) ( * 697 ) - NEW met1 ( 6601 663 ) ( 6647 * ) - NEW met1 ( 5497 595 ) ( * 663 ) + NEW met1 ( 3013 697 ) ( 3151 * ) + NEW met1 ( 5313 697 ) ( 5451 * ) + NEW met1 ( 2047 629 ) ( * 663 ) + NEW met1 ( 2047 629 ) ( 2415 * ) + NEW met1 ( 2415 629 ) ( * 663 ) + NEW met1 ( 2415 663 ) ( 3013 * ) + NEW met1 ( 2047 595 ) ( * 629 ) + NEW met1 ( 6647 629 ) ( * 663 ) + NEW met1 ( 5497 629 ) ( * 663 ) + NEW met1 ( 5497 629 ) ( 6647 * ) + NEW met1 ( 5451 663 ) ( 5497 * ) NEW met1 ( 4347 629 ) ( * 663 ) - NEW met1 ( 4347 629 ) ( 4393 * ) - NEW met1 ( 4393 595 ) ( * 629 ) - NEW met1 ( 4393 595 ) ( 5497 * ) + NEW met1 ( 4347 629 ) ( 4715 * ) + NEW met1 ( 4715 629 ) ( * 663 ) + NEW met1 ( 4715 663 ) ( 5313 * ) NEW met1 ( 3197 595 ) ( * 663 ) - NEW met1 ( 3197 595 ) ( 4393 * ) - NEW met1 ( 2047 629 ) ( * 663 ) - NEW met1 ( 2047 629 ) ( 2093 * ) - NEW met1 ( 2093 595 ) ( * 629 ) - NEW met1 ( 2093 595 ) ( 3197 * ) - NEW met1 ( 897 595 ) ( 2093 * ) - NEW met1 ( 5497 595 ) ( 6463 * ) + NEW met1 ( 3197 595 ) ( 3749 * ) + NEW met1 ( 3749 595 ) ( * 629 ) + NEW met1 ( 3749 629 ) ( 4347 * ) + NEW met1 ( 3151 663 ) ( 3197 * ) + NEW met1 ( 897 595 ) ( 2047 * ) + NEW met1 ( 3013 663 ) ( * 697 ) + NEW met1 ( 3151 663 ) ( * 697 ) + NEW met1 ( 5313 663 ) ( * 697 ) + NEW met1 ( 5451 663 ) ( * 697 ) NEW met1 ( 8947 697 ) ( * 731 ) NEW met1 ( 8947 731 ) ( 10189 * ) NEW met1 ( 7797 697 ) ( 8119 * ) NEW met1 ( 8119 697 ) ( * 765 ) NEW met1 ( 8119 765 ) ( 8947 * ) NEW met1 ( 8947 731 ) ( * 765 ) - NEW met1 ( 7797 663 ) ( * 697 ) - NEW met1 ( 7015 663 ) ( 7797 * ) + NEW met1 ( 7797 629 ) ( * 697 ) + NEW met1 ( 6647 629 ) ( 7797 * ) NEW li1 ( 897 663 ) L1M1_PR_MR + NEW li1 ( 2047 663 ) L1M1_PR_MR NEW li1 ( 6647 663 ) L1M1_PR_MR NEW li1 ( 5497 663 ) L1M1_PR_MR NEW li1 ( 4347 663 ) L1M1_PR_MR NEW li1 ( 3197 663 ) L1M1_PR_MR - NEW li1 ( 2047 663 ) L1M1_PR_MR NEW li1 ( 8947 697 ) L1M1_PR_MR NEW li1 ( 10189 731 ) L1M1_PR_MR NEW li1 ( 7797 697 ) L1M1_PR_MR ; - - storage_2_0.we0 ( storage_2_0.gcand X ) ( storage_2_0.cg GATE ) + USE SIGNAL + - storage_2_0_0.we0 ( storage_2_0_0.gcand X ) ( storage_2_0_0.cg GATE ) + USE SIGNAL + ROUTED met2 ( 9453 697 ) ( * 765 ) NEW met1 ( 9453 765 ) ( 10097 * ) NEW li1 ( 9453 697 ) L1M1_PR_MR NEW met1 ( 9453 697 ) M1M2_PR NEW met1 ( 9453 765 ) M1M2_PR NEW li1 ( 10097 765 ) L1M1_PR_MR ; - - storage_3_0.bit0.storage ( storage_3_0.bit0.obuf0 A ) ( storage_3_0.bit0.bit Q ) + USE SIGNAL - + ROUTED met1 ( 805 901 ) ( * 935 ) - NEW met1 ( 759 901 ) ( 805 * ) + - storage_3_0_0.bit0.storage ( storage_3_0_0.bit0.obuf0 A ) ( storage_3_0_0.bit0.bit Q ) + USE SIGNAL + + ROUTED met1 ( 759 935 ) ( 805 * ) + NEW met1 ( 759 901 ) ( * 935 ) NEW li1 ( 805 935 ) L1M1_PR_MR NEW li1 ( 759 901 ) L1M1_PR_MR ; - - storage_3_0.bit1.storage ( storage_3_0.bit1.obuf0 A ) ( storage_3_0.bit1.bit Q ) + USE SIGNAL - + ROUTED met1 ( 1955 901 ) ( * 935 ) - NEW met1 ( 1909 901 ) ( 1955 * ) + - storage_3_0_0.bit1.storage ( storage_3_0_0.bit1.obuf0 A ) ( storage_3_0_0.bit1.bit Q ) + USE SIGNAL + + ROUTED met1 ( 1909 935 ) ( 1955 * ) + NEW met1 ( 1909 901 ) ( * 935 ) NEW li1 ( 1955 935 ) L1M1_PR_MR NEW li1 ( 1909 901 ) L1M1_PR_MR ; - - storage_3_0.bit2.storage ( storage_3_0.bit2.obuf0 A ) ( storage_3_0.bit2.bit Q ) + USE SIGNAL - + ROUTED met1 ( 3105 901 ) ( * 935 ) - NEW met1 ( 3059 901 ) ( 3105 * ) + - storage_3_0_0.bit2.storage ( storage_3_0_0.bit2.obuf0 A ) ( storage_3_0_0.bit2.bit Q ) + USE SIGNAL + + ROUTED met1 ( 3059 935 ) ( 3105 * ) + NEW met1 ( 3059 901 ) ( * 935 ) NEW li1 ( 3105 935 ) L1M1_PR_MR NEW li1 ( 3059 901 ) L1M1_PR_MR ; - - storage_3_0.bit3.storage ( storage_3_0.bit3.obuf0 A ) ( storage_3_0.bit3.bit Q ) + USE SIGNAL - + ROUTED met1 ( 4255 901 ) ( * 935 ) - NEW met1 ( 4209 901 ) ( 4255 * ) + - storage_3_0_0.bit3.storage ( storage_3_0_0.bit3.obuf0 A ) ( storage_3_0_0.bit3.bit Q ) + USE SIGNAL + + ROUTED met1 ( 4209 935 ) ( 4255 * ) + NEW met1 ( 4209 901 ) ( * 935 ) NEW li1 ( 4255 935 ) L1M1_PR_MR NEW li1 ( 4209 901 ) L1M1_PR_MR ; - - storage_3_0.bit4.storage ( storage_3_0.bit4.obuf0 A ) ( storage_3_0.bit4.bit Q ) + USE SIGNAL - + ROUTED met1 ( 5405 901 ) ( * 935 ) - NEW met1 ( 5359 901 ) ( 5405 * ) + - storage_3_0_0.bit4.storage ( storage_3_0_0.bit4.obuf0 A ) ( storage_3_0_0.bit4.bit Q ) + USE SIGNAL + + ROUTED met1 ( 5359 935 ) ( 5405 * ) + NEW met1 ( 5359 901 ) ( * 935 ) NEW li1 ( 5405 935 ) L1M1_PR_MR NEW li1 ( 5359 901 ) L1M1_PR_MR ; - - storage_3_0.bit5.storage ( storage_3_0.bit5.obuf0 A ) ( storage_3_0.bit5.bit Q ) + USE SIGNAL - + ROUTED met1 ( 6555 901 ) ( * 935 ) - NEW met1 ( 6509 901 ) ( 6555 * ) + - storage_3_0_0.bit5.storage ( storage_3_0_0.bit5.obuf0 A ) ( storage_3_0_0.bit5.bit Q ) + USE SIGNAL + + ROUTED met1 ( 6509 935 ) ( 6555 * ) + NEW met1 ( 6509 901 ) ( * 935 ) NEW li1 ( 6555 935 ) L1M1_PR_MR NEW li1 ( 6509 901 ) L1M1_PR_MR ; - - storage_3_0.bit6.storage ( storage_3_0.bit6.obuf0 A ) ( storage_3_0.bit6.bit Q ) + USE SIGNAL - + ROUTED met1 ( 7705 901 ) ( * 935 ) - NEW met1 ( 7659 901 ) ( 7705 * ) + - storage_3_0_0.bit6.storage ( storage_3_0_0.bit6.obuf0 A ) ( storage_3_0_0.bit6.bit Q ) + USE SIGNAL + + ROUTED met1 ( 7659 935 ) ( 7705 * ) + NEW met1 ( 7659 901 ) ( * 935 ) NEW li1 ( 7705 935 ) L1M1_PR_MR NEW li1 ( 7659 901 ) L1M1_PR_MR ; - - storage_3_0.bit7.storage ( storage_3_0.bit7.obuf0 A ) ( storage_3_0.bit7.bit Q ) + USE SIGNAL - + ROUTED met1 ( 8855 901 ) ( * 935 ) - NEW met1 ( 8809 901 ) ( 8855 * ) + - storage_3_0_0.bit7.storage ( storage_3_0_0.bit7.obuf0 A ) ( storage_3_0_0.bit7.bit Q ) + USE SIGNAL + + ROUTED met1 ( 8809 935 ) ( 8855 * ) + NEW met1 ( 8809 901 ) ( * 935 ) NEW li1 ( 8855 935 ) L1M1_PR_MR NEW li1 ( 8809 901 ) L1M1_PR_MR ; - - storage_3_0.gclock ( storage_3_0.cg GCLK ) ( storage_3_0.bit7.bit CLK ) ( storage_3_0.bit6.bit CLK ) ( storage_3_0.bit5.bit CLK ) ( storage_3_0.bit4.bit CLK ) ( storage_3_0.bit3.bit CLK ) ( storage_3_0.bit2.bit CLK ) - ( storage_3_0.bit1.bit CLK ) ( storage_3_0.bit0.bit CLK ) + USE SIGNAL + - storage_3_0_0.gclock ( storage_3_0_0.cg GCLK ) ( storage_3_0_0.bit7.bit CLK ) ( storage_3_0_0.bit6.bit CLK ) ( storage_3_0_0.bit5.bit CLK ) ( storage_3_0_0.bit4.bit CLK ) ( storage_3_0_0.bit3.bit CLK ) ( storage_3_0_0.bit2.bit CLK ) + ( storage_3_0_0.bit1.bit CLK ) ( storage_3_0_0.bit0.bit CLK ) + USE SIGNAL + ROUTED met1 ( 1219 867 ) ( * 935 ) NEW met1 ( 69 969 ) ( 851 * ) NEW met1 ( 851 935 ) ( * 969 ) NEW met1 ( 851 935 ) ( 1219 * ) + NEW met1 ( 6969 867 ) ( * 935 ) NEW met1 ( 2369 867 ) ( * 935 ) NEW met1 ( 3519 867 ) ( * 935 ) NEW met1 ( 2369 867 ) ( 3519 * ) NEW met1 ( 4669 867 ) ( * 935 ) NEW met1 ( 3519 867 ) ( 4669 * ) - NEW met1 ( 1219 867 ) ( 2369 * ) NEW met1 ( 5819 867 ) ( * 935 ) - NEW met1 ( 5819 867 ) ( 6969 * ) - NEW met1 ( 6969 867 ) ( * 969 ) NEW met1 ( 4669 867 ) ( 5819 * ) - NEW met1 ( 8119 969 ) ( 9223 * ) - NEW met1 ( 9223 969 ) ( * 1037 ) - NEW met1 ( 9223 1037 ) ( 9867 * ) - NEW met1 ( 6969 969 ) ( 8119 * ) + NEW met1 ( 1219 867 ) ( 2369 * ) + NEW met1 ( 5819 867 ) ( 6969 * ) + NEW met1 ( 8119 867 ) ( * 935 ) + NEW met1 ( 8119 867 ) ( 9867 * ) + NEW met1 ( 6969 867 ) ( 8119 * ) NEW li1 ( 1219 935 ) L1M1_PR_MR NEW li1 ( 69 969 ) L1M1_PR_MR + NEW li1 ( 6969 935 ) L1M1_PR_MR NEW li1 ( 2369 935 ) L1M1_PR_MR NEW li1 ( 3519 935 ) L1M1_PR_MR NEW li1 ( 4669 935 ) L1M1_PR_MR - NEW li1 ( 6969 969 ) L1M1_PR_MR NEW li1 ( 5819 935 ) L1M1_PR_MR - NEW li1 ( 8119 969 ) L1M1_PR_MR - NEW li1 ( 9867 1037 ) L1M1_PR_MR ; - - storage_3_0.select0_b ( storage_3_0.select_inv_0 Y ) ( storage_3_0.bit7.obuf0 TE_B ) ( storage_3_0.bit6.obuf0 TE_B ) ( storage_3_0.bit5.obuf0 TE_B ) ( storage_3_0.bit4.obuf0 TE_B ) ( storage_3_0.bit3.obuf0 TE_B ) ( storage_3_0.bit2.obuf0 TE_B ) - ( storage_3_0.bit1.obuf0 TE_B ) ( storage_3_0.bit0.obuf0 TE_B ) + USE SIGNAL + NEW li1 ( 8119 935 ) L1M1_PR_MR + NEW li1 ( 9867 867 ) L1M1_PR_MR ; + - storage_3_0_0.select0_b ( storage_3_0_0.select_inv_0 Y ) ( storage_3_0_0.bit7.obuf0 TE_B ) ( storage_3_0_0.bit6.obuf0 TE_B ) ( storage_3_0_0.bit5.obuf0 TE_B ) ( storage_3_0_0.bit4.obuf0 TE_B ) ( storage_3_0_0.bit3.obuf0 TE_B ) ( storage_3_0_0.bit2.obuf0 TE_B ) + ( storage_3_0_0.bit1.obuf0 TE_B ) ( storage_3_0_0.bit0.obuf0 TE_B ) + USE SIGNAL + ROUTED met1 ( 4347 969 ) ( 5497 * ) NEW met1 ( 3197 969 ) ( 4347 * ) NEW met1 ( 2047 969 ) ( 3197 * ) NEW met1 ( 897 969 ) ( 2047 * ) - NEW met1 ( 6647 969 ) ( 6923 * ) - NEW met1 ( 6923 969 ) ( * 1037 ) NEW met1 ( 5497 969 ) ( 6647 * ) NEW met1 ( 8947 901 ) ( * 935 ) NEW met1 ( 8947 901 ) ( 10189 * ) - NEW met1 ( 7797 867 ) ( * 935 ) - NEW met1 ( 7797 867 ) ( 8947 * ) - NEW met1 ( 8947 867 ) ( * 901 ) - NEW met2 ( 7797 935 ) ( * 1037 ) - NEW met1 ( 6923 1037 ) ( 7797 * ) + NEW met1 ( 7797 969 ) ( * 1003 ) + NEW met1 ( 7797 1003 ) ( 8119 * ) + NEW met1 ( 8119 1003 ) ( * 1037 ) + NEW met1 ( 8119 1037 ) ( 8947 * ) + NEW met2 ( 8947 935 ) ( * 1037 ) + NEW met1 ( 6647 969 ) ( 7797 * ) NEW li1 ( 897 969 ) L1M1_PR_MR + NEW li1 ( 6647 969 ) L1M1_PR_MR NEW li1 ( 5497 969 ) L1M1_PR_MR NEW li1 ( 4347 969 ) L1M1_PR_MR NEW li1 ( 3197 969 ) L1M1_PR_MR NEW li1 ( 2047 969 ) L1M1_PR_MR - NEW li1 ( 6647 969 ) L1M1_PR_MR NEW li1 ( 8947 935 ) L1M1_PR_MR NEW li1 ( 10189 901 ) L1M1_PR_MR - NEW li1 ( 7797 935 ) L1M1_PR_MR - NEW met1 ( 7797 1037 ) M1M2_PR - NEW met1 ( 7797 935 ) M1M2_PR ; - - storage_3_0.we0 ( storage_3_0.gcand X ) ( storage_3_0.cg GATE ) + USE SIGNAL - + ROUTED met2 ( 9453 867 ) ( * 935 ) - NEW met1 ( 9453 867 ) ( 10097 * ) - NEW li1 ( 9453 935 ) L1M1_PR_MR - NEW met1 ( 9453 935 ) M1M2_PR - NEW met1 ( 9453 867 ) M1M2_PR - NEW li1 ( 10097 867 ) L1M1_PR_MR ; - - storage_4_0.bit0.storage ( storage_4_0.bit0.obuf0 A ) ( storage_4_0.bit0.bit Q ) + USE SIGNAL + NEW li1 ( 7797 969 ) L1M1_PR_MR + NEW met1 ( 8947 1037 ) M1M2_PR + NEW met1 ( 8947 935 ) M1M2_PR ; + - storage_3_0_0.we0 ( storage_3_0_0.gcand X ) ( storage_3_0_0.cg GATE ) + USE SIGNAL + + ROUTED met1 ( 9453 1037 ) ( 10097 * ) + NEW li1 ( 9453 1037 ) L1M1_PR_MR + NEW li1 ( 10097 1037 ) L1M1_PR_MR ; + - storage_4_0_0.bit0.storage ( storage_4_0_0.bit0.obuf0 A ) ( storage_4_0_0.bit0.bit Q ) + USE SIGNAL + ROUTED met1 ( 805 1241 ) ( * 1275 ) NEW met1 ( 759 1275 ) ( 805 * ) NEW li1 ( 805 1241 ) L1M1_PR_MR NEW li1 ( 759 1275 ) L1M1_PR_MR ; - - storage_4_0.bit1.storage ( storage_4_0.bit1.obuf0 A ) ( storage_4_0.bit1.bit Q ) + USE SIGNAL + - storage_4_0_0.bit1.storage ( storage_4_0_0.bit1.obuf0 A ) ( storage_4_0_0.bit1.bit Q ) + USE SIGNAL + ROUTED met1 ( 1955 1241 ) ( * 1275 ) NEW met1 ( 1909 1275 ) ( 1955 * ) NEW li1 ( 1955 1241 ) L1M1_PR_MR NEW li1 ( 1909 1275 ) L1M1_PR_MR ; - - storage_4_0.bit2.storage ( storage_4_0.bit2.obuf0 A ) ( storage_4_0.bit2.bit Q ) + USE SIGNAL + - storage_4_0_0.bit2.storage ( storage_4_0_0.bit2.obuf0 A ) ( storage_4_0_0.bit2.bit Q ) + USE SIGNAL + ROUTED met1 ( 3105 1241 ) ( * 1275 ) NEW met1 ( 3059 1275 ) ( 3105 * ) NEW li1 ( 3105 1241 ) L1M1_PR_MR NEW li1 ( 3059 1275 ) L1M1_PR_MR ; - - storage_4_0.bit3.storage ( storage_4_0.bit3.obuf0 A ) ( storage_4_0.bit3.bit Q ) + USE SIGNAL + - storage_4_0_0.bit3.storage ( storage_4_0_0.bit3.obuf0 A ) ( storage_4_0_0.bit3.bit Q ) + USE SIGNAL + ROUTED met1 ( 4255 1241 ) ( * 1275 ) NEW met1 ( 4209 1275 ) ( 4255 * ) NEW li1 ( 4255 1241 ) L1M1_PR_MR NEW li1 ( 4209 1275 ) L1M1_PR_MR ; - - storage_4_0.bit4.storage ( storage_4_0.bit4.obuf0 A ) ( storage_4_0.bit4.bit Q ) + USE SIGNAL + - storage_4_0_0.bit4.storage ( storage_4_0_0.bit4.obuf0 A ) ( storage_4_0_0.bit4.bit Q ) + USE SIGNAL + ROUTED met1 ( 5405 1241 ) ( * 1275 ) NEW met1 ( 5359 1275 ) ( 5405 * ) NEW li1 ( 5405 1241 ) L1M1_PR_MR NEW li1 ( 5359 1275 ) L1M1_PR_MR ; - - storage_4_0.bit5.storage ( storage_4_0.bit5.obuf0 A ) ( storage_4_0.bit5.bit Q ) + USE SIGNAL + - storage_4_0_0.bit5.storage ( storage_4_0_0.bit5.obuf0 A ) ( storage_4_0_0.bit5.bit Q ) + USE SIGNAL + ROUTED met1 ( 6555 1241 ) ( * 1275 ) NEW met1 ( 6509 1275 ) ( 6555 * ) NEW li1 ( 6555 1241 ) L1M1_PR_MR NEW li1 ( 6509 1275 ) L1M1_PR_MR ; - - storage_4_0.bit6.storage ( storage_4_0.bit6.obuf0 A ) ( storage_4_0.bit6.bit Q ) + USE SIGNAL + - storage_4_0_0.bit6.storage ( storage_4_0_0.bit6.obuf0 A ) ( storage_4_0_0.bit6.bit Q ) + USE SIGNAL + ROUTED met1 ( 7705 1241 ) ( * 1275 ) NEW met1 ( 7659 1275 ) ( 7705 * ) NEW li1 ( 7705 1241 ) L1M1_PR_MR NEW li1 ( 7659 1275 ) L1M1_PR_MR ; - - storage_4_0.bit7.storage ( storage_4_0.bit7.obuf0 A ) ( storage_4_0.bit7.bit Q ) + USE SIGNAL + - storage_4_0_0.bit7.storage ( storage_4_0_0.bit7.obuf0 A ) ( storage_4_0_0.bit7.bit Q ) + USE SIGNAL + ROUTED met1 ( 8855 1241 ) ( * 1275 ) NEW met1 ( 8809 1275 ) ( 8855 * ) NEW li1 ( 8855 1241 ) L1M1_PR_MR NEW li1 ( 8809 1275 ) L1M1_PR_MR ; - - storage_4_0.gclock ( storage_4_0.cg GCLK ) ( storage_4_0.bit7.bit CLK ) ( storage_4_0.bit6.bit CLK ) ( storage_4_0.bit5.bit CLK ) ( storage_4_0.bit4.bit CLK ) ( storage_4_0.bit3.bit CLK ) ( storage_4_0.bit2.bit CLK ) - ( storage_4_0.bit1.bit CLK ) ( storage_4_0.bit0.bit CLK ) + USE SIGNAL - + ROUTED met1 ( 69 1173 ) ( * 1207 ) + - storage_4_0_0.gclock ( storage_4_0_0.cg GCLK ) ( storage_4_0_0.bit7.bit CLK ) ( storage_4_0_0.bit6.bit CLK ) ( storage_4_0_0.bit5.bit CLK ) ( storage_4_0_0.bit4.bit CLK ) ( storage_4_0_0.bit3.bit CLK ) ( storage_4_0_0.bit2.bit CLK ) + ( storage_4_0_0.bit1.bit CLK ) ( storage_4_0_0.bit0.bit CLK ) + USE SIGNAL + + ROUTED met1 ( 1219 1241 ) ( * 1309 ) + NEW met1 ( 69 1173 ) ( * 1207 ) + NEW met1 ( 69 1173 ) ( 851 * ) + NEW met1 ( 851 1173 ) ( * 1241 ) + NEW met1 ( 851 1241 ) ( 1219 * ) NEW met1 ( 6969 1173 ) ( * 1207 ) - NEW met1 ( 6969 1139 ) ( * 1173 ) - NEW met1 ( 4301 1241 ) ( 4669 * ) - NEW met1 ( 4301 1241 ) ( * 1309 ) - NEW met1 ( 5451 1241 ) ( 5819 * ) - NEW met1 ( 5451 1241 ) ( * 1309 ) - NEW met1 ( 4669 1309 ) ( 5451 * ) - NEW met1 ( 4669 1241 ) ( * 1309 ) - NEW met2 ( 5819 1139 ) ( * 1241 ) - NEW met1 ( 5819 1139 ) ( 6969 * ) - NEW met1 ( 69 1173 ) ( 690 * ) - NEW met1 ( 3519 1241 ) ( * 1309 ) + NEW met1 ( 2185 1241 ) ( 2369 * ) + NEW met1 ( 2185 1241 ) ( * 1309 ) + NEW met1 ( 3381 1241 ) ( 3519 * ) + NEW met1 ( 3381 1241 ) ( * 1309 ) + NEW met1 ( 2369 1309 ) ( 3381 * ) NEW met1 ( 2369 1241 ) ( * 1309 ) - NEW met1 ( 2369 1309 ) ( 3151 * ) - NEW met1 ( 3151 1275 ) ( * 1309 ) - NEW met1 ( 3151 1275 ) ( 3519 * ) - NEW met2 ( 1219 1207 ) ( * 1309 ) - NEW met1 ( 1219 1309 ) ( 2001 * ) - NEW met1 ( 2001 1275 ) ( * 1309 ) - NEW met1 ( 2001 1275 ) ( 2369 * ) - NEW met1 ( 690 1173 ) ( * 1207 ) - NEW met1 ( 690 1207 ) ( 1219 * ) - NEW met1 ( 3519 1309 ) ( 4301 * ) + NEW met1 ( 4485 1241 ) ( 4669 * ) + NEW met1 ( 4485 1241 ) ( * 1309 ) + NEW met1 ( 3519 1309 ) ( 4485 * ) + NEW met1 ( 3519 1241 ) ( * 1309 ) + NEW met1 ( 5819 1241 ) ( * 1275 ) + NEW met1 ( 5681 1275 ) ( 5819 * ) + NEW met1 ( 5681 1275 ) ( * 1309 ) + NEW met1 ( 4669 1309 ) ( 5681 * ) + NEW met1 ( 4669 1241 ) ( * 1309 ) + NEW met1 ( 5819 1173 ) ( * 1241 ) + NEW met1 ( 1219 1309 ) ( 2185 * ) + NEW met1 ( 5819 1173 ) ( 6969 * ) NEW met1 ( 8119 1139 ) ( * 1207 ) NEW met1 ( 8119 1139 ) ( 9867 * ) NEW met1 ( 6969 1173 ) ( 8119 * ) + NEW li1 ( 1219 1241 ) L1M1_PR_MR NEW li1 ( 69 1207 ) L1M1_PR_MR NEW li1 ( 6969 1207 ) L1M1_PR_MR + NEW li1 ( 2369 1241 ) L1M1_PR_MR + NEW li1 ( 3519 1241 ) L1M1_PR_MR NEW li1 ( 4669 1241 ) L1M1_PR_MR NEW li1 ( 5819 1241 ) L1M1_PR_MR - NEW met1 ( 5819 1139 ) M1M2_PR - NEW met1 ( 5819 1241 ) M1M2_PR - NEW li1 ( 3519 1241 ) L1M1_PR_MR - NEW li1 ( 2369 1241 ) L1M1_PR_MR - NEW li1 ( 1219 1207 ) L1M1_PR_MR - NEW met1 ( 1219 1207 ) M1M2_PR - NEW met1 ( 1219 1309 ) M1M2_PR NEW li1 ( 8119 1207 ) L1M1_PR_MR NEW li1 ( 9867 1139 ) L1M1_PR_MR ; - - storage_4_0.select0_b ( storage_4_0.select_inv_0 Y ) ( storage_4_0.bit7.obuf0 TE_B ) ( storage_4_0.bit6.obuf0 TE_B ) ( storage_4_0.bit5.obuf0 TE_B ) ( storage_4_0.bit4.obuf0 TE_B ) ( storage_4_0.bit3.obuf0 TE_B ) ( storage_4_0.bit2.obuf0 TE_B ) - ( storage_4_0.bit1.obuf0 TE_B ) ( storage_4_0.bit0.obuf0 TE_B ) + USE SIGNAL - + ROUTED met1 ( 6647 1241 ) ( 6969 * ) - NEW met1 ( 6969 1241 ) ( * 1309 ) - NEW met1 ( 6647 1173 ) ( * 1241 ) - NEW met1 ( 5497 1207 ) ( 5819 * ) - NEW met1 ( 5819 1173 ) ( * 1207 ) + - storage_4_0_0.select0_b ( storage_4_0_0.select_inv_0 Y ) ( storage_4_0_0.bit7.obuf0 TE_B ) ( storage_4_0_0.bit6.obuf0 TE_B ) ( storage_4_0_0.bit5.obuf0 TE_B ) ( storage_4_0_0.bit4.obuf0 TE_B ) ( storage_4_0_0.bit3.obuf0 TE_B ) ( storage_4_0_0.bit2.obuf0 TE_B ) + ( storage_4_0_0.bit1.obuf0 TE_B ) ( storage_4_0_0.bit0.obuf0 TE_B ) + USE SIGNAL + + ROUTED met1 ( 897 1173 ) ( * 1207 ) + NEW met1 ( 6647 1241 ) ( * 1309 ) + NEW met1 ( 6969 1275 ) ( * 1309 ) + NEW met1 ( 6647 1275 ) ( 6969 * ) + NEW met1 ( 5497 1241 ) ( 5773 * ) + NEW met2 ( 5773 1241 ) ( * 1309 ) NEW met1 ( 4347 1173 ) ( * 1207 ) NEW met1 ( 4347 1173 ) ( 5497 * ) - NEW met1 ( 5497 1173 ) ( * 1207 ) - NEW met1 ( 5819 1173 ) ( 6647 * ) - NEW met1 ( 1265 1207 ) ( 2047 * ) - NEW met1 ( 1265 1207 ) ( * 1241 ) - NEW met1 ( 897 1241 ) ( 1265 * ) + NEW met1 ( 5497 1173 ) ( * 1241 ) NEW met1 ( 3197 1173 ) ( * 1207 ) - NEW met1 ( 2047 1173 ) ( 3197 * ) - NEW met1 ( 2047 1173 ) ( * 1207 ) NEW met1 ( 3197 1173 ) ( 4347 * ) + NEW met1 ( 2047 1173 ) ( * 1207 ) + NEW met1 ( 2047 1173 ) ( 3197 * ) + NEW met1 ( 897 1173 ) ( 2047 * ) + NEW met1 ( 5773 1309 ) ( 6647 * ) NEW met1 ( 8947 1241 ) ( * 1275 ) NEW met1 ( 8947 1275 ) ( 10189 * ) NEW met1 ( 7797 1241 ) ( 8119 * ) @@ -2096,219 +2113,238 @@ NETS 152 ; NEW met1 ( 8947 1275 ) ( * 1309 ) NEW met1 ( 7797 1241 ) ( * 1309 ) NEW met1 ( 6969 1309 ) ( 7797 * ) + NEW li1 ( 897 1207 ) L1M1_PR_MR NEW li1 ( 6647 1241 ) L1M1_PR_MR - NEW li1 ( 5497 1207 ) L1M1_PR_MR + NEW li1 ( 5497 1241 ) L1M1_PR_MR + NEW met1 ( 5773 1241 ) M1M2_PR + NEW met1 ( 5773 1309 ) M1M2_PR NEW li1 ( 4347 1207 ) L1M1_PR_MR - NEW li1 ( 2047 1207 ) L1M1_PR_MR - NEW li1 ( 897 1241 ) L1M1_PR_MR NEW li1 ( 3197 1207 ) L1M1_PR_MR + NEW li1 ( 2047 1207 ) L1M1_PR_MR NEW li1 ( 8947 1241 ) L1M1_PR_MR NEW li1 ( 10189 1275 ) L1M1_PR_MR NEW li1 ( 7797 1241 ) L1M1_PR_MR ; - - storage_4_0.we0 ( storage_4_0.gcand X ) ( storage_4_0.cg GATE ) + USE SIGNAL + - storage_4_0_0.we0 ( storage_4_0_0.gcand X ) ( storage_4_0_0.cg GATE ) + USE SIGNAL + ROUTED met2 ( 9453 1241 ) ( * 1309 ) NEW met1 ( 9453 1309 ) ( 10097 * ) NEW li1 ( 9453 1241 ) L1M1_PR_MR NEW met1 ( 9453 1241 ) M1M2_PR NEW met1 ( 9453 1309 ) M1M2_PR NEW li1 ( 10097 1309 ) L1M1_PR_MR ; - - storage_5_0.bit0.storage ( storage_5_0.bit0.obuf0 A ) ( storage_5_0.bit0.bit Q ) + USE SIGNAL - + ROUTED met1 ( 805 1445 ) ( * 1479 ) - NEW met1 ( 759 1445 ) ( 805 * ) + - storage_5_0_0.bit0.storage ( storage_5_0_0.bit0.obuf0 A ) ( storage_5_0_0.bit0.bit Q ) + USE SIGNAL + + ROUTED met1 ( 759 1479 ) ( 805 * ) + NEW met1 ( 759 1445 ) ( * 1479 ) NEW li1 ( 805 1479 ) L1M1_PR_MR NEW li1 ( 759 1445 ) L1M1_PR_MR ; - - storage_5_0.bit1.storage ( storage_5_0.bit1.obuf0 A ) ( storage_5_0.bit1.bit Q ) + USE SIGNAL - + ROUTED met1 ( 1955 1445 ) ( * 1479 ) - NEW met1 ( 1909 1445 ) ( 1955 * ) + - storage_5_0_0.bit1.storage ( storage_5_0_0.bit1.obuf0 A ) ( storage_5_0_0.bit1.bit Q ) + USE SIGNAL + + ROUTED met1 ( 1909 1479 ) ( 1955 * ) + NEW met1 ( 1909 1445 ) ( * 1479 ) NEW li1 ( 1955 1479 ) L1M1_PR_MR NEW li1 ( 1909 1445 ) L1M1_PR_MR ; - - storage_5_0.bit2.storage ( storage_5_0.bit2.obuf0 A ) ( storage_5_0.bit2.bit Q ) + USE SIGNAL - + ROUTED met1 ( 3105 1445 ) ( * 1479 ) - NEW met1 ( 3059 1445 ) ( 3105 * ) + - storage_5_0_0.bit2.storage ( storage_5_0_0.bit2.obuf0 A ) ( storage_5_0_0.bit2.bit Q ) + USE SIGNAL + + ROUTED met1 ( 3059 1479 ) ( 3105 * ) + NEW met1 ( 3059 1445 ) ( * 1479 ) NEW li1 ( 3105 1479 ) L1M1_PR_MR NEW li1 ( 3059 1445 ) L1M1_PR_MR ; - - storage_5_0.bit3.storage ( storage_5_0.bit3.obuf0 A ) ( storage_5_0.bit3.bit Q ) + USE SIGNAL - + ROUTED met1 ( 4255 1445 ) ( * 1479 ) - NEW met1 ( 4209 1445 ) ( 4255 * ) + - storage_5_0_0.bit3.storage ( storage_5_0_0.bit3.obuf0 A ) ( storage_5_0_0.bit3.bit Q ) + USE SIGNAL + + ROUTED met1 ( 4209 1479 ) ( 4255 * ) + NEW met1 ( 4209 1445 ) ( * 1479 ) NEW li1 ( 4255 1479 ) L1M1_PR_MR NEW li1 ( 4209 1445 ) L1M1_PR_MR ; - - storage_5_0.bit4.storage ( storage_5_0.bit4.obuf0 A ) ( storage_5_0.bit4.bit Q ) + USE SIGNAL - + ROUTED met1 ( 5405 1445 ) ( * 1479 ) - NEW met1 ( 5359 1445 ) ( 5405 * ) + - storage_5_0_0.bit4.storage ( storage_5_0_0.bit4.obuf0 A ) ( storage_5_0_0.bit4.bit Q ) + USE SIGNAL + + ROUTED met1 ( 5359 1479 ) ( 5405 * ) + NEW met1 ( 5359 1445 ) ( * 1479 ) NEW li1 ( 5405 1479 ) L1M1_PR_MR NEW li1 ( 5359 1445 ) L1M1_PR_MR ; - - storage_5_0.bit5.storage ( storage_5_0.bit5.obuf0 A ) ( storage_5_0.bit5.bit Q ) + USE SIGNAL - + ROUTED met1 ( 6555 1445 ) ( * 1479 ) - NEW met1 ( 6509 1445 ) ( 6555 * ) + - storage_5_0_0.bit5.storage ( storage_5_0_0.bit5.obuf0 A ) ( storage_5_0_0.bit5.bit Q ) + USE SIGNAL + + ROUTED met1 ( 6509 1479 ) ( 6555 * ) + NEW met1 ( 6509 1445 ) ( * 1479 ) NEW li1 ( 6555 1479 ) L1M1_PR_MR NEW li1 ( 6509 1445 ) L1M1_PR_MR ; - - storage_5_0.bit6.storage ( storage_5_0.bit6.obuf0 A ) ( storage_5_0.bit6.bit Q ) + USE SIGNAL - + ROUTED met1 ( 7705 1445 ) ( * 1479 ) - NEW met1 ( 7659 1445 ) ( 7705 * ) + - storage_5_0_0.bit6.storage ( storage_5_0_0.bit6.obuf0 A ) ( storage_5_0_0.bit6.bit Q ) + USE SIGNAL + + ROUTED met1 ( 7659 1479 ) ( 7705 * ) + NEW met1 ( 7659 1445 ) ( * 1479 ) NEW li1 ( 7705 1479 ) L1M1_PR_MR NEW li1 ( 7659 1445 ) L1M1_PR_MR ; - - storage_5_0.bit7.storage ( storage_5_0.bit7.obuf0 A ) ( storage_5_0.bit7.bit Q ) + USE SIGNAL - + ROUTED met1 ( 8855 1445 ) ( * 1479 ) - NEW met1 ( 8809 1445 ) ( 8855 * ) + - storage_5_0_0.bit7.storage ( storage_5_0_0.bit7.obuf0 A ) ( storage_5_0_0.bit7.bit Q ) + USE SIGNAL + + ROUTED met1 ( 8809 1479 ) ( 8855 * ) + NEW met1 ( 8809 1445 ) ( * 1479 ) NEW li1 ( 8855 1479 ) L1M1_PR_MR NEW li1 ( 8809 1445 ) L1M1_PR_MR ; - - storage_5_0.gclock ( storage_5_0.cg GCLK ) ( storage_5_0.bit7.bit CLK ) ( storage_5_0.bit6.bit CLK ) ( storage_5_0.bit5.bit CLK ) ( storage_5_0.bit4.bit CLK ) ( storage_5_0.bit3.bit CLK ) ( storage_5_0.bit2.bit CLK ) - ( storage_5_0.bit1.bit CLK ) ( storage_5_0.bit0.bit CLK ) + USE SIGNAL - + ROUTED met1 ( 1219 1513 ) ( 2369 * ) - NEW met1 ( 69 1513 ) ( 1219 * ) - NEW met1 ( 4669 1513 ) ( 5819 * ) - NEW met1 ( 3519 1513 ) ( 4669 * ) - NEW met1 ( 2369 1513 ) ( 3519 * ) - NEW met1 ( 6969 1411 ) ( * 1479 ) - NEW met1 ( 6601 1479 ) ( * 1513 ) - NEW met1 ( 6601 1479 ) ( 6969 * ) - NEW met1 ( 5819 1513 ) ( 6601 * ) - NEW met1 ( 8119 1411 ) ( * 1479 ) - NEW met1 ( 8119 1411 ) ( 9867 * ) - NEW met1 ( 6969 1411 ) ( 8119 * ) - NEW li1 ( 2369 1513 ) L1M1_PR_MR - NEW li1 ( 1219 1513 ) L1M1_PR_MR + - storage_5_0_0.gclock ( storage_5_0_0.cg GCLK ) ( storage_5_0_0.bit7.bit CLK ) ( storage_5_0_0.bit6.bit CLK ) ( storage_5_0_0.bit5.bit CLK ) ( storage_5_0_0.bit4.bit CLK ) ( storage_5_0_0.bit3.bit CLK ) ( storage_5_0_0.bit2.bit CLK ) + ( storage_5_0_0.bit1.bit CLK ) ( storage_5_0_0.bit0.bit CLK ) + USE SIGNAL + + ROUTED met1 ( 1219 1411 ) ( * 1479 ) + NEW met1 ( 69 1513 ) ( 851 * ) + NEW met1 ( 851 1479 ) ( * 1513 ) + NEW met1 ( 851 1479 ) ( 1219 * ) + NEW met1 ( 6969 1513 ) ( 7153 * ) + NEW met1 ( 7153 1513 ) ( * 1547 ) + NEW met1 ( 6969 1411 ) ( * 1513 ) + NEW met1 ( 2369 1411 ) ( * 1479 ) + NEW met1 ( 3519 1411 ) ( * 1479 ) + NEW met1 ( 2369 1411 ) ( 3519 * ) + NEW met1 ( 4669 1411 ) ( * 1479 ) + NEW met1 ( 3519 1411 ) ( 4669 * ) + NEW met1 ( 5819 1411 ) ( * 1479 ) + NEW met1 ( 4669 1411 ) ( 5819 * ) + NEW met1 ( 1219 1411 ) ( 2369 * ) + NEW met1 ( 5819 1411 ) ( 6969 * ) + NEW met1 ( 8119 1513 ) ( 9223 * ) + NEW met1 ( 9223 1513 ) ( * 1581 ) + NEW met1 ( 9223 1581 ) ( 9867 * ) + NEW met1 ( 8119 1513 ) ( * 1547 ) + NEW met1 ( 7153 1547 ) ( 8119 * ) + NEW li1 ( 1219 1479 ) L1M1_PR_MR NEW li1 ( 69 1513 ) L1M1_PR_MR - NEW li1 ( 5819 1513 ) L1M1_PR_MR - NEW li1 ( 4669 1513 ) L1M1_PR_MR - NEW li1 ( 3519 1513 ) L1M1_PR_MR - NEW li1 ( 6969 1479 ) L1M1_PR_MR - NEW li1 ( 8119 1479 ) L1M1_PR_MR - NEW li1 ( 9867 1411 ) L1M1_PR_MR ; - - storage_5_0.select0_b ( storage_5_0.select_inv_0 Y ) ( storage_5_0.bit7.obuf0 TE_B ) ( storage_5_0.bit6.obuf0 TE_B ) ( storage_5_0.bit5.obuf0 TE_B ) ( storage_5_0.bit4.obuf0 TE_B ) ( storage_5_0.bit3.obuf0 TE_B ) ( storage_5_0.bit2.obuf0 TE_B ) - ( storage_5_0.bit1.obuf0 TE_B ) ( storage_5_0.bit0.obuf0 TE_B ) + USE SIGNAL - + ROUTED met1 ( 2047 1411 ) ( * 1479 ) - NEW met1 ( 897 1411 ) ( 2047 * ) - NEW met1 ( 897 1411 ) ( * 1479 ) - NEW met1 ( 3197 1411 ) ( * 1479 ) - NEW met1 ( 2047 1411 ) ( 3197 * ) - NEW met1 ( 4347 1411 ) ( * 1479 ) - NEW met1 ( 5497 1411 ) ( * 1479 ) - NEW met1 ( 4347 1411 ) ( 5497 * ) - NEW met1 ( 3197 1411 ) ( 4347 * ) - NEW met2 ( 6647 1411 ) ( * 1513 ) - NEW met1 ( 5497 1411 ) ( 6647 * ) + NEW li1 ( 6969 1513 ) L1M1_PR_MR + NEW li1 ( 2369 1479 ) L1M1_PR_MR + NEW li1 ( 3519 1479 ) L1M1_PR_MR + NEW li1 ( 4669 1479 ) L1M1_PR_MR + NEW li1 ( 5819 1479 ) L1M1_PR_MR + NEW li1 ( 8119 1513 ) L1M1_PR_MR + NEW li1 ( 9867 1581 ) L1M1_PR_MR ; + - storage_5_0_0.select0_b ( storage_5_0_0.select_inv_0 Y ) ( storage_5_0_0.bit7.obuf0 TE_B ) ( storage_5_0_0.bit6.obuf0 TE_B ) ( storage_5_0_0.bit5.obuf0 TE_B ) ( storage_5_0_0.bit4.obuf0 TE_B ) ( storage_5_0_0.bit3.obuf0 TE_B ) ( storage_5_0_0.bit2.obuf0 TE_B ) + ( storage_5_0_0.bit1.obuf0 TE_B ) ( storage_5_0_0.bit0.obuf0 TE_B ) + USE SIGNAL + + ROUTED met1 ( 6647 1513 ) ( 6923 * ) + NEW met1 ( 6923 1513 ) ( * 1581 ) + NEW met1 ( 6210 1513 ) ( 6647 * ) + NEW met1 ( 5497 1513 ) ( * 1547 ) + NEW met1 ( 5497 1547 ) ( 6210 * ) + NEW met1 ( 6210 1513 ) ( * 1547 ) + NEW met1 ( 4347 1513 ) ( 5497 * ) + NEW met1 ( 3197 1513 ) ( 4347 * ) + NEW met1 ( 2047 1513 ) ( 3197 * ) + NEW met1 ( 897 1513 ) ( 2047 * ) NEW met1 ( 8947 1445 ) ( * 1479 ) NEW met1 ( 8947 1445 ) ( 10189 * ) - NEW met1 ( 7797 1513 ) ( * 1547 ) - NEW met1 ( 7797 1547 ) ( 8119 * ) - NEW met1 ( 8119 1547 ) ( * 1581 ) - NEW met1 ( 8119 1581 ) ( 8947 * ) - NEW met2 ( 8947 1479 ) ( * 1581 ) - NEW met1 ( 6647 1513 ) ( 7797 * ) - NEW li1 ( 2047 1479 ) L1M1_PR_MR - NEW li1 ( 897 1479 ) L1M1_PR_MR - NEW li1 ( 3197 1479 ) L1M1_PR_MR - NEW li1 ( 4347 1479 ) L1M1_PR_MR - NEW li1 ( 5497 1479 ) L1M1_PR_MR + NEW met1 ( 7797 1411 ) ( * 1479 ) + NEW met1 ( 7797 1411 ) ( 8947 * ) + NEW met1 ( 8947 1411 ) ( * 1445 ) + NEW met2 ( 7797 1479 ) ( * 1581 ) + NEW met1 ( 6923 1581 ) ( 7797 * ) + NEW li1 ( 897 1513 ) L1M1_PR_MR NEW li1 ( 6647 1513 ) L1M1_PR_MR - NEW met1 ( 6647 1411 ) M1M2_PR - NEW met1 ( 6647 1513 ) M1M2_PR + NEW li1 ( 5497 1513 ) L1M1_PR_MR + NEW li1 ( 4347 1513 ) L1M1_PR_MR + NEW li1 ( 3197 1513 ) L1M1_PR_MR + NEW li1 ( 2047 1513 ) L1M1_PR_MR NEW li1 ( 8947 1479 ) L1M1_PR_MR NEW li1 ( 10189 1445 ) L1M1_PR_MR - NEW li1 ( 7797 1513 ) L1M1_PR_MR - NEW met1 ( 8947 1581 ) M1M2_PR - NEW met1 ( 8947 1479 ) M1M2_PR ; - - storage_5_0.we0 ( storage_5_0.gcand X ) ( storage_5_0.cg GATE ) + USE SIGNAL - + ROUTED met1 ( 9453 1581 ) ( 10097 * ) - NEW li1 ( 9453 1581 ) L1M1_PR_MR - NEW li1 ( 10097 1581 ) L1M1_PR_MR ; - - storage_6_0.bit0.storage ( storage_6_0.bit0.obuf0 A ) ( storage_6_0.bit0.bit Q ) + USE SIGNAL + NEW li1 ( 7797 1479 ) L1M1_PR_MR + NEW met1 ( 7797 1581 ) M1M2_PR + NEW met1 ( 7797 1479 ) M1M2_PR ; + - storage_5_0_0.we0 ( storage_5_0_0.gcand X ) ( storage_5_0_0.cg GATE ) + USE SIGNAL + + ROUTED met2 ( 9453 1411 ) ( * 1479 ) + NEW met1 ( 9453 1411 ) ( 10097 * ) + NEW li1 ( 9453 1479 ) L1M1_PR_MR + NEW met1 ( 9453 1479 ) M1M2_PR + NEW met1 ( 9453 1411 ) M1M2_PR + NEW li1 ( 10097 1411 ) L1M1_PR_MR ; + - storage_6_0_0.bit0.storage ( storage_6_0_0.bit0.obuf0 A ) ( storage_6_0_0.bit0.bit Q ) + USE SIGNAL + ROUTED met1 ( 805 1785 ) ( * 1819 ) NEW met1 ( 759 1819 ) ( 805 * ) NEW li1 ( 805 1785 ) L1M1_PR_MR NEW li1 ( 759 1819 ) L1M1_PR_MR ; - - storage_6_0.bit1.storage ( storage_6_0.bit1.obuf0 A ) ( storage_6_0.bit1.bit Q ) + USE SIGNAL + - storage_6_0_0.bit1.storage ( storage_6_0_0.bit1.obuf0 A ) ( storage_6_0_0.bit1.bit Q ) + USE SIGNAL + ROUTED met1 ( 1955 1785 ) ( * 1819 ) NEW met1 ( 1909 1819 ) ( 1955 * ) NEW li1 ( 1955 1785 ) L1M1_PR_MR NEW li1 ( 1909 1819 ) L1M1_PR_MR ; - - storage_6_0.bit2.storage ( storage_6_0.bit2.obuf0 A ) ( storage_6_0.bit2.bit Q ) + USE SIGNAL + - storage_6_0_0.bit2.storage ( storage_6_0_0.bit2.obuf0 A ) ( storage_6_0_0.bit2.bit Q ) + USE SIGNAL + ROUTED met1 ( 3105 1785 ) ( * 1819 ) NEW met1 ( 3059 1819 ) ( 3105 * ) NEW li1 ( 3105 1785 ) L1M1_PR_MR NEW li1 ( 3059 1819 ) L1M1_PR_MR ; - - storage_6_0.bit3.storage ( storage_6_0.bit3.obuf0 A ) ( storage_6_0.bit3.bit Q ) + USE SIGNAL + - storage_6_0_0.bit3.storage ( storage_6_0_0.bit3.obuf0 A ) ( storage_6_0_0.bit3.bit Q ) + USE SIGNAL + ROUTED met1 ( 4255 1785 ) ( * 1819 ) NEW met1 ( 4209 1819 ) ( 4255 * ) NEW li1 ( 4255 1785 ) L1M1_PR_MR NEW li1 ( 4209 1819 ) L1M1_PR_MR ; - - storage_6_0.bit4.storage ( storage_6_0.bit4.obuf0 A ) ( storage_6_0.bit4.bit Q ) + USE SIGNAL + - storage_6_0_0.bit4.storage ( storage_6_0_0.bit4.obuf0 A ) ( storage_6_0_0.bit4.bit Q ) + USE SIGNAL + ROUTED met1 ( 5405 1785 ) ( * 1819 ) NEW met1 ( 5359 1819 ) ( 5405 * ) NEW li1 ( 5405 1785 ) L1M1_PR_MR NEW li1 ( 5359 1819 ) L1M1_PR_MR ; - - storage_6_0.bit5.storage ( storage_6_0.bit5.obuf0 A ) ( storage_6_0.bit5.bit Q ) + USE SIGNAL + - storage_6_0_0.bit5.storage ( storage_6_0_0.bit5.obuf0 A ) ( storage_6_0_0.bit5.bit Q ) + USE SIGNAL + ROUTED met1 ( 6555 1785 ) ( * 1819 ) NEW met1 ( 6509 1819 ) ( 6555 * ) NEW li1 ( 6555 1785 ) L1M1_PR_MR NEW li1 ( 6509 1819 ) L1M1_PR_MR ; - - storage_6_0.bit6.storage ( storage_6_0.bit6.obuf0 A ) ( storage_6_0.bit6.bit Q ) + USE SIGNAL + - storage_6_0_0.bit6.storage ( storage_6_0_0.bit6.obuf0 A ) ( storage_6_0_0.bit6.bit Q ) + USE SIGNAL + ROUTED met1 ( 7705 1785 ) ( * 1819 ) NEW met1 ( 7659 1819 ) ( 7705 * ) NEW li1 ( 7705 1785 ) L1M1_PR_MR NEW li1 ( 7659 1819 ) L1M1_PR_MR ; - - storage_6_0.bit7.storage ( storage_6_0.bit7.obuf0 A ) ( storage_6_0.bit7.bit Q ) + USE SIGNAL + - storage_6_0_0.bit7.storage ( storage_6_0_0.bit7.obuf0 A ) ( storage_6_0_0.bit7.bit Q ) + USE SIGNAL + ROUTED met1 ( 8855 1785 ) ( * 1819 ) NEW met1 ( 8809 1819 ) ( 8855 * ) NEW li1 ( 8855 1785 ) L1M1_PR_MR NEW li1 ( 8809 1819 ) L1M1_PR_MR ; - - storage_6_0.gclock ( storage_6_0.cg GCLK ) ( storage_6_0.bit7.bit CLK ) ( storage_6_0.bit6.bit CLK ) ( storage_6_0.bit5.bit CLK ) ( storage_6_0.bit4.bit CLK ) ( storage_6_0.bit3.bit CLK ) ( storage_6_0.bit2.bit CLK ) - ( storage_6_0.bit1.bit CLK ) ( storage_6_0.bit0.bit CLK ) + USE SIGNAL - + ROUTED met1 ( 2369 1785 ) ( * 1853 ) - NEW met1 ( 2369 1853 ) ( 3151 * ) - NEW met1 ( 3151 1785 ) ( * 1853 ) - NEW met1 ( 1219 1785 ) ( * 1853 ) - NEW met1 ( 1219 1853 ) ( 2001 * ) - NEW met1 ( 2001 1819 ) ( * 1853 ) - NEW met1 ( 2001 1819 ) ( 2369 * ) + - storage_6_0_0.gclock ( storage_6_0_0.cg GCLK ) ( storage_6_0_0.bit7.bit CLK ) ( storage_6_0_0.bit6.bit CLK ) ( storage_6_0_0.bit5.bit CLK ) ( storage_6_0_0.bit4.bit CLK ) ( storage_6_0_0.bit3.bit CLK ) ( storage_6_0_0.bit2.bit CLK ) + ( storage_6_0_0.bit1.bit CLK ) ( storage_6_0_0.bit0.bit CLK ) + USE SIGNAL + + ROUTED met1 ( 1219 1683 ) ( * 1751 ) NEW met1 ( 69 1717 ) ( * 1751 ) - NEW met1 ( 69 1717 ) ( 851 * ) - NEW met1 ( 851 1717 ) ( * 1785 ) - NEW met1 ( 851 1785 ) ( 1219 * ) - NEW met1 ( 4669 1785 ) ( * 1853 ) - NEW met1 ( 4669 1853 ) ( 5451 * ) - NEW met1 ( 5451 1819 ) ( * 1853 ) + NEW met1 ( 69 1717 ) ( 1219 * ) + NEW met1 ( 6969 1717 ) ( * 1751 ) + NEW met1 ( 6969 1683 ) ( * 1717 ) + NEW met1 ( 3381 1785 ) ( 3519 * ) + NEW met1 ( 3381 1785 ) ( * 1853 ) + NEW met1 ( 4485 1751 ) ( 4669 * ) + NEW met1 ( 4485 1751 ) ( * 1853 ) + NEW met1 ( 3519 1853 ) ( 4485 * ) NEW met1 ( 3519 1785 ) ( * 1853 ) - NEW met1 ( 3519 1853 ) ( 4301 * ) - NEW met1 ( 4301 1819 ) ( * 1853 ) - NEW met1 ( 4301 1819 ) ( 4669 * ) - NEW met1 ( 3151 1785 ) ( 3519 * ) - NEW met1 ( 6969 1751 ) ( 7015 * ) - NEW met1 ( 7015 1717 ) ( * 1751 ) - NEW met1 ( 5819 1785 ) ( * 1853 ) - NEW met1 ( 5819 1853 ) ( 6601 * ) - NEW met1 ( 6601 1819 ) ( * 1853 ) - NEW met1 ( 6601 1819 ) ( 6969 * ) - NEW met1 ( 6969 1751 ) ( * 1819 ) - NEW met1 ( 5451 1819 ) ( 5819 * ) + NEW met1 ( 4715 1717 ) ( * 1751 ) + NEW met1 ( 4669 1751 ) ( 4715 * ) + NEW met1 ( 5819 1683 ) ( * 1751 ) + NEW met1 ( 5819 1683 ) ( 6969 * ) + NEW met2 ( 2277 1683 ) ( * 1853 ) + NEW met1 ( 2369 1751 ) ( 2415 * ) + NEW met2 ( 2415 1683 ) ( * 1751 ) + NEW met1 ( 2277 1683 ) ( 2415 * ) + NEW met1 ( 1219 1683 ) ( 2277 * ) + NEW met1 ( 2277 1853 ) ( 3381 * ) + NEW met1 ( 5520 1751 ) ( 5819 * ) + NEW met1 ( 5520 1717 ) ( * 1751 ) + NEW met1 ( 4715 1717 ) ( 5520 * ) NEW met1 ( 8119 1683 ) ( * 1751 ) NEW met1 ( 8119 1683 ) ( 9867 * ) - NEW met1 ( 7015 1717 ) ( 8119 * ) - NEW li1 ( 2369 1785 ) L1M1_PR_MR - NEW li1 ( 1219 1785 ) L1M1_PR_MR + NEW met1 ( 6969 1717 ) ( 8119 * ) + NEW li1 ( 1219 1751 ) L1M1_PR_MR NEW li1 ( 69 1751 ) L1M1_PR_MR - NEW li1 ( 4669 1785 ) L1M1_PR_MR - NEW li1 ( 3519 1785 ) L1M1_PR_MR NEW li1 ( 6969 1751 ) L1M1_PR_MR - NEW li1 ( 5819 1785 ) L1M1_PR_MR + NEW li1 ( 3519 1785 ) L1M1_PR_MR + NEW li1 ( 4669 1751 ) L1M1_PR_MR + NEW li1 ( 5819 1751 ) L1M1_PR_MR + NEW met1 ( 2277 1683 ) M1M2_PR + NEW met1 ( 2277 1853 ) M1M2_PR + NEW li1 ( 2369 1751 ) L1M1_PR_MR + NEW met1 ( 2415 1751 ) M1M2_PR + NEW met1 ( 2415 1683 ) M1M2_PR NEW li1 ( 8119 1751 ) L1M1_PR_MR NEW li1 ( 9867 1683 ) L1M1_PR_MR ; - - storage_6_0.select0_b ( storage_6_0.select_inv_0 Y ) ( storage_6_0.bit7.obuf0 TE_B ) ( storage_6_0.bit6.obuf0 TE_B ) ( storage_6_0.bit5.obuf0 TE_B ) ( storage_6_0.bit4.obuf0 TE_B ) ( storage_6_0.bit3.obuf0 TE_B ) ( storage_6_0.bit2.obuf0 TE_B ) - ( storage_6_0.bit1.obuf0 TE_B ) ( storage_6_0.bit0.obuf0 TE_B ) + USE SIGNAL - + ROUTED met1 ( 2047 1717 ) ( * 1751 ) - NEW met1 ( 897 1717 ) ( 2047 * ) - NEW met1 ( 897 1717 ) ( * 1751 ) + - storage_6_0_0.select0_b ( storage_6_0_0.select_inv_0 Y ) ( storage_6_0_0.bit7.obuf0 TE_B ) ( storage_6_0_0.bit6.obuf0 TE_B ) ( storage_6_0_0.bit5.obuf0 TE_B ) ( storage_6_0_0.bit4.obuf0 TE_B ) ( storage_6_0_0.bit3.obuf0 TE_B ) ( storage_6_0_0.bit2.obuf0 TE_B ) + ( storage_6_0_0.bit1.obuf0 TE_B ) ( storage_6_0_0.bit0.obuf0 TE_B ) + USE SIGNAL + + ROUTED met1 ( 1265 1751 ) ( * 1785 ) + NEW met1 ( 897 1785 ) ( 1265 * ) + NEW met1 ( 6647 1785 ) ( 6877 * ) + NEW met1 ( 6877 1785 ) ( * 1853 ) + NEW met1 ( 6647 1717 ) ( * 1785 ) + NEW met1 ( 6210 1717 ) ( 6647 * ) + NEW met1 ( 5865 1751 ) ( * 1785 ) + NEW met1 ( 5865 1751 ) ( 6210 * ) + NEW met1 ( 6210 1717 ) ( * 1751 ) + NEW met1 ( 4347 1683 ) ( * 1751 ) NEW met1 ( 3197 1717 ) ( * 1751 ) - NEW met1 ( 2047 1717 ) ( 3197 * ) - NEW met1 ( 4347 1717 ) ( * 1751 ) - NEW met1 ( 5497 1717 ) ( * 1751 ) - NEW met1 ( 4347 1717 ) ( 5497 * ) NEW met1 ( 3197 1717 ) ( 4347 * ) - NEW met1 ( 6647 1717 ) ( * 1751 ) - NEW met1 ( 6647 1717 ) ( 6877 * ) - NEW met2 ( 6877 1717 ) ( * 1853 ) - NEW met1 ( 5497 1717 ) ( 6647 * ) + NEW met1 ( 1265 1751 ) ( 2047 * ) + NEW met2 ( 2323 1751 ) ( * 1802 ) + NEW met2 ( 2323 1802 ) ( 2461 * ) + NEW met2 ( 2461 1717 ) ( * 1802 ) + NEW met1 ( 2047 1751 ) ( 2323 * ) + NEW met1 ( 2461 1717 ) ( 3197 * ) + NEW met2 ( 5497 1683 ) ( * 1785 ) + NEW met1 ( 4347 1683 ) ( 5497 * ) + NEW met1 ( 5497 1785 ) ( 5865 * ) NEW met1 ( 8947 1785 ) ( * 1819 ) NEW met1 ( 8947 1819 ) ( 10189 * ) NEW met1 ( 7797 1785 ) ( 8119 * ) @@ -2317,123 +2353,129 @@ NETS 152 ; NEW met1 ( 8947 1819 ) ( * 1853 ) NEW met1 ( 7797 1785 ) ( * 1853 ) NEW met1 ( 6877 1853 ) ( 7797 * ) - NEW li1 ( 2047 1751 ) L1M1_PR_MR - NEW li1 ( 897 1751 ) L1M1_PR_MR - NEW li1 ( 3197 1751 ) L1M1_PR_MR + NEW li1 ( 897 1785 ) L1M1_PR_MR + NEW li1 ( 6647 1785 ) L1M1_PR_MR NEW li1 ( 4347 1751 ) L1M1_PR_MR - NEW li1 ( 5497 1751 ) L1M1_PR_MR - NEW li1 ( 6647 1751 ) L1M1_PR_MR - NEW met1 ( 6877 1717 ) M1M2_PR - NEW met1 ( 6877 1853 ) M1M2_PR + NEW li1 ( 3197 1751 ) L1M1_PR_MR + NEW li1 ( 2047 1751 ) L1M1_PR_MR + NEW met1 ( 2323 1751 ) M1M2_PR + NEW met1 ( 2461 1717 ) M1M2_PR + NEW met1 ( 5497 1785 ) M1M2_PR + NEW met1 ( 5497 1683 ) M1M2_PR + NEW li1 ( 5497 1785 ) L1M1_PR_MR NEW li1 ( 8947 1785 ) L1M1_PR_MR NEW li1 ( 10189 1819 ) L1M1_PR_MR - NEW li1 ( 7797 1785 ) L1M1_PR_MR ; - - storage_6_0.we0 ( storage_6_0.gcand X ) ( storage_6_0.cg GATE ) + USE SIGNAL + NEW li1 ( 7797 1785 ) L1M1_PR_MR + NEW met1 ( 5497 1785 ) RECT ( -35 -7 0 7 ) ; + - storage_6_0_0.we0 ( storage_6_0_0.gcand X ) ( storage_6_0_0.cg GATE ) + USE SIGNAL + ROUTED met1 ( 9453 1785 ) ( 9821 * ) NEW met1 ( 9821 1717 ) ( * 1785 ) NEW met1 ( 9821 1717 ) ( 10097 * ) NEW li1 ( 9453 1785 ) L1M1_PR_MR NEW li1 ( 10097 1717 ) L1M1_PR_MR ; - - storage_7_0.bit0.storage ( storage_7_0.bit0.obuf0 A ) ( storage_7_0.bit0.bit Q ) + USE SIGNAL - + ROUTED met1 ( 805 1989 ) ( * 2023 ) - NEW met1 ( 759 1989 ) ( 805 * ) + - storage_7_0_0.bit0.storage ( storage_7_0_0.bit0.obuf0 A ) ( storage_7_0_0.bit0.bit Q ) + USE SIGNAL + + ROUTED met1 ( 759 2023 ) ( 805 * ) + NEW met1 ( 759 1989 ) ( * 2023 ) NEW li1 ( 805 2023 ) L1M1_PR_MR NEW li1 ( 759 1989 ) L1M1_PR_MR ; - - storage_7_0.bit1.storage ( storage_7_0.bit1.obuf0 A ) ( storage_7_0.bit1.bit Q ) + USE SIGNAL - + ROUTED met1 ( 1955 1989 ) ( * 2023 ) - NEW met1 ( 1909 1989 ) ( 1955 * ) + - storage_7_0_0.bit1.storage ( storage_7_0_0.bit1.obuf0 A ) ( storage_7_0_0.bit1.bit Q ) + USE SIGNAL + + ROUTED met1 ( 1909 2023 ) ( 1955 * ) + NEW met1 ( 1909 1989 ) ( * 2023 ) NEW li1 ( 1955 2023 ) L1M1_PR_MR NEW li1 ( 1909 1989 ) L1M1_PR_MR ; - - storage_7_0.bit2.storage ( storage_7_0.bit2.obuf0 A ) ( storage_7_0.bit2.bit Q ) + USE SIGNAL - + ROUTED met1 ( 3105 1989 ) ( * 2023 ) - NEW met1 ( 3059 1989 ) ( 3105 * ) + - storage_7_0_0.bit2.storage ( storage_7_0_0.bit2.obuf0 A ) ( storage_7_0_0.bit2.bit Q ) + USE SIGNAL + + ROUTED met1 ( 3059 2023 ) ( 3105 * ) + NEW met1 ( 3059 1989 ) ( * 2023 ) NEW li1 ( 3105 2023 ) L1M1_PR_MR NEW li1 ( 3059 1989 ) L1M1_PR_MR ; - - storage_7_0.bit3.storage ( storage_7_0.bit3.obuf0 A ) ( storage_7_0.bit3.bit Q ) + USE SIGNAL - + ROUTED met1 ( 4255 1989 ) ( * 2023 ) - NEW met1 ( 4209 1989 ) ( 4255 * ) + - storage_7_0_0.bit3.storage ( storage_7_0_0.bit3.obuf0 A ) ( storage_7_0_0.bit3.bit Q ) + USE SIGNAL + + ROUTED met1 ( 4209 2023 ) ( 4255 * ) + NEW met1 ( 4209 1989 ) ( * 2023 ) NEW li1 ( 4255 2023 ) L1M1_PR_MR NEW li1 ( 4209 1989 ) L1M1_PR_MR ; - - storage_7_0.bit4.storage ( storage_7_0.bit4.obuf0 A ) ( storage_7_0.bit4.bit Q ) + USE SIGNAL - + ROUTED met1 ( 5405 1989 ) ( * 2023 ) - NEW met1 ( 5359 1989 ) ( 5405 * ) + - storage_7_0_0.bit4.storage ( storage_7_0_0.bit4.obuf0 A ) ( storage_7_0_0.bit4.bit Q ) + USE SIGNAL + + ROUTED met1 ( 5359 2023 ) ( 5405 * ) + NEW met1 ( 5359 1989 ) ( * 2023 ) NEW li1 ( 5405 2023 ) L1M1_PR_MR NEW li1 ( 5359 1989 ) L1M1_PR_MR ; - - storage_7_0.bit5.storage ( storage_7_0.bit5.obuf0 A ) ( storage_7_0.bit5.bit Q ) + USE SIGNAL - + ROUTED met1 ( 6555 1989 ) ( * 2023 ) - NEW met1 ( 6509 1989 ) ( 6555 * ) + - storage_7_0_0.bit5.storage ( storage_7_0_0.bit5.obuf0 A ) ( storage_7_0_0.bit5.bit Q ) + USE SIGNAL + + ROUTED met1 ( 6509 2023 ) ( 6555 * ) + NEW met1 ( 6509 1989 ) ( * 2023 ) NEW li1 ( 6555 2023 ) L1M1_PR_MR NEW li1 ( 6509 1989 ) L1M1_PR_MR ; - - storage_7_0.bit6.storage ( storage_7_0.bit6.obuf0 A ) ( storage_7_0.bit6.bit Q ) + USE SIGNAL - + ROUTED met1 ( 7705 1989 ) ( * 2023 ) - NEW met1 ( 7659 1989 ) ( 7705 * ) + - storage_7_0_0.bit6.storage ( storage_7_0_0.bit6.obuf0 A ) ( storage_7_0_0.bit6.bit Q ) + USE SIGNAL + + ROUTED met1 ( 7659 2023 ) ( 7705 * ) + NEW met1 ( 7659 1989 ) ( * 2023 ) NEW li1 ( 7705 2023 ) L1M1_PR_MR NEW li1 ( 7659 1989 ) L1M1_PR_MR ; - - storage_7_0.bit7.storage ( storage_7_0.bit7.obuf0 A ) ( storage_7_0.bit7.bit Q ) + USE SIGNAL - + ROUTED met1 ( 8855 1989 ) ( * 2023 ) - NEW met1 ( 8809 1989 ) ( 8855 * ) + - storage_7_0_0.bit7.storage ( storage_7_0_0.bit7.obuf0 A ) ( storage_7_0_0.bit7.bit Q ) + USE SIGNAL + + ROUTED met1 ( 8809 2023 ) ( 8855 * ) + NEW met1 ( 8809 1989 ) ( * 2023 ) NEW li1 ( 8855 2023 ) L1M1_PR_MR NEW li1 ( 8809 1989 ) L1M1_PR_MR ; - - storage_7_0.gclock ( storage_7_0.cg GCLK ) ( storage_7_0.bit7.bit CLK ) ( storage_7_0.bit6.bit CLK ) ( storage_7_0.bit5.bit CLK ) ( storage_7_0.bit4.bit CLK ) ( storage_7_0.bit3.bit CLK ) ( storage_7_0.bit2.bit CLK ) - ( storage_7_0.bit1.bit CLK ) ( storage_7_0.bit0.bit CLK ) + USE SIGNAL - + ROUTED met1 ( 2369 1955 ) ( * 2023 ) - NEW met1 ( 1219 1955 ) ( * 2023 ) - NEW met1 ( 1219 1955 ) ( 2369 * ) + - storage_7_0_0.gclock ( storage_7_0_0.cg GCLK ) ( storage_7_0_0.bit7.bit CLK ) ( storage_7_0_0.bit6.bit CLK ) ( storage_7_0_0.bit5.bit CLK ) ( storage_7_0_0.bit4.bit CLK ) ( storage_7_0_0.bit3.bit CLK ) ( storage_7_0_0.bit2.bit CLK ) + ( storage_7_0_0.bit1.bit CLK ) ( storage_7_0_0.bit0.bit CLK ) + USE SIGNAL + + ROUTED met1 ( 1219 1955 ) ( * 2023 ) NEW met1 ( 69 1955 ) ( * 2023 ) NEW met1 ( 69 1955 ) ( 1219 * ) - NEW met1 ( 5819 1955 ) ( * 2023 ) + NEW met1 ( 6969 1955 ) ( * 2023 ) + NEW met1 ( 2369 1955 ) ( * 2023 ) + NEW met1 ( 3519 1955 ) ( * 2023 ) + NEW met1 ( 2369 1955 ) ( 3519 * ) NEW met1 ( 4669 1955 ) ( * 2023 ) + NEW met1 ( 3519 1955 ) ( 4669 * ) + NEW met1 ( 5819 1955 ) ( * 2023 ) NEW met1 ( 4669 1955 ) ( 5819 * ) - NEW met1 ( 3519 1955 ) ( * 2023 ) - NEW met1 ( 2369 1955 ) ( 4669 * ) - NEW met1 ( 6969 1955 ) ( * 2023 ) + NEW met1 ( 1219 1955 ) ( 2369 * ) NEW met1 ( 5819 1955 ) ( 6969 * ) NEW met1 ( 8119 1955 ) ( * 2023 ) NEW met1 ( 8119 1955 ) ( 9867 * ) NEW met1 ( 6969 1955 ) ( 8119 * ) - NEW li1 ( 2369 2023 ) L1M1_PR_MR NEW li1 ( 1219 2023 ) L1M1_PR_MR NEW li1 ( 69 2023 ) L1M1_PR_MR - NEW li1 ( 5819 2023 ) L1M1_PR_MR - NEW li1 ( 4669 2023 ) L1M1_PR_MR - NEW li1 ( 3519 2023 ) L1M1_PR_MR NEW li1 ( 6969 2023 ) L1M1_PR_MR + NEW li1 ( 2369 2023 ) L1M1_PR_MR + NEW li1 ( 3519 2023 ) L1M1_PR_MR + NEW li1 ( 4669 2023 ) L1M1_PR_MR + NEW li1 ( 5819 2023 ) L1M1_PR_MR NEW li1 ( 8119 2023 ) L1M1_PR_MR NEW li1 ( 9867 1955 ) L1M1_PR_MR ; - - storage_7_0.select0_b ( storage_7_0.select_inv_0 Y ) ( storage_7_0.bit7.obuf0 TE_B ) ( storage_7_0.bit6.obuf0 TE_B ) ( storage_7_0.bit5.obuf0 TE_B ) ( storage_7_0.bit4.obuf0 TE_B ) ( storage_7_0.bit3.obuf0 TE_B ) ( storage_7_0.bit2.obuf0 TE_B ) - ( storage_7_0.bit1.obuf0 TE_B ) ( storage_7_0.bit0.obuf0 TE_B ) + USE SIGNAL - + ROUTED met1 ( 2047 2057 ) ( * 2091 ) - NEW met1 ( 897 2091 ) ( 2047 * ) - NEW met1 ( 897 2057 ) ( * 2091 ) + - storage_7_0_0.select0_b ( storage_7_0_0.select_inv_0 Y ) ( storage_7_0_0.bit7.obuf0 TE_B ) ( storage_7_0_0.bit6.obuf0 TE_B ) ( storage_7_0_0.bit5.obuf0 TE_B ) ( storage_7_0_0.bit4.obuf0 TE_B ) ( storage_7_0_0.bit3.obuf0 TE_B ) ( storage_7_0_0.bit2.obuf0 TE_B ) + ( storage_7_0_0.bit1.obuf0 TE_B ) ( storage_7_0_0.bit0.obuf0 TE_B ) + USE SIGNAL + + ROUTED met1 ( 897 2057 ) ( * 2091 ) + NEW met1 ( 6647 2057 ) ( * 2091 ) + NEW met1 ( 6210 2057 ) ( 6647 * ) + NEW met1 ( 2047 2057 ) ( * 2091 ) NEW met1 ( 3197 2057 ) ( * 2091 ) NEW met1 ( 2047 2091 ) ( 3197 * ) NEW met1 ( 4347 2057 ) ( * 2091 ) + NEW met1 ( 3197 2091 ) ( 4347 * ) NEW met1 ( 5497 2057 ) ( * 2091 ) NEW met1 ( 4347 2091 ) ( 5497 * ) - NEW met1 ( 3197 2091 ) ( 4347 * ) - NEW met1 ( 6647 2057 ) ( * 2091 ) - NEW met1 ( 5497 2057 ) ( 6647 * ) + NEW met1 ( 6210 2057 ) ( * 2091 ) + NEW met1 ( 5497 2091 ) ( 6210 * ) + NEW met1 ( 897 2091 ) ( 2047 * ) NEW met1 ( 8947 1989 ) ( * 2023 ) NEW met1 ( 8947 1989 ) ( 10189 * ) NEW met1 ( 7797 2057 ) ( * 2091 ) NEW met1 ( 7797 2091 ) ( 8947 * ) NEW met1 ( 8947 2023 ) ( * 2091 ) NEW met1 ( 6647 2091 ) ( 7797 * ) - NEW li1 ( 2047 2057 ) L1M1_PR_MR NEW li1 ( 897 2057 ) L1M1_PR_MR + NEW li1 ( 6647 2057 ) L1M1_PR_MR + NEW li1 ( 2047 2057 ) L1M1_PR_MR NEW li1 ( 3197 2057 ) L1M1_PR_MR NEW li1 ( 4347 2057 ) L1M1_PR_MR NEW li1 ( 5497 2057 ) L1M1_PR_MR - NEW li1 ( 6647 2057 ) L1M1_PR_MR NEW li1 ( 8947 2023 ) L1M1_PR_MR NEW li1 ( 10189 1989 ) L1M1_PR_MR NEW li1 ( 7797 2057 ) L1M1_PR_MR ; - - storage_7_0.we0 ( storage_7_0.gcand X ) ( storage_7_0.cg GATE ) + USE SIGNAL + - storage_7_0_0.we0 ( storage_7_0_0.gcand X ) ( storage_7_0_0.cg GATE ) + USE SIGNAL + ROUTED met1 ( 9453 2125 ) ( 10097 * ) NEW li1 ( 9453 2125 ) L1M1_PR_MR NEW li1 ( 10097 2125 ) L1M1_PR_MR ; - - we[0] ( PIN we[0] ) ( storage_7_0.gcand B ) ( storage_6_0.gcand B ) ( storage_5_0.gcand B ) ( storage_4_0.gcand B ) ( storage_3_0.gcand B ) ( storage_2_0.gcand B ) - ( storage_1_0.gcand B ) ( storage_0_0.gcand B ) + USE SIGNAL + - we[0] ( PIN we[0] ) ( storage_7_0_0.gcand B ) ( storage_6_0_0.gcand B ) ( storage_5_0_0.gcand B ) ( storage_4_0_0.gcand B ) ( storage_3_0_0.gcand B ) ( storage_2_0_0.gcand B ) + ( storage_1_0_0.gcand B ) ( storage_0_0_0.gcand B ) + USE SIGNAL + ROUTED met1 ( 10005 391 ) ( 10097 * ) NEW met2 ( 10097 306 ) ( * 391 ) NEW met3 ( 10097 306 ) ( 10994 * 0 ) diff --git a/src/ram/test/make_8x8.lefok b/src/ram/test/make_8x8.lefok index d406ace593c..d7b72865189 100644 --- a/src/ram/test/make_8x8.lefok +++ b/src/ram/test/make_8x8.lefok @@ -25,30 +25,30 @@ MACRO RAM8x8 RECT 109.6 2.91 110.4 3.21 ; END END we[0] - PIN addr[0] + PIN addr_rw[0] DIRECTION INPUT ; USE SIGNAL ; PORT LAYER met3 ; RECT 109.6 4.27 110.4 4.57 ; END - END addr[0] - PIN addr[1] + END addr_rw[0] + PIN addr_rw[1] DIRECTION INPUT ; USE SIGNAL ; PORT LAYER met3 ; RECT 109.6 6.99 110.4 7.29 ; END - END addr[1] - PIN addr[2] + END addr_rw[1] + PIN addr_rw[2] DIRECTION INPUT ; USE SIGNAL ; PORT LAYER met3 ; RECT 109.6 5.63 110.4 5.93 ; END - END addr[2] + END addr_rw[2] PIN D[0] DIRECTION INPUT ; USE SIGNAL ; @@ -235,19 +235,18 @@ MACRO RAM8x8 LAYER met1 ; RECT 0 -0.24 110.4 24.72 ; LAYER met2 ; - RECT 59.76 0 60.24 0.35 ; - RECT 19.76 0 20.24 0.69 ; - RECT 13.44 0.69 20.24 1.03 ; + RECT 59.76 0 60.24 0.27 ; + RECT 57.66 0.27 60.24 0.35 ; + RECT 19.76 0 20.24 1.03 ; RECT 39.76 -0.24 40.24 1.03 ; - RECT 69.56 0.35 69.82 1.03 ; + RECT 57.14 0.35 60.24 1.03 ; RECT 79.76 -0.24 80.24 1.03 ; RECT 99.76 0 100.24 1.03 ; RECT 97.62 1.03 109.38 1.37 ; RECT 1.94 1.03 2.2 2.05 ; - RECT 12.06 1.03 25.2 2.05 ; - RECT 36.44 1.03 48.2 2.05 ; - RECT 58.06 0.35 60.24 2.05 ; - RECT 69.56 1.03 82.7 2.05 ; + RECT 13.44 1.03 25.2 2.05 ; + RECT 36.44 1.03 60.24 2.05 ; + RECT 70.94 1.03 82.7 2.05 ; RECT 94.4 1.37 109.38 2.05 ; RECT 1.94 2.05 109.38 5.595 ; RECT 1.94 5.595 109.39 10.21 ; diff --git a/src/ram/test/make_8x8.ok b/src/ram/test/make_8x8.ok index 427bf80537e..d053c4cbda4 100644 --- a/src/ram/test/make_8x8.ok +++ b/src/ram/test/make_8x8.ok @@ -6,6 +6,7 @@ [INFO RAM-0016] Selected and2 cell sky130_fd_sc_hd__and2_0 [INFO RAM-0016] Selected clock gate cell sky130_fd_sc_hd__dlclkp_1 [INFO RAM-0016] Selected buffer cell sky130_fd_sc_hd__buf_1 +[INFO RAM-0016] Selected aoi22 cell sky130_fd_sc_hd__a22oi_1 [INFO RAM-0024] Behavioral Verilog written for RAM8x8 [INFO PDN-0001] Inserting grid: ram_grid [INFO PPL-0067] Restrict pins [ D[0] Q[0] D[1] Q[1] D[2] ... ] to region 0.00u-110.40u at the TOP edge. @@ -55,9 +56,9 @@ [INFO DRT-0036] FR_VIA guide region query size = 0. [INFO DRT-0036] li1 guide region query size = 334. [INFO DRT-0036] mcon guide region query size = 0. -[INFO DRT-0036] met1 guide region query size = 216. +[INFO DRT-0036] met1 guide region query size = 214. [INFO DRT-0036] via guide region query size = 0. -[INFO DRT-0036] met2 guide region query size = 49. +[INFO DRT-0036] met2 guide region query size = 57. [INFO DRT-0036] via2 guide region query size = 0. [INFO DRT-0036] met3 guide region query size = 5. [INFO DRT-0036] via3 guide region query size = 0. diff --git a/src/ram/test/make_8x8.tcl b/src/ram/test/make_8x8.tcl index 73d78b0a724..b72e2ebca0f 100644 --- a/src/ram/test/make_8x8.tcl +++ b/src/ram/test/make_8x8.tcl @@ -13,6 +13,7 @@ generate_ram \ -mask_size 8 \ -word_size 8 \ -num_words 8 \ + -column_mux_ratio 1 \ -read_ports 1 \ -storage_cell sky130_fd_sc_hd__dfxtp_1 \ -power_pin VPWR \ diff --git a/src/ram/test/make_8x8_mux2.lefok b/src/ram/test/make_8x8_mux2.lefok new file mode 100644 index 00000000000..c62ebaa6b76 --- /dev/null +++ b/src/ram/test/make_8x8_mux2.lefok @@ -0,0 +1,373 @@ +VERSION 5.8 ; +BUSBITCHARS "[]" ; +DIVIDERCHAR "/" ; +UNITS + DATABASE MICRONS 1000 ; +END UNITS + +MACRO RAM8x8 + FOREIGN RAM8x8 0 0 ; + CLASS BLOCK ; + SIZE 215.28 BY 13.6 ; + PIN clk + DIRECTION INPUT ; + USE SIGNAL ; + PORT + LAYER met2 ; + RECT 187.84 0 187.98 0.485 ; + END + END clk + PIN we[0] + DIRECTION INPUT ; + USE SIGNAL ; + PORT + LAYER met2 ; + RECT 194.28 0 194.42 0.485 ; + END + END we[0] + PIN addr_rw[0] + DIRECTION INPUT ; + USE SIGNAL ; + PORT + LAYER met2 ; + RECT 13.04 0 13.18 0.485 ; + END + END addr_rw[0] + PIN addr_rw[1] + DIRECTION INPUT ; + USE SIGNAL ; + PORT + LAYER met3 ; + RECT 214.48 6.99 215.28 7.29 ; + END + END addr_rw[1] + PIN addr_rw[2] + DIRECTION INPUT ; + USE SIGNAL ; + PORT + LAYER met3 ; + RECT 214.48 1.55 215.28 1.85 ; + END + END addr_rw[2] + PIN D[0] + DIRECTION INPUT ; + USE SIGNAL ; + PORT + LAYER met2 ; + RECT 2 13.115 2.14 13.6 ; + END + END D[0] + PIN Q[0] + DIRECTION OUTPUT ; + USE SIGNAL ; + PORT + LAYER met2 ; + RECT 15.8 13.115 15.94 13.6 ; + END + END Q[0] + PIN D[1] + DIRECTION INPUT ; + USE SIGNAL ; + PORT + LAYER met2 ; + RECT 24.08 13.115 24.22 13.6 ; + END + END D[1] + PIN Q[1] + DIRECTION OUTPUT ; + USE SIGNAL ; + PORT + LAYER met2 ; + RECT 26.84 13.115 26.98 13.6 ; + END + END Q[1] + PIN D[2] + DIRECTION INPUT ; + USE SIGNAL ; + PORT + LAYER met2 ; + RECT 27.76 13.115 27.9 13.6 ; + END + END D[2] + PIN Q[2] + DIRECTION OUTPUT ; + USE SIGNAL ; + PORT + LAYER met2 ; + RECT 28.68 13.115 28.82 13.6 ; + END + END Q[2] + PIN D[3] + DIRECTION INPUT ; + USE SIGNAL ; + PORT + LAYER met2 ; + RECT 69.16 13.115 69.3 13.6 ; + END + END D[3] + PIN Q[3] + DIRECTION OUTPUT ; + USE SIGNAL ; + PORT + LAYER met2 ; + RECT 84.8 13.115 84.94 13.6 ; + END + END Q[3] + PIN D[4] + DIRECTION INPUT ; + USE SIGNAL ; + PORT + LAYER met2 ; + RECT 93.08 13.115 93.22 13.6 ; + END + END D[4] + PIN Q[4] + DIRECTION OUTPUT ; + USE SIGNAL ; + PORT + LAYER met2 ; + RECT 107.8 13.115 107.94 13.6 ; + END + END Q[4] + PIN D[5] + DIRECTION INPUT ; + USE SIGNAL ; + PORT + LAYER met2 ; + RECT 116.08 13.115 116.22 13.6 ; + END + END D[5] + PIN Q[5] + DIRECTION OUTPUT ; + USE SIGNAL ; + PORT + LAYER met2 ; + RECT 130.8 13.115 130.94 13.6 ; + END + END Q[5] + PIN D[6] + DIRECTION INPUT ; + USE SIGNAL ; + PORT + LAYER met2 ; + RECT 139.08 13.115 139.22 13.6 ; + END + END D[6] + PIN Q[6] + DIRECTION OUTPUT ; + USE SIGNAL ; + PORT + LAYER met2 ; + RECT 153.8 13.115 153.94 13.6 ; + END + END Q[6] + PIN D[7] + DIRECTION INPUT ; + USE SIGNAL ; + PORT + LAYER met2 ; + RECT 162.08 13.115 162.22 13.6 ; + END + END D[7] + PIN Q[7] + DIRECTION OUTPUT ; + USE SIGNAL ; + PORT + LAYER met2 ; + RECT 176.8 13.115 176.94 13.6 ; + END + END Q[7] + PIN VSS + DIRECTION INOUT ; + USE GROUND ; + PORT + LAYER met3 ; + RECT 214.98 9.76 215.28 10.24 ; + RECT 0 9.76 0.3 10.24 ; + LAYER met2 ; + RECT 199.76 13.46 200.24 13.6 ; + RECT 199.76 0 200.24 0.14 ; + RECT 179.76 13.46 180.24 13.6 ; + RECT 179.76 0 180.24 0.14 ; + RECT 159.76 13.46 160.24 13.6 ; + RECT 159.76 0 160.24 0.14 ; + RECT 139.76 13.46 140.24 13.6 ; + RECT 139.76 0 140.24 0.14 ; + RECT 119.76 13.46 120.24 13.6 ; + RECT 119.76 0 120.24 0.14 ; + RECT 99.76 13.46 100.24 13.6 ; + RECT 99.76 0 100.24 0.14 ; + RECT 79.76 13.46 80.24 13.6 ; + RECT 79.76 0 80.24 0.14 ; + RECT 59.76 13.46 60.24 13.6 ; + RECT 59.76 0 60.24 0.14 ; + RECT 39.76 13.46 40.24 13.6 ; + RECT 39.76 0 40.24 0.14 ; + RECT 19.76 13.46 20.24 13.6 ; + RECT 19.76 0 20.24 0.14 ; + LAYER met1 ; + RECT 215.14 10.64 215.28 11.12 ; + RECT 0 10.64 0.14 11.12 ; + RECT 215.14 5.2 215.28 5.68 ; + RECT 0 5.2 0.14 5.68 ; + RECT 215.14 -0.24 215.28 0.24 ; + RECT 0 -0.24 0.14 0.24 ; + END + END VSS + PIN VDD + DIRECTION INOUT ; + USE POWER ; + PORT + LAYER met3 ; + RECT 214.98 4.76 215.28 5.24 ; + RECT 0 4.76 0.3 5.24 ; + LAYER met2 ; + RECT 209.76 13.46 210.24 13.6 ; + RECT 209.76 0 210.24 0.14 ; + RECT 189.76 13.46 190.24 13.6 ; + RECT 189.76 0 190.24 0.14 ; + RECT 169.76 13.46 170.24 13.6 ; + RECT 169.76 0 170.24 0.14 ; + RECT 149.76 13.46 150.24 13.6 ; + RECT 149.76 0 150.24 0.14 ; + RECT 129.76 13.46 130.24 13.6 ; + RECT 129.76 0 130.24 0.14 ; + RECT 109.76 13.46 110.24 13.6 ; + RECT 109.76 0 110.24 0.14 ; + RECT 89.76 13.46 90.24 13.6 ; + RECT 89.76 0 90.24 0.14 ; + RECT 69.76 13.46 70.24 13.6 ; + RECT 69.76 0 70.24 0.14 ; + RECT 49.76 13.46 50.24 13.6 ; + RECT 49.76 0 50.24 0.14 ; + RECT 29.76 13.46 30.24 13.6 ; + RECT 29.76 0 30.24 0.14 ; + RECT 9.76 13.46 10.24 13.6 ; + RECT 9.76 0 10.24 0.14 ; + LAYER met1 ; + RECT 215.14 13.36 215.28 13.84 ; + RECT 0 13.36 0.14 13.84 ; + RECT 215.14 7.92 215.28 8.4 ; + RECT 0 7.92 0.14 8.4 ; + RECT 215.14 2.48 215.28 2.96 ; + RECT 0 2.48 0.14 2.96 ; + END + END VDD + OBS + LAYER li1 ; + RECT 0 -0.085 215.28 13.685 ; + LAYER met1 ; + RECT 0 -0.24 215.28 13.84 ; + LAYER met2 ; + RECT 49.76 0 50.24 0.155 ; + RECT 59.76 -0.24 60.24 0.155 ; + RECT 139.76 -0.24 140.24 0.155 ; + RECT 149.76 0 150.24 0.155 ; + RECT 159.76 -0.24 160.24 0.155 ; + RECT 169.76 0 170.24 0.155 ; + RECT 179.76 -0.24 180.24 0.155 ; + RECT 9.76 0 10.24 0.34 ; + RECT 19.76 -0.24 20.24 0.34 ; + RECT 159.76 0.155 180.24 0.34 ; + RECT 189.76 0 190.24 0.34 ; + RECT 199.76 -0.24 200.24 0.34 ; + RECT 29.76 0 30.24 0.35 ; + RECT 39.76 -0.24 40.24 0.35 ; + RECT 129.76 0 130.24 0.35 ; + RECT 139.76 0.155 150.24 0.35 ; + RECT 159.76 0.34 200.24 0.35 ; + RECT 209.76 0 210.24 0.35 ; + RECT 9.76 0.34 20.24 0.69 ; + RECT 29.76 0.35 40.24 0.69 ; + RECT 49.76 0.155 60.24 0.69 ; + RECT 69.76 0 70.24 0.69 ; + RECT 79.76 -0.24 80.24 0.69 ; + RECT 99.76 -0.24 100.24 0.69 ; + RECT 109.76 0 110.24 0.69 ; + RECT 119.76 -0.24 120.24 0.69 ; + RECT 129.76 0.35 150.24 0.69 ; + RECT 89.76 0 90.24 0.835 ; + RECT 99.76 0.69 150.24 0.835 ; + RECT 1.94 0.69 20.24 1.03 ; + RECT 29.76 0.69 80.24 1.03 ; + RECT 89.76 0.835 150.24 1.03 ; + RECT 159.76 0.35 210.24 1.03 ; + RECT 1.94 1.03 214.26 1.515 ; + RECT 1.94 1.515 214.27 7.325 ; + RECT 1.94 7.325 214.26 7.47 ; + RECT 1.94 7.47 213.8 9.51 ; + RECT 1.94 9.51 211.96 11.55 ; + RECT 1.94 11.55 70.24 12.23 ; + RECT 199.76 11.55 211.96 12.23 ; + RECT 39.76 12.23 70.24 12.765 ; + RECT 199.76 12.23 211.5 12.91 ; + RECT 39.76 12.765 50.24 13.25 ; + RECT 79.76 11.55 180.24 13.25 ; + RECT 2 12.23 30.24 13.26 ; + RECT 59.76 12.765 70.24 13.26 ; + RECT 79.76 13.25 120.24 13.26 ; + RECT 129.76 13.25 140.24 13.26 ; + RECT 149.76 13.25 180.24 13.26 ; + RECT 19.76 13.26 20.24 13.6 ; + RECT 39.76 13.25 40.24 13.6 ; + RECT 59.76 13.26 60.24 13.6 ; + RECT 79.76 13.26 80.24 13.6 ; + RECT 99.76 13.26 100.24 13.6 ; + RECT 119.76 13.26 120.24 13.6 ; + RECT 139.76 13.26 140.24 13.6 ; + RECT 159.76 13.26 160.24 13.6 ; + RECT 179.76 13.26 180.24 13.6 ; + RECT 199.76 12.91 200.24 13.6 ; + RECT 9.76 13.26 10.24 13.84 ; + RECT 29.76 13.26 30.24 13.84 ; + RECT 49.76 13.25 50.24 13.84 ; + RECT 69.76 13.26 70.24 13.84 ; + RECT 89.76 13.26 90.24 13.84 ; + RECT 109.76 13.26 110.24 13.84 ; + RECT 129.76 13.26 130.24 13.84 ; + RECT 149.76 13.26 150.24 13.84 ; + RECT 169.76 13.26 170.24 13.84 ; + RECT 189.76 11.55 190.24 13.84 ; + RECT 209.76 12.91 210.24 13.84 ; + LAYER met3 ; + RECT 0 4.76 8.805 10.24 ; + RECT 8.805 4.76 9.135 11.385 ; + RECT 9.135 4.76 23.065 11.37 ; + RECT 23.065 1.535 31.805 11.37 ; + RECT 31.805 0.855 32.135 11.385 ; + RECT 32.135 0.87 35.025 11.385 ; + RECT 35.025 0.87 47.445 12.065 ; + RECT 47.445 0.855 54.805 12.065 ; + RECT 54.805 0.175 55.135 12.065 ; + RECT 55.135 0.19 57.565 12.065 ; + RECT 57.565 0.19 61.575 12.745 ; + RECT 61.575 0.19 67.095 11.385 ; + RECT 67.095 0.19 73.29 11.37 ; + RECT 73.29 0.855 78.135 11.37 ; + RECT 78.135 0.87 88.845 11.37 ; + RECT 88.845 0.87 89.175 11.385 ; + RECT 89.175 0.87 95.285 10.24 ; + RECT 95.285 0.855 101.135 10.24 ; + RECT 101.135 0.87 103.565 10.24 ; + RECT 103.565 0.87 123.805 11.385 ; + RECT 123.805 0.855 124.135 11.385 ; + RECT 124.135 1.535 129.195 11.385 ; + RECT 129.195 1.535 145.425 10.24 ; + RECT 145.425 0.175 145.755 10.24 ; + RECT 145.755 0.19 150.945 10.24 ; + RECT 150.945 0.19 151.275 12.065 ; + RECT 151.275 0.19 161.525 12.05 ; + RECT 161.525 0.175 172.895 12.05 ; + RECT 172.895 0.855 173.025 12.05 ; + RECT 173.025 0.855 176.115 12.745 ; + RECT 176.115 0.855 177.035 12.065 ; + RECT 177.035 0.855 191.885 11.37 ; + RECT 191.885 0.855 192.215 11.385 ; + RECT 192.215 0.87 208.905 10.24 ; + RECT 208.905 0.855 209.235 10.24 ; + RECT 209.235 1.535 214.295 10.24 ; + RECT 214.295 1.55 214.82 10.24 ; + RECT 214.82 4.76 215.28 10.24 ; + END +END RAM8x8 +END LIBRARY diff --git a/src/ram/test/make_8x8_mux2.ok b/src/ram/test/make_8x8_mux2.ok new file mode 100644 index 00000000000..9cb8b9a9792 --- /dev/null +++ b/src/ram/test/make_8x8_mux2.ok @@ -0,0 +1,69 @@ +[INFO ODB-0227] LEF file: sky130hd/sky130hd.tlef, created 13 layers, 25 vias +[INFO ODB-0227] LEF file: sky130hd/sky130_fd_sc_hd_merged.lef, created 437 library cells +[WARNING RAM-0022] No tapcell is specified. + The generated layout may not pass Design Rule Checks. +[INFO RAM-0003] Generating RAM8x8 +[INFO RAM-0016] Selected inverter cell sky130_fd_sc_hd__clkinv_1 +[INFO RAM-0016] Selected tristate cell sky130_fd_sc_hd__ebufn_1 +[INFO RAM-0016] Selected and2 cell sky130_fd_sc_hd__and2_0 +[INFO RAM-0016] Selected clock gate cell sky130_fd_sc_hd__dlclkp_1 +[INFO RAM-0016] Selected buffer cell sky130_fd_sc_hd__buf_1 +[INFO RAM-0016] Selected aoi22 cell sky130_fd_sc_hd__a22oi_1 +[INFO PDN-0001] Inserting grid: ram_grid +[INFO PPL-0067] Restrict pins [ D[0] Q[0] D[1] Q[1] D[2] ... ] to region 0.00u-206.54u at the TOP edge. +[INFO PPL-0001] Number of available slots 438 +[INFO PPL-0002] Number of I/O 21 +[INFO PPL-0003] Number of I/O w/sink 21 +[INFO PPL-0004] Number of I/O w/o sink 0 +[INFO PPL-0005] Slots per section 200 +[INFO PPL-0008] Successfully assigned pins to sections. +[INFO PPL-0012] I/O nets HPWL: 387.07 um. +[INFO DPL-0001] Placed 78 filler instances. +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer mcon +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer mcon +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via2 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via2 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via3 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via3 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via4 +[WARNING DRT-0349] LEF58_ENCLOSURE with no CUTCLASS is not supported. Skipping for layer via4 +[INFO DRT-0167] List of default vias: + Layer via + default via: M1M2_PR + Layer via2 + default via: M2M3_PR + Layer via3 + default via: M3M4_PR + Layer via4 + default via: M4M5_PR +[INFO DRT-0168] Init region query. +[INFO DRT-0033] FR_MASTERSLICE shape region query size = 0. +[INFO DRT-0033] FR_VIA shape region query size = 0. +[INFO DRT-0033] li1 shape region query size = 7247. +[INFO DRT-0033] mcon shape region query size = 384. +[INFO DRT-0033] met1 shape region query size = 1176. +[INFO DRT-0033] via shape region query size = 60. +[INFO DRT-0033] met2 shape region query size = 159. +[INFO DRT-0033] via2 shape region query size = 20. +[INFO DRT-0033] met3 shape region query size = 28. +[INFO DRT-0033] via3 shape region query size = 0. +[INFO DRT-0033] met4 shape region query size = 0. +[INFO DRT-0033] via4 shape region query size = 0. +[INFO DRT-0033] met5 shape region query size = 0. +[INFO DRT-0178] Init guide query. +[INFO DRT-0036] FR_MASTERSLICE guide region query size = 0. +[INFO DRT-0036] FR_VIA guide region query size = 0. +[INFO DRT-0036] li1 guide region query size = 344. +[INFO DRT-0036] mcon guide region query size = 0. +[INFO DRT-0036] met1 guide region query size = 205. +[INFO DRT-0036] via guide region query size = 0. +[INFO DRT-0036] met2 guide region query size = 21. +[INFO DRT-0036] via2 guide region query size = 0. +[INFO DRT-0036] met3 guide region query size = 2. +[INFO DRT-0036] via3 guide region query size = 0. +[INFO DRT-0036] met4 guide region query size = 0. +[INFO DRT-0036] via4 guide region query size = 0. +[INFO DRT-0036] met5 guide region query size = 0. +[INFO DRT-0179] Init gr pin query. diff --git a/src/ram/test/make_8x8_mux2.tcl b/src/ram/test/make_8x8_mux2.tcl new file mode 100644 index 00000000000..b86e2fba0ba --- /dev/null +++ b/src/ram/test/make_8x8_mux2.tcl @@ -0,0 +1,20 @@ +source "helpers.tcl" +read_liberty sky130hd/sky130_fd_sc_hd__tt_025C_1v80.lib +read_lef sky130hd/sky130hd.tlef +read_lef sky130hd/sky130_fd_sc_hd_merged.lef +generate_ram \ + -mask_size 8 \ + -word_size 8 \ + -num_words 8 \ + -column_mux_ratio 2 \ + -read_ports 1 \ + -storage_cell sky130_fd_sc_hd__dfxtp_1 \ + -power_pin VPWR \ + -ground_pin VGND \ + -routing_layer {met1 0.48} \ + -ver_layer {met2 0.48 20} \ + -hor_layer {met3 0.48 10} \ + -filler_cells {sky130_fd_sc_hd__fill_1 sky130_fd_sc_hd__fill_2 \ + sky130_fd_sc_hd__fill_4 sky130_fd_sc_hd__fill_8} +write_verilog [make_result_file test_8x8_mux2.v] + diff --git a/src/ram/test/regression_tests.tcl b/src/ram/test/regression_tests.tcl index 8a7c361fe17..9bf9adb990b 100644 --- a/src/ram/test/regression_tests.tcl +++ b/src/ram/test/regression_tests.tcl @@ -1,5 +1,4 @@ record_tests { make_8x8 - make_16x8_mux2 - make_32x8_mux4 + make_8x8_mux2 } diff --git a/src/rcx/test/net_name_consistency.ok b/src/rcx/test/net_name_consistency.ok index 60b7ccd8980..f22d4e762e9 100644 --- a/src/rcx/test/net_name_consistency.ok +++ b/src/rcx/test/net_name_consistency.ok @@ -80,9 +80,9 @@ [INFO RCX-0040] Final 5 rc segments [INFO RCX-0439] Coupling Cap extraction top ... [INFO RCX-0440] Coupling threshhold is 0.1000 fF, coupling capacitance less than 0.1000 fF will be grounded. -[INFO RCX-0442] 50% of 8 wires extracted -[INFO RCX-0442] 100% of 8 wires extracted -[INFO RCX-0045] Extract 2 nets, 8 rsegs, 8 caps, 2 ccs +[INFO RCX-0442] 44% of 9 wires extracted +[INFO RCX-0442] 100% of 9 wires extracted +[INFO RCX-0045] Extract 2 nets, 8 rsegs, 8 caps, 1 ccs No differences found. [INFO RCX-0443] 4 nets finished No differences found. diff --git a/src/rcx/test/net_name_consistency.spefok b/src/rcx/test/net_name_consistency.spefok index e421c92a479..02b8d7c558b 100644 --- a/src/rcx/test/net_name_consistency.spefok +++ b/src/rcx/test/net_name_consistency.spefok @@ -1,9 +1,9 @@ *SPEF "ieee 1481-1999" *DESIGN "top" -*DATE "16:33:29 Tuesday October 07, 2025" +*DATE "22:32:56 Thursday March 26, 2026" *VENDOR "The OpenROAD Project" *PROGRAM "OpenROAD" -*VERSION "v2.0-25129-g8c29de770e" +*VERSION "26Q1-2587-g305aac2da5" *DESIGN_FLOW "NAME_SCOPE LOCAL" "PIN_CAP NONE" *DIVIDER / *DELIMITER : @@ -25,33 +25,31 @@ *13 b/buf0_1 *14 b/leaf_2 -*D_NET *2 6.18647e-05 +*D_NET *2 8.26554e-05 *CONN -*I *10:A I *D INV_X1 *I *11:A I *D INV_X1 +*I *10:A I *D INV_X1 *I *8:ZN O *D INV_X1 *CAP -1 *10:A 0 -2 *11:A 1.67394e-05 -3 *8:ZN 8.12034e-06 -4 *2:6 2.48598e-05 -5 *11:A *12:A 1.09597e-05 -6 *2:6 *12:A 1.18547e-06 +1 *11:A 0 +2 *10:A 1.33728e-05 +3 *8:ZN 1.22834e-05 +4 *2:8 2.56562e-05 +5 *2:8 *12:A 3.1343e-05 *RES -1 *8:ZN *2:6 5.92857 -2 *2:6 *11:A 7.25 -3 *2:6 *10:A 5 +1 *8:ZN *2:8 8.17857 +2 *2:8 *10:A 7 +3 *2:8 *11:A 5 *END -*D_NET *5 0.000136987 +*D_NET *5 0.000150118 *CONN *I *12:A I *D INV_X1 *I *13:Z O *D LOGIC0_X1 *CAP -1 *12:A 6.24209e-05 -2 *13:Z 6.24209e-05 -3 *11:A *12:A 1.09597e-05 -4 *2:6 *12:A 1.18547e-06 +1 *12:A 5.93874e-05 +2 *13:Z 5.93874e-05 +3 *2:8 *12:A 3.1343e-05 *RES 1 *13:Z *12:A 17.6964 *END diff --git a/src/rsz/test/report_buffers_ihp.ok b/src/rsz/test/report_buffers_ihp.ok index 5ff929a5c1e..f52b2b2b742 100644 --- a/src/rsz/test/report_buffers_ihp.ok +++ b/src/rsz/test/report_buffers_ihp.ok @@ -204,4 +204,3 @@ sg13g2_dlygate4sd3_1 is the buffer chosen for hold fixing ==== set clock buffer footprint to DLY === ==== should get an error === [ERROR CTS-0134] -clock_buffer_footprint cannot be set because -clock_buffer_string is already defined. -Error: report_buffers_ihp.tcl, 32 CTS-0134 diff --git a/src/rsz/test/report_buffers_ihp.tcl b/src/rsz/test/report_buffers_ihp.tcl index 698a6c2ac53..08611b994f7 100644 --- a/src/rsz/test/report_buffers_ihp.tcl +++ b/src/rsz/test/report_buffers_ihp.tcl @@ -29,4 +29,4 @@ report_buffers puts "\n==== set clock buffer footprint to DLY ===" puts "==== should get an error ===" -set_cts_config -clock_buffer_footprint DLY +catch { set_cts_config -clock_buffer_footprint DLY } diff --git a/src/web/README.md b/src/web/README.md index 466df004f46..1fb299c9941 100644 --- a/src/web/README.md +++ b/src/web/README.md @@ -30,6 +30,82 @@ web_server | `-port` | TCP port to listen on. Default: `8080`. | | `-dir` | Path to the document root directory containing the web assets (`index.html`, `*.js`, `*.css`). | +### Save Image + +Save the layout to a PNG file. By default, the command uses the GUI (Qt) +renderer. Pass `-web` to use the web tile renderer instead, which runs +entirely server-side without a display and is suitable for headless CI. + +```tcl +save_image + [-web] + [-area {x0 y0 x1 y1}] + [-width width] + [-resolution microns_per_pixel] + [-display_option option] + path +``` + +#### Options + +| Switch Name | Description | +| ----- | ----- | +| `-web` | Use the web tile renderer instead of the GUI renderer. Does not require a display or a running web server. | +| `-area` | Bounding box in microns `{x0 y0 x1 y1}`. Default: die area (with 5% margin in `-web` mode). | +| `-width` | Output image width in pixels. Cannot be used with `-resolution`. | +| `-resolution` | Resolution in microns per pixel. Minimum: 1 DBU per pixel. Cannot be used with `-width`. | +| `-display_option` | Repeatable visibility overrides as `{control value}` pairs. See [Display option keys](#display-option-keys) below. | +| `path` | Output PNG file path. | + +When using `-web`, if neither `-width` nor `-resolution` is specified, the +image defaults to 1024 pixels wide. The maximum image dimension is 16384 +pixels; larger requests are clamped automatically. + +#### Display option keys (web mode) + +Display options control which elements are rendered when using `-web`. +Each option is a `{key value}` pair where the key matches a visibility +field and the value is `true` or `false`. + +| Key | Default | Description | +| --- | ------- | ----------- | +| `stdcells` | true | Standard cells | +| `macros` | true | Macros | +| `routing` | true | Signal routing | +| `special_nets` | true | Power/ground straps | +| `pins` | true | Instance pins | +| `pin_markers` | true | IO pin direction markers | +| `blockages` | true | Blockages | +| `net_signal` | true | Signal nets | +| `net_power` | true | Power nets | +| `net_clock` | true | Clock nets | +| `rows` | false | Row outlines | +| `tracks_pref` | false | Preferred-direction tracks | + +#### Examples + +```tcl +# Save using the GUI renderer (default) +save_image layout.png + +# Save using the web renderer (headless) +save_image -web layout.png + +# Save at 1024px wide with the web renderer +save_image -web -width 1024 layout.png + +# Save at 0.1 um per pixel +save_image -web -resolution 0.1 layout.png + +# Save a specific region (in microns) +save_image -web -area {0 0 100 100} -width 2048 region.png + +# Hide routing and power nets +save_image -web -display_option {routing false} \ + -display_option {net_power false} \ + layout.png +``` + ## Features - **Tile-based rendering** — The server renders 256x256 PNG tiles on demand, diff --git a/src/web/include/web/web.h b/src/web/include/web/web.h index a3f28ad0e24..e01897a0ba1 100644 --- a/src/web/include/web/web.h +++ b/src/web/include/web/web.h @@ -33,6 +33,15 @@ class WebServer void serve(int port, const std::string& doc_root); + void saveImage(const std::string& filename, + int x0, + int y0, + int x1, + int y1, + int width_px, + double dbu_per_pixel, + const std::string& vis_json); + private: odb::dbDatabase* db_ = nullptr; sta::dbSta* sta_ = nullptr; diff --git a/src/web/src/coordinates.js b/src/web/src/coordinates.js index 845a14032b2..61fdcc6b927 100644 --- a/src/web/src/coordinates.js +++ b/src/web/src/coordinates.js @@ -5,26 +5,28 @@ // // The tile renderer uses two Y-flips (tile index + pixel row), so the // correct mapping is: -// lat = (dbu_y - maxDXDY) * scale -// lng = dbu_x * scale +// lat = (dbu_y - originY - maxDXDY) * scale +// lng = (dbu_x - originX) * scale // // `scale` = tileSize / max(designWidth, designHeight) (pixels-per-DBU) // `maxDXDY` = max(designWidth, designHeight) in DBU +// `originX` = bounds.xMin() in DBU (tile grid origin) +// `originY` = bounds.yMin() in DBU (tile grid origin) -export function dbuToLatLng(dbuX, dbuY, scale, maxDXDY) { - return [(dbuY - maxDXDY) * scale, dbuX * scale]; +export function dbuToLatLng(dbuX, dbuY, scale, maxDXDY, originX = 0, originY = 0) { + return [(dbuY - originY - maxDXDY) * scale, (dbuX - originX) * scale]; } -export function dbuRectToBounds(x1, y1, x2, y2, scale, maxDXDY) { +export function dbuRectToBounds(x1, y1, x2, y2, scale, maxDXDY, originX = 0, originY = 0) { return [ - [(y1 - maxDXDY) * scale, x1 * scale], - [(y2 - maxDXDY) * scale, x2 * scale], + [(y1 - originY - maxDXDY) * scale, (x1 - originX) * scale], + [(y2 - originY - maxDXDY) * scale, (x2 - originX) * scale], ]; } -export function latLngToDbu(lat, lng, scale, maxDXDY) { +export function latLngToDbu(lat, lng, scale, maxDXDY, originX = 0, originY = 0) { return { - dbuX: Math.round(lng / scale), - dbuY: Math.round(maxDXDY + lat / scale), + dbuX: Math.round(originX + lng / scale), + dbuY: Math.round(originY + maxDXDY + lat / scale), }; } diff --git a/src/web/src/display-controls.js b/src/web/src/display-controls.js index b458786739f..557d298d9df 100644 --- a/src/web/src/display-controls.js +++ b/src/web/src/display-controls.js @@ -43,9 +43,17 @@ export function populateDisplayControls(app, visibility, WebSocketTileLayer, instancesLayer.addTo(app.map); app.allLayers.push(instancesLayer); + // IO pin markers layer (between instances and routing layers) + const pinsLayer = new WebSocketTileLayer(app.websocketManager, '_pins', { + zIndex: 1, + }); + pinsLayer.addTo(app.map); + app.pinsLayer = pinsLayer; + app.allLayers.push(pinsLayer); + // Module coloring overlay layer (between instances and routing layers) const modulesLayer = new WebSocketTileLayer(app.websocketManager, '_modules', { - zIndex: 1, + zIndex: 2, }); // Don't add to map until "Module view" is enabled app.modulesLayer = modulesLayer; @@ -62,7 +70,7 @@ export function populateDisplayControls(app, visibility, WebSocketTileLayer, children: techData.layers.map((name, index) => { const layer = new WebSocketTileLayer(app.websocketManager, name, { opacity: 0.7, - zIndex: index + 2, + zIndex: index + 3, }); layer.addTo(app.map); app.allLayers.push(layer); @@ -263,6 +271,7 @@ export function populateDisplayControls(app, visibility, WebSocketTileLayer, { key: 'routing', label: 'Routing' }, { key: 'special_nets', label: 'Special Nets' }, { key: 'pins', label: 'Pins' }, + { key: 'pin_markers', label: 'Pin Markers' }, { key: 'blockages', label: 'Blockages' }, ]}); visTree.add({ label: 'Blockages', children: [ diff --git a/src/web/src/inspector.js b/src/web/src/inspector.js index d3674c29360..00c5cd1094f 100644 --- a/src/web/src/inspector.js +++ b/src/web/src/inspector.js @@ -125,7 +125,7 @@ export function createInspectorPanel(app, redrawAllLayers) { function boundsWithMinimumScreenSize(x1, y1, x2, y2) { const baseBounds = L.latLngBounds( - dbuRectToBounds(x1, y1, x2, y2, app.designScale, app.designMaxDXDY) + dbuRectToBounds(x1, y1, x2, y2, app.designScale, app.designMaxDXDY, app.designOriginX, app.designOriginY) ); if (!app.map) { return baseBounds; @@ -291,7 +291,7 @@ export function createInspectorPanel(app, redrawAllLayers) { if (app.highlightRect) { app.map.removeLayer(app.highlightRect); } - const bounds = dbuRectToBounds(x1, y1, x2, y2, app.designScale, app.designMaxDXDY); + const bounds = dbuRectToBounds(x1, y1, x2, y2, app.designScale, app.designMaxDXDY, app.designOriginX, app.designOriginY); app.highlightRect = L.rectangle(bounds, { color: '#ff0', weight: 2, fill: false, dashArray: '6,4', }).addTo(app.map); @@ -372,7 +372,7 @@ export function createInspectorPanel(app, redrawAllLayers) { function zoomToBBox(bbox) { if (!bbox || !app.map || !app.designScale) return; const [x1, y1, x2, y2] = bbox; - app.map.fitBounds(dbuRectToBounds(x1, y1, x2, y2, app.designScale, app.designMaxDXDY), + app.map.fitBounds(dbuRectToBounds(x1, y1, x2, y2, app.designScale, app.designMaxDXDY, app.designOriginX, app.designOriginY), { padding: [20, 20] }); } diff --git a/src/web/src/main.js b/src/web/src/main.js index 3295b00c8b7..f35ab4fbbd3 100644 --- a/src/web/src/main.js +++ b/src/web/src/main.js @@ -45,6 +45,8 @@ const app = { allLayers: [], designScale: null, // pixels-per-DBU for coordinate conversion designMaxDXDY: null, // max(width, height) in DBU for Y-axis mapping + designOriginX: 0, // bounds.xMin() in DBU (tile grid origin) + designOriginY: 0, // bounds.yMin() in DBU (tile grid origin) websocketManager: null, // set after construction below goldenLayout: null, // set after GL init below hasLiberty: false, @@ -55,6 +57,7 @@ const app = { hoverHighlightLayer: null, hoverHighlightPane: 'hover-highlight-pane', modulesLayer: null, + pinsLayer: null, hierarchyBrowser: null, focusNets: new Set(), routeGuideNets: new Set(), @@ -108,6 +111,7 @@ const visibility = { routing: true, special_nets: true, pins: true, + pin_markers: true, blockages: true, // Blockages placement_blockages: true, @@ -234,6 +238,14 @@ function redrawAllLayers() { app.map.removeLayer(app.modulesLayer); } } + // Show/hide pin markers layer + if (app.pinsLayer) { + if (visibility.pin_markers && !app.map.hasLayer(app.pinsLayer)) { + app.pinsLayer.addTo(app.map); + } else if (!visibility.pin_markers && app.map.hasLayer(app.pinsLayer)) { + app.map.removeLayer(app.pinsLayer); + } + } for (const layer of app.allLayers) { layer.refreshTiles(); } @@ -280,7 +292,8 @@ function createLayoutViewer(container) { app.lastMouseLatLng = e.latlng; if (!app.designScale) return; const { dbuX, dbuY } = latLngToDbu( - e.latlng.lat, e.latlng.lng, app.designScale, app.designMaxDXDY); + e.latlng.lat, e.latlng.lng, app.designScale, app.designMaxDXDY, + app.designOriginX, app.designOriginY); const dbuPerUm = app.techData?.dbu_per_micron || 1000; const precision = Math.ceil(Math.log10(dbuPerUm)); const xUm = (dbuX / dbuPerUm).toFixed(precision); @@ -638,13 +651,16 @@ app.websocketManager.readyPromise.then(async () => { const hasDesign = designWidth > 0 && designHeight > 0; if (hasDesign) { const tileSize = 256; - const scale = tileSize / Math.max(designWidth, designHeight); + const maxDXDY = Math.max(designWidth, designHeight); + const scale = tileSize / maxDXDY; app.designScale = scale; - app.designMaxDXDY = Math.max(designWidth, designHeight); + app.designMaxDXDY = maxDXDY; + app.designOriginX = minX; + app.designOriginY = minY; app.fitBounds = [ - [-minY * scale, minX * scale], - [-maxY * scale, maxX * scale] + [-maxDXDY * scale, 0], + [(designHeight - maxDXDY) * scale, designWidth * scale] ]; app.map.fitBounds(app.fitBounds); } @@ -654,7 +670,8 @@ app.websocketManager.readyPromise.then(async () => { if (!app.designScale) return; if (app.rulerManager && app.rulerManager.isActive()) return; const { dbuX: dbu_x, dbuY: dbu_y } = latLngToDbu( - e.latlng.lat, e.latlng.lng, app.designScale, app.designMaxDXDY); + e.latlng.lat, e.latlng.lng, app.designScale, app.designMaxDXDY, + app.designOriginX, app.designOriginY); const vf = {}; for (const [k, v] of Object.entries(visibility)) { diff --git a/src/web/src/request_handler.cpp b/src/web/src/request_handler.cpp index 69d0e6ba5bb..3adb8f1be36 100644 --- a/src/web/src/request_handler.cpp +++ b/src/web/src/request_handler.cpp @@ -546,6 +546,7 @@ WebSocketResponse dispatch_request( builder.endArray(); builder.endArray(); builder.field("shapes_ready", gen.shapesReady()); + builder.field("pin_max_size", gen.getPinMaxSize()); builder.endObject(); const std::string& json = builder.str(); resp.payload.assign(json.begin(), json.end()); diff --git a/src/web/src/ruler.js b/src/web/src/ruler.js index fd2f1056226..8be577b2215 100644 --- a/src/web/src/ruler.js +++ b/src/web/src/ruler.js @@ -143,7 +143,8 @@ export class RulerManager { e.clientX - rect.left, e.clientY - rect.top ]); const dbu = latLngToDbu(pt.lat, pt.lng, - this._app.designScale, this._app.designMaxDXDY); + this._app.designScale, this._app.designMaxDXDY, + this._app.designOriginX, this._app.designOriginY); // Debounce snap requests at ~50ms if (this._snapTimer) clearTimeout(this._snapTimer); @@ -165,7 +166,8 @@ export class RulerManager { } const dbu = latLngToDbu(e.latlng.lat, e.latlng.lng, - this._app.designScale, this._app.designMaxDXDY); + this._app.designScale, this._app.designMaxDXDY, + this._app.designOriginX, this._app.designOriginY); // Use the last snap result if available, otherwise raw click const snapped = this._getSnappedPoint(dbu.dbuX, dbu.dbuY); @@ -304,9 +306,11 @@ export class RulerManager { const scale = this._app.designScale; const maxDXDY = this._app.designMaxDXDY; + const originX = this._app.designOriginX; + const originY = this._app.designOriginY; if (snap.is_point) { - const ll = dbuToLatLng(snap.edge[0][0], snap.edge[0][1], scale, maxDXDY); + const ll = dbuToLatLng(snap.edge[0][0], snap.edge[0][1], scale, maxDXDY, originX, originY); const marker = L.circleMarker(ll, { radius: 5, color: SNAP_INDICATOR_COLOR, @@ -318,8 +322,8 @@ export class RulerManager { }); this._snapGroup.addLayer(marker); } else { - const p1 = dbuToLatLng(snap.edge[0][0], snap.edge[0][1], scale, maxDXDY); - const p2 = dbuToLatLng(snap.edge[1][0], snap.edge[1][1], scale, maxDXDY); + const p1 = dbuToLatLng(snap.edge[0][0], snap.edge[0][1], scale, maxDXDY, originX, originY); + const p2 = dbuToLatLng(snap.edge[1][0], snap.edge[1][1], scale, maxDXDY, originX, originY); const line = L.polyline([p1, p2], { color: SNAP_INDICATOR_COLOR, weight: 1, @@ -336,10 +340,12 @@ export class RulerManager { const scale = this._app.designScale; const maxDXDY = this._app.designMaxDXDY; + const originX = this._app.designOriginX; + const originY = this._app.designOriginY; const snapped = this._getSnappedPoint(rawX, rawY); - const p0 = dbuToLatLng(this._pt0.x, this._pt0.y, scale, maxDXDY); - const p1 = dbuToLatLng(snapped.x, snapped.y, scale, maxDXDY); + const p0 = dbuToLatLng(this._pt0.x, this._pt0.y, scale, maxDXDY, originX, originY); + const p1 = dbuToLatLng(snapped.x, snapped.y, scale, maxDXDY, originX, originY); const line = L.polyline([p0, p1], { color: RULER_COLOR, @@ -386,9 +392,11 @@ export class RulerManager { _renderRuler(ruler) { const scale = this._app.designScale; const maxDXDY = this._app.designMaxDXDY; + const originX = this._app.designOriginX; + const originY = this._app.designOriginY; - const p0 = dbuToLatLng(ruler.pt0.x, ruler.pt0.y, scale, maxDXDY); - const p1 = dbuToLatLng(ruler.pt1.x, ruler.pt1.y, scale, maxDXDY); + const p0 = dbuToLatLng(ruler.pt0.x, ruler.pt0.y, scale, maxDXDY, originX, originY); + const p1 = dbuToLatLng(ruler.pt1.x, ruler.pt1.y, scale, maxDXDY, originX, originY); const isSelected = ruler.id === this._selectedRulerId; const color = isSelected ? RULER_SELECTED_COLOR : RULER_COLOR; @@ -423,8 +431,8 @@ export class RulerManager { const py = dx / len; for (const pt of [ruler.pt0, ruler.pt1]) { - const t0 = dbuToLatLng(pt.x + px * tickLen, pt.y + py * tickLen, scale, maxDXDY); - const t1 = dbuToLatLng(pt.x - px * tickLen, pt.y - py * tickLen, scale, maxDXDY); + const t0 = dbuToLatLng(pt.x + px * tickLen, pt.y + py * tickLen, scale, maxDXDY, originX, originY); + const t1 = dbuToLatLng(pt.x - px * tickLen, pt.y - py * tickLen, scale, maxDXDY, originX, originY); group.addLayer(L.polyline([t0, t1], { color, weight: 2, diff --git a/src/web/src/tile_generator.cpp b/src/web/src/tile_generator.cpp index fffd80ff071..78922ac4eac 100644 --- a/src/web/src/tile_generator.cpp +++ b/src/web/src/tile_generator.cpp @@ -4,6 +4,7 @@ #include "tile_generator.h" #include +#include #include #include #include @@ -39,6 +40,10 @@ constexpr int kBitmapGlyphWidth = 5; constexpr int kBitmapGlyphHeight = 7; constexpr int kBitmapGlyphSpacing = 1; +constexpr float kPinMarkerSizeRatio = 0.02; +constexpr int kMinPinMarkerSize = 8; +constexpr int kMinPinNameSizePixels = 20; + const unsigned char* getBitmapGlyph(const char ch) { // Minimal 5x7 bitmap font. Each byte is one row, only the low 5 bits are @@ -114,21 +119,37 @@ const unsigned char* getBitmapGlyph(const char ch) = {0x00, 0x00, 0x1F, 0x00, 0x1F, 0x00, 0x00}; return glyph; } - case 'x': { - static constexpr unsigned char glyph[] - = {0x00, 0x00, 0x11, 0x0A, 0x04, 0x0A, 0x11}; - return glyph; - } - case 'y': { - static constexpr unsigned char glyph[] - = {0x00, 0x00, 0x11, 0x0A, 0x04, 0x04, 0x04}; - return glyph; - } - case 'z': { - static constexpr unsigned char glyph[] - = {0x00, 0x00, 0x1F, 0x02, 0x04, 0x08, 0x1F}; - return glyph; - } + // clang-format off + case 'A': case 'a': { static constexpr unsigned char g[]={0x0E,0x11,0x11,0x1F,0x11,0x11,0x11}; return g; } + case 'B': case 'b': { static constexpr unsigned char g[]={0x1E,0x11,0x11,0x1E,0x11,0x11,0x1E}; return g; } + case 'C': case 'c': { static constexpr unsigned char g[]={0x0E,0x11,0x10,0x10,0x10,0x11,0x0E}; return g; } + case 'D': case 'd': { static constexpr unsigned char g[]={0x1E,0x11,0x11,0x11,0x11,0x11,0x1E}; return g; } + case 'E': case 'e': { static constexpr unsigned char g[]={0x1F,0x10,0x10,0x1E,0x10,0x10,0x1F}; return g; } + case 'F': case 'f': { static constexpr unsigned char g[]={0x1F,0x10,0x10,0x1E,0x10,0x10,0x10}; return g; } + case 'G': case 'g': { static constexpr unsigned char g[]={0x0E,0x11,0x10,0x17,0x11,0x11,0x0F}; return g; } + case 'H': case 'h': { static constexpr unsigned char g[]={0x11,0x11,0x11,0x1F,0x11,0x11,0x11}; return g; } + case 'I': case 'i': { static constexpr unsigned char g[]={0x0E,0x04,0x04,0x04,0x04,0x04,0x0E}; return g; } + case 'J': case 'j': { static constexpr unsigned char g[]={0x07,0x02,0x02,0x02,0x02,0x12,0x0C}; return g; } + case 'K': case 'k': { static constexpr unsigned char g[]={0x11,0x12,0x14,0x18,0x14,0x12,0x11}; return g; } + case 'L': case 'l': { static constexpr unsigned char g[]={0x10,0x10,0x10,0x10,0x10,0x10,0x1F}; return g; } + case 'M': case 'm': { static constexpr unsigned char g[]={0x11,0x1B,0x15,0x15,0x11,0x11,0x11}; return g; } + case 'N': case 'n': { static constexpr unsigned char g[]={0x11,0x19,0x15,0x13,0x11,0x11,0x11}; return g; } + case 'O': case 'o': { static constexpr unsigned char g[]={0x0E,0x11,0x11,0x11,0x11,0x11,0x0E}; return g; } + case 'P': case 'p': { static constexpr unsigned char g[]={0x1E,0x11,0x11,0x1E,0x10,0x10,0x10}; return g; } + case 'Q': case 'q': { static constexpr unsigned char g[]={0x0E,0x11,0x11,0x11,0x15,0x12,0x0D}; return g; } + case 'R': case 'r': { static constexpr unsigned char g[]={0x1E,0x11,0x11,0x1E,0x14,0x12,0x11}; return g; } + case 'S': case 's': { static constexpr unsigned char g[]={0x0E,0x11,0x10,0x0E,0x01,0x11,0x0E}; return g; } + case 'T': case 't': { static constexpr unsigned char g[]={0x1F,0x04,0x04,0x04,0x04,0x04,0x04}; return g; } + case 'U': case 'u': { static constexpr unsigned char g[]={0x11,0x11,0x11,0x11,0x11,0x11,0x0E}; return g; } + case 'V': case 'v': { static constexpr unsigned char g[]={0x11,0x11,0x11,0x11,0x0A,0x0A,0x04}; return g; } + case 'W': case 'w': { static constexpr unsigned char g[]={0x11,0x11,0x11,0x15,0x15,0x1B,0x11}; return g; } + case 'X': case 'x': { static constexpr unsigned char g[]={0x11,0x0A,0x04,0x04,0x04,0x0A,0x11}; return g; } + case 'Y': case 'y': { static constexpr unsigned char g[]={0x11,0x0A,0x04,0x04,0x04,0x04,0x04}; return g; } + case 'Z': case 'z': { static constexpr unsigned char g[]={0x1F,0x01,0x02,0x04,0x08,0x10,0x1F}; return g; } + case '_': { static constexpr unsigned char g[]={0x00,0x00,0x00,0x00,0x00,0x00,0x1F}; return g; } + case '[': { static constexpr unsigned char g[]={0x0E,0x08,0x08,0x08,0x08,0x08,0x0E}; return g; } + case ']': { static constexpr unsigned char g[]={0x0E,0x02,0x02,0x02,0x02,0x02,0x0E}; return g; } + // clang-format on default: return nullptr; } @@ -191,6 +212,7 @@ void TileVisibility::parseFromJson(const std::string& json) {"routing", &TileVisibility::routing, true}, {"special_nets", &TileVisibility::special_nets, true}, {"pins", &TileVisibility::pins, true}, + {"pin_markers", &TileVisibility::pin_markers, true}, {"blockages", &TileVisibility::blockages, true}, {"placement_blockages", &TileVisibility::placement_blockages, true}, {"routing_obstructions", &TileVisibility::routing_obstructions, true}, @@ -488,10 +510,30 @@ odb::Rect TileGenerator::getBounds() const odb::Rect bounds; if (odb::dbBlock* block = getBlock()) { bounds = block->getBBox()->getBox(); + // Expand for pin markers that extend outside the die edge. + const int margin = getPinMaxSize(); + if (margin > 0) { + bounds.set_xlo(bounds.xMin() - margin); + bounds.set_ylo(bounds.yMin() - margin); + bounds.set_xhi(bounds.xMax() + margin); + bounds.set_yhi(bounds.yMax() + margin); + } } return bounds; } +int TileGenerator::getPinMaxSize() const +{ + odb::dbBlock* block = getBlock(); + if (!block) { + return 0; + } + const odb::Rect die = block->getDieArea(); + const int die_max_dim = std::max(die.dx(), die.dy()); + return std::max(static_cast(kPinMarkerSizeRatio * die_max_dim), + kMinPinMarkerSize); +} + std::vector TileGenerator::getLayers() const { std::vector layers; @@ -694,6 +736,50 @@ std::vector TileGenerator::generateTile( const std::map* module_colors, const std::set* focus_net_ids, const std::set* route_guide_net_ids) const +{ + auto image_buffer = renderTileBuffer(layer, + z, + x, + y, + vis, + highlight_rects, + highlight_polys, + colored_rects, + flight_lines, + module_colors, + focus_net_ids, + route_guide_net_ids); + + std::vector png_data; + const unsigned error = lodepng::encode( + png_data, image_buffer, kTileSizeInPixel, kTileSizeInPixel); + if (error) { + logger_->report("PNG encoder error: {}", lodepng_error_text(error)); + } + + if (logger_->debugCheck(utl::WEB, "tile_generator", 1)) { + const std::string filename = "/tmp/tile_" + layer + "_" + std::to_string(z) + + "_" + std::to_string(x) + "_" + + std::to_string(y) + ".png"; + lodepng::save_file(png_data, filename); + } + + return png_data; +} + +std::vector TileGenerator::renderTileBuffer( + const std::string& layer, + const int z, + const int x, + int y, + const TileVisibility& vis, + const std::vector& highlight_rects, + const std::vector& highlight_polys, + const std::vector& colored_rects, + const std::vector& flight_lines, + const std::map* module_colors, + const std::set* focus_net_ids, + const std::set* route_guide_net_ids) const { static_assert(sizeof(Color) == 4); constexpr int buffer_size = kTileSizeInPixel * kTileSizeInPixel * 4; @@ -741,11 +827,14 @@ std::vector TileGenerator::generateTile( const double num_tiles_at_zoom = pow(2, z); if (x >= 0 && y >= 0 && x < num_tiles_at_zoom && y < num_tiles_at_zoom) { y = num_tiles_at_zoom - 1 - y; // flip - const double tile_dbu_size = getBounds().maxDXDY() / num_tiles_at_zoom; - const int dbu_x_min = x * tile_dbu_size; - const int dbu_y_min = y * tile_dbu_size; - const int dbu_x_max = std::ceil((x + 1) * tile_dbu_size); - const int dbu_y_max = std::ceil((y + 1) * tile_dbu_size); + const odb::Rect full_bounds = getBounds(); + const double tile_dbu_size = full_bounds.maxDXDY() / num_tiles_at_zoom; + const int dbu_x_min = full_bounds.xMin() + x * tile_dbu_size; + const int dbu_y_min = full_bounds.yMin() + y * tile_dbu_size; + const int dbu_x_max + = full_bounds.xMin() + std::ceil((x + 1) * tile_dbu_size); + const int dbu_y_max + = full_bounds.yMin() + std::ceil((y + 1) * tile_dbu_size); const odb::Rect dbu_tile(dbu_x_min, dbu_y_min, dbu_x_max, dbu_y_max); const double scale = kTileSizeInPixel / tile_dbu_size; @@ -786,12 +875,215 @@ std::vector TileGenerator::generateTile( } } + // Special "_pins" layer: draw IO pin direction markers + const bool pins_layer = (layer == "_pins"); + if (pins_layer && vis.pin_markers) { + const odb::Rect die_area = block->getDieArea(); + // Match GUI: scale markers to min(die, viewport) so they shrink + // when zoomed in (GUI renderThread.cpp:1598-1602). + const int die_max_dim = std::max(die_area.dx(), die_area.dy()); + const int tile_extent = static_cast(tile_dbu_size); + const int effective_dim = std::min(die_max_dim, tile_extent); + const int pin_max_size + = std::max(static_cast(kPinMarkerSizeRatio * effective_dim), + kMinPinMarkerSize); + const int qw = pin_max_size / 4; // quarter-width of marker + + // Show pin names when the full (die-relative) marker is large enough + // in pixels. pin_max_size shrinks with zoom, but the die-relative + // size grows as scale increases, so names appear when zoomed in. + const int die_pin_size + = std::max(static_cast(kPinMarkerSizeRatio * die_max_dim), + kMinPinMarkerSize); + const bool draw_pin_names + = (static_cast(die_pin_size * scale) >= kMinPinNameSizePixels); + + // Marker templates (same as GUI renderThread.cpp). + // Defined for "top edge" orientation; rotated per actual edge. + using Pts = std::vector; + const Pts in_marker{// arrow pointing into block + {qw, pin_max_size}, + {0, 0}, + {-qw, pin_max_size}, + {qw, pin_max_size}}; + const Pts out_marker{// arrow pointing out of block + {0, pin_max_size}, + {-qw, 0}, + {qw, 0}, + {0, pin_max_size}}; + const Pts bi_marker{// diamond + {0, 0}, + {-qw, pin_max_size / 2}, + {0, pin_max_size}, + {qw, pin_max_size / 2}, + {0, 0}}; + + // Determine layer colors for per-layer coloring of markers. + const auto all_layers = getLayers(); + + // Iterate per-box like the GUI (each dbBox gets its own marker). + for (odb::dbBTerm* term : block->getBTerms()) { + for (odb::dbBPin* pin : term->getBPins()) { + const odb::dbPlacementStatus status = pin->getPlacementStatus(); + if (status == odb::dbPlacementStatus::NONE + || status == odb::dbPlacementStatus::UNPLACED) { + continue; + } + + for (odb::dbBox* box : pin->getBoxes()) { + if (!box) { + continue; + } + const odb::Rect box_rect = box->getBox(); + + // Layer color for this box. + Color marker_color{.r = 200, .g = 200, .b = 200, .a = 220}; + odb::dbTechLayer* pin_layer = box->getTechLayer(); + if (pin_layer) { + const auto it = std::ranges::find( + all_layers, std::string(pin_layer->getName())); + if (it != all_layers.end()) { + const int idx = std::distance(all_layers.begin(), it); + marker_color = palette[idx % palette_size]; + marker_color.a = 220; + } + } + + // Center and edge distances from this specific box. + const odb::Point pin_center = box_rect.center(); + + const int dist_to_left + = std::abs(box_rect.xMin() - die_area.xMin()); + const int dist_to_right + = std::abs(box_rect.xMax() - die_area.xMax()); + const int dist_to_top = std::abs(box_rect.yMax() - die_area.yMax()); + const int dist_to_bot = std::abs(box_rect.yMin() - die_area.yMin()); + const std::array dists{ + dist_to_left, dist_to_right, dist_to_top, dist_to_bot}; + const int arg_min = static_cast( + std::distance(dists.begin(), std::ranges::min_element(dists))); + + odb::dbTransform xfm(pin_center); + if (arg_min == 0) { // left + xfm.setOrient(odb::dbOrientType::R90); + if (dist_to_left == 0) { + xfm.setOffset({die_area.xMin(), pin_center.y()}); + } + } else if (arg_min == 1) { // right + xfm.setOrient(odb::dbOrientType::R270); + if (dist_to_right == 0) { + xfm.setOffset({die_area.xMax(), pin_center.y()}); + } + } else if (arg_min == 2) { // top + // No rotation needed. + if (dist_to_top == 0) { + xfm.setOffset({pin_center.x(), die_area.yMax()}); + } + } else { // bottom + xfm.setOrient(odb::dbOrientType::MX); + if (dist_to_bot == 0) { + xfm.setOffset({pin_center.x(), die_area.yMin()}); + } + } + + // Select template based on IO direction. + const Pts* tmpl = &bi_marker; + const auto pin_dir = term->getIoType(); + if (pin_dir == odb::dbIoType::INPUT) { + tmpl = &in_marker; + } else if (pin_dir == odb::dbIoType::OUTPUT) { + tmpl = &out_marker; + } + + // Transform template to final marker polygon. + std::vector marker_pts; + marker_pts.reserve(tmpl->size()); + for (const auto& pt : *tmpl) { + odb::Point new_pt = pt; + xfm.apply(new_pt); + marker_pts.push_back(new_pt); + } + const odb::Polygon marker_poly(marker_pts); + + // Only draw if marker intersects this tile. + const odb::Rect marker_bbox = marker_poly.getEnclosingRect(); + if (marker_bbox.overlaps(dbu_tile)) { + fillPolygon( + image_buffer, marker_poly, dbu_tile, scale, marker_color); + } + + // Draw the box rect itself (same as GUI painter.drawRect). + if (box_rect.overlaps(dbu_tile)) { + const odb::Rect overlap = box_rect.intersect(dbu_tile); + const odb::Rect draw = toPixels(scale, overlap, dbu_tile); + drawFilledRect(image_buffer, draw, marker_color); + } + + // Draw pin name label when zoomed in enough. + if (draw_pin_names) { + const std::string name = term->getName(); + const odb::Point anchor_pt = xfm.getOffset(); + constexpr int text_scale = 2; + const int text_w = getBitmapTextWidth(name, text_scale); + const int text_h = getBitmapTextHeight(text_scale); + const int text_margin_px = text_scale + 1; + const bool rotated = (arg_min == 2 || arg_min == 3); + + // For rotated text, width/height swap. + const int block_w = rotated ? text_h : text_w; + const int block_h = rotated ? text_w : text_h; + + // Convert anchor to pixel coords. + const int anchor_px + = static_cast((anchor_pt.x() - dbu_tile.xMin()) * scale); + const int anchor_py_raw + = static_cast((anchor_pt.y() - dbu_tile.yMin()) * scale); + const int anchor_py = 255 - anchor_py_raw; + + // Position text beyond the marker, anchored per edge. + const int marker_px = static_cast(pin_max_size * scale); + int px; + int py; + if (arg_min == 0) { // left — right-aligned, left of marker + px = anchor_px - marker_px - text_margin_px - text_w; + py = anchor_py - text_h / 2; + } else if (arg_min == 1) { // right — left-aligned + px = anchor_px + marker_px + text_margin_px; + py = anchor_py - text_h / 2; + } else if (arg_min == 2) { // top — rotated, above marker + px = anchor_px - block_w / 2; + py = anchor_py - marker_px - text_margin_px - block_h; + } else { // bottom — rotated, below marker + px = anchor_px - block_w / 2; + py = anchor_py + marker_px + text_margin_px; + } + + if (px > -block_w && px < kTileSizeInPixel && py > -block_h + && py < kTileSizeInPixel) { + const Color text_color{.r = marker_color.r, + .g = marker_color.g, + .b = marker_color.b, + .a = 255}; + if (rotated) { + drawBitmapTextRotated( + image_buffer, px, py, name, text_scale, text_color); + } else { + drawBitmapText( + image_buffer, px, py, name, text_scale, text_color); + } + } + } + } + } + } + } + // Special "_instances" layer: only draw instance borders, no routing const bool instances_only = (layer == "_instances"); - // "_modules" layer only draws filled module-color rects (already done - // above); skip all other drawing (instances, routing, etc.) - if (!modules_layer) { + // "_modules" and "_pins" layers handle their own drawing above; + // skip all other drawing (instances, routing, etc.) + if (!modules_layer && !pins_layer) { // Draw instances for (odb::dbInst* inst : search_->searchInsts( block, dbu_x_min, dbu_y_min, dbu_x_max, dbu_y_max)) { @@ -1207,7 +1499,7 @@ std::vector TileGenerator::generateTile( } } - } // end if (!modules_layer) + } // end if (!modules_layer && !pins_layer) if (!highlight_rects.empty() || !highlight_polys.empty()) { drawHighlight( @@ -1229,21 +1521,7 @@ std::vector TileGenerator::generateTile( drawDebugOverlay(image_buffer, z, x, y); } - std::vector png_data; - unsigned error = lodepng::encode( - png_data, image_buffer, kTileSizeInPixel, kTileSizeInPixel); - if (error) { - logger_->report("PNG encoder error: {}", lodepng_error_text(error)); - } - - if (logger_->debugCheck(utl::WEB, "tile_generator", 1)) { - std::string filename = "/tmp/tile_" + layer + "_" + std::to_string(z) + "_" - + std::to_string(x) + "_" + std::to_string(y) - + ".png"; - lodepng::save_file(png_data, filename); - } - - return png_data; + return image_buffer; } std::vector TileGenerator::generateHeatMapTile( @@ -1261,11 +1539,12 @@ std::vector TileGenerator::generateHeatMapTile( } y = num_tiles_at_zoom - 1 - y; - const double tile_dbu_size = getBounds().maxDXDY() / num_tiles_at_zoom; - const int dbu_x_min = x * tile_dbu_size; - const int dbu_y_min = y * tile_dbu_size; - const int dbu_x_max = std::ceil((x + 1) * tile_dbu_size); - const int dbu_y_max = std::ceil((y + 1) * tile_dbu_size); + const odb::Rect hm_bounds = getBounds(); + const double tile_dbu_size = hm_bounds.maxDXDY() / num_tiles_at_zoom; + const int dbu_x_min = hm_bounds.xMin() + x * tile_dbu_size; + const int dbu_y_min = hm_bounds.yMin() + y * tile_dbu_size; + const int dbu_x_max = hm_bounds.xMin() + std::ceil((x + 1) * tile_dbu_size); + const int dbu_y_max = hm_bounds.yMin() + std::ceil((y + 1) * tile_dbu_size); const odb::Rect dbu_tile(dbu_x_min, dbu_y_min, dbu_x_max, dbu_y_max); const double scale = kTileSizeInPixel / tile_dbu_size; constexpr double text_rect_margin = 0.8; @@ -1331,6 +1610,201 @@ std::vector TileGenerator::generateHeatMapTile( return png_data; } +// Alpha-composite src onto dst (Porter-Duff "over"). +static void compositePixel(unsigned char* dst, const unsigned char* src) +{ + const int sa = src[3]; + if (sa == 0) { + return; + } + if (sa == 255 || dst[3] == 0) { + std::memcpy(dst, src, 4); + return; + } + const int da = dst[3]; + const int out_a = sa + da * (255 - sa) / 255; + if (out_a == 0) { + return; + } + for (int c = 0; c < 3; ++c) { + dst[c] = (src[c] * sa + dst[c] * da * (255 - sa) / 255) / out_a; + } + dst[3] = out_a; +} + +void TileGenerator::saveImage(const std::string& filename, + const odb::Rect& region, + const int width_px, + const double dbu_per_pixel, + const TileVisibility& vis) const +{ + odb::dbBlock* block = getBlock(); + if (!block) { + logger_->error(utl::WEB, 20, "No design loaded."); + return; + } + + // Determine rendering region (DBU). + odb::Rect area = region; + if (area.dx() == 0 || area.dy() == 0) { + area = block->getDieArea(); + if (area.dx() == 0 || area.dy() == 0) { + area = block->getBBox()->getBox(); + } + // Bloat by 5% like GUI headless default. + const int margin_x = area.dx() * 5 / 100; + const int margin_y = area.dy() * 5 / 100; + area.bloat(std::max(margin_x, margin_y), area); + } + + // Determine scale (pixels per DBU). + double scale = 0; + if (width_px > 0) { + scale = static_cast(width_px) / area.dx(); + } else if (dbu_per_pixel > 0) { + scale = 1.0 / dbu_per_pixel; + } else { + // Default: 1024px wide. + scale = 1024.0 / area.dx(); + } + + const int img_w = static_cast(std::ceil(area.dx() * scale)); + const int img_h = static_cast(std::ceil(area.dy() * scale)); + + if (img_w <= 0 || img_h <= 0) { + logger_->error(utl::WEB, 21, "Invalid image dimensions."); + return; + } + + // Cap image size at 16k x 16k to prevent excessive memory usage. + constexpr int kMaxDim = 16384; + if (img_w > kMaxDim || img_h > kMaxDim) { + logger_->warn(utl::WEB, + 22, + "Image dimensions {}x{} exceed max {}; clamping.", + img_w, + img_h, + kMaxDim); + scale = std::min(static_cast(kMaxDim) / area.dx(), + static_cast(kMaxDim) / area.dy()); + } + + const int final_w = static_cast(std::ceil(area.dx() * scale)); + const int final_h = static_cast(std::ceil(area.dy() * scale)); + + // Compute zoom level that gives tile_scale close to our target scale. + // tile_scale = kTileSizeInPixel / (maxDXDY / 2^z) + // We want tile_scale >= scale, so z = ceil(log2(scale * maxDXDY / 256)). + const odb::Rect bounds = getBounds(); + const double max_dxdy = bounds.maxDXDY(); + const int z = std::max(0, + static_cast(std::ceil( + std::log2(scale * max_dxdy / kTileSizeInPixel)))); + const int num_tiles = static_cast(std::pow(2, z)); + const double tile_dbu_size = max_dxdy / num_tiles; + const double tile_scale = kTileSizeInPixel / tile_dbu_size; + + // Determine which tiles overlap our area. + const int tx_min = std::max( + 0, static_cast((area.xMin() - bounds.xMin()) / tile_dbu_size)); + const int ty_min = std::max( + 0, static_cast((area.yMin() - bounds.yMin()) / tile_dbu_size)); + const int tx_max + = std::min(num_tiles - 1, + static_cast( + std::ceil((area.xMax() - bounds.xMin()) / tile_dbu_size))); + const int ty_max + = std::min(num_tiles - 1, + static_cast( + std::ceil((area.yMax() - bounds.yMin()) / tile_dbu_size))); + + // Allocate output buffer (RGBA). + const int tile_span_w = (tx_max - tx_min + 1) * kTileSizeInPixel; + const int tile_span_h = (ty_max - ty_min + 1) * kTileSizeInPixel; + std::vector output(4UL * tile_span_w * tile_span_h, 0); + + // Layers to render (bottom to top): _instances, tech layers, _pins. + std::vector layers_to_render; + layers_to_render.emplace_back("_instances"); + for (const auto& name : getLayers()) { + layers_to_render.push_back(name); + } + if (vis.pin_markers) { + layers_to_render.emplace_back("_pins"); + } + + // Render each tile, compositing all layers. + for (int ty = ty_min; ty <= ty_max; ++ty) { + for (int tx = tx_min; tx <= tx_max; ++tx) { + // Tile position in the output buffer. + const int out_ox = (tx - tx_min) * kTileSizeInPixel; + // Y is flipped: tile_y in generateTile is bottom-up, output is top-down. + const int out_oy = (ty_max - ty) * kTileSizeInPixel; + + // Leaflet-style y coordinate (before the flip in renderTileBuffer). + const int leaflet_y = num_tiles - 1 - ty; + + for (const auto& layer : layers_to_render) { + auto tile_buf = renderTileBuffer(layer, z, tx, leaflet_y, vis); + + // Composite tile onto output at (out_ox, out_oy). + for (int py = 0; py < kTileSizeInPixel; ++py) { + for (int px = 0; px < kTileSizeInPixel; ++px) { + const int src_idx = (py * kTileSizeInPixel + px) * 4; + const int dst_x = out_ox + px; + const int dst_y = out_oy + py; + if (dst_x >= tile_span_w || dst_y >= tile_span_h) { + continue; + } + const int dst_idx = (dst_y * tile_span_w + dst_x) * 4; + compositePixel(&output[dst_idx], &tile_buf[src_idx]); + } + } + } + } + } + + // Crop to the exact requested area. + // The tile span covers a larger region; compute the pixel offset of the + // area's origin within the tile span. + const int crop_x = static_cast( + (area.xMin() - bounds.xMin() - tx_min * tile_dbu_size) * tile_scale); + const int crop_y_bottom = static_cast( + (area.yMin() - bounds.yMin() - ty_min * tile_dbu_size) * tile_scale); + // In the output buffer, y=0 is the top (ty_max), and area.yMin maps + // to the bottom. The crop origin in output coords: + const int crop_y + = tile_span_h - crop_y_bottom - static_cast(area.dy() * tile_scale); + + // Resample to exact requested dimensions (nearest-neighbor from tile_scale + // to target scale). + std::vector final_buf(4UL * final_w * final_h, 0); + for (int fy = 0; fy < final_h; ++fy) { + for (int fx = 0; fx < final_w; ++fx) { + // Map final pixel to tile-span pixel. + const int sx = crop_x + static_cast(fx * tile_scale / scale); + const int sy = crop_y + static_cast(fy * tile_scale / scale); + if (sx >= 0 && sx < tile_span_w && sy >= 0 && sy < tile_span_h) { + const int src_idx = (sy * tile_span_w + sx) * 4; + const int dst_idx = (fy * final_w + fx) * 4; + std::memcpy(&final_buf[dst_idx], &output[src_idx], 4); + } + } + } + + // Encode to PNG and save. + std::vector png_data; + const unsigned error = lodepng::encode(png_data, final_buf, final_w, final_h); + if (error) { + logger_->error( + utl::WEB, 23, "PNG encode error: {}", lodepng_error_text(error)); + return; + } + lodepng::save_file(png_data, filename); + logger_->info( + utl::WEB, 24, "Saved {}x{} image to {}", final_w, final_h, filename); +} + void TileGenerator::drawDebugOverlay(std::vector& image, const int z, const int x, @@ -1418,6 +1892,51 @@ void TileGenerator::drawBitmapText(std::vector& image, } } +/* static */ +void TileGenerator::drawBitmapTextRotated(std::vector& image, + const int x, + const int y, + const std::string_view text, + const int scale, + const Color& color) +{ + // 90° CW rotation: original (col, row) → (H-1-row, col) + // where H = kBitmapGlyphHeight. Characters stack downward (y increasing). + int cursor_y = y; + for (const char ch : text) { + if (ch == ' ') { + cursor_y += getBitmapGlyphAdvance(ch) * scale; + continue; + } + + const unsigned char* glyph = getBitmapGlyph(ch); + if (glyph == nullptr) { + cursor_y += getBitmapGlyphAdvance(ch) * scale; + continue; + } + + // Rotated glyph: width = kBitmapGlyphHeight, height = kBitmapGlyphWidth + for (int row = 0; row < kBitmapGlyphHeight; ++row) { + const unsigned char bits = glyph[row]; + for (int col = 0; col < kBitmapGlyphWidth; ++col) { + if ((bits & (0x10 >> col)) == 0) { + continue; + } + // 90° CW: (col, row) → screen (x + (H-1-row), cursor_y + col) + const int px = x + (kBitmapGlyphHeight - 1 - row) * scale; + const int py = cursor_y + col * scale; + for (int sy = 0; sy < scale; ++sy) { + for (int sx = 0; sx < scale; ++sx) { + blendPixel(image, px + sx, py + sy, color); + } + } + } + } + + cursor_y += getBitmapGlyphAdvance(ch) * scale; + } +} + /* static */ void TileGenerator::blendPixel(std::vector& image, const int x, diff --git a/src/web/src/tile_generator.h b/src/web/src/tile_generator.h index 6e60f81acdd..8e8e1003475 100644 --- a/src/web/src/tile_generator.h +++ b/src/web/src/tile_generator.h @@ -102,6 +102,7 @@ struct TileVisibility bool routing = true; bool special_nets = true; bool pins = true; + bool pin_markers = true; bool blockages = true; // Blockages (dbBlockage / dbObstruction) @@ -139,6 +140,7 @@ class TileGenerator sta::dbSta* getSta() const { return sta_; } odb::Rect getBounds() const; + int getPinMaxSize() const; std::vector getLayers() const; std::vector getSites() const; @@ -187,7 +189,30 @@ class TileGenerator int x, int y) const; + // Render full design (or region) to a PNG file. Works without a running + // web server. region in DBU; if zero-area, defaults to die + 5% margin. + void saveImage(const std::string& filename, + const odb::Rect& region, + int width_px, + double dbu_per_pixel, + const TileVisibility& vis) const; + private: + // Render a single tile into a raw RGBA buffer (pre-PNG-encoding). + // Same signature as generateTile but returns raw pixels. + std::vector renderTileBuffer( + const std::string& layer, + int z, + int x, + int y, + const TileVisibility& vis = {}, + const std::vector& highlight_rects = {}, + const std::vector& highlight_polys = {}, + const std::vector& colored_rects = {}, + const std::vector& flight_lines = {}, + const std::map* module_colors = nullptr, + const std::set* focus_net_ids = nullptr, + const std::set* route_guide_net_ids = nullptr) const; void setPixel(std::vector& image, int x, int y, @@ -206,6 +231,14 @@ class TileGenerator std::string_view text, int scale, const Color& color); + // Draw text rotated 90° CCW (reads bottom-to-top). + // (x, y) is the bottom-left corner of the rotated text block. + static void drawBitmapTextRotated(std::vector& image, + int x, + int y, + std::string_view text, + int scale, + const Color& color); void drawHighlight(std::vector& image, const std::vector& rects, diff --git a/src/web/src/web.cpp b/src/web/src/web.cpp index e8ae4bcf6f9..fa8d423d44e 100644 --- a/src/web/src/web.cpp +++ b/src/web/src/web.cpp @@ -1000,6 +1000,29 @@ WebServer::WebServer(odb::dbDatabase* db, WebServer::~WebServer() = default; +void WebServer::saveImage(const std::string& filename, + const int x0, + const int y0, + const int x1, + const int y1, + const int width_px, + const double dbu_per_pixel, + const std::string& vis_json) +{ + // Create generator on demand (server may not be running). + if (!generator_) { + generator_ = std::make_shared(db_, sta_, logger_); + } + generator_->eagerInit(); + + const odb::Rect region(x0, y0, x1, y1); + TileVisibility vis; + if (!vis_json.empty()) { + vis.parseFromJson(vis_json); + } + generator_->saveImage(filename, region, width_px, dbu_per_pixel, vis); +} + void WebServer::serve(int port, const std::string& doc_root) { try { diff --git a/src/web/src/web.i b/src/web/src/web.i index 3aa4d413819..16f83115d21 100644 --- a/src/web/src/web.i +++ b/src/web/src/web.i @@ -19,6 +19,17 @@ web_server_cmd(int port, const char* doc_root) server->serve(port, doc_root); } +void +save_image_cmd(const char* filename, + int x0, int y0, int x1, int y1, + int width, double resolution, + const char* vis_json) +{ + web::WebServer *server = ord::OpenRoad::openRoad()->getWebServer(); + server->saveImage(filename, x0, y0, x1, y1, width, resolution, + vis_json ? vis_json : ""); +} + } // namespace web %} // inline diff --git a/src/web/src/web.tcl b/src/web/src/web.tcl index aa331913567..10954f84b8e 100644 --- a/src/web/src/web.tcl +++ b/src/web/src/web.tcl @@ -20,3 +20,109 @@ proc web_server { args } { web::web_server_cmd $port $keys(-dir) } + +sta::define_cmd_args "save_image" {[-web] \ + [-area {x0 y0 x1 y1}] \ + [-width width] \ + [-resolution microns_per_pixel] \ + [-display_option option] \ + path +} + +proc save_image { args } { + ord::parse_list_args "save_image" args list {-display_option} + sta::parse_key_args "save_image" args \ + keys {-area -width -resolution} flags {-web} + + set use_web [info exists flags(-web)] + + set resolution 0 + if { [info exists keys(-resolution)] } { + sta::check_positive_float "-resolution" $keys(-resolution) + set db [ord::get_db] + set resolution [expr $keys(-resolution) * [$db getDbuPerMicron]] + if { $resolution < 1 } { + set resolution 1.0 + set res_per_pixel [expr $resolution / [$db getDbuPerMicron]] + utl::warn WEB 25 "Resolution too high for design, defaulting to ${res_per_pixel}um per pixel" + } + } + + set area "0 0 0 0" + if { [info exists keys(-area)] } { + set area $keys(-area) + if { [llength $area] != 4 } { + utl::error WEB 26 "Area must contain 4 elements." + } + } + + set width 0 + if { [info exists keys(-width)] } { + if { $resolution != 0 } { + utl::error WEB 27 "Cannot set -width if -resolution has already been specified." + } + sta::check_positive_int "-width" $keys(-width) + set width $keys(-width) + if { $width == 0 } { + utl::error WEB 29 "Specified -width cannot be zero." + } + } + + sta::check_argc_eq1 "save_image" $args + set path [lindex $args 0] + + if { $use_web } { + # Convert area from microns to DBU for the web renderer. + set web_area $area + if { + [lindex $area 0] != 0 || [lindex $area 1] != 0 + || [lindex $area 2] != 0 || [lindex $area 3] != 0 + } { + set db [ord::get_db] + set dbu [$db getDbuPerMicron] + set web_area [list \ + [expr { int([lindex $area 0] * $dbu) }] \ + [expr { int([lindex $area 1] * $dbu) }] \ + [expr { int([lindex $area 2] * $dbu) }] \ + [expr { int([lindex $area 3] * $dbu) }]] + } + + # Build visibility JSON from display options. + set vis_json "" + if { [llength $list(-display_option)] > 0 } { + set pairs {} + foreach opt $list(-display_option) { + if { [llength $opt] != 2 } { + utl::error WEB 28 "Display option must have 2 elements {control} {value}." + } + set key [lindex $opt 0] + set val [lindex $opt 1] + if { $val eq "true" || $val eq "1" } { + set val 1 + } else { + set val 0 + } + lappend pairs "\"$key\":$val" + } + set vis_json "\{[join $pairs ,]\}" + } + + web::save_image_cmd $path \ + [lindex $web_area 0] [lindex $web_area 1] \ + [lindex $web_area 2] [lindex $web_area 3] \ + $width $resolution $vis_json + } else { + # Dispatch to the GUI renderer. + set options [gui::DisplayControlMap] + foreach opt $list(-display_option) { + if { [llength $opt] != 2 } { + utl::error GUI 19 "Display option must have 2 elements {control name} {value}." + } + $options set [lindex $opt 0] [lindex $opt 1] + } + + gui::save_image $path {*}$area $width $resolution $options + + rename $options "" + } +} diff --git a/src/web/test/BUILD b/src/web/test/BUILD index a096501b683..7972d6f27d2 100644 --- a/src/web/test/BUILD +++ b/src/web/test/BUILD @@ -178,6 +178,27 @@ cc_test( ], ) +cc_test( + name = "save_image_test", + srcs = ["cpp/TestSaveImage.cpp"], + copts = ["-Isrc/web/src"], + data = [ + "//test:nangate45_data", + ], + features = ["-layering_check"], + deps = [ + "//src/gui", + "//src/odb", + "//src/tst", + "//src/tst:nangate45_fixture", + "//src/utl", + "//src/web", + "//third-party/lodepng", + "@googletest//:gtest", + "@googletest//:gtest_main", + ], +) + cc_test( name = "snap_test", srcs = ["cpp/TestSnap.cpp"], diff --git a/src/web/test/cpp/TestSaveImage.cpp b/src/web/test/cpp/TestSaveImage.cpp new file mode 100644 index 00000000000..9bb5b8e0686 --- /dev/null +++ b/src/web/test/cpp/TestSaveImage.cpp @@ -0,0 +1,278 @@ +// SPDX-License-Identifier: BSD-3-Clause +// Copyright (c) 2026, The OpenROAD Authors + +#include +#include +#include +#include +#include +#include + +#include "gtest/gtest.h" +#include "lodepng.h" +#include "odb/db.h" +#include "odb/dbTypes.h" +#include "tile_generator.h" +#include "tst/nangate45_fixture.h" + +namespace web { +namespace { + +class SaveImageTest : public tst::Nangate45Fixture +{ + protected: + void SetUp() override + { + block_->setDieArea(odb::Rect(0, 0, 100000, 100000)); + placeInst("BUF_X16", "buf1", 10000, 10000); + makeTileGen(); + } + + void TearDown() override + { + // Clean up any output files. + for (const auto& path : output_files_) { + std::filesystem::remove(path); + } + } + + void makeTileGen() + { + tile_gen_ = std::make_unique( + getDb(), /*sta=*/nullptr, getLogger()); + tile_gen_->eagerInit(); + } + + odb::dbInst* placeInst(const char* master_name, + const char* inst_name, + int x, + int y) + { + odb::dbMaster* master = lib_->findMaster(master_name); + EXPECT_NE(master, nullptr) << "Master not found: " << master_name; + odb::dbInst* inst = odb::dbInst::create(block_, master, inst_name); + inst->setLocation(x, y); + inst->setPlacementStatus(odb::dbPlacementStatus::PLACED); + return inst; + } + + // Create a BTerm pin on a metal layer at the die boundary. + void makeBTermAtEdge(const char* name, + const char* layer_name, + int x, + int y, + int w, + int h, + odb::dbIoType io_type = odb::dbIoType::INPUT) + { + odb::dbNet* net = odb::dbNet::create(block_, name); + odb::dbBTerm* bterm = odb::dbBTerm::create(net, name); + bterm->setIoType(io_type); + odb::dbBPin* bpin = odb::dbBPin::create(bterm); + odb::dbTechLayer* layer = getDb()->getTech()->findLayer(layer_name); + ASSERT_NE(layer, nullptr); + odb::dbBox::create(bpin, layer, x, y, x + w, y + h); + bpin->setPlacementStatus(odb::dbPlacementStatus::PLACED); + } + + // Save to a temp file and register for cleanup. + std::string tempPng(const std::string& label) + { + std::string path = std::filesystem::temp_directory_path() + / ("web_test_" + label + ".png"); + output_files_.push_back(path); + return path; + } + + // Decode a PNG file from disk; returns RGBA pixels. + std::vector decodePngFile(const std::string& path, + unsigned& width, + unsigned& height) + { + std::vector pixels; + unsigned err = lodepng::decode(pixels, width, height, path); + EXPECT_EQ(err, 0u) << lodepng_error_text(err); + return pixels; + } + + static bool hasNonTransparentPixel(const std::vector& rgba) + { + for (size_t i = 3; i < rgba.size(); i += 4) { + if (rgba[i] > 0) { + return true; + } + } + return false; + } + + std::unique_ptr tile_gen_; + std::vector output_files_; +}; + +// ─── Basic functionality ───────────────────────────────────────────────────── + +TEST_F(SaveImageTest, DefaultProducesValidPng) +{ + const std::string path = tempPng("default"); + tile_gen_->saveImage(path, odb::Rect(0, 0, 0, 0), 0, 0, {}); + + ASSERT_TRUE(std::filesystem::exists(path)); + unsigned w = 0, h = 0; + auto pixels = decodePngFile(path, w, h); + EXPECT_GT(w, 0u); + EXPECT_GT(h, 0u); + // Should contain visible content (placed instance). + EXPECT_TRUE(hasNonTransparentPixel(pixels)); +} + +TEST_F(SaveImageTest, WidthOption) +{ + const std::string path = tempPng("width"); + tile_gen_->saveImage(path, odb::Rect(0, 0, 0, 0), 512, 0, {}); + + unsigned w = 0, h = 0; + decodePngFile(path, w, h); + EXPECT_EQ(w, 512u); +} + +TEST_F(SaveImageTest, ResolutionOption) +{ + const std::string path = tempPng("resolution"); + // 10 dbu per pixel on a 100000 dbu (+margin) design → ~10000+ pixels wide. + // Use a coarser resolution to keep the test fast. + const double dbu_per_pixel = 100.0; + tile_gen_->saveImage(path, odb::Rect(0, 0, 0, 0), 0, dbu_per_pixel, {}); + + unsigned w = 0, h = 0; + decodePngFile(path, w, h); + // Expected: ~100000 / 100 * 1.05 (bloat) ≈ 1050. + // Allow some tolerance for rounding and bloat margin. + EXPECT_GT(w, 500u); + EXPECT_LT(w, 2000u); +} + +TEST_F(SaveImageTest, ExplicitAreaOption) +{ + const std::string path = tempPng("area"); + // Render only the bottom-left quadrant. + const odb::Rect area(0, 0, 50000, 50000); + tile_gen_->saveImage(path, area, 256, 0, {}); + + unsigned w = 0, h = 0; + auto pixels = decodePngFile(path, w, h); + EXPECT_EQ(w, 256u); + // Aspect ratio should be ~1:1 for a square area. + EXPECT_EQ(h, 256u); +} + +// ─── Visibility options ────────────────────────────────────────────────────── + +TEST_F(SaveImageTest, VisibilityStdcellsOff) +{ + const std::string path = tempPng("vis_off"); + TileVisibility vis; + vis.stdcells = false; + // With stdcells hidden and no routing, the _instances layer should be empty. + tile_gen_->saveImage(path, odb::Rect(0, 0, 0, 0), 256, 0, vis); + + unsigned w = 0, h = 0; + auto pixels = decodePngFile(path, w, h); + EXPECT_FALSE(hasNonTransparentPixel(pixels)); +} + +TEST_F(SaveImageTest, VisibilityPinMarkersOff) +{ + // Place a BTerm to generate pin markers. + makeBTermAtEdge("clk", "metal1", 0, 50000, 200, 200); + makeTileGen(); + + const std::string path_on = tempPng("pins_on"); + TileVisibility vis_on; + vis_on.stdcells = false; + tile_gen_->saveImage(path_on, odb::Rect(0, 0, 0, 0), 512, 0, vis_on); + + const std::string path_off = tempPng("pins_off"); + TileVisibility vis_off; + vis_off.stdcells = false; + vis_off.pin_markers = false; + tile_gen_->saveImage(path_off, odb::Rect(0, 0, 0, 0), 512, 0, vis_off); + + unsigned w1 = 0, h1 = 0, w2 = 0, h2 = 0; + auto pixels_on = decodePngFile(path_on, w1, h1); + auto pixels_off = decodePngFile(path_off, w2, h2); + + // With pin_markers on, there should be visible content from the marker. + // With it off, less or no content. + EXPECT_TRUE(hasNonTransparentPixel(pixels_on)); + // The two images should differ. + EXPECT_NE(pixels_on, pixels_off); +} + +// ─── Edge cases ────────────────────────────────────────────────────────────── + +TEST_F(SaveImageTest, EmptyDesign) +{ + // Create a fresh block with no instances. + odb::dbChip::destroy(chip_); + chip_ = odb::dbChip::create(getDb(), getDb()->getTech()); + block_ = odb::dbBlock::create(chip_, "empty"); + block_->setDefUnits(lib_->getTech()->getLefUnits()); + block_->setDieArea(odb::Rect(0, 0, 100000, 100000)); + makeTileGen(); + + const std::string path = tempPng("empty"); + tile_gen_->saveImage(path, odb::Rect(0, 0, 0, 0), 256, 0, {}); + + ASSERT_TRUE(std::filesystem::exists(path)); + unsigned w = 0, h = 0; + auto pixels = decodePngFile(path, w, h); + EXPECT_EQ(w, 256u); + // Empty design should produce a transparent image. + EXPECT_FALSE(hasNonTransparentPixel(pixels)); +} + +TEST_F(SaveImageTest, LargeWidthClamped) +{ + const std::string path = tempPng("clamped"); + // Request a very large image; should be clamped to max dimension. + tile_gen_->saveImage(path, odb::Rect(0, 0, 0, 0), 100000, 0, {}); + + unsigned w = 0, h = 0; + decodePngFile(path, w, h); + EXPECT_LE(w, 16384u); + EXPECT_LE(h, 16384u); +} + +TEST_F(SaveImageTest, PinMarkersRendered) +{ + makeBTermAtEdge("in_pin", "metal1", 0, 40000, 200, 200, odb::dbIoType::INPUT); + makeBTermAtEdge( + "out_pin", "metal1", 99800, 60000, 200, 200, odb::dbIoType::OUTPUT); + makeTileGen(); + + const std::string path = tempPng("pin_markers"); + TileVisibility vis; + vis.stdcells = false; + tile_gen_->saveImage(path, odb::Rect(0, 0, 0, 0), 512, 0, vis); + + unsigned w = 0, h = 0; + auto pixels = decodePngFile(path, w, h); + EXPECT_TRUE(hasNonTransparentPixel(pixels)); +} + +TEST_F(SaveImageTest, MultipleLayersComposited) +{ + // Place instances to generate content on multiple layers. + placeInst("BUF_X16", "buf2", 50000, 50000); + makeTileGen(); + + const std::string path = tempPng("multi_layer"); + tile_gen_->saveImage(path, odb::Rect(0, 0, 0, 0), 512, 0, {}); + + unsigned w = 0, h = 0; + auto pixels = decodePngFile(path, w, h); + EXPECT_TRUE(hasNonTransparentPixel(pixels)); +} + +} // namespace +} // namespace web diff --git a/test/aes_sky130hs.metrics b/test/aes_sky130hs.metrics index a8e93637017..d72debbc5b5 100644 --- a/test/aes_sky130hs.metrics +++ b/test/aes_sky130hs.metrics @@ -8,7 +8,7 @@ "design__instance__displacement__max": 10.614, "route__wirelength__estimated": 1.25688e+06, "RSZ::repair_design_buffer_count": "742", - "RSZ::max_slew_slack": "19.296753406524658", + "RSZ::max_slew_slack": "19.2961648106575", "RSZ::max_fanout_slack": "100.0", "RSZ::max_capacitance_slack": "21.4689486280825", "design__instance__displacement__total": 643.952, @@ -18,7 +18,7 @@ "design__instance__count__setup_buffer": 1480, "design__instance__count__hold_buffer": 109, "RSZ::worst_slack_min": "0.0008305578682118604", - "RSZ::worst_slack_max": "-0.8175194086419096", + "RSZ::worst_slack_max": "-0.817519852731132", "RSZ::tns_max": "-97.81004727440795", "RSZ::hold_buffer_count": "109", "design__instance__displacement__total": 14189.7, @@ -40,55 +40,55 @@ "grt__antenna__violating__nets": 0, "grt__antenna__violating__pins": 0, "GRT::ANT::errors": "0", - "route__drc_errors__iter:0": 6067, - "route__wirelength__iter:0": 1729531, - "route__drc_errors__iter:1": 1680, - "route__wirelength__iter:1": 1725516, - "route__drc_errors__iter:2": 1082, - "route__wirelength__iter:2": 1724464, - "route__drc_errors__iter:3": 8, - "route__wirelength__iter:3": 1724667, + "route__drc_errors__iter:0": 6454, + "route__wirelength__iter:0": 1729780, + "route__drc_errors__iter:1": 1849, + "route__wirelength__iter:1": 1725589, + "route__drc_errors__iter:2": 1231, + "route__wirelength__iter:2": 1724365, + "route__drc_errors__iter:3": 11, + "route__wirelength__iter:3": 1724564, "route__drc_errors__iter:4": 0, - "route__wirelength__iter:4": 1724666, + "route__wirelength__iter:4": 1724566, "route__drc_errors": 0, - "route__wirelength": 1724666, - "route__vias": 155066, - "route__vias__singlecut": 155066, + "route__wirelength": 1724566, + "route__vias": 155234, + "route__vias__singlecut": 155234, "route__vias__multicut": 0, "DRT::drv": "0", - "drt__repair_antennas__pre_repair__antenna__violating__nets": 191, + "drt__repair_antennas__pre_repair__antenna__violating__nets": 190, "drt__repair_antennas__pre_repair__antenna__violating__pins": 193, - "drt__repair_antennas__iter_0__global_route__vias": 2008, - "drt__repair_antennas__iter_0__antenna_diodes_count": 607, - "drt__repair_antennas__iter_0__route__drc_errors__iter:0": 883, - "drt__repair_antennas__iter_0__route__wirelength__iter:0": 1725506, - "drt__repair_antennas__iter_0__route__drc_errors__iter:1": 117, - "drt__repair_antennas__iter_0__route__wirelength__iter:1": 1725389, - "drt__repair_antennas__iter_0__route__drc_errors__iter:2": 72, - "drt__repair_antennas__iter_0__route__wirelength__iter:2": 1725372, + "drt__repair_antennas__iter_0__global_route__vias": 1961, + "drt__repair_antennas__iter_0__antenna_diodes_count": 606, + "drt__repair_antennas__iter_0__route__drc_errors__iter:0": 938, + "drt__repair_antennas__iter_0__route__wirelength__iter:0": 1725465, + "drt__repair_antennas__iter_0__route__drc_errors__iter:1": 113, + "drt__repair_antennas__iter_0__route__wirelength__iter:1": 1725372, + "drt__repair_antennas__iter_0__route__drc_errors__iter:2": 88, + "drt__repair_antennas__iter_0__route__wirelength__iter:2": 1725379, "drt__repair_antennas__iter_0__route__drc_errors__iter:3": 0, - "drt__repair_antennas__iter_0__route__wirelength__iter:3": 1725152, + "drt__repair_antennas__iter_0__route__wirelength__iter:3": 1725180, "drt__repair_antennas__iter_0__route__drc_errors": 0, - "drt__repair_antennas__iter_0__route__wirelength": 1725152, - "drt__repair_antennas__iter_0__route__vias": 155613, - "drt__repair_antennas__iter_0__route__vias__singlecut": 155613, + "drt__repair_antennas__iter_0__route__wirelength": 1725180, + "drt__repair_antennas__iter_0__route__vias": 155771, + "drt__repair_antennas__iter_0__route__vias__singlecut": 155771, "drt__repair_antennas__iter_0__route__vias__multicut": 0, - "drt__repair_antennas__iter_0__antenna__violating__nets": 6, - "drt__repair_antennas__iter_0__antenna__violating__pins": 7, - "drt__repair_antennas__iter_1__global_route__vias": 161, - "drt__repair_antennas__iter_1__antenna_diodes_count": 640, - "drt__repair_antennas__iter_1__route__drc_errors__iter:0": 50, - "drt__repair_antennas__iter_1__route__wirelength__iter:0": 1725275, - "drt__repair_antennas__iter_1__route__drc_errors__iter:1": 4, - "drt__repair_antennas__iter_1__route__wirelength__iter:1": 1725265, - "drt__repair_antennas__iter_1__route__drc_errors__iter:2": 3, - "drt__repair_antennas__iter_1__route__wirelength__iter:2": 1725265, + "drt__repair_antennas__iter_0__antenna__violating__nets": 9, + "drt__repair_antennas__iter_0__antenna__violating__pins": 10, + "drt__repair_antennas__iter_1__global_route__vias": 207, + "drt__repair_antennas__iter_1__antenna_diodes_count": 662, + "drt__repair_antennas__iter_1__route__drc_errors__iter:0": 77, + "drt__repair_antennas__iter_1__route__wirelength__iter:0": 1725379, + "drt__repair_antennas__iter_1__route__drc_errors__iter:1": 2, + "drt__repair_antennas__iter_1__route__wirelength__iter:1": 1725354, + "drt__repair_antennas__iter_1__route__drc_errors__iter:2": 1, + "drt__repair_antennas__iter_1__route__wirelength__iter:2": 1725355, "drt__repair_antennas__iter_1__route__drc_errors__iter:3": 0, - "drt__repair_antennas__iter_1__route__wirelength__iter:3": 1725233, + "drt__repair_antennas__iter_1__route__wirelength__iter:3": 1725342, "drt__repair_antennas__iter_1__route__drc_errors": 0, - "drt__repair_antennas__iter_1__route__wirelength": 1725233, - "drt__repair_antennas__iter_1__route__vias": 155672, - "drt__repair_antennas__iter_1__route__vias__singlecut": 155672, + "drt__repair_antennas__iter_1__route__wirelength": 1725342, + "drt__repair_antennas__iter_1__route__vias": 155895, + "drt__repair_antennas__iter_1__route__vias__singlecut": 155895, "drt__repair_antennas__iter_1__route__vias__multicut": 0, "drt__repair_antennas__iter_1__antenna__violating__nets": 0, "drt__repair_antennas__iter_1__antenna__violating__pins": 0, @@ -98,13 +98,13 @@ "design__violations": 0, "timing__drv__floating__nets": 0, "timing__drv__floating__pins": 0, - "DRT::worst_slack_min": "-0.07190193088883681", - "DRT::worst_slack_max": "-1.1130270353747043", - "DRT::tns_max": "-134.29334824288884", - "DRT::clock_skew": "0.3872034469317265", - "DRT::max_slew_slack": "-0.3901768010109663", + "DRT::worst_slack_min": "-0.0750716177137865", + "DRT::worst_slack_max": "-1.1179413267098905", + "DRT::tns_max": "-135.04052658323636", + "DRT::clock_skew": "0.37967385865461617", + "DRT::max_slew_slack": "-1.3513745740056038", "DRT::max_fanout_slack": "100.0", - "DRT::max_capacitance_slack": "-2.000670207788527", + "DRT::max_capacitance_slack": "-2.98574848473127", "DRT::clock_period": "2.811000", "flow__warnings__count": 27, "flow__errors__count": 0, diff --git a/test/aes_sky130hs.metrics_limits b/test/aes_sky130hs.metrics_limits index d8cce813211..f555c050947 100644 --- a/test/aes_sky130hs.metrics_limits +++ b/test/aes_sky130hs.metrics_limits @@ -7,17 +7,17 @@ ,"RSZ::max_capacitance_slack" : "0" ,"RSZ::max_fanout_slack" : "0" ,"RSZ::worst_slack_min" : "-0.28026944213178817" - ,"RSZ::worst_slack_max" : "-1.0986194086419097" + ,"RSZ::worst_slack_max" : "-1.0986198527311322" ,"RSZ::tns_max" : "-556.677687274408" ,"RSZ::hold_buffer_count" : "130" ,"GRT::ANT::errors" : "0" ,"DRT::drv" : "0" - ,"DRT::worst_slack_min" : "-0.3530019308888368" - ,"DRT::worst_slack_max" : "-1.3941270353747042" - ,"DRT::tns_max" : "-593.1609882428888" - ,"DRT::clock_skew" : "0.4646441363180718" - ,"DRT::max_slew_slack" : "-0.46821216121315956" - ,"DRT::max_capacitance_slack" : "-2.4008042493462325" + ,"DRT::worst_slack_min" : "-0.3561716177137865" + ,"DRT::worst_slack_max" : "-1.3990413267098907" + ,"DRT::tns_max" : "-593.9081665832364" + ,"DRT::clock_skew" : "0.4556086303855394" + ,"DRT::max_slew_slack" : "-1.6216494888067245" + ,"DRT::max_capacitance_slack" : "-3.582898181677524" ,"DRT::max_fanout_slack" : "0" ,"DRT::clock_period" : "2.811" ,"DRT::ANT::errors" : "0" diff --git a/test/jpeg_sky130hd.metrics b/test/jpeg_sky130hd.metrics index e4f109f4b23..438b04f7dd4 100644 --- a/test/jpeg_sky130hd.metrics +++ b/test/jpeg_sky130hd.metrics @@ -8,137 +8,118 @@ "design__instance__displacement__max": 11.594, "route__wirelength__estimated": 1.53777e+06, "RSZ::repair_design_buffer_count": "339", - "RSZ::max_slew_slack": "16.61500632762909", + "RSZ::max_slew_slack": "16.406350334485374", "RSZ::max_fanout_slack": "100.0", "RSZ::max_capacitance_slack": "28.672422793354542", "design__instance__displacement__total": 3482.11, "design__instance__displacement__mean": 0.046, "design__instance__displacement__max": 10.124, "route__wirelength__estimated": 1.597e+06, - "design__instance__count__setup_buffer": 151, + "design__instance__count__setup_buffer": 150, "design__instance__count__hold_buffer": 29, - "RSZ::worst_slack_min": "0.015490498211486167", - "RSZ::worst_slack_max": "-0.05001244004934275", - "RSZ::tns_max": "-0.16355095518595736", + "RSZ::worst_slack_min": "0.012663426221625614", + "RSZ::worst_slack_max": "-0.09150014338530768", + "RSZ::tns_max": "-0.3933076198272071", "RSZ::hold_buffer_count": "29", - "design__instance__displacement__total": 1361.47, + "design__instance__displacement__total": 1349.66, "design__instance__displacement__mean": 0.018, "design__instance__displacement__max": 12.388, - "route__wirelength__estimated": 1.64052e+06, - "DPL::utilization": "21.1", - "DPL::design_area": "460409", + "route__wirelength__estimated": 1.63959e+06, + "DPL::utilization": "22.7", + "DPL::design_area": "496953", "route__net": 57386, "route__net__special": 2, - "global_route__vias": 369892, - "global_route__wirelength": 2697610, - "grt__global_route__vias": 3012, + "global_route__vias": 369917, + "global_route__wirelength": 2696761, + "grt__global_route__vias": 2816, "grt__global_route__vias": 54, "grt__global_route__vias": 58, - "grt__antenna_diodes_count": 60, + "grt__antenna_diodes_count": 54, "grt__antenna__violating__nets": 0, "grt__antenna__violating__pins": 0, "GRT::ANT::errors": "0", - "route__drc_errors__iter:0": 6451, - "route__wirelength__iter:0": 1839203, - "route__drc_errors__iter:1": 862, - "route__wirelength__iter:1": 1830974, - "route__drc_errors__iter:2": 383, - "route__wirelength__iter:2": 1830132, - "route__drc_errors__iter:3": 17, - "route__wirelength__iter:3": 1830101, - "route__drc_errors__iter:4": 0, - "route__wirelength__iter:4": 1830097, + "route__drc_errors__iter:0": 6652, + "route__wirelength__iter:0": 1837848, + "route__drc_errors__iter:1": 919, + "route__wirelength__iter:1": 1829816, + "route__drc_errors__iter:2": 398, + "route__wirelength__iter:2": 1828882, + "route__drc_errors__iter:3": 0, + "route__wirelength__iter:3": 1828879, "route__drc_errors": 0, - "route__wirelength": 1830097, - "route__vias": 313497, - "route__vias__singlecut": 313497, + "route__wirelength": 1828879, + "route__vias": 313415, + "route__vias__singlecut": 313415, "route__vias__multicut": 0, "DRT::drv": "0", - "drt__repair_antennas__pre_repair__antenna__violating__nets": 186, - "drt__repair_antennas__pre_repair__antenna__violating__pins": 246, - "drt__repair_antennas__iter_0__global_route__vias": 5662, - "drt__repair_antennas__iter_0__antenna_diodes_count": 334, - "drt__repair_antennas__iter_0__route__drc_errors__iter:0": 1540, - "drt__repair_antennas__iter_0__route__wirelength__iter:0": 1830188, - "drt__repair_antennas__iter_0__route__drc_errors__iter:1": 182, - "drt__repair_antennas__iter_0__route__wirelength__iter:1": 1829809, - "drt__repair_antennas__iter_0__route__drc_errors__iter:2": 126, - "drt__repair_antennas__iter_0__route__wirelength__iter:2": 1829794, - "drt__repair_antennas__iter_0__route__drc_errors__iter:3": 0, - "drt__repair_antennas__iter_0__route__wirelength__iter:3": 1829866, + "drt__repair_antennas__pre_repair__antenna__violating__nets": 179, + "drt__repair_antennas__pre_repair__antenna__violating__pins": 226, + "drt__repair_antennas__iter_0__global_route__vias": 5203, + "drt__repair_antennas__iter_0__antenna_diodes_count": 303, + "drt__repair_antennas__iter_0__route__drc_errors__iter:0": 1406, + "drt__repair_antennas__iter_0__route__wirelength__iter:0": 1829127, + "drt__repair_antennas__iter_0__route__drc_errors__iter:1": 180, + "drt__repair_antennas__iter_0__route__wirelength__iter:1": 1828808, + "drt__repair_antennas__iter_0__route__drc_errors__iter:2": 102, + "drt__repair_antennas__iter_0__route__wirelength__iter:2": 1828779, + "drt__repair_antennas__iter_0__route__drc_errors__iter:3": 7, + "drt__repair_antennas__iter_0__route__wirelength__iter:3": 1828797, + "drt__repair_antennas__iter_0__route__drc_errors__iter:4": 0, + "drt__repair_antennas__iter_0__route__wirelength__iter:4": 1828779, "drt__repair_antennas__iter_0__route__drc_errors": 0, - "drt__repair_antennas__iter_0__route__wirelength": 1829866, - "drt__repair_antennas__iter_0__route__vias": 313619, - "drt__repair_antennas__iter_0__route__vias__singlecut": 313619, + "drt__repair_antennas__iter_0__route__wirelength": 1828779, + "drt__repair_antennas__iter_0__route__vias": 313662, + "drt__repair_antennas__iter_0__route__vias__singlecut": 313662, "drt__repair_antennas__iter_0__route__vias__multicut": 0, - "drt__repair_antennas__iter_0__antenna__violating__nets": 20, - "drt__repair_antennas__iter_0__antenna__violating__pins": 24, - "drt__repair_antennas__iter_1__global_route__vias": 1238, - "drt__repair_antennas__iter_1__antenna_diodes_count": 361, - "drt__repair_antennas__iter_1__route__drc_errors__iter:0": 105, - "drt__repair_antennas__iter_1__route__wirelength__iter:0": 1829969, - "drt__repair_antennas__iter_1__route__drc_errors__iter:1": 5, - "drt__repair_antennas__iter_1__route__wirelength__iter:1": 1829929, - "drt__repair_antennas__iter_1__route__drc_errors__iter:2": 0, - "drt__repair_antennas__iter_1__route__wirelength__iter:2": 1829931, + "drt__repair_antennas__iter_0__antenna__violating__nets": 22, + "drt__repair_antennas__iter_0__antenna__violating__pins": 25, + "drt__repair_antennas__iter_1__global_route__vias": 1357, + "drt__repair_antennas__iter_1__antenna_diodes_count": 333, + "drt__repair_antennas__iter_1__route__drc_errors__iter:0": 164, + "drt__repair_antennas__iter_1__route__wirelength__iter:0": 1828929, + "drt__repair_antennas__iter_1__route__drc_errors__iter:1": 7, + "drt__repair_antennas__iter_1__route__wirelength__iter:1": 1828885, + "drt__repair_antennas__iter_1__route__drc_errors__iter:2": 5, + "drt__repair_antennas__iter_1__route__wirelength__iter:2": 1828887, + "drt__repair_antennas__iter_1__route__drc_errors__iter:3": 0, + "drt__repair_antennas__iter_1__route__wirelength__iter:3": 1828860, "drt__repair_antennas__iter_1__route__drc_errors": 0, - "drt__repair_antennas__iter_1__route__wirelength": 1829931, - "drt__repair_antennas__iter_1__route__vias": 313679, - "drt__repair_antennas__iter_1__route__vias__singlecut": 313679, + "drt__repair_antennas__iter_1__route__wirelength": 1828860, + "drt__repair_antennas__iter_1__route__vias": 313702, + "drt__repair_antennas__iter_1__route__vias__singlecut": 313702, "drt__repair_antennas__iter_1__route__vias__multicut": 0, - "drt__repair_antennas__iter_1__antenna__violating__nets": 4, - "drt__repair_antennas__iter_1__antenna__violating__pins": 4, - "drt__repair_antennas__iter_2__global_route__vias": 287, - "drt__repair_antennas__iter_2__antenna_diodes_count": 365, - "drt__repair_antennas__iter_2__route__drc_errors__iter:0": 40, - "drt__repair_antennas__iter_2__route__wirelength__iter:0": 1829919, - "drt__repair_antennas__iter_2__route__drc_errors__iter:1": 2, - "drt__repair_antennas__iter_2__route__wirelength__iter:1": 1829930, - "drt__repair_antennas__iter_2__route__drc_errors__iter:2": 1, - "drt__repair_antennas__iter_2__route__wirelength__iter:2": 1829931, - "drt__repair_antennas__iter_2__route__drc_errors__iter:3": 0, - "drt__repair_antennas__iter_2__route__wirelength__iter:3": 1829930, + "drt__repair_antennas__iter_1__antenna__violating__nets": 2, + "drt__repair_antennas__iter_1__antenna__violating__pins": 2, + "drt__repair_antennas__iter_2__global_route__vias": 181, + "drt__repair_antennas__iter_2__antenna_diodes_count": 335, + "drt__repair_antennas__iter_2__route__drc_errors__iter:0": 2, + "drt__repair_antennas__iter_2__route__wirelength__iter:0": 1828852, + "drt__repair_antennas__iter_2__route__drc_errors__iter:1": 0, + "drt__repair_antennas__iter_2__route__wirelength__iter:1": 1828862, "drt__repair_antennas__iter_2__route__drc_errors": 0, - "drt__repair_antennas__iter_2__route__wirelength": 1829930, - "drt__repair_antennas__iter_2__route__vias": 313687, - "drt__repair_antennas__iter_2__route__vias__singlecut": 313687, + "drt__repair_antennas__iter_2__route__wirelength": 1828862, + "drt__repair_antennas__iter_2__route__vias": 313714, + "drt__repair_antennas__iter_2__route__vias__singlecut": 313714, "drt__repair_antennas__iter_2__route__vias__multicut": 0, - "drt__repair_antennas__iter_2__antenna__violating__nets": 2, - "drt__repair_antennas__iter_2__antenna__violating__pins": 2, - "drt__repair_antennas__iter_3__global_route__vias": 189, - "drt__repair_antennas__iter_3__antenna_diodes_count": 367, - "drt__repair_antennas__iter_3__route__drc_errors__iter:0": 33, - "drt__repair_antennas__iter_3__route__wirelength__iter:0": 1829951, - "drt__repair_antennas__iter_3__route__drc_errors__iter:1": 2, - "drt__repair_antennas__iter_3__route__wirelength__iter:1": 1829938, - "drt__repair_antennas__iter_3__route__drc_errors__iter:2": 2, - "drt__repair_antennas__iter_3__route__wirelength__iter:2": 1829939, - "drt__repair_antennas__iter_3__route__drc_errors__iter:3": 0, - "drt__repair_antennas__iter_3__route__wirelength__iter:3": 1829932, - "drt__repair_antennas__iter_3__route__drc_errors": 0, - "drt__repair_antennas__iter_3__route__wirelength": 1829932, - "drt__repair_antennas__iter_3__route__vias": 313691, - "drt__repair_antennas__iter_3__route__vias__singlecut": 313691, - "drt__repair_antennas__iter_3__route__vias__multicut": 0, - "drt__repair_antennas__iter_3__antenna__violating__nets": 0, - "drt__repair_antennas__iter_3__antenna__violating__pins": 0, + "drt__repair_antennas__iter_2__antenna__violating__nets": 0, + "drt__repair_antennas__iter_2__antenna__violating__pins": 0, "drt__antenna__violating__nets": 0, "drt__antenna__violating__pins": 0, "DRT::ANT::errors": "0", "design__violations": 0, "timing__drv__floating__nets": 0, "timing__drv__floating__pins": 0, - "DRT::worst_slack_min": "0.036516568580310035", - "DRT::worst_slack_max": "-0.2307194500754341", - "DRT::tns_max": "-2.505983935738513", - "DRT::clock_skew": "0.5633924597424793", - "DRT::max_slew_slack": "-14.292257030804953", + "DRT::worst_slack_min": "0.029821479463260442", + "DRT::worst_slack_max": "-0.35063508644585295", + "DRT::tns_max": "-5.474352681671627", + "DRT::clock_skew": "0.53360251061401", + "DRT::max_slew_slack": "-21.499905983606972", "DRT::max_fanout_slack": "100.0", - "DRT::max_capacitance_slack": "-2.7863562915889113", + "DRT::max_capacitance_slack": "-1.7929347890051868", "DRT::clock_period": "8.000000", - "flow__warnings__count": 178, + "flow__warnings__count": 153, "flow__errors__count": 0, - "flow__warnings__count:DRT-0120": 150, + "flow__warnings__count:DRT-0120": 125, "flow__warnings__count:DRT-0349": 10, "flow__warnings__count:GRT-0243": 1, "flow__warnings__count:GRT-0281": 5, diff --git a/test/jpeg_sky130hd.metrics_limits b/test/jpeg_sky130hd.metrics_limits index 3faab9eb8cc..203c82f795d 100644 --- a/test/jpeg_sky130hd.metrics_limits +++ b/test/jpeg_sky130hd.metrics_limits @@ -1,23 +1,23 @@ { "IFP::instance_count" : "54760.799999999996" - ,"DPL::design_area" : "552490.7999999999" - ,"DPL::utilization" : "25.32" + ,"DPL::design_area" : "596343.6" + ,"DPL::utilization" : "27.24" ,"RSZ::repair_design_buffer_count" : "406" ,"RSZ::max_slew_slack" : "0" ,"RSZ::max_capacitance_slack" : "0" ,"RSZ::max_fanout_slack" : "0" - ,"RSZ::worst_slack_min" : "-0.7845095017885139" - ,"RSZ::worst_slack_max" : "-0.8500124400493428" - ,"RSZ::tns_max" : "-3650.883550955187" + ,"RSZ::worst_slack_min" : "-0.7873365737783744" + ,"RSZ::worst_slack_max" : "-0.8915001433853077" + ,"RSZ::tns_max" : "-3651.113307619828" ,"RSZ::hold_buffer_count" : "34" ,"GRT::ANT::errors" : "0" ,"DRT::drv" : "0" - ,"DRT::worst_slack_min" : "-0.76348343141969" - ,"DRT::worst_slack_max" : "-1.0307194500754342" - ,"DRT::tns_max" : "-3653.2259839357394" - ,"DRT::clock_skew" : "0.6760709516909752" - ,"DRT::max_slew_slack" : "-17.150708436965942" - ,"DRT::max_capacitance_slack" : "-3.3436275499066936" + ,"DRT::worst_slack_min" : "-0.7701785205367396" + ,"DRT::worst_slack_max" : "-1.150635086445853" + ,"DRT::tns_max" : "-3656.194352681672" + ,"DRT::clock_skew" : "0.6403230127368119" + ,"DRT::max_slew_slack" : "-25.799887180328366" + ,"DRT::max_capacitance_slack" : "-2.151521746806224" ,"DRT::max_fanout_slack" : "0" ,"DRT::clock_period" : "8.0" ,"DRT::ANT::errors" : "0" diff --git a/test/regression_test.sh b/test/regression_test.sh index 3464cc6718f..f6446464388 100755 --- a/test/regression_test.sh +++ b/test/regression_test.sh @@ -1,6 +1,7 @@ #!/usr/bin/env bash set -e +set -o pipefail RESULTS_DIR="${RESULTS_DIR:-results}" LOG_FILE="${RESULTS_DIR}/$TEST_NAME-$TEST_EXT.log"