diff --git a/docs/source/cmd/index_techlibs_coolrunner2.rst b/docs/source/cmd/index_techlibs_coolrunner2.rst deleted file mode 100644 index 23d91a500..000000000 --- a/docs/source/cmd/index_techlibs_coolrunner2.rst +++ /dev/null @@ -1,5 +0,0 @@ -CoolRunner-II ------------------- - -.. autocmdgroup:: techlibs/coolrunner2 - :members: diff --git a/techlibs/CMakeLists.txt b/techlibs/CMakeLists.txt index 551c80604..2fc179f60 100644 --- a/techlibs/CMakeLists.txt +++ b/techlibs/CMakeLists.txt @@ -2,7 +2,6 @@ add_subdirectory(achronix) add_subdirectory(analogdevices) add_subdirectory(anlogic) add_subdirectory(common) -add_subdirectory(coolrunner2) add_subdirectory(easic) add_subdirectory(efinix) add_subdirectory(fabulous) diff --git a/techlibs/coolrunner2/CMakeLists.txt b/techlibs/coolrunner2/CMakeLists.txt deleted file mode 100644 index a19290d92..000000000 --- a/techlibs/coolrunner2/CMakeLists.txt +++ /dev/null @@ -1,42 +0,0 @@ -yosys_pass(coolrunner2_sop - coolrunner2_sop.cc -) -yosys_pass(coolrunner2_fixup - coolrunner2_fixup.cc -) - -yosys_pass(synth_coolrunner2 - synth_coolrunner2.cc - REQUIRES - abc - attrmvcp - blackbox - check - clean - coolrunner2_fixup - coolrunner2_sop - dffinit - dfflibmap - extract - extract_counter - flatten - hierarchy - iopadmap - opt - proc - read_verilog - splitnets - stat - synth - techmap - tribuf - write_json - DATA_DIR - coolrunner2 - DATA_FILES - cells_latch.v - cells_sim.v - cells_counter_map.v - tff_extract.v - xc2_dff.lib -) diff --git a/techlibs/coolrunner2/cells_counter_map.v b/techlibs/coolrunner2/cells_counter_map.v deleted file mode 100644 index f9c44c80f..000000000 --- a/techlibs/coolrunner2/cells_counter_map.v +++ /dev/null @@ -1,162 +0,0 @@ -module \$__COUNT_ (CE, CLK, OUT, POUT, RST, UP); - - input wire CE; - input wire CLK; - output wire OUT; - (* force_downto *) - output wire[WIDTH-1:0] POUT; - input wire RST; - input wire UP; - - parameter COUNT_TO = 1; - parameter RESET_MODE = "RISING"; - parameter RESET_TO_MAX = 0; - parameter HAS_POUT = 0; - parameter HAS_CE = 0; - parameter WIDTH = 8; - parameter DIRECTION = "DOWN"; - - if (DIRECTION == "UP") begin - if (WIDTH < 2) begin - initial begin - $display("ERROR: \$__COUNT_ must be at least 2 bits wide (bug in extract_counter pass?)."); - $finish; - end - end - - // FIXME: Max width? - - assign OUT = POUT == COUNT_TO; - - if (HAS_CE) begin - genvar i; - for (i = 0; i < WIDTH; i++) begin: countbits - // each bit = (cur & !reset) ^ (all prev & !reset) - wire xor_to_mc_bitn; - FDCP #( - .INIT(0) - ) bitn_ff ( - .C(CLK), - .CLR(0), - .D(xor_to_mc_bitn), - .PRE(0), - .Q(POUT[i]) - ); - wire orterm_to_xor_bitn; - wire pterm0_to_or_bitn; - wire pterm1_to_or_bitn; - MACROCELL_XOR #( - .INVERT_OUT(0) - ) bitn_xor ( - .IN_ORTERM(orterm_to_xor_bitn), - .IN_PTC(pterm1_to_or_bitn), - .OUT(xor_to_mc_bitn) - ); - ORTERM #( - .WIDTH(1) - ) bitn_or ( - .IN(pterm0_to_or_bitn), - .OUT(orterm_to_xor_bitn) - ); - ANDTERM #( - .COMP_INP(1), - .TRUE_INP(1) - ) bitn_pterm0 ( - .IN(POUT[i]), - .IN_B(OUT), - .OUT(pterm0_to_or_bitn) - ); - ANDTERM #( - .COMP_INP(1), - .TRUE_INP(i + 1) - ) bitn_pterm1 ( - .IN({POUT[i-1:0], CE}), - .IN_B(OUT), - .OUT(pterm1_to_or_bitn) - ); - end - end else begin - // Bit0 is special; toggle unless reset - // cur reset out - // 0 0 1 - // 0 1 0 - // 1 0 0 - // 1 1 0 - wire xor_to_mc_bit0; - FDCP #( - .INIT(0) - ) bit0_ff ( - .C(CLK), - .CLR(0), - .D(xor_to_mc_bit0), - .PRE(0), - .Q(POUT[0]) - ); - wire pterm_to_xor_bit0; - MACROCELL_XOR #( - .INVERT_OUT(0) - ) bit0_xor ( - .IN_PTC(pterm_to_xor_bit0), - .OUT(xor_to_mc_bit0) - ); - ANDTERM #( - .COMP_INP(2), - .TRUE_INP(0) - ) bit0_pterm ( - .IN(), - .IN_B({POUT[0], OUT}), - .OUT(pterm_to_xor_bit0) - ); - - genvar i; - for (i = 1; i < WIDTH; i++) begin: countbits - // each bit = (cur & !reset) ^ (all prev & !reset) - wire xor_to_mc_bitn; - FDCP #( - .INIT(0) - ) bitn_ff ( - .C(CLK), - .CLR(0), - .D(xor_to_mc_bitn), - .PRE(0), - .Q(POUT[i]) - ); - wire orterm_to_xor_bitn; - wire pterm0_to_or_bitn; - wire pterm1_to_or_bitn; - MACROCELL_XOR #( - .INVERT_OUT(0) - ) bitn_xor ( - .IN_ORTERM(orterm_to_xor_bitn), - .IN_PTC(pterm1_to_or_bitn), - .OUT(xor_to_mc_bitn) - ); - ORTERM #( - .WIDTH(1) - ) bitn_or ( - .IN(pterm0_to_or_bitn), - .OUT(orterm_to_xor_bitn) - ); - ANDTERM #( - .COMP_INP(1), - .TRUE_INP(1) - ) bitn_pterm0 ( - .IN(POUT[i]), - .IN_B(OUT), - .OUT(pterm0_to_or_bitn) - ); - ANDTERM #( - .COMP_INP(1), - .TRUE_INP(i) - ) bitn_pterm1 ( - .IN(POUT[i-1:0]), - .IN_B(OUT), - .OUT(pterm1_to_or_bitn) - ); - end - end - end - - // FIXME: down counters - -endmodule diff --git a/techlibs/coolrunner2/cells_latch.v b/techlibs/coolrunner2/cells_latch.v deleted file mode 100644 index f1e19da3a..000000000 --- a/techlibs/coolrunner2/cells_latch.v +++ /dev/null @@ -1,19 +0,0 @@ -module $_DLATCH_P_(input E, input D, output Q); - LDCP _TECHMAP_REPLACE_ ( - .D(D), - .G(E), - .Q(Q), - .PRE(1'b0), - .CLR(1'b0) - ); -endmodule - -module $_DLATCH_N_(input E, input D, output Q); - LDCP_N _TECHMAP_REPLACE_ ( - .D(D), - .G(E), - .Q(Q), - .PRE(1'b0), - .CLR(1'b0) - ); -endmodule diff --git a/techlibs/coolrunner2/cells_sim.v b/techlibs/coolrunner2/cells_sim.v deleted file mode 100644 index 562fb1efd..000000000 --- a/techlibs/coolrunner2/cells_sim.v +++ /dev/null @@ -1,310 +0,0 @@ -module IBUF(input I, output O); - assign O = I; -endmodule - -module IOBUFE(input I, input E, output O, inout IO); - assign O = IO; - assign IO = E ? I : 1'bz; -endmodule - -module ANDTERM(IN, IN_B, OUT); - parameter TRUE_INP = 0; - parameter COMP_INP = 0; - - input [TRUE_INP-1:0] IN; - input [COMP_INP-1:0] IN_B; - output reg OUT; - - integer i; - - always @(*) begin - OUT = 1; - for (i = 0; i < TRUE_INP; i=i+1) - OUT = OUT & IN[i]; - for (i = 0; i < COMP_INP; i=i+1) - OUT = OUT & ~IN_B[i]; - end -endmodule - -module ORTERM(IN, OUT); - parameter WIDTH = 0; - - input [WIDTH-1:0] IN; - output reg OUT; - - integer i; - - always @(*) begin - OUT = 0; - for (i = 0; i < WIDTH; i=i+1) begin - OUT = OUT | IN[i]; - end - end -endmodule - -module MACROCELL_XOR(IN_PTC, IN_ORTERM, OUT); - parameter INVERT_OUT = 0; - - input IN_PTC; - input IN_ORTERM; - output wire OUT; - - wire xor_intermed; - - assign OUT = INVERT_OUT ? ~xor_intermed : xor_intermed; - assign xor_intermed = IN_ORTERM ^ IN_PTC; -endmodule - -module FDCP (C, PRE, CLR, D, Q); - parameter INIT = 0; - - input C, PRE, CLR, D; - output reg Q; - - initial begin - Q <= INIT; - end - - always @(posedge C, posedge PRE, posedge CLR) begin - if (CLR == 1) - Q <= 0; - else if (PRE == 1) - Q <= 1; - else - Q <= D; - end -endmodule - -module FDCP_N (C, PRE, CLR, D, Q); - parameter INIT = 0; - - input C, PRE, CLR, D; - output reg Q; - - initial begin - Q <= INIT; - end - - always @(negedge C, posedge PRE, posedge CLR) begin - if (CLR == 1) - Q <= 0; - else if (PRE == 1) - Q <= 1; - else - Q <= D; - end -endmodule - -module LDCP (G, PRE, CLR, D, Q); - parameter INIT = 0; - - input G, PRE, CLR, D; - output reg Q; - - initial begin - Q <= INIT; - end - - always @* begin - if (CLR == 1) - Q <= 0; - else if (G == 1) - Q <= D; - else if (PRE == 1) - Q <= 1; - end -endmodule - -module LDCP_N (G, PRE, CLR, D, Q); - parameter INIT = 0; - - input G, PRE, CLR, D; - output reg Q; - - initial begin - Q <= INIT; - end - - always @* begin - if (CLR == 1) - Q <= 0; - else if (G == 0) - Q <= D; - else if (PRE == 1) - Q <= 1; - end -endmodule - -module BUFG(I, O); - input I; - output O; - - assign O = I; -endmodule - -module BUFGSR(I, O); - parameter INVERT = 0; - - input I; - output O; - - assign O = INVERT ? ~I : I; -endmodule - -module BUFGTS(I, O); - parameter INVERT = 0; - - input I; - output O; - - assign O = INVERT ? ~I : I; -endmodule - -module FDDCP (C, PRE, CLR, D, Q); - parameter INIT = 0; - - input C, PRE, CLR, D; - output reg Q; - - initial begin - Q <= INIT; - end - - always @(posedge C, negedge C, posedge PRE, posedge CLR) begin - if (CLR == 1) - Q <= 0; - else if (PRE == 1) - Q <= 1; - else - Q <= D; - end -endmodule - -module FTCP (C, PRE, CLR, T, Q); - parameter INIT = 0; - - input C, PRE, CLR, T; - output wire Q; - reg Q_; - - initial begin - Q_ <= INIT; - end - - always @(posedge C, posedge PRE, posedge CLR) begin - if (CLR == 1) - Q_ <= 0; - else if (PRE == 1) - Q_ <= 1; - else if (T == 1) - Q_ <= ~Q_; - end - - assign Q = Q_; -endmodule - -module FTCP_N (C, PRE, CLR, T, Q); - parameter INIT = 0; - - input C, PRE, CLR, T; - output wire Q; - reg Q_; - - initial begin - Q_ <= INIT; - end - - always @(negedge C, posedge PRE, posedge CLR) begin - if (CLR == 1) - Q_ <= 0; - else if (PRE == 1) - Q_ <= 1; - else if (T == 1) - Q_ <= ~Q_; - end - - assign Q = Q_; -endmodule - -module FTDCP (C, PRE, CLR, T, Q); - parameter INIT = 0; - - input C, PRE, CLR, T; - output wire Q; - reg Q_; - - initial begin - Q_ <= INIT; - end - - always @(posedge C, negedge C, posedge PRE, posedge CLR) begin - if (CLR == 1) - Q_ <= 0; - else if (PRE == 1) - Q_ <= 1; - else if (T == 1) - Q_ <= ~Q_; - end - - assign Q = Q_; -endmodule - -module FDCPE (C, PRE, CLR, D, Q, CE); - parameter INIT = 0; - - input C, PRE, CLR, D, CE; - output reg Q; - - initial begin - Q <= INIT; - end - - always @(posedge C, posedge PRE, posedge CLR) begin - if (CLR == 1) - Q <= 0; - else if (PRE == 1) - Q <= 1; - else if (CE == 1) - Q <= D; - end -endmodule - -module FDCPE_N (C, PRE, CLR, D, Q, CE); - parameter INIT = 0; - - input C, PRE, CLR, D, CE; - output reg Q; - - initial begin - Q <= INIT; - end - - always @(negedge C, posedge PRE, posedge CLR) begin - if (CLR == 1) - Q <= 0; - else if (PRE == 1) - Q <= 1; - else if (CE == 1) - Q <= D; - end -endmodule - -module FDDCPE (C, PRE, CLR, D, Q, CE); - parameter INIT = 0; - - input C, PRE, CLR, D, CE; - output reg Q; - - initial begin - Q <= INIT; - end - - always @(posedge C, negedge C, posedge PRE, posedge CLR) begin - if (CLR == 1) - Q <= 0; - else if (PRE == 1) - Q <= 1; - else if (CE == 1) - Q <= D; - end -endmodule diff --git a/techlibs/coolrunner2/coolrunner2_fixup.cc b/techlibs/coolrunner2/coolrunner2_fixup.cc deleted file mode 100644 index 2b2249596..000000000 --- a/techlibs/coolrunner2/coolrunner2_fixup.cc +++ /dev/null @@ -1,520 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2020 R. Ou - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -#include "kernel/yosys.h" -#include "kernel/sigtools.h" - -USING_YOSYS_NAMESPACE -PRIVATE_NAMESPACE_BEGIN - -RTLIL::Wire *makexorbuffer(RTLIL::Module *module, SigBit inwire, const char *cellname) -{ - RTLIL::Wire *outwire = nullptr; - - if (inwire == SigBit(true)) - { - // Constant 1 - outwire = module->addWire( - module->uniquify(stringf("$xc2fix$%s_BUF1_XOR_OUT", cellname))); - auto xor_cell = module->addCell( - module->uniquify(stringf("$xc2fix$%s_BUF1_XOR", cellname)), - ID(MACROCELL_XOR)); - xor_cell->setParam(ID(INVERT_OUT), true); - xor_cell->setPort(ID(OUT), outwire); - } - else if (inwire == SigBit(false)) - { - // Constant 0 - outwire = module->addWire( - module->uniquify(stringf("$xc2fix$%s_BUF0_XOR_OUT", cellname))); - auto xor_cell = module->addCell( - module->uniquify(stringf("$xc2fix$%s_BUF0_XOR", cellname)), - ID(MACROCELL_XOR)); - xor_cell->setParam(ID(INVERT_OUT), false); - xor_cell->setPort(ID(OUT), outwire); - } - else if (inwire == SigBit(RTLIL::State::Sx)) - { - // x; treat as 0 - log_warning("While buffering, changing x to 0 into cell %s\n", cellname); - outwire = module->addWire( - module->uniquify(stringf("$xc2fix$%s_BUF0_XOR_OUT", cellname))); - auto xor_cell = module->addCell( - module->uniquify(stringf("$xc2fix$%s_BUF0_XOR", cellname)), - ID(MACROCELL_XOR)); - xor_cell->setParam(ID(INVERT_OUT), false); - xor_cell->setPort(ID(OUT), outwire); - } - else - { - auto inwire_name = inwire.wire->name.c_str(); - - outwire = module->addWire( - module->uniquify(stringf("$xc2fix$%s_BUF_XOR_OUT", inwire_name))); - - auto and_to_xor_wire = module->addWire( - module->uniquify(stringf("$xc2fix$%s_BUF_AND_OUT", inwire_name))); - - auto and_cell = module->addCell( - module->uniquify(stringf("$xc2fix$%s_BUF_AND", inwire_name)), - ID(ANDTERM)); - and_cell->setParam(ID(TRUE_INP), 1); - and_cell->setParam(ID(COMP_INP), 0); - and_cell->setPort(ID(OUT), and_to_xor_wire); - and_cell->setPort(ID(IN), inwire); - and_cell->setPort(ID(IN_B), SigSpec()); - - auto xor_cell = module->addCell( - module->uniquify(stringf("$xc2fix$%s_BUF_XOR", inwire_name)), - ID(MACROCELL_XOR)); - xor_cell->setParam(ID(INVERT_OUT), false); - xor_cell->setPort(ID(IN_PTC), and_to_xor_wire); - xor_cell->setPort(ID(OUT), outwire); - } - - return outwire; -} - -RTLIL::Wire *makeptermbuffer(RTLIL::Module *module, SigBit inwire) -{ - auto inwire_name = inwire.wire->name.c_str(); - - auto outwire = module->addWire( - module->uniquify(stringf("$xc2fix$%s_BUF_AND_OUT", inwire_name))); - - auto and_cell = module->addCell( - module->uniquify(stringf("$xc2fix$%s_BUF_AND", inwire_name)), - ID(ANDTERM)); - and_cell->setParam(ID(TRUE_INP), 1); - and_cell->setParam(ID(COMP_INP), 0); - and_cell->setPort(ID(OUT), outwire); - and_cell->setPort(ID(IN), inwire); - and_cell->setPort(ID(IN_B), SigSpec()); - - return outwire; -} - -struct Coolrunner2FixupPass : public Pass { - Coolrunner2FixupPass() : Pass("coolrunner2_fixup", "insert necessary buffer cells for CoolRunner-II architecture") { } - void help() override - { - log("\n"); - log(" coolrunner2_fixup [options] [selection]\n"); - log("\n"); - log("Insert necessary buffer cells for CoolRunner-II architecture.\n"); - log("\n"); - } - void execute(std::vector args, RTLIL::Design *design) override - { - log_header(design, "Executing COOLRUNNER2_FIXUP pass (insert necessary buffer cells for CoolRunner-II architecture).\n"); - extra_args(args, 1, design); - - for (auto module : design->selected_modules()) - { - SigMap sigmap(module); - - // Find all the FF outputs - pool sig_fed_by_ff; - for (auto cell : module->selected_cells()) - { - if (cell->type.in(ID(FDCP), ID(FDCP_N), ID(FDDCP), ID(LDCP), ID(LDCP_N), - ID(FTCP), ID(FTCP_N), ID(FTDCP), ID(FDCPE), ID(FDCPE_N), ID(FDDCPE))) - { - auto output = sigmap(cell->getPort(ID::Q)[0]); - sig_fed_by_ff.insert(output); - } - } - - // Find all the XOR outputs - pool sig_fed_by_xor; - for (auto cell : module->selected_cells()) - { - if (cell->type == ID(MACROCELL_XOR)) - { - auto output = sigmap(cell->getPort(ID(OUT))[0]); - sig_fed_by_xor.insert(output); - } - } - - // Find all the input/inout outputs - pool sig_fed_by_io; - for (auto cell : module->selected_cells()) - { - if (cell->type.in(ID(IBUF), ID(IOBUFE))) - { - if (cell->hasPort(ID::O)) { - auto output = sigmap(cell->getPort(ID::O)[0]); - sig_fed_by_io.insert(output); - } - } - } - - // Find all the pterm outputs - pool sig_fed_by_pterm; - for (auto cell : module->selected_cells()) - { - if (cell->type == ID(ANDTERM)) - { - auto output = sigmap(cell->getPort(ID(OUT))[0]); - sig_fed_by_pterm.insert(output); - } - } - - // Find all the bufg outputs - pool sig_fed_by_bufg; - for (auto cell : module->selected_cells()) - { - if (cell->type == ID(BUFG)) - { - auto output = sigmap(cell->getPort(ID::O)[0]); - sig_fed_by_bufg.insert(output); - } - } - - // Find all the bufgsr outputs - pool sig_fed_by_bufgsr; - for (auto cell : module->selected_cells()) - { - if (cell->type == ID(BUFGSR)) - { - auto output = sigmap(cell->getPort(ID::O)[0]); - sig_fed_by_bufgsr.insert(output); - } - } - - // Find all the bufgts outputs - pool sig_fed_by_bufgts; - for (auto cell : module->selected_cells()) - { - if (cell->type == ID(BUFGTS)) - { - auto output = sigmap(cell->getPort(ID::O)[0]); - sig_fed_by_bufgts.insert(output); - } - } - - // This is used to fix the input -> FF -> output scenario - pool sig_fed_by_ibuf; - for (auto cell : module->selected_cells()) - { - if (cell->type == ID(IBUF)) - { - auto output = sigmap(cell->getPort(ID::O)[0]); - sig_fed_by_ibuf.insert(output); - } - } - - // Find all of the sinks for each output from an IBUF - dict> ibuf_fanouts; - for (auto cell : module->selected_cells()) - { - for (auto &conn : cell->connections()) - { - if (cell->input(conn.first)) - { - for (auto wire_in : sigmap(conn.second)) - { - if (sig_fed_by_ibuf[wire_in]) - { - auto existing_count = ibuf_fanouts[wire_in].first; - ibuf_fanouts[wire_in] = - std::pair(existing_count + 1, cell); - } - } - } - } - } - - dict ibuf_out_to_packed_reg_cell; - pool packed_reg_out; - for (auto x : ibuf_fanouts) - { - auto ibuf_out_wire = x.first; - auto fanout_count = x.second.first; - auto maybe_ff_cell = x.second.second; - - // The register can be packed with the IBUF only if it's - // actually a register and it's the only fanout. Otherwise, - // the pad-to-zia path has to be used up and the register - // can't be packed with the ibuf. - if (fanout_count == 1 && maybe_ff_cell->type.in( - ID(FDCP), ID(FDCP_N), ID(FDDCP), ID(LDCP), ID(LDCP_N), - ID(FTCP), ID(FTCP_N), ID(FTDCP), ID(FDCPE), ID(FDCPE_N), ID(FDDCPE))) - { - SigBit input; - if (maybe_ff_cell->type.in(ID(FTCP), ID(FTCP_N), ID(FTDCP))) - input = sigmap(maybe_ff_cell->getPort(ID::T)[0]); - else - input = sigmap(maybe_ff_cell->getPort(ID::D)[0]); - SigBit output = sigmap(maybe_ff_cell->getPort(ID::Q)[0]); - - if (input == ibuf_out_wire) - { - log("Found IBUF %s that can be packed with FF %s (type %s)\n", - ibuf_out_wire.wire->name.c_str(), - maybe_ff_cell->name.c_str(), - maybe_ff_cell->type.c_str()); - - ibuf_out_to_packed_reg_cell[ibuf_out_wire] = maybe_ff_cell; - packed_reg_out.insert(output); - } - } - } - - for (auto cell : module->selected_cells()) - { - if (cell->type.in(ID(FDCP), ID(FDCP_N), ID(FDDCP), ID(LDCP), ID(LDCP_N), - ID(FTCP), ID(FTCP_N), ID(FTDCP), ID(FDCPE), ID(FDCPE_N), ID(FDDCPE))) - { - // Buffering FF inputs. FF inputs can only come from either - // an IO pin or from an XOR. Otherwise AND/XOR cells need - // to be inserted. - SigBit input; - if (cell->type.in(ID(FTCP), ID(FTCP_N), ID(FTDCP))) - input = sigmap(cell->getPort(ID::T)[0]); - else - input = sigmap(cell->getPort(ID::D)[0]); - - // If the input wasn't an XOR nor an IO, then a buffer - // definitely needs to be added. - // Otherwise, if it is an IO, only leave unbuffered - // if we're being packed with the IO. - if ((!sig_fed_by_xor[input] && !sig_fed_by_io[input]) || - (sig_fed_by_io[input] && ibuf_out_to_packed_reg_cell[input] != cell)) - { - log("Buffering input to \"%s\"\n", cell->name); - - auto xor_to_ff_wire = makexorbuffer(module, input, cell->name.c_str()); - - if (cell->type.in(ID(FTCP), ID(FTCP_N), ID(FTDCP))) - cell->setPort(ID::T, xor_to_ff_wire); - else - cell->setPort(ID::D, xor_to_ff_wire); - } - - // Buffering FF clocks. FF clocks can only come from either - // a pterm or a bufg. In some cases this will be handled - // in coolrunner2_sop (e.g. if clock is generated from - // AND-ing two signals) but not in all cases. - SigBit clock; - if (cell->type.in(ID(LDCP), ID(LDCP_N))) - clock = sigmap(cell->getPort(ID::G)[0]); - else - clock = sigmap(cell->getPort(ID::C)[0]); - - if (!sig_fed_by_pterm[clock] && !sig_fed_by_bufg[clock]) - { - log("Buffering clock to \"%s\"\n", cell->name); - - auto pterm_to_ff_wire = makeptermbuffer(module, clock); - - if (cell->type.in(ID(LDCP), ID(LDCP_N))) - cell->setPort(ID::G, pterm_to_ff_wire); - else - cell->setPort(ID::C, pterm_to_ff_wire); - } - - // Buffering FF set/reset. This can only come from either - // a pterm or a bufgsr. - SigBit set; - set = sigmap(cell->getPort(ID(PRE))[0]); - if (set != SigBit(false)) - { - if (!sig_fed_by_pterm[set] && !sig_fed_by_bufgsr[set]) - { - log("Buffering set to \"%s\"\n", cell->name); - - auto pterm_to_ff_wire = makeptermbuffer(module, set); - - cell->setPort(ID(PRE), pterm_to_ff_wire); - } - } - - SigBit reset; - reset = sigmap(cell->getPort(ID::CLR)[0]); - if (reset != SigBit(false)) - { - if (!sig_fed_by_pterm[reset] && !sig_fed_by_bufgsr[reset]) - { - log("Buffering reset to \"%s\"\n", cell->name); - - auto pterm_to_ff_wire = makeptermbuffer(module, reset); - - cell->setPort(ID::CLR, pterm_to_ff_wire); - } - } - - // Buffering FF clock enable - // FIXME: This doesn't fully fix PTC conflicts - // FIXME: Need to ensure constant enables are optimized out - if (cell->type.in(ID(FDCPE), ID(FDCPE_N), ID(FDDCPE))) - { - SigBit ce; - ce = sigmap(cell->getPort(ID(CE))[0]); - if (!sig_fed_by_pterm[ce]) - { - log("Buffering clock enable to \"%s\"\n", cell->name); - - auto pterm_to_ff_wire = makeptermbuffer(module, ce); - - cell->setPort(ID(CE), pterm_to_ff_wire); - } - } - } - } - - for (auto cell : module->selected_cells()) - { - if (cell->type == ID(IOBUFE)) - { - // Buffer IOBUFE inputs. This can only be fed from an XOR or FF. - SigBit input = sigmap(cell->getPort(ID::I)[0]); - - if ((!sig_fed_by_xor[input] && !sig_fed_by_ff[input]) || - packed_reg_out[input]) - { - log("Buffering input to \"%s\"\n", cell->name); - - auto xor_to_io_wire = makexorbuffer(module, input, cell->name.c_str()); - - cell->setPort(ID::I, xor_to_io_wire); - } - - // Buffer IOBUFE enables. This can only be fed from a pterm - // or a bufgts. - if (cell->hasPort(ID::E)) - { - SigBit oe; - oe = sigmap(cell->getPort(ID::E)[0]); - if (!sig_fed_by_pterm[oe] && !sig_fed_by_bufgts[oe]) - { - log("Buffering output enable to \"%s\"\n", cell->name); - - auto pterm_to_oe_wire = makeptermbuffer(module, oe); - - cell->setPort(ID::E, pterm_to_oe_wire); - } - } - } - } - - // Now we have to fix up some cases where shared logic can - // cause XORs to have multiple fanouts to something other than - // pterms (which is not ok) - - // Find all the XOR outputs - dict xor_out_to_xor_cell; - for (auto cell : module->selected_cells()) - { - if (cell->type == ID(MACROCELL_XOR)) - { - auto output = sigmap(cell->getPort(ID(OUT))[0]); - xor_out_to_xor_cell[output] = cell; - } - } - - // Find all of the sinks for each output from an XOR - pool xor_fanout_once; - for (auto cell : module->selected_cells()) - { - if (cell->type == ID(ANDTERM)) - continue; - - for (auto &conn : cell->connections()) - { - if (cell->input(conn.first)) - { - for (auto wire_in : sigmap(conn.second)) - { - auto xor_cell = xor_out_to_xor_cell[wire_in]; - if (xor_cell) - { - if (xor_fanout_once[wire_in]) - { - log("Additional fanout found for %s into %s (type %s), duplicating\n", - xor_cell->name.c_str(), - cell->name.c_str(), - cell->type.c_str()); - - auto new_xor_cell = module->addCell( - module->uniquify(xor_cell->name), xor_cell); - auto new_wire = module->addWire( - module->uniquify(wire_in.wire->name)); - new_xor_cell->setPort(ID(OUT), new_wire); - cell->setPort(conn.first, new_wire); - } - xor_fanout_once.insert(wire_in); - } - } - } - } - } - - // Do the same fanout fixing for OR terms. By doing this - // after doing XORs, both pieces will be duplicated when necessary. - - // Find all the OR outputs - dict or_out_to_or_cell; - for (auto cell : module->selected_cells()) - { - if (cell->type == ID(ORTERM)) - { - auto output = sigmap(cell->getPort(ID(OUT))[0]); - or_out_to_or_cell[output] = cell; - } - } - - // Find all of the sinks for each output from an OR - pool or_fanout_once; - for (auto cell : module->selected_cells()) - { - for (auto &conn : cell->connections()) - { - if (cell->input(conn.first)) - { - for (auto wire_in : sigmap(conn.second)) - { - auto or_cell = or_out_to_or_cell[wire_in]; - if (or_cell) - { - if (or_fanout_once[wire_in]) - { - log("Additional fanout found for %s into %s (type %s), duplicating\n", - or_cell->name.c_str(), - cell->name.c_str(), - cell->type.c_str()); - - auto new_or_cell = module->addCell( - module->uniquify(or_cell->name), or_cell); - auto new_wire = module->addWire( - module->uniquify(wire_in.wire->name)); - new_or_cell->setPort(ID(OUT), new_wire); - cell->setPort(conn.first, new_wire); - } - or_fanout_once.insert(wire_in); - } - } - } - } - } - } - } -} Coolrunner2FixupPass; - -PRIVATE_NAMESPACE_END diff --git a/techlibs/coolrunner2/coolrunner2_sop.cc b/techlibs/coolrunner2/coolrunner2_sop.cc deleted file mode 100644 index 17e0d8432..000000000 --- a/techlibs/coolrunner2/coolrunner2_sop.cc +++ /dev/null @@ -1,234 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2017 Robert Ou - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -#include "kernel/yosys.h" -#include "kernel/sigtools.h" - -USING_YOSYS_NAMESPACE -PRIVATE_NAMESPACE_BEGIN - -struct Coolrunner2SopPass : public Pass { - Coolrunner2SopPass() : Pass("coolrunner2_sop", "break $sop cells into ANDTERM/ORTERM cells") { } - void help() override - { - log("\n"); - log(" coolrunner2_sop [options] [selection]\n"); - log("\n"); - log("Break $sop cells into ANDTERM/ORTERM cells.\n"); - log("\n"); - } - void execute(std::vector args, RTLIL::Design *design) override - { - log_header(design, "Executing COOLRUNNER2_SOP pass (break $sop cells into ANDTERM/ORTERM cells).\n"); - extra_args(args, 1, design); - - for (auto module : design->selected_modules()) - { - pool cells_to_remove; - SigMap sigmap(module); - - // Find all the $_NOT_ cells - dict> not_cells; - for (auto cell : module->selected_cells()) - { - if (cell->type == ID($_NOT_)) - { - auto not_input = sigmap(cell->getPort(ID::A)[0]); - auto not_output = sigmap(cell->getPort(ID::Y)[0]); - not_cells[not_input] = tuple(not_output, cell); - } - } - - // Find wires that need to become special product terms - dict>> special_pterms_no_inv; - dict>> special_pterms_inv; - for (auto cell : module->selected_cells()) - { - if (cell->type.in(ID(FDCP), ID(FDCP_N), ID(FDDCP), ID(FTCP), ID(FTCP_N), ID(FTDCP), - ID(FDCPE), ID(FDCPE_N), ID(FDDCPE), ID(LDCP), ID(LDCP_N))) - { - if (cell->hasPort(ID(PRE))) - special_pterms_no_inv[sigmap(cell->getPort(ID(PRE))[0])].insert( - make_tuple(cell, ID(PRE))); - if (cell->hasPort(ID::CLR)) - special_pterms_no_inv[sigmap(cell->getPort(ID::CLR)[0])].insert( - make_tuple(cell, ID::CLR)); - if (cell->hasPort(ID(CE))) - special_pterms_no_inv[sigmap(cell->getPort(ID(CE))[0])].insert( - make_tuple(cell, ID(CE))); - - if (cell->hasPort(ID::C)) - special_pterms_inv[sigmap(cell->getPort(ID::C)[0])].insert( - make_tuple(cell, ID::C)); - if (cell->hasPort(ID::G)) - special_pterms_inv[sigmap(cell->getPort(ID::G)[0])].insert( - make_tuple(cell, ID::G)); - } - } - - // Process $sop cells - for (auto cell : module->selected_cells()) - { - if (cell->type == ID($sop)) - { - // Read the inputs/outputs/parameters of the $sop cell - auto sop_inputs = sigmap(cell->getPort(ID::A)); - auto sop_output = sigmap(cell->getPort(ID::Y))[0]; - auto sop_depth = cell->getParam(ID::DEPTH).as_int(); - auto sop_width = cell->getParam(ID::WIDTH).as_int(); - auto sop_table = cell->getParam(ID::TABLE); - - auto sop_output_wire_name = sop_output.wire->name.c_str(); - - // Check for a $_NOT_ at the output - bool has_invert = false; - if (not_cells.count(sop_output)) - { - auto not_cell = not_cells.at(sop_output); - - has_invert = true; - sop_output = std::get<0>(not_cell); - - // remove the $_NOT_ cell because it gets folded into the xor - cells_to_remove.insert(std::get<1>(not_cell)); - } - - // Check for special P-term usage - bool is_special_pterm = - special_pterms_no_inv.count(sop_output) || special_pterms_inv.count(sop_output); - - // Construct AND cells - pool intermed_wires; - for (int i = 0; i < sop_depth; i++) { - // Wire for the output - auto and_out = module->addWire( - module->uniquify(stringf("$xc2sop$%s_AND%d_OUT", sop_output_wire_name, i))); - intermed_wires.insert(and_out); - - // Signals for the inputs - pool and_in_true; - pool and_in_comp; - for (int j = 0; j < sop_width; j++) - { - if (sop_table[2 * (i * sop_width + j) + 0]) - { - and_in_comp.insert(sop_inputs[j]); - } - if (sop_table[2 * (i * sop_width + j) + 1]) - { - and_in_true.insert(sop_inputs[j]); - } - } - - // Construct the cell - auto and_cell = module->addCell( - module->uniquify(stringf("$xc2sop$%s_AND%d", sop_output_wire_name, i)), - ID(ANDTERM)); - and_cell->setParam(ID(TRUE_INP), GetSize(and_in_true)); - and_cell->setParam(ID(COMP_INP), GetSize(and_in_comp)); - and_cell->setPort(ID(OUT), and_out); - and_cell->setPort(ID(IN), and_in_true); - and_cell->setPort(ID(IN_B), and_in_comp); - } - - if (sop_depth == 1) - { - // If there is only one term, don't construct an OR cell. Directly construct the XOR gate - auto xor_cell = module->addCell( - module->uniquify(stringf("$xc2sop$%s_XOR", sop_output_wire_name)), - ID(MACROCELL_XOR)); - xor_cell->setParam(ID(INVERT_OUT), has_invert); - xor_cell->setPort(ID(IN_PTC), *intermed_wires.begin()); - xor_cell->setPort(ID(OUT), sop_output); - - // Special P-term handling - if (is_special_pterm) - { - // Can always connect the P-term directly if it's going - // into something invert-capable - for (const auto &x : special_pterms_inv[sop_output]) - { - std::get<0>(x)->setPort(std::get<1>(x), *intermed_wires.begin()); - - // If this signal is indeed inverted, flip the cell polarity - if (has_invert) - { - auto cell = std::get<0>(x); - if (cell->type == ID(FDCP)) cell->type = ID(FDCP_N); - else if (cell->type == ID(FDCP_N)) cell->type = ID(FDCP); - else if (cell->type == ID(FTCP)) cell->type = ID(FTCP_N); - else if (cell->type == ID(FTCP_N)) cell->type = ID(FTCP); - else if (cell->type == ID(FDCPE)) cell->type = ID(FDCPE_N); - else if (cell->type == ID(FDCPE_N)) cell->type = ID(FDCPE); - else if (cell->type == ID(LDCP)) cell->type = ID(LDCP_N); - else if (cell->type == ID(LDCP_N)) cell->type = ID(LDCP); - else log_assert(!"Internal error! Bad cell type!"); - } - } - - // If it's going into something that's not invert-capable, - // connect it directly only if this signal isn't inverted - if (!has_invert) - { - for (auto x : special_pterms_no_inv[sop_output]) - std::get<0>(x)->setPort(std::get<1>(x), *intermed_wires.begin()); - } - - // Otherwise, a feedthrough P-term has to be created. Leave that to happen - // in the coolrunner2_fixup pass. - } - } - else - { - // Wire from OR to XOR - auto or_to_xor_wire = module->addWire( - module->uniquify(stringf("$xc2sop$%s_OR_OUT", sop_output_wire_name))); - - // Construct the OR cell - auto or_cell = module->addCell( - module->uniquify(stringf("$xc2sop$%s_OR", sop_output_wire_name)), - ID(ORTERM)); - or_cell->setParam(ID::WIDTH, sop_depth); - or_cell->setPort(ID(IN), intermed_wires); - or_cell->setPort(ID(OUT), or_to_xor_wire); - - // Construct the XOR cell - auto xor_cell = module->addCell( - module->uniquify(stringf("$xc2sop$%s_XOR", sop_output_wire_name)), - ID(MACROCELL_XOR)); - xor_cell->setParam(ID(INVERT_OUT), has_invert); - xor_cell->setPort(ID(IN_ORTERM), or_to_xor_wire); - xor_cell->setPort(ID(OUT), sop_output); - } - - // Finally, remove the $sop cell - cells_to_remove.insert(cell); - } - } - - // Actually do the removal now that we aren't iterating - for (auto cell : cells_to_remove) - { - module->remove(cell); - } - } - } -} Coolrunner2SopPass; - -PRIVATE_NAMESPACE_END diff --git a/techlibs/coolrunner2/synth_coolrunner2.cc b/techlibs/coolrunner2/synth_coolrunner2.cc deleted file mode 100644 index 1b30f51bc..000000000 --- a/techlibs/coolrunner2/synth_coolrunner2.cc +++ /dev/null @@ -1,207 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2017 Robert Ou - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - * - */ - -#include "kernel/register.h" -#include "kernel/celltypes.h" -#include "kernel/rtlil.h" -#include "kernel/log.h" - -USING_YOSYS_NAMESPACE -PRIVATE_NAMESPACE_BEGIN - -struct SynthCoolrunner2Pass : public ScriptPass -{ - SynthCoolrunner2Pass() : ScriptPass("synth_coolrunner2", "synthesis for Xilinx Coolrunner-II CPLDs") { } - - void help() override - { - // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| - log("\n"); - log(" synth_coolrunner2 [options]\n"); - log("\n"); - log("This command runs synthesis for Coolrunner-II CPLDs. This work is experimental.\n"); - log("It is intended to be used with https://github.com/azonenberg/openfpga as the\n"); - log("place-and-route.\n"); - log("\n"); - log(" -top \n"); - log(" use the specified module as top module (default='top')\n"); - log("\n"); - log(" -json \n"); - log(" write the design to the specified JSON file. writing of an output file\n"); - log(" is omitted if this parameter is not specified.\n"); - log("\n"); - log(" -run :\n"); - log(" only run the commands between the labels (see below). an empty\n"); - log(" from label is synonymous to 'begin', and empty to label is\n"); - log(" synonymous to the end of the command list.\n"); - log("\n"); - log(" -noflatten\n"); - log(" do not flatten design before synthesis\n"); - log("\n"); - log(" -retime\n"); - log(" run 'abc' with '-dff -D 1' options\n"); - log("\n"); - log("\n"); - log("The following commands are executed by this synthesis command:\n"); - help_script(); - log("\n"); - } - - string top_opt, json_file; - bool flatten, retime; - - void clear_flags() override - { - top_opt = "-auto-top"; - json_file = ""; - flatten = true; - retime = false; - } - - void execute(std::vector args, RTLIL::Design *design) override - { - string run_from, run_to; - clear_flags(); - - size_t argidx; - for (argidx = 1; argidx < args.size(); argidx++) - { - if (args[argidx] == "-top" && argidx+1 < args.size()) { - top_opt = "-top " + args[++argidx]; - continue; - } - if (args[argidx] == "-json" && argidx+1 < args.size()) { - json_file = args[++argidx]; - continue; - } - if (args[argidx] == "-run" && argidx+1 < args.size()) { - size_t pos = args[argidx+1].find(':'); - if (pos == std::string::npos) - break; - run_from = args[++argidx].substr(0, pos); - run_to = args[argidx].substr(pos+1); - continue; - } - if (args[argidx] == "-noflatten") { - flatten = false; - continue; - } - if (args[argidx] == "-retime") { - retime = true; - continue; - } - break; - } - extra_args(args, argidx, design); - - if (!design->full_selection()) - log_cmd_error("This command only operates on fully selected designs!\n"); - - log_header(design, "Executing SYNTH_COOLRUNNER2 pass.\n"); - log_push(); - - run_script(design, run_from, run_to); - - log_pop(); - } - - void script() override - { - if (check_label("begin")) - { - run("read_verilog -lib +/coolrunner2/cells_sim.v"); - run(stringf("hierarchy -check %s", help_mode ? "-top " : top_opt)); - } - - if (flatten && check_label("flatten", "(unless -noflatten)")) - { - run("proc"); - run("check"); - run("flatten"); - run("tribuf -logic"); - } - - if (check_label("coarse")) - { - run("synth -run coarse"); - } - - if (check_label("fine")) - { - run("extract_counter -dir up -allow_arst no"); - run("techmap -map +/coolrunner2/cells_counter_map.v"); - run("clean"); - run("opt -fast -full"); - run("techmap -map +/techmap.v -map +/coolrunner2/cells_latch.v"); - run("opt -fast"); - run("dfflibmap -prepare -liberty +/coolrunner2/xc2_dff.lib"); - } - - if (check_label("map_tff")) - { - // This is quite hacky. By telling abc that it can only use AND and XOR gates, abc will try and use XOR - // gates "whenever possible." This will hopefully cause toggle flip-flop structures to turn into an XOR - // connected to a D flip-flop. We then match on these and convert them into XC2 TFF cells. - run("abc -g AND,XOR"); - run("clean"); - run("extract -map +/coolrunner2/tff_extract.v"); - } - - if (check_label("map_pla")) - { - run("abc -sop -I 40 -P 56" + string(retime ? " -dff -D 1" : "")); - run("clean"); - } - - if (check_label("map_cells")) - { - run("dfflibmap -liberty +/coolrunner2/xc2_dff.lib"); - run("dffinit -ff FDCP Q INIT"); - run("dffinit -ff FDCP_N Q INIT"); - run("dffinit -ff FTCP Q INIT"); - run("dffinit -ff FTCP_N Q INIT"); - run("dffinit -ff LDCP Q INIT"); - run("dffinit -ff LDCP_N Q INIT"); - run("coolrunner2_sop"); - run("clean"); - run("iopadmap -bits -inpad IBUF O:I -outpad IOBUFE I:IO -inoutpad IOBUFE O:IO -toutpad IOBUFE E:I:IO -tinoutpad IOBUFE E:O:I:IO"); - run("attrmvcp -attr src -attr LOC t:IOBUFE n:*"); - run("attrmvcp -attr src -attr LOC -driven t:IBUF n:*"); - run("coolrunner2_fixup"); - run("splitnets"); - run("clean"); - } - - if (check_label("check")) - { - run("hierarchy -check"); - run("stat"); - run("check -noinit"); - run("blackbox =A:whitebox"); - } - - if (check_label("json")) - { - if (!json_file.empty() || help_mode) - run(stringf("write_json %s", help_mode ? "" : json_file)); - } - } -} SynthCoolrunner2Pass; - -PRIVATE_NAMESPACE_END diff --git a/techlibs/coolrunner2/tff_extract.v b/techlibs/coolrunner2/tff_extract.v deleted file mode 100644 index b4237dd18..000000000 --- a/techlibs/coolrunner2/tff_extract.v +++ /dev/null @@ -1,41 +0,0 @@ -module FTCP (C, PRE, CLR, T, Q); - input C, PRE, CLR, T; - output wire Q; - - wire xorout; - - $_XOR_ xorgate ( - .A(T), - .B(Q), - .Y(xorout), - ); - - $_DFFSR_PPP_ dff ( - .C(C), - .D(xorout), - .Q(Q), - .S(PRE), - .R(CLR), - ); -endmodule - -module FTCP_N (C, PRE, CLR, T, Q); - input C, PRE, CLR, T; - output wire Q; - - wire xorout; - - $_XOR_ xorgate ( - .A(T), - .B(Q), - .Y(xorout), - ); - - $_DFFSR_NPP_ dff ( - .C(C), - .D(xorout), - .Q(Q), - .S(PRE), - .R(CLR), - ); -endmodule diff --git a/techlibs/coolrunner2/xc2_dff.lib b/techlibs/coolrunner2/xc2_dff.lib deleted file mode 100644 index b578493a1..000000000 --- a/techlibs/coolrunner2/xc2_dff.lib +++ /dev/null @@ -1,31 +0,0 @@ -library(xc2_dff) { - cell(FDCP) { - area: 1; - ff("IQ", "IQN") { clocked_on: C; - next_state: D; - clear: "CLR"; - preset: "PRE"; } - pin(C) { direction: input; - clock: true; } - pin(D) { direction: input; } - pin(Q) { direction: output; - function: "IQ"; } - pin(CLR) { direction: input; } - pin(PRE) { direction: input; } - } - - cell(FDCP_N) { - area: 1; - ff("IQ", "IQN") { clocked_on: "!C"; - next_state: D; - clear: "CLR"; - preset: "PRE"; } - pin(C) { direction: input; - clock: true; } - pin(D) { direction: input; } - pin(Q) { direction: output; - function: "IQ"; } - pin(CLR) { direction: input; } - pin(PRE) { direction: input; } - } -}