diff --git a/docs/source/cmd/index_techlibs_greenpak4.rst b/docs/source/cmd/index_techlibs_greenpak4.rst deleted file mode 100644 index add1ab102..000000000 --- a/docs/source/cmd/index_techlibs_greenpak4.rst +++ /dev/null @@ -1,5 +0,0 @@ -GreenPAK4 ------------------- - -.. autocmdgroup:: techlibs/greenpak4 - :members: diff --git a/passes/opt/rmports.cc b/passes/opt/rmports.cc index 3a39570b4..12171f007 100644 --- a/passes/opt/rmports.cc +++ b/passes/opt/rmports.cc @@ -26,11 +26,6 @@ PRIVATE_NAMESPACE_BEGIN struct RmportsPassPass : public Pass { RmportsPassPass() : Pass("rmports", "remove module ports with no connections") { } - bool formatted_help() override { - auto *help = PrettyHelp::get_current(); - help->set_group("techlibs/greenpak4"); - return false; - } void help() override { // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| diff --git a/passes/techmap/CMakeLists.txt b/passes/techmap/CMakeLists.txt index 841b5b43e..8a6e11eef 100644 --- a/passes/techmap/CMakeLists.txt +++ b/passes/techmap/CMakeLists.txt @@ -166,13 +166,6 @@ yosys_pass(lut2mux yosys_pass(lut2bmux lut2bmux.cc ) -yosys_pass(nlutmap - nlutmap.cc - REQUIRES - abc - lut2mux - opt_clean -) yosys_pass(shregmap shregmap.cc ) diff --git a/passes/techmap/nlutmap.cc b/passes/techmap/nlutmap.cc deleted file mode 100644 index c823f10fe..000000000 --- a/passes/techmap/nlutmap.cc +++ /dev/null @@ -1,187 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2012 Claire Xenia Wolf - * - * 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 NlutmapConfig -{ - vector luts; - bool assert_mode = false; -}; - -struct NlutmapWorker -{ - const NlutmapConfig &config; - pool mapped_cells; - Module *module; - - NlutmapWorker(const NlutmapConfig &config, Module *module) : - config(config), module(module) - { - } - - RTLIL::Selection get_selection() - { - auto sel = RTLIL::Selection::EmptySelection(module->design); - for (auto cell : module->cells()) - if (!mapped_cells.count(cell)) - sel.select(module, cell); - return sel; - } - - void run_abc(int lut_size) - { - Pass::call_on_selection(module->design, get_selection(), "lut2mux"); - - if (lut_size > 0) - Pass::call_on_selection(module->design, get_selection(), stringf("abc -lut 1:%d", lut_size)); - else - Pass::call_on_selection(module->design, get_selection(), "abc"); - - Pass::call_on_module(module->design, module, "opt_clean"); - } - - void run() - { - vector available_luts = config.luts; - - while (GetSize(available_luts) > 1) - { - int n_luts = available_luts.back(); - int lut_size = GetSize(available_luts); - available_luts.pop_back(); - - if (n_luts == 0) - continue; - - run_abc(lut_size); - - SigMap sigmap(module); - dict candidate_ratings; - dict bit_lut_count; - - for (auto cell : module->cells()) - { - if (cell->type != ID($lut) || mapped_cells.count(cell)) - continue; - - if (GetSize(cell->getPort(ID::A)) == lut_size || lut_size == 2) - candidate_ratings[cell] = 0; - - for (auto &conn : cell->connections()) - for (auto bit : sigmap(conn.second)) - bit_lut_count[bit]++; - } - - for (auto &cand : candidate_ratings) - { - for (auto &conn : cand.first->connections()) - for (auto bit : sigmap(conn.second)) - cand.second -= bit_lut_count[bit]; - } - - vector> rated_candidates; - - for (auto &cand : candidate_ratings) - rated_candidates.push_back(pair(cand.second, cand.first->name)); - - std::sort(rated_candidates.begin(), rated_candidates.end()); - - while (n_luts > 0 && !rated_candidates.empty()) { - mapped_cells.insert(module->cell(rated_candidates.back().second)); - rated_candidates.pop_back(); - n_luts--; - } - - if (!available_luts.empty()) - available_luts.back() += n_luts; - } - - if (config.assert_mode) { - for (auto cell : module->cells()) - if (cell->type == ID($lut) && !mapped_cells.count(cell)) - log_error("Insufficient number of LUTs to map all logic cells!\n"); - } - - run_abc(0); - } -}; - -struct NlutmapPass : public Pass { - NlutmapPass() : Pass("nlutmap", "map to LUTs of different sizes") { } - void help() override - { - // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| - log("\n"); - log(" nlutmap [options] [selection]\n"); - log("\n"); - log("This pass uses successive calls to 'abc' to map to an architecture. That\n"); - log("provides a small number of differently sized LUTs.\n"); - log("\n"); - log(" -luts N_1,N_2,N_3,...\n"); - log(" The number of LUTs with 1, 2, 3, ... inputs that are\n"); - log(" available in the target architecture.\n"); - log("\n"); - log(" -assert\n"); - log(" Create an error if not all logic can be mapped\n"); - log("\n"); - log("Excess logic that does not fit into the specified LUTs is mapped back\n"); - log("to generic logic gates ($_AND_, etc.).\n"); - log("\n"); - } - void execute(std::vector args, RTLIL::Design *design) override - { - NlutmapConfig config; - - log_header(design, "Executing NLUTMAP pass (mapping to constant drivers).\n"); - log_push(); - - size_t argidx; - for (argidx = 1; argidx < args.size(); argidx++) - { - if (args[argidx] == "-luts" && argidx+1 < args.size()) { - vector tokens = split_tokens(args[++argidx], ","); - config.luts.clear(); - for (auto &token : tokens) - config.luts.push_back(atoi(token.c_str())); - continue; - } - if (args[argidx] == "-assert") { - config.assert_mode = true; - continue; - } - break; - } - extra_args(args, argidx, design); - - for (auto module : design->selected_whole_modules_warn()) - { - NlutmapWorker worker(config, module); - worker.run(); - } - - log_pop(); - } -} NlutmapPass; - -PRIVATE_NAMESPACE_END diff --git a/techlibs/CMakeLists.txt b/techlibs/CMakeLists.txt index 551c80604..9a0a3ad96 100644 --- a/techlibs/CMakeLists.txt +++ b/techlibs/CMakeLists.txt @@ -8,7 +8,6 @@ add_subdirectory(efinix) add_subdirectory(fabulous) add_subdirectory(gatemate) add_subdirectory(gowin) -add_subdirectory(greenpak4) add_subdirectory(ice40) add_subdirectory(intel) add_subdirectory(intel_alm) diff --git a/techlibs/greenpak4/CMakeLists.txt b/techlibs/greenpak4/CMakeLists.txt deleted file mode 100644 index c721bdc0d..000000000 --- a/techlibs/greenpak4/CMakeLists.txt +++ /dev/null @@ -1,42 +0,0 @@ -yosys_pass(greenpak4_dffinv - greenpak4_dffinv.cc -) - -yosys_pass(synth_greenpak4 - synth_greenpak4.cc - REQUIRES - abc - attrmvcp - blackbox - check - clean - dffinit - dfflibmap - extract_counter - flatten - greenpak4_dffinv - hierarchy - iopadmap - memory_map - nlutmap - opt - proc - read_verilog - shregmap - stat - synth - techmap - tribuf - write_json - DATA_DIR - greenpak4 - DATA_FILES - cells_blackbox.v - cells_latch.v - cells_map.v - cells_sim.v - cells_sim_ams.v - cells_sim_digital.v - cells_sim_wip.v - gp_dff.lib -) diff --git a/techlibs/greenpak4/cells_blackbox.v b/techlibs/greenpak4/cells_blackbox.v deleted file mode 100644 index 1895b90de..000000000 --- a/techlibs/greenpak4/cells_blackbox.v +++ /dev/null @@ -1,18 +0,0 @@ -module \$__COUNT_ (CE, CLK, OUT, POUT, RST, UP); - - input wire CE; - input wire CLK; - output reg OUT; - output reg[WIDTH-1:0] POUT; - input wire RST; - input wire UP; - - parameter COUNT_TO = 1; - parameter RESET_MODE = "RISING"; - parameter RESET_TO_MAX = "1"; - parameter HAS_POUT = 0; - parameter HAS_CE = 0; - parameter WIDTH = 8; - parameter DIRECTION = "DOWN"; - -endmodule diff --git a/techlibs/greenpak4/cells_latch.v b/techlibs/greenpak4/cells_latch.v deleted file mode 100644 index 2ccdd2031..000000000 --- a/techlibs/greenpak4/cells_latch.v +++ /dev/null @@ -1,15 +0,0 @@ -module $_DLATCH_P_(input E, input D, output Q); - GP_DLATCH _TECHMAP_REPLACE_ ( - .D(D), - .nCLK(!E), - .Q(Q) - ); -endmodule - -module $_DLATCH_N_(input E, input D, output Q); - GP_DLATCH _TECHMAP_REPLACE_ ( - .D(D), - .nCLK(E), - .Q(Q) - ); -endmodule diff --git a/techlibs/greenpak4/cells_map.v b/techlibs/greenpak4/cells_map.v deleted file mode 100644 index 316be3f73..000000000 --- a/techlibs/greenpak4/cells_map.v +++ /dev/null @@ -1,261 +0,0 @@ -module GP_DFFS(input D, CLK, nSET, output reg Q); - parameter [0:0] INIT = 1'bx; - GP_DFFSR #( - .INIT(INIT), - .SRMODE(1'b1), - ) _TECHMAP_REPLACE_ ( - .D(D), - .CLK(CLK), - .nSR(nSET), - .Q(Q) - ); -endmodule - -module GP_DFFR(input D, CLK, nRST, output reg Q); - parameter [0:0] INIT = 1'bx; - GP_DFFSR #( - .INIT(INIT), - .SRMODE(1'b0), - ) _TECHMAP_REPLACE_ ( - .D(D), - .CLK(CLK), - .nSR(nRST), - .Q(Q) - ); -endmodule - -module GP_DFFSI(input D, CLK, nSET, output reg nQ); - parameter [0:0] INIT = 1'bx; - GP_DFFSRI #( - .INIT(INIT), - .SRMODE(1'b1), - ) _TECHMAP_REPLACE_ ( - .D(D), - .CLK(CLK), - .nSR(nSET), - .nQ(nQ) - ); -endmodule - -module GP_DFFRI(input D, CLK, nRST, output reg nQ); - parameter [0:0] INIT = 1'bx; - GP_DFFSRI #( - .INIT(INIT), - .SRMODE(1'b0), - ) _TECHMAP_REPLACE_ ( - .D(D), - .CLK(CLK), - .nSR(nRST), - .nQ(nQ) - ); -endmodule - -module GP_DLATCHS(input D, nCLK, nSET, output reg Q); - parameter [0:0] INIT = 1'bx; - GP_DLATCHSR #( - .INIT(INIT), - .SRMODE(1'b1), - ) _TECHMAP_REPLACE_ ( - .D(D), - .nCLK(nCLK), - .nSR(nSET), - .Q(Q) - ); -endmodule - -module GP_DLATCHR(input D, nCLK, nRST, output reg Q); - parameter [0:0] INIT = 1'bx; - GP_DLATCHSR #( - .INIT(INIT), - .SRMODE(1'b0), - ) _TECHMAP_REPLACE_ ( - .D(D), - .nCLK(nCLK), - .nSR(nRST), - .Q(Q) - ); -endmodule - -module GP_DLATCHSI(input D, nCLK, nSET, output reg nQ); - parameter [0:0] INIT = 1'bx; - GP_DLATCHSRI #( - .INIT(INIT), - .SRMODE(1'b1), - ) _TECHMAP_REPLACE_ ( - .D(D), - .nCLK(nCLK), - .nSR(nSET), - .nQ(nQ) - ); -endmodule - -module GP_DLATCHRI(input D, nCLK, nRST, output reg nQ); - parameter [0:0] INIT = 1'bx; - GP_DLATCHSRI #( - .INIT(INIT), - .SRMODE(1'b0), - ) _TECHMAP_REPLACE_ ( - .D(D), - .nCLK(nCLK), - .nSR(nRST), - .nQ(nQ) - ); -endmodule - -module GP_OBUFT(input IN, input OE, output OUT); - GP_IOBUF _TECHMAP_REPLACE_ ( - .IN(IN), - .OE(OE), - .IO(OUT), - .OUT() - ); -endmodule - -module \$lut (A, Y); - parameter WIDTH = 0; - parameter LUT = 0; - - (* force_downto *) - input [WIDTH-1:0] A; - output Y; - - generate - if (WIDTH == 1) begin - if(LUT == 2'b01) begin - GP_INV _TECHMAP_REPLACE_ (.OUT(Y), .IN(A[0]) ); - end - else begin - GP_2LUT #(.INIT({2'b00, LUT})) _TECHMAP_REPLACE_ (.OUT(Y), - .IN0(A[0]), .IN1(1'b0)); - end - end else - if (WIDTH == 2) begin - GP_2LUT #(.INIT(LUT)) _TECHMAP_REPLACE_ (.OUT(Y), - .IN0(A[0]), .IN1(A[1])); - end else - if (WIDTH == 3) begin - GP_3LUT #(.INIT(LUT)) _TECHMAP_REPLACE_ (.OUT(Y), - .IN0(A[0]), .IN1(A[1]), .IN2(A[2])); - end else - if (WIDTH == 4) begin - GP_4LUT #(.INIT(LUT)) _TECHMAP_REPLACE_ (.OUT(Y), - .IN0(A[0]), .IN1(A[1]), .IN2(A[2]), .IN3(A[3])); - end else begin - wire _TECHMAP_FAIL_ = 1; - end - endgenerate -endmodule - -module \$__COUNT_ (CE, CLK, OUT, POUT, RST, UP); - - input wire CE; - input wire CLK; - output reg OUT; - (* force_downto *) - output reg[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 we have a DIRECTION other than DOWN fail... GP_COUNTx_ADV is not supported yet - if(DIRECTION != "DOWN") begin - initial begin - $display("ERROR: \$__COUNT_ support for GP_COUNTx_ADV is not yet implemented. This counter should never have been extracted (bug in extract_counter pass?)."); - $finish; - end - end - - //If counter is more than 14 bits wide, complain (also shouldn't happen) - else if(WIDTH > 14) begin - initial begin - $display("ERROR: \$__COUNT_ support for cascaded counters is not yet implemented. This counter should never have been extracted (bug in extract_counter pass?)."); - $finish; - end - end - - //If counter is more than 8 bits wide and has parallel output, we have a problem - else if(WIDTH > 8 && HAS_POUT) begin - initial begin - $display("ERROR: \$__COUNT_ support for 9-14 bit counters with parallel output is not yet implemented. This counter should never have been extracted (bug in extract_counter pass?)."); - $finish; - end - end - - //Looks like a legal counter! Do something with it - else if(WIDTH <= 8) begin - if(HAS_CE) begin - wire ce_not; - GP_INV ceinv( - .IN(CE), - .OUT(ce_not) - ); - GP_COUNT8_ADV #( - .COUNT_TO(COUNT_TO), - .RESET_MODE(RESET_MODE), - .RESET_VALUE(RESET_TO_MAX ? "COUNT_TO" : "ZERO"), - .CLKIN_DIVIDE(1) - ) _TECHMAP_REPLACE_ ( - .CLK(CLK), - .RST(RST), - .OUT(OUT), - .UP(1'b0), //always count down for now - .KEEP(ce_not), - .POUT(POUT) - ); - end - else begin - GP_COUNT8 #( - .COUNT_TO(COUNT_TO), - .RESET_MODE(RESET_MODE), - .CLKIN_DIVIDE(1) - ) _TECHMAP_REPLACE_ ( - .CLK(CLK), - .RST(RST), - .OUT(OUT), - .POUT(POUT) - ); - end - end - - else begin - if(HAS_CE) begin - wire ce_not; - GP_INV ceinv( - .IN(CE), - .OUT(ce_not) - ); - GP_COUNT14_ADV #( - .COUNT_TO(COUNT_TO), - .RESET_MODE(RESET_TO_MAX ? "COUNT_TO" : "ZERO"), - .RESET_VALUE("COUNT_TO"), - .CLKIN_DIVIDE(1) - ) _TECHMAP_REPLACE_ ( - .CLK(CLK), - .RST(RST), - .OUT(OUT), - .UP(1'b0), //always count down for now - .KEEP(ce_not), - .POUT(POUT) - ); - end - else begin - GP_COUNT14 #( - .COUNT_TO(COUNT_TO), - .RESET_MODE(RESET_MODE), - .CLKIN_DIVIDE(1) - ) _TECHMAP_REPLACE_ ( - .CLK(CLK), - .RST(RST), - .OUT(OUT) - ); - end - end - -endmodule diff --git a/techlibs/greenpak4/cells_sim.v b/techlibs/greenpak4/cells_sim.v deleted file mode 100644 index 221bee694..000000000 --- a/techlibs/greenpak4/cells_sim.v +++ /dev/null @@ -1,5 +0,0 @@ -`timescale 1ns/1ps - -`include "cells_sim_ams.v" -`include "cells_sim_digital.v" -`include "cells_sim_wip.v" diff --git a/techlibs/greenpak4/cells_sim_ams.v b/techlibs/greenpak4/cells_sim_ams.v deleted file mode 100644 index 7f8b3de3b..000000000 --- a/techlibs/greenpak4/cells_sim_ams.v +++ /dev/null @@ -1,110 +0,0 @@ -`timescale 1ns/1ps - -/* - This file contains analog / mixed signal cells, or other things that are not possible to fully model - in behavioral Verilog. - - It also contains some stuff like oscillators that use non-synthesizeable constructs such as delays. - TODO: do we want a third file for those cells? - */ - -module GP_ABUF(input wire IN, output wire OUT); - - assign OUT = IN; - - //must be 1, 5, 20, 50 - //values >1 only available with Vdd > 2.7V - parameter BANDWIDTH_KHZ = 1; - -endmodule - -module GP_ACMP(input wire PWREN, input wire VIN, input wire VREF, output reg OUT); - - parameter BANDWIDTH = "HIGH"; - parameter VIN_ATTEN = 1; - parameter VIN_ISRC_EN = 0; - parameter HYSTERESIS = 0; - - initial OUT = 0; - -endmodule - -module GP_BANDGAP(output reg OK); - parameter AUTO_PWRDN = 1; - parameter CHOPPER_EN = 1; - parameter OUT_DELAY = 100; - -endmodule - -module GP_DAC(input[7:0] DIN, input wire VREF, output reg VOUT); - - initial VOUT = 0; - - //analog hard IP is not supported for simulation - -endmodule - -module GP_LFOSC(input PWRDN, output reg CLKOUT); - - parameter PWRDN_EN = 0; - parameter AUTO_PWRDN = 0; - parameter OUT_DIV = 1; - - initial CLKOUT = 0; - - //auto powerdown not implemented for simulation - //output dividers not implemented for simulation - - always begin - if(PWRDN) - CLKOUT = 0; - else begin - //half period of 1730 Hz - #289017; - CLKOUT = ~CLKOUT; - end - end - -endmodule - -module GP_PGA(input wire VIN_P, input wire VIN_N, input wire VIN_SEL, output reg VOUT); - - parameter GAIN = 1; - parameter INPUT_MODE = "SINGLE"; - - initial VOUT = 0; - - //cannot simulate mixed signal IP - -endmodule - -module GP_PWRDET(output reg VDD_LOW); - initial VDD_LOW = 0; -endmodule - -module GP_VREF(input VIN, output reg VOUT); - parameter VIN_DIV = 1; - parameter VREF = 0; - //cannot simulate mixed signal IP -endmodule - -module GP_POR(output reg RST_DONE); - parameter POR_TIME = 500; - - initial begin - RST_DONE = 0; - - if(POR_TIME == 4) - #4000; - else if(POR_TIME == 500) - #500000; - else begin - $display("ERROR: bad POR_TIME for GP_POR cell"); - $finish; - end - - RST_DONE = 1; - - end - -endmodule diff --git a/techlibs/greenpak4/cells_sim_digital.v b/techlibs/greenpak4/cells_sim_digital.v deleted file mode 100644 index f1393be0c..000000000 --- a/techlibs/greenpak4/cells_sim_digital.v +++ /dev/null @@ -1,794 +0,0 @@ -`timescale 1ns/1ps - -/* - This file contains simulation models for GreenPAK cells which are possible to fully model using synthesizeable - behavioral Verilog constructs only. - */ - -module GP_2LUT(input IN0, IN1, output OUT); - parameter [3:0] INIT = 0; - assign OUT = INIT[{IN1, IN0}]; -endmodule - -module GP_3LUT(input IN0, IN1, IN2, output OUT); - parameter [7:0] INIT = 0; - assign OUT = INIT[{IN2, IN1, IN0}]; -endmodule - -module GP_4LUT( - input wire IN0, - input wire IN1, - input wire IN2, - input wire IN3, - output wire OUT); - - parameter [15:0] INIT = 0; - assign OUT = INIT[{IN3, IN2, IN1, IN0}]; -endmodule - -module GP_CLKBUF(input wire IN, output wire OUT); - assign OUT = IN; -endmodule - -module GP_COUNT14(input CLK, input wire RST, output reg OUT); - - parameter RESET_MODE = "RISING"; - - parameter COUNT_TO = 14'h1; - parameter CLKIN_DIVIDE = 1; - - reg[13:0] count = COUNT_TO; - - initial begin - if(CLKIN_DIVIDE != 1) begin - $display("ERROR: CLKIN_DIVIDE values other than 1 not implemented"); - $finish; - end - end - - //Combinatorially output underflow flag whenever we wrap low - always @(*) begin - OUT = (count == 14'h0); - end - - //POR or SYSRST reset value is COUNT_TO. Datasheet is unclear but conversations w/ Silego confirm. - //Runtime reset value is clearly 0 except in count/FSM cells where it's configurable but we leave at 0 for now. - generate - case(RESET_MODE) - - "RISING": begin - always @(posedge CLK, posedge RST) begin - if(RST) - count <= 0; - else begin - count <= count - 1'd1; - if(count == 0) - count <= COUNT_TO; - end - end - end - - "FALLING": begin - always @(posedge CLK, negedge RST) begin - if(!RST) - count <= 0; - else begin - count <= count - 1'd1; - if(count == 0) - count <= COUNT_TO; - end - end - end - - "BOTH": begin - initial begin - $display("Both-edge reset mode for GP_COUNT14 not implemented"); - $finish; - end - end - - "LEVEL": begin - always @(posedge CLK, posedge RST) begin - if(RST) - count <= 0; - - else begin - count <= count - 1'd1; - if(count == 0) - count <= COUNT_TO; - end - end - end - - default: begin - initial begin - $display("Invalid RESET_MODE on GP_COUNT14"); - $finish; - end - end - - endcase - endgenerate - -endmodule - -module GP_COUNT14_ADV(input CLK, input RST, output reg OUT, - input UP, input KEEP, output reg[7:0] POUT); - - parameter RESET_MODE = "RISING"; - parameter RESET_VALUE = "ZERO"; - - parameter COUNT_TO = 14'h1; - parameter CLKIN_DIVIDE = 1; - - initial begin - if(CLKIN_DIVIDE != 1) begin - $display("ERROR: CLKIN_DIVIDE values other than 1 not implemented"); - $finish; - end - end - - reg[13:0] count = COUNT_TO; - - //Combinatorially output underflow flag whenever we wrap low - always @(*) begin - if(UP) - OUT = (count == 14'h3fff); - else - OUT = (count == 14'h0); - POUT = count[7:0]; - end - - //POR or SYSRST reset value is COUNT_TO. Datasheet is unclear but conversations w/ Silego confirm. - //Runtime reset value is clearly 0 except in count/FSM cells where it's configurable but we leave at 0 for now. - generate - case(RESET_MODE) - - "RISING": begin - always @(posedge CLK, posedge RST) begin - - //Resets - if(RST) begin - if(RESET_VALUE == "ZERO") - count <= 0; - else - count <= COUNT_TO; - end - - else if(KEEP) begin - end - else if(UP) begin - count <= count + 1'd1; - if(count == 14'h3fff) - count <= COUNT_TO; - end - else begin - count <= count - 1'd1; - - if(count == 0) - count <= COUNT_TO; - end - - end - end - - "FALLING": begin - always @(posedge CLK, negedge RST) begin - - //Resets - if(!RST) begin - if(RESET_VALUE == "ZERO") - count <= 0; - else - count <= COUNT_TO; - end - - else if(KEEP) begin - end - else if(UP) begin - count <= count + 1'd1; - if(count == 14'h3fff) - count <= COUNT_TO; - end - else begin - count <= count - 1'd1; - - if(count == 0) - count <= COUNT_TO; - end - - end - end - - "BOTH": begin - initial begin - $display("Both-edge reset mode for GP_COUNT14_ADV not implemented"); - $finish; - end - end - - "LEVEL": begin - always @(posedge CLK, posedge RST) begin - - //Resets - if(RST) begin - if(RESET_VALUE == "ZERO") - count <= 0; - else - count <= COUNT_TO; - end - - else begin - - if(KEEP) begin - end - else if(UP) begin - count <= count + 1'd1; - if(count == 14'h3fff) - count <= COUNT_TO; - end - else begin - count <= count - 1'd1; - - if(count == 0) - count <= COUNT_TO; - end - - end - - end - end - - default: begin - initial begin - $display("Invalid RESET_MODE on GP_COUNT14_ADV"); - $finish; - end - end - - endcase - endgenerate - -endmodule - -module GP_COUNT8_ADV(input CLK, input RST, output reg OUT, - input UP, input KEEP, output reg[7:0] POUT); - - parameter RESET_MODE = "RISING"; - parameter RESET_VALUE = "ZERO"; - - parameter COUNT_TO = 8'h1; - parameter CLKIN_DIVIDE = 1; - - reg[7:0] count = COUNT_TO; - - initial begin - if(CLKIN_DIVIDE != 1) begin - $display("ERROR: CLKIN_DIVIDE values other than 1 not implemented"); - $finish; - end - end - - //Combinatorially output underflow flag whenever we wrap low - always @(*) begin - if(UP) - OUT = (count == 8'hff); - else - OUT = (count == 8'h0); - POUT = count; - end - - //POR or SYSRST reset value is COUNT_TO. Datasheet is unclear but conversations w/ Silego confirm. - //Runtime reset value is clearly 0 except in count/FSM cells where it's configurable but we leave at 0 for now. - generate - case(RESET_MODE) - - "RISING": begin - always @(posedge CLK, posedge RST) begin - - //Resets - if(RST) begin - if(RESET_VALUE == "ZERO") - count <= 0; - else - count <= COUNT_TO; - end - - //Main counter - else if(KEEP) begin - end - else if(UP) begin - count <= count + 1'd1; - if(count == 8'hff) - count <= COUNT_TO; - end - else begin - count <= count - 1'd1; - - if(count == 0) - count <= COUNT_TO; - end - - end - end - - "FALLING": begin - always @(posedge CLK, negedge RST) begin - - //Resets - if(!RST) begin - if(RESET_VALUE == "ZERO") - count <= 0; - else - count <= COUNT_TO; - end - - //Main counter - else if(KEEP) begin - end - else if(UP) begin - count <= count + 1'd1; - if(count == 8'hff) - count <= COUNT_TO; - end - else begin - count <= count - 1'd1; - - if(count == 0) - count <= COUNT_TO; - end - - end - end - - "BOTH": begin - initial begin - $display("Both-edge reset mode for GP_COUNT8_ADV not implemented"); - $finish; - end - end - - "LEVEL": begin - always @(posedge CLK, posedge RST) begin - - //Resets - if(RST) begin - if(RESET_VALUE == "ZERO") - count <= 0; - else - count <= COUNT_TO; - end - - else begin - - if(KEEP) begin - end - else if(UP) begin - count <= count + 1'd1; - if(count == 8'hff) - count <= COUNT_TO; - end - else begin - count <= count - 1'd1; - - if(count == 0) - count <= COUNT_TO; - end - end - - end - end - - default: begin - initial begin - $display("Invalid RESET_MODE on GP_COUNT8_ADV"); - $finish; - end - end - - endcase - endgenerate - -endmodule - -module GP_COUNT8( - input wire CLK, - input wire RST, - output reg OUT, - output reg[7:0] POUT); - - parameter RESET_MODE = "RISING"; - - parameter COUNT_TO = 8'h1; - parameter CLKIN_DIVIDE = 1; - - initial begin - if(CLKIN_DIVIDE != 1) begin - $display("ERROR: CLKIN_DIVIDE values other than 1 not implemented"); - $finish; - end - end - - reg[7:0] count = COUNT_TO; - - //Combinatorially output underflow flag whenever we wrap low - always @(*) begin - OUT = (count == 8'h0); - POUT = count; - end - - //POR or SYSRST reset value is COUNT_TO. Datasheet is unclear but conversations w/ Silego confirm. - //Runtime reset value is clearly 0 except in count/FSM cells where it's configurable but we leave at 0 for now. - generate - case(RESET_MODE) - - "RISING": begin - always @(posedge CLK, posedge RST) begin - if(RST) - count <= 0; - else begin - count <= count - 1'd1; - if(count == 0) - count <= COUNT_TO; - end - end - end - - "FALLING": begin - always @(posedge CLK, negedge RST) begin - if(!RST) - count <= 0; - else begin - count <= count - 1'd1; - if(count == 0) - count <= COUNT_TO; - end - end - end - - "BOTH": begin - initial begin - $display("Both-edge reset mode for GP_COUNT8 not implemented"); - $finish; - end - end - - "LEVEL": begin - always @(posedge CLK, posedge RST) begin - if(RST) - count <= 0; - - else begin - count <= count - 1'd1; - if(count == 0) - count <= COUNT_TO; - end - end - end - - default: begin - initial begin - $display("Invalid RESET_MODE on GP_COUNT8"); - $finish; - end - end - - endcase - endgenerate - -endmodule - -module GP_DCMPREF(output reg[7:0]OUT); - parameter[7:0] REF_VAL = 8'h00; - initial OUT = REF_VAL; -endmodule - -module GP_DCMPMUX(input[1:0] SEL, input[7:0] IN0, input[7:0] IN1, input[7:0] IN2, input[7:0] IN3, output reg[7:0] OUTA, output reg[7:0] OUTB); - - always @(*) begin - case(SEL) - 2'd00: begin - OUTA = IN0; - OUTB = IN3; - end - - 2'd01: begin - OUTA = IN1; - OUTB = IN2; - end - - 2'd02: begin - OUTA = IN2; - OUTB = IN1; - end - - 2'd03: begin - OUTA = IN3; - OUTB = IN0; - end - - endcase - end -endmodule - -module GP_DELAY(input IN, output reg OUT); - - parameter DELAY_STEPS = 1; - parameter GLITCH_FILTER = 0; - - initial OUT = 0; - - generate - - if(GLITCH_FILTER) begin - initial begin - $display("ERROR: GP_DELAY glitch filter mode not implemented"); - $finish; - end - end - - //TODO: These delays are PTV dependent! For now, hard code 3v3 timing - //Change simulation-mode delay depending on global Vdd range (how to specify this?) - always @(*) begin - case(DELAY_STEPS) - 1: #166 OUT = IN; - 2: #318 OUT = IN; - 2: #471 OUT = IN; - 3: #622 OUT = IN; - default: begin - $display("ERROR: GP_DELAY must have DELAY_STEPS in range [1,4]"); - $finish; - end - endcase - end - - endgenerate - -endmodule - -module GP_DFF(input D, CLK, output reg Q); - parameter [0:0] INIT = 1'bx; - initial Q = INIT; - always @(posedge CLK) begin - Q <= D; - end -endmodule - -module GP_DFFI(input D, CLK, output reg nQ); - parameter [0:0] INIT = 1'bx; - initial nQ = INIT; - always @(posedge CLK) begin - nQ <= ~D; - end -endmodule - -module GP_DFFR(input D, CLK, nRST, output reg Q); - parameter [0:0] INIT = 1'bx; - initial Q = INIT; - always @(posedge CLK, negedge nRST) begin - if (!nRST) - Q <= 1'b0; - else - Q <= D; - end -endmodule - -module GP_DFFRI(input D, CLK, nRST, output reg nQ); - parameter [0:0] INIT = 1'bx; - initial nQ = INIT; - always @(posedge CLK, negedge nRST) begin - if (!nRST) - nQ <= 1'b1; - else - nQ <= ~D; - end -endmodule - -module GP_DFFS(input D, CLK, nSET, output reg Q); - parameter [0:0] INIT = 1'bx; - initial Q = INIT; - always @(posedge CLK, negedge nSET) begin - if (!nSET) - Q <= 1'b1; - else - Q <= D; - end -endmodule - -module GP_DFFSI(input D, CLK, nSET, output reg nQ); - parameter [0:0] INIT = 1'bx; - initial nQ = INIT; - always @(posedge CLK, negedge nSET) begin - if (!nSET) - nQ <= 1'b0; - else - nQ <= ~D; - end -endmodule - -module GP_DFFSR(input D, CLK, nSR, output reg Q); - parameter [0:0] INIT = 1'bx; - parameter [0:0] SRMODE = 1'bx; - initial Q = INIT; - always @(posedge CLK, negedge nSR) begin - if (!nSR) - Q <= SRMODE; - else - Q <= D; - end -endmodule - -module GP_DFFSRI(input D, CLK, nSR, output reg nQ); - parameter [0:0] INIT = 1'bx; - parameter [0:0] SRMODE = 1'bx; - initial nQ = INIT; - always @(posedge CLK, negedge nSR) begin - if (!nSR) - nQ <= ~SRMODE; - else - nQ <= ~D; - end -endmodule - -module GP_DLATCH(input D, input nCLK, output reg Q); - parameter [0:0] INIT = 1'bx; - initial Q = INIT; - always @(*) begin - if(!nCLK) - Q = D; - end -endmodule - -module GP_DLATCHI(input D, input nCLK, output reg nQ); - parameter [0:0] INIT = 1'bx; - initial nQ = INIT; - always @(*) begin - if(!nCLK) - nQ = ~D; - end -endmodule - -module GP_DLATCHR(input D, input nCLK, input nRST, output reg Q); - parameter [0:0] INIT = 1'bx; - initial Q = INIT; - always @(*) begin - if(!nRST) - Q = 1'b0; - else if(!nCLK) - Q = D; - end -endmodule - -module GP_DLATCHRI(input D, input nCLK, input nRST, output reg nQ); - parameter [0:0] INIT = 1'bx; - initial nQ = INIT; - always @(*) begin - if(!nRST) - nQ = 1'b1; - else if(!nCLK) - nQ = ~D; - end -endmodule - -module GP_DLATCHS(input D, input nCLK, input nSET, output reg Q); - parameter [0:0] INIT = 1'bx; - initial Q = INIT; - always @(*) begin - if(!nSET) - Q = 1'b1; - else if(!nCLK) - Q = D; - end -endmodule - -module GP_DLATCHSI(input D, input nCLK, input nSET, output reg nQ); - parameter [0:0] INIT = 1'bx; - initial nQ = INIT; - always @(*) begin - if(!nSET) - nQ = 1'b0; - else if(!nCLK) - nQ = ~D; - end -endmodule - -module GP_DLATCHSR(input D, input nCLK, input nSR, output reg Q); - parameter [0:0] INIT = 1'bx; - parameter[0:0] SRMODE = 1'bx; - initial Q = INIT; - always @(*) begin - if(!nSR) - Q = SRMODE; - else if(!nCLK) - Q = D; - end -endmodule - -module GP_DLATCHSRI(input D, input nCLK, input nSR, output reg nQ); - parameter [0:0] INIT = 1'bx; - parameter[0:0] SRMODE = 1'bx; - initial nQ = INIT; - always @(*) begin - if(!nSR) - nQ = ~SRMODE; - else if(!nCLK) - nQ = ~D; - end -endmodule - -module GP_IBUF(input IN, output OUT); - assign OUT = IN; -endmodule - -module GP_IOBUF(input IN, input OE, output OUT, inout IO); - assign OUT = IO; - assign IO = OE ? IN : 1'bz; -endmodule - -module GP_INV(input IN, output OUT); - assign OUT = ~IN; -endmodule - -module GP_OBUF(input IN, output OUT); - assign OUT = IN; -endmodule - -module GP_OBUFT(input IN, input OE, output OUT); - assign OUT = OE ? IN : 1'bz; -endmodule - -module GP_PGEN(input wire nRST, input wire CLK, output reg OUT); - initial OUT = 0; - parameter PATTERN_DATA = 16'h0; - parameter PATTERN_LEN = 5'd16; - - localparam COUNT_MAX = PATTERN_LEN - 1'h1; - - reg[3:0] count = 0; - always @(posedge CLK, negedge nRST) begin - - if(!nRST) - count <= 0; - - else begin - count <= count - 1'h1; - if(count == 0) - count <= COUNT_MAX; - end - end - - always @(*) - OUT = PATTERN_DATA[count]; - -endmodule - -module GP_SHREG(input nRST, input CLK, input IN, output OUTA, output OUTB); - - parameter OUTA_TAP = 1; - parameter OUTA_INVERT = 0; - parameter OUTB_TAP = 1; - - reg[15:0] shreg = 0; - - always @(posedge CLK, negedge nRST) begin - - if(!nRST) - shreg = 0; - - else - shreg <= {shreg[14:0], IN}; - - end - - assign OUTA = (OUTA_INVERT) ? ~shreg[OUTA_TAP - 1] : shreg[OUTA_TAP - 1]; - assign OUTB = shreg[OUTB_TAP - 1]; - -endmodule - -module GP_VDD(output OUT); - assign OUT = 1; -endmodule - -module GP_VSS(output OUT); - assign OUT = 0; -endmodule diff --git a/techlibs/greenpak4/cells_sim_wip.v b/techlibs/greenpak4/cells_sim_wip.v deleted file mode 100644 index 5261b12d2..000000000 --- a/techlibs/greenpak4/cells_sim_wip.v +++ /dev/null @@ -1,136 +0,0 @@ - -//Cells still in this file have INCOMPLETE simulation models, need to finish them - -module GP_DCMP(input[7:0] INP, input[7:0] INN, input CLK, input PWRDN, output reg GREATER, output reg EQUAL); - parameter PWRDN_SYNC = 1'b0; - parameter CLK_EDGE = "RISING"; - parameter GREATER_OR_EQUAL = 1'b0; - - //TODO implement power-down mode - - initial GREATER = 0; - initial EQUAL = 0; - - wire clk_minv = (CLK_EDGE == "RISING") ? CLK : ~CLK; - always @(posedge clk_minv) begin - if(GREATER_OR_EQUAL) - GREATER <= (INP >= INN); - else - GREATER <= (INP > INN); - - EQUAL <= (INP == INN); - end - -endmodule - -module GP_EDGEDET(input IN, output reg OUT); - - parameter EDGE_DIRECTION = "RISING"; - parameter DELAY_STEPS = 1; - parameter GLITCH_FILTER = 0; - - //not implemented for simulation - -endmodule - -module GP_RCOSC(input PWRDN, output reg CLKOUT_HARDIP, output reg CLKOUT_FABRIC); - - parameter PWRDN_EN = 0; - parameter AUTO_PWRDN = 0; - parameter HARDIP_DIV = 1; - parameter FABRIC_DIV = 1; - parameter OSC_FREQ = "25k"; - - initial CLKOUT_HARDIP = 0; - initial CLKOUT_FABRIC = 0; - - //output dividers not implemented for simulation - //auto powerdown not implemented for simulation - - always begin - if(PWRDN) begin - CLKOUT_HARDIP = 0; - CLKOUT_FABRIC = 0; - end - else begin - - if(OSC_FREQ == "25k") begin - //half period of 25 kHz - #20000; - end - - else begin - //half period of 2 MHz - #250; - end - - CLKOUT_HARDIP = ~CLKOUT_HARDIP; - CLKOUT_FABRIC = ~CLKOUT_FABRIC; - end - end - -endmodule - -module GP_RINGOSC(input PWRDN, output reg CLKOUT_HARDIP, output reg CLKOUT_FABRIC); - - parameter PWRDN_EN = 0; - parameter AUTO_PWRDN = 0; - parameter HARDIP_DIV = 1; - parameter FABRIC_DIV = 1; - - initial CLKOUT_HARDIP = 0; - initial CLKOUT_FABRIC = 0; - - //output dividers not implemented for simulation - //auto powerdown not implemented for simulation - - always begin - if(PWRDN) begin - CLKOUT_HARDIP = 0; - CLKOUT_FABRIC = 0; - end - else begin - //half period of 27 MHz - #18.518; - CLKOUT_HARDIP = ~CLKOUT_HARDIP; - CLKOUT_FABRIC = ~CLKOUT_FABRIC; - end - end - -endmodule - -module GP_SPI( - input SCK, - inout SDAT, - input CSN, - input[7:0] TXD_HIGH, - input[7:0] TXD_LOW, - output reg[7:0] RXD_HIGH, - output reg[7:0] RXD_LOW, - output reg INT); - - initial RXD_HIGH = 0; - initial RXD_LOW = 0; - initial INT = 0; - - parameter DATA_WIDTH = 8; //byte or word width - parameter SPI_CPHA = 0; //SPI clock phase - parameter SPI_CPOL = 0; //SPI clock polarity - parameter DIRECTION = "INPUT"; //SPI data direction (either input to chip or output to host) - //parallel output to fabric not yet implemented - - //TODO: write sim model - //TODO: SPI SDIO control... can we use ADC output while SPI is input?? - //TODO: clock sync - -endmodule - -//keep constraint needed to prevent optimization since we have no outputs -(* keep *) -module GP_SYSRESET(input RST); - parameter RESET_MODE = "EDGE"; - parameter EDGE_SPEED = 4; - - //cannot simulate whole system reset - -endmodule diff --git a/techlibs/greenpak4/gp_dff.lib b/techlibs/greenpak4/gp_dff.lib deleted file mode 100644 index b4b8c1028..000000000 --- a/techlibs/greenpak4/gp_dff.lib +++ /dev/null @@ -1,36 +0,0 @@ -library(gp_dff) { - cell(GP_DFF) { - area: 1; - ff("IQ", "IQN") { clocked_on: CLK; - next_state: D; } - pin(CLK) { direction: input; - clock: true; } - pin(D) { direction: input; } - pin(Q) { direction: output; - function: "IQ"; } - } - cell(GP_DFFS) { - area: 1; - ff("IQ", "IQN") { clocked_on: CLK; - next_state: D; - preset: "nSET'"; } - pin(CLK) { direction: input; - clock: true; } - pin(D) { direction: input; } - pin(Q) { direction: output; - function: "IQ"; } - pin(nSET) { direction: input; } - } - cell(GP_DFFR) { - area: 1; - ff("IQ", "IQN") { clocked_on: CLK; - next_state: D; - clear: "nRST'"; } - pin(CLK) { direction: input; - clock: true; } - pin(D) { direction: input; } - pin(Q) { direction: output; - function: "IQ"; } - pin(nRST) { direction: input; } - } -} diff --git a/techlibs/greenpak4/greenpak4_dffinv.cc b/techlibs/greenpak4/greenpak4_dffinv.cc deleted file mode 100644 index 691013c8e..000000000 --- a/techlibs/greenpak4/greenpak4_dffinv.cc +++ /dev/null @@ -1,210 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2012 Claire Xenia Wolf - * - * 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 - -void invert_gp_dff(Cell *cell, bool invert_input) -{ - string cell_type = cell->type.str(); - bool cell_type_latch = cell_type.find("LATCH") != string::npos; - bool cell_type_i = cell_type.find('I') != string::npos; - bool cell_type_r = cell_type.find('R') != string::npos; - bool cell_type_s = cell_type.find('S') != string::npos; - - if (!invert_input) - { - Const initval = cell->getParam(ID::INIT); - if (GetSize(initval) >= 1) { - if (initval[0] == State::S0) - initval.set(0, State::S1); - else if (initval[0] == State::S1) - initval.set(0, State::S0); - cell->setParam(ID::INIT, initval); - } - - if (cell_type_r && cell_type_s) - { - Const srmode = cell->getParam(ID(SRMODE)); - if (GetSize(srmode) >= 1) { - if (srmode[0] == State::S0) - srmode.set(0, State::S1); - else if (srmode[0] == State::S1) - srmode.set(0, State::S0); - cell->setParam(ID(SRMODE), srmode); - } - } - else - { - if (cell_type_r) { - cell->setPort(ID(nSET), cell->getPort(ID(nRST))); - cell->unsetPort(ID(nRST)); - cell_type_r = false; - cell_type_s = true; - } else - if (cell_type_s) { - cell->setPort(ID(nRST), cell->getPort(ID(nSET))); - cell->unsetPort(ID(nSET)); - cell_type_r = true; - cell_type_s = false; - } - } - } - - if (cell_type_i) { - cell->setPort(ID::Q, cell->getPort(ID(nQ))); - cell->unsetPort(ID(nQ)); - cell_type_i = false; - } else { - cell->setPort(ID(nQ), cell->getPort(ID::Q)); - cell->unsetPort(ID::Q); - cell_type_i = true; - } - - if(cell_type_latch) - cell->type = stringf("\\GP_DLATCH%s%s%s", cell_type_s ? "S" : "", cell_type_r ? "R" : "", cell_type_i ? "I" : ""); - else - cell->type = stringf("\\GP_DFF%s%s%s", cell_type_s ? "S" : "", cell_type_r ? "R" : "", cell_type_i ? "I" : ""); - - log("Merged %s inverter into cell %s.%s: %s -> %s\n", invert_input ? "input" : "output", - cell->module, cell, cell_type.c_str()+1, cell->type.unescape()); -} - -struct Greenpak4DffInvPass : public Pass { - Greenpak4DffInvPass() : Pass("greenpak4_dffinv", "merge greenpak4 inverters and DFF/latches") { } - void help() override - { - log("\n"); - log(" greenpak4_dffinv [options] [selection]\n"); - log("\n"); - log("Merge GP_INV cells with GP_DFF* and GP_DLATCH* cells.\n"); - log("\n"); - } - void execute(std::vector args, RTLIL::Design *design) override - { - log_header(design, "Executing GREENPAK4_DFFINV pass (merge input/output inverters into FF/latch cells).\n"); - - size_t argidx; - for (argidx = 1; argidx < args.size(); argidx++) - { - // if (args[argidx] == "-singleton") { - // singleton_mode = true; - // continue; - // } - break; - } - extra_args(args, argidx, design); - - pool gp_dff_types; - gp_dff_types.insert(ID(GP_DFF)); - gp_dff_types.insert(ID(GP_DFFI)); - gp_dff_types.insert(ID(GP_DFFR)); - gp_dff_types.insert(ID(GP_DFFRI)); - gp_dff_types.insert(ID(GP_DFFS)); - gp_dff_types.insert(ID(GP_DFFSI)); - gp_dff_types.insert(ID(GP_DFFSR)); - gp_dff_types.insert(ID(GP_DFFSRI)); - - gp_dff_types.insert(ID(GP_DLATCH)); - gp_dff_types.insert(ID(GP_DLATCHI)); - gp_dff_types.insert(ID(GP_DLATCHR)); - gp_dff_types.insert(ID(GP_DLATCHRI)); - gp_dff_types.insert(ID(GP_DLATCHS)); - gp_dff_types.insert(ID(GP_DLATCHSI)); - gp_dff_types.insert(ID(GP_DLATCHSR)); - gp_dff_types.insert(ID(GP_DLATCHSRI)); - - for (auto module : design->selected_modules()) - { - SigMap sigmap(module); - dict sig_use_cnt; - dict inv_in2out, inv_out2in; - dict inv_in2cell; - pool dff_cells; - - for (auto wire : module->wires()) - { - if (!wire->port_output) - continue; - - for (auto bit : sigmap(wire)) - sig_use_cnt[bit]++; - } - - for (auto cell : module->cells()) - for (auto &conn : cell->connections()) - if (cell->input(conn.first) || !cell->known()) - for (auto bit : sigmap(conn.second)) - sig_use_cnt[bit]++; - - for (auto cell : module->selected_cells()) - { - if (gp_dff_types.count(cell->type)) { - dff_cells.insert(cell); - continue; - } - - if (cell->type == ID(GP_INV)) { - SigBit in_bit = sigmap(cell->getPort(ID(IN))); - SigBit out_bit = sigmap(cell->getPort(ID(OUT))); - inv_in2out[in_bit] = out_bit; - inv_out2in[out_bit] = in_bit; - inv_in2cell[in_bit] = cell; - continue; - } - } - - for (auto cell : dff_cells) - { - SigBit d_bit = sigmap(cell->getPort(ID::D)); - SigBit q_bit = sigmap(cell->hasPort(ID::Q) ? cell->getPort(ID::Q) : cell->getPort(ID(nQ))); - - while (inv_out2in.count(d_bit)) - { - sig_use_cnt[d_bit]--; - invert_gp_dff(cell, true); - d_bit = inv_out2in.at(d_bit); - cell->setPort(ID::D, d_bit); - sig_use_cnt[d_bit]++; - } - - while (inv_in2out.count(q_bit) && sig_use_cnt[q_bit] == 1) - { - SigBit new_q_bit = inv_in2out.at(q_bit); - module->remove(inv_in2cell.at(q_bit)); - sig_use_cnt.erase(q_bit); - inv_in2out.erase(q_bit); - inv_out2in.erase(new_q_bit); - inv_in2cell.erase(q_bit); - - invert_gp_dff(cell, false); - if (cell->hasPort(ID::Q)) - cell->setPort(ID::Q, new_q_bit); - else - cell->setPort(ID(nQ), new_q_bit); - } - } - } - } -} Greenpak4DffInvPass; - -PRIVATE_NAMESPACE_END diff --git a/techlibs/greenpak4/synth_greenpak4.cc b/techlibs/greenpak4/synth_greenpak4.cc deleted file mode 100644 index 7f91d6332..000000000 --- a/techlibs/greenpak4/synth_greenpak4.cc +++ /dev/null @@ -1,211 +0,0 @@ -/* - * yosys -- Yosys Open SYnthesis Suite - * - * Copyright (C) 2012 Claire Xenia Wolf - * - * 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 SynthGreenPAK4Pass : public ScriptPass -{ - SynthGreenPAK4Pass() : ScriptPass("synth_greenpak4", "synthesis for GreenPAK4 FPGAs") { } - - void help() override - { - // |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---| - log("\n"); - log(" synth_greenpak4 [options]\n"); - log("\n"); - log("This command runs synthesis for GreenPAK4 FPGAs. 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(" -part \n"); - log(" synthesize for the specified part. Valid values are SLG46140V,\n"); - log(" SLG46620V, and SLG46621V (default).\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, part, json_file; - bool flatten, retime; - - void clear_flags() override - { - top_opt = "-auto-top"; - part = "SLG46621V"; - 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] == "-part" && argidx+1 < args.size()) { - part = 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"); - - if (part != "SLG46140V" && part != "SLG46620V" && part != "SLG46621V") - log_cmd_error("Invalid part name: '%s'\n", part); - - log_header(design, "Executing SYNTH_GREENPAK4 pass.\n"); - log_push(); - - run_script(design, run_from, run_to); - - log_pop(); - } - - void script() override - { - if (check_label("begin")) - { - run("read_verilog -lib +/greenpak4/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 -pout GP_DCMP,GP_DAC -maxwidth 14"); - run("clean"); - run("opt -fast -mux_undef -undriven -fine"); - run("memory_map"); - run("opt -undriven -fine"); - run("techmap -map +/techmap.v -map +/greenpak4/cells_latch.v"); - run("dfflibmap -prepare -liberty +/greenpak4/gp_dff.lib"); - run("opt -fast -noclkinv -noff"); - if (retime || help_mode) - run("abc -dff -D 1", "(only if -retime)"); - } - - if (check_label("map_luts")) - { - if (help_mode || part == "SLG46140V") run("nlutmap -assert -luts 0,6,8,2", " (for -part SLG46140V)"); - if (help_mode || part == "SLG46620V") run("nlutmap -assert -luts 2,8,16,2", "(for -part SLG46620V)"); - if (help_mode || part == "SLG46621V") run("nlutmap -assert -luts 2,8,16,2", "(for -part SLG46621V)"); - run("clean"); - } - - if (check_label("map_cells")) - { - run("shregmap -tech greenpak4"); - run("dfflibmap -liberty +/greenpak4/gp_dff.lib"); - run("dffinit -ff GP_DFF Q INIT"); - run("dffinit -ff GP_DFFR Q INIT"); - run("dffinit -ff GP_DFFS Q INIT"); - run("dffinit -ff GP_DFFSR Q INIT"); - run("iopadmap -bits -inpad GP_IBUF OUT:IN -outpad GP_OBUF IN:OUT -inoutpad GP_OBUF OUT:IN -toutpad GP_OBUFT OE:IN:OUT -tinoutpad GP_IOBUF OE:OUT:IN:IO"); - run("attrmvcp -attr src -attr LOC t:GP_OBUF t:GP_OBUFT t:GP_IOBUF n:*"); - run("attrmvcp -attr src -attr LOC -driven t:GP_IBUF n:*"); - run("techmap -map +/greenpak4/cells_map.v"); - run("greenpak4_dffinv"); - 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)); - } - } -} SynthGreenPAK4Pass; - -PRIVATE_NAMESPACE_END