3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-07-30 16:03:17 +00:00

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

This commit is contained in:
Eddie Hung 2019-07-01 10:44:42 -07:00
commit 699d8e3939
92 changed files with 3035 additions and 853 deletions

View file

@ -13,6 +13,7 @@ $(eval $(call add_share_file,share/ecp5,techlibs/ecp5/latches_map.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))
EXTRA_OBJS += techlibs/ecp5/brams_init.mk techlibs/ecp5/brams_connect.mk
.SECONDARY: techlibs/ecp5/brams_init.mk techlibs/ecp5/brams_connect.mk

View file

@ -1,5 +1,12 @@
# NB: Inputs/Outputs must be ordered alphabetically
# (with exceptions for carry in/out)
# Box 1 : CCU2C (2xCARRY + 2xLUT4)
# Outputs: S0, S1, COUT
# (NB: carry chain input/output must be last
# input/output and bus has been moved
# there overriding the otherwise
# alphabetical ordering)
# name ID w/b ins outs
CCU2C 1 1 9 3
@ -9,7 +16,7 @@ CCU2C 1 1 9 3
516 516 516 516 412 412 278 278 43
# Box 2 : TRELLIS_DPR16X4 (16x4 dist ram)
# Outputs: DO0, DO1, DO2, DO3, DO4
# Outputs: DO0, DO1, DO2, DO3
# name ID w/b ins outs
TRELLIS_DPR16X4 2 0 14 4

View file

@ -0,0 +1,12 @@
# ECP5-5G LUT library for ABC
# Note that ECP5 architecture assigns difference
# in LUT input delay to interconnect, so this is
# considered too
# Simple LUTs
# area D C B A
1 1 141
2 1 141 275
3 1 141 275 379
4 1 141 275 379 379

View file

