3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-04-24 01:25:33 +00:00

Merge remote-tracking branch 'origin/master' into xaig_dff

This commit is contained in:
Eddie Hung 2019-09-27 15:14:31 -07:00
commit 8f5710c464
174 changed files with 26477 additions and 2398 deletions

View file

@ -1,7 +1,7 @@
OBJS += techlibs/anlogic/synth_anlogic.o
OBJS += techlibs/anlogic/anlogic_eqn.o
OBJS += techlibs/anlogic/anlogic_determine_init.o
OBJS += techlibs/anlogic/anlogic_fixcarry.o
$(eval $(call add_share_file,share/anlogic,techlibs/anlogic/cells_map.v))
$(eval $(call add_share_file,share/anlogic,techlibs/anlogic/arith_map.v))

View file

@ -1,72 +0,0 @@
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2018 Icenowy Zheng <icenowy@aosc.io>
*
* 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 AnlogicDetermineInitPass : public Pass {
AnlogicDetermineInitPass() : Pass("anlogic_determine_init", "Anlogic: Determine the init value of cells") { }
void help() YS_OVERRIDE
{
log("\n");
log(" anlogic_determine_init [selection]\n");
log("\n");
log("Determine the init value of cells that doesn't allow unknown init value.\n");
log("\n");
}
Const determine_init(Const init)
{
for (int i = 0; i < GetSize(init); i++) {
if (init[i] != State::S0 && init[i] != State::S1)
init[i] = State::S0;
}
return init;
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
log_header(design, "Executing ANLOGIC_DETERMINE_INIT pass (determine init value for cells).\n");
extra_args(args, args.size(), design);
int cnt = 0;
for (auto module : design->selected_modules())
{
for (auto cell : module->selected_cells())
{
if (cell->type == "\\EG_LOGIC_DRAM16X4")
{
cell->setParam("\\INIT_D0", determine_init(cell->getParam("\\INIT_D0")));
cell->setParam("\\INIT_D1", determine_init(cell->getParam("\\INIT_D1")));
cell->setParam("\\INIT_D2", determine_init(cell->getParam("\\INIT_D2")));
cell->setParam("\\INIT_D3", determine_init(cell->getParam("\\INIT_D3")));
cnt++;
}
}
}
log_header(design, "Updated %d cells with determined init value.\n", cnt);
}
} AnlogicDetermineInitPass;
PRIVATE_NAMESPACE_END

View file

@ -0,0 +1,130 @@
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2019 Miodrag Milanovic <miodrag@symbioticeda.com>
*
* 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
static SigBit get_bit_or_zero(const SigSpec &sig)
{
if (GetSize(sig) == 0)
return State::S0;
return sig[0];
}
static void fix_carry_chain(Module *module)
{
SigMap sigmap(module);
pool<SigBit> ci_bits;
dict<SigBit, SigBit> mapping_bits;
for (auto cell : module->cells())
{
if (cell->type == "\\AL_MAP_ADDER") {
if (cell->getParam("\\ALUTYPE") != Const("ADD")) continue;
SigBit bit_i0 = get_bit_or_zero(cell->getPort("\\a"));
SigBit bit_i1 = get_bit_or_zero(cell->getPort("\\b"));
if (bit_i0 == State::S0 && bit_i1== State::S0) {
SigBit bit_ci = get_bit_or_zero(cell->getPort("\\c"));
SigSpec o = cell->getPort("\\o");
if (GetSize(o) == 2) {
SigBit bit_o = o[0];
ci_bits.insert(bit_ci);
mapping_bits[bit_ci] = bit_o;
}
}
}
}
vector<Cell*> adders_to_fix_cells;
for (auto cell : module->cells())
{
if (cell->type == "\\AL_MAP_ADDER") {
if (cell->getParam("\\ALUTYPE") != Const("ADD")) continue;
SigBit bit_ci = get_bit_or_zero(cell->getPort("\\c"));
SigBit bit_i0 = get_bit_or_zero(cell->getPort("\\a"));
SigBit bit_i1 = get_bit_or_zero(cell->getPort("\\b"));
SigBit canonical_bit = sigmap(bit_ci);
if (!ci_bits.count(canonical_bit))
continue;
if (bit_i0 == State::S0 && bit_i1== State::S0)
continue;
adders_to_fix_cells.push_back(cell);
log("Found %s cell named %s with invalid 'c' signal.\n", log_id(cell->type), log_id(cell));
}
}
for (auto cell : adders_to_fix_cells)
{
SigBit bit_ci = get_bit_or_zero(cell->getPort("\\c"));
SigBit canonical_bit = sigmap(bit_ci);
auto bit = mapping_bits.at(canonical_bit);
log("Fixing %s cell named %s breaking carry chain.\n", log_id(cell->type), log_id(cell));
Cell *c = module->addCell(NEW_ID, "\\AL_MAP_ADDER");
SigBit new_bit = module->addWire(NEW_ID);
SigBit dummy_bit = module->addWire(NEW_ID);
SigSpec bits;
bits.append(dummy_bit);
bits.append(new_bit);
c->setParam("\\ALUTYPE", Const("ADD_CARRY"));
c->setPort("\\a", bit);
c->setPort("\\b", State::S0);
c->setPort("\\c", State::S0);
c->setPort("\\o", bits);
cell->setPort("\\c", new_bit);
}
}
struct AnlogicCarryFixPass : public Pass {
AnlogicCarryFixPass() : Pass("anlogic_fixcarry", "Anlogic: fix carry chain") { }
void help() YS_OVERRIDE
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
log(" anlogic_fixcarry [options] [selection]\n");
log("\n");
log("Add Anlogic adders to fix carry chain if needed.\n");
log("\n");
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
log_header(design, "Executing anlogic_fixcarry pass (fix invalid carry chain).\n");
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++)
{
break;
}
extra_args(args, argidx, design);
Module *module = design->top_module();
if (module == nullptr)
log_cmd_error("No top module found.\n");
fix_carry_chain(module);
}
} AnlogicCarryFixPass;
PRIVATE_NAMESPACE_END

View file

@ -31,7 +31,10 @@ module _80_anlogic_alu (A, B, CI, BI, X, Y, CO);
output [Y_WIDTH-1:0] X, Y;
input CI, BI;
output CO;
output [Y_WIDTH-1:0] CO;
wire CIx;
wire [Y_WIDTH-1:0] COx;
wire _TECHMAP_FAIL_ = Y_WIDTH <= 2;
@ -41,15 +44,16 @@ module _80_anlogic_alu (A, B, CI, BI, X, Y, CO);
wire [Y_WIDTH-1:0] AA = A_buf;
wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf;
wire [Y_WIDTH+1:0] COx;
wire [Y_WIDTH+2:0] C = {COx, CI};
wire [Y_WIDTH-1:0] C = { COx, CIx };
wire dummy;
AL_MAP_ADDER #(
.ALUTYPE("ADD_CARRY"))
adder_cin (
.a(C[0]),
.o({COx[0], dummy})
.a(CI),
.b(1'b0),
.c(1'b0),
.o({CIx, dummy})
);
genvar i;
@ -59,18 +63,22 @@ module _80_anlogic_alu (A, B, CI, BI, X, Y, CO);
) adder_i (
.a(AA[i]),
.b(BB[i]),
.c(C[i+1]),
.o({COx[i+1],Y[i]})
.c(C[i]),
.o({COx[i],Y[i]})
);
end: slice
wire cout;
AL_MAP_ADDER #(
.ALUTYPE("ADD"))
adder_cout (
.a(1'b0),
.b(1'b0),
.c(COx[i]),
.o({cout, CO[i]})
);
end: slice
endgenerate
/* End implementation */
AL_MAP_ADDER #(
.ALUTYPE("ADD"))
adder_cout (
.c(C[Y_WIDTH+1]),
.o(COx[Y_WIDTH+1])
);
assign CO = COx[Y_WIDTH+1];
assign X = AA ^ BB;
endmodule
/* End implementation */
assign X = AA ^ BB;
endmodule

View file

@ -1,5 +1,5 @@
module AL_MAP_SEQ (
output q,
output reg q,
input ce,
input clk,
input sr,
@ -9,6 +9,71 @@ module AL_MAP_SEQ (
parameter REGSET = "RESET"; //RESET/SET
parameter SRMUX = "SR"; //SR/INV
parameter SRMODE = "SYNC"; //SYNC/ASYNC
wire clk_ce;
assign clk_ce = ce ? clk : 1'b0;
wire srmux;
generate
case (SRMUX)
"SR": assign srmux = sr;
"INV": assign srmux = ~sr;
default: assign srmux = sr;
endcase
endgenerate
wire regset;
generate
case (REGSET)
"RESET": assign regset = 1'b0;
"SET": assign regset = 1'b1;
default: assign regset = 1'b0;
endcase
endgenerate
initial q = regset;
generate
if (DFFMODE == "FF")
begin
if (SRMODE == "ASYNC")
begin
always @(posedge clk_ce, posedge srmux)
if (srmux)
q <= regset;
else
q <= d;
end
else
begin
always @(posedge clk_ce)
if (srmux)
q <= regset;
else
q <= d;
end
end
else
begin
// DFFMODE == "LATCH"
if (SRMODE == "ASYNC")
begin
always @(clk_ce, srmux)
if (srmux)
q <= regset;
else
q <= d;
end
else
begin
always @(clk_ce)
if (srmux)
q <= regset;
else
q <= d;
end
end
endgenerate
endmodule
module AL_MAP_LUT1 (
@ -17,7 +82,8 @@ module AL_MAP_LUT1 (
);
parameter [1:0] INIT = 2'h0;
parameter EQN = "(A)";
assign o = INIT >> a;
assign o = a ? INIT[1] : INIT[0];
endmodule
module AL_MAP_LUT2 (
@ -27,7 +93,9 @@ module AL_MAP_LUT2 (
);
parameter [3:0] INIT = 4'h0;
parameter EQN = "(A)";
assign o = INIT >> {b, a};
wire [1:0] s1 = b ? INIT[ 3:2] : INIT[1:0];
assign o = a ? s1[1] : s1[0];
endmodule
module AL_MAP_LUT3 (
@ -38,7 +106,10 @@ module AL_MAP_LUT3 (
);
parameter [7:0] INIT = 8'h0;
parameter EQN = "(A)";
assign o = INIT >> {c, b, a};
wire [3:0] s2 = c ? INIT[ 7:4] : INIT[3:0];
wire [1:0] s1 = b ? s2[ 3:2] : s2[1:0];
assign o = a ? s1[1] : s1[0];
endmodule
module AL_MAP_LUT4 (
@ -50,7 +121,11 @@ module AL_MAP_LUT4 (
);
parameter [15:0] INIT = 16'h0;
parameter EQN = "(A)";
assign o = INIT >> {d, c, b, a};
wire [7:0] s3 = d ? INIT[15:8] : INIT[7:0];
wire [3:0] s2 = c ? s3[ 7:4] : s3[3:0];
wire [1:0] s1 = b ? s2[ 3:2] : s2[1:0];
assign o = a ? s1[1] : s1[0];
endmodule
module AL_MAP_LUT5 (
@ -100,4 +175,18 @@ module AL_MAP_ADDER (
output [1:0] o
);
parameter ALUTYPE = "ADD";
generate
case (ALUTYPE)
"ADD": assign o = a + b + c;
"SUB": assign o = a - b - c;
"A_LE_B": assign o = a - b - c;
"ADD_CARRY": assign o = { a, 1'b0 };
"SUB_CARRY": assign o = { ~a, 1'b0 };
"A_LE_B_CARRY": assign o = { a, 1'b0 };
default: assign o = a + b + c;
endcase
endgenerate
endmodule

View file

@ -154,7 +154,7 @@ struct SynthAnlogicPass : public ScriptPass
{
run("memory_bram -rules +/anlogic/drams.txt");
run("techmap -map +/anlogic/drams_map.v");
run("anlogic_determine_init");
run("setundef -zero -params t:EG_LOGIC_DRAM16X4");
}
if (check_label("fine"))
@ -186,6 +186,11 @@ struct SynthAnlogicPass : public ScriptPass
{
run("techmap -map +/anlogic/cells_map.v");
run("clean");
}
if (check_label("map_anlogic"))
{
run("anlogic_fixcarry");
run("anlogic_eqn");
}

View file

@ -28,3 +28,4 @@ $(eval $(call add_share_file,share,techlibs/common/dff2ff.v))
$(eval $(call add_share_file,share,techlibs/common/gate2lut.v))
$(eval $(call add_share_file,share,techlibs/common/cmp2lut.v))
$(eval $(call add_share_file,share,techlibs/common/cells.lib))
$(eval $(call add_share_file,share,techlibs/common/dummy.box))

View file

@ -0,0 +1 @@
(dummy) 1 0 0 0

View file

@ -175,7 +175,7 @@ struct SynthPass : public ScriptPass
log_cmd_error("This command only operates on fully selected designs!\n");
if (abc == "abc9" && !lut)
log_cmd_error("ABC9 flow only supported for FPGA synthesis (using '-lut' option)");
log_cmd_error("ABC9 flow only supported for FPGA synthesis (using '-lut' option)\n");
log_header(design, "Executing SYNTH pass.\n");
log_push();

View file

@ -1,6 +1,9 @@
OBJS += techlibs/ecp5/synth_ecp5.o techlibs/ecp5/ecp5_ffinit.o
OBJS += techlibs/ecp5/synth_ecp5.o techlibs/ecp5/ecp5_ffinit.o \
techlibs/ecp5/ecp5_gsr.o
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/cells_ff.vh))
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/cells_io.vh))
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/cells_map.v))
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/cells_sim.v))
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/cells_bb.v))
@ -11,6 +14,9 @@ $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/bram.txt))
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/arith_map.v))
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/latches_map.v))
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/abc_map.v))
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/abc_unmap.v))
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/abc_model.v))
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/abc_5g.box))
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/abc_5g.lut))
$(eval $(call add_share_file,share/ecp5,techlibs/ecp5/abc_5g_nowide.lut))

View file

@ -15,16 +15,16 @@ CCU2C 1 1 9 3
630 379 630 379 526 275 392 141 273
516 516 516 516 412 412 278 278 43
# Box 2 : TRELLIS_DPR16X4 (16x4 dist ram)
# Box 2 : TRELLIS_DPR16X4_COMB (16x4 dist ram)
# Outputs: DO0, DO1, DO2, DO3
# name ID w/b ins outs
TRELLIS_DPR16X4 2 0 14 4
# name ID w/b ins outs
$__ABC_DPR16X4_COMB 2 0 8 4
#DI0 DI1 DI2 DI3 RAD0 RAD1 RAD2 RAD3 WAD0 WAD1 WAD2 WAD3 WCK WRE
- - - - 141 379 275 379 - - - - - -
- - - - 141 379 275 379 - - - - - -
- - - - 141 379 275 379 - - - - - -
- - - - 141 379 275 379 - - - - - -
#A0 A1 A2 A3 RAD0 RAD1 RAD2 RAD3
0 0 0 0 141 379 275 379
0 0 0 0 141 379 275 379
0 0 0 0 141 379 275 379
0 0 0 0 141 379 275 379
# Box 3 : PFUMX (MUX2)
# Outputs: Z

24
techlibs/ecp5/abc_map.v Normal file
View file

@ -0,0 +1,24 @@
// ---------------------------------------
module TRELLIS_DPR16X4 (
input [3:0] DI,
input [3:0] WAD,
input WRE,
input WCK,
input [3:0] RAD,
output [3:0] DO
);
parameter WCKMUX = "WCK";
parameter WREMUX = "WRE";
parameter [63:0] INITVAL = 64'h0000000000000000;
wire [3:0] \$DO ;
TRELLIS_DPR16X4 #(
.WCKMUX(WCKMUX), .WREMUX(WREMUX), .INITVAL(INITVAL)
) _TECHMAP_REPLACE_ (
.DI(DI), .WAD(WAD), .WRE(WRE), .WCK(WCK),
.RAD(RAD), .DO(\$DO )
);
\$__ABC_DPR16X4_COMB do (.A(\$DO ), .S(RAD), .Y(DO));
endmodule

View file

@ -0,0 +1,5 @@
// ---------------------------------------
(* abc_box_id=2 *)
module \$__ABC_DPR16X4_COMB (input [3:0] A, S, output [3:0] Y);
endmodule

View file

@ -0,0 +1,5 @@
// ---------------------------------------
module \$__ABC_DPR16X4_COMB (input [3:0] A, S, output [3:0] Y);
assign Y = A;
endmodule

View file