@ -50,20 +50,21 @@ module _80_ecp5_alu (A, B, CI, BI, X, Y, CO);
wire [Y_WIDTH2-1:0] AA = A_buf;
wire [Y_WIDTH2-1:0] BB = BI ? ~B_buf : B_buf;
wire [Y_WIDTH2-1:0] BX = B_buf;
wire [Y_WIDTH2-1:0] C = {CO, CI};
wire [Y_WIDTH2-1:0] FCO, Y1;
genvar i;
generate for (i = 0; i < Y_WIDTH2; i = i + 2) begin:slice
CCU2C #(
.INIT0(16'b0110011010101010),
.INIT1(16'b0110011010101010),
.INIT0(16'b1001011010101010),
.INIT1(16'b1001011010101010),
.INJECT1_0("NO"),
.INJECT1_1("NO")
) ccu2c_i (
.CIN(C[i]),
.A0(AA[i]), .B0(BB[i]), .C0(1'b0), .D0(1'b1),
.A1(AA[i+1]), .B1(BB[i+1]), .C1(1'b0), .D1(1'b1),
.A0(AA[i]), .B0(BX[i]), .C0(BI), .D0(1'b1),
.A1(AA[i+1]), .B1(BX[i+1]), .C1(BI), .D1(1'b1),
.S0(Y[i]), .S1(Y1[i]),
.COUT(FCO[i])
);

View file

@ -47,6 +47,28 @@ module \$__DFFSE_NP1 (input D, C, E, R, output Q); TRELLIS_FF #(.GSR("DISABLED"
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
// 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
@ -62,14 +84,30 @@ module BBPD (input I, T, output O, inout B); (* PULLMODE="DOWN" *) TRELLIS_IO #(
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
// For Diamond compatibility, FIXME: add all Diamond flipflop mappings
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
// 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
`ifndef NO_LUT
module \$lut (A, Y);
parameter WIDTH = 0;
parameter LUT = 0;
input [WIDTH-1:0] A;
output Y;
// Need to swap input ordering, and fix init accordingly,
// to match ABC's expectation of LUT inputs in non-decreasing
@ -86,19 +124,15 @@ module \$lut (A, Y);
endfunction
function [2**P_WIDTH-1:0] permute_init;
input [2**P_WIDTH-1:0] orig;
integer i;
begin
permute_init = 0;
for (i = 0; i < 2**P_WIDTH; i = i + 1)
permute_init[i] = orig[permute_index(i)];
permute_init[i] = LUT[permute_index(i)];
end
endfunction
parameter [2**P_WIDTH-1:0] P_LUT = permute_init(LUT);
input [WIDTH-1:0] A;
output Y;
parameter [2**P_WIDTH-1:0] P_LUT = permute_init();
generate
if (WIDTH == 1) begin

View file

@ -15,11 +15,9 @@ module L6MUX21 (input D0, D1, SD, output Z);
endmodule
// ---------------------------------------
(* abc_box_id=1, abc_carry, lib_whitebox *)
module CCU2C((* abc_carry_in *) input CIN,
input A0, B0, C0, D0, A1, B1, C1, D1,
output S0, S1,
(* abc_carry_out *) output COUT);
(* abc_box_id=1, abc_carry="CIN,COUT", lib_whitebox *)
module CCU2C(input CIN, A0, B0, C0, D0, A1, B1, C1, D1,
output S0, S1, COUT);
parameter [15:0] INIT0 = 16'h0000;
parameter [15:0] INIT1 = 16'h0000;
@ -106,7 +104,7 @@ module PFUMX (input ALUT, BLUT, C0, output Z);
endmodule
// ---------------------------------------
//(* abc_box_id=2 *)
//(* abc_box_id=2, abc_scc_break="DI,WAD,WRE" *)
module TRELLIS_DPR16X4 (
input [3:0] DI,
input [3:0] WAD,
@ -260,18 +258,6 @@ module TRELLIS_FF(input CLK, LSR, CE, DI, M, output reg Q);
endgenerate
endmodule
// ---------------------------------------
module OBZ(input I, T, output O);
assign O = T ? 1'bz : I;
endmodule
// ---------------------------------------
module IB(input I, output O);
assign O = I;
endmodule
// ---------------------------------------
(* keep *)
module TRELLIS_IO(
@ -303,19 +289,6 @@ endmodule
// ---------------------------------------
module OB(input I, output O);
assign O = I;
endmodule
// ---------------------------------------
module BB(input I, T, output O, inout B);
assign B = T ? 1'bz : I;
assign O = B;
endmodule
// ---------------------------------------
module INV(input A, output Z);
assign Z = !A;
endmodule
@ -568,19 +541,56 @@ module DP16KD(
parameter INITVAL_3F = 320'h00000000000000000000000000000000000000000000000000000000000000000000000000000000;
endmodule
// For Diamond compatibility, FIXME: add all Diamond flipflop mappings
module FD1S3BX(input PD, D, CK, output Q);
TRELLIS_FF #(
.GSR("DISABLED"),
.CEMUX("1"),
.CLKMUX("CLK"),
.LSRMUX("LSR"),
.REGSET("SET"),
.SRMODE("ASYNC")
) tff_i (
.CLK(CK),
.LSR(PD),
.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")) 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
// 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
// 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

View file

@ -76,7 +76,7 @@ struct SynthEcp5Pass : public ScriptPass
log(" -nodram\n");
log(" do not use distributed RAM cells in output netlist\n");
log("\n");
log(" -nomux\n");
log(" -nowidelut\n");
log(" do not use PFU muxes to implement LUTs larger than LUT4s\n");
log("\n");
log(" -abc2\n");
@ -96,7 +96,7 @@ struct SynthEcp5Pass : public ScriptPass
}
string top_opt, blif_file, edif_file, json_file;
bool noccu2, nodffe, nobram, nodram, nomux, flatten, retime, abc2, abc9, vpr;
bool noccu2, nodffe, nobram, nodram, nowidelut, flatten, retime, abc2, abc9, vpr;
void clear_flags() YS_OVERRIDE
{
@ -108,7 +108,7 @@ struct SynthEcp5Pass : public ScriptPass
nodffe = false;
nobram = false;
nodram = false;
nomux = false;
nowidelut = false;
flatten = true;
retime = false;
abc2 = false;
@ -176,8 +176,8 @@ struct SynthEcp5Pass : public ScriptPass
nodram = true;
continue;
}
if (args[argidx] == "-nomux") {
nomux = true;
if (args[argidx] == "-nowidelut" || args[argidx] == "-nomux") {
nowidelut = true;
continue;
}
if (args[argidx] == "-abc2") {
@ -273,14 +273,16 @@ struct SynthEcp5Pass : public ScriptPass
}
run("techmap -map +/ecp5/latches_map.v");
if (abc9) {
run("abc9 -lut +/ecp5/abc_5g.lut -box +/ecp5/abc_5g.box -W 200");
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");
} else {
if (nomux)
if (nowidelut)
run("abc -lut 4 -dress");
else
run("abc -lut 4:7 -dress");
}
run("clean");
}

View file

@ -1,113 +1,17 @@
# From https://github.com/cliffordwolf/icestorm/blob/be0bca0/icefuzz/timings_hx8k.txt
# NB: Inputs/Outputs must be ordered alphabetically
# (with exceptions for carry in/out)
# Inputs: C D
# Outputs: Q
SB_DFF 1 0 2 1
- -
# Inputs: C D E
# Outputs: Q
SB_DFFE 2 0 3 1
- - -
# Inputs: C D R
# Outputs: Q
SB_DFFSR 3 0 3 1
- - -
# Inputs: C D R
# Outputs: Q
SB_DFFR 4 0 3 1
- - -
# Inputs: C D S
# Outputs: Q
SB_DFFSS 5 0 3 1
- - -
# Inputs: C D S
# Outputs: Q
SB_DFFS 6 0 3 1
- - -
# Inputs: C D E R
# Outputs: Q
SB_DFFESR 7 0 4 1
- - - -
# Inputs: C D E R
# Outputs: Q
SB_DFFER 8 0 4 1
- - - -
# Inputs: C D E S
# Outputs: Q
SB_DFFESS 9 0 4 1
- - - -
# Inputs: C D E S
# Outputs: Q
SB_DFFES 10 0 4 1
- - - -
# Inputs: C D
# Outputs: Q
SB_DFFN 11 0 2 1
- -
# Inputs: C D E
# Outputs: Q
SB_DFFNE 12 0 3 1
- - -
# Inputs: C D R
# Outputs: Q
SB_DFFNSR 13 0 3 1
- - -
# Inputs: C D R
# Outputs: Q
SB_DFFNR 14 0 3 1
- - -
# Inputs: C D S
# Outputs: Q
SB_DFFNSS 15 0 3 1
- - -
# Inputs: C D S
# Outputs: Q
SB_DFFNS 16 0 3 1
- - -
# Inputs: C D E R
# Outputs: Q
SB_DFFNESR 17 0 4 1
- - - -
# Inputs: C D E R
# Outputs: Q
SB_DFFNER 18 0 4 1
- - - -
# Inputs: C D E S
# Outputs: Q
SB_DFFNESS 19 0 4 1
- - - -
# Inputs: C D E S
# Outputs: Q
SB_DFFNES 20 0 4 1
- - - -
# Inputs: CI I0 I1
# Inputs: I0 I1 CI
# Outputs: CO
SB_CARRY 21 1 3 1
126 259 231
# (NB: carry chain input/output must be last
# input/output and have been moved there
# overriding the alphabetical ordering)
SB_CARRY 1 1 3 1
259 231 126
# Inputs: I0 I1 I2 I3
# Outputs: O
SB_LUT4 22 1 4 1
SB_LUT4 2 1 4 1
449 400 379 316

View file

@ -1,113 +1,17 @@
# From https://github.com/cliffordwolf/icestorm/blob/be0bca0/icefuzz/timings_lp8k.txt
# NB: Inputs/Outputs must be ordered alphabetically
# Inputs: C D
# Outputs: Q
SB_DFF 1 0 2 1
- -
# Inputs: C D E
# Outputs: Q
SB_DFFE 2 0 3 1
- - -
# Inputs: C D R
# Outputs: Q
SB_DFFSR 3 0 3 1
- - -
# Inputs: C D R
# Outputs: Q
SB_DFFR 4 0 3 1
- - -
# Inputs: C D S
# Outputs: Q
SB_DFFSS 5 0 3 1
- - -
# Inputs: C D S
# Outputs: Q
SB_DFFS 6 0 3 1
- - -
# Inputs: C D E R
# Outputs: Q
SB_DFFESR 7 0 4 1
- - - -
# Inputs: C D E R
# Outputs: Q
SB_DFFER 8 0 4 1
- - - -
# Inputs: C D E S
# Outputs: Q
SB_DFFESS 9 0 4 1
- - - -
# Inputs: C D E S
# Outputs: Q
SB_DFFES 10 0 4 1
- - - -
# Inputs: C D
# Outputs: Q
SB_DFFN 11 0 2 1
- -
# Inputs: C D E
# Outputs: Q
SB_DFFNE 12 0 3 1
- - -
# Inputs: C D R
# Outputs: Q
SB_DFFNSR 13 0 3 1
- - -
# Inputs: C D R
# Outputs: Q
SB_DFFNR 14 0 3 1
- - -
# Inputs: C D S
# Outputs: Q
SB_DFFNSS 15 0 3 1
- - -
# Inputs: C D S
# Outputs: Q
SB_DFFNS 16 0 3 1
- - -
# Inputs: C D E R
# Outputs: Q
SB_DFFNESR 17 0 4 1
- - - -
# Inputs: C D E R
# Outputs: Q
SB_DFFNER 18 0 4 1
- - - -
# Inputs: C D E S
# Outputs: Q
SB_DFFNESS 19 0 4 1
- - - -
# Inputs: C D E S
# Outputs: Q
SB_DFFNES 20 0 4 1
- - - -
# (with exceptions for carry in/out)
# Inputs: CI I0 I1
# Outputs: CO
SB_CARRY 21 1 3 1
186 675 609
# (NB: carry chain input/output must be last
# input/output and have been moved there
# overriding the alphabetical ordering)
SB_CARRY 1 1 3 1
675 609 186
# Inputs: I0 I1 I2 I3
# Outputs: O
SB_LUT4 22 1 4 1
SB_LUT4 2 1 4 1
661 589 558 465

View file

@ -1,113 +1,17 @@
# From https://github.com/cliffordwolf/icestorm/blob/be0bca0/icefuzz/timings_up5k.txt
# NB: Inputs/Outputs must be ordered alphabetically
# (with exceptions for carry in/out)
# Inputs: C D
# Outputs: Q
SB_DFF 1 0 2 1
- -
# Inputs: C D E
# Outputs: Q
SB_DFFE 2 0 3 1
- - -
# Inputs: C D R
# Outputs: Q
SB_DFFSR 3 0 3 1
- - -
# Inputs: C D R
# Outputs: Q
SB_DFFR 4 0 3 1
- - -
# Inputs: C D S
# Outputs: Q
SB_DFFSS 5 0 3 1
- - -
# Inputs: C D S
# Outputs: Q
SB_DFFS 6 0 3 1
- - -
# Inputs: C D E R
# Outputs: Q
SB_DFFESR 7 0 4 1
- - - -
# Inputs: C D E R
# Outputs: Q
SB_DFFER 8 0 4 1
- - - -
# Inputs: C D E S
# Outputs: Q
SB_DFFESS 9 0 4 1
- - - -
# Inputs: C D E S
# Outputs: Q
SB_DFFES 10 0 4 1
- - - -
# Inputs: C D
# Outputs: Q
SB_DFFN 11 0 2 1
- -
# Inputs: C D E
# Outputs: Q
SB_DFFNE 12 0 3 1
- - -
# Inputs: C D R
# Outputs: Q
SB_DFFNSR 13 0 3 1
- - -
# Inputs: C D R
# Outputs: Q
SB_DFFNR 14 0 3 1
- - -
# Inputs: C D S
# Outputs: Q
SB_DFFNSS 15 0 3 1
- - -
# Inputs: C D S
# Outputs: Q
SB_DFFNS 16 0 3 1
- - -
# Inputs: C D E R
# Outputs: Q
SB_DFFNESR 17 0 4 1
- - - -
# Inputs: C D E R
# Outputs: Q
SB_DFFNER 18 0 4 1
- - - -
# Inputs: C D E S
# Outputs: Q
SB_DFFNESS 19 0 4 1
- - - -
# Inputs: C D E S
# Outputs: Q
SB_DFFNES 20 0 4 1
- - - -
# Inputs: CI I0 I1
# Inputs: I0 I1 CI
# Outputs: CO
SB_CARRY 21 1 3 1
278 675 609
# (NB: carry chain input/output must be last
# input/output and have been moved there
# overriding the alphabetical ordering)
SB_CARRY 1 1 3 1
675 609 278
# Inputs: I0 I1 I2 I3
# Outputs: O
SB_LUT4 22 1 4 1
SB_LUT4 2 1 4 1
1285 1231 1205 874

View file

@ -127,7 +127,7 @@ endmodule
// SiliconBlue Logic Cells
(* abc_box_id = 22, lib_whitebox *)
(* abc_box_id = 2, lib_whitebox *)
module SB_LUT4 (output O, input I0, I1, I2, I3);
parameter [15:0] LUT_INIT = 0;
wire [7:0] s3 = I3 ? LUT_INIT[15:8] : LUT_INIT[7:0];
@ -136,20 +136,16 @@ module SB_LUT4 (output O, input I0, I1, I2, I3);
assign O = I0 ? s1[1] : s1[0];
endmodule
(* abc_box_id = 21, abc_carry, lib_whitebox *)
module SB_CARRY ((* abc_carry_out *) output CO, input I0, I1, (* abc_carry_in *) input CI);
(* abc_box_id = 1, abc_carry="CI,CO", lib_whitebox *)
module SB_CARRY (output CO, input I0, I1, CI);
assign CO = (I0 && I1) || ((I0 || I1) && CI);
endmodule
// Positive Edge SiliconBlue FF Cells
module SB_DFF (output `SB_DFF_REG, input C, D);
`ifndef _ABC
always @(posedge C)
Q <= D;
`else
always @* Q <= D;
`endif
endmodule
module SB_DFFE (output `SB_DFF_REG, input C, E, D);
@ -896,7 +892,6 @@ module SB_WARMBOOT (
);
endmodule
(* nomem2reg *)
module SB_SPRAM256KA (
input [13:0] ADDRESS,
input [15:0] DATAIN,

View file

@ -74,7 +74,7 @@ static void run_ice40_unlut(Module *module)
}
struct Ice40UnlutPass : public Pass {
Ice40UnlutPass() : Pass("ice40_unlut", "iCE40: perform simple optimizations") { }
Ice40UnlutPass() : Pass("ice40_unlut", "iCE40: transform SB_LUT4 cells to $lut cells") { }
void help() YS_OVERRIDE
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|

View file

@ -38,8 +38,8 @@ struct SynthIce40Pass : public ScriptPass
log("This command runs synthesis for iCE40 FPGAs.\n");
log("\n");
log(" -device < hx | lp | u >\n");
log(" optimise the synthesis netlist for the specified device.\n");
log(" HX is the default target if no device argument specified.\n");
log(" relevant only for '-abc9' flow, optimise timing for the specified device.\n");
log(" default: hx\n");
log("\n");
log(" -top <module>\n");
log(" use the specified module as top module\n");
@ -105,7 +105,6 @@ struct SynthIce40Pass : public ScriptPass
log("\n");
}
string top_opt, blif_file, edif_file, json_file, abc, device_opt;
bool nocarry, nodffe, nobram, dsp, flatten, retime, relut, noabc, abc2, vpr;
int min_ce_use;
@ -331,8 +330,16 @@ struct SynthIce40Pass : public ScriptPass
run("techmap -map +/gate2lut.v -D LUT_WIDTH=4", "(only if -noabc)");
}
if (!noabc) {
if (abc == "abc9")
run(abc + stringf(" -lut +/ice40/abc_%s.lut -box +/ice40/abc_%s.box", device_opt.c_str(), device_opt.c_str()), "(skip if -noabc)");
if (abc == "abc9") {
int wire_delay;
if (device_opt == "lp")
wire_delay = 400;
else if (device_opt == "u")
wire_delay = 750;
else
wire_delay = 250;
run(abc + stringf(" -W %d -lut +/ice40/abc_%s.lut -box +/ice40/abc_%s.box", wire_delay, device_opt.c_str(), device_opt.c_str()), "(skip if -noabc)");
}
else
run(abc + " -dress -lut 4", "(skip if -noabc)");
}

View file

@ -30,9 +30,11 @@ $(eval $(call add_share_file,share/xilinx,techlibs/xilinx/drams_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/lut_map.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc_ff.v))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc_xc7.box))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc_xc7.lut))
$(eval $(call add_share_file,share/xilinx,techlibs/xilinx/abc_xc7_nowide.lut))
$(eval $(call add_gen_share_file,share/xilinx,techlibs/xilinx/brams_init_36.vh))
$(eval $(call add_gen_share_file,share/xilinx,techlibs/xilinx/brams_init_32.vh))

View file

@ -1,5 +1,8 @@
# Max delays from https://github.com/SymbiFlow/prjxray-db/blob/34ea6eb08a63d21ec16264ad37a0a7b142ff6031/artix7/timings/CLBLL_L.sdf
# NB: Inputs/Outputs must be ordered alphabetically
# (with exceptions for carry in/out)
# F7BMUX slower than F7AMUX
# Inputs: I0 I1 S0
# Outputs: O
@ -12,34 +15,42 @@ MUXF8 2 1 3 1
104 94 273
# CARRY4 + CARRY4_[ABCD]X
# Inputs: S0 S1 S2 S3 CYINIT DI0 DI1 DI2 DI3 CI
# Inputs: CYINIT DI0 DI1 DI2 DI3 S0 S1 S2 S3 CI
# Outputs: O0 O1 O2 O3 CO0 CO1 CO2 CO3
# (NB: carry chain input/output must be last input/output,
# swapped with what normally would have been the last
# output, here: CI <-> S, CO <-> O
# (NB: carry chain input/output must be last
# input/output and the entire bus has been
# moved there overriding the otherwise
# alphabetical ordering)
CARRY4 3 1 10 8
223 - - - 482 - - - - 222
400 205 - - 598 407 - - - 334
523 558 226 - 584 556 537 - - 239
582 618 330 227 642 615 596 438 - 313
340 - - - 536 379 - - - 271
433 469 - - 494 465 445 - - 157
512 548 292 - 592 540 520 356 - 228
508 528 378 380 580 526 507 398 385 114
482 - - - - 223 - - - 222
598 407 - - - 400 205 - - 334
584 556 537 - - 523 558 226 - 239
642 615 596 438 - 582 618 330 227 313
536 379 - - - 340 - - - 271
494 465 445 - - 433 469 - - 157
592 540 520 356 - 512 548 292 - 228
580 526 507 398 385 508 528 378 380 114
# SLICEM/A6LUT
# Inputs: A0 A1 A2 A3 A4 D DPRA0 DPRA1 DPRA2 DPRA3 DPRA4 WCLK WE
# Outputs: DPO SPO
RAM32X1D 4 0 13 2
- - - - - - 631 472 407 238 127 - -
631 472 407 238 127 - - - - - - - -
# SLICEM/A6LUT
# Inputs: A0 A1 A2 A3 A4 A5 D DPRA0 DPRA1 DPRA2 DPRA3 DPRA4 DPRA5 WCLK WE
# Outputs: DPO SPO
RAM64X1D 4 0 15 2
- - - - - - - 124 124 124 124 124 124 - -
124 124 124 124 124 124 - - - - - - 124 - -
RAM64X1D 5 0 15 2
- - - - - - - 642 631 472 407 238 127 - -
642 631 472 407 238 127 - - - - - - - - -
# SLICEM/A6LUT + F7[AB]MUX
# Inputs: A0 A1 A2 A3 A4 A5 A6 D DPRA0 DPRA1 DPRA2 DPRA3 DPRA4 DPRA5 DPRA6 WCLK WE
# Outputs: DPO SPO
RAM128X1D 5 0 17 2
- - - - - - - - 314 314 314 314 314 314 292 - -
347 347 347 347 347 347 296 - - - - - - - - - -
RAM128X1D 6 0 17 2
- - - - - - - - 1009 998 839 774 605 494 450 - -
1047 1036 877 812 643 532 478 - - - - - - - - - -
# Inputs: C CE D R \$pastQ
# Outputs: Q