@ -33,7 +33,7 @@ module \$__ECP5_DP16KD (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
.CLKBMUX(CLKBMUX),
.WRITEMODE_A(WRITEMODE_A),
.WRITEMODE_B("READBEFOREWRITE"),
.GSR("DISABLED")
.GSR("AUTO")
) _TECHMAP_REPLACE_ (
`include "bram_conn_1.vh"
.CLKA(CLK2), .CLKB(CLK3),
@ -50,7 +50,7 @@ module \$__ECP5_DP16KD (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
.CLKBMUX(CLKBMUX),
.WRITEMODE_A(WRITEMODE_A),
.WRITEMODE_B("READBEFOREWRITE"),
.GSR("DISABLED")
.GSR("AUTO")
) _TECHMAP_REPLACE_ (
`include "bram_conn_2.vh"
.CLKA(CLK2), .CLKB(CLK3),
@ -67,7 +67,7 @@ module \$__ECP5_DP16KD (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
.CLKBMUX(CLKBMUX),
.WRITEMODE_A(WRITEMODE_A),
.WRITEMODE_B("READBEFOREWRITE"),
.GSR("DISABLED")
.GSR("AUTO")
) _TECHMAP_REPLACE_ (
`include "bram_conn_4.vh"
.CLKA(CLK2), .CLKB(CLK3),
@ -84,7 +84,7 @@ module \$__ECP5_DP16KD (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
.CLKBMUX(CLKBMUX),
.WRITEMODE_A(WRITEMODE_A),
.WRITEMODE_B("READBEFOREWRITE"),
.GSR("DISABLED")
.GSR("AUTO")
) _TECHMAP_REPLACE_ (
`include "bram_conn_9.vh"
.CLKA(CLK2), .CLKB(CLK3),
@ -101,7 +101,7 @@ module \$__ECP5_DP16KD (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
.CLKBMUX(CLKBMUX),
.WRITEMODE_A(WRITEMODE_A),
.WRITEMODE_B("READBEFOREWRITE"),
.GSR("DISABLED")
.GSR("AUTO")
) _TECHMAP_REPLACE_ (
`include "bram_conn_18.vh"
.CLKA(CLK2), .CLKB(CLK3),

View file

@ -664,3 +664,23 @@ module PCSCLKDIV (
);
parameter GSR = "DISABLED";
endmodule
// Note: this module is not marked keep as we want it swept away in synth (sim use only)
(* blackbox *)
module PUR (
input PUR
);
parameter RST_PULSE = 1;
endmodule
(* blackbox, keep *)
module GSR (
input GSR
);
endmodule
(* blackbox, keep *)
module SGSR (
input GSR, CLK
);
endmodule

40
techlibs/ecp5/cells_ff.vh Normal file
View file

@ -0,0 +1,40 @@
// Diamond flip-flops
module FD1P3AX(input D, SP, CK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(0), .CE(SP), .DI(D), .Q(Q)); endmodule
module FD1P3AY(input D, SP, CK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(0), .CE(SP), .DI(D), .Q(Q)); endmodule
module FD1P3BX(input PD, D, SP, CK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule
module FD1P3DX(input CD, D, SP, CK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule
module FD1P3IX(input CD, D, SP, CK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule
module FD1P3JX(input PD, D, SP, CK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule
module FD1S3AX(input D, CK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(0), .DI(D), .Q(Q)); endmodule
module FD1S3AY(input D, CK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(0), .DI(D), .Q(Q)); endmodule
module FD1S3BX(input PD, D, CK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(PD), .DI(D), .Q(Q)); endmodule
module FD1S3DX(input CD, D, CK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(CD), .DI(D), .Q(Q)); endmodule
module FD1S3IX(input CD, D, CK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(CD), .DI(D), .Q(Q)); endmodule
module FD1S3JX(input PD, D, CK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(PD), .DI(D), .Q(Q)); endmodule
// TODO: Diamond latches
// module FL1P3AY(); endmodule
// module FL1P3AZ(); endmodule
// module FL1P3BX(); endmodule
// module FL1P3DX(); endmodule
// module FL1P3IY(); endmodule
// module FL1P3JY(); endmodule
// module FL1S3AX(); endmodule
// module FL1S3AY(); endmodule
// Diamond I/O registers
module IFS1P3BX(input PD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule
module IFS1P3DX(input CD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule
module IFS1P3IX(input CD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule
module IFS1P3JX(input PD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule
module OFS1P3BX(input PD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule
module OFS1P3DX(input CD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule
module OFS1P3IX(input CD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule
module OFS1P3JX(input PD, D, SP, SCLK, output Q); parameter GSR = "ENABLED"; TRELLIS_FF #(.GSR(GSR), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule
// TODO: Diamond I/O latches
// module IFS1S1B(input PD, D, SCLK, output Q); endmodule
// module IFS1S1D(input CD, D, SCLK, output Q); endmodule
// module IFS1S1I(input PD, D, SCLK, output Q); endmodule
// module IFS1S1J(input CD, D, SCLK, output Q); endmodule

14
techlibs/ecp5/cells_io.vh Normal file
View file

@ -0,0 +1,14 @@
// Diamond I/O buffers
module IB (input I, output O); (* PULLMODE="NONE" *) TRELLIS_IO #(.DIR("INPUT")) _TECHMAP_REPLACE_ (.B(I), .O(O)); endmodule
module IBPU (input I, output O); (* PULLMODE="UP" *) TRELLIS_IO #(.DIR("INPUT")) _TECHMAP_REPLACE_ (.B(I), .O(O)); endmodule
module IBPD (input I, output O); (* PULLMODE="DOWN" *) TRELLIS_IO #(.DIR("INPUT")) _TECHMAP_REPLACE_ (.B(I), .O(O)); endmodule
module OB (input I, output O); (* PULLMODE="NONE" *) TRELLIS_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.B(O), .I(I)); endmodule
module OBZ (input I, T, output O); (* PULLMODE="NONE" *) TRELLIS_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.B(O), .I(I), .T(T)); endmodule
module OBZPU(input I, T, output O); (* PULLMODE="UP" *) TRELLIS_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.B(O), .I(I), .T(T)); endmodule
module OBZPD(input I, T, output O); (* PULLMODE="DOWN" *) TRELLIS_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.B(O), .I(I), .T(T)); endmodule
module OBCO (input I, output OT, OC); OLVDS olvds (.A(I), .Z(OT), .ZN(OC)); endmodule
module BB (input I, T, output O, inout B); (* PULLMODE="NONE" *) TRELLIS_IO #(.DIR("BIDIR")) _TECHMAP_REPLACE_ (.B(B), .I(I), .O(O), .T(T)); endmodule
module BBPU (input I, T, output O, inout B); (* PULLMODE="UP" *) TRELLIS_IO #(.DIR("BIDIR")) _TECHMAP_REPLACE_ (.B(B), .I(I), .O(O), .T(T)); endmodule
module BBPD (input I, T, output O, inout B); (* PULLMODE="DOWN" *) TRELLIS_IO #(.DIR("BIDIR")) _TECHMAP_REPLACE_ (.B(B), .I(I), .O(O), .T(T)); endmodule
module ILVDS(input A, AN, output Z ); TRELLIS_IO #(.DIR("INPUT")) _TECHMAP_REPLACE_ (.B(A), .O(Z)); endmodule
module OLVDS(input A, output Z, ZN); TRELLIS_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.B(Z), .I(A)); endmodule

View file

@ -1,105 +1,54 @@
module \$_DFF_N_ (input D, C, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); endmodule
module \$_DFF_P_ (input D, C, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); endmodule
module \$_DFF_N_ (input D, C, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); endmodule
module \$_DFF_P_ (input D, C, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(1'b0), .DI(D), .Q(Q)); endmodule
module \$_DFFE_NN_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule
module \$_DFFE_PN_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule
module \$_DFFE_NN_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule
module \$_DFFE_PN_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("INV"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule
module \$_DFFE_NP_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule
module \$_DFFE_PP_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule
module \$_DFFE_NP_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule
module \$_DFFE_PP_ (input D, C, E, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(1'b0), .DI(D), .Q(Q)); endmodule
module \$_DFF_NN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
module \$_DFF_NN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
module \$_DFF_PN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
module \$_DFF_PN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
module \$_DFF_NN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
module \$_DFF_NN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
module \$_DFF_PN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
module \$_DFF_PN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
module \$_DFF_NP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
module \$_DFF_NP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
module \$_DFF_PP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
module \$_DFF_PP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
module \$_DFF_NP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
module \$_DFF_NP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
module \$_DFF_PP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
module \$_DFF_PP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
module \$__DFFS_NN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
module \$__DFFS_NN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
module \$__DFFS_PN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
module \$__DFFS_PN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
module \$__DFFS_NN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
module \$__DFFS_NN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
module \$__DFFS_PN0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
module \$__DFFS_PN1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(!R), .DI(D), .Q(Q)); endmodule
module \$__DFFS_NP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
module \$__DFFS_NP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
module \$__DFFS_PP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
module \$__DFFS_PP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
module \$__DFFS_NP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
module \$__DFFS_NP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
module \$__DFFS_PP0_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
module \$__DFFS_PP1_ (input D, C, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .LSR(R), .DI(D), .Q(Q)); endmodule
module \$__DFFE_NN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule
module \$__DFFE_NN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule
module \$__DFFE_PN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule
module \$__DFFE_PN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule
module \$__DFFE_NN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule
module \$__DFFE_NN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule
module \$__DFFE_PN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule
module \$__DFFE_PN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule
module \$__DFFE_NP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
module \$__DFFE_NP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
module \$__DFFE_PP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
module \$__DFFE_PP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
module \$__DFFE_NP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
module \$__DFFE_NP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
module \$__DFFE_PP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
module \$__DFFE_PP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
module \$__DFFSE_NN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule
module \$__DFFSE_NN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule
module \$__DFFSE_PN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule
module \$__DFFSE_PN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule
module \$__DFFSE_NN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule
module \$__DFFSE_NN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule
module \$__DFFSE_PN0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule
module \$__DFFSE_PN1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(!R), .DI(D), .Q(Q)); endmodule
module \$__DFFSE_NP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
module \$__DFFSE_NP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
module \$__DFFSE_PP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
module \$__DFFSE_PP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
module \$__DFFSE_NP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
module \$__DFFSE_NP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("INV"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
module \$__DFFSE_PP0 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
module \$__DFFSE_PP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("AUTO"), .CEMUX("CE"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(C), .CE(E), .LSR(R), .DI(D), .Q(Q)); endmodule
// TODO: Diamond flip-flops
// module FD1P3AX(); endmodule
// module FD1P3AY(); endmodule
// module FD1P3BX(); endmodule
// module FD1P3DX(); endmodule
// module FD1P3IX(); endmodule
// module FD1P3JX(); endmodule
// module FD1S3AX(); endmodule
// module FD1S3AY(); endmodule
module FD1S3BX(input PD, D, CK, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(PD), .DI(D), .Q(Q)); endmodule
module FD1S3DX(input CD, D, CK, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(CD), .DI(D), .Q(Q)); endmodule
module FD1S3IX(input CD, D, CK, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(CD), .DI(D), .Q(Q)); endmodule
module FD1S3JX(input PD, D, CK, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(CK), .LSR(PD), .DI(D), .Q(Q)); endmodule
// module FL1P3AY(); endmodule
// module FL1P3AZ(); endmodule
// module FL1P3BX(); endmodule
// module FL1P3DX(); endmodule
// module FL1P3IY(); endmodule
// module FL1P3JY(); endmodule
// module FL1S3AX(); endmodule
// module FL1S3AY(); endmodule
// Diamond I/O buffers
module IB (input I, output O); (* PULLMODE="NONE" *) TRELLIS_IO #(.DIR("INPUT")) _TECHMAP_REPLACE_ (.B(I), .O(O)); endmodule
module IBPU (input I, output O); (* PULLMODE="UP" *) TRELLIS_IO #(.DIR("INPUT")) _TECHMAP_REPLACE_ (.B(I), .O(O)); endmodule
module IBPD (input I, output O); (* PULLMODE="DOWN" *) TRELLIS_IO #(.DIR("INPUT")) _TECHMAP_REPLACE_ (.B(I), .O(O)); endmodule
module OB (input I, output O); (* PULLMODE="NONE" *) TRELLIS_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.B(O), .I(I)); endmodule
module OBZ (input I, T, output O); (* PULLMODE="NONE" *) TRELLIS_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.B(O), .I(I), .T(T)); endmodule
module OBZPU(input I, T, output O); (* PULLMODE="UP" *) TRELLIS_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.B(O), .I(I), .T(T)); endmodule
module OBZPD(input I, T, output O); (* PULLMODE="DOWN" *) TRELLIS_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.B(O), .I(I), .T(T)); endmodule
module OBCO (input I, output OT, OC); OLVDS _TECHMAP_REPLACE_ (.A(I), .Z(OT), .ZN(OC)); endmodule
module BB (input I, T, output O, inout B); (* PULLMODE="NONE" *) TRELLIS_IO #(.DIR("BIDIR")) _TECHMAP_REPLACE_ (.B(B), .I(I), .O(O), .T(T)); endmodule
module BBPU (input I, T, output O, inout B); (* PULLMODE="UP" *) TRELLIS_IO #(.DIR("BIDIR")) _TECHMAP_REPLACE_ (.B(B), .I(I), .O(O), .T(T)); endmodule
module BBPD (input I, T, output O, inout B); (* PULLMODE="DOWN" *) TRELLIS_IO #(.DIR("BIDIR")) _TECHMAP_REPLACE_ (.B(B), .I(I), .O(O), .T(T)); endmodule
module ILVDS(input A, AN, output Z); TRELLIS_IO #(.DIR("INPUT")) _TECHMAP_REPLACE_ (.B(A), .O(Z)); endmodule
module OLVDS(input A, output Z, ZN); TRELLIS_IO #(.DIR("OUTPUT")) _TECHMAP_REPLACE_ (.B(Z), .I(A)); endmodule
// Diamond I/O registers
module IFS1P3BX(input PD, D, SP, SCLK, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule
module IFS1P3DX(input CD, D, SP, SCLK, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule
module IFS1P3IX(input CD, D, SP, SCLK, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule
module IFS1P3JX(input PD, D, SP, SCLK, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule
module OFS1P3BX(input PD, D, SP, SCLK, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule
module OFS1P3DX(input CD, D, SP, SCLK, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule
module OFS1P3IX(input CD, D, SP, SCLK, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule
module OFS1P3JX(input PD, D, SP, SCLK, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) _TECHMAP_REPLACE_ (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule
// TODO: Diamond I/O latches
// module IFS1S1B(input PD, D, SCLK, output Q); endmodule
// module IFS1S1D(input CD, D, SCLK, output Q); endmodule
// module IFS1S1I(input PD, D, SCLK, output Q); endmodule
// module IFS1S1J(input CD, D, SCLK, output Q); endmodule
`include "cells_ff.vh"
`include "cells_io.vh"
`ifndef NO_LUT
module \$lut (A, Y);

View file

@ -17,10 +17,12 @@ endmodule
// ---------------------------------------
(* abc_box_id=1, lib_whitebox *)
module CCU2C(
(* abc_carry *) input CIN,
(* abc_carry *)
input CIN,
input A0, B0, C0, D0, A1, B1, C1, D1,
output S0, S1,
(* abc_carry *) output COUT
(* abc_carry *)
output COUT
);
parameter [15:0] INIT0 = 16'h0000;
parameter [15:0] INIT1 = 16'h0000;
@ -107,13 +109,13 @@ module PFUMX (input ALUT, BLUT, C0, output Z);
endmodule
// ---------------------------------------
//(* abc_box_id=2 *)
module TRELLIS_DPR16X4 (
(* abc_scc_break *) input [3:0] DI,
(* abc_scc_break *) input [3:0] WAD,
(* abc_scc_break *) input WRE,
input [3:0] DI,
input [3:0] WAD,
input WRE,
input WCK,
input [3:0] RAD,
/* (* abc_arrival=<TODO> *) */
output [3:0] DO
);
parameter WCKMUX = "WCK";
@ -224,14 +226,15 @@ module TRELLIS_FF(input CLK, LSR, CE, DI, M, output reg Q);
parameter REGSET = "RESET";
parameter [127:0] LSRMODE = "LSR";
reg muxce;
always @(*)
wire muxce;
generate
case (CEMUX)
"1": muxce = 1'b1;
"0": muxce = 1'b0;
"INV": muxce = ~CE;
default: muxce = CE;
"1": assign muxce = 1'b1;
"0": assign muxce = 1'b0;
"INV": assign muxce = ~CE;
default: assign muxce = CE;
endcase
endgenerate
wire muxlsr = (LSRMUX == "INV") ? ~LSR : LSR;
wire muxclk = (CLKMUX == "INV") ? ~CLK : CLK;
@ -688,56 +691,9 @@ module DP16KD(
parameter INITVAL_3F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
endmodule
// TODO: Diamond flip-flops
// module FD1P3AX(); endmodule
// module FD1P3AY(); endmodule
// module FD1P3BX(); endmodule
// module FD1P3DX(); endmodule
// module FD1P3IX(); endmodule
// module FD1P3JX(); endmodule
// module FD1S3AX(); endmodule
// module FD1S3AY(); endmodule
module FD1S3BX(input PD, D, CK, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) tff (.CLK(CK), .LSR(PD), .DI(D), .Q(Q)); endmodule
module FD1S3DX(input CD, D, CK, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) tff (.CLK(CK), .LSR(CD), .DI(D), .Q(Q)); endmodule
module FD1S3IX(input CD, D, CK, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) tff (.CLK(CK), .LSR(CD), .DI(D), .Q(Q)); endmodule
module FD1S3JX(input PD, D, CK, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) tff (.CLK(CK), .LSR(PD), .DI(D), .Q(Q)); endmodule
// module FL1P3AY(); endmodule
// module FL1P3AZ(); endmodule
// module FL1P3BX(); endmodule
// module FL1P3DX(); endmodule
// module FL1P3IY(); endmodule
// module FL1P3JY(); endmodule
// module FL1S3AX(); endmodule
// module FL1S3AY(); endmodule
`ifndef NO_INCLUDES
// Diamond I/O buffers
module IB (input I, output O); (* PULLMODE="NONE" *) TRELLIS_IO #(.DIR("INPUT")) tio (.B(I), .O(O)); endmodule
module IBPU (input I, output O); (* PULLMODE="UP" *) TRELLIS_IO #(.DIR("INPUT")) tio (.B(I), .O(O)); endmodule
module IBPD (input I, output O); (* PULLMODE="DOWN" *) TRELLIS_IO #(.DIR("INPUT")) tio (.B(I), .O(O)); endmodule
module OB (input I, output O); (* PULLMODE="NONE" *) TRELLIS_IO #(.DIR("OUTPUT")) tio (.B(O), .I(I)); endmodule
module OBZ (input I, T, output O); (* PULLMODE="NONE" *) TRELLIS_IO #(.DIR("OUTPUT")) tio (.B(O), .I(I), .T(T)); endmodule
module OBZPU(input I, T, output O); (* PULLMODE="UP" *) TRELLIS_IO #(.DIR("OUTPUT")) tio (.B(O), .I(I), .T(T)); endmodule
module OBZPD(input I, T, output O); (* PULLMODE="DOWN" *) TRELLIS_IO #(.DIR("OUTPUT")) tio (.B(O), .I(I), .T(T)); endmodule
module OBCO (input I, output OT, OC); OLVDS olvds (.A(I), .Z(OT), .ZN(OC)); endmodule
module BB (input I, T, output O, inout B); (* PULLMODE="NONE" *) TRELLIS_IO #(.DIR("BIDIR")) tio (.B(B), .I(I), .O(O), .T(T)); endmodule
module BBPU (input I, T, output O, inout B); (* PULLMODE="UP" *) TRELLIS_IO #(.DIR("BIDIR")) tio (.B(B), .I(I), .O(O), .T(T)); endmodule
module BBPD (input I, T, output O, inout B); (* PULLMODE="DOWN" *) TRELLIS_IO #(.DIR("BIDIR")) tio (.B(B), .I(I), .O(O), .T(T)); endmodule
module ILVDS(input A, AN, output Z); TRELLIS_IO #(.DIR("INPUT")) tio (.B(A), .O(Z)); endmodule
module OLVDS(input A, output Z, ZN); TRELLIS_IO #(.DIR("OUTPUT")) tio (.B(Z), .I(A)); endmodule
`include "cells_ff.vh"
`include "cells_io.vh"
// Diamond I/O registers
module IFS1P3BX(input PD, D, SP, SCLK, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) tff (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule
module IFS1P3DX(input CD, D, SP, SCLK, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) tff (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule
module IFS1P3IX(input CD, D, SP, SCLK, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) tff (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule
module IFS1P3JX(input PD, D, SP, SCLK, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) tff (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule
module OFS1P3BX(input PD, D, SP, SCLK, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("ASYNC")) tff (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule
module OFS1P3DX(input CD, D, SP, SCLK, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("ASYNC")) tff (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule
module OFS1P3IX(input CD, D, SP, SCLK, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("RESET"), .SRMODE("LSR_OVER_CE")) tff (.CLK(SCLK), .LSR(CD), .CE(SP), .DI(D), .Q(Q)); endmodule
module OFS1P3JX(input PD, D, SP, SCLK, output Q); TRELLIS_FF #(.GSR("DISABLED"), .CEMUX("1"), .CLKMUX("CLK"), .LSRMUX("LSR"), .REGSET("SET"), .SRMODE("LSR_OVER_CE")) tff (.CLK(SCLK), .LSR(PD), .CE(SP), .DI(D), .Q(Q)); endmodule
// TODO: Diamond I/O latches
// module IFS1S1B(input PD, D, SCLK, output Q); endmodule
// module IFS1S1D(input CD, D, SCLK, output Q); endmodule
// module IFS1S1I(input PD, D, SCLK, output Q); endmodule
// module IFS1S1J(input CD, D, SCLK, output Q); endmodule
`endif

135
techlibs/ecp5/ecp5_gsr.cc Normal file
View file

@ -0,0 +1,135 @@
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
* Copyright (C) 2019 David Shah <david@symbioticeda.com>
*
* 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 Ecp5GsrPass : public Pass {
Ecp5GsrPass() : Pass("ecp5_gsr", "ECP5: handle GSR") { }
void help() YS_OVERRIDE
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
log(" ecp5_gsr [options] [selection]\n");
log("\n");
log("Trim active low async resets connected to GSR and resolve GSR parameter,\n");
log("if a GSR or SGSR primitive is used in the design.\n");
log("\n");
log("If any cell has the GSR parameter set to \"AUTO\", this will be resolved\n");
log("to \"ENABLED\" if a GSR primitive is present and the (* nogsr *) attribute\n");
log("is not set, otherwise it will be resolved to \"DISABLED\".\n");
log("\n");
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
log_header(design, "Executing ECP5_GSR pass (implement FF init values).\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);
for (auto module : design->selected_modules())
{
log("Handling GSR in %s.\n", log_id(module));
SigMap sigmap(module);
SigBit gsr;
bool found_gsr = false;
for (auto cell : module->selected_cells())
{
if (cell->type != ID(GSR) && cell->type != ID(SGSR))
continue;
if (found_gsr)
log_error("Found more than one GSR or SGSR cell in module %s.\n", log_id(module));
found_gsr = true;
SigSpec sig_gsr = cell->getPort(ID(GSR));
if (GetSize(sig_gsr) < 1)
log_error("GSR cell %s has disconnected GSR input.\n", log_id(cell));
gsr = sigmap(sig_gsr[0]);
}
// Resolve GSR parameter
for (auto cell : module->selected_cells())
{
if (!cell->hasParam(ID(GSR)) || cell->getParam(ID(GSR)).decode_string() != "AUTO")
continue;
bool gsren = found_gsr;
if (cell->get_bool_attribute("\\nogsr"))
gsren = false;
cell->setParam(ID(GSR), gsren ? Const("ENABLED") : Const("DISABLED"));
}
if (!found_gsr)
continue;
// For finding active low FF inputs
pool<SigBit> inverted_gsr;
log_debug("GSR net in module %s is %s.\n", log_id(module), log_signal(gsr));
for (auto cell : module->selected_cells())
{
if (cell->type != ID($_NOT_))
continue;
SigSpec sig_a = cell->getPort(ID(A)), sig_y = cell->getPort(ID(Y));
if (GetSize(sig_a) < 1 || GetSize(sig_y) < 1)
continue;
SigBit a = sigmap(sig_a[0]);
if (a == gsr)
inverted_gsr.insert(sigmap(sig_y[0]));
}
for (auto cell : module->selected_cells())
{
if (cell->type != ID(TRELLIS_FF))
continue;
if (!cell->hasParam(ID(GSR)) || cell->getParam(ID(GSR)).decode_string() != "ENABLED")
continue;
if (!cell->hasParam(ID(SRMODE)) || cell->getParam(ID(SRMODE)).decode_string() != "ASYNC")
continue;
SigSpec sig_lsr = cell->getPort(ID(LSR));
if (GetSize(sig_lsr) < 1)
continue;
SigBit lsr = sigmap(sig_lsr[0]);
if (!inverted_gsr.count(lsr))
continue;
cell->setParam(ID(SRMODE), Const("LSR_OVER_CE"));
cell->unsetPort(ID(LSR));
}
}
}
} Ecp5GsrPass;
PRIVATE_NAMESPACE_END

View file

@ -271,6 +271,8 @@ struct SynthEcp5Pass : public ScriptPass
run("opt_expr -undriven -mux_undef");
run("simplemap");
run("ecp5_ffinit");
run("ecp5_gsr");
run("opt_clean");
}
if (check_label("map_luts"))
@ -278,12 +280,17 @@ struct SynthEcp5Pass : public ScriptPass
if (abc2 || help_mode) {
run("abc", " (only if -abc2)");
}
run("techmap -map +/ecp5/latches_map.v");
std::string techmap_args = "-map +/ecp5/latches_map.v";
if (abc9)
techmap_args += " -map +/ecp5/abc_map.v -max_iter 1";
run("techmap " + techmap_args);
if (abc9) {
if (nowidelut)
run("abc9 -lut +/ecp5/abc_5g_nowide.lut -box +/ecp5/abc_5g.box -W 200");
else
run("abc9 -lut +/ecp5/abc_5g.lut -box +/ecp5/abc_5g.box -W 200");
run("techmap -map +/ecp5/abc_unmap.v");
} else {
if (nowidelut)
run("abc -lut 4 -dress");

1
techlibs/ecp5/tests/.gitignore vendored Normal file
View file

@ -0,0 +1 @@
work_*

View file

@ -0,0 +1,82 @@
import os
import subprocess
if not os.path.exists("work_ff"):
os.mkdir("work_ff")
modules = []
with open("../cells_ff.vh", "r") as f:
with open("work_ff/cells_ff_gate.v", "w") as g:
for line in f:
if not line.startswith("module"):
g.write(line)
continue
else:
spidx = line.find(" ")
bridx = line.find("(")
modname = line[spidx+1 : bridx]
g.write("module %s_gate" % modname)
g.write(line[bridx:])
inpidx = line.find("input ")
outpidx = line.find(", output")
modules.append((modname, [x.strip() for x in line[inpidx+6:outpidx].split(",")]))
with open("work_ff/testbench.v", "w") as f:
print("""
`timescale 1ns/ 1ps
module testbench;
reg pur = 0, clk, rst, cen, d;
// Needed for Diamond sim models
GSR GSR_INST (.GSR(1'b1));
PUR PUR_INST (.PUR(pur));
initial begin
$dumpfile("work_ff/ffs.vcd");
$dumpvars(0, testbench);
#5;
pur = 1;
#95;
repeat (2500) begin
{clk, rst, cen, d} = $random;
#10;
check_outputs;
#1;
end
$finish;
end
""", file=f)
for modname, inputs in modules:
print(" wire %s_gold_q, %s_gate_q;" % (modname, modname), file=f)
portconns = []
for inp in inputs:
if inp in ("SCLK", "CK"):
portconns.append(".%s(clk)" % inp)
elif inp in ("CD", "PD"):
portconns.append(".%s(rst)" % inp)
elif inp == "SP":
portconns.append(".%s(cen)" % inp)
elif inp == "D":
portconns.append(".%s(d)" % inp)
else:
assert False
portconns.append(".Q(%s_gold_q)" % modname)
print(" %s %s_gold_i (%s);" % (modname, modname, ", ".join(portconns)), file=f)
portconns[-1] = (".Q(%s_gate_q)" % modname)
print(" %s_gate %s_gate_i (%s);" % (modname, modname, ", ".join(portconns)), file=f)
print("", file=f)
print(" task check_outputs;", file=f)
print(" begin", file=f)
print(" if (%s_gold_q != %s_gate_q) $display(\"MISMATCH at %%1t: %s_gold_q=%%b, %s_gate_q=%%b\", $time, %s_gold_q, %s_gate_q);" %
(modname, modname, modname, modname, modname, modname), file=f)
print(" end", file=f)
print(" endtask", file=f)
print("endmodule", file=f)
diamond_models = "/usr/local/diamond/3.10_x64/cae_library/simulation/verilog/ecp5u"
subprocess.call(["iverilog", "-s", "testbench", "-o", "work_ff/testbench", "-Dmixed_hdl", "-DNO_INCLUDES", "-y", diamond_models, "work_ff/cells_ff_gate.v", "../cells_sim.v", "work_ff/testbench.v"])
subprocess.call(["vvp", "work_ff/testbench"])

View file

@ -0,0 +1,10 @@
OBJS += techlibs/efinix/synth_efinix.o
OBJS += techlibs/efinix/efinix_gbuf.o
OBJS += techlibs/efinix/efinix_fixcarry.o
$(eval $(call add_share_file,share/efinix,techlibs/efinix/cells_map.v))
$(eval $(call add_share_file,share/efinix,techlibs/efinix/arith_map.v))
$(eval $(call add_share_file,share/efinix,techlibs/efinix/cells_sim.v))
$(eval $(call add_share_file,share/efinix,techlibs/efinix/brams_map.v))
$(eval $(call add_share_file,share/efinix,techlibs/efinix/bram.txt))

View file

@ -0,0 +1,79 @@
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2018 Miodrag Milanovic <miodrag@symbioticeda.com>
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
*
* 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.
*
*/
(* techmap_celltype = "$alu" *)
module _80_efinix_alu (A, B, CI, BI, X, Y, CO);
parameter A_SIGNED = 0;
parameter B_SIGNED = 0;
parameter A_WIDTH = 1;
parameter B_WIDTH = 1;
parameter Y_WIDTH = 1;
input [A_WIDTH-1:0] A;
input [B_WIDTH-1:0] B;
output [Y_WIDTH-1:0] X, Y;
input CI, BI;
output [Y_WIDTH-1:0] CO;
wire CIx;
wire [Y_WIDTH-1:0] COx;
wire _TECHMAP_FAIL_ = Y_WIDTH <= 2;
wire [Y_WIDTH-1:0] A_buf, B_buf;
\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
wire [Y_WIDTH-1:0] AA = A_buf;
wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf;
wire [Y_WIDTH-1:0] C = { COx, CIx };
EFX_ADD #(.I0_POLARITY(1'b1),.I1_POLARITY(1'b1))
adder_cin (
.I0(CI),
.I1(1'b1),
.CI(1'b0),
.CO(CIx)
);
genvar i;
generate for (i = 0; i < Y_WIDTH; i = i + 1) begin: slice
EFX_ADD #(.I0_POLARITY(1'b1),.I1_POLARITY(1'b1))
adder_i (
.I0(AA[i]),
.I1(BB[i]),
.CI(C[i]),
.O(Y[i]),
.CO(COx[i])
);
EFX_ADD #(.I0_POLARITY(1'b1),.I1_POLARITY(1'b1))
adder_cout (
.I0(1'b0),
.I1(1'b0),
.CI(COx[i]),
.O(CO[i])
);
end: slice
endgenerate
/* End implementation */
assign X = AA ^ BB;
endmodule

32
techlibs/efinix/bram.txt Normal file
View file

@ -0,0 +1,32 @@
bram $__EFINIX_5K
init 1
abits 8 @a8d16
dbits 16 @a8d16
abits 9 @a9d8
dbits 8 @a9d8
abits 10 @a10d4
dbits 4 @a10d4
abits 11 @a11d2
dbits 2 @a11d2
abits 12 @a12d1
dbits 1 @a12d1
abits 8 @a8d20
dbits 20 @a8d20
abits 9 @a9d10
dbits 10 @a9d10
groups 2
ports 1 1
wrmode 1 0
enable 1 1
transp 0 2
clocks 2 3
clkpol 2 3
endbram
match $__EFINIX_5K
min bits 256
min efficiency 5
shuffle_enable B
endmatch

View file

@ -0,0 +1,65 @@
module \$__EFINIX_5K (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
parameter CFG_ABITS = 8;
parameter CFG_DBITS = 20;
parameter CFG_ENABLE_A = 1;
parameter CLKPOL2 = 1;
parameter CLKPOL3 = 1;
parameter [5119:0] INIT = 5119'bx;
parameter TRANSP2 = 0;
input CLK2;
input CLK3;
input [CFG_ABITS-1:0] A1ADDR;
input [CFG_DBITS-1:0] A1DATA;
input [CFG_ENABLE_A-1:0] A1EN;
input [CFG_ABITS-1:0] B1ADDR;
output [CFG_DBITS-1:0] B1DATA;
input B1EN;
localparam WRITEMODE_A = TRANSP2 ? "WRITE_FIRST" : "READ_FIRST";
EFX_RAM_5K #(
.READ_WIDTH(CFG_DBITS),
.WRITE_WIDTH(CFG_DBITS),
.OUTPUT_REG(1'b0),
.RCLK_POLARITY(1'b1),
.RE_POLARITY(1'b1),
.WCLK_POLARITY(1'b1),
.WE_POLARITY(1'b1),
.WCLKE_POLARITY(1'b1),
.WRITE_MODE(WRITEMODE_A),
.INIT_0(INIT[ 0*256 +: 256]),
.INIT_1(INIT[ 1*256 +: 256]),
.INIT_2(INIT[ 2*256 +: 256]),
.INIT_3(INIT[ 3*256 +: 256]),
.INIT_4(INIT[ 4*256 +: 256]),
.INIT_5(INIT[ 5*256 +: 256]),
.INIT_6(INIT[ 6*256 +: 256]),
.INIT_7(INIT[ 7*256 +: 256]),
.INIT_8(INIT[ 8*256 +: 256]),
.INIT_9(INIT[ 9*256 +: 256]),
.INIT_A(INIT[10*256 +: 256]),
.INIT_B(INIT[11*256 +: 256]),
.INIT_C(INIT[12*256 +: 256]),
.INIT_D(INIT[13*256 +: 256]),
.INIT_E(INIT[14*256 +: 256]),
.INIT_F(INIT[15*256 +: 256]),
.INIT_10(INIT[16*256 +: 256]),
.INIT_11(INIT[17*256 +: 256]),
.INIT_12(INIT[18*256 +: 256]),
.INIT_13(INIT[19*256 +: 256])
) _TECHMAP_REPLACE_ (
.WDATA(A1DATA),
.WADDR(A1ADDR),
.WE(A1EN),
.WCLK(CLK2),
.WCLKE(1'b1),
.RDATA(B1DATA),
.RADDR(B1ADDR),
.RE(B1EN),
.RCLK(CLK3)
);
endmodule

View file

@ -0,0 +1,45 @@
module \$_DFF_N_ (input D, C, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(1'b0), .Q(Q)); endmodule
module \$_DFF_P_ (input D, C, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(1'b0), .Q(Q)); endmodule
module \$_DFFE_NN_ (input D, C, E, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b0), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(E), .CLK(C), .SR(1'b0), .Q(Q)); endmodule
module \$_DFFE_NP_ (input D, C, E, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(E), .CLK(C), .SR(1'b0), .Q(Q)); endmodule
module \$_DFFE_PN_ (input D, C, E, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b0), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(E), .CLK(C), .SR(1'b0), .Q(Q)); endmodule
module \$_DFFE_PP_ (input D, C, E, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b1), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(E), .CLK(C), .SR(1'b0), .Q(Q)); endmodule
module \$_DFF_NN0_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b0), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule
module \$_DFF_NN1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b0), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b1), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule
module \$_DFF_PN0_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b0), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule
module \$_DFF_PN1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b0), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b1), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule
module \$_DFF_NP0_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule
module \$_DFF_NP1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b0), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b1), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule
module \$_DFF_PP0_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b0), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule
module \$_DFF_PP1_ (input D, C, R, output Q); EFX_FF #(.CLK_POLARITY(1'b1), .CE_POLARITY(1'b1), .SR_POLARITY(1'b1), .D_POLARITY(1'b1), .SR_SYNC(1'b0), .SR_VALUE(1'b1), .SR_SYNC_PRIORITY(1'b1)) _TECHMAP_REPLACE_ (.D(D), .CE(1'b1), .CLK(C), .SR(R), .Q(Q)); endmodule
`ifndef NO_LUT
module \$lut (A, Y);
parameter WIDTH = 0;
parameter LUT = 0;
input [WIDTH-1:0] A;
output Y;
generate
if (WIDTH == 1) begin
EFX_LUT4 #(.LUTMASK(LUT)) _TECHMAP_REPLACE_ (.O(Y), .I0(A[0]), .I1(1'b0), .I2(1'b0), .I3(1'b0));
end else
if (WIDTH == 2) begin
EFX_LUT4 #(.LUTMASK(LUT)) _TECHMAP_REPLACE_ (.O(Y), .I0(A[0]), .I1(A[1]), .I2(1'b0), .I3(1'b0));
end else
if (WIDTH == 3) begin
EFX_LUT4 #(.LUTMASK(LUT)) _TECHMAP_REPLACE_ (.O(Y), .I0(A[0]), .I1(A[1]), .I2(A[2]), .I3(1'b0));
end else
if (WIDTH == 4) begin
EFX_LUT4 #(.LUTMASK(LUT)) _TECHMAP_REPLACE_ (.O(Y), .I0(A[0]), .I1(A[1]), .I2(A[2]), .I3(A[3]));
end else begin
wire _TECHMAP_FAIL_ = 1;
end
endgenerate
endmodule
`endif

173
techlibs/efinix/cells_sim.v Normal file
View file

@ -0,0 +1,173 @@
module EFX_LUT4(
output O,
input I0,
input I1,
input I2,
input I3
);
parameter LUTMASK = 16'h0000;
wire [7:0] s3 = I3 ? LUTMASK[15:8] : LUTMASK[7:0];
wire [3:0] s2 = I2 ? s3[ 7:4] : s3[3:0];
wire [1:0] s1 = I1 ? s2[ 3:2] : s2[1:0];
assign O = I0 ? s1[1] : s1[0];
endmodule
module EFX_ADD(
output O,
output CO,
input I0,
input I1,
input CI
);
parameter I0_POLARITY = 1;
parameter I1_POLARITY = 1;
wire i0;
wire i1;
assign i0 = I0_POLARITY ? I0 : ~I0;
assign i1 = I1_POLARITY ? I1 : ~I1;
assign {CO, O} = i0 + i1 + CI;
endmodule
module EFX_FF(
output reg Q,
input D,
input CE,
input CLK,
input SR
);
parameter CLK_POLARITY = 1;
parameter CE_POLARITY = 1;
parameter SR_POLARITY = 1;
parameter SR_SYNC = 0;
parameter SR_VALUE = 0;
parameter SR_SYNC_PRIORITY = 0;
parameter D_POLARITY = 1;
wire clk;
wire ce;
wire sr;
wire d;
wire prio;
wire sync;
wire async;
assign clk = CLK_POLARITY ? CLK : ~CLK;
assign ce = CE_POLARITY ? CE : ~CE;
assign sr = SR_POLARITY ? SR : ~SR;
assign d = D_POLARITY ? D : ~D;
generate
if (SR_SYNC == 1)
begin
if (SR_SYNC_PRIORITY == 1)
begin
always @(posedge clk)
if (sr)
Q <= SR_VALUE;
else if (ce)
Q <= d;
end
else
begin
always @(posedge clk)
if (ce)
begin
if (sr)
Q <= SR_VALUE;
else
Q <= d;
end
end
end
else
begin
always @(posedge clk or posedge sr)
if (sr)
Q <= SR_VALUE;
else if (ce)
Q <= d;
end
endgenerate
endmodule
module EFX_GBUFCE(
input CE,
input I,
output O
);
parameter CE_POLARITY = 1'b1;
wire ce;
assign ce = CE_POLARITY ? CE : ~CE;
assign O = I & ce;
endmodule
module EFX_RAM_5K(
input [WRITE_WIDTH-1:0] WDATA,
input [WRITE_ADDR_WIDTH-1:0] WADDR,
input WE,
input WCLK,
input WCLKE,
output [READ_WIDTH-1:0] RDATA,
input [READ_ADDR_WIDTH-1:0] RADDR,
input RE,
input RCLK
);
parameter READ_WIDTH = 20;
parameter WRITE_WIDTH = 20;
parameter OUTPUT_REG = 1'b0;
parameter RCLK_POLARITY = 1'b1;
parameter RE_POLARITY = 1'b1;
parameter WCLK_POLARITY = 1'b1;
parameter WE_POLARITY = 1'b1;
parameter WCLKE_POLARITY = 1'b1;
parameter WRITE_MODE = "READ_FIRST";
parameter INIT_0 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_1 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_2 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_3 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_4 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_5 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_6 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_7 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_8 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_9 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_10 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_11 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_12 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INIT_13 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
localparam READ_ADDR_WIDTH =
(READ_WIDTH == 16) ? 8 : // 256x16
(READ_WIDTH == 8) ? 9 : // 512x8
(READ_WIDTH == 4) ? 10 : // 1024x4
(READ_WIDTH == 2) ? 11 : // 2048x2
(READ_WIDTH == 1) ? 12 : // 4096x1
(READ_WIDTH == 20) ? 8 : // 256x20
(READ_WIDTH == 10) ? 9 : // 512x10
(READ_WIDTH == 5) ? 10 : -1; // 1024x5
localparam WRITE_ADDR_WIDTH =
(WRITE_WIDTH == 16) ? 8 : // 256x16
(WRITE_WIDTH == 8) ? 9 : // 512x8
(WRITE_WIDTH == 4) ? 10 : // 1024x4
(WRITE_WIDTH == 2) ? 11 : // 2048x2
(WRITE_WIDTH == 1) ? 12 : // 4096x1
(WRITE_WIDTH == 20) ? 8 : // 256x20
(WRITE_WIDTH == 10) ? 9 : // 512x10
(WRITE_WIDTH == 5) ? 10 : -1; // 1024x5
endmodule

View file

@ -0,0 +1,122 @@
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2019 Miodrag Milanovic <miodrag@symbioticeda.com>
*
* 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
static SigBit get_bit_or_zero(const SigSpec &sig)
{
if (GetSize(sig) == 0)
return State::S0;
return sig[0];
}
static void fix_carry_chain(Module *module)
{
SigMap sigmap(module);
pool<SigBit> ci_bits;
dict<SigBit, SigBit> mapping_bits;
for (auto cell : module->cells())
{
if (cell->type == "\\EFX_ADD") {
SigBit bit_i0 = get_bit_or_zero(cell->getPort("\\I0"));
SigBit bit_i1 = get_bit_or_zero(cell->getPort("\\I1"));
if (bit_i0 == State::S0 && bit_i1== State::S0) {
SigBit bit_ci = get_bit_or_zero(cell->getPort("\\CI"));
SigBit bit_o = sigmap(cell->getPort("\\O"));
ci_bits.insert(bit_ci);
mapping_bits[bit_ci] = bit_o;
}
}
}
vector<Cell*> adders_to_fix_cells;
for (auto cell : module->cells())
{
if (cell->type == "\\EFX_ADD") {
SigBit bit_ci = get_bit_or_zero(cell->getPort("\\CI"));
SigBit bit_i0 = get_bit_or_zero(cell->getPort("\\I0"));
SigBit bit_i1 = get_bit_or_zero(cell->getPort("\\I1"));
SigBit canonical_bit = sigmap(bit_ci);
if (!ci_bits.count(canonical_bit))
continue;
if (bit_i0 == State::S0 && bit_i1== State::S0)
continue;
adders_to_fix_cells.push_back(cell);
log("Found %s cell named %s with invalid CI signal.\n", log_id(cell->type), log_id(cell));
}
}
for (auto cell : adders_to_fix_cells)
{
SigBit bit_ci = get_bit_or_zero(cell->getPort("\\CI"));
SigBit canonical_bit = sigmap(bit_ci);
auto bit = mapping_bits.at(canonical_bit);
log("Fixing %s cell named %s breaking carry chain.\n", log_id(cell->type), log_id(cell));
Cell *c = module->addCell(NEW_ID, "\\EFX_ADD");
SigBit new_bit = module->addWire(NEW_ID);
c->setParam("\\I0_POLARITY", State::S1);
c->setParam("\\I1_POLARITY", State::S1);
c->setPort("\\I0", bit);
c->setPort("\\I1", State::S1);
c->setPort("\\CI", State::S0);
c->setPort("\\CO", new_bit);
cell->setPort("\\CI", new_bit);
}
}
struct EfinixCarryFixPass : public Pass {
EfinixCarryFixPass() : Pass("efinix_fixcarry", "Efinix: fix carry chain") { }
void help() YS_OVERRIDE
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
log(" efinix_fixcarry [options] [selection]\n");
log("\n");
log("Add Efinix adders to fix carry chain if needed.\n");
log("\n");
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
log_header(design, "Executing efinix_fixcarry pass (fix invalid carry chain).\n");
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++)
{
break;
}
extra_args(args, argidx, design);
Module *module = design->top_module();
if (module == nullptr)
log_cmd_error("No top module found.\n");
fix_carry_chain(module);
}
} EfinixCarryFixPass;
PRIVATE_NAMESPACE_END

View file

@ -0,0 +1,119 @@
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2019 Miodrag Milanovic <miodrag@symbioticeda.com>
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
*
* 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
static void handle_gbufs(Module *module)
{
SigMap sigmap(module);
pool<SigBit> clk_bits;
dict<SigBit, SigBit> rewrite_bits;
vector<pair<Cell*, SigBit>> pad_bits;
for (auto cell : module->cells())
{
if (cell->type == "\\EFX_FF") {
for (auto bit : sigmap(cell->getPort("\\CLK")))
clk_bits.insert(bit);
}
if (cell->type == "\\EFX_RAM_5K") {
for (auto bit : sigmap(cell->getPort("\\RCLK")))
clk_bits.insert(bit);
for (auto bit : sigmap(cell->getPort("\\WCLK")))
clk_bits.insert(bit);
}
}
for (auto wire : vector<Wire*>(module->wires()))
{
if (!wire->port_input)
continue;
for (int index = 0; index < GetSize(wire); index++)
{
SigBit bit(wire, index);
SigBit canonical_bit = sigmap(bit);
if (!clk_bits.count(canonical_bit))
continue;
Cell *c = module->addCell(NEW_ID, "\\EFX_GBUFCE");
SigBit new_bit = module->addWire(NEW_ID);
c->setParam("\\CE_POLARITY", State::S1);
c->setPort("\\O", new_bit);
c->setPort("\\CE", State::S1);
pad_bits.push_back(make_pair(c, bit));
rewrite_bits[canonical_bit] = new_bit;
log("Added %s cell %s for port bit %s.\n", log_id(c->type), log_id(c), log_signal(bit));
}
}
auto rewrite_function = [&](SigSpec &s) {
for (auto &bit : s) {
SigBit canonical_bit = sigmap(bit);
if (rewrite_bits.count(canonical_bit))
bit = rewrite_bits.at(canonical_bit);
}
};
module->rewrite_sigspecs(rewrite_function);
for (auto &it : pad_bits)
it.first->setPort("\\I", it.second);
}
struct EfinixGbufPass : public Pass {
EfinixGbufPass() : Pass("efinix_gbuf", "Efinix: insert global clock buffers") { }
void help() YS_OVERRIDE
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
log(" efinix_gbuf [options] [selection]\n");
log("\n");
log("Add Efinix global clock buffers to top module as needed.\n");
log("\n");
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
{
log_header(design, "Executing efinix_gbuf pass (insert global clock buffers).\n");
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++)
{
break;
}
extra_args(args, argidx, design);
Module *module = design->top_module();
if (module == nullptr)
log_cmd_error("No top module found.\n");
handle_gbufs(module);
}
} EfinixGbufPass;
PRIVATE_NAMESPACE_END

View file

@ -0,0 +1,219 @@
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2019 Miodrag Milanovic <miodrag@symbioticeda.com>
* Copyright (C) 2019 Clifford Wolf <clifford@clifford.at>
*
* 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 SynthEfinixPass : public ScriptPass
{
SynthEfinixPass() : ScriptPass("synth_efinix", "synthesis for Efinix FPGAs") { }
void help() YS_OVERRIDE
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
log(" synth_efinix [options]\n");
log("\n");
log("This command runs synthesis for Efinix FPGAs.\n");
log("\n");
log(" -top <module>\n");
log(" use the specified module as top module\n");
log("\n");
log(" -edif <file>\n");
log(" write the design to the specified EDIF file. writing of an output file\n");
log(" is omitted if this parameter is not specified.\n");
log("\n");
log(" -json <file>\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 <from_label>:<to_label>\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 option\n");
log("\n");
log("\n");
log("The following commands are executed by this synthesis command:\n");
help_script();
log("\n");
}
string top_opt, edif_file, json_file;
bool flatten, retime;
void clear_flags() YS_OVERRIDE
{
top_opt = "-auto-top";
edif_file = "";
json_file = "";
flatten = true;
retime = false;
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_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] == "-edif" && argidx+1 < args.size()) {
edif_file = 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_EFINIX pass.\n");
log_push();
run_script(design, run_from, run_to);
log_pop();
}
void script() YS_OVERRIDE
{
if (check_label("begin"))
{
run("read_verilog -lib +/efinix/cells_sim.v");
run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
}
if (flatten && check_label("flatten", "(unless -noflatten)"))
{
run("proc");
run("flatten");
run("tribuf -logic");
run("deminout");
}
if (check_label("coarse"))
{
run("synth -run coarse");
}
if (check_label("map_bram", "(skip if -nobram)"))
{
run("memory_bram -rules +/efinix/bram.txt");
run("techmap -map +/efinix/brams_map.v");
run("setundef -zero -params t:EFX_RAM_5K");
}
if (check_label("fine"))
{
run("opt -fast -mux_undef -undriven -fine");
run("memory_map");
run("opt -undriven -fine");
run("techmap -map +/techmap.v -map +/efinix/arith_map.v");
if (retime || help_mode)
run("abc -dff", "(only if -retime)");
}
if (check_label("map_ffs"))
{
run("dffsr2dff");
run("techmap -D NO_LUT -map +/efinix/cells_map.v");
run("dffinit -strinit SET RESET -ff AL_MAP_SEQ q REGSET -noreinit");
run("opt_expr -mux_undef");
run("simplemap");
}
if (check_label("map_luts"))
{
run("abc -lut 4");
run("clean");
}
if (check_label("map_cells"))
{
run("techmap -map +/efinix/cells_map.v");
run("clean");
}
if (check_label("map_gbuf"))
{
run("efinix_gbuf");
run("efinix_fixcarry");
run("clean");
}
if (check_label("check"))
{
run("hierarchy -check");
run("stat");
run("check -noinit");
}
if (check_label("edif"))
{
if (!edif_file.empty() || help_mode)
run(stringf("write_edif %s", help_mode ? "<file-name>" : edif_file.c_str()));
}
if (check_label("json"))
{
if (!json_file.empty() || help_mode)
run(stringf("write_json %s", help_mode ? "<file-name>" : json_file.c_str()));
}
}
} SynthEfinixPass;
PRIVATE_NAMESPACE_END

View file

@ -3,11 +3,11 @@
# NB: Inputs/Outputs must be ordered alphabetically
# (with exceptions for carry in/out)
# Inputs: A B CI
# Inputs: A B I0 I3 CI
# Outputs: O CO
# (NB: carry chain input/output must be last
# input/output and have been moved there
# overriding the alphabetical ordering)
$__ICE40_FULL_ADDER 1 1 3 2
400 379 316
259 231 126
$__ICE40_CARRY_WRAPPER 1 1 5 2
400 379 449 316 316
259 231 - - 126

View file

@ -3,11 +3,11 @@
# NB: Inputs/Outputs must be ordered alphabetically
# (with exceptions for carry in/out)
# Inputs: A B CI
# Inputs: A B I0 I3 CI
# Outputs: O CO
# (NB: carry chain input/output must be last
# input/output and have been moved there
# overriding the alphabetical ordering)
$__ICE40_FULL_ADDER 1 1 3 2
589 558 465
675 609 186
$__ICE40_CARRY_WRAPPER 1 1 5 2
589 558 661 465 465
675 609 - - 186

View file

@ -3,11 +3,11 @@
# NB: Inputs/Outputs must be ordered alphabetically
# (with exceptions for carry in/out)
# Inputs: A B CI
# Inputs: A B I0 I3 CI
# Outputs: O CO
# (NB: carry chain input/output must be last
# input/output and have been moved there
# overriding the alphabetical ordering)
$__ICE40_FULL_ADDER 1 1 3 2
1231 1205 874
675 609 278
$__ICE40_CARRY_WRAPPER 1 1 5 2
1231 1205 1285 874 874
675 609 - - 278

View file

@ -2,6 +2,10 @@
`define SB_DFF_REG reg Q = 0
// `define SB_DFF_REG reg Q
`define ABC_ARRIVAL_HX(TIME) `ifdef ICE40_HX (* abc_arrival=TIME *) `endif
`define ABC_ARRIVAL_LP(TIME) `ifdef ICE40_LP (* abc_arrival=TIME *) `endif
`define ABC_ARRIVAL_U(TIME) `ifdef ICE40_U (* abc_arrival=TIME *) `endif
// SiliconBlue IO Cells
module SB_IO (
@ -142,13 +146,16 @@ module SB_CARRY (output CO, input I0, I1, CI);
endmodule
(* abc_box_id = 1, lib_whitebox *)
module \$__ICE40_FULL_ADDER (
(* abc_carry *) output CO,
module \$__ICE40_CARRY_WRAPPER (
(* abc_carry *)
output CO,
output O,
input A,
input B,
(* abc_carry *) input CI
input A, B,
(* abc_carry *)
input CI,
input I0, I3
);
parameter LUT = 0;
SB_CARRY carry (
.I0(A),
.I1(B),
@ -156,34 +163,52 @@ module \$__ICE40_FULL_ADDER (
.CO(CO)
);
SB_LUT4 #(
// I0: 1010 1010 1010 1010
// I1: 1100 1100 1100 1100
// I2: 1111 0000 1111 0000
// I3: 1111 1111 0000 0000
.LUT_INIT(16'b 0110_1001_1001_0110)
.LUT_INIT(LUT)
) adder (
.I0(1'b0),
.I0(I0),
.I1(A),
.I2(B),
.I3(CI),
.I3(I3),
.O(O)
);
endmodule
// Max delay from: https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L90
// https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L90
// https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L102
// Positive Edge SiliconBlue FF Cells
module SB_DFF (output `SB_DFF_REG, input C, D);
module SB_DFF (
`ABC_ARRIVAL_HX(540)
`ABC_ARRIVAL_LP(796)
`ABC_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, D
);
always @(posedge C)
Q <= D;
endmodule
module SB_DFFE (output `SB_DFF_REG, input C, E, D);
module SB_DFFE (
`ABC_ARRIVAL_HX(540)
`ABC_ARRIVAL_LP(796)
`ABC_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, E, D
);
always @(posedge C)
if (E)
Q <= D;
endmodule
module SB_DFFSR (output `SB_DFF_REG, input C, R, D);
module SB_DFFSR (
`ABC_ARRIVAL_HX(540)
`ABC_ARRIVAL_LP(796)
`ABC_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, R, D
);
always @(posedge C)
if (R)
Q <= 0;
@ -191,7 +216,13 @@ module SB_DFFSR (output `SB_DFF_REG, input C, R, D);
Q <= D;
endmodule
module SB_DFFR (output `SB_DFF_REG, input C, R, D);
module SB_DFFR (
`ABC_ARRIVAL_HX(540)
`ABC_ARRIVAL_LP(796)
`ABC_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, R, D
);
always @(posedge C, posedge R)
if (R)
Q <= 0;
@ -199,7 +230,13 @@ module SB_DFFR (output `SB_DFF_REG, input C, R, D);
Q <= D;
endmodule
module SB_DFFSS (output `SB_DFF_REG, input C, S, D);
module SB_DFFSS (
`ABC_ARRIVAL_HX(540)
`ABC_ARRIVAL_LP(796)
`ABC_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, S, D
);
always @(posedge C)
if (S)
Q <= 1;
@ -207,7 +244,13 @@ module SB_DFFSS (output `SB_DFF_REG, input C, S, D);
Q <= D;
endmodule
module SB_DFFS (output `SB_DFF_REG, input C, S, D);
module SB_DFFS (
`ABC_ARRIVAL_HX(540)
`ABC_ARRIVAL_LP(796)
`ABC_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, S, D
);
always @(posedge C, posedge S)
if (S)
Q <= 1;
@ -215,7 +258,13 @@ module SB_DFFS (output `SB_DFF_REG, input C, S, D);
Q <= D;
endmodule
module SB_DFFESR (output `SB_DFF_REG, input C, E, R, D);
module SB_DFFESR (
`ABC_ARRIVAL_HX(540)
`ABC_ARRIVAL_LP(796)
`ABC_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, E, R, D
);
always @(posedge C)
if (E) begin
if (R)
@ -225,7 +274,13 @@ module SB_DFFESR (output `SB_DFF_REG, input C, E, R, D);
end
endmodule
module SB_DFFER (output `SB_DFF_REG, input C, E, R, D);
module SB_DFFER (
`ABC_ARRIVAL_HX(540)
`ABC_ARRIVAL_LP(796)
`ABC_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, E, R, D
);
always @(posedge C, posedge R)
if (R)
Q <= 0;
@ -233,7 +288,13 @@ module SB_DFFER (output `SB_DFF_REG, input C, E, R, D);
Q <= D;
endmodule
module SB_DFFESS (output `SB_DFF_REG, input C, E, S, D);
module SB_DFFESS (
`ABC_ARRIVAL_HX(540)
`ABC_ARRIVAL_LP(796)
`ABC_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, E, S, D
);
always @(posedge C)
if (E) begin
if (S)
@ -243,7 +304,13 @@ module SB_DFFESS (output `SB_DFF_REG, input C, E, S, D);
end
endmodule
module SB_DFFES (output `SB_DFF_REG, input C, E, S, D);
module SB_DFFES (
`ABC_ARRIVAL_HX(540)
`ABC_ARRIVAL_LP(796)
`ABC_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, E, S, D
);
always @(posedge C, posedge S)
if (S)
Q <= 1;
@ -253,18 +320,36 @@ endmodule
// Negative Edge SiliconBlue FF Cells
module SB_DFFN (output `SB_DFF_REG, input C, D);
module SB_DFFN (
`ABC_ARRIVAL_HX(540)
`ABC_ARRIVAL_LP(796)
`ABC_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, D
);
always @(negedge C)
Q <= D;
endmodule
module SB_DFFNE (output `SB_DFF_REG, input C, E, D);
module SB_DFFNE (
`ABC_ARRIVAL_HX(540)
`ABC_ARRIVAL_LP(796)
`ABC_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, E, D
);
always @(negedge C)
if (E)
Q <= D;
endmodule
module SB_DFFNSR (output `SB_DFF_REG, input C, R, D);
module SB_DFFNSR (
`ABC_ARRIVAL_HX(540)
`ABC_ARRIVAL_LP(796)
`ABC_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, R, D
);
always @(negedge C)
if (R)
Q <= 0;
@ -272,7 +357,13 @@ module SB_DFFNSR (output `SB_DFF_REG, input C, R, D);
Q <= D;
endmodule
module SB_DFFNR (output `SB_DFF_REG, input C, R, D);
module SB_DFFNR (
`ABC_ARRIVAL_HX(540)
`ABC_ARRIVAL_LP(796)
`ABC_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, R, D
);
always @(negedge C, posedge R)
if (R)
Q <= 0;
@ -280,7 +371,13 @@ module SB_DFFNR (output `SB_DFF_REG, input C, R, D);
Q <= D;
endmodule
module SB_DFFNSS (output `SB_DFF_REG, input C, S, D);
module SB_DFFNSS (
`ABC_ARRIVAL_HX(540)
`ABC_ARRIVAL_LP(796)
`ABC_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, S, D
);
always @(negedge C)
if (S)
Q <= 1;
@ -288,7 +385,13 @@ module SB_DFFNSS (output `SB_DFF_REG, input C, S, D);
Q <= D;
endmodule
module SB_DFFNS (output `SB_DFF_REG, input C, S, D);
module SB_DFFNS (
`ABC_ARRIVAL_HX(540)
`ABC_ARRIVAL_LP(796)
`ABC_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, S, D
);
always @(negedge C, posedge S)
if (S)
Q <= 1;
@ -296,7 +399,13 @@ module SB_DFFNS (output `SB_DFF_REG, input C, S, D);
Q <= D;
endmodule
module SB_DFFNESR (output `SB_DFF_REG, input C, E, R, D);
module SB_DFFNESR (
`ABC_ARRIVAL_HX(540)
`ABC_ARRIVAL_LP(796)
`ABC_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, E, R, D
);
always @(negedge C)
if (E) begin
if (R)
@ -306,7 +415,13 @@ module SB_DFFNESR (output `SB_DFF_REG, input C, E, R, D);
end
endmodule
module SB_DFFNER (output `SB_DFF_REG, input C, E, R, D);
module SB_DFFNER (
`ABC_ARRIVAL_HX(540)
`ABC_ARRIVAL_LP(796)
`ABC_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, E, R, D
);
always @(negedge C, posedge R)
if (R)
Q <= 0;
@ -314,7 +429,13 @@ module SB_DFFNER (output `SB_DFF_REG, input C, E, R, D);
Q <= D;
endmodule
module SB_DFFNESS (output `SB_DFF_REG, input C, E, S, D);
module SB_DFFNESS (
`ABC_ARRIVAL_HX(540)
`ABC_ARRIVAL_LP(796)
`ABC_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, E, S, D
);
always @(negedge C)
if (E) begin
if (S)
@ -324,7 +445,13 @@ module SB_DFFNESS (output `SB_DFF_REG, input C, E, S, D);
end
endmodule
module SB_DFFNES (output `SB_DFF_REG, input C, E, S, D);
module SB_DFFNES (
`ABC_ARRIVAL_HX(540)
`ABC_ARRIVAL_LP(796)
`ABC_ARRIVAL_U(1391)
output `SB_DFF_REG,
input C, E, S, D
);
always @(negedge C, posedge S)
if (S)
Q <= 1;
@ -335,6 +462,9 @@ endmodule
// SiliconBlue RAM Cells
module SB_RAM40_4K (
`ABC_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401
`ABC_ARRIVAL_LP(3163) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401
`ABC_ARRIVAL_U(1179) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026
output [15:0] RDATA,
input RCLK, RCLKE, RE,
input [10:0] RADDR,
@ -503,6 +633,9 @@ module SB_RAM40_4K (
endmodule
module SB_RAM40_4KNR (
`ABC_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401
`ABC_ARRIVAL_LP(3163) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401
`ABC_ARRIVAL_U(1179) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026
output [15:0] RDATA,
input RCLKN, RCLKE, RE,
input [10:0] RADDR,
@ -568,6 +701,9 @@ module SB_RAM40_4KNR (
endmodule
module SB_RAM40_4KNW (
`ABC_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401
`ABC_ARRIVAL_LP(3163) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401
`ABC_ARRIVAL_U(1179) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026
output [15:0] RDATA,
input RCLK, RCLKE, RE,
input [10:0] RADDR,
@ -633,6 +769,9 @@ module SB_RAM40_4KNW (
endmodule
module SB_RAM40_4KNRNW (
`ABC_ARRIVAL_HX(2146) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_hx1k.txt#L401
`ABC_ARRIVAL_LP(3163) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_lp1k.txt#L401
`ABC_ARRIVAL_U(1179) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026
output [15:0] RDATA,
input RCLKN, RCLKE, RE,
input [10:0] RADDR,
@ -701,7 +840,12 @@ endmodule
module ICESTORM_LC (
input I0, I1, I2, I3, CIN, CLK, CEN, SR,
output LO, O, COUT
output LO,
`ABC_ARRIVAL_HX(540)
`ABC_ARRIVAL_LP(796)
`ABC_ARRIVAL_U(1391)
output O,
output COUT
);
parameter [15:0] LUT_INIT = 0;
@ -1301,6 +1445,7 @@ module SB_MAC16 (
input ADDSUBTOP, ADDSUBBOT,
input OHOLDTOP, OHOLDBOT,
input CI, ACCUMCI, SIGNEXTIN,
//`ABC_ARRIVAL_U(1984) // https://github.com/cliffordwolf/icestorm/blob/95949315364f8d9b0c693386aefadf44b28e2cf6/icefuzz/timings_up5k.txt#L13026
output [31:0] O,
output CO, ACCUMCO, SIGNEXTOUT
);

View file

@ -84,7 +84,7 @@ static void run_ice40_opts(Module *module)
continue;
}
if (cell->type == "$__ICE40_FULL_ADDER")
if (cell->type == "$__ICE40_CARRY_WRAPPER")
{
SigSpec non_const_inputs, replacement_output;
int count_zeros = 0, count_ones = 0;
@ -114,16 +114,17 @@ static void run_ice40_opts(Module *module)
optimized_co.insert(sigmap(cell->getPort("\\CO")[0]));
module->connect(cell->getPort("\\CO")[0], replacement_output);
module->design->scratchpad_set_bool("opt.did_something", true);
log("Optimized $__ICE40_FULL_ADDER cell back to logic (without SB_CARRY) %s.%s: CO=%s\n",
log("Optimized $__ICE40_CARRY_WRAPPER cell back to logic (without SB_CARRY) %s.%s: CO=%s\n",
log_id(module), log_id(cell), log_signal(replacement_output));
cell->type = "$lut";
cell->setPort("\\A", { State::S0, inbit[0], inbit[1], inbit[2] });
cell->setPort("\\A", { cell->getPort("\\I0"), inbit[0], inbit[1], cell->getPort("\\I3") });
cell->setPort("\\Y", cell->getPort("\\O"));
cell->unsetPort("\\B");
cell->unsetPort("\\CI");
cell->unsetPort("\\I0");
cell->unsetPort("\\I3");
cell->unsetPort("\\CO");
cell->unsetPort("\\O");
cell->setParam("\\LUT", RTLIL::Const::from_string("0110100110010110"));
cell->setParam("\\WIDTH", 4);
}
continue;

View file

@ -238,7 +238,14 @@ struct SynthIce40Pass : public ScriptPass
{
if (check_label("begin"))
{
run("read_verilog -icells -lib +/ice40/cells_sim.v");
std::string define;
if (device_opt == "lp")
define = "-D ICE40_LP";
else if (device_opt == "u")
define = "-D ICE40_U";
else
define = "-D ICE40_HX";
run("read_verilog -icells " + define + " -lib +/ice40/cells_sim.v");
run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
run("proc");
}

View file

@ -25,7 +25,10 @@ techlibs/xilinx/brams_init_8.vh: techlibs/xilinx/brams_init.mk
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/cells_map.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/cells_sim.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/cells_xtra.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_cells_xtra.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6v_cells_xtra.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_cells_xtra.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xcu_cells_xtra.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_brams.txt))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_brams_map.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_brams_bb.v))
@ -35,7 +38,8 @@ $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_brams_bb.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lutrams.txt))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lutrams_map.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/arith_map.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/ff_map.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc6s_ff_map.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/xc7_ff_map.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/lut_map.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/mux_map.v))

View file

@ -128,7 +128,7 @@ module RAM32X1D (
parameter INIT = 32'h0;
parameter IS_WCLK_INVERTED = 1'b0;
wire \$DPO , \$SPO ;
\$__ABC_RAM32X1D #(
RAM32X1D #(
.INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED)
) _TECHMAP_REPLACE_ (
.DPO(\$DPO ), .SPO(\$SPO ),
@ -136,8 +136,8 @@ module RAM32X1D (
.A0(A0), .A1(A1), .A2(A2), .A3(A3), .A4(A4),
.DPRA0(DPRA0), .DPRA1(DPRA1), .DPRA2(DPRA2), .DPRA3(DPRA3), .DPRA4(DPRA4)
);
\$__ABC_LUTMUX6 dpo (.A(\$DPO ), .S({1'b0, A0, A1, A2, A3, A4}), .Y(DPO));
\$__ABC_LUTMUX6 spo (.A(\$SPO ), .S({1'b0, A0, A1, A2, A3, A4}), .Y(SPO));
\$__ABC_LUT6 dpo (.A(\$DPO ), .S({1'b0, A0, A1, A2, A3, A4}), .Y(DPO));
\$__ABC_LUT6 spo (.A(\$SPO ), .S({1'b0, A0, A1, A2, A3, A4}), .Y(SPO));
endmodule
module RAM64X1D (
@ -151,7 +151,7 @@ module RAM64X1D (
parameter INIT = 64'h0;
parameter IS_WCLK_INVERTED = 1'b0;
wire \$DPO , \$SPO ;
\$__ABC_RAM64X1D #(
RAM64X1D #(
.INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED)
) _TECHMAP_REPLACE_ (
.DPO(\$DPO ), .SPO(\$SPO ),
@ -159,8 +159,8 @@ module RAM64X1D (
.A0(A0), .A1(A1), .A2(A2), .A3(A3), .A4(A4), .A5(A5),
.DPRA0(DPRA0), .DPRA1(DPRA1), .DPRA2(DPRA2), .DPRA3(DPRA3), .DPRA4(DPRA4), .DPRA5(DPRA5)
);
\$__ABC_LUTMUX6 dpo (.A(\$DPO ), .S({A0, A1, A2, A3, A4, A5}), .Y(DPO));
\$__ABC_LUTMUX6 spo (.A(\$SPO ), .S({A0, A1, A2, A3, A4, A5}), .Y(SPO));
\$__ABC_LUT6 dpo (.A(\$DPO ), .S({A0, A1, A2, A3, A4, A5}), .Y(DPO));
\$__ABC_LUT6 spo (.A(\$SPO ), .S({A0, A1, A2, A3, A4, A5}), .Y(SPO));
endmodule
module RAM128X1D (
@ -173,7 +173,7 @@ module RAM128X1D (
parameter INIT = 128'h0;
parameter IS_WCLK_INVERTED = 1'b0;
wire \$DPO , \$SPO ;
\$__ABC_RAM128X1D #(
RAM128X1D #(
.INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED)
) _TECHMAP_REPLACE_ (
.DPO(\$DPO ), .SPO(\$SPO ),
@ -181,8 +181,8 @@ module RAM128X1D (
.A(A),
.DPRA(DPRA)
);
\$__ABC_LUTMUX7 dpo (.A(\$DPO ), .S(A), .Y(DPO));
\$__ABC_LUTMUX7 spo (.A(\$SPO ), .S(A), .Y(SPO));
\$__ABC_LUT7 dpo (.A(\$DPO ), .S(A), .Y(DPO));
\$__ABC_LUT7 spo (.A(\$SPO ), .S(A), .Y(SPO));
endmodule
module SRL16E (
@ -192,14 +192,13 @@ module SRL16E (
parameter [15:0] INIT = 16'h0000;
parameter [0:0] IS_CLK_INVERTED = 1'b0;
wire \$Q ;
\$__ABC_SRL16E #(
SRL16E #(
.INIT(INIT), .IS_CLK_INVERTED(IS_CLK_INVERTED)
) _TECHMAP_REPLACE_ (
.Q(\$Q ),
.A0(A0), .A1(A1), .A2(A2), .A3(A3), .CE(CE), .CLK(CLK), .D(D)
);
// TODO: Check if SRL uses fast inputs or slow inputs
\$__ABC_LUTMUX6 q (.A(\$Q ), .S({A0, A1, A2, A3, 1'b0, 1'b0}), .Y(Q));
\$__ABC_LUT6 q (.A(\$Q ), .S({1'b1, A0, A1, A2, A3, 1'b1}), .Y(Q));
endmodule
module SRLC32E (
@ -211,12 +210,11 @@ module SRLC32E (
parameter [31:0] INIT = 32'h00000000;
parameter [0:0] IS_CLK_INVERTED = 1'b0;
wire \$Q ;
\$__ABC_SRLC32E #(
SRLC32E #(
.INIT(INIT), .IS_CLK_INVERTED(IS_CLK_INVERTED)
) _TECHMAP_REPLACE_ (
.Q(\$Q ), .Q31(Q31),
.A(A), .CE(CE), .CLK(CLK), .D(D)
);
// TODO: Check if SRL uses fast inputs or slow inputs
\$__ABC_LUTMUX6 q (.A(\$Q ), .S({A, 1'b0}), .Y(Q));
\$__ABC_LUT6 q (.A(\$Q ), .S({1'b1, A}), .Y(Q));
endmodule

View file

@ -115,65 +115,8 @@ module \$__ABC_FDPE_1 ((* abc_flop_q, abc_arrival=303 *) output Q,
endmodule
(* abc_box_id=2000 *)
module \$__ABC_LUTMUX6 (input A, input [5:0] S, output Y);
module \$__ABC_LUT6 (input A, input [5:0] S, output Y);
endmodule
(* abc_box_id=2001 *)
module \$__ABC_LUTMUX7 (input A, input [6:0] S, output Y);
endmodule
module \$__ABC_RAM32X1D (
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957
(* abc_arrival=1153 *) output DPO, SPO,
input D,
input WCLK,
input WE,
input A0, A1, A2, A3, A4,
input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4
);
endmodule
module \$__ABC_RAM64X1D (
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957
(* abc_arrival=1153 *) output DPO, SPO,
input D,
input WCLK,
input WE,
input A0, A1, A2, A3, A4, A5,
input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5
);
parameter INIT = 64'h0;
parameter IS_WCLK_INVERTED = 1'b0;
endmodule
module \$__ABC_RAM128X1D (
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957
(* abc_arrival=1153 *) output DPO, SPO,
input D,
input WCLK,
input WE,
input [6:0] A, DPRA
);
parameter INIT = 128'h0;
parameter IS_WCLK_INVERTED = 1'b0;
endmodule
module SRL16E (
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905
(* abc_arrival=1472 *) output Q,
input A0, A1, A2, A3, CE, CLK, D
);
parameter [15:0] INIT = 16'h0000;
parameter [0:0] IS_CLK_INVERTED = 1'b0;
endmodule
module SRLC32E (
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905
(* abc_arrival=1472 *) output Q,
(* abc_arrival=1114 *) output Q31,
input [4:0] A,
input CE, CLK, D
);
parameter [31:0] INIT = 32'h00000000;
parameter [0:0] IS_CLK_INVERTED = 1'b0;
module \$__ABC_LUT7 (input A, input [6:0] S, output Y);
endmodule

View file

@ -139,101 +139,9 @@ module \$__ABC_FDPE_1 (output Q,
);
endmodule
module \$__ABC_LUTMUX6 (input A, input [5:0] S, output Y);
module \$__ABC_LUT6 (input A, input [5:0] S, output Y);
assign Y = A;
endmodule
module \$__ABC_LUTMUX7 (input A, input [6:0] S, output Y);
module \$__ABC_LUT7 (input A, input [6:0] S, output Y);
assign Y = A;
endmodule
module \$__ABC_RAM32X1D (
output DPO, SPO,
input D,
input WCLK,
input WE,
input A0, A1, A2, A3, A4,
input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4
);
parameter INIT = 32'h0;
parameter IS_WCLK_INVERTED = 1'b0;
RAM32X1D #(
.INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED)
) _TECHMAP_REPLACE_ (
.DPO(DPO), .SPO(SPO),
.D(D), .WCLK(WCLK), .WE(WE),
.A0(A0), .A1(A1), .A2(A2), .A3(A3), .A4(A4),
.DPRA0(DPRA0), .DPRA1(DPRA1), .DPRA2(DPRA2), .DPRA3(DPRA3), .DPRA4(DPRA4)
);
endmodule
module \$__ABC_RAM64X1D (
output DPO, SPO,
input D,
input WCLK,
input WE,
input A0, A1, A2, A3, A4, A5,
input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, DPRA5
);
parameter INIT = 64'h0;
parameter IS_WCLK_INVERTED = 1'b0;
RAM64X1D #(
.INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED)
) _TECHMAP_REPLACE_ (
.DPO(DPO), .SPO(SPO),
.D(D), .WCLK(WCLK), .WE(WE),
.A0(A0), .A1(A1), .A2(A2), .A3(A3), .A4(A4), .A5(A5),
.DPRA0(DPRA0), .DPRA1(DPRA1), .DPRA2(DPRA2), .DPRA3(DPRA3), .DPRA4(DPRA4), .DPRA5(DPRA5)
);
endmodule
module \$__ABC_RAM128X1D (
output DPO, SPO,
input D,
input WCLK,
input WE,
input A,
input DPRA,
);
parameter INIT = 128'h0;
parameter IS_WCLK_INVERTED = 1'b0;
RAM128X1D #(
.INIT(INIT), .IS_WCLK_INVERTED(IS_WCLK_INVERTED)
) _TECHMAP_REPLACE_ (
.DPO(DPO), .SPO(SPO),
.D(D), .WCLK(WCLK), .WE(WE),
.A(A),
.DPRA(DPRA)
);
endmodule
module \$__ABC_SRL16E (
output Q,
input A0, A1, A2, A3, CE, CLK, D
);
parameter [15:0] INIT = 16'h0000;
parameter [0:0] IS_CLK_INVERTED = 1'b0;
SRL16E #(
.INIT(INIT), .IS_CLK_INVERTED(IS_CLK_INVERTED)
) _TECHMAP_REPLACE_ (
.Q(Q),
.A0(A0), .A1(A1), .A2(A2), .A3(A3), .CE(CE), .CLK(CLK), .D(D)
);
endmodule
module \$__ABC_SRLC32E (
output Q,
output Q31,
input [4:0] A,
input CE, CLK, D
);
parameter [31:0] INIT = 32'h00000000;
parameter [0:0] IS_CLK_INVERTED = 1'b0;
SRLC32E #(
.INIT(INIT), .IS_CLK_INVERTED(IS_CLK_INVERTED)
) _TECHMAP_REPLACE_ (
.Q(Q), .Q31(Q31),
.A(A), .CE(CE), .CLK(CLK), .D(D)
);
endmodule

View file

@ -15,7 +15,10 @@ F7MUX 1 1 3 1
MUXF8 2 1 3 1
104 94 273
# Box containing MUXF7.[AB] + MUXF8
# Box containing MUXF7.[AB] + MUXF8,
# Necessary to make these an atomic unit so that
# ABC cannot optimise just one of the MUXF7 away
# and expect to save on its delay
# Inputs: I0 I1 I2 I3 S0 S1
# Outputs: O
$__MUXF78 3 1 6 1
@ -81,14 +84,19 @@ FDPE_1 1006 1 5 1
# SLICEM/A6LUT
# Box to emulate comb/seq behaviour of RAMD{32,64} and SRL{16,32}
# Necessary since RAMD* and SRL* have both combinatorial (i.e.
# same-cycle read operation) and sequential (write operation
# is only committed on the next clock edge).
# To model the combinatorial path, such cells have to be split
# into comb and seq parts, with this box modelling only the former.
# Inputs: A S0 S1 S2 S3 S4 S5
# Outputs: Y
$__ABC_LUTRAM6 2000 0 7 1
$__ABC_LUT6 2000 0 7 1
0 642 631 472 407 238 127
# SLICEM/A6LUT + F7BMUX
# Box to emulate comb/seq behaviour of RAMD128
# Inputs: A S0 S1 S2 S3 S4 S5 S6
# Outputs: DPO SPO
$__ABC_LUTRAM7 2001 0 8 1
$__ABC_LUT7 2001 0 8 1
0 1047 1036 877 812 643 532 478

View file

@ -29,29 +29,49 @@ module GND(output G);
assign G = 0;
endmodule
module IBUF(output O, input I);
module IBUF(
output O,
(* iopad_external_pin *)
input I);
parameter IOSTANDARD = "default";
parameter IBUF_LOW_PWR = 0;
assign O = I;
endmodule
module OBUF(output O, input I);
module OBUF(
(* iopad_external_pin *)
output O,
input I);
parameter IOSTANDARD = "default";
parameter DRIVE = 12;
parameter SLEW = "SLOW";
assign O = I;
endmodule
module BUFG(output O, input I);
module BUFG(
(* clkbuf_driver *)
output O,
input I);
assign O = I;
endmodule
module BUFGCTRL(
(* clkbuf_driver *)
output O,
input I0, input I1,
input S0, input S1,
input CE0, input CE1,
input IGNORE0, input IGNORE1);
(* invertible_pin = "IS_S0_INVERTED" *)
input S0,
(* invertible_pin = "IS_S1_INVERTED" *)
input S1,
(* invertible_pin = "IS_CE0_INVERTED" *)
input CE0,
(* invertible_pin = "IS_CE1_INVERTED" *)
input CE1,
(* invertible_pin = "IS_IGNORE0_INVERTED" *)
input IGNORE0,
(* invertible_pin = "IS_IGNORE1_INVERTED" *)
input IGNORE1);
parameter [0:0] INIT_OUT = 1'b0;
parameter PRESELECT_I0 = "FALSE";
@ -72,7 +92,12 @@ assign O = S0_true ? I0_internal : (S1_true ? I1_internal : INIT_OUT);
endmodule
module BUFHCE(output O, input I, input CE);
module BUFHCE(
(* clkbuf_driver *)
output O,
input I,
(* invertible_pin = "IS_CE_INVERTED" *)
input CE);
parameter [0:0] INIT_OUT = 1'b0;
parameter CE_TYPE = "SYNC";
@ -175,9 +200,11 @@ endmodule
(* abc_box_id = 4, lib_whitebox *)
module CARRY4(
(* abc_carry *) output [3:0] CO,
(* abc_carry *)
output [3:0] CO,
output [3:0] O,
(* abc_carry *) input CI,
(* abc_carry *)
input CI,
input CYINIT,
input [3:0] DI, S
);
@ -211,7 +238,20 @@ endmodule
`endif
module FDRE (output reg Q, input C, CE, D, R);
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf#L238-L250
module FDRE (
(* abc_arrival=303 *)
output reg Q,
(* clkbuf_sink *)
(* invertible_pin = "IS_C_INVERTED" *)
input C,
input CE,
(* invertible_pin = "IS_D_INVERTED" *)
input D,
(* invertible_pin = "IS_R_INVERTED" *)
input R
);
parameter [0:0] INIT = 1'b0;
parameter [0:0] IS_C_INVERTED = 1'b0;
parameter [0:0] IS_D_INVERTED = 1'b0;
@ -223,7 +263,18 @@ module FDRE (output reg Q, input C, CE, D, R);
endcase endgenerate
endmodule
module FDSE (output reg Q, input C, CE, D, S);
module FDSE (
(* abc_arrival=303 *)
output reg Q,
(* clkbuf_sink *)
(* invertible_pin = "IS_C_INVERTED" *)
input C,
input CE,
(* invertible_pin = "IS_D_INVERTED" *)
input D,
(* invertible_pin = "IS_S_INVERTED" *)
input S
);
parameter [0:0] INIT = 1'b1;
parameter [0:0] IS_C_INVERTED = 1'b0;
parameter [0:0] IS_D_INVERTED = 1'b0;
@ -235,7 +286,18 @@ module FDSE (output reg Q, input C, CE, D, S);
endcase endgenerate
endmodule
module FDCE (output reg Q, input C, CE, D, CLR);
module FDCE (
(* abc_arrival=303 *)
output reg Q,
(* clkbuf_sink *)
(* invertible_pin = "IS_C_INVERTED" *)
input C,
input CE,
(* invertible_pin = "IS_D_INVERTED" *)
input D,
(* invertible_pin = "IS_CLR_INVERTED" *)
input CLR
);
parameter [0:0] INIT = 1'b0;
parameter [0:0] IS_C_INVERTED = 1'b0;
parameter [0:0] IS_D_INVERTED = 1'b0;
@ -249,7 +311,18 @@ module FDCE (output reg Q, input C, CE, D, CLR);
endcase endgenerate
endmodule
module FDPE (output reg Q, input C, CE, D, PRE);
module FDPE (
(* abc_arrival=303 *)
output reg Q,
(* clkbuf_sink *)
(* invertible_pin = "IS_C_INVERTED" *)
input C,
input CE,
(* invertible_pin = "IS_D_INVERTED" *)
input D,
(* invertible_pin = "IS_PRE_INVERTED" *)
input PRE
);
parameter [0:0] INIT = 1'b1;
parameter [0:0] IS_C_INVERTED = 1'b0;
parameter [0:0] IS_D_INVERTED = 1'b0;
@ -263,33 +336,61 @@ module FDPE (output reg Q, input C, CE, D, PRE);
endcase endgenerate
endmodule
module FDRE_1 (output reg Q, input C, CE, D, R);
module FDRE_1 (
(* abc_arrival=303 *)
output reg Q,
(* clkbuf_sink *)
input C,
input CE, D, R
);
parameter [0:0] INIT = 1'b0;
initial Q <= INIT;
always @(negedge C) if (R) Q <= 1'b0; else if(CE) Q <= D;
endmodule
module FDSE_1 (output reg Q, input C, CE, D, S);
module FDSE_1 (
(* abc_arrival=303 *)
output reg Q,
(* clkbuf_sink *)
input C,
input CE, D, S
);
parameter [0:0] INIT = 1'b1;
initial Q <= INIT;
always @(negedge C) if (S) Q <= 1'b1; else if(CE) Q <= D;
endmodule
module FDCE_1 (output reg Q, input C, CE, D, CLR);
module FDCE_1 (
(* abc_arrival=303 *)
output reg Q,
(* clkbuf_sink *)
input C,
input CE, D, CLR
);
parameter [0:0] INIT = 1'b0;
initial Q <= INIT;
always @(negedge C, posedge CLR) if (CLR) Q <= 1'b0; else if (CE) Q <= D;
endmodule
module FDPE_1 (output reg Q, input C, CE, D, PRE);
module FDPE_1 (
(* abc_arrival=303 *)
output reg Q,
(* clkbuf_sink *)
input C,
input CE, D, PRE
);
parameter [0:0] INIT = 1'b1;
initial Q <= INIT;
always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else if (CE) Q <= D;
endmodule
module RAM32X1D (
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957
(* abc_arrival=1153 *)
output DPO, SPO,
input D,
(* clkbuf_sink *)
(* invertible_pin = "IS_WCLK_INVERTED" *)
input WCLK,
input WE,
input A0, A1, A2, A3, A4,
@ -307,8 +408,12 @@ module RAM32X1D (
endmodule
module RAM64X1D (
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957
(* abc_arrival=1153 *)
output DPO, SPO,
input D,
(* clkbuf_sink *)
(* invertible_pin = "IS_WCLK_INVERTED" *)
input WCLK,
input WE,
input A0, A1, A2, A3, A4, A5,
@ -326,8 +431,12 @@ module RAM64X1D (
endmodule
module RAM128X1D (
output DPO, SPO,
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L957
(* abc_arrival=1153 *)
output DPO, SPO,
input D,
(* clkbuf_sink *)
(* invertible_pin = "IS_WCLK_INVERTED" *)
input WCLK,
input WE,
input [6:0] A, DPRA
@ -342,8 +451,14 @@ module RAM128X1D (
endmodule
module SRL16E (
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905
(* abc_arrival=1472 *)
output Q,
input A0, A1, A2, A3, CE, CLK, D
input A0, A1, A2, A3, CE,
(* clkbuf_sink *)
(* invertible_pin = "IS_CLK_INVERTED" *)
input CLK,
input D
);
parameter [15:0] INIT = 16'h0000;
parameter [0:0] IS_CLK_INVERTED = 1'b0;
@ -355,15 +470,46 @@ module SRL16E (
always @(negedge CLK) if (CE) r <= { r[14:0], D };
end
else
always @(posedge CLK) if (CE) r <= { r[14:0], D };
always @(posedge CLK) if (CE) r <= { r[14:0], D };
endgenerate
endmodule
module SRLC16E (
output Q,
output Q15,
input A0, A1, A2, A3, CE,
(* clkbuf_sink *)
(* invertible_pin = "IS_CLK_INVERTED" *)
input CLK,
input D
);
parameter [15:0] INIT = 16'h0000;
parameter [0:0] IS_CLK_INVERTED = 1'b0;
reg [15:0] r = INIT;
assign Q15 = r[15];
assign Q = r[{A3,A2,A1,A0}];
generate
if (IS_CLK_INVERTED) begin
always @(negedge CLK) if (CE) r <= { r[14:0], D };
end
else
always @(posedge CLK) if (CE) r <= { r[14:0], D };
endgenerate
endmodule
module SRLC32E (
// Max delay from: https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLM_R.sdf#L904-L905
(* abc_arrival=1472 *)
output Q,
(* abc_arrival=1114 *)
output Q31,
input [4:0] A,
input CE, CLK, D
input CE,
(* clkbuf_sink *)
(* invertible_pin = "IS_CLK_INVERTED" *)
input CLK,
input D
);
parameter [31:0] INIT = 32'h00000000;
parameter [0:0] IS_CLK_INVERTED = 1'b0;

View file

@ -0,0 +1,708 @@
#!/usr/bin/env python3
from argparse import ArgumentParser
from io import StringIO
from enum import Enum, auto
import os.path
import sys
import re
class Cell:
def __init__(self, name, keep=False, port_attrs={}):
self.name = name
self.keep = keep
self.port_attrs = port_attrs
XC6S_CELLS = [
# Design elements types listed in Xilinx UG615.
# Advanced.
Cell('MCB'),
Cell('PCIE_A1'),
# Arithmetic functions.
Cell('DSP48A1', port_attrs={'CLK': ['clkbuf_sink']}),
# Clock components.
# Cell('BUFG', port_attrs={'O': ['clkbuf_driver']}),
Cell('BUFGCE', port_attrs={'O': ['clkbuf_driver']}),
Cell('BUFGCE_1', port_attrs={'O': ['clkbuf_driver']}),
Cell('BUFGMUX', port_attrs={'O': ['clkbuf_driver']}),
Cell('BUFGMUX_1', port_attrs={'O': ['clkbuf_driver']}),
Cell('BUFH', port_attrs={'O': ['clkbuf_driver']}),
Cell('BUFIO2', port_attrs={'IOCLK': ['clkbuf_driver'], 'DIVCLK': ['clkbuf_driver']}),
Cell('BUFIO2_2CLK', port_attrs={'IOCLK': ['clkbuf_driver'], 'DIVCLK': ['clkbuf_driver']}),
Cell('BUFIO2FB', port_attrs={'O': ['clkbuf_driver']}),
Cell('BUFPLL_MCB', port_attrs={'IOCLK0': ['clkbuf_driver'], 'IOCLK1': ['clkbuf_driver']}),
Cell('DCM_CLKGEN'),
Cell('DCM_SP'),
Cell('PLL_BASE'),
# Config/BSCAN components.
Cell('BSCAN_SPARTAN6', keep=True),
Cell('DNA_PORT'),
Cell('ICAP_SPARTAN6', keep=True),
Cell('POST_CRC_INTERNAL'),
Cell('STARTUP_SPARTAN6', keep=True),
Cell('SUSPEND_SYNC', keep=True),
# I/O components.
Cell('GTPA1_DUAL'),
# Cell('IBUF', port_attrs={'I': ['iopad_external_pin']}),
Cell('IBUFDS', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('IBUFDS_DIFF_OUT', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('IBUFG', port_attrs={'I': ['iopad_external_pin']}),
Cell('IBUFGDS', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('IBUFGDS_DIFF_OUT', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('IOBUF', port_attrs={'IO': ['iopad_external_pin']}),
Cell('IOBUFDS', port_attrs={'IO': ['iopad_external_pin']}),
Cell('IODELAY2', port_attrs={'IOCLK0': ['clkbuf_sink'], 'IOCLK1': ['clkbuf_sink'], 'CLK': ['clkbuf_sink']}),
Cell('IODRP2', port_attrs={'IOCLK0': ['clkbuf_sink'], 'IOCLK1': ['clkbuf_sink'], 'CLK': ['clkbuf_sink']}),
Cell('IODRP2_MCB', port_attrs={'IOCLK0': ['clkbuf_sink'], 'IOCLK1': ['clkbuf_sink'], 'CLK': ['clkbuf_sink']}),
Cell('ISERDES2', port_attrs={
'CLK0': ['clkbuf_sink'],
'CLK1': ['clkbuf_sink'],
'CLKDIV': ['clkbuf_sink'],
}),
Cell('KEEPER'),
# Cell('OBUF', port_attrs={'O': ['iopad_external_pin']}),
Cell('OBUFDS', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
Cell('OBUFT', port_attrs={'O': ['iopad_external_pin']}),
Cell('OBUFTDS', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
Cell('OSERDES2', port_attrs={
'CLK0': ['clkbuf_sink'],
'CLK1': ['clkbuf_sink'],
'CLKDIV': ['clkbuf_sink'],
}),
Cell('PULLDOWN'),
Cell('PULLUP'),
# RAM/ROM.
#Cell('RAM128X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
# NOTE: not in the official library guide!
Cell('RAM128X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
Cell('RAM256X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
Cell('RAM32M', port_attrs={'WCLK': ['clkbuf_sink']}),
#Cell('RAM32X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
Cell('RAM32X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
Cell('RAM32X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}),
Cell('RAM32X2S', port_attrs={'WCLK': ['clkbuf_sink']}),
Cell('RAM64M', port_attrs={'WCLK': ['clkbuf_sink']}),
#Cell('RAM64X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
Cell('RAM64X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
Cell('RAM64X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}),
# NOTE: not in the official library guide!
Cell('RAM64X2S', port_attrs={'WCLK': ['clkbuf_sink']}),
# Cell('RAMB8BWER', port_attrs={'CLKAWRCLK': ['clkbuf_sink'], 'CLKBRDCLK': ['clkbuf_sink']}),
# Cell('RAMB16BWER', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
Cell('ROM128X1'),
Cell('ROM256X1'),
Cell('ROM32X1'),
Cell('ROM64X1'),
# Registers/latches.
# Cell('FDCE'),
# Cell('FDPE'),
# Cell('FDRE'),
# Cell('FDSE'),
Cell('IDDR2', port_attrs={'C0': ['clkbuf_sink'], 'C1': ['clkbuf_sink']}),
Cell('LDCE'),
Cell('LDPE'),
Cell('ODDR2', port_attrs={'C0': ['clkbuf_sink'], 'C1': ['clkbuf_sink']}),
# Slice/CLB primitives.
# Cell('CARRY4'),
Cell('CFGLUT5', port_attrs={'CLK': ['clkbuf_sink']}),
# Cell('LUT1'),
# Cell('LUT2'),
# Cell('LUT3'),
# Cell('LUT4'),
# Cell('LUT5'),
# Cell('LUT6'),
# Cell('LUT6_2'),
# Cell('MUXF7'),
# Cell('MUXF8'),
# Cell('SRL16E', port_attrs={'CLK': ['clkbuf_sink']}),
# Cell('SRLC32E', port_attrs={'CLK': ['clkbuf_sink']}),
]
XC6V_CELLS = [
# Design elements types listed in Xilinx UG623.
# Advanced.
Cell('PCIE_2_0'),
Cell('SYSMON'),
# Arithmetic functions.
Cell('DSP48E1', port_attrs={'CLK': ['clkbuf_sink']}),
# Clock components.
# Cell('BUFG', port_attrs={'O': ['clkbuf_driver']}),
Cell('BUFGCE', port_attrs={'O': ['clkbuf_driver']}),
Cell('BUFGCE_1', port_attrs={'O': ['clkbuf_driver']}),
#Cell('BUFGCTRL', port_attrs={'O': ['clkbuf_driver']}),
Cell('BUFGMUX', port_attrs={'O': ['clkbuf_driver']}),
Cell('BUFGMUX_1', port_attrs={'O': ['clkbuf_driver']}),
Cell('BUFGMUX_CTRL', port_attrs={'O': ['clkbuf_driver']}),
Cell('BUFH', port_attrs={'O': ['clkbuf_driver']}),
#Cell('BUFHCE', port_attrs={'O': ['clkbuf_driver']}),
Cell('BUFIO', port_attrs={'O': ['clkbuf_driver']}),
Cell('BUFIODQS', port_attrs={'O': ['clkbuf_driver']}),
Cell('BUFR', port_attrs={'O': ['clkbuf_driver']}),
Cell('IBUFDS_GTXE1', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('MMCM_ADV'),
Cell('MMCM_BASE'),
# Config/BSCAN components.
Cell('BSCAN_VIRTEX6', keep=True),
Cell('CAPTURE_VIRTEX6', keep=True),
Cell('DNA_PORT'),
Cell('EFUSE_USR'),
Cell('FRAME_ECC_VIRTEX6'),
Cell('ICAP_VIRTEX6', keep=True),
Cell('STARTUP_VIRTEX6', keep=True),
Cell('USR_ACCESS_VIRTEX6'),
# I/O components.
Cell('DCIRESET', keep=True),
Cell('GTHE1_QUAD'),
Cell('GTXE1'),
# Cell('IBUF', port_attrs={'I': ['iopad_external_pin']}),
Cell('IBUFDS', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('IBUFDS_DIFF_OUT', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('IBUFDS_GTHE1', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('IBUFG', port_attrs={'I': ['iopad_external_pin']}),
Cell('IBUFGDS', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('IBUFGDS_DIFF_OUT', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('IDELAYCTRL', keep=True, port_attrs={'REFCLK': ['clkbuf_sink']}),
Cell('IOBUF', port_attrs={'IO': ['iopad_external_pin']}),
Cell('IOBUFDS', port_attrs={'IO': ['iopad_external_pin']}),
Cell('IODELAYE1', port_attrs={'C': ['clkbuf_sink']}),
Cell('ISERDESE1', port_attrs={
'CLK': ['clkbuf_sink'],
'CLKB': ['clkbuf_sink'],
'OCLK': ['clkbuf_sink'],
'CLKDIV': ['clkbuf_sink'],
}),
Cell('KEEPER'),
# Cell('OBUF', port_attrs={'O': ['iopad_external_pin']}),
Cell('OBUFDS', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
Cell('OBUFT', port_attrs={'O': ['iopad_external_pin']}),
Cell('OBUFTDS', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
Cell('OSERDESE1', port_attrs={'CLK': ['clkbuf_sink'], 'CLKDIV': ['clkbuf_sink']}),
Cell('PULLDOWN'),
Cell('PULLUP'),
Cell('TEMAC_SINGLE'),
# RAM/ROM.
Cell('FIFO18E1', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
Cell('FIFO36E1', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
#Cell('RAM128X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
Cell('RAM128X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
Cell('RAM256X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
Cell('RAM32M', port_attrs={'WCLK': ['clkbuf_sink']}),
#Cell('RAM32X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
Cell('RAM32X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
Cell('RAM32X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}),
Cell('RAM32X2S', port_attrs={'WCLK': ['clkbuf_sink']}),
Cell('RAM64M', port_attrs={'WCLK': ['clkbuf_sink']}),
#Cell('RAM64X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
Cell('RAM64X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
Cell('RAM64X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}),
# NOTE: not in the official library guide!
Cell('RAM64X2S', port_attrs={'WCLK': ['clkbuf_sink']}),
# Cell('RAMB18E1', port_attrs={'CLKARDCLK': ['clkbuf_sink'], 'CLKBWRCLK': ['clkbuf_sink']}),
# Cell('RAMB36E1', port_attrs={'CLKARDCLK': ['clkbuf_sink'], 'CLKBWRCLK': ['clkbuf_sink']}),
Cell('ROM128X1'),
Cell('ROM256X1'),
Cell('ROM32X1'),
Cell('ROM64X1'),
# Registers/latches.
# Cell('FDCE'),
# Cell('FDPE'),
# Cell('FDRE'),
# Cell('FDSE'),
Cell('IDDR', port_attrs={'C': ['clkbuf_sink']}),
Cell('IDDR_2CLK', port_attrs={'C': ['clkbuf_sink'], 'CB': ['clkbuf_sink']}),
Cell('LDCE'),
Cell('LDPE'),
Cell('ODDR', port_attrs={'C': ['clkbuf_sink']}),
# Slice/CLB primitives.
# Cell('CARRY4'),
Cell('CFGLUT5', port_attrs={'CLK': ['clkbuf_sink']}),
# Cell('LUT1'),
# Cell('LUT2'),
# Cell('LUT3'),
# Cell('LUT4'),
# Cell('LUT5'),
# Cell('LUT6'),
# Cell('LUT6_2'),
# Cell('MUXF7'),
# Cell('MUXF8'),
# Cell('SRL16E', port_attrs={'CLK': ['clkbuf_sink']}),
# Cell('SRLC32E', port_attrs={'CLK': ['clkbuf_sink']}),
]
XC7_CELLS = [
# Design elements types listed in Xilinx UG953.
# Advanced.
Cell('GTHE2_CHANNEL'),
Cell('GTHE2_COMMON'),
Cell('GTPE2_CHANNEL'),
Cell('GTPE2_COMMON'),
Cell('GTXE2_CHANNEL'),
Cell('GTXE2_COMMON'),
Cell('PCIE_2_1'),
Cell('PCIE_3_0'),
Cell('XADC'),
# Arithmetic functions.
Cell('DSP48E1', port_attrs={'CLK': ['clkbuf_sink']}),
# Clock components.
# Cell('BUFG', port_attrs={'O': ['clkbuf_driver']}),
Cell('BUFGCE', port_attrs={'O': ['clkbuf_driver']}),
Cell('BUFGCE_1', port_attrs={'O': ['clkbuf_driver']}),
#Cell('BUFGCTRL', port_attrs={'O': ['clkbuf_driver']}),
Cell('BUFGMUX', port_attrs={'O': ['clkbuf_driver']}),
Cell('BUFGMUX_1', port_attrs={'O': ['clkbuf_driver']}),
Cell('BUFGMUX_CTRL', port_attrs={'O': ['clkbuf_driver']}),
Cell('BUFH', port_attrs={'O': ['clkbuf_driver']}),
#Cell('BUFHCE', port_attrs={'O': ['clkbuf_driver']}),
Cell('BUFIO', port_attrs={'O': ['clkbuf_driver']}),
Cell('BUFMR', port_attrs={'O': ['clkbuf_driver']}),
Cell('BUFMRCE', port_attrs={'O': ['clkbuf_driver']}),
Cell('BUFR', port_attrs={'O': ['clkbuf_driver']}),
Cell('MMCME2_ADV'),
Cell('MMCME2_BASE'),
Cell('PLLE2_ADV'),
Cell('PLLE2_BASE'),
# Config/BSCAN components.
Cell('BSCANE2', keep=True),
Cell('CAPTUREE2', keep=True),
Cell('DNA_PORT'),
Cell('EFUSE_USR'),
Cell('FRAME_ECCE2'),
Cell('ICAPE2', keep=True),
Cell('STARTUPE2', keep=True),
Cell('USR_ACCESSE2'),
# I/O components.
Cell('DCIRESET', keep=True),
# Cell('IBUF', port_attrs={'I': ['iopad_external_pin']}),
Cell('IBUF_IBUFDISABLE', port_attrs={'I': ['iopad_external_pin']}),
Cell('IBUF_INTERMDISABLE', port_attrs={'I': ['iopad_external_pin']}),
Cell('IBUFDS', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('IBUFDS_DIFF_OUT', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('IBUFDS_DIFF_OUT_IBUFDISABLE', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('IBUFDS_DIFF_OUT_INTERMDISABLE', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('IBUFDS_GTE2', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('IBUFDS_IBUFDISABLE', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('IBUFDS_INTERMDISABLE', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('IBUFG', port_attrs={'I': ['iopad_external_pin']}),
Cell('IBUFGDS', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('IBUFGDS_DIFF_OUT', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('IDELAYCTRL', keep=True, port_attrs={'REFCLK': ['clkbuf_sink']}),
Cell('IDELAYE2', port_attrs={'C': ['clkbuf_sink']}),
Cell('IN_FIFO', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
Cell('IOBUF', port_attrs={'IO': ['iopad_external_pin']}),
Cell('IOBUF_DCIEN', port_attrs={'IO': ['iopad_external_pin']}),
Cell('IOBUF_INTERMDISABLE', port_attrs={'IO': ['iopad_external_pin']}),
Cell('IOBUFDS', port_attrs={'IO': ['iopad_external_pin']}),
Cell('IOBUFDS_DCIEN', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
Cell('IOBUFDS_DIFF_OUT', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
Cell('IOBUFDS_DIFF_OUT_DCIEN', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
Cell('IOBUFDS_DIFF_OUT_INTERMDISABLE', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
Cell('IOBUFDS_INTERMDISABLE', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
Cell('ISERDESE2', port_attrs={
'CLK': ['clkbuf_sink'],
'CLKB': ['clkbuf_sink'],
'OCLK': ['clkbuf_sink'],
'OCLKB': ['clkbuf_sink'],
'CLKDIV': ['clkbuf_sink'],
'CLKDIVP': ['clkbuf_sink'],
}),
Cell('KEEPER'),
# Cell('OBUF', port_attrs={'O': ['iopad_external_pin']}),
Cell('OBUFDS', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
Cell('OBUFT', port_attrs={'O': ['iopad_external_pin']}),
Cell('OBUFTDS', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
Cell('ODELAYE2', port_attrs={'C': ['clkbuf_sink']}),
Cell('OSERDESE2', port_attrs={'CLK': ['clkbuf_sink'], 'CLKDIV': ['clkbuf_sink']}),
Cell('OUT_FIFO', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
Cell('PHASER_IN'),
Cell('PHASER_IN_PHY'),
Cell('PHASER_OUT'),
Cell('PHASER_OUT_PHY'),
Cell('PHASER_REF'),
Cell('PHY_CONTROL'),
Cell('PULLDOWN'),
Cell('PULLUP'),
# RAM/ROM.
Cell('FIFO18E1', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
Cell('FIFO36E1', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
#Cell('RAM128X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
Cell('RAM128X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
Cell('RAM256X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
Cell('RAM32M', port_attrs={'WCLK': ['clkbuf_sink']}),
#Cell('RAM32X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
Cell('RAM32X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
Cell('RAM32X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}),
Cell('RAM32X2S', port_attrs={'WCLK': ['clkbuf_sink']}),
Cell('RAM64M', port_attrs={'WCLK': ['clkbuf_sink']}),
#Cell('RAM64X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
Cell('RAM64X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
Cell('RAM64X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}),
# NOTE: not in the official library guide!
Cell('RAM64X2S', port_attrs={'WCLK': ['clkbuf_sink']}),
# Cell('RAMB18E1', port_attrs={'CLKARDCLK': ['clkbuf_sink'], 'CLKBWRCLK': ['clkbuf_sink']}),
# Cell('RAMB36E1', port_attrs={'CLKARDCLK': ['clkbuf_sink'], 'CLKBWRCLK': ['clkbuf_sink']}),
Cell('ROM128X1'),
Cell('ROM256X1'),
Cell('ROM32X1'),
Cell('ROM64X1'),
# Registers/latches.
# Cell('FDCE'),
# Cell('FDPE'),
# Cell('FDRE'),
# Cell('FDSE'),
Cell('IDDR', port_attrs={'C': ['clkbuf_sink']}),
Cell('IDDR_2CLK', port_attrs={'C': ['clkbuf_sink'], 'CB': ['clkbuf_sink']}),
Cell('LDCE'),
Cell('LDPE'),
Cell('ODDR', port_attrs={'C': ['clkbuf_sink']}),
# Slice/CLB primitives.
# Cell('CARRY4'),
Cell('CFGLUT5', port_attrs={'CLK': ['clkbuf_sink']}),
# Cell('LUT1'),
# Cell('LUT2'),
# Cell('LUT3'),
# Cell('LUT4'),
# Cell('LUT5'),
# Cell('LUT6'),
# Cell('LUT6_2'),
# Cell('MUXF7'),
# Cell('MUXF8'),
# Cell('SRL16E', port_attrs={'CLK': ['clkbuf_sink']}),
# Cell('SRLC32E', port_attrs={'CLK': ['clkbuf_sink']}),
# NOTE: not in the official library guide!
Cell('PS7', keep=True),
]
XCU_CELLS = [
# Design elements types listed in Xilinx UG974.
# Advanced.
Cell('CMAC'),
Cell('CMACE4'),
Cell('GTHE3_CHANNEL'),
Cell('GTHE3_COMMON'),
Cell('GTHE4_CHANNEL'),
Cell('GTHE4_COMMON'),
Cell('GTYE3_CHANNEL'),
Cell('GTYE3_COMMON'),
Cell('GTYE4_CHANNEL'),
Cell('GTYE4_COMMON'),
Cell('IBUFDS_GTE3', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('IBUFDS_GTE4', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('ILKN'),
Cell('ILKNE4'),
Cell('OBUFDS_GTE3', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
Cell('OBUFDS_GTE3_ADV', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
Cell('OBUFDS_GTE4', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
Cell('OBUFDS_GTE4_ADV', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
Cell('PCIE40E4'),
Cell('PCIE_3_1'),
Cell('SYSMONE1'),
Cell('SYSMONE4'),
# Arithmetic functions.
Cell('DSP48E2', port_attrs={'CLK': ['clkbuf_sink']}),
# Blockram.
Cell('FIFO18E2', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
Cell('FIFO36E2', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
Cell('RAMB18E2', port_attrs={'CLKARDCLK': ['clkbuf_sink'], 'CLKBWRCLK': ['clkbuf_sink']}),
Cell('RAMB36E2', port_attrs={'CLKARDCLK': ['clkbuf_sink'], 'CLKBWRCLK': ['clkbuf_sink']}),
Cell('URAM288', port_attrs={'CLK': ['clkbuf_sink']}),
Cell('URAM288_BASE', port_attrs={'CLK': ['clkbuf_sink']}),
# CLB.
# Cell('LUT6_2'),
#Cell('RAM128X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
Cell('RAM128X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
Cell('RAM256X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
Cell('RAM256X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
Cell('RAM32M', port_attrs={'WCLK': ['clkbuf_sink']}),
Cell('RAM32M16', port_attrs={'WCLK': ['clkbuf_sink']}),
#Cell('RAM32X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
Cell('RAM32X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
Cell('RAM512X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
Cell('RAM64M', port_attrs={'WCLK': ['clkbuf_sink']}),
Cell('RAM64M8', port_attrs={'WCLK': ['clkbuf_sink']}),
#Cell('RAM64X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
Cell('RAM64X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
Cell('AND2B1L'),
Cell('CARRY8'),
Cell('CFGLUT5', port_attrs={'CLK': ['clkbuf_sink']}),
# Cell('LUT1'),
# Cell('LUT2'),
# Cell('LUT3'),
# Cell('LUT4'),
# Cell('LUT5'),
# Cell('LUT6'),
# Cell('MUXF7'),
# Cell('MUXF8'),
Cell('MUXF9'),
Cell('OR2L'),
# Cell('SRL16E', port_attrs={'CLK': ['clkbuf_sink']}),
# Cell('SRLC32E', port_attrs={'CLK': ['clkbuf_sink']}),
# Clock.
# Cell('BUFG', port_attrs={'O': ['clkbuf_driver']}),
Cell('BUFG_GT', port_attrs={'O': ['clkbuf_driver']}),
Cell('BUFG_GT_SYNC'),
Cell('BUFG_PS', port_attrs={'O': ['clkbuf_driver']}),
Cell('BUFGCE', port_attrs={'O': ['clkbuf_driver']}),
Cell('BUFGCE_1', port_attrs={'O': ['clkbuf_driver']}),
Cell('BUFGCE_DIV', port_attrs={'O': ['clkbuf_driver']}),
#Cell('BUFGCTRL', port_attrs={'O': ['clkbuf_driver']}),
Cell('BUFGMUX', port_attrs={'O': ['clkbuf_driver']}),
Cell('BUFGMUX_1', port_attrs={'O': ['clkbuf_driver']}),
Cell('BUFGMUX_CTRL', port_attrs={'O': ['clkbuf_driver']}),
Cell('MMCME3_ADV'),
Cell('MMCME3_BASE'),
Cell('MMCME4_ADV'),
Cell('MMCME4_BASE'),
Cell('PLLE3_ADV'),
Cell('PLLE3_BASE'),
Cell('PLLE4_ADV'),
Cell('PLLE4_BASE'),
# Configuration.
Cell('BSCANE2', keep=True),
Cell('DNA_PORTE2'),
Cell('EFUSE_USR'),
Cell('FRAME_ECCE3'),
Cell('ICAPE3', keep=True),
Cell('MASTER_JTAG', keep=True),
Cell('STARTUPE3', keep=True),
Cell('USR_ACCESSE2'),
# I/O.
Cell('BITSLICE_CONTROL', keep=True),
Cell('DCIRESET', keep=True),
Cell('HPIO_VREF'),
# XXX
# Cell('IBUF', port_attrs={'I': ['iopad_external_pin']}),
Cell('IBUF_ANALOG', port_attrs={'I': ['iopad_external_pin']}),
Cell('IBUF_IBUFDISABLE', port_attrs={'I': ['iopad_external_pin']}),
Cell('IBUF_INTERMDISABLE', port_attrs={'I': ['iopad_external_pin']}),
Cell('IBUFDS', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('IBUFDS_DIFF_OUT', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('IBUFDS_DIFF_OUT_IBUFDISABLE', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('IBUFDS_DIFF_OUT_INTERMDISABLE', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('IBUFDS_DPHY', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('IBUFDS_IBUFDISABLE', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('IBUFDS_INTERMDISABLE', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('IBUFDSE3', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
Cell('IBUFE3', port_attrs={'I': ['iopad_external_pin']}),
Cell('IDELAYCTRL', keep=True, port_attrs={'REFCLK': ['clkbuf_sink']}),
Cell('IDELAYE3', port_attrs={'CLK': ['clkbuf_sink']}),
Cell('IOBUF', port_attrs={'IO': ['iopad_external_pin']}),
Cell('IOBUF_DCIEN', port_attrs={'IO': ['iopad_external_pin']}),
Cell('IOBUF_INTERMDISABLE', port_attrs={'IO': ['iopad_external_pin']}),
Cell('IOBUFDS', port_attrs={'IO': ['iopad_external_pin']}),
Cell('IOBUFDS_DCIEN', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
Cell('IOBUFDS_DIFF_OUT', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
Cell('IOBUFDS_DIFF_OUT_DCIEN', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
Cell('IOBUFDS_DIFF_OUT_INTERMDISABLE', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
Cell('IOBUFDS_INTERMDISABLE', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
Cell('IOBUFDSE3', port_attrs={'IO': ['iopad_external_pin']}),
Cell('IOBUFE3', port_attrs={'IO': ['iopad_external_pin']}),
Cell('ISERDESE3', port_attrs={
'CLK': ['clkbuf_sink'],
'CLK_B': ['clkbuf_sink'],
'FIFO_RD_CLK': ['clkbuf_sink'],
'CLKDIV': ['clkbuf_sink'],
}),
Cell('KEEPER'),
# Cell('OBUF', port_attrs={'O': ['iopad_external_pin']}),
Cell('OBUFDS', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
Cell('OBUFDS_DPHY', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
Cell('OBUFT', port_attrs={'O': ['iopad_external_pin']}),
Cell('OBUFTDS', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
Cell('ODELAYE3', port_attrs={'CLK': ['clkbuf_sink']}),
Cell('OSERDESE3', port_attrs={'CLK': ['clkbuf_sink'], 'CLKDIV': ['clkbuf_sink']}),
Cell('PULLDOWN'),
Cell('PULLUP'),
Cell('RIU_OR'),
Cell('RX_BITSLICE'),
Cell('RXTX_BITSLICE'),
Cell('TX_BITSLICE'),
Cell('TX_BITSLICE_TRI'),
# Registers.
# Cell('FDCE'),
# Cell('FDPE'),
# Cell('FDRE'),
# Cell('FDSE'),
Cell('HARD_SYNC', port_attrs={'CLK': ['clkbuf_sink']}),
Cell('IDDRE1', port_attrs={'C': ['clkbuf_sink'], 'CB': ['clkbuf_sink']}),
Cell('LDCE'),
Cell('LDPE'),
Cell('ODDRE1', port_attrs={'C': ['clkbuf_sink']}),
# NOTE: not in the official library guide!
Cell('PS8', keep=True),
]
class State(Enum):
OUTSIDE = auto()
IN_MODULE = auto()
IN_OTHER_MODULE = auto()
IN_FUNCTION = auto()
IN_TASK = auto()
def xtract_cell_decl(cell, dirs, outf):
for dir in dirs:
fname = os.path.join(dir, cell.name + '.v')
try:
with open(fname) as f:
state = State.OUTSIDE
found = False
# Probably the most horrible Verilog "parser" ever written.
module_ports = []
invertible_ports = set()
for l in f:
l = l.partition('//')[0]
l = l.strip()
if l == 'module {}'.format(cell.name) or l.startswith('module {} '.format(cell.name)):
if found:
print('Multiple modules in {}.'.format(fname))
sys.exit(1)
elif state != State.OUTSIDE:
print('Nested modules in {}.'.format(fname))
sys.exit(1)
found = True
state = State.IN_MODULE
if cell.keep:
outf.write('(* keep *)\n')
outf.write('module {} (...);\n'.format(cell.name))
elif l.startswith('module '):
if state != State.OUTSIDE:
print('Nested modules in {}.'.format(fname))
sys.exit(1)
state = State.IN_OTHER_MODULE
elif l.startswith('task '):
if state == State.IN_MODULE:
state = State.IN_TASK
elif l.startswith('function '):
if state == State.IN_MODULE:
state = State.IN_FUNCTION
elif l == 'endtask':
if state == State.IN_TASK:
state = State.IN_MODULE
elif l == 'endfunction':
if state == State.IN_FUNCTION:
state = State.IN_MODULE
elif l == 'endmodule':
if state == State.IN_MODULE:
for kind, rng, port in module_ports:
for attr in cell.port_attrs.get(port, []):
outf.write(' (* {} *)\n'.format(attr))
if port in invertible_ports:
outf.write(' (* invertible_pin = "IS_{}_INVERTED" *)\n'.format(port))
if rng is None:
outf.write(' {} {};\n'.format(kind, port))
else:
outf.write(' {} {} {};\n'.format(kind, rng, port))
outf.write(l + '\n')
outf.write('\n')
elif state != State.IN_OTHER_MODULE:
print('endmodule in weird place in {}.'.format(cell.name, fname))
sys.exit(1)
state = State.OUTSIDE
elif l.startswith(('input ', 'output ', 'inout ')) and state == State.IN_MODULE:
if l.endswith((';', ',')):
l = l[:-1]
if ';' in l:
print('Weird port line in {} [{}].'.format(fname, l))
sys.exit(1)
kind, _, ports = l.partition(' ')
for port in ports.split(','):
port = port.strip()
if port.startswith('['):
rng, port = port.split()
else:
rng = None
module_ports.append((kind, rng, port))
elif l.startswith('parameter ') and state == State.IN_MODULE:
if 'UNPLACED' in l:
continue
if l.endswith((';', ',')):
l = l[:-1]
while ' ' in l:
l = l.replace(' ', ' ')
if ';' in l:
print('Weird parameter line in {} [{}].'.format(fname, l))
sys.exit(1)
outf.write(' {};\n'.format(l))
match = re.search('IS_([a-zA-Z0-9_]+)_INVERTED', l)
if match:
invertible_ports.add(match[1])
if state != State.OUTSIDE:
print('endmodule not found in {}.'.format(fname))
sys.exit(1)
if not found:
print('Cannot find module {} in {}.'.format(cell.name, fname))
sys.exit(1)
return
except FileNotFoundError:
continue
print('Cannot find {}.'.format(cell.name))
sys.exit(1)
if __name__ == '__main__':
parser = ArgumentParser(description='Extract Xilinx blackbox cell definitions from ISE and Vivado.')
parser.add_argument('vivado_dir', nargs='?', default='/opt/Xilinx/Vivado/2018.1')
parser.add_argument('ise_dir', nargs='?', default='/opt/Xilinx/ISE/14.7')
args = parser.parse_args()
dirs = [
os.path.join(args.vivado_dir, 'data/verilog/src/xeclib'),
os.path.join(args.vivado_dir, 'data/verilog/src/retarget'),
os.path.join(args.ise_dir, 'ISE_DS/ISE/verilog/xeclib/unisims'),
]
for dir in dirs:
if not os.path.isdir(dir):
print('{} is not a directory'.format(dir))
for ofile, cells in [
('xc6s_cells_xtra.v', XC6S_CELLS),
('xc6v_cells_xtra.v', XC6V_CELLS),
('xc7_cells_xtra.v', XC7_CELLS),
('xcu_cells_xtra.v', XCU_CELLS),
]:
out = StringIO()
for cell in cells:
xtract_cell_decl(cell, dirs, out)
with open(ofile, 'w') as f:
f.write('// Created by cells_xtra.py from Xilinx models\n')
f.write('\n')
f.write(out.getvalue())

View file

@ -1,147 +0,0 @@
#!/bin/bash
set -e
libdir="/opt/Xilinx/Vivado/2018.1/data/verilog/src"
function xtract_cell_decl()
{
for dir in $libdir/xeclib $libdir/retarget; do
[ -f $dir/$1.v ] || continue
[ -z "$2" ] || echo $2
egrep '^\s*((end)?module|parameter|input|inout|output|(end)?function|(end)?task)' $dir/$1.v |
sed -re '/UNPLACED/ d; /^\s*function/,/endfunction/ d; /^\s*task/,/endtask/ d;
s,//.*,,; s/#?\(.*/(...);/; s/^(input|output|parameter)/ \1/;
s/\s+$//; s/,$/;/; /input|output|parameter/ s/[^;]$/&;/; s/\s+/ /g;
s/^ ((end)?module)/\1/; s/^ / /; /module.*_bb/,/endmodule/ d;'
echo; return
done
echo "Can't find $1."
exit 1
}
{
echo "// Created by cells_xtra.sh from Xilinx models"
echo
# Design elements types listed in Xilinx UG953
xtract_cell_decl BSCANE2
# xtract_cell_decl BUFG
xtract_cell_decl BUFGCE
xtract_cell_decl BUFGCE_1
#xtract_cell_decl BUFGCTRL
xtract_cell_decl BUFGMUX
xtract_cell_decl BUFGMUX_1
xtract_cell_decl BUFGMUX_CTRL
xtract_cell_decl BUFH
#xtract_cell_decl BUFHCE
xtract_cell_decl BUFIO
xtract_cell_decl BUFMR
xtract_cell_decl BUFMRCE
xtract_cell_decl BUFR
xtract_cell_decl CAPTUREE2 "(* keep *)"
# xtract_cell_decl CARRY4
xtract_cell_decl CFGLUT5
xtract_cell_decl DCIRESET "(* keep *)"
xtract_cell_decl DNA_PORT
xtract_cell_decl DSP48E1
xtract_cell_decl EFUSE_USR
# xtract_cell_decl FDCE
# xtract_cell_decl FDPE
# xtract_cell_decl FDRE
# xtract_cell_decl FDSE
xtract_cell_decl FIFO18E1
xtract_cell_decl FIFO36E1
xtract_cell_decl FRAME_ECCE2
xtract_cell_decl GTHE2_CHANNEL
xtract_cell_decl GTHE2_COMMON
xtract_cell_decl GTPE2_CHANNEL
xtract_cell_decl GTPE2_COMMON
xtract_cell_decl GTXE2_CHANNEL
xtract_cell_decl GTXE2_COMMON
# xtract_cell_decl IBUF
xtract_cell_decl IBUF_IBUFDISABLE
xtract_cell_decl IBUF_INTERMDISABLE
xtract_cell_decl IBUFDS
xtract_cell_decl IBUFDS_DIFF_OUT
xtract_cell_decl IBUFDS_DIFF_OUT_IBUFDISABLE
xtract_cell_decl IBUFDS_DIFF_OUT_INTERMDISABLE
xtract_cell_decl IBUFDS_GTE2
xtract_cell_decl IBUFDS_IBUFDISABLE
xtract_cell_decl IBUFDS_INTERMDISABLE
xtract_cell_decl ICAPE2 "(* keep *)"
xtract_cell_decl IDDR
xtract_cell_decl IDDR_2CLK
xtract_cell_decl IDELAYCTRL "(* keep *)"
xtract_cell_decl IDELAYE2
xtract_cell_decl IN_FIFO
xtract_cell_decl IOBUF
xtract_cell_decl IOBUF_DCIEN
xtract_cell_decl IOBUF_INTERMDISABLE
xtract_cell_decl IOBUFDS
xtract_cell_decl IOBUFDS_DCIEN
xtract_cell_decl IOBUFDS_DIFF_OUT
xtract_cell_decl IOBUFDS_DIFF_OUT_DCIEN
xtract_cell_decl IOBUFDS_DIFF_OUT_INTERMDISABLE
xtract_cell_decl ISERDESE2
xtract_cell_decl KEEPER
xtract_cell_decl LDCE
xtract_cell_decl LDPE
# xtract_cell_decl LUT1
# xtract_cell_decl LUT2
# xtract_cell_decl LUT3
# xtract_cell_decl LUT4
# xtract_cell_decl LUT5
# xtract_cell_decl LUT6
#xtract_cell_decl LUT6_2
xtract_cell_decl MMCME2_ADV
xtract_cell_decl MMCME2_BASE
# xtract_cell_decl MUXF7
# xtract_cell_decl MUXF8
# xtract_cell_decl OBUF
xtract_cell_decl OBUFDS
xtract_cell_decl OBUFT
xtract_cell_decl OBUFTDS
xtract_cell_decl ODDR
xtract_cell_decl ODELAYE2
xtract_cell_decl OSERDESE2
xtract_cell_decl OUT_FIFO
xtract_cell_decl PHASER_IN
xtract_cell_decl PHASER_IN_PHY
xtract_cell_decl PHASER_OUT
xtract_cell_decl PHASER_OUT_PHY
xtract_cell_decl PHASER_REF
xtract_cell_decl PHY_CONTROL
xtract_cell_decl PLLE2_ADV
xtract_cell_decl PLLE2_BASE
xtract_cell_decl PS7 "(* keep *)"
xtract_cell_decl PULLDOWN
xtract_cell_decl PULLUP
#xtract_cell_decl RAM128X1D
xtract_cell_decl RAM128X1S
xtract_cell_decl RAM256X1S
xtract_cell_decl RAM32M
#xtract_cell_decl RAM32X1D
xtract_cell_decl RAM32X1S
xtract_cell_decl RAM32X1S_1
xtract_cell_decl RAM32X2S
xtract_cell_decl RAM64M
#xtract_cell_decl RAM64X1D
xtract_cell_decl RAM64X1S
xtract_cell_decl RAM64X1S_1
xtract_cell_decl RAM64X2S
# xtract_cell_decl RAMB18E1
# xtract_cell_decl RAMB36E1
xtract_cell_decl ROM128X1
xtract_cell_decl ROM256X1
xtract_cell_decl ROM32X1
xtract_cell_decl ROM64X1
#xtract_cell_decl SRL16E
#xtract_cell_decl SRLC32E
xtract_cell_decl STARTUPE2 "(* keep *)"
xtract_cell_decl USR_ACCESSE2
xtract_cell_decl XADC
} > cells_xtra.new
mv cells_xtra.new cells_xtra.v
exit 0

View file

@ -1,42 +0,0 @@
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
*
* 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.
*
*/
// ============================================================================
// FF mapping
`ifndef _NO_FFS
module \$_DFF_N_ (input D, C, output Q); FDRE_1 #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0)); endmodule
module \$_DFF_P_ (input D, C, output Q); FDRE #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0)); endmodule
module \$_DFFE_NP_ (input D, C, E, output Q); FDRE_1 #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R(1'b0)); endmodule
module \$_DFFE_PP_ (input D, C, E, output Q); FDRE #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R(1'b0)); endmodule
module \$_DFF_NN0_ (input D, C, R, output Q); FDCE_1 #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR(!R)); endmodule
module \$_DFF_NP0_ (input D, C, R, output Q); FDCE_1 #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R)); endmodule
module \$_DFF_PN0_ (input D, C, R, output Q); FDCE #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR(!R)); endmodule
module \$_DFF_PP0_ (input D, C, R, output Q); FDCE #(.INIT(|0)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R)); endmodule
module \$_DFF_NN1_ (input D, C, R, output Q); FDPE_1 #(.INIT(|1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE(!R)); endmodule
module \$_DFF_NP1_ (input D, C, R, output Q); FDPE_1 #(.INIT(|1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R)); endmodule
module \$_DFF_PN1_ (input D, C, R, output Q); FDPE #(.INIT(|1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE(!R)); endmodule
module \$_DFF_PP1_ (input D, C, R, output Q); FDPE #(.INIT(|1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R)); endmodule
`endif

View file

@ -46,7 +46,7 @@ struct SynthXilinxPass : public ScriptPass
log(" -top <module>\n");
log(" use the specified module as top module\n");
log("\n");
log(" -family {xcup|xcu|xc7|xc6s}\n");
log(" -family {xcup|xcu|xc7|xc6v|xc6s}\n");
log(" run synthesis for the specified Xilinx architecture\n");
log(" generate the synthesis netlist for the specified family.\n");
log(" default: xc7\n");
@ -63,6 +63,9 @@ struct SynthXilinxPass : public ScriptPass
log(" generate an output netlist (and BLIF file) suitable for VPR\n");
log(" (this feature is experimental and incomplete)\n");
log("\n");
log(" -ise\n");
log(" generate an output netlist suitable for ISE (enables -iopad)\n");
log("\n");
log(" -nobram\n");
log(" do not use block RAM cells in output netlist\n");
log("\n");
@ -78,6 +81,15 @@ struct SynthXilinxPass : public ScriptPass
log(" -nowidelut\n");
log(" do not use MUXF[78] resources to implement LUTs larger than LUT6s\n");
log("\n");
log(" -iopad\n");
log(" enable I/O buffer insertion (selected automatically by -ise)\n");
log("\n");
log(" -noiopad\n");
log(" disable I/O buffer insertion (only useful with -ise)\n");
log("\n");
log(" -noclkbuf\n");
log(" disable automatic clock buffer insertion\n");
log("\n");
log(" -widemux <int>\n");
log(" enable inference of hard multiplexer resources (MUXF[78]) for muxes at or\n");
log(" above this number of inputs (minimum value 2, recommended value >= 5).\n");
@ -104,7 +116,8 @@ struct SynthXilinxPass : public ScriptPass
}
std::string top_opt, edif_file, blif_file, family;
bool flatten, retime, vpr, nobram, nolutram, nosrl, nocarry, nowidelut, abc9;
bool flatten, retime, vpr, ise, iopad, noiopad, noclkbuf, nobram, nolutram, nosrl, nocarry, nowidelut, abc9;
bool flatten_before_abc;
int widemux;
void clear_flags() YS_OVERRIDE
@ -116,6 +129,10 @@ struct SynthXilinxPass : public ScriptPass
flatten = false;
retime = false;
vpr = false;
ise = false;
iopad = false;
noiopad = false;
noclkbuf = false;
nocarry = false;
nobram = false;
nolutram = false;
@ -123,6 +140,7 @@ struct SynthXilinxPass : public ScriptPass
nocarry = false;
nowidelut = false;
abc9 = false;
flatten_before_abc = false;
widemux = 0;
}
@ -162,6 +180,10 @@ struct SynthXilinxPass : public ScriptPass
flatten = true;
continue;
}
if (args[argidx] == "-flatten_before_abc") {
flatten_before_abc = true;
continue;
}
if (args[argidx] == "-retime") {
retime = true;
continue;
@ -178,6 +200,22 @@ struct SynthXilinxPass : public ScriptPass
vpr = true;
continue;
}
if (args[argidx] == "-ise") {
ise = true;
continue;
}
if (args[argidx] == "-iopad") {
iopad = true;
continue;
}
if (args[argidx] == "-noiopad") {
noiopad = true;
continue;
}
if (args[argidx] == "-noclkbuf") {
noclkbuf = true;
continue;
}
if (args[argidx] == "-nocarry") {
nocarry = true;
continue;
@ -206,7 +244,7 @@ struct SynthXilinxPass : public ScriptPass
}
extra_args(args, argidx, design);
if (family != "xcup" && family != "xcu" && family != "xc7" && family != "xc6s")
if (family != "xcup" && family != "xcu" && family != "xc7" && family != "xc6v" && family != "xc6s")
log_cmd_error("Invalid Xilinx -family setting: '%s'.\n", family.c_str());
if (widemux != 0 && widemux < 2)
@ -228,19 +266,36 @@ struct SynthXilinxPass : public ScriptPass
void script() YS_OVERRIDE
{
std::string ff_map_file;
if (help_mode)
ff_map_file = "+/xilinx/{family}_ff_map.v";
else if (family == "xc6s")
ff_map_file = "+/xilinx/xc6s_ff_map.v";
else
ff_map_file = "+/xilinx/xc7_ff_map.v";
if (check_label("begin")) {
if (vpr)
run("read_verilog -lib -D_EXPLICIT_CARRY +/xilinx/cells_sim.v");
else
run("read_verilog -lib +/xilinx/cells_sim.v");
run("read_verilog -lib +/xilinx/cells_xtra.v");
if (help_mode)
run("read_verilog -lib +/xilinx/{family}_cells_xtra.v");
else if (family == "xc6s")
run("read_verilog -lib +/xilinx/xc6s_cells_xtra.v");
else if (family == "xc6v")
run("read_verilog -lib +/xilinx/xc6v_cells_xtra.v");
else if (family == "xc7")
run("read_verilog -lib +/xilinx/xc7_cells_xtra.v");
else if (family == "xcu" || family == "xcup")
run("read_verilog -lib +/xilinx/xcu_cells_xtra.v");
if (help_mode) {
run("read_verilog -lib +/xilinx/{family}_brams_bb.v");
} else if (family == "xc6s") {
run("read_verilog -lib +/xilinx/xc6s_brams_bb.v");
} else if (family == "xc7") {
} else if (family == "xc6v" || family == "xc7") {
run("read_verilog -lib +/xilinx/xc7_brams_bb.v");
}
@ -265,9 +320,8 @@ struct SynthXilinxPass : public ScriptPass
if (widemux > 0 || help_mode)
run("muxpack", " ('-widemux' only)");
// shregmap -tech xilinx can cope with $shiftx and $mux
// cells for identifying variable-length shift registers,
// so attempt to convert $pmux-es to the former
// xilinx_srl looks for $shiftx cells for identifying variable-length
// shift registers, so attempt to convert $pmux-es to this
// Also: wide multiplexer inference benefits from this too
if (!(nosrl && widemux == 0) || help_mode) {
run("pmux2shiftx", "(skip if '-nosrl' and '-widemux=0')");
@ -292,7 +346,7 @@ struct SynthXilinxPass : public ScriptPass
if (family == "xc6s") {
run("memory_bram -rules +/xilinx/xc6s_brams.txt");
run("techmap -map +/xilinx/xc6s_brams_map.v");
} else if (family == "xc7") {
} else if (family == "xc6v" || family == "xc7") {
run("memory_bram -rules +/xilinx/xc7_brams.txt");
run("techmap -map +/xilinx/xc7_brams_map.v");
} else {
@ -349,13 +403,8 @@ struct SynthXilinxPass : public ScriptPass
}
run("opt -full");
if (!nosrl || help_mode) {
// shregmap operates on bit-level flops, not word-level,
// so break those down here
run("simplemap t:$dff t:$dffe", " (skip if '-nosrl')");
// shregmap with '-tech xilinx' infers variable length shift regs
run("shregmap -tech xilinx -minlen 3", "(skip if '-nosrl')");
}
if (!nosrl || help_mode)
run("xilinx_srl -variable -minlen 3", "(skip if '-nosrl')");
std::string techmap_args = " -map +/techmap.v";
if (help_mode)
@ -379,21 +428,27 @@ struct SynthXilinxPass : public ScriptPass
std::string techmap_args = "-map +/techmap.v -map +/xilinx/cells_map.v";
if (widemux > 0)
techmap_args += stringf(" -D MIN_MUX_INPUTS=%d", widemux);
if (abc9)
techmap_args += " -map +/xilinx/ff_map.v";
run("techmap " + techmap_args);
run("clean");
}
if (check_label("map_ffs")) {
if (abc9 || help_mode) {
run("techmap -map " + ff_map_file, "('-abc9' only)");
}
}
if (check_label("map_luts")) {
run("opt_expr -mux_undef");
if (flatten_before_abc)
run("flatten");
if (help_mode)
run("abc -luts 2:2,3,6:5[,10,20] [-dff]", "(option for 'nowidelut', option for '-retime')");
run("abc -luts 2:2,3,6:5[,10,20] [-dff]", "(option for 'nowidelut'; option for '-retime')");
else if (abc9) {
if (family != "xc7")
log_warning("'synth_xilinx -abc9' currently supports '-family xc7' only.\n");
run("techmap -map +/xilinx/abc_map.v -max_iter 1");
run("read_verilog -icells -lib +/xilinx/abc_model.v");
run("techmap -map +/xilinx/abc_map.v");
if (nowidelut)
run("abc9 -lut +/xilinx/abc_xc7_nowide.lut -box +/xilinx/abc_xc7.box -W " + std::to_string(XC7_WIRE_DELAY));
else
@ -410,18 +465,32 @@ struct SynthXilinxPass : public ScriptPass
// This shregmap call infers fixed length shift registers after abc
// has performed any necessary retiming
if (!nosrl || help_mode)
run("shregmap -minlen 3 -init -params -enpol any_or_none", "(skip if '-nosrl')");
std::string techmap_args = "-map +/xilinx/lut_map.v";
if (abc9)
run("xilinx_srl -fixed -minlen 3", "(skip if '-nosrl')");
std::string techmap_args = "-map +/xilinx/lut_map.v -map +/xilinx/cells_map.v";
if (help_mode)
techmap_args += " [-map " + ff_map_file + "]";
else if (abc9)
techmap_args += " -map +/xilinx/abc_unmap.v";
else
techmap_args += " -map +/xilinx/ff_map.v";
techmap_args += " -map " + ff_map_file;
run("techmap " + techmap_args);
run("dffinit -ff FDRE Q INIT -ff FDCE Q INIT -ff FDPE Q INIT -ff FDSE Q INIT "
"-ff FDRE_1 Q INIT -ff FDCE_1 Q INIT -ff FDPE_1 Q INIT -ff FDSE_1 Q INIT");
run("clean");
}
if (check_label("finalize")) {
bool do_iopad = iopad || (ise && !noiopad);
if (help_mode || !noclkbuf) {
if (help_mode || do_iopad)
run("clkbufmap -buf BUFG O:I -inpad IBUFG O:I", "(skip if '-noclkbuf', '-inpad' passed if '-iopad' or '-ise' and not '-noiopad')");
else
run("clkbufmap -buf BUFG O:I");
}
if (help_mode || do_iopad)
run("iopadmap -bits -outpad OBUF I:O -inpad IBUF O:I A:top", "(only if '-iopad' or '-ise' and not '-noiopad')");
if (help_mode || ise)
run("extractinv -inv INV O:I", "(only if '-ise')");
}
if (check_label("check")) {
run("hierarchy -check");
run("stat -tech xilinx");

View file

@ -1,5 +1,7 @@
module RAMB8BWER (
(* clkbuf_sink *)
input CLKAWRCLK,
(* clkbuf_sink *)
input CLKBRDCLK,
input ENAWREN,
input ENBRDEN,
@ -87,7 +89,9 @@ module RAMB8BWER (
endmodule
module RAMB16BWER (
(* clkbuf_sink *)
input CLKA,
(* clkbuf_sink *)
input CLKB,
input ENA,
input ENB,

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,126 @@
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
*
* 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.
*
*/
// ============================================================================
// FF mapping
`ifndef _NO_FFS
module \$_DFF_N_ (input D, C, output Q);
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
FDSE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .S(1'b0));
else
FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0));
endgenerate
endmodule
module \$_DFF_P_ (input D, C, output Q);
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
FDSE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .S(1'b0));
else
FDRE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0));
endgenerate
endmodule
module \$_DFFE_NP_ (input D, C, E, output Q);
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
FDSE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .S(1'b0));
else
FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R(1'b0));
endgenerate
endmodule
module \$_DFFE_PP_ (input D, C, E, output Q);
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
FDSE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .S(1'b0));
else
FDRE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R(1'b0));
endgenerate
endmodule
module \$_DFF_NN0_ (input D, C, R, output Q);
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
$error("Spartan 6 doesn't support FFs with asynchronous reset initialized to 1");
else
FDCE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR(!R));
endgenerate
endmodule
module \$_DFF_NP0_ (input D, C, R, output Q);
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
$error("Spartan 6 doesn't support FFs with asynchronous reset initialized to 1");
else
FDCE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R));
endgenerate
endmodule
module \$_DFF_PN0_ (input D, C, R, output Q);
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
$error("Spartan 6 doesn't support FFs with asynchronous reset initialized to 1");
else
FDCE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR(!R));
endgenerate
endmodule
module \$_DFF_PP0_ (input D, C, R, output Q);
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
generate if (_TECHMAP_WIREINIT_Q_ === 1'b1)
$error("Spartan 6 doesn't support FFs with asynchronous reset initialized to 1");
else
FDCE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R));
endgenerate
endmodule
module \$_DFF_NN1_ (input D, C, R, output Q);
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
generate if (_TECHMAP_WIREINIT_Q_ === 1'b0)
$error("Spartan 6 doesn't support FFs with asynchronous set initialized to 0");
else
FDPE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE(!R));
endgenerate
endmodule
module \$_DFF_NP1_ (input D, C, R, output Q);
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
generate if (_TECHMAP_WIREINIT_Q_ === 1'b0)
$error("Spartan 6 doesn't support FFs with asynchronous set initialized to 0");
else
FDPE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R));
endgenerate
endmodule
module \$_DFF_PN1_ (input D, C, R, output Q);
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
generate if (_TECHMAP_WIREINIT_Q_ === 1'b0)
$error("Spartan 6 doesn't support FFs with asynchronous set initialized to 0");
else
FDPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE(!R));
endgenerate
endmodule
module \$_DFF_PP1_ (input D, C, R, output Q);
parameter [0:0] _TECHMAP_WIREINIT_Q_ = 1'bx;
generate if (_TECHMAP_WIREINIT_Q_ === 1'b0)
$error("Spartan 6 doesn't support FFs with asynchronous set initialized to 0");
else
FDPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R));
endgenerate
endmodule
`endif

File diff suppressed because it is too large Load diff

View file

@ -1,15 +1,25 @@
// Max delays from https://github.com/SymbiFlow/prjxray-db/blob/f8e0364116b2983ac72a3dc8c509ea1cc79e2e3d/artix7/timings/BRAM_L.sdf#L138-L147
module RAMB18E1 (
(* clkbuf_sink *)
(* invertible_pin = "IS_CLKARDCLK_INVERTED" *)
input CLKARDCLK,
(* clkbuf_sink *)
(* invertible_pin = "IS_CLKBWRCLK_INVERTED" *)
input CLKBWRCLK,
(* invertible_pin = "IS_ENARDEN_INVERTED" *)
input ENARDEN,
(* invertible_pin = "IS_ENBWREN_INVERTED" *)
input ENBWREN,
input REGCEAREGCE,
input REGCEB,
(* invertible_pin = "IS_RSTRAMARSTRAM_INVERTED" *)
input RSTRAMARSTRAM,
(* invertible_pin = "IS_RSTRAMB_INVERTED" *)
input RSTRAMB,
(* invertible_pin = "IS_RSTREGARSTREG_INVERTED" *)
input RSTREGARSTREG,
(* invertible_pin = "IS_RSTREGB_INVERTED" *)
input RSTREGB,
input [13:0] ADDRARDADDR,
@ -21,10 +31,14 @@ module RAMB18E1 (
input [1:0] WEA,
input [3:0] WEBWE,
(* abc_arrival=2454 *) output [15:0] DOADO,
(* abc_arrival=2454 *) output [15:0] DOBDO,
(* abc_arrival=2454 *) output [1:0] DOPADOP,
(* abc_arrival=2454 *) output [1:0] DOPBDOP
(* abc_arrival=2454 *)
output [15:0] DOADO,
(* abc_arrival=2454 *)
output [15:0] DOBDO,
(* abc_arrival=2454 *)
output [1:0] DOPADOP,
(* abc_arrival=2454 *)
output [1:0] DOPBDOP
);
parameter INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INITP_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
@ -125,15 +139,25 @@ module RAMB18E1 (
endmodule
module RAMB36E1 (
(* clkbuf_sink *)
(* invertible_pin = "IS_CLKARDCLK_INVERTED" *)
input CLKARDCLK,
(* clkbuf_sink *)
(* invertible_pin = "IS_CLKBWRCLK_INVERTED" *)
input CLKBWRCLK,
(* invertible_pin = "IS_ENARDEN_INVERTED" *)
input ENARDEN,
(* invertible_pin = "IS_ENBWREN_INVERTED" *)
input ENBWREN,
input REGCEAREGCE,
input REGCEB,
(* invertible_pin = "IS_RSTRAMARSTRAM_INVERTED" *)
input RSTRAMARSTRAM,
(* invertible_pin = "IS_RSTRAMB_INVERTED" *)
input RSTRAMB,
(* invertible_pin = "IS_RSTREGARSTREG_INVERTED" *)
input RSTREGARSTREG,
(* invertible_pin = "IS_RSTREGB_INVERTED" *)
input RSTREGB,
input [15:0] ADDRARDADDR,
@ -145,10 +169,14 @@ module RAMB36E1 (
input [3:0] WEA,
input [7:0] WEBWE,
(* abc_arrival=2454 *) output [31:0] DOADO,
(* abc_arrival=2454 *) output [31:0] DOBDO,
(* abc_arrival=2454 *) output [3:0] DOPADOP,
(* abc_arrival=2454 *) output [3:0] DOPBDOP
(* abc_arrival=2454 *)
output [31:0] DOADO,
(* abc_arrival=2454 *)
output [31:0] DOBDO,
(* abc_arrival=2454 *)
output [3:0] DOPADOP,
(* abc_arrival=2454 *)
output [3:0] DOPBDOP
);
parameter INITP_00 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
parameter INITP_01 = 256'h0000000000000000000000000000000000000000000000000000000000000000;

View file

@ -0,0 +1,78 @@
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2012 Clifford Wolf <clifford@clifford.at>
*
* 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.
*
*/
// ============================================================================
// FF mapping
`ifndef _NO_FFS
module \$_DFF_N_ (input D, C, output Q);
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0));
endmodule
module \$_DFF_P_ (input D, C, output Q);
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
FDRE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .R(1'b0));
endmodule
module \$_DFFE_NP_ (input D, C, E, output Q);
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
FDRE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R(1'b0));
endmodule
module \$_DFFE_PP_ (input D, C, E, output Q);
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
FDRE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R(1'b0));
endmodule
module \$_DFF_NN0_ (input D, C, R, output Q);
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
FDCE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR(!R));
endmodule
module \$_DFF_NP0_ (input D, C, R, output Q);
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
FDCE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R));
endmodule
module \$_DFF_PN0_ (input D, C, R, output Q);
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
FDCE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR(!R));
endmodule
module \$_DFF_PP0_ (input D, C, R, output Q);
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
FDCE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .CLR( R));
endmodule
module \$_DFF_NN1_ (input D, C, R, output Q);
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
FDPE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE(!R));
endmodule
module \$_DFF_NP1_ (input D, C, R, output Q);
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
FDPE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R));
endmodule
module \$_DFF_PN1_ (input D, C, R, output Q);
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
FDPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE(!R));
endmodule
module \$_DFF_PP1_ (input D, C, R, output Q);
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
FDPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(1'b1), .PRE( R));
endmodule
`endif

File diff suppressed because it is too large Load diff