View file

@ -8,7 +8,7 @@
4 3 127 238 407 472
5 3 127 238 407 472 631
6 5 127 238 407 472 631 642
# F7AMUX.S+F7BMUX.S + AOUTMUX+COUTMUX / 2
# (F7[AB]MUX.S + [AC]OUTMUX) / 2
7 10 464 513 624 793 858 1017 1028
# F8MUX.S+BOUTMUX
# F8MUX.I0+F7MUX.S+BOUTMUX

View file

@ -0,0 +1,10 @@
# Max delays from https://github.com/SymbiFlow/prjxray-db/blob/82bf5f158cd8e9a11ac4d04f1aeef48ed1a528a5/artix7/timings/CLBLL_L.sdf
# and https://github.com/SymbiFlow/prjxray-db/blob/82bf5f158cd8e9a11ac4d04f1aeef48ed1a528a5/artix7/tile_type_CLBLL_L.json
# K area delay
1 1 127
2 2 127 238
3 3 127 238 407
4 3 127 238 407 472
5 3 127 238 407 472 631
6 5 127 238 407 472 631 642

View file

@ -20,16 +20,14 @@
// Convert negative-polarity reset to positive-polarity
(* techmap_celltype = "$_DFF_NN0_" *)
module _90_dff_nn0_to_np0(input D, C, R, output Q); \$_DFF_NP0_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule
module _90_dff_nn0_to_np0 (input D, C, R, output Q); \$_DFF_NP0_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule
(* techmap_celltype = "$_DFF_PN0_" *)
module _90_dff_pn0_to_pp0(input D, C, R, output Q); \$_DFF_PP0_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule
module _90_dff_pn0_to_pp0 (input D, C, R, output Q); \$_DFF_PP0_ _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule
(* techmap_celltype = "$_DFF_NN1_" *)
module _90_dff_nn1_to_np1 (input D, C, R, output Q); \$_DFF_NP1 _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule
(* techmap_celltype = "$_DFF_PN1_" *)
module _90_dff_pn1_to_pp1 (input D, C, R, output Q); \$_DFF_PP1 _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .R(~R)); endmodule
module \$__SHREG_ (input C, input D, input E, output Q);
parameter DEPTH = 0;
parameter [DEPTH-1:0] INIT = 0;

View file

@ -173,8 +173,8 @@ module XORCY(output O, input CI, LI);
assign O = CI ^ LI;
endmodule
(* abc_box_id = 3, abc_carry, lib_whitebox *)
module CARRY4((* abc_carry_out *) output [3:0] CO, output [3:0] O, (* abc_carry_in *) input CI, input CYINIT, input [3:0] DI, S);
(* abc_box_id = 3, abc_carry="CI,CO", lib_whitebox *)
module CARRY4(output [3:0] CO, O, input CI, CYINIT, input [3:0] DI, S);
assign O = S ^ {CO[2:0], CI | CYINIT};
assign CO[0] = S[0] ? CI | CYINIT : DI[0];
assign CO[1] = S[1] ? CO[0] : DI[1];
@ -281,7 +281,25 @@ module FDPE_1 (output reg Q, input C, CE, D, PRE);
always @(negedge C, posedge PRE) if (PRE) Q <= 1'b1; else if (CE) Q <= D;
endmodule
//(* abc_box_id = 4 /*, lib_whitebox*/ *)
(* abc_box_id = 4, abc_scc_break="D,WE" *)
module RAM32X1D (
output DPO, SPO,
input D, WCLK, WE,
input A0, A1, A2, A3, A4,
input DPRA0, DPRA1, DPRA2, DPRA3, DPRA4
);
parameter INIT = 32'h0;
parameter IS_WCLK_INVERTED = 1'b0;
wire [4:0] a = {A4, A3, A2, A1, A0};
wire [4:0] dpra = {DPRA4, DPRA3, DPRA2, DPRA1, DPRA0};
reg [31:0] mem = INIT;
assign SPO = mem[a];
assign DPO = mem[dpra];
wire clk = WCLK ^ IS_WCLK_INVERTED;
always @(posedge clk) if (WE) mem[a] <= D;
endmodule
(* abc_box_id = 5, abc_scc_break="D,WE" *)
module RAM64X1D (
output DPO, SPO,
input D, WCLK, WE,
@ -299,7 +317,7 @@ module RAM64X1D (
always @(posedge clk) if (WE) mem[a] <= D;
endmodule
//(* abc_box_id = 5 /*, lib_whitebox*/ *)
(* abc_box_id = 6, abc_scc_break="D,WE" *)
module RAM128X1D (
output DPO, SPO,
input D, WCLK, WE,

View file

@ -120,7 +120,7 @@ function xtract_cell_decl()
xtract_cell_decl RAM128X1S
xtract_cell_decl RAM256X1S
xtract_cell_decl RAM32M
xtract_cell_decl RAM32X1D
#xtract_cell_decl RAM32X1D
xtract_cell_decl RAM32X1S
xtract_cell_decl RAM32X1S_1
xtract_cell_decl RAM32X2S

View file

@ -3694,13 +3694,6 @@ module RAM32M (...);
input WE;
endmodule
module RAM32X1D (...);
parameter [31:0] INIT = 32'h00000000;
parameter [0:0] IS_WCLK_INVERTED = 1'b0;
output DPO, SPO;
input A0, A1, A2, A3, A4, D, DPRA0, DPRA1, DPRA2, DPRA3, DPRA4, WCLK, WE;
endmodule
module RAM32X1S (...);
parameter [31:0] INIT = 32'h00000000;
parameter [0:0] IS_WCLK_INVERTED = 1'b0;

View file

@ -1,4 +1,17 @@
bram $__XILINX_RAM32X1D
init 1
abits 5
dbits 1
groups 2
ports 1 1
wrmode 0 1
enable 0 1
transp 0 0
clocks 0 1
clkpol 0 2
endbram
bram $__XILINX_RAM64X1D
init 1
abits 6
@ -25,6 +38,13 @@ bram $__XILINX_RAM128X1D
clkpol 0 2
endbram
match $__XILINX_RAM32X1D
min bits 3
min wports 1
make_outreg
or_next_if_better
endmatch
match $__XILINX_RAM64X1D
min bits 5
min wports 1

View file

@ -1,4 +1,38 @@
module \$__XILINX_RAM32X1D (CLK1, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
parameter [31:0] INIT = 32'bx;
parameter CLKPOL2 = 1;
input CLK1;
input [4:0] A1ADDR;
output A1DATA;
input [4:0] B1ADDR;
input B1DATA;
input B1EN;
RAM32X1D #(
.INIT(INIT),
.IS_WCLK_INVERTED(!CLKPOL2)
) _TECHMAP_REPLACE_ (
.DPRA0(A1ADDR[0]),
.DPRA1(A1ADDR[1]),
.DPRA2(A1ADDR[2]),
.DPRA3(A1ADDR[3]),
.DPRA4(A1ADDR[4]),
.DPO(A1DATA),
.A0(B1ADDR[0]),
.A1(B1ADDR[1]),
.A2(B1ADDR[2]),
.A3(B1ADDR[3]),
.A4(B1ADDR[4]),
.D(B1DATA),
.WCLK(CLK1),
.WE(B1EN)
);
endmodule
module \$__XILINX_RAM64X1D (CLK1, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
parameter [63:0] INIT = 64'bx;
parameter CLKPOL2 = 1;

View file

@ -29,61 +29,86 @@ module \$lut (A, Y);
input [WIDTH-1:0] A;
output Y;
// Need to swap input ordering, and fix init accordingly,
// to match ABC's expectation of LUT inputs in non-decreasing
// delay order
function [WIDTH-1:0] permute_index;
input [WIDTH-1:0] i;
integer j;
begin
permute_index = 0;
for (j = 0; j < WIDTH; j = j + 1)
permute_index[WIDTH-1 - j] = i[j];
end
endfunction
function [2**WIDTH-1:0] permute_init;
input [2**WIDTH-1:0] orig;
integer i;
begin
permute_init = 0;
for (i = 0; i < 2**WIDTH; i = i + 1)
permute_init[i] = orig[permute_index(i)];
end
endfunction
parameter [2**WIDTH-1:0] P_LUT = permute_init(LUT);
generate
if (WIDTH == 1) begin
LUT1 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y),
LUT1 #(.INIT(P_LUT)) _TECHMAP_REPLACE_ (.O(Y),
.I0(A[0]));
end else
if (WIDTH == 2) begin
LUT2 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y),
.I0(A[0]), .I1(A[1]));
LUT2 #(.INIT(P_LUT)) _TECHMAP_REPLACE_ (.O(Y),
.I0(A[1]), .I1(A[0]));
end else
if (WIDTH == 3) begin
LUT3 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y),
.I0(A[0]), .I1(A[1]), .I2(A[2]));
LUT3 #(.INIT(P_LUT)) _TECHMAP_REPLACE_ (.O(Y),
.I0(A[2]), .I1(A[1]), .I2(A[0]));
end else
if (WIDTH == 4) begin
LUT4 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y),
.I0(A[0]), .I1(A[1]), .I2(A[2]),
.I3(A[3]));
LUT4 #(.INIT(P_LUT)) _TECHMAP_REPLACE_ (.O(Y),
.I0(A[3]), .I1(A[2]), .I2(A[1]),
.I3(A[0]));
end else
if (WIDTH == 5) begin
LUT5 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y),
.I0(A[0]), .I1(A[1]), .I2(A[2]),
.I3(A[3]), .I4(A[4]));
LUT5 #(.INIT(P_LUT)) _TECHMAP_REPLACE_ (.O(Y),
.I0(A[4]), .I1(A[3]), .I2(A[2]),
.I3(A[1]), .I4(A[0]));
end else
if (WIDTH == 6) begin
LUT6 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y),
.I0(A[0]), .I1(A[1]), .I2(A[2]),
.I3(A[3]), .I4(A[4]), .I5(A[5]));
LUT6 #(.INIT(P_LUT)) _TECHMAP_REPLACE_ (.O(Y),
.I0(A[5]), .I1(A[4]), .I2(A[3]),
.I3(A[2]), .I4(A[1]), .I5(A[0]));
end else
if (WIDTH == 7) begin
wire T0, T1;
LUT6 #(.INIT(LUT[63:0])) fpga_lut_0 (.O(T0),
.I0(A[0]), .I1(A[1]), .I2(A[2]),
.I3(A[3]), .I4(A[4]), .I5(A[5]));
LUT6 #(.INIT(LUT[127:64])) fpga_lut_1 (.O(T1),
.I0(A[0]), .I1(A[1]), .I2(A[2]),
.I3(A[3]), .I4(A[4]), .I5(A[5]));
MUXF7 fpga_mux_0 (.O(Y), .I0(T0), .I1(T1), .S(A[6]));
LUT6 #(.INIT(P_LUT[63:0])) fpga_lut_0 (.O(T0),
.I0(A[6]), .I1(A[5]), .I2(A[4]),
.I3(A[3]), .I4(A[2]), .I5(A[1]));
LUT6 #(.INIT(P_LUT[127:64])) fpga_lut_1 (.O(T1),
.I0(A[6]), .I1(A[5]), .I2(A[4]),
.I3(A[3]), .I4(A[2]), .I5(A[1]));
MUXF7 fpga_mux_0 (.O(Y), .I0(T0), .I1(T1), .S(A[0]));
end else
if (WIDTH == 8) begin
wire T0, T1, T2, T3, T4, T5;
LUT6 #(.INIT(LUT[63:0])) fpga_lut_0 (.O(T0),
.I0(A[0]), .I1(A[1]), .I2(A[2]),
.I3(A[3]), .I4(A[4]), .I5(A[5]));
LUT6 #(.INIT(LUT[127:64])) fpga_lut_1 (.O(T1),
.I0(A[0]), .I1(A[1]), .I2(A[2]),
.I3(A[3]), .I4(A[4]), .I5(A[5]));
LUT6 #(.INIT(LUT[191:128])) fpga_lut_2 (.O(T2),
.I0(A[0]), .I1(A[1]), .I2(A[2]),
.I3(A[3]), .I4(A[4]), .I5(A[5]));
LUT6 #(.INIT(LUT[255:192])) fpga_lut_3 (.O(T3),
.I0(A[0]), .I1(A[1]), .I2(A[2]),
.I3(A[3]), .I4(A[4]), .I5(A[5]));
MUXF7 fpga_mux_0 (.O(T4), .I0(T0), .I1(T1), .S(A[6]));
MUXF7 fpga_mux_1 (.O(T5), .I0(T2), .I1(T3), .S(A[6]));
MUXF8 fpga_mux_2 (.O(Y), .I0(T4), .I1(T5), .S(A[7]));
LUT6 #(.INIT(P_LUT[63:0])) fpga_lut_0 (.O(T0),
.I0(A[7]), .I1(A[6]), .I2(A[5]),
.I3(A[4]), .I4(A[3]), .I5(A[2]));
LUT6 #(.INIT(P_LUT[127:64])) fpga_lut_1 (.O(T1),
.I0(A[7]), .I1(A[6]), .I2(A[5]),
.I3(A[4]), .I4(A[3]), .I5(A[2]));
LUT6 #(.INIT(P_LUT[191:128])) fpga_lut_2 (.O(T2),
.I0(A[7]), .I1(A[6]), .I2(A[5]),
.I3(A[4]), .I4(A[3]), .I5(A[2]));
LUT6 #(.INIT(P_LUT[255:192])) fpga_lut_3 (.O(T3),
.I0(A[7]), .I1(A[6]), .I2(A[5]),
.I3(A[4]), .I4(A[3]), .I5(A[2]));
MUXF7 fpga_mux_0 (.O(T4), .I0(T0), .I1(T1), .S(A[1]));
MUXF7 fpga_mux_1 (.O(T5), .I0(T2), .I1(T3), .S(A[1]));
MUXF8 fpga_mux_2 (.O(Y), .I0(T4), .I1(T5), .S(A[0]));
end else begin
wire _TECHMAP_FAIL_ = 1;
end

View file

@ -45,8 +45,9 @@ struct SynthXilinxPass : public ScriptPass
log(" -top <module>\n");
log(" use the specified module as top module\n");
log("\n");
log(" -arch {xcup|xcu|xc7|xc6s}\n");
log(" -family {xcup|xcu|xc7|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");
log("\n");
log(" -edif <file>\n");
@ -61,9 +62,6 @@ 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(" -nocarry\n");
log(" disable inference of carry chains\n");
log("\n");
log(" -nobram\n");
log(" disable inference of block rams\n");
log("\n");
@ -73,6 +71,12 @@ struct SynthXilinxPass : public ScriptPass
log(" -nosrl\n");
log(" disable inference of shift registers\n");
log("\n");
log(" -nocarry\n");
log(" do not use XORCY/MUXCY/CARRY4 cells in output netlist\n");
log("\n");
log(" -nowidelut\n");
log(" do not use MUXF[78] resources to implement LUTs larger than LUT6s\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");
@ -93,15 +97,15 @@ struct SynthXilinxPass : public ScriptPass
log("\n");
}
std::string top_opt, edif_file, blif_file, abc, arch;
bool flatten, retime, vpr, nocarry, nobram, nodram, nosrl;
std::string top_opt, edif_file, blif_file, family;
bool flatten, retime, vpr, nobram, nodram, nosrl, nocarry, nowidelut, abc9;
void clear_flags() YS_OVERRIDE
{
top_opt = "-auto-top";
edif_file.clear();
blif_file.clear();
abc = "abc";
family = "xc7";
flatten = false;
retime = false;
vpr = false;
@ -109,7 +113,9 @@ struct SynthXilinxPass : public ScriptPass
nobram = false;
nodram = false;
nosrl = false;
arch = "xc7";
nocarry = false;
nowidelut = false;
abc9 = false;
}
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
@ -124,8 +130,8 @@ struct SynthXilinxPass : public ScriptPass
top_opt = "-top " + args[++argidx];
continue;
}
if (args[argidx] == "-arch" && argidx+1 < args.size()) {
arch = args[++argidx];
if ((args[argidx] == "-family" || args[argidx] == "-arch") && argidx+1 < args.size()) {
family = args[++argidx];
continue;
}
if (args[argidx] == "-edif" && argidx+1 < args.size()) {
@ -152,6 +158,14 @@ struct SynthXilinxPass : public ScriptPass
retime = true;
continue;
}
if (args[argidx] == "-nocarry") {
nocarry = true;
continue;
}
if (args[argidx] == "-nowidelut") {
nowidelut = true;
continue;
}
if (args[argidx] == "-vpr") {
vpr = true;
continue;
@ -173,15 +187,15 @@ struct SynthXilinxPass : public ScriptPass
continue;
}
if (args[argidx] == "-abc9") {
abc = "abc9";
abc9 = true;
continue;
}
break;
}
extra_args(args, argidx, design);
if (arch != "xcup" && arch != "xcu" && arch != "xc7" && arch != "xc6s")
log_cmd_error("Invalid Xilinx -arch setting: %s\n", arch.c_str());
if (family != "xcup" && family != "xcu" && family != "xc7" && family != "xc6s")
log_cmd_error("Invalid Xilinx -family setting: %s\n", family.c_str());
if (!design->full_selection())
log_cmd_error("This command only operates on fully selected designs!\n");
@ -225,11 +239,6 @@ struct SynthXilinxPass : public ScriptPass
// so attempt to convert $pmux-es to the former
if (!nosrl || help_mode)
run("pmux2shiftx", "(skip if '-nosrl')");
// Run a number of peephole optimisations, including one
// that optimises $mul cells driving $shiftx's B input
// and that aids wide mux analysis
run("peepopt");
}
if (check_label("bram", "(skip if '-nobram')")) {
@ -268,7 +277,7 @@ struct SynthXilinxPass : public ScriptPass
techmap_files += " -map +/xilinx/arith_map.v";
if (vpr)
techmap_files += " -D _EXPLICIT_CARRY";
else if (abc == "abc9")
else if (abc9)
techmap_files += " -D _CLB_CARRY";
}
run("techmap " + techmap_files);
@ -276,7 +285,7 @@ struct SynthXilinxPass : public ScriptPass
}
if (check_label("map_cells")) {
if (abc == "abc9")
if (abc9)
run("techmap -map +/techmap.v -map +/xilinx/cells_map.v -D _ABC -map +/xilinx/ff_map.v");
else
run("techmap -map +/techmap.v -map +/xilinx/cells_map.v");
@ -284,21 +293,31 @@ struct SynthXilinxPass : public ScriptPass
}
if (check_label("map_luts")) {
if (abc == "abc9") {
run("opt_expr -mux_undef");
if (help_mode)
run("abc -luts 2:2,3,6:5[,10,20] [-dff]", "(skip if 'nowidelut', only for '-retime')");
else if (abc9) {
if (family != "xc7")
log_warning("'synth_xilinx -abc9' currently supports '-family xc7' only.\n");
run("read_verilog -icells -lib +/xilinx/abc_ff.v");
run(abc + " -lut +/xilinx/abc_xc7.lut -box +/xilinx/abc_xc7.box -W " + XC7_WIRE_DELAY + string(retime ? " -retime" : ""));
if (nowidelut)
run("abc9 -lut +/xilinx/abc_xc7_nowide.lut -box +/xilinx/abc_xc7.box -W " + std::string(XC7_WIRE_DELAY) + string(retime ? " -dff" : ""));
else
run("abc9 -lut +/xilinx/abc_xc7.lut -box +/xilinx/abc_xc7.box -W " + std::string(XC7_WIRE_DELAY) + string(retime ? " -dff" : ""));
}
else {
if (nowidelut)
run("abc -luts 2:2,3,6:5" + string(retime ? " -dff" : ""));
else
run("abc -luts 2:2,3,6:5,10,20" + string(retime ? " -dff" : ""));
}
else if (help_mode)
run(abc + " -luts 2:2,3,6:5,10,20 [-dff]");
else
run(abc + " -luts 2:2,3,6:5,10,20" + string(retime ? " -dff" : ""));
run("clean");
// 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')");
if (abc == "abc9")
if (abc9)
run("techmap -map +/xilinx/lut_map.v -map +/xilinx/cells_map.v");
else
run("techmap -map +/xilinx/lut_map.v -map +/xilinx/cells_map.v -map +/xilinx/ff_map.v");