mirror of
https://github.com/YosysHQ/yosys
synced 2025-10-09 09:21:58 +00:00
Create synth_analogdevices
This commit is contained in:
parent
da2e021e3b
commit
091a417b35
17 changed files with 42187 additions and 0 deletions
22
techlibs/analogdevices/Makefile.inc
Normal file
22
techlibs/analogdevices/Makefile.inc
Normal file
|
@ -0,0 +1,22 @@
|
|||
|
||||
OBJS += techlibs/analogdevices/synth_analogdevices.o
|
||||
|
||||
$(eval $(call add_share_file,share/analogdevices,techlibs/analogdevices/cells_map.v))
|
||||
$(eval $(call add_share_file,share/analogdevices,techlibs/analogdevices/cells_sim.v))
|
||||
$(eval $(call add_share_file,share/analogdevices,techlibs/analogdevices/cells_xtra.v))
|
||||
|
||||
$(eval $(call add_share_file,share/analogdevices,techlibs/analogdevices/lutrams.txt))
|
||||
$(eval $(call add_share_file,share/analogdevices,techlibs/analogdevices/lutrams_map.v))
|
||||
|
||||
$(eval $(call add_share_file,share/analogdevices,techlibs/analogdevices/brams_defs.vh))
|
||||
|
||||
$(eval $(call add_share_file,share/analogdevices,techlibs/analogdevices/brams.txt))
|
||||
$(eval $(call add_share_file,share/analogdevices,techlibs/analogdevices/brams_map.v))
|
||||
|
||||
$(eval $(call add_share_file,share/analogdevices,techlibs/analogdevices/arith_map.v))
|
||||
$(eval $(call add_share_file,share/analogdevices,techlibs/analogdevices/ff_map.v))
|
||||
$(eval $(call add_share_file,share/analogdevices,techlibs/analogdevices/lut_map.v))
|
||||
$(eval $(call add_share_file,share/analogdevices,techlibs/analogdevices/mux_map.v))
|
||||
$(eval $(call add_share_file,share/analogdevices,techlibs/analogdevices/dsp_map.v))
|
||||
|
||||
$(eval $(call add_share_file,share/analogdevices,techlibs/analogdevices/abc9_model.v))
|
39
techlibs/analogdevices/abc9_model.v
Normal file
39
techlibs/analogdevices/abc9_model.v
Normal file
|
@ -0,0 +1,39 @@
|
|||
/*
|
||||
* yosys -- Yosys Open SYnthesis Suite
|
||||
*
|
||||
* Copyright (C) 2012 Claire Xenia Wolf <claire@yosyshq.com>
|
||||
* 2019 Eddie Hung <eddie@fpgeh.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.
|
||||
*
|
||||
*/
|
||||
|
||||
// ============================================================================
|
||||
|
||||
// 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
|
||||
(* abc9_box, lib_whitebox *)
|
||||
module \$__XILINX_MUXF78 (output O, input I0, I1, I2, I3, S0, S1);
|
||||
assign O = S1 ? (S0 ? I3 : I2)
|
||||
: (S0 ? I1 : I0);
|
||||
specify
|
||||
(I0 => O) = 294;
|
||||
(I1 => O) = 297;
|
||||
(I2 => O) = 311;
|
||||
(I3 => O) = 317;
|
||||
(S0 => O) = 390;
|
||||
(S1 => O) = 273;
|
||||
endspecify
|
||||
endmodule
|
157
techlibs/analogdevices/arith_map.v
Normal file
157
techlibs/analogdevices/arith_map.v
Normal file
|
@ -0,0 +1,157 @@
|
|||
/*
|
||||
* yosys -- Yosys Open SYnthesis Suite
|
||||
*
|
||||
* Copyright (C) 2012 Claire Xenia Wolf <claire@yosyshq.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.
|
||||
*
|
||||
*/
|
||||
|
||||
// ============================================================================
|
||||
// LCU
|
||||
|
||||
(* techmap_celltype = "$lcu" *)
|
||||
module _80_analogdevices_lcu (P, G, CI, CO);
|
||||
parameter WIDTH = 2;
|
||||
|
||||
(* force_downto *)
|
||||
input [WIDTH-1:0] P, G;
|
||||
input CI;
|
||||
|
||||
(* force_downto *)
|
||||
output [WIDTH-1:0] CO;
|
||||
|
||||
wire _TECHMAP_FAIL_ = WIDTH <= 2;
|
||||
|
||||
genvar i;
|
||||
|
||||
generate
|
||||
localparam CARRY4_COUNT = (WIDTH + 3) / 4;
|
||||
localparam MAX_WIDTH = CARRY4_COUNT * 4;
|
||||
localparam PAD_WIDTH = MAX_WIDTH - WIDTH;
|
||||
|
||||
(* force_downto *)
|
||||
wire [MAX_WIDTH-1:0] S = {{PAD_WIDTH{1'b0}}, P & ~G};
|
||||
(* force_downto *)
|
||||
wire [MAX_WIDTH-1:0] GG = {{PAD_WIDTH{1'b0}}, G};
|
||||
(* force_downto *)
|
||||
wire [MAX_WIDTH-1:0] C;
|
||||
assign CO = C;
|
||||
|
||||
generate for (i = 0; i < CARRY4_COUNT; i = i + 1) begin:slice
|
||||
if (i == 0) begin
|
||||
CRY4 carry4
|
||||
(
|
||||
.CYINIT(CI),
|
||||
.CI (1'd0),
|
||||
.DI (GG[i*4 +: 4]),
|
||||
.S (S [i*4 +: 4]),
|
||||
.CO (C [i*4 +: 4]),
|
||||
);
|
||||
end else begin
|
||||
CRY4 carry4
|
||||
(
|
||||
.CYINIT(1'd0),
|
||||
.CI (C [i*4 - 1]),
|
||||
.DI (GG[i*4 +: 4]),
|
||||
.S (S [i*4 +: 4]),
|
||||
.CO (C [i*4 +: 4]),
|
||||
);
|
||||
end
|
||||
end endgenerate
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
// ============================================================================
|
||||
// ALU
|
||||
|
||||
(* techmap_celltype = "$alu" *)
|
||||
module _80_analogdevices_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;
|
||||
parameter _TECHMAP_CONSTVAL_CI_ = 0;
|
||||
parameter _TECHMAP_CONSTMSK_CI_ = 0;
|
||||
|
||||
(* force_downto *)
|
||||
input [A_WIDTH-1:0] A;
|
||||
(* force_downto *)
|
||||
input [B_WIDTH-1:0] B;
|
||||
(* force_downto *)
|
||||
output [Y_WIDTH-1:0] X, Y;
|
||||
|
||||
input CI, BI;
|
||||
(* force_downto *)
|
||||
output [Y_WIDTH-1:0] CO;
|
||||
|
||||
wire _TECHMAP_FAIL_ = Y_WIDTH <= 2;
|
||||
|
||||
(* force_downto *)
|
||||
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));
|
||||
|
||||
(* force_downto *)
|
||||
wire [Y_WIDTH-1:0] AA = A_buf;
|
||||
(* force_downto *)
|
||||
wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf;
|
||||
|
||||
genvar i;
|
||||
|
||||
localparam CARRY4_COUNT = (Y_WIDTH + 3) / 4;
|
||||
localparam MAX_WIDTH = CARRY4_COUNT * 4;
|
||||
localparam PAD_WIDTH = MAX_WIDTH - Y_WIDTH;
|
||||
|
||||
(* force_downto *)
|
||||
wire [MAX_WIDTH-1:0] S = {{PAD_WIDTH{1'b0}}, AA ^ BB};
|
||||
(* force_downto *)
|
||||
wire [MAX_WIDTH-1:0] DI = {{PAD_WIDTH{1'b0}}, AA};
|
||||
|
||||
(* force_downto *)
|
||||
wire [MAX_WIDTH-1:0] O;
|
||||
(* force_downto *)
|
||||
wire [MAX_WIDTH-1:0] C;
|
||||
assign Y = O, CO = C;
|
||||
|
||||
genvar i;
|
||||
generate for (i = 0; i < CARRY4_COUNT; i = i + 1) begin:slice
|
||||
if (i == 0) begin
|
||||
CRY4 carry4
|
||||
(
|
||||
.CYINIT(CI),
|
||||
.CI (1'd0),
|
||||
.DI (DI[i*4 +: 4]),
|
||||
.S (S [i*4 +: 4]),
|
||||
.O (O [i*4 +: 4]),
|
||||
.CO (C [i*4 +: 4])
|
||||
);
|
||||
end else begin
|
||||
CRY4 carry4
|
||||
(
|
||||
.CYINIT(1'd0),
|
||||
.CI (C [i*4 - 1]),
|
||||
.DI (DI[i*4 +: 4]),
|
||||
.S (S [i*4 +: 4]),
|
||||
.O (O [i*4 +: 4]),
|
||||
.CO (C [i*4 +: 4])
|
||||
);
|
||||
end
|
||||
end endgenerate
|
||||
|
||||
assign X = S;
|
||||
endmodule
|
||||
|
165
techlibs/analogdevices/brams.txt
Normal file
165
techlibs/analogdevices/brams.txt
Normal file
|
@ -0,0 +1,165 @@
|
|||
# Block RAMs for Virtex 4+.
|
||||
# The corresponding mapping files are:
|
||||
# - brams_xc6v_map.v: Virtex 6, Series 7
|
||||
|
||||
ram block $__ANALOGDEVICES_BLOCKRAM_TDP_ {
|
||||
byte 9;
|
||||
ifdef HAS_SIZE_36 {
|
||||
option "MODE" "HALF" {
|
||||
abits 14;
|
||||
widths 1 2 4 9 18 per_port;
|
||||
cost 129;
|
||||
}
|
||||
option "MODE" "FULL" {
|
||||
abits 15;
|
||||
widths 1 2 4 9 18 36 per_port;
|
||||
cost 257;
|
||||
}
|
||||
ifdef HAS_CASCADE {
|
||||
option "MODE" "CASCADE" {
|
||||
abits 16;
|
||||
# hack to enforce same INIT layout as in the other modes
|
||||
widths 1 2 4 9 per_port;
|
||||
cost 513;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
option "MODE" "FULL" {
|
||||
abits 14;
|
||||
widths 1 2 4 9 18 36 per_port;
|
||||
cost 129;
|
||||
}
|
||||
ifdef HAS_CASCADE {
|
||||
option "MODE" "CASCADE" {
|
||||
abits 15;
|
||||
widths 1 2 4 9 per_port;
|
||||
cost 257;
|
||||
}
|
||||
}
|
||||
}
|
||||
init any;
|
||||
port srsw "A" "B" {
|
||||
option "MODE" "HALF" {
|
||||
width mix;
|
||||
}
|
||||
option "MODE" "FULL" {
|
||||
width mix;
|
||||
}
|
||||
option "MODE" "CASCADE" {
|
||||
width mix 1;
|
||||
}
|
||||
ifdef HAS_ADDRCE {
|
||||
# TODO
|
||||
# addrce;
|
||||
}
|
||||
# Spartan 6 and Virtex 6 have a bug where READ_FIRST is not usable with asynchronous clocks.
|
||||
ifdef HAS_CONFLICT_BUG {
|
||||
option "HAS_RDFIRST" 1 {
|
||||
clock posedge "C";
|
||||
}
|
||||
option "HAS_RDFIRST" 0 {
|
||||
clock posedge;
|
||||
}
|
||||
} else {
|
||||
clock posedge;
|
||||
}
|
||||
clken;
|
||||
rdsrst any gated_clken;
|
||||
rdinit any;
|
||||
portoption "WRITE_MODE" "NO_CHANGE" {
|
||||
rdwr no_change;
|
||||
option "MODE" "CASCADE" {
|
||||
forbid;
|
||||
}
|
||||
}
|
||||
portoption "WRITE_MODE" "WRITE_FIRST" {
|
||||
ifdef HAS_SIZE_36 {
|
||||
rdwr new;
|
||||
} else {
|
||||
rdwr new_only;
|
||||
}
|
||||
}
|
||||
ifdef HAS_CONFLICT_BUG {
|
||||
option "HAS_RDFIRST" 1 {
|
||||
portoption "WRITE_MODE" "READ_FIRST" {
|
||||
rdwr old;
|
||||
wrtrans all old;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
portoption "WRITE_MODE" "READ_FIRST" {
|
||||
rdwr old;
|
||||
wrtrans all old;
|
||||
}
|
||||
}
|
||||
optional_rw;
|
||||
}
|
||||
}
|
||||
|
||||
ifdef HAS_SIZE_36 {
|
||||
ram block $__ANALOGDEVICES_BLOCKRAM_SDP_ {
|
||||
byte 9;
|
||||
option "MODE" "HALF" {
|
||||
abits 14;
|
||||
widths 1 2 4 9 18 36 per_port;
|
||||
cost 129;
|
||||
}
|
||||
option "MODE" "FULL" {
|
||||
abits 15;
|
||||
widths 1 2 4 9 18 36 72 per_port;
|
||||
cost 257;
|
||||
}
|
||||
init any;
|
||||
port sw "W" {
|
||||
ifndef HAS_MIXWIDTH_SDP {
|
||||
option "MODE" "HALF" width 36;
|
||||
option "MODE" "FULL" width 72;
|
||||
}
|
||||
ifdef HAS_ADDRCE {
|
||||
# TODO
|
||||
# addrce;
|
||||
}
|
||||
# Spartan 6 and Virtex 6 have a bug where READ_FIRST is not usable with asynchronous clocks.
|
||||
ifdef HAS_CONFLICT_BUG {
|
||||
option "WRITE_MODE" "READ_FIRST" {
|
||||
clock posedge "C";
|
||||
}
|
||||
option "WRITE_MODE" "WRITE_FIRST" {
|
||||
clock posedge;
|
||||
}
|
||||
} else {
|
||||
clock posedge;
|
||||
}
|
||||
clken;
|
||||
option "WRITE_MODE" "READ_FIRST" {
|
||||
wrtrans all old;
|
||||
}
|
||||
optional;
|
||||
}
|
||||
port sr "R" {
|
||||
ifndef HAS_MIXWIDTH_SDP {
|
||||
option "MODE" "HALF" width 36;
|
||||
option "MODE" "FULL" width 72;
|
||||
}
|
||||
ifdef HAS_ADDRCE {
|
||||
# TODO
|
||||
# addrce;
|
||||
}
|
||||
# Spartan 6 and Virtex 6 have a bug where READ_FIRST is not usable with asynchronous clocks.
|
||||
ifdef HAS_CONFLICT_BUG {
|
||||
option "WRITE_MODE" "READ_FIRST" {
|
||||
clock posedge "C";
|
||||
}
|
||||
option "WRITE_MODE" "WRITE_FIRST" {
|
||||
clock posedge;
|
||||
}
|
||||
} else {
|
||||
clock posedge;
|
||||
}
|
||||
clken;
|
||||
rdsrst any gated_clken;
|
||||
rdinit any;
|
||||
optional;
|
||||
}
|
||||
}
|
||||
}
|
561
techlibs/analogdevices/brams_defs.vh
Normal file
561
techlibs/analogdevices/brams_defs.vh
Normal file
|
@ -0,0 +1,561 @@
|
|||
`define PARAMS_INIT_9 \
|
||||
.INIT_00(slice_init('h00)), \
|
||||
.INIT_01(slice_init('h01)), \
|
||||
.INIT_02(slice_init('h02)), \
|
||||
.INIT_03(slice_init('h03)), \
|
||||
.INIT_04(slice_init('h04)), \
|
||||
.INIT_05(slice_init('h05)), \
|
||||
.INIT_06(slice_init('h06)), \
|
||||
.INIT_07(slice_init('h07)), \
|
||||
.INIT_08(slice_init('h08)), \
|
||||
.INIT_09(slice_init('h09)), \
|
||||
.INIT_0A(slice_init('h0a)), \
|
||||
.INIT_0B(slice_init('h0b)), \
|
||||
.INIT_0C(slice_init('h0c)), \
|
||||
.INIT_0D(slice_init('h0d)), \
|
||||
.INIT_0E(slice_init('h0e)), \
|
||||
.INIT_0F(slice_init('h0f)), \
|
||||
.INIT_10(slice_init('h10)), \
|
||||
.INIT_11(slice_init('h11)), \
|
||||
.INIT_12(slice_init('h12)), \
|
||||
.INIT_13(slice_init('h13)), \
|
||||
.INIT_14(slice_init('h14)), \
|
||||
.INIT_15(slice_init('h15)), \
|
||||
.INIT_16(slice_init('h16)), \
|
||||
.INIT_17(slice_init('h17)), \
|
||||
.INIT_18(slice_init('h18)), \
|
||||
.INIT_19(slice_init('h19)), \
|
||||
.INIT_1A(slice_init('h1a)), \
|
||||
.INIT_1B(slice_init('h1b)), \
|
||||
.INIT_1C(slice_init('h1c)), \
|
||||
.INIT_1D(slice_init('h1d)), \
|
||||
.INIT_1E(slice_init('h1e)), \
|
||||
.INIT_1F(slice_init('h1f)),
|
||||
|
||||
`define PARAMS_INITP_9 \
|
||||
.INITP_00(slice_initp('h00)), \
|
||||
.INITP_01(slice_initp('h01)), \
|
||||
.INITP_02(slice_initp('h02)), \
|
||||
.INITP_03(slice_initp('h03)),
|
||||
|
||||
`define PARAMS_INIT_18 \
|
||||
.INIT_00(slice_init('h00)), \
|
||||
.INIT_01(slice_init('h01)), \
|
||||
.INIT_02(slice_init('h02)), \
|
||||
.INIT_03(slice_init('h03)), \
|
||||
.INIT_04(slice_init('h04)), \
|
||||
.INIT_05(slice_init('h05)), \
|
||||
.INIT_06(slice_init('h06)), \
|
||||
.INIT_07(slice_init('h07)), \
|
||||
.INIT_08(slice_init('h08)), \
|
||||
.INIT_09(slice_init('h09)), \
|
||||
.INIT_0A(slice_init('h0a)), \
|
||||
.INIT_0B(slice_init('h0b)), \
|
||||
.INIT_0C(slice_init('h0c)), \
|
||||
.INIT_0D(slice_init('h0d)), \
|
||||
.INIT_0E(slice_init('h0e)), \
|
||||
.INIT_0F(slice_init('h0f)), \
|
||||
.INIT_10(slice_init('h10)), \
|
||||
.INIT_11(slice_init('h11)), \
|
||||
.INIT_12(slice_init('h12)), \
|
||||
.INIT_13(slice_init('h13)), \
|
||||
.INIT_14(slice_init('h14)), \
|
||||
.INIT_15(slice_init('h15)), \
|
||||
.INIT_16(slice_init('h16)), \
|
||||
.INIT_17(slice_init('h17)), \
|
||||
.INIT_18(slice_init('h18)), \
|
||||
.INIT_19(slice_init('h19)), \
|
||||
.INIT_1A(slice_init('h1a)), \
|
||||
.INIT_1B(slice_init('h1b)), \
|
||||
.INIT_1C(slice_init('h1c)), \
|
||||
.INIT_1D(slice_init('h1d)), \
|
||||
.INIT_1E(slice_init('h1e)), \
|
||||
.INIT_1F(slice_init('h1f)), \
|
||||
.INIT_20(slice_init('h20)), \
|
||||
.INIT_21(slice_init('h21)), \
|
||||
.INIT_22(slice_init('h22)), \
|
||||
.INIT_23(slice_init('h23)), \
|
||||
.INIT_24(slice_init('h24)), \
|
||||
.INIT_25(slice_init('h25)), \
|
||||
.INIT_26(slice_init('h26)), \
|
||||
.INIT_27(slice_init('h27)), \
|
||||
.INIT_28(slice_init('h28)), \
|
||||
.INIT_29(slice_init('h29)), \
|
||||
.INIT_2A(slice_init('h2a)), \
|
||||
.INIT_2B(slice_init('h2b)), \
|
||||
.INIT_2C(slice_init('h2c)), \
|
||||
.INIT_2D(slice_init('h2d)), \
|
||||
.INIT_2E(slice_init('h2e)), \
|
||||
.INIT_2F(slice_init('h2f)), \
|
||||
.INIT_30(slice_init('h30)), \
|
||||
.INIT_31(slice_init('h31)), \
|
||||
.INIT_32(slice_init('h32)), \
|
||||
.INIT_33(slice_init('h33)), \
|
||||
.INIT_34(slice_init('h34)), \
|
||||
.INIT_35(slice_init('h35)), \
|
||||
.INIT_36(slice_init('h36)), \
|
||||
.INIT_37(slice_init('h37)), \
|
||||
.INIT_38(slice_init('h38)), \
|
||||
.INIT_39(slice_init('h39)), \
|
||||
.INIT_3A(slice_init('h3a)), \
|
||||
.INIT_3B(slice_init('h3b)), \
|
||||
.INIT_3C(slice_init('h3c)), \
|
||||
.INIT_3D(slice_init('h3d)), \
|
||||
.INIT_3E(slice_init('h3e)), \
|
||||
.INIT_3F(slice_init('h3f)),
|
||||
|
||||
`define PARAMS_INIT_18_U \
|
||||
.INIT_00(slice_init('h40)), \
|
||||
.INIT_01(slice_init('h41)), \
|
||||
.INIT_02(slice_init('h42)), \
|
||||
.INIT_03(slice_init('h43)), \
|
||||
.INIT_04(slice_init('h44)), \
|
||||
.INIT_05(slice_init('h45)), \
|
||||
.INIT_06(slice_init('h46)), \
|
||||
.INIT_07(slice_init('h47)), \
|
||||
.INIT_08(slice_init('h48)), \
|
||||
.INIT_09(slice_init('h49)), \
|
||||
.INIT_0A(slice_init('h4a)), \
|
||||
.INIT_0B(slice_init('h4b)), \
|
||||
.INIT_0C(slice_init('h4c)), \
|
||||
.INIT_0D(slice_init('h4d)), \
|
||||
.INIT_0E(slice_init('h4e)), \
|
||||
.INIT_0F(slice_init('h4f)), \
|
||||
.INIT_10(slice_init('h50)), \
|
||||
.INIT_11(slice_init('h51)), \
|
||||
.INIT_12(slice_init('h52)), \
|
||||
.INIT_13(slice_init('h53)), \
|
||||
.INIT_14(slice_init('h54)), \
|
||||
.INIT_15(slice_init('h55)), \
|
||||
.INIT_16(slice_init('h56)), \
|
||||
.INIT_17(slice_init('h57)), \
|
||||
.INIT_18(slice_init('h58)), \
|
||||
.INIT_19(slice_init('h59)), \
|
||||
.INIT_1A(slice_init('h5a)), \
|
||||
.INIT_1B(slice_init('h5b)), \
|
||||
.INIT_1C(slice_init('h5c)), \
|
||||
.INIT_1D(slice_init('h5d)), \
|
||||
.INIT_1E(slice_init('h5e)), \
|
||||
.INIT_1F(slice_init('h5f)), \
|
||||
.INIT_20(slice_init('h60)), \
|
||||
.INIT_21(slice_init('h61)), \
|
||||
.INIT_22(slice_init('h62)), \
|
||||
.INIT_23(slice_init('h63)), \
|
||||
.INIT_24(slice_init('h64)), \
|
||||
.INIT_25(slice_init('h65)), \
|
||||
.INIT_26(slice_init('h66)), \
|
||||
.INIT_27(slice_init('h67)), \
|
||||
.INIT_28(slice_init('h68)), \
|
||||
.INIT_29(slice_init('h69)), \
|
||||
.INIT_2A(slice_init('h6a)), \
|
||||
.INIT_2B(slice_init('h6b)), \
|
||||
.INIT_2C(slice_init('h6c)), \
|
||||
.INIT_2D(slice_init('h6d)), \
|
||||
.INIT_2E(slice_init('h6e)), \
|
||||
.INIT_2F(slice_init('h6f)), \
|
||||
.INIT_30(slice_init('h70)), \
|
||||
.INIT_31(slice_init('h71)), \
|
||||
.INIT_32(slice_init('h72)), \
|
||||
.INIT_33(slice_init('h73)), \
|
||||
.INIT_34(slice_init('h74)), \
|
||||
.INIT_35(slice_init('h75)), \
|
||||
.INIT_36(slice_init('h76)), \
|
||||
.INIT_37(slice_init('h77)), \
|
||||
.INIT_38(slice_init('h78)), \
|
||||
.INIT_39(slice_init('h79)), \
|
||||
.INIT_3A(slice_init('h7a)), \
|
||||
.INIT_3B(slice_init('h7b)), \
|
||||
.INIT_3C(slice_init('h7c)), \
|
||||
.INIT_3D(slice_init('h7d)), \
|
||||
.INIT_3E(slice_init('h7e)), \
|
||||
.INIT_3F(slice_init('h7f)),
|
||||
|
||||
`define PARAMS_INITP_18 \
|
||||
.INITP_00(slice_initp('h00)), \
|
||||
.INITP_01(slice_initp('h01)), \
|
||||
.INITP_02(slice_initp('h02)), \
|
||||
.INITP_03(slice_initp('h03)), \
|
||||
.INITP_04(slice_initp('h04)), \
|
||||
.INITP_05(slice_initp('h05)), \
|
||||
.INITP_06(slice_initp('h06)), \
|
||||
.INITP_07(slice_initp('h07)),
|
||||
|
||||
`define PARAMS_INIT_36 \
|
||||
.INIT_00(slice_init('h00)), \
|
||||
.INIT_01(slice_init('h01)), \
|
||||
.INIT_02(slice_init('h02)), \
|
||||
.INIT_03(slice_init('h03)), \
|
||||
.INIT_04(slice_init('h04)), \
|
||||
.INIT_05(slice_init('h05)), \
|
||||
.INIT_06(slice_init('h06)), \
|
||||
.INIT_07(slice_init('h07)), \
|
||||
.INIT_08(slice_init('h08)), \
|
||||
.INIT_09(slice_init('h09)), \
|
||||
.INIT_0A(slice_init('h0a)), \
|
||||
.INIT_0B(slice_init('h0b)), \
|
||||
.INIT_0C(slice_init('h0c)), \
|
||||
.INIT_0D(slice_init('h0d)), \
|
||||
.INIT_0E(slice_init('h0e)), \
|
||||
.INIT_0F(slice_init('h0f)), \
|
||||
.INIT_10(slice_init('h10)), \
|
||||
.INIT_11(slice_init('h11)), \
|
||||
.INIT_12(slice_init('h12)), \
|
||||
.INIT_13(slice_init('h13)), \
|
||||
.INIT_14(slice_init('h14)), \
|
||||
.INIT_15(slice_init('h15)), \
|
||||
.INIT_16(slice_init('h16)), \
|
||||
.INIT_17(slice_init('h17)), \
|
||||
.INIT_18(slice_init('h18)), \
|
||||
.INIT_19(slice_init('h19)), \
|
||||
.INIT_1A(slice_init('h1a)), \
|
||||
.INIT_1B(slice_init('h1b)), \
|
||||
.INIT_1C(slice_init('h1c)), \
|
||||
.INIT_1D(slice_init('h1d)), \
|
||||
.INIT_1E(slice_init('h1e)), \
|
||||
.INIT_1F(slice_init('h1f)), \
|
||||
.INIT_20(slice_init('h20)), \
|
||||
.INIT_21(slice_init('h21)), \
|
||||
.INIT_22(slice_init('h22)), \
|
||||
.INIT_23(slice_init('h23)), \
|
||||
.INIT_24(slice_init('h24)), \
|
||||
.INIT_25(slice_init('h25)), \
|
||||
.INIT_26(slice_init('h26)), \
|
||||
.INIT_27(slice_init('h27)), \
|
||||
.INIT_28(slice_init('h28)), \
|
||||
.INIT_29(slice_init('h29)), \
|
||||
.INIT_2A(slice_init('h2a)), \
|
||||
.INIT_2B(slice_init('h2b)), \
|
||||
.INIT_2C(slice_init('h2c)), \
|
||||
.INIT_2D(slice_init('h2d)), \
|
||||
.INIT_2E(slice_init('h2e)), \
|
||||
.INIT_2F(slice_init('h2f)), \
|
||||
.INIT_30(slice_init('h30)), \
|
||||
.INIT_31(slice_init('h31)), \
|
||||
.INIT_32(slice_init('h32)), \
|
||||
.INIT_33(slice_init('h33)), \
|
||||
.INIT_34(slice_init('h34)), \
|
||||
.INIT_35(slice_init('h35)), \
|
||||
.INIT_36(slice_init('h36)), \
|
||||
.INIT_37(slice_init('h37)), \
|
||||
.INIT_38(slice_init('h38)), \
|
||||
.INIT_39(slice_init('h39)), \
|
||||
.INIT_3A(slice_init('h3a)), \
|
||||
.INIT_3B(slice_init('h3b)), \
|
||||
.INIT_3C(slice_init('h3c)), \
|
||||
.INIT_3D(slice_init('h3d)), \
|
||||
.INIT_3E(slice_init('h3e)), \
|
||||
.INIT_3F(slice_init('h3f)), \
|
||||
.INIT_40(slice_init('h40)), \
|
||||
.INIT_41(slice_init('h41)), \
|
||||
.INIT_42(slice_init('h42)), \
|
||||
.INIT_43(slice_init('h43)), \
|
||||
.INIT_44(slice_init('h44)), \
|
||||
.INIT_45(slice_init('h45)), \
|
||||
.INIT_46(slice_init('h46)), \
|
||||
.INIT_47(slice_init('h47)), \
|
||||
.INIT_48(slice_init('h48)), \
|
||||
.INIT_49(slice_init('h49)), \
|
||||
.INIT_4A(slice_init('h4a)), \
|
||||
.INIT_4B(slice_init('h4b)), \
|
||||
.INIT_4C(slice_init('h4c)), \
|
||||
.INIT_4D(slice_init('h4d)), \
|
||||
.INIT_4E(slice_init('h4e)), \
|
||||
.INIT_4F(slice_init('h4f)), \
|
||||
.INIT_50(slice_init('h50)), \
|
||||
.INIT_51(slice_init('h51)), \
|
||||
.INIT_52(slice_init('h52)), \
|
||||
.INIT_53(slice_init('h53)), \
|
||||
.INIT_54(slice_init('h54)), \
|
||||
.INIT_55(slice_init('h55)), \
|
||||
.INIT_56(slice_init('h56)), \
|
||||
.INIT_57(slice_init('h57)), \
|
||||
.INIT_58(slice_init('h58)), \
|
||||
.INIT_59(slice_init('h59)), \
|
||||
.INIT_5A(slice_init('h5a)), \
|
||||
.INIT_5B(slice_init('h5b)), \
|
||||
.INIT_5C(slice_init('h5c)), \
|
||||
.INIT_5D(slice_init('h5d)), \
|
||||
.INIT_5E(slice_init('h5e)), \
|
||||
.INIT_5F(slice_init('h5f)), \
|
||||
.INIT_60(slice_init('h60)), \
|
||||
.INIT_61(slice_init('h61)), \
|
||||
.INIT_62(slice_init('h62)), \
|
||||
.INIT_63(slice_init('h63)), \
|
||||
.INIT_64(slice_init('h64)), \
|
||||
.INIT_65(slice_init('h65)), \
|
||||
.INIT_66(slice_init('h66)), \
|
||||
.INIT_67(slice_init('h67)), \
|
||||
.INIT_68(slice_init('h68)), \
|
||||
.INIT_69(slice_init('h69)), \
|
||||
.INIT_6A(slice_init('h6a)), \
|
||||
.INIT_6B(slice_init('h6b)), \
|
||||
.INIT_6C(slice_init('h6c)), \
|
||||
.INIT_6D(slice_init('h6d)), \
|
||||
.INIT_6E(slice_init('h6e)), \
|
||||
.INIT_6F(slice_init('h6f)), \
|
||||
.INIT_70(slice_init('h70)), \
|
||||
.INIT_71(slice_init('h71)), \
|
||||
.INIT_72(slice_init('h72)), \
|
||||
.INIT_73(slice_init('h73)), \
|
||||
.INIT_74(slice_init('h74)), \
|
||||
.INIT_75(slice_init('h75)), \
|
||||
.INIT_76(slice_init('h76)), \
|
||||
.INIT_77(slice_init('h77)), \
|
||||
.INIT_78(slice_init('h78)), \
|
||||
.INIT_79(slice_init('h79)), \
|
||||
.INIT_7A(slice_init('h7a)), \
|
||||
.INIT_7B(slice_init('h7b)), \
|
||||
.INIT_7C(slice_init('h7c)), \
|
||||
.INIT_7D(slice_init('h7d)), \
|
||||
.INIT_7E(slice_init('h7e)), \
|
||||
.INIT_7F(slice_init('h7f)),
|
||||
|
||||
`define PARAMS_INIT_36_U \
|
||||
.INIT_00(slice_init('h80)), \
|
||||
.INIT_01(slice_init('h81)), \
|
||||
.INIT_02(slice_init('h82)), \
|
||||
.INIT_03(slice_init('h83)), \
|
||||
.INIT_04(slice_init('h84)), \
|
||||
.INIT_05(slice_init('h85)), \
|
||||
.INIT_06(slice_init('h86)), \
|
||||
.INIT_07(slice_init('h87)), \
|
||||
.INIT_08(slice_init('h88)), \
|
||||
.INIT_09(slice_init('h89)), \
|
||||
.INIT_0A(slice_init('h8a)), \
|
||||
.INIT_0B(slice_init('h8b)), \
|
||||
.INIT_0C(slice_init('h8c)), \
|
||||
.INIT_0D(slice_init('h8d)), \
|
||||
.INIT_0E(slice_init('h8e)), \
|
||||
.INIT_0F(slice_init('h8f)), \
|
||||
.INIT_10(slice_init('h90)), \
|
||||
.INIT_11(slice_init('h91)), \
|
||||
.INIT_12(slice_init('h92)), \
|
||||
.INIT_13(slice_init('h93)), \
|
||||
.INIT_14(slice_init('h94)), \
|
||||
.INIT_15(slice_init('h95)), \
|
||||
.INIT_16(slice_init('h96)), \
|
||||
.INIT_17(slice_init('h97)), \
|
||||
.INIT_18(slice_init('h98)), \
|
||||
.INIT_19(slice_init('h99)), \
|
||||
.INIT_1A(slice_init('h9a)), \
|
||||
.INIT_1B(slice_init('h9b)), \
|
||||
.INIT_1C(slice_init('h9c)), \
|
||||
.INIT_1D(slice_init('h9d)), \
|
||||
.INIT_1E(slice_init('h9e)), \
|
||||
.INIT_1F(slice_init('h9f)), \
|
||||
.INIT_20(slice_init('ha0)), \
|
||||
.INIT_21(slice_init('ha1)), \
|
||||
.INIT_22(slice_init('ha2)), \
|
||||
.INIT_23(slice_init('ha3)), \
|
||||
.INIT_24(slice_init('ha4)), \
|
||||
.INIT_25(slice_init('ha5)), \
|
||||
.INIT_26(slice_init('ha6)), \
|
||||
.INIT_27(slice_init('ha7)), \
|
||||
.INIT_28(slice_init('ha8)), \
|
||||
.INIT_29(slice_init('ha9)), \
|
||||
.INIT_2A(slice_init('haa)), \
|
||||
.INIT_2B(slice_init('hab)), \
|
||||
.INIT_2C(slice_init('hac)), \
|
||||
.INIT_2D(slice_init('had)), \
|
||||
.INIT_2E(slice_init('hae)), \
|
||||
.INIT_2F(slice_init('haf)), \
|
||||
.INIT_30(slice_init('hb0)), \
|
||||
.INIT_31(slice_init('hb1)), \
|
||||
.INIT_32(slice_init('hb2)), \
|
||||
.INIT_33(slice_init('hb3)), \
|
||||
.INIT_34(slice_init('hb4)), \
|
||||
.INIT_35(slice_init('hb5)), \
|
||||
.INIT_36(slice_init('hb6)), \
|
||||
.INIT_37(slice_init('hb7)), \
|
||||
.INIT_38(slice_init('hb8)), \
|
||||
.INIT_39(slice_init('hb9)), \
|
||||
.INIT_3A(slice_init('hba)), \
|
||||
.INIT_3B(slice_init('hbb)), \
|
||||
.INIT_3C(slice_init('hbc)), \
|
||||
.INIT_3D(slice_init('hbd)), \
|
||||
.INIT_3E(slice_init('hbe)), \
|
||||
.INIT_3F(slice_init('hbf)), \
|
||||
.INIT_40(slice_init('hc0)), \
|
||||
.INIT_41(slice_init('hc1)), \
|
||||
.INIT_42(slice_init('hc2)), \
|
||||
.INIT_43(slice_init('hc3)), \
|
||||
.INIT_44(slice_init('hc4)), \
|
||||
.INIT_45(slice_init('hc5)), \
|
||||
.INIT_46(slice_init('hc6)), \
|
||||
.INIT_47(slice_init('hc7)), \
|
||||
.INIT_48(slice_init('hc8)), \
|
||||
.INIT_49(slice_init('hc9)), \
|
||||
.INIT_4A(slice_init('hca)), \
|
||||
.INIT_4B(slice_init('hcb)), \
|
||||
.INIT_4C(slice_init('hcc)), \
|
||||
.INIT_4D(slice_init('hcd)), \
|
||||
.INIT_4E(slice_init('hce)), \
|
||||
.INIT_4F(slice_init('hcf)), \
|
||||
.INIT_50(slice_init('hd0)), \
|
||||
.INIT_51(slice_init('hd1)), \
|
||||
.INIT_52(slice_init('hd2)), \
|
||||
.INIT_53(slice_init('hd3)), \
|
||||
.INIT_54(slice_init('hd4)), \
|
||||
.INIT_55(slice_init('hd5)), \
|
||||
.INIT_56(slice_init('hd6)), \
|
||||
.INIT_57(slice_init('hd7)), \
|
||||
.INIT_58(slice_init('hd8)), \
|
||||
.INIT_59(slice_init('hd9)), \
|
||||
.INIT_5A(slice_init('hda)), \
|
||||
.INIT_5B(slice_init('hdb)), \
|
||||
.INIT_5C(slice_init('hdc)), \
|
||||
.INIT_5D(slice_init('hdd)), \
|
||||
.INIT_5E(slice_init('hde)), \
|
||||
.INIT_5F(slice_init('hdf)), \
|
||||
.INIT_60(slice_init('he0)), \
|
||||
.INIT_61(slice_init('he1)), \
|
||||
.INIT_62(slice_init('he2)), \
|
||||
.INIT_63(slice_init('he3)), \
|
||||
.INIT_64(slice_init('he4)), \
|
||||
.INIT_65(slice_init('he5)), \
|
||||
.INIT_66(slice_init('he6)), \
|
||||
.INIT_67(slice_init('he7)), \
|
||||
.INIT_68(slice_init('he8)), \
|
||||
.INIT_69(slice_init('he9)), \
|
||||
.INIT_6A(slice_init('hea)), \
|
||||
.INIT_6B(slice_init('heb)), \
|
||||
.INIT_6C(slice_init('hec)), \
|
||||
.INIT_6D(slice_init('hed)), \
|
||||
.INIT_6E(slice_init('hee)), \
|
||||
.INIT_6F(slice_init('hef)), \
|
||||
.INIT_70(slice_init('hf0)), \
|
||||
.INIT_71(slice_init('hf1)), \
|
||||
.INIT_72(slice_init('hf2)), \
|
||||
.INIT_73(slice_init('hf3)), \
|
||||
.INIT_74(slice_init('hf4)), \
|
||||
.INIT_75(slice_init('hf5)), \
|
||||
.INIT_76(slice_init('hf6)), \
|
||||
.INIT_77(slice_init('hf7)), \
|
||||
.INIT_78(slice_init('hf8)), \
|
||||
.INIT_79(slice_init('hf9)), \
|
||||
.INIT_7A(slice_init('hfa)), \
|
||||
.INIT_7B(slice_init('hfb)), \
|
||||
.INIT_7C(slice_init('hfc)), \
|
||||
.INIT_7D(slice_init('hfd)), \
|
||||
.INIT_7E(slice_init('hfe)), \
|
||||
.INIT_7F(slice_init('hff)),
|
||||
|
||||
`define PARAMS_INITP_36 \
|
||||
.INITP_00(slice_initp('h00)), \
|
||||
.INITP_01(slice_initp('h01)), \
|
||||
.INITP_02(slice_initp('h02)), \
|
||||
.INITP_03(slice_initp('h03)), \
|
||||
.INITP_04(slice_initp('h04)), \
|
||||
.INITP_05(slice_initp('h05)), \
|
||||
.INITP_06(slice_initp('h06)), \
|
||||
.INITP_07(slice_initp('h07)), \
|
||||
.INITP_08(slice_initp('h08)), \
|
||||
.INITP_09(slice_initp('h09)), \
|
||||
.INITP_0A(slice_initp('h0a)), \
|
||||
.INITP_0B(slice_initp('h0b)), \
|
||||
.INITP_0C(slice_initp('h0c)), \
|
||||
.INITP_0D(slice_initp('h0d)), \
|
||||
.INITP_0E(slice_initp('h0e)), \
|
||||
.INITP_0F(slice_initp('h0f)),
|
||||
|
||||
`define MAKE_DO(do, dop, rdata) \
|
||||
wire [63:0] do; \
|
||||
wire [7:0] dop; \
|
||||
assign rdata = { \
|
||||
dop[7], \
|
||||
do[63:56], \
|
||||
dop[6], \
|
||||
do[55:48], \
|
||||
dop[5], \
|
||||
do[47:40], \
|
||||
dop[4], \
|
||||
do[39:32], \
|
||||
dop[3], \
|
||||
do[31:24], \
|
||||
dop[2], \
|
||||
do[23:16], \
|
||||
dop[1], \
|
||||
do[15:8], \
|
||||
dop[0], \
|
||||
do[7:0] \
|
||||
};
|
||||
|
||||
`define MAKE_DI(di, dip, wdata) \
|
||||
wire [63:0] di; \
|
||||
wire [7:0] dip; \
|
||||
assign { \
|
||||
dip[7], \
|
||||
di[63:56], \
|
||||
dip[6], \
|
||||
di[55:48], \
|
||||
dip[5], \
|
||||
di[47:40], \
|
||||
dip[4], \
|
||||
di[39:32], \
|
||||
dip[3], \
|
||||
di[31:24], \
|
||||
dip[2], \
|
||||
di[23:16], \
|
||||
dip[1], \
|
||||
di[15:8], \
|
||||
dip[0], \
|
||||
di[7:0] \
|
||||
} = wdata;
|
||||
|
||||
function [71:0] ival;
|
||||
input integer width;
|
||||
input [71:0] val;
|
||||
if (width == 72)
|
||||
ival = {
|
||||
val[71],
|
||||
val[62],
|
||||
val[53],
|
||||
val[44],
|
||||
val[35],
|
||||
val[26],
|
||||
val[17],
|
||||
val[8],
|
||||
val[70:63],
|
||||
val[61:54],
|
||||
val[52:45],
|
||||
val[43:36],
|
||||
val[34:27],
|
||||
val[25:18],
|
||||
val[16:9],
|
||||
val[7:0]
|
||||
};
|
||||
else if (width == 36)
|
||||
ival = {
|
||||
val[35],
|
||||
val[26],
|
||||
val[17],
|
||||
val[8],
|
||||
val[34:27],
|
||||
val[25:18],
|
||||
val[16:9],
|
||||
val[7:0]
|
||||
};
|
||||
else if (width == 18)
|
||||
ival = {
|
||||
val[17],
|
||||
val[8],
|
||||
val[16:9],
|
||||
val[7:0]
|
||||
};
|
||||
else
|
||||
ival = val;
|
||||
endfunction
|
||||
|
||||
function [255:0] slice_init;
|
||||
input integer idx;
|
||||
integer i;
|
||||
for (i = 0; i < 32; i = i + 1)
|
||||
slice_init[i*8+:8] = INIT[(idx * 32 + i)*9+:8];
|
||||
endfunction
|
||||
|
||||
function [255:0] slice_initp;
|
||||
input integer idx;
|
||||
integer i;
|
||||
for (i = 0; i < 256; i = i + 1)
|
||||
slice_initp[i] = INIT[(idx * 256 + i)*9+8];
|
||||
endfunction
|
284
techlibs/analogdevices/brams_map.v
Normal file
284
techlibs/analogdevices/brams_map.v
Normal file
|
@ -0,0 +1,284 @@
|
|||
module $__ANALOGDEVICES_BLOCKRAM_TDP_ (...);
|
||||
|
||||
parameter INIT = 0;
|
||||
parameter OPTION_MODE = "FULL";
|
||||
parameter OPTION_HAS_RDFIRST = 0;
|
||||
|
||||
parameter PORT_A_RD_WIDTH = 1;
|
||||
parameter PORT_A_WR_WIDTH = 1;
|
||||
parameter PORT_A_WR_EN_WIDTH = 1;
|
||||
parameter PORT_A_RD_USED = 1;
|
||||
parameter PORT_A_WR_USED = 1;
|
||||
parameter PORT_A_OPTION_WRITE_MODE = "NO_CHANGE";
|
||||
parameter PORT_A_RD_INIT_VALUE = 0;
|
||||
parameter PORT_A_RD_SRST_VALUE = 1;
|
||||
|
||||
parameter PORT_B_RD_WIDTH = 1;
|
||||
parameter PORT_B_WR_WIDTH = 1;
|
||||
parameter PORT_B_WR_EN_WIDTH = 1;
|
||||
parameter PORT_B_RD_USED = 0;
|
||||
parameter PORT_B_WR_USED = 0;
|
||||
parameter PORT_B_OPTION_WRITE_MODE = "NO_CHANGE";
|
||||
parameter PORT_B_RD_INIT_VALUE = 0;
|
||||
parameter PORT_B_RD_SRST_VALUE = 0;
|
||||
|
||||
input CLK_C;
|
||||
|
||||
input PORT_A_CLK;
|
||||
input PORT_A_CLK_EN;
|
||||
input [15:0] PORT_A_ADDR;
|
||||
input [PORT_A_WR_WIDTH-1:0] PORT_A_WR_DATA;
|
||||
input [PORT_A_WR_EN_WIDTH-1:0] PORT_A_WR_EN;
|
||||
output [PORT_A_RD_WIDTH-1:0] PORT_A_RD_DATA;
|
||||
input PORT_A_RD_SRST;
|
||||
|
||||
input PORT_B_CLK;
|
||||
input PORT_B_CLK_EN;
|
||||
input [15:0] PORT_B_ADDR;
|
||||
input [PORT_B_WR_WIDTH-1:0] PORT_B_WR_DATA;
|
||||
input [PORT_B_WR_EN_WIDTH-1:0] PORT_B_WR_EN;
|
||||
output [PORT_B_RD_WIDTH-1:0] PORT_B_RD_DATA;
|
||||
input PORT_B_RD_SRST;
|
||||
|
||||
`include "brams_defs.vh"
|
||||
|
||||
`define PARAMS_COMMON \
|
||||
.WRITE_MODE_A(PORT_A_OPTION_WRITE_MODE), \
|
||||
.WRITE_MODE_B(PORT_B_OPTION_WRITE_MODE), \
|
||||
.READ_WIDTH_A(PORT_A_RD_USED ? PORT_A_RD_WIDTH : 0), \
|
||||
.READ_WIDTH_B(PORT_B_RD_USED ? PORT_B_RD_WIDTH : 0), \
|
||||
.WRITE_WIDTH_A(PORT_A_WR_USED ? PORT_A_WR_WIDTH : 0), \
|
||||
.WRITE_WIDTH_B(PORT_B_WR_USED ? PORT_B_WR_WIDTH : 0), \
|
||||
.DOA_REG(0), \
|
||||
.DOB_REG(0), \
|
||||
.INIT_A(ival(PORT_A_RD_WIDTH, PORT_A_RD_INIT_VALUE)), \
|
||||
.INIT_B(ival(PORT_B_RD_WIDTH, PORT_B_RD_INIT_VALUE)), \
|
||||
.SRVAL_A(ival(PORT_A_RD_WIDTH, PORT_A_RD_SRST_VALUE)), \
|
||||
.SRVAL_B(ival(PORT_B_RD_WIDTH, PORT_B_RD_SRST_VALUE)), \
|
||||
.RAM_MODE("TDP"),
|
||||
|
||||
`define PORTS_COMMON \
|
||||
.DOADO(DO_A), \
|
||||
.DOPADOP(DOP_A), \
|
||||
.DIADI(DI_A), \
|
||||
.DIPADIP(DIP_A), \
|
||||
.DOBDO(DO_B), \
|
||||
.DOPBDOP(DOP_B), \
|
||||
.DIBDI(DI_B), \
|
||||
.DIPBDIP(DIP_B), \
|
||||
.CLKARDCLK(PORT_A_CLK), \
|
||||
.CLKBWRCLK(PORT_B_CLK), \
|
||||
.ENARDEN(PORT_A_CLK_EN), \
|
||||
.ENBWREN(PORT_B_CLK_EN), \
|
||||
.REGCEAREGCE(1'b0), \
|
||||
.REGCEB(1'b0), \
|
||||
.RSTRAMARSTRAM(PORT_A_RD_SRST), \
|
||||
.RSTRAMB(PORT_B_RD_SRST), \
|
||||
.RSTREGARSTREG(1'b0), \
|
||||
.RSTREGB(1'b0), \
|
||||
.WEA(WE_A), \
|
||||
.WEBWE(WE_B),
|
||||
|
||||
`MAKE_DI(DI_A, DIP_A, PORT_A_WR_DATA)
|
||||
`MAKE_DI(DI_B, DIP_B, PORT_B_WR_DATA)
|
||||
`MAKE_DO(DO_A, DOP_A, PORT_A_RD_DATA)
|
||||
`MAKE_DO(DO_B, DOP_B, PORT_B_RD_DATA)
|
||||
|
||||
wire [3:0] WE_A = {4{PORT_A_WR_EN}};
|
||||
wire [3:0] WE_B = {4{PORT_B_WR_EN}};
|
||||
|
||||
generate
|
||||
|
||||
if (OPTION_MODE == "HALF") begin
|
||||
RAMB18E1 #(
|
||||
`PARAMS_INIT_18
|
||||
`PARAMS_INITP_18
|
||||
`PARAMS_COMMON
|
||||
) _TECHMAP_REPLACE_ (
|
||||
`PORTS_COMMON
|
||||
.ADDRARDADDR(PORT_A_ADDR[13:0]),
|
||||
.ADDRBWRADDR(PORT_B_ADDR[13:0]),
|
||||
);
|
||||
end else if (OPTION_MODE == "FULL") begin
|
||||
RAMB36E1 #(
|
||||
`PARAMS_INIT_36
|
||||
`PARAMS_INITP_36
|
||||
`PARAMS_COMMON
|
||||
.RAM_EXTENSION_A("NONE"),
|
||||
.RAM_EXTENSION_B("NONE"),
|
||||
) _TECHMAP_REPLACE_ (
|
||||
`PORTS_COMMON
|
||||
.ADDRARDADDR({1'b1, PORT_A_ADDR[14:0]}),
|
||||
.ADDRBWRADDR({1'b1, PORT_B_ADDR[14:0]}),
|
||||
);
|
||||
end else begin
|
||||
wire CAS_A, CAS_B;
|
||||
RAMB36E1 #(
|
||||
`PARAMS_INIT_36
|
||||
`PARAMS_COMMON
|
||||
.RAM_EXTENSION_A("LOWER"),
|
||||
.RAM_EXTENSION_B("LOWER"),
|
||||
) lower (
|
||||
.DIADI(DI_A),
|
||||
.DIBDI(DI_B),
|
||||
.CLKARDCLK(PORT_A_CLK),
|
||||
.CLKBWRCLK(PORT_B_CLK),
|
||||
.ENARDEN(PORT_A_CLK_EN),
|
||||
.ENBWREN(PORT_B_CLK_EN),
|
||||
.REGCEAREGCE(1'b0),
|
||||
.REGCEB(1'b0),
|
||||
.RSTRAMARSTRAM(PORT_A_RD_SRST),
|
||||
.RSTRAMB(PORT_B_RD_SRST),
|
||||
.RSTREGARSTREG(1'b0),
|
||||
.RSTREGB(1'b0),
|
||||
.WEA(WE_A),
|
||||
.WEBWE(WE_B),
|
||||
.ADDRARDADDR(PORT_A_ADDR),
|
||||
.ADDRBWRADDR(PORT_B_ADDR),
|
||||
.CASCADEOUTA(CAS_A),
|
||||
.CASCADEOUTB(CAS_B),
|
||||
);
|
||||
RAMB36E1 #(
|
||||
`PARAMS_INIT_36_U
|
||||
`PARAMS_COMMON
|
||||
.RAM_EXTENSION_A("UPPER"),
|
||||
.RAM_EXTENSION_B("UPPER"),
|
||||
) upper (
|
||||
.DOADO(DO_A),
|
||||
.DIADI(DI_A),
|
||||
.DOBDO(DO_B),
|
||||
.DIBDI(DI_B),
|
||||
.CLKARDCLK(PORT_A_CLK),
|
||||
.CLKBWRCLK(PORT_B_CLK),
|
||||
.ENARDEN(PORT_A_CLK_EN),
|
||||
.ENBWREN(PORT_B_CLK_EN),
|
||||
.REGCEAREGCE(1'b0),
|
||||
.REGCEB(1'b0),
|
||||
.RSTRAMARSTRAM(PORT_A_RD_SRST),
|
||||
.RSTRAMB(PORT_B_RD_SRST),
|
||||
.RSTREGARSTREG(1'b0),
|
||||
.RSTREGB(1'b0),
|
||||
.WEA(WE_A),
|
||||
.WEBWE(WE_B),
|
||||
.ADDRARDADDR(PORT_A_ADDR),
|
||||
.ADDRBWRADDR(PORT_B_ADDR),
|
||||
.CASCADEINA(CAS_A),
|
||||
.CASCADEINB(CAS_B),
|
||||
);
|
||||
end
|
||||
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
module $__ANALOGDEVICES_BLOCKRAM_SDP_ (...);
|
||||
|
||||
parameter INIT = 0;
|
||||
parameter OPTION_MODE = "FULL";
|
||||
parameter OPTION_WRITE_MODE = "READ_FIRST";
|
||||
|
||||
parameter PORT_W_WIDTH = 1;
|
||||
parameter PORT_W_WR_EN_WIDTH = 1;
|
||||
parameter PORT_W_USED = 1;
|
||||
|
||||
parameter PORT_R_WIDTH = 1;
|
||||
parameter PORT_R_USED = 0;
|
||||
parameter PORT_R_RD_INIT_VALUE = 0;
|
||||
parameter PORT_R_RD_SRST_VALUE = 0;
|
||||
|
||||
input CLK_C;
|
||||
|
||||
input PORT_W_CLK;
|
||||
input PORT_W_CLK_EN;
|
||||
input [15:0] PORT_W_ADDR;
|
||||
input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA;
|
||||
input [PORT_W_WR_EN_WIDTH-1:0] PORT_W_WR_EN;
|
||||
|
||||
input PORT_R_CLK;
|
||||
input PORT_R_CLK_EN;
|
||||
input [15:0] PORT_R_ADDR;
|
||||
output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA;
|
||||
input PORT_R_RD_SRST;
|
||||
|
||||
`include "brams_defs.vh"
|
||||
|
||||
`define PARAMS_COMMON \
|
||||
.WRITE_MODE_A(OPTION_WRITE_MODE), \
|
||||
.WRITE_MODE_B(OPTION_WRITE_MODE), \
|
||||
.READ_WIDTH_A(PORT_R_USED ? PORT_R_WIDTH : 0), \
|
||||
.READ_WIDTH_B(0), \
|
||||
.WRITE_WIDTH_A(0), \
|
||||
.WRITE_WIDTH_B(PORT_W_USED ? PORT_W_WIDTH : 0), \
|
||||
.DOA_REG(0), \
|
||||
.DOB_REG(0), \
|
||||
.RAM_MODE("SDP"),
|
||||
|
||||
`define PORTS_COMMON \
|
||||
.CLKBWRCLK(PORT_W_CLK), \
|
||||
.CLKARDCLK(PORT_R_CLK), \
|
||||
.ENBWREN(PORT_W_CLK_EN), \
|
||||
.ENARDEN(PORT_R_CLK_EN), \
|
||||
.REGCEAREGCE(1'b0), \
|
||||
.REGCEB(1'b0), \
|
||||
.RSTRAMARSTRAM(PORT_R_RD_SRST), \
|
||||
.RSTRAMB(1'b0), \
|
||||
.RSTREGARSTREG(1'b0), \
|
||||
.RSTREGB(1'b0), \
|
||||
.WEA(0), \
|
||||
.WEBWE(PORT_W_WR_EN),
|
||||
|
||||
`MAKE_DI(DI, DIP, PORT_W_WR_DATA)
|
||||
`MAKE_DO(DO, DOP, PORT_R_RD_DATA)
|
||||
|
||||
generate
|
||||
|
||||
if (OPTION_MODE == "HALF") begin
|
||||
RAMB18E1 #(
|
||||
`PARAMS_INIT_18
|
||||
`PARAMS_INITP_18
|
||||
`PARAMS_COMMON
|
||||
.INIT_A(PORT_R_WIDTH == 36 ? ival(18, PORT_R_RD_INIT_VALUE[17:0]) : ival(PORT_R_WIDTH, PORT_R_RD_INIT_VALUE)),
|
||||
.INIT_B(PORT_R_WIDTH == 36 ? ival(18, PORT_R_RD_INIT_VALUE[35:18]) : 0),
|
||||
.SRVAL_A(PORT_R_WIDTH == 36 ? ival(18, PORT_R_RD_SRST_VALUE[17:0]) : ival(PORT_R_WIDTH, PORT_R_RD_SRST_VALUE)),
|
||||
.SRVAL_B(PORT_R_WIDTH == 36 ? ival(18, PORT_R_RD_SRST_VALUE[35:18]) : 0),
|
||||
) _TECHMAP_REPLACE_ (
|
||||
`PORTS_COMMON
|
||||
.ADDRARDADDR(PORT_R_ADDR[13:0]),
|
||||
.ADDRBWRADDR(PORT_W_ADDR[13:0]),
|
||||
.DOADO(DO[15:0]),
|
||||
.DOBDO(DO[31:16]),
|
||||
.DOPADOP(DOP[1:0]),
|
||||
.DOPBDOP(DOP[3:2]),
|
||||
.DIADI(DI[15:0]),
|
||||
.DIBDI(PORT_W_WIDTH == 36 ? DI[31:16] : DI[15:0]),
|
||||
.DIPADIP(DIP[1:0]),
|
||||
.DIPBDIP(PORT_W_WIDTH == 36 ? DIP[3:2] : DIP[1:0]),
|
||||
);
|
||||
end else if (OPTION_MODE == "FULL") begin
|
||||
RAMB36E1 #(
|
||||
`PARAMS_INIT_36
|
||||
`PARAMS_INITP_36
|
||||
`PARAMS_COMMON
|
||||
.INIT_A(PORT_R_WIDTH == 72 ? ival(36, PORT_R_RD_INIT_VALUE[35:0]) : ival(PORT_R_WIDTH, PORT_R_RD_INIT_VALUE)),
|
||||
.INIT_B(PORT_R_WIDTH == 72 ? ival(36, PORT_R_RD_INIT_VALUE[71:36]) : 0),
|
||||
.SRVAL_A(PORT_R_WIDTH == 72 ? ival(36, PORT_R_RD_SRST_VALUE[35:0]) : ival(PORT_R_WIDTH, PORT_R_RD_SRST_VALUE)),
|
||||
.SRVAL_B(PORT_R_WIDTH == 72 ? ival(36, PORT_R_RD_SRST_VALUE[71:36]) : 0),
|
||||
) _TECHMAP_REPLACE_ (
|
||||
`PORTS_COMMON
|
||||
.ADDRARDADDR({1'b1, PORT_R_ADDR}),
|
||||
.ADDRBWRADDR({1'b1, PORT_W_ADDR}),
|
||||
.DOADO(DO[31:0]),
|
||||
.DOBDO(DO[63:32]),
|
||||
.DOPADOP(DOP[3:0]),
|
||||
.DOPBDOP(DOP[7:4]),
|
||||
.DIADI(DI[31:0]),
|
||||
.DIBDI(PORT_W_WIDTH == 72 ? DI[63:32] : DI[31:0]),
|
||||
.DIPADIP(DIP[3:0]),
|
||||
.DIPBDIP(PORT_W_WIDTH == 71 ? DIP[7:4] : DIP[3:0]),
|
||||
);
|
||||
end
|
||||
|
||||
endgenerate
|
||||
|
||||
endmodule
|
364
techlibs/analogdevices/cells_map.v
Normal file
364
techlibs/analogdevices/cells_map.v
Normal file
|
@ -0,0 +1,364 @@
|
|||
/*
|
||||
* yosys -- Yosys Open SYnthesis Suite
|
||||
*
|
||||
* Copyright (C) 2012 Claire Xenia Wolf <claire@yosyshq.com>
|
||||
* 2019 Eddie Hung <eddie@fpgeh.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.
|
||||
*
|
||||
*/
|
||||
|
||||
module \$__SHREG_ (input C, input D, input E, output Q);
|
||||
parameter DEPTH = 0;
|
||||
parameter [DEPTH-1:0] INIT = 0;
|
||||
parameter CLKPOL = 1;
|
||||
parameter ENPOL = 2;
|
||||
|
||||
\$__ANALOGDEVICES_SHREG_ #(.DEPTH(DEPTH), .INIT(INIT), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) _TECHMAP_REPLACE_ (.C(C), .D(D), .L(DEPTH-1), .E(E), .Q(Q));
|
||||
endmodule
|
||||
|
||||
module \$__ANALOGDEVICES_SHREG_ (input C, input D, input [31:0] L, input E, output Q, output SO);
|
||||
parameter DEPTH = 0;
|
||||
parameter [DEPTH-1:0] INIT = 0;
|
||||
parameter CLKPOL = 1;
|
||||
parameter ENPOL = 2;
|
||||
|
||||
// shregmap's INIT parameter shifts out LSB first;
|
||||
// however Analog Devices expects MSB first
|
||||
function [DEPTH-1:0] brev;
|
||||
input [DEPTH-1:0] din;
|
||||
integer i;
|
||||
begin
|
||||
for (i = 0; i < DEPTH; i=i+1)
|
||||
brev[i] = din[DEPTH-1-i];
|
||||
end
|
||||
endfunction
|
||||
localparam [DEPTH-1:0] INIT_R = brev(INIT);
|
||||
|
||||
parameter _TECHMAP_CONSTMSK_L_ = 0;
|
||||
|
||||
wire CE;
|
||||
generate
|
||||
if (ENPOL == 0)
|
||||
assign CE = ~E;
|
||||
else if (ENPOL == 1)
|
||||
assign CE = E;
|
||||
else
|
||||
assign CE = 1'b1;
|
||||
if (DEPTH == 1) begin
|
||||
if (CLKPOL)
|
||||
FDRE #(.INIT(INIT_R)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(CE), .R(1'b0));
|
||||
else
|
||||
FDRE_1 #(.INIT(INIT_R)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(CE), .R(1'b0));
|
||||
end else
|
||||
if (DEPTH <= 16) begin
|
||||
SRL16E #(.INIT(INIT_R), .IS_CLK_INVERTED(~CLKPOL[0])) _TECHMAP_REPLACE_ (.A0(L[0]), .A1(L[1]), .A2(L[2]), .A3(L[3]), .CE(CE), .CLK(C), .D(D), .Q(Q));
|
||||
end else
|
||||
if (DEPTH > 17 && DEPTH <= 32) begin
|
||||
SRLC32E #(.INIT(INIT_R), .IS_CLK_INVERTED(~CLKPOL[0])) _TECHMAP_REPLACE_ (.A(L[4:0]), .CE(CE), .CLK(C), .D(D), .Q(Q));
|
||||
end else
|
||||
if (DEPTH > 33 && DEPTH <= 64) begin
|
||||
wire T0, T1, T2;
|
||||
SRLC32E #(.INIT(INIT_R[32-1:0]), .IS_CLK_INVERTED(~CLKPOL[0])) fpga_srl_0 (.A(L[4:0]), .CE(CE), .CLK(C), .D(D), .Q(T0), .Q31(T1));
|
||||
\$__ANALOGDEVICES_SHREG_ #(.DEPTH(DEPTH-32), .INIT(INIT[DEPTH-32-1:0]), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) fpga_srl_1 (.C(C), .D(T1), .L(L), .E(E), .Q(T2));
|
||||
if (&_TECHMAP_CONSTMSK_L_)
|
||||
assign Q = T2;
|
||||
else
|
||||
LUTMUX7 fpga_mux_0 (.O(Q), .I0(T0), .I1(T2), .S(L[5]));
|
||||
end else
|
||||
if (DEPTH > 65 && DEPTH <= 96) begin
|
||||
wire T0, T1, T2, T3, T4, T5, T6;
|
||||
SRLC32E #(.INIT(INIT_R[32-1: 0]), .IS_CLK_INVERTED(~CLKPOL[0])) fpga_srl_0 (.A(L[4:0]), .CE(CE), .CLK(C), .D( D), .Q(T0), .Q31(T1));
|
||||
SRLC32E #(.INIT(INIT_R[64-1:32]), .IS_CLK_INVERTED(~CLKPOL[0])) fpga_srl_1 (.A(L[4:0]), .CE(CE), .CLK(C), .D(T1), .Q(T2), .Q31(T3));
|
||||
\$__ANALOGDEVICES_SHREG_ #(.DEPTH(DEPTH-64), .INIT(INIT[DEPTH-64-1:0]), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) fpga_srl_2 (.C(C), .D(T3), .L(L[4:0]), .E(E), .Q(T4));
|
||||
if (&_TECHMAP_CONSTMSK_L_)
|
||||
assign Q = T4;
|
||||
else
|
||||
\$__ANALOGDEVICES_LUTMUX78 fpga_hard_mux (.I0(T0), .I1(T2), .I2(T4), .I3(1'bx), .S0(L[5]), .S1(L[6]), .O(Q));
|
||||
end else
|
||||
if (DEPTH > 97 && DEPTH < 128) begin
|
||||
wire T0, T1, T2, T3, T4, T5, T6, T7, T8;
|
||||
SRLC32E #(.INIT(INIT_R[32-1: 0]), .IS_CLK_INVERTED(~CLKPOL[0])) fpga_srl_0 (.A(L[4:0]), .CE(CE), .CLK(C), .D( D), .Q(T0), .Q31(T1));
|
||||
SRLC32E #(.INIT(INIT_R[64-1:32]), .IS_CLK_INVERTED(~CLKPOL[0])) fpga_srl_1 (.A(L[4:0]), .CE(CE), .CLK(C), .D(T1), .Q(T2), .Q31(T3));
|
||||
SRLC32E #(.INIT(INIT_R[96-1:64]), .IS_CLK_INVERTED(~CLKPOL[0])) fpga_srl_2 (.A(L[4:0]), .CE(CE), .CLK(C), .D(T3), .Q(T4), .Q31(T5));
|
||||
\$__ANALOGDEVICES_SHREG_ #(.DEPTH(DEPTH-96), .INIT(INIT[DEPTH-96-1:0]), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) fpga_srl_3 (.C(C), .D(T5), .L(L[4:0]), .E(E), .Q(T6));
|
||||
if (&_TECHMAP_CONSTMSK_L_)
|
||||
assign Q = T6;
|
||||
else
|
||||
\$__ANALOGDEVICES_LUTMUX78 fpga_hard_mux (.I0(T0), .I1(T2), .I2(T4), .I3(T6), .S0(L[5]), .S1(L[6]), .O(Q));
|
||||
end
|
||||
else if (DEPTH == 128) begin
|
||||
wire T0, T1, T2, T3, T4, T5, T6;
|
||||
SRLC32E #(.INIT(INIT_R[ 32-1: 0]), .IS_CLK_INVERTED(~CLKPOL[0])) fpga_srl_0 (.A(L[4:0]), .CE(CE), .CLK(C), .D( D), .Q(T0), .Q31(T1));
|
||||
SRLC32E #(.INIT(INIT_R[ 64-1:32]), .IS_CLK_INVERTED(~CLKPOL[0])) fpga_srl_1 (.A(L[4:0]), .CE(CE), .CLK(C), .D(T1), .Q(T2), .Q31(T3));
|
||||
SRLC32E #(.INIT(INIT_R[ 96-1:64]), .IS_CLK_INVERTED(~CLKPOL[0])) fpga_srl_2 (.A(L[4:0]), .CE(CE), .CLK(C), .D(T3), .Q(T4), .Q31(T5));
|
||||
SRLC32E #(.INIT(INIT_R[128-1:96]), .IS_CLK_INVERTED(~CLKPOL[0])) fpga_srl_3 (.A(L[4:0]), .CE(CE), .CLK(C), .D(T5), .Q(T6), .Q31(SO));
|
||||
if (&_TECHMAP_CONSTMSK_L_)
|
||||
assign Q = T6;
|
||||
else
|
||||
\$__ANALOGDEVICES_LUTMUX78 fpga_hard_mux (.I0(T0), .I1(T2), .I2(T4), .I3(T6), .S0(L[5]), .S1(L[6]), .O(Q));
|
||||
end
|
||||
// For fixed length, if just 1 over a convenient value, decompose
|
||||
else if (DEPTH <= 129 && &_TECHMAP_CONSTMSK_L_) begin
|
||||
wire T;
|
||||
\$__ANALOGDEVICES_SHREG_ #(.DEPTH(DEPTH-1), .INIT(INIT[DEPTH-1:1]), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) fpga_srl (.C(C), .D(D), .L({32{1'b1}}), .E(E), .Q(T));
|
||||
\$__ANALOGDEVICES_SHREG_ #(.DEPTH(1), .INIT(INIT[0]), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) fpga_srl_last (.C(C), .D(T), .L(L), .E(E), .Q(Q));
|
||||
end
|
||||
// For variable length, if just 1 over a convenient value, then bump up one more
|
||||
else if (DEPTH < 129 && ~&_TECHMAP_CONSTMSK_L_)
|
||||
\$__ANALOGDEVICES_SHREG_ #(.DEPTH(DEPTH+1), .INIT({INIT,1'b0}), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) _TECHMAP_REPLACE_ (.C(C), .D(D), .L(L), .E(E), .Q(Q));
|
||||
else begin
|
||||
localparam depth0 = 128;
|
||||
localparam num_srl128 = DEPTH / depth0;
|
||||
localparam depthN = DEPTH % depth0;
|
||||
wire [num_srl128 + (depthN > 0 ? 1 : 0) - 1:0] T;
|
||||
wire [num_srl128 + (depthN > 0 ? 1 : 0) :0] S;
|
||||
assign S[0] = D;
|
||||
genvar i;
|
||||
for (i = 0; i < num_srl128; i++)
|
||||
\$__ANALOGDEVICES_SHREG_ #(.DEPTH(depth0), .INIT(INIT[DEPTH-1-i*depth0-:depth0]), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) fpga_srl (.C(C), .D(S[i]), .L(L[$clog2(depth0)-1:0]), .E(E), .Q(T[i]), .SO(S[i+1]));
|
||||
|
||||
if (depthN > 0)
|
||||
\$__ANALOGDEVICES_SHREG_ #(.DEPTH(depthN), .INIT(INIT[depthN-1:0]), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) fpga_srl_last (.C(C), .D(S[num_srl128]), .L(L[$clog2(depth0)-1:0]), .E(E), .Q(T[num_srl128]));
|
||||
|
||||
if (&_TECHMAP_CONSTMSK_L_)
|
||||
assign Q = T[num_srl128 + (depthN > 0 ? 1 : 0) - 1];
|
||||
else
|
||||
assign Q = T[L[DEPTH-1:$clog2(depth0)]];
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
`ifdef MIN_MUX_INPUTS
|
||||
module \$__ANALOGDEVICES_SHIFTX (A, B, Y);
|
||||
parameter A_SIGNED = 0;
|
||||
parameter B_SIGNED = 0;
|
||||
parameter A_WIDTH = 1;
|
||||
parameter B_WIDTH = 1;
|
||||
parameter Y_WIDTH = 1;
|
||||
|
||||
(* force_downto *)
|
||||
input [A_WIDTH-1:0] A;
|
||||
(* force_downto *)
|
||||
input [B_WIDTH-1:0] B;
|
||||
(* force_downto *)
|
||||
output [Y_WIDTH-1:0] Y;
|
||||
|
||||
parameter [A_WIDTH-1:0] _TECHMAP_CONSTMSK_A_ = 0;
|
||||
parameter [A_WIDTH-1:0] _TECHMAP_CONSTVAL_A_ = 0;
|
||||
parameter [B_WIDTH-1:0] _TECHMAP_CONSTMSK_B_ = 0;
|
||||
parameter [B_WIDTH-1:0] _TECHMAP_CONSTVAL_B_ = 0;
|
||||
|
||||
function integer A_WIDTH_trimmed;
|
||||
input integer start;
|
||||
begin
|
||||
A_WIDTH_trimmed = start;
|
||||
while (A_WIDTH_trimmed > 0 && _TECHMAP_CONSTMSK_A_[A_WIDTH_trimmed-1] && _TECHMAP_CONSTVAL_A_[A_WIDTH_trimmed-1] === 1'bx)
|
||||
A_WIDTH_trimmed = A_WIDTH_trimmed - 1;
|
||||
end
|
||||
endfunction
|
||||
|
||||
generate
|
||||
genvar i, j;
|
||||
// Bit-blast
|
||||
if (Y_WIDTH > 1) begin
|
||||
for (i = 0; i < Y_WIDTH; i++)
|
||||
\$__ANALOGDEVICES_SHIFTX #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH(A_WIDTH-Y_WIDTH+1), .B_WIDTH(B_WIDTH), .Y_WIDTH(1'd1)) bitblast (.A(A[A_WIDTH-Y_WIDTH+i:i]), .B(B), .Y(Y[i]));
|
||||
end
|
||||
// If the LSB of B is constant zero (and Y_WIDTH is 1) then
|
||||
// we can optimise by removing every other entry from A
|
||||
// and popping the constant zero from B
|
||||
else if (_TECHMAP_CONSTMSK_B_[0] && !_TECHMAP_CONSTVAL_B_[0]) begin
|
||||
wire [(A_WIDTH+1)/2-1:0] A_i;
|
||||
for (i = 0; i < (A_WIDTH+1)/2; i++)
|
||||
assign A_i[i] = A[i*2];
|
||||
\$__ANALOGDEVICES_SHIFTX #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH((A_WIDTH+1'd1)/2'd2), .B_WIDTH(B_WIDTH-1'd1), .Y_WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(A_i), .B(B[B_WIDTH-1:1]), .Y(Y));
|
||||
end
|
||||
// Trim off any leading 1'bx -es in A
|
||||
else if (_TECHMAP_CONSTMSK_A_[A_WIDTH-1] && _TECHMAP_CONSTVAL_A_[A_WIDTH-1] === 1'bx) begin
|
||||
localparam A_WIDTH_new = A_WIDTH_trimmed(A_WIDTH-1);
|
||||
if (A_WIDTH_new == 0)
|
||||
assign Y = 1'bx;
|
||||
else
|
||||
\$__ANALOGDEVICES_SHIFTX #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH(A_WIDTH_new), .B_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(A[A_WIDTH_new-1:0]), .B(B), .Y(Y));
|
||||
end
|
||||
else if (A_WIDTH < `MIN_MUX_INPUTS) begin
|
||||
wire _TECHMAP_FAIL_ = 1;
|
||||
end
|
||||
else if (A_WIDTH == 2) begin
|
||||
LUTMUX7 fpga_hard_mux (.I0(A[0]), .I1(A[1]), .S(B[0]), .O(Y));
|
||||
end
|
||||
else if (A_WIDTH <= 4) begin
|
||||
wire [4-1:0] Ax;
|
||||
if (A_WIDTH == 4)
|
||||
assign Ax = A;
|
||||
else
|
||||
// Rather than extend with 1'bx which gets flattened to 1'b0
|
||||
// causing the "don't care" status to get lost, extend with
|
||||
// the same driver of F7B.I0 so that we can optimise F7B away
|
||||
// later
|
||||
assign Ax = {A[1], A};
|
||||
\$__ANALOGDEVICES_LUTMUX78 fpga_hard_mux (.I0(Ax[0]), .I1(Ax[2]), .I2(Ax[1]), .I3(Ax[3]), .S0(B[1]), .S1(B[0]), .O(Y));
|
||||
end
|
||||
// Note that the following decompositions are 'backwards' in that
|
||||
// the LSBs are placed on the hard resources, and the soft resources
|
||||
// are used for MSBs.
|
||||
// This has the effect of more effectively utilising the hard mux;
|
||||
// take for example a 5:1 multiplexer, currently this would map as:
|
||||
//
|
||||
// A[0] \___ __ A[0] \__ __
|
||||
// A[4] / \| \ whereas the more A[1] / \| \
|
||||
// A[1] _____| | obvious mapping A[2] \___| |
|
||||
// A[2] _____| |-- of MSBs to hard A[3] / | |__
|
||||
// A[3]______| | resources would A[4] ____| |
|
||||
// |__/ lead to: 1'bx ____| |
|
||||
// || |__/
|
||||
// || ||
|
||||
// B[1:0] B[1:2]
|
||||
//
|
||||
// Expectation would be that the 'forward' mapping (right) is more
|
||||
// area efficient (consider a 9:1 multiplexer using 2x4:1 multiplexers
|
||||
// on its I0 and I1 inputs, and A[8] and 1'bx on its I2 and I3 inputs)
|
||||
// but that the 'backwards' mapping (left) is more delay efficient
|
||||
// since smaller LUTs are faster than wider ones.
|
||||
else if (A_WIDTH <= 8) begin
|
||||
wire [8-1:0] Ax = {{{8-A_WIDTH}{1'bx}}, A};
|
||||
wire T0 = B[2] ? Ax[4] : Ax[0];
|
||||
wire T1 = B[2] ? Ax[5] : Ax[1];
|
||||
wire T2 = B[2] ? Ax[6] : Ax[2];
|
||||
wire T3 = B[2] ? Ax[7] : Ax[3];
|
||||
\$__ANALOGDEVICES_LUTMUX78 fpga_hard_mux (.I0(T0), .I1(T2), .I2(T1), .I3(T3), .S0(B[1]), .S1(B[0]), .O(Y));
|
||||
end
|
||||
else if (A_WIDTH <= 16) begin
|
||||
wire [16-1:0] Ax = {{{16-A_WIDTH}{1'bx}}, A};
|
||||
wire T0 = B[2] ? B[3] ? Ax[12] : Ax[4]
|
||||
: B[3] ? Ax[ 8] : Ax[0];
|
||||
wire T1 = B[2] ? B[3] ? Ax[13] : Ax[5]
|
||||
: B[3] ? Ax[ 9] : Ax[1];
|
||||
wire T2 = B[2] ? B[3] ? Ax[14] : Ax[6]
|
||||
: B[3] ? Ax[10] : Ax[2];
|
||||
wire T3 = B[2] ? B[3] ? Ax[15] : Ax[7]
|
||||
: B[3] ? Ax[11] : Ax[3];
|
||||
\$__ANALOGDEVICES_LUTMUX78 fpga_hard_mux (.I0(T0), .I1(T2), .I2(T1), .I3(T3), .S0(B[1]), .S1(B[0]), .O(Y));
|
||||
end
|
||||
else begin
|
||||
localparam num_mux16 = (A_WIDTH+15) / 16;
|
||||
localparam clog2_num_mux16 = $clog2(num_mux16);
|
||||
wire [num_mux16-1:0] T;
|
||||
wire [num_mux16*16-1:0] Ax = {{(num_mux16*16-A_WIDTH){1'bx}}, A};
|
||||
for (i = 0; i < num_mux16; i++)
|
||||
\$__ANALOGDEVICES_SHIFTX #(
|
||||
.A_SIGNED(A_SIGNED),
|
||||
.B_SIGNED(B_SIGNED),
|
||||
.A_WIDTH(16),
|
||||
.B_WIDTH(4),
|
||||
.Y_WIDTH(Y_WIDTH)
|
||||
) fpga_mux (
|
||||
.A(Ax[i*16+:16]),
|
||||
.B(B[3:0]),
|
||||
.Y(T[i])
|
||||
);
|
||||
\$__ANALOGDEVICES_SHIFTX #(
|
||||
.A_SIGNED(A_SIGNED),
|
||||
.B_SIGNED(B_SIGNED),
|
||||
.A_WIDTH(num_mux16),
|
||||
.B_WIDTH(clog2_num_mux16),
|
||||
.Y_WIDTH(Y_WIDTH)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.A(T),
|
||||
.B(B[B_WIDTH-1-:clog2_num_mux16]),
|
||||
.Y(Y));
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
(* techmap_celltype = "$__ANALOGDEVICES_SHIFTX" *)
|
||||
module _90__ANALOGDEVICES_SHIFTX (A, B, Y);
|
||||
parameter A_SIGNED = 0;
|
||||
parameter B_SIGNED = 0;
|
||||
parameter A_WIDTH = 1;
|
||||
parameter B_WIDTH = 1;
|
||||
parameter Y_WIDTH = 1;
|
||||
|
||||
(* force_downto *)
|
||||
input [A_WIDTH-1:0] A;
|
||||
(* force_downto *)
|
||||
input [B_WIDTH-1:0] B;
|
||||
(* force_downto *)
|
||||
output [Y_WIDTH-1:0] Y;
|
||||
|
||||
\$shiftx #(.A_SIGNED(A_SIGNED), .B_SIGNED(B_SIGNED), .A_WIDTH(A_WIDTH), .B_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) _TECHMAP_REPLACE_ (.A(A), .B(B), .Y(Y));
|
||||
endmodule
|
||||
|
||||
module \$_MUX_ (A, B, S, Y);
|
||||
input A, B, S;
|
||||
output Y;
|
||||
generate
|
||||
if (`MIN_MUX_INPUTS == 2)
|
||||
\$__ANALOGDEVICES_SHIFTX #(.A_SIGNED(0), .B_SIGNED(0), .A_WIDTH(2), .B_WIDTH(1), .Y_WIDTH(1)) _TECHMAP_REPLACE_ (.A({B,A}), .B(S), .Y(Y));
|
||||
else
|
||||
wire _TECHMAP_FAIL_ = 1;
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
module \$_MUX4_ (A, B, C, D, S, T, Y);
|
||||
input A, B, C, D, S, T;
|
||||
output Y;
|
||||
\$__ANALOGDEVICES_SHIFTX #(.A_SIGNED(0), .B_SIGNED(0), .A_WIDTH(4), .B_WIDTH(2), .Y_WIDTH(1)) _TECHMAP_REPLACE_ (.A({D,C,B,A}), .B({T,S}), .Y(Y));
|
||||
endmodule
|
||||
|
||||
module \$_MUX8_ (A, B, C, D, E, F, G, H, S, T, U, Y);
|
||||
input A, B, C, D, E, F, G, H, S, T, U;
|
||||
output Y;
|
||||
\$__ANALOGDEVICES_SHIFTX #(.A_SIGNED(0), .B_SIGNED(0), .A_WIDTH(8), .B_WIDTH(3), .Y_WIDTH(1)) _TECHMAP_REPLACE_ (.A({H,G,F,E,D,C,B,A}), .B({U,T,S}), .Y(Y));
|
||||
endmodule
|
||||
|
||||
module \$_MUX16_ (A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, S, T, U, V, Y);
|
||||
input A, B, C, D, E, F, G, H, I, J, K, L, M, N, O, P, S, T, U, V;
|
||||
output Y;
|
||||
\$__ANALOGDEVICES_SHIFTX #(.A_SIGNED(0), .B_SIGNED(0), .A_WIDTH(16), .B_WIDTH(4), .Y_WIDTH(1)) _TECHMAP_REPLACE_ (.A({P,O,N,M,L,K,J,I,H,G,F,E,D,C,B,A}), .B({V,U,T,S}), .Y(Y));
|
||||
endmodule
|
||||
`endif
|
||||
|
||||
module \$__ANALOGDEVICES_LUTMUX78 (O, I0, I1, I2, I3, S0, S1);
|
||||
output O;
|
||||
input I0, I1, I2, I3, S0, S1;
|
||||
wire T0, T1;
|
||||
parameter _TECHMAP_BITS_CONNMAP_ = 0;
|
||||
parameter [_TECHMAP_BITS_CONNMAP_-1:0] _TECHMAP_CONNMAP_I0_ = 0;
|
||||
parameter [_TECHMAP_BITS_CONNMAP_-1:0] _TECHMAP_CONNMAP_I1_ = 0;
|
||||
parameter [_TECHMAP_BITS_CONNMAP_-1:0] _TECHMAP_CONNMAP_I2_ = 0;
|
||||
parameter [_TECHMAP_BITS_CONNMAP_-1:0] _TECHMAP_CONNMAP_I3_ = 0;
|
||||
parameter _TECHMAP_CONSTMSK_S0_ = 0;
|
||||
parameter _TECHMAP_CONSTVAL_S0_ = 0;
|
||||
parameter _TECHMAP_CONSTMSK_S1_ = 0;
|
||||
parameter _TECHMAP_CONSTVAL_S1_ = 0;
|
||||
if (_TECHMAP_CONSTMSK_S0_ && _TECHMAP_CONSTVAL_S0_ === 1'b1)
|
||||
assign T0 = I1;
|
||||
else if (_TECHMAP_CONSTMSK_S0_ || _TECHMAP_CONNMAP_I0_ === _TECHMAP_CONNMAP_I1_)
|
||||
assign T0 = I0;
|
||||
else
|
||||
LUTMUX7 mux7a (.I0(I0), .I1(I1), .S(S0), .O(T0));
|
||||
if (_TECHMAP_CONSTMSK_S0_ && _TECHMAP_CONSTVAL_S0_ === 1'b1)
|
||||
assign T1 = I3;
|
||||
else if (_TECHMAP_CONSTMSK_S0_ || _TECHMAP_CONNMAP_I2_ === _TECHMAP_CONNMAP_I3_)
|
||||
assign T1 = I2;
|
||||
else
|
||||
LUTMUX7 mux7b (.I0(I2), .I1(I3), .S(S0), .O(T1));
|
||||
if (_TECHMAP_CONSTMSK_S1_ && _TECHMAP_CONSTVAL_S1_ === 1'b1)
|
||||
assign O = T1;
|
||||
else if (_TECHMAP_CONSTMSK_S1_ || (_TECHMAP_CONNMAP_I0_ === _TECHMAP_CONNMAP_I1_ && _TECHMAP_CONNMAP_I1_ === _TECHMAP_CONNMAP_I2_ && _TECHMAP_CONNMAP_I2_ === _TECHMAP_CONNMAP_I3_))
|
||||
assign O = T0;
|
||||
else
|
||||
LUTMUX8 mux8 (.I0(T0), .I1(T1), .S(S1), .O(O));
|
||||
endmodule
|
4377
techlibs/analogdevices/cells_sim.v
Normal file
4377
techlibs/analogdevices/cells_sim.v
Normal file
File diff suppressed because it is too large
Load diff
730
techlibs/analogdevices/cells_xtra.py
Normal file
730
techlibs/analogdevices/cells_xtra.py
Normal file
|
@ -0,0 +1,730 @@
|
|||
#!/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
|
||||
|
||||
|
||||
CELLS = [
|
||||
# Design element types listed in:
|
||||
# - UG607 (Spartan 3)
|
||||
# - UG613 (Spartan 3A)
|
||||
# - UG617 (Spartan 3E)
|
||||
# - UG615 (Spartan 6)
|
||||
# - UG619 (Virtex 4)
|
||||
# - UG621 (Virtex 5)
|
||||
# - UG623 (Virtex 6)
|
||||
# - UG953 (Series 7)
|
||||
# - UG974 (Ultrascale)
|
||||
|
||||
# CLB -- RAM/ROM.
|
||||
# Cell('RAM16X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# Cell('RAM16X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# Cell('RAM32X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# Cell('RAM32X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# Cell('RAM64X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# Cell('RAM64X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# Cell('RAM128X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# Cell('RAM128X1S_1', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# Cell('RAM256X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# Cell('RAM512X1S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# Cell('RAM16X2S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# Cell('RAM32X2S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# Cell('RAM64X2S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# Cell('RAM16X4S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# Cell('RAM32X4S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# Cell('RAM16X8S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# Cell('RAM32X8S', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# Cell('RAM16X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# Cell('RAM16X1D_1', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# Cell('RAM32X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# Cell('RAM32X1D_1', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# Cell('RAM64X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# Cell('RAM64X1D_1', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# Cell('RAM128X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# Cell('RAM256X1D', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# Cell('RAM32M', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# Cell('RAM32M16', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# Cell('RAM64M', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# Cell('RAM64M8', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# Cell('RAM32X16DR8', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# Cell('RAM64X8SW', port_attrs={'WCLK': ['clkbuf_sink']}),
|
||||
# Cell('ROM16X1'),
|
||||
# Cell('ROM32X1'),
|
||||
# Cell('ROM64X1'),
|
||||
# Cell('ROM128X1'),
|
||||
# Cell('ROM256X1'),
|
||||
|
||||
# CLB -- registers/latches.
|
||||
# Virtex 1/2/4/5, Spartan 3.
|
||||
# Cell('FDCPE', port_attrs={'C': ['clkbuf_sink']}),
|
||||
# Cell('FDRSE', port_attrs={'C': ['clkbuf_sink']}),
|
||||
# Cell('LDCPE', port_attrs={'C': ['clkbuf_sink']}),
|
||||
# Virtex 6, Spartan 6, Series 7, Ultrascale.
|
||||
# Cell('FDCE'),
|
||||
# Cell('FDPE'),
|
||||
# Cell('FDRE'),
|
||||
# Cell('FDSE'),
|
||||
# Cell('LDCE'),
|
||||
# Cell('LDPE'),
|
||||
# Cell('AND2B1L'),
|
||||
# Cell('OR2L'),
|
||||
|
||||
# CLB -- other.
|
||||
# Cell('LUT1'),
|
||||
# Cell('LUT2'),
|
||||
# Cell('LUT3'),
|
||||
# Cell('LUT4'),
|
||||
# Cell('LUT5'),
|
||||
# Cell('LUT6'),
|
||||
# Cell('LUT6_2'),
|
||||
# Cell('MUXF5'),
|
||||
# Cell('MUXF6'),
|
||||
# Cell('MUXF7'),
|
||||
# Cell('MUXF8'),
|
||||
# Cell('MUXF9'),
|
||||
# Cell('CARRY4'),
|
||||
# Cell('CARRY8'),
|
||||
# Cell('MUXCY'),
|
||||
# Cell('XORCY'),
|
||||
# Cell('ORCY'),
|
||||
# Cell('MULT_AND'),
|
||||
# Cell('SRL16', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
# Cell('SRL16E', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
# Cell('SRLC16', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
# Cell('SRLC16E', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
# Cell('SRLC32E', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
# Cell('CFGLUT5', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
|
||||
# Block RAM.
|
||||
# Virtex.
|
||||
Cell('RAMB4_S1', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
Cell('RAMB4_S2', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
Cell('RAMB4_S4', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
Cell('RAMB4_S8', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
Cell('RAMB4_S16', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
Cell('RAMB4_S1_S1', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB4_S1_S2', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB4_S1_S4', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB4_S1_S8', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB4_S1_S16', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB4_S2_S2', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB4_S2_S4', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB4_S2_S8', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB4_S2_S16', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB4_S4_S4', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB4_S4_S8', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB4_S4_S16', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB4_S8_S8', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB4_S8_S16', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB4_S16_S16', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
# Virtex 2, Spartan 3.
|
||||
Cell('RAMB16_S1', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
Cell('RAMB16_S2', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
Cell('RAMB16_S4', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
Cell('RAMB16_S9', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
Cell('RAMB16_S18', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
Cell('RAMB16_S36', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
Cell('RAMB16_S1_S1', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB16_S1_S2', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB16_S1_S4', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB16_S1_S9', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB16_S1_S18', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB16_S1_S36', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB16_S2_S2', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB16_S2_S4', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB16_S2_S9', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB16_S2_S18', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB16_S2_S36', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB16_S4_S4', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB16_S4_S9', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB16_S4_S18', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB16_S4_S36', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB16_S9_S9', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB16_S9_S18', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB16_S9_S36', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB16_S18_S18', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB16_S18_S36', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB16_S36_S36', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
# Spartan 3A (in addition to above).
|
||||
Cell('RAMB16BWE_S18', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
Cell('RAMB16BWE_S36', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
Cell('RAMB16BWE_S18_S9', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB16BWE_S18_S18', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB16BWE_S36_S9', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB16BWE_S36_S18', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB16BWE_S36_S36', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
# Spartan 3A DSP.
|
||||
Cell('RAMB16BWER', port_attrs={ 'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
# Spartan 6 (in addition to above).
|
||||
Cell('RAMB8BWER', port_attrs={ 'CLKAWRCLK': ['clkbuf_sink'], 'CLKBRDCLK': ['clkbuf_sink']}),
|
||||
# Virtex 4.
|
||||
Cell('FIFO16', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
|
||||
Cell('RAMB16', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB32_S64_ECC', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
|
||||
# Virtex 5.
|
||||
Cell('FIFO18', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
|
||||
Cell('FIFO18_36', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
|
||||
Cell('FIFO36', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
|
||||
Cell('FIFO36_72', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
|
||||
Cell('RAMB18', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB36', port_attrs={'CLKA': ['clkbuf_sink'], 'CLKB': ['clkbuf_sink']}),
|
||||
Cell('RAMB18SDP', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
|
||||
Cell('RAMB36SDP', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
|
||||
# Virtex 6 / Series 7.
|
||||
Cell('FIFO18E1', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
|
||||
Cell('FIFO36E1', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
|
||||
#Cell('RAMB18E1', port_attrs={'CLKARDCLK': ['clkbuf_sink'], 'CLKBWRCLK': ['clkbuf_sink']]}),
|
||||
#Cell('RAMB36E1', port_attrs={'CLKARDCLK': ['clkbuf_sink'], 'CLKBWRCLK': ['clkbuf_sink']]}),
|
||||
# Ultrascale.
|
||||
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']}),
|
||||
|
||||
# Ultra RAM.
|
||||
Cell('URAM288', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
Cell('URAM288_BASE', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
|
||||
# Multipliers and DSP.
|
||||
# Cell('MULT18X18'), # Virtex 2, Spartan 3
|
||||
# Cell('MULT18X18S', port_attrs={'C': ['clkbuf_sink']}), # Spartan 3
|
||||
# Cell('MULT18X18SIO', port_attrs={'CLK': ['clkbuf_sink']}), # Spartan 3E
|
||||
# Cell('DSP48A', port_attrs={'CLK': ['clkbuf_sink']}), # Spartan 3A DSP
|
||||
# Cell('DSP48A1', port_attrs={'CLK': ['clkbuf_sink']}), # Spartan 6
|
||||
# Cell('DSP48', port_attrs={'CLK': ['clkbuf_sink']}), # Virtex 4
|
||||
Cell('DSP48E', port_attrs={'CLK': ['clkbuf_sink']}), # Virtex 5
|
||||
#Cell('DSP48E1', port_attrs={'CLK': ['clkbuf_sink']}), # Virtex 6 / Series 7
|
||||
Cell('DSP48E2', port_attrs={'CLK': ['clkbuf_sink']}), # Ultrascale
|
||||
|
||||
# I/O logic.
|
||||
# Virtex 2, Spartan 3.
|
||||
# Note: these two are not officially listed in the HDL library guide, but
|
||||
# they are more fundamental than OFDDR* and are necessary to construct
|
||||
# differential DDR outputs (OFDDR* can only do single-ended).
|
||||
Cell('FDDRCPE', port_attrs={'C0': ['clkbuf_sink'], 'C1': ['clkbuf_sink']}),
|
||||
Cell('FDDRRSE', port_attrs={'C0': ['clkbuf_sink'], 'C1': ['clkbuf_sink']}),
|
||||
Cell('IFDDRCPE', port_attrs={'C0': ['clkbuf_sink'], 'C1': ['clkbuf_sink'], 'D': ['iopad_external_pin']}),
|
||||
Cell('IFDDRRSE', port_attrs={'C0': ['clkbuf_sink'], 'C1': ['clkbuf_sink'], 'D': ['iopad_external_pin']}),
|
||||
Cell('OFDDRCPE', port_attrs={'C0': ['clkbuf_sink'], 'C1': ['clkbuf_sink'], 'Q': ['iopad_external_pin']}),
|
||||
Cell('OFDDRRSE', port_attrs={'C0': ['clkbuf_sink'], 'C1': ['clkbuf_sink'], 'Q': ['iopad_external_pin']}),
|
||||
Cell('OFDDRTCPE', port_attrs={'C0': ['clkbuf_sink'], 'C1': ['clkbuf_sink'], 'O': ['iopad_external_pin']}),
|
||||
Cell('OFDDRTRSE', port_attrs={'C0': ['clkbuf_sink'], 'C1': ['clkbuf_sink'], 'O': ['iopad_external_pin']}),
|
||||
# Spartan 3E.
|
||||
Cell('IDDR2', port_attrs={'C0': ['clkbuf_sink'], 'C1': ['clkbuf_sink']}),
|
||||
Cell('ODDR2', port_attrs={'C0': ['clkbuf_sink'], 'C1': ['clkbuf_sink']}),
|
||||
# Virtex 4.
|
||||
Cell('IDDR', port_attrs={'C': ['clkbuf_sink']}),
|
||||
Cell('IDDR_2CLK', port_attrs={'C': ['clkbuf_sink'], 'CB': ['clkbuf_sink']}),
|
||||
Cell('ODDR', port_attrs={'C': ['clkbuf_sink']}),
|
||||
Cell('IDELAYCTRL', keep=True, port_attrs={'REFCLK': ['clkbuf_sink']}),
|
||||
Cell('IDELAY', port_attrs={'C': ['clkbuf_sink']}),
|
||||
Cell('ISERDES', port_attrs={
|
||||
'CLK': ['clkbuf_sink'],
|
||||
'OCLK': ['clkbuf_sink'],
|
||||
'CLKDIV': ['clkbuf_sink'],
|
||||
}),
|
||||
Cell('OSERDES', port_attrs={'CLK': ['clkbuf_sink'], 'CLKDIV': ['clkbuf_sink']}),
|
||||
# Virtex 5.
|
||||
Cell('IODELAY', port_attrs={'C': ['clkbuf_sink']}),
|
||||
Cell('ISERDES_NODELAY', port_attrs={
|
||||
'CLK': ['clkbuf_sink'],
|
||||
'CLKB': ['clkbuf_sink'],
|
||||
'OCLK': ['clkbuf_sink'],
|
||||
'CLKDIV': ['clkbuf_sink'],
|
||||
}),
|
||||
# Virtex 6.
|
||||
Cell('IODELAYE1', port_attrs={'C': ['clkbuf_sink']}),
|
||||
Cell('ISERDESE1', port_attrs={
|
||||
'CLK': ['clkbuf_sink'],
|
||||
'CLKB': ['clkbuf_sink'],
|
||||
'OCLK': ['clkbuf_sink'],
|
||||
'CLKDIV': ['clkbuf_sink'],
|
||||
}),
|
||||
Cell('OSERDESE1', port_attrs={'CLK': ['clkbuf_sink'], 'CLKDIV': ['clkbuf_sink']}),
|
||||
# Series 7.
|
||||
Cell('IDELAYE2', port_attrs={'C': ['clkbuf_sink']}),
|
||||
Cell('ODELAYE2', port_attrs={'C': ['clkbuf_sink']}),
|
||||
Cell('ISERDESE2', port_attrs={
|
||||
'CLK': ['clkbuf_sink'],
|
||||
'CLKB': ['clkbuf_sink'],
|
||||
'OCLK': ['clkbuf_sink'],
|
||||
'OCLKB': ['clkbuf_sink'],
|
||||
'CLKDIV': ['clkbuf_sink'],
|
||||
'CLKDIVP': ['clkbuf_sink'],
|
||||
}),
|
||||
Cell('OSERDESE2', port_attrs={'CLK': ['clkbuf_sink'], 'CLKDIV': ['clkbuf_sink']}),
|
||||
Cell('PHASER_IN', keep=True),
|
||||
Cell('PHASER_IN_PHY', keep=True),
|
||||
Cell('PHASER_OUT', keep=True),
|
||||
Cell('PHASER_OUT_PHY', keep=True),
|
||||
Cell('PHASER_REF', keep=True),
|
||||
Cell('PHY_CONTROL', keep=True),
|
||||
# Ultrascale.
|
||||
Cell('IDDRE1', port_attrs={'C': ['clkbuf_sink'], 'CB': ['clkbuf_sink']}),
|
||||
Cell('ODDRE1', port_attrs={'C': ['clkbuf_sink']}),
|
||||
Cell('IDELAYE3', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
Cell('ODELAYE3', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
Cell('ISERDESE3', port_attrs={
|
||||
'CLK': ['clkbuf_sink'],
|
||||
'CLK_B': ['clkbuf_sink'],
|
||||
'FIFO_RD_CLK': ['clkbuf_sink'],
|
||||
'CLKDIV': ['clkbuf_sink'],
|
||||
}),
|
||||
Cell('OSERDESE3', port_attrs={'CLK': ['clkbuf_sink'], 'CLKDIV': ['clkbuf_sink']}),
|
||||
Cell('BITSLICE_CONTROL', keep=True),
|
||||
Cell('RIU_OR', keep=True),
|
||||
Cell('RX_BITSLICE'),
|
||||
Cell('RXTX_BITSLICE'),
|
||||
Cell('TX_BITSLICE'),
|
||||
Cell('TX_BITSLICE_TRI'),
|
||||
# Spartan 6.
|
||||
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('OSERDES2', port_attrs={
|
||||
'CLK0': ['clkbuf_sink'],
|
||||
'CLK1': ['clkbuf_sink'],
|
||||
'CLKDIV': ['clkbuf_sink'],
|
||||
}),
|
||||
|
||||
# I/O buffers.
|
||||
# Input.
|
||||
# Cell('IBUF', port_attrs={'I': ['iopad_external_pin']}),
|
||||
Cell('IBUF_DLY_ADJ', 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('IBUF_ANALOG', port_attrs={'I': ['iopad_external_pin']}),
|
||||
Cell('IBUFE3', port_attrs={'I': ['iopad_external_pin']}),
|
||||
Cell('IBUFDS', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
Cell('IBUFDS_DLY_ADJ', 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('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('IBUFDSE3', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
Cell('IBUFDS_DPHY', 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']}),
|
||||
# I/O.
|
||||
# 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('IOBUFE3', port_attrs={'IO': ['iopad_external_pin']}),
|
||||
Cell('IOBUFDS', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
|
||||
Cell('IOBUFDS_DCIEN', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
|
||||
Cell('IOBUFDS_INTERMDISABLE', 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('IOBUFDSE3', port_attrs={'IO': ['iopad_external_pin'], 'IOB': ['iopad_external_pin']}),
|
||||
# Output.
|
||||
# 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']}),
|
||||
# Output + tristate.
|
||||
# Cell('OBUFT', port_attrs={'O': ['iopad_external_pin']}),
|
||||
Cell('OBUFTDS', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
|
||||
# Pulls.
|
||||
Cell('KEEPER'),
|
||||
Cell('PULLDOWN'),
|
||||
Cell('PULLUP'),
|
||||
# Misc.
|
||||
Cell('DCIRESET', keep=True),
|
||||
Cell('HPIO_VREF', keep=True), # Ultrascale
|
||||
|
||||
# Clock buffers (global).
|
||||
# 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('BUFGCTRL', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFGMUX_CTRL', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFGMUX_VIRTEX4', 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_DIV', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFH', port_attrs={'O': ['clkbuf_driver']}),
|
||||
#Cell('BUFHCE', port_attrs={'O': ['clkbuf_driver']}),
|
||||
|
||||
# Clock buffers (IO) -- Spartan 6.
|
||||
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', port_attrs={'IOCLK': ['clkbuf_driver']}),
|
||||
Cell('BUFPLL_MCB', port_attrs={'IOCLK0': ['clkbuf_driver'], 'IOCLK1': ['clkbuf_driver']}),
|
||||
|
||||
# Clock buffers (IO and regional) -- Virtex.
|
||||
Cell('BUFIO', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFIODQS', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFR', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFMR', port_attrs={'O': ['clkbuf_driver']}),
|
||||
Cell('BUFMRCE', port_attrs={'O': ['clkbuf_driver']}),
|
||||
|
||||
# Clock components.
|
||||
# VIrtex.
|
||||
# TODO: CLKDLL
|
||||
# TODO: CLKDLLE
|
||||
# TODO: CLKDLLHF
|
||||
# Virtex 2, Spartan 3.
|
||||
Cell('DCM'),
|
||||
# Spartan 3E.
|
||||
Cell('DCM_SP'),
|
||||
# Spartan 6 (also uses DCM_SP and PLL_BASE).
|
||||
Cell('DCM_CLKGEN'),
|
||||
# Virtex 4/5.
|
||||
Cell('DCM_ADV'),
|
||||
Cell('DCM_BASE'),
|
||||
Cell('DCM_PS'),
|
||||
# Virtex 4.
|
||||
Cell('PMCD'),
|
||||
# Virtex 5.
|
||||
Cell('PLL_ADV'),
|
||||
Cell('PLL_BASE'),
|
||||
# Virtex 6.
|
||||
Cell('MMCM_ADV'),
|
||||
Cell('MMCM_BASE'),
|
||||
# Series 7.
|
||||
Cell('MMCME2_ADV'),
|
||||
Cell('MMCME2_BASE'),
|
||||
Cell('PLLE2_ADV'),
|
||||
Cell('PLLE2_BASE'),
|
||||
# Ultrascale.
|
||||
Cell('MMCME3_ADV'),
|
||||
Cell('MMCME3_BASE'),
|
||||
Cell('PLLE3_ADV'),
|
||||
Cell('PLLE3_BASE'),
|
||||
# Ultrascale+.
|
||||
Cell('MMCME4_ADV'),
|
||||
Cell('MMCME4_BASE'),
|
||||
Cell('PLLE4_ADV'),
|
||||
Cell('PLLE4_BASE'),
|
||||
|
||||
# Misc stuff.
|
||||
Cell('BUFT'),
|
||||
# Series 7 I/O FIFOs.
|
||||
Cell('IN_FIFO', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
|
||||
Cell('OUT_FIFO', port_attrs={'RDCLK': ['clkbuf_sink'], 'WRCLK': ['clkbuf_sink']}),
|
||||
# Ultrascale special synchronizer register.
|
||||
Cell('HARD_SYNC', port_attrs={'CLK': ['clkbuf_sink']}),
|
||||
|
||||
# Singletons.
|
||||
# Startup.
|
||||
# TODO: STARTUP_VIRTEX
|
||||
# TODO: STARTUP_VIRTEX2
|
||||
Cell('STARTUP_SPARTAN3', keep=True),
|
||||
Cell('STARTUP_SPARTAN3E', keep=True),
|
||||
Cell('STARTUP_SPARTAN3A', keep=True),
|
||||
Cell('STARTUP_SPARTAN6', keep=True),
|
||||
Cell('STARTUP_VIRTEX4', keep=True),
|
||||
Cell('STARTUP_VIRTEX5', keep=True),
|
||||
Cell('STARTUP_VIRTEX6', keep=True),
|
||||
Cell('STARTUPE2', keep=True), # Series 7
|
||||
Cell('STARTUPE3', keep=True), # Ultrascale
|
||||
# Capture trigger.
|
||||
# TODO: CAPTURE_VIRTEX
|
||||
# TODO: CAPTURE_VIRTEX2
|
||||
Cell('CAPTURE_SPARTAN3', keep=True),
|
||||
Cell('CAPTURE_SPARTAN3A', keep=True),
|
||||
Cell('CAPTURE_VIRTEX4', keep=True),
|
||||
Cell('CAPTURE_VIRTEX5', keep=True),
|
||||
Cell('CAPTURE_VIRTEX6', keep=True),
|
||||
Cell('CAPTUREE2', keep=True), # Series 7
|
||||
# Internal Configuration Access Port.
|
||||
# TODO: ICAP_VIRTEX2
|
||||
Cell('ICAP_SPARTAN3A', keep=True),
|
||||
Cell('ICAP_SPARTAN6', keep=True),
|
||||
Cell('ICAP_VIRTEX4', keep=True),
|
||||
Cell('ICAP_VIRTEX5', keep=True),
|
||||
Cell('ICAP_VIRTEX6', keep=True),
|
||||
Cell('ICAPE2', keep=True), # Series 7
|
||||
Cell('ICAPE3', keep=True), # Ultrascale
|
||||
# JTAG.
|
||||
# TODO: BSCAN_VIRTEX
|
||||
# TODO: BSCAN_VIRTEX2
|
||||
Cell('BSCAN_SPARTAN3', keep=True),
|
||||
Cell('BSCAN_SPARTAN3A', keep=True),
|
||||
Cell('BSCAN_SPARTAN6', keep=True),
|
||||
Cell('BSCAN_VIRTEX4', keep=True),
|
||||
Cell('BSCAN_VIRTEX5', keep=True),
|
||||
Cell('BSCAN_VIRTEX6', keep=True),
|
||||
Cell('BSCANE2', keep=True), # Series 7, Ultrascale
|
||||
# DNA port.
|
||||
Cell('DNA_PORT'), # Virtex 5/6, Series 7, Spartan 3A/6
|
||||
Cell('DNA_PORTE2'), # Ultrascale
|
||||
# Frame ECC.
|
||||
Cell('FRAME_ECC_VIRTEX4'),
|
||||
Cell('FRAME_ECC_VIRTEX5'),
|
||||
Cell('FRAME_ECC_VIRTEX6'),
|
||||
Cell('FRAME_ECCE2'), # Series 7
|
||||
Cell('FRAME_ECCE3'), # Ultrascale
|
||||
Cell('FRAME_ECCE4'), # Ultrascale+
|
||||
# AXSS command access.
|
||||
Cell('USR_ACCESS_VIRTEX4'),
|
||||
Cell('USR_ACCESS_VIRTEX5'),
|
||||
Cell('USR_ACCESS_VIRTEX6'),
|
||||
Cell('USR_ACCESSE2'), # Series 7, Ultrascale
|
||||
# Misc.
|
||||
Cell('POST_CRC_INTERNAL'), # Spartan 6
|
||||
Cell('SUSPEND_SYNC', keep=True), # Spartan 6
|
||||
Cell('KEY_CLEAR', keep=True), # Virtex 5
|
||||
Cell('MASTER_JTAG', keep=True), # Ultrascale
|
||||
Cell('SPI_ACCESS', keep=True), # Spartan 3AN
|
||||
Cell('EFUSE_USR'),
|
||||
|
||||
# ADC.
|
||||
Cell('SYSMON', keep=True), # Virtex 5/6
|
||||
Cell('XADC', keep=True), # Series 7
|
||||
Cell('SYSMONE1', keep=True), # Ultrascale
|
||||
Cell('SYSMONE4', keep=True), # Ultrascale+
|
||||
|
||||
# Gigabit transceivers.
|
||||
# Spartan 6.
|
||||
Cell('GTPA1_DUAL'),
|
||||
# Virtex 2 Pro.
|
||||
# TODO: GT_*
|
||||
# TODO: GT10_*
|
||||
# Virtex 4.
|
||||
Cell('GT11_CUSTOM'),
|
||||
Cell('GT11_DUAL'),
|
||||
Cell('GT11CLK'),
|
||||
Cell('GT11CLK_MGT'),
|
||||
# Virtex 5.
|
||||
Cell('GTP_DUAL'),
|
||||
Cell('GTX_DUAL'),
|
||||
Cell('CRC32', port_attrs={'CRCCLK': ['clkbuf_sink']}),
|
||||
Cell('CRC64', port_attrs={'CRCCLK': ['clkbuf_sink']}),
|
||||
# Virtex 6.
|
||||
Cell('GTHE1_QUAD'),
|
||||
Cell('GTXE1'),
|
||||
Cell('IBUFDS_GTXE1', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
Cell('IBUFDS_GTHE1', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
# Series 7.
|
||||
Cell('GTHE2_CHANNEL'),
|
||||
Cell('GTHE2_COMMON'),
|
||||
Cell('GTPE2_CHANNEL'),
|
||||
Cell('GTPE2_COMMON'),
|
||||
Cell('GTXE2_CHANNEL'),
|
||||
Cell('GTXE2_COMMON'),
|
||||
Cell('IBUFDS_GTE2', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
# Ultrascale.
|
||||
Cell('GTHE3_CHANNEL'),
|
||||
Cell('GTHE3_COMMON'),
|
||||
Cell('GTYE3_CHANNEL'),
|
||||
Cell('GTYE3_COMMON'),
|
||||
Cell('IBUFDS_GTE3', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
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']}),
|
||||
# Ultrascale+.
|
||||
Cell('GTHE4_CHANNEL'),
|
||||
Cell('GTHE4_COMMON'),
|
||||
Cell('GTYE4_CHANNEL'),
|
||||
Cell('GTYE4_COMMON'),
|
||||
Cell('IBUFDS_GTE4', port_attrs={'I': ['iopad_external_pin'], 'IB': ['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']}),
|
||||
# Ultrascale+ GTM.
|
||||
Cell('GTM_DUAL'), # not in the libraries guide
|
||||
Cell('IBUFDS_GTM', port_attrs={'I': ['iopad_external_pin'], 'IB': ['iopad_external_pin']}),
|
||||
Cell('OBUFDS_GTM', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
|
||||
Cell('OBUFDS_GTM_ADV', port_attrs={'O': ['iopad_external_pin'], 'OB': ['iopad_external_pin']}),
|
||||
|
||||
# High-speed ADC/DAC.
|
||||
Cell('HSDAC'), # not in libraries guide
|
||||
Cell('HSADC'), # not in libraries guide
|
||||
Cell('RFDAC'), # not in libraries guide
|
||||
Cell('RFADC'), # not in libraries guide
|
||||
|
||||
# PCIE IP.
|
||||
Cell('PCIE_A1'), # Spartan 6
|
||||
Cell('PCIE_EP'), # Virtex 5
|
||||
Cell('PCIE_2_0'), # Virtex 6
|
||||
Cell('PCIE_2_1'), # Series 7
|
||||
Cell('PCIE_3_0'), # Series 7
|
||||
Cell('PCIE_3_1'), # Ultrascale
|
||||
Cell('PCIE40E4'), # Ultrascale+
|
||||
Cell('PCIE4CE4'), # Ultrascale+ v2 (not in the libraries guide)
|
||||
|
||||
# Ethernet IP.
|
||||
Cell('EMAC'), # Virtex 4
|
||||
Cell('TEMAC'), # Virtex 5
|
||||
Cell('TEMAC_SINGLE'), # Virtex 6
|
||||
Cell('CMAC'), # Ultrascale
|
||||
Cell('CMACE4'), # Ultrsacale+
|
||||
|
||||
# Hard memory controllers.
|
||||
Cell('MCB'), # Spartan 6 Memory Controller Block
|
||||
Cell('HBM_REF_CLK', keep=True), # not in liraries guide
|
||||
# not sure how the following relate to the hw
|
||||
Cell('HBM_SNGLBLI_INTF_APB', keep=True), # not in liraries guide
|
||||
Cell('HBM_SNGLBLI_INTF_AXI', keep=True), # not in liraries guide
|
||||
Cell('HBM_ONE_STACK_INTF', keep=True), # not in liraries guide
|
||||
Cell('HBM_TWO_STACK_INTF', keep=True), # not in liraries guide
|
||||
|
||||
# PowerPC.
|
||||
# TODO PPC405 (Virtex 2)
|
||||
Cell('PPC405_ADV'), # Virtex 4
|
||||
Cell('PPC440'), # Virtex 5
|
||||
|
||||
# ARM.
|
||||
Cell('PS7', keep=True), # The Zynq 7000 ARM Processor System (not in libraries guide).
|
||||
Cell('PS8', keep=True), # The Zynq Ultrascale+ ARM Processor System (not in libraries guide).
|
||||
|
||||
# Misc hard IP.
|
||||
Cell('ILKN'), # Ultrascale Interlaken
|
||||
Cell('ILKNE4'), # Ultrascale+ Interlaken
|
||||
Cell('VCU', keep=True), # Zynq MPSoC Video Codec Unit (not in libraries guide).
|
||||
Cell('FE'), # Zynq RFSoC Forward Error Correction (not in libraries guide).
|
||||
]
|
||||
|
||||
|
||||
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:
|
||||
for ext in ['.v', '.sv']:
|
||||
fname = os.path.join(dir, cell.name + ext)
|
||||
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 Analog Devices blackbox cell definitions from ISE and Vivado.')
|
||||
parser.add_argument('vivado_dir', nargs='?', default='/opt/Analog Devices/Vivado/2022.2')
|
||||
parser.add_argument('ise_dir', nargs='?', default='/opt/Analog Devices/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/unisims'),
|
||||
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))
|
||||
|
||||
out = StringIO()
|
||||
for cell in CELLS:
|
||||
xtract_cell_decl(cell, dirs, out)
|
||||
|
||||
with open('cells_xtra.v', 'w') as f:
|
||||
f.write('// Created by cells_xtra.py from Analog Devices models\n')
|
||||
f.write('\n')
|
||||
f.write(out.getvalue())
|
34120
techlibs/analogdevices/cells_xtra.v
Normal file
34120
techlibs/analogdevices/cells_xtra.v
Normal file
File diff suppressed because it is too large
Load diff
50
techlibs/analogdevices/dsp_map.v
Normal file
50
techlibs/analogdevices/dsp_map.v
Normal file
|
@ -0,0 +1,50 @@
|
|||
module \$__MUL25X18 (input [24:0] A, input [17:0] B, output [42:0] Y);
|
||||
parameter A_SIGNED = 0;
|
||||
parameter B_SIGNED = 0;
|
||||
parameter A_WIDTH = 0;
|
||||
parameter B_WIDTH = 0;
|
||||
parameter Y_WIDTH = 0;
|
||||
|
||||
wire [47:0] P_48;
|
||||
DSP48E1 #(
|
||||
// Disable all registers
|
||||
.ACASCREG(0),
|
||||
.ADREG(0),
|
||||
.A_INPUT("DIRECT"),
|
||||
.ALUMODEREG(0),
|
||||
.AREG(0),
|
||||
.BCASCREG(0),
|
||||
.B_INPUT("DIRECT"),
|
||||
.BREG(0),
|
||||
.CARRYINREG(0),
|
||||
.CARRYINSELREG(0),
|
||||
.CREG(0),
|
||||
.DREG(0),
|
||||
.INMODEREG(0),
|
||||
.MREG(0),
|
||||
.OPMODEREG(0),
|
||||
.PREG(0),
|
||||
.USE_MULT("MULTIPLY"),
|
||||
.USE_SIMD("ONE48"),
|
||||
.USE_DPORT("FALSE")
|
||||
) _TECHMAP_REPLACE_ (
|
||||
//Data path
|
||||
.A({{5{A[24]}}, A}),
|
||||
.B(B),
|
||||
.C(48'b0),
|
||||
.D(25'b0),
|
||||
.CARRYIN(1'b0),
|
||||
.P(P_48),
|
||||
|
||||
.INMODE(5'b00000),
|
||||
.ALUMODE(4'b0000),
|
||||
.OPMODE(7'b000101),
|
||||
.CARRYINSEL(3'b000),
|
||||
|
||||
.ACIN(30'b0),
|
||||
.BCIN(18'b0),
|
||||
.PCIN(48'b0),
|
||||
.CARRYIN(1'b0)
|
||||
);
|
||||
assign Y = P_48;
|
||||
endmodule
|
120
techlibs/analogdevices/ff_map.v
Normal file
120
techlibs/analogdevices/ff_map.v
Normal file
|
@ -0,0 +1,120 @@
|
|||
/*
|
||||
* yosys -- Yosys Open SYnthesis Suite
|
||||
*
|
||||
* Copyright (C) 2012 Claire Xenia Wolf <claire@yosyshq.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.
|
||||
*
|
||||
*/
|
||||
|
||||
`ifndef _NO_FFS
|
||||
|
||||
// Async reset, enable.
|
||||
|
||||
module \$_DFFE_NP0P_ (input D, C, E, R, output Q);
|
||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
FDCE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .CLR(R));
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
module \$_DFFE_PP0P_ (input D, C, E, R, output Q);
|
||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
FDCE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .CLR(R));
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
|
||||
module \$_DFFE_NP1P_ (input D, C, E, R, output Q);
|
||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
FDPE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .PRE(R));
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
module \$_DFFE_PP1P_ (input D, C, E, R, output Q);
|
||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
FDPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .PRE(R));
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
|
||||
// Async set and reset, enable.
|
||||
|
||||
module \$_DFFSRE_NPPP_ (input D, C, E, S, R, output Q);
|
||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
FDCPE #(.INIT(_TECHMAP_WIREINIT_Q_), .IS_C_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .CLR(R), .PRE(S));
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
module \$_DFFSRE_PPPP_ (input D, C, E, S, R, output Q);
|
||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
FDCPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .CLR(R), .PRE(S));
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
|
||||
// Sync reset, enable.
|
||||
|
||||
module \$_SDFFE_NP0P_ (input D, C, E, R, 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(R));
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
module \$_SDFFE_PP0P_ (input D, C, E, R, output Q);
|
||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
FDRE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .R(R));
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
|
||||
module \$_SDFFE_NP1P_ (input D, C, E, R, output Q);
|
||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
FDSE_1 #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .S(R));
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
module \$_SDFFE_PP1P_ (input D, C, E, R, output Q);
|
||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
FDSE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .S(R));
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
|
||||
// Latches with reset.
|
||||
|
||||
module \$_DLATCH_NP0_ (input E, R, D, output Q);
|
||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
LDCE #(.INIT(_TECHMAP_WIREINIT_Q_), .IS_G_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .CLR(R));
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
module \$_DLATCH_PP0_ (input E, R, D, output Q);
|
||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
LDCE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .CLR(R));
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
module \$_DLATCH_NP1_ (input E, R, D, output Q);
|
||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
LDPE #(.INIT(_TECHMAP_WIREINIT_Q_), .IS_G_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .PRE(R));
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
module \$_DLATCH_PP1_ (input E, R, D, output Q);
|
||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
LDPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .PRE(R));
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
|
||||
// Latches with set and reset.
|
||||
|
||||
module \$_DLATCH_NPP_ (input E, S, R, D, output Q);
|
||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
LDCPE #(.INIT(_TECHMAP_WIREINIT_Q_), .IS_G_INVERTED(1'b1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .CLR(R), .PRE(S));
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
module \$_DLATCH_PPP_ (input E, S, R, D, output Q);
|
||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
LDCPE #(.INIT(_TECHMAP_WIREINIT_Q_)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .G(E), .GE(1'b1), .CLR(R), .PRE(S));
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||
endmodule
|
||||
|
||||
`endif
|
||||
|
83
techlibs/analogdevices/lut_map.v
Normal file
83
techlibs/analogdevices/lut_map.v
Normal file
|
@ -0,0 +1,83 @@
|
|||
/*
|
||||
* yosys -- Yosys Open SYnthesis Suite
|
||||
*
|
||||
* Copyright (C) 2012 Claire Xenia Wolf <claire@yosyshq.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.
|
||||
*
|
||||
*/
|
||||
|
||||
// ============================================================================
|
||||
// LUT mapping
|
||||
|
||||
`ifndef _NO_LUTS
|
||||
|
||||
module \$lut (A, Y);
|
||||
parameter WIDTH = 0;
|
||||
parameter LUT = 0;
|
||||
|
||||
(* force_downto *)
|
||||
input [WIDTH-1:0] A;
|
||||
output Y;
|
||||
|
||||
generate
|
||||
if (WIDTH == 1) begin
|
||||
if (LUT == 2'b01) begin
|
||||
INV _TECHMAP_REPLACE_ (.O(Y), .I(A[0]));
|
||||
end else begin
|
||||
LUT1 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y),
|
||||
.I0(A[0]));
|
||||
end
|
||||
end else
|
||||
if (WIDTH == 2) begin
|
||||
LUT2 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y),
|
||||
.I0(A[0]), .I1(A[1]));
|
||||
end else
|
||||
if (WIDTH == 3) begin
|
||||
LUT3 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y),
|
||||
.I0(A[0]), .I1(A[1]), .I2(A[2]));
|
||||
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]));
|
||||
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]));
|
||||
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]));
|
||||
end else
|
||||
if (WIDTH == 7) begin
|
||||
wire f0, f1;
|
||||
\$lut #(.LUT(LUT[ 63: 0]), .WIDTH(6)) lut0 (.A(A[5:0]), .Y(f0));
|
||||
\$lut #(.LUT(LUT[127:64]), .WIDTH(6)) lut1 (.A(A[5:0]), .Y(f1));
|
||||
LUTMUX7 mux7(.I0(f0), .I1(f1), .S(A[6]), .O(Y));
|
||||
end else
|
||||
if (WIDTH == 8) begin
|
||||
wire f0, f1;
|
||||
\$lut #(.LUT(LUT[127: 0]), .WIDTH(7)) lut0 (.A(A[6:0]), .Y(f0));
|
||||
\$lut #(.LUT(LUT[255:128]), .WIDTH(7)) lut1 (.A(A[6:0]), .Y(f1));
|
||||
LUTMUX8 mux8(.I0(f0), .I1(f1), .S(A[7]), .O(Y));
|
||||
end else begin
|
||||
wire _TECHMAP_FAIL_ = 1;
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
`endif
|
||||
|
78
techlibs/analogdevices/lutrams.txt
Normal file
78
techlibs/analogdevices/lutrams.txt
Normal file
|
@ -0,0 +1,78 @@
|
|||
# LUT RAMs for Virtex 5, Virtex 6, Spartan 6, Series 7.
|
||||
# The corresponding mapping file is lutrams_xc5v_map.v
|
||||
|
||||
# Single-port RAMs.
|
||||
|
||||
ram distributed $__ANALOGDEVICES_LUTRAM_SP_ {
|
||||
cost 8;
|
||||
widthscale;
|
||||
option "ABITS" 5 {
|
||||
abits 5;
|
||||
widths 8 global;
|
||||
}
|
||||
option "ABITS" 6 {
|
||||
abits 6;
|
||||
widths 4 global;
|
||||
}
|
||||
option "ABITS" 7 {
|
||||
abits 7;
|
||||
widths 2 global;
|
||||
}
|
||||
option "ABITS" 8 {
|
||||
abits 8;
|
||||
widths 1 global;
|
||||
}
|
||||
init no_undef;
|
||||
prune_rom;
|
||||
port arsw "RW" {
|
||||
clock posedge;
|
||||
}
|
||||
}
|
||||
|
||||
# Dual-port RAMs.
|
||||
|
||||
ram distributed $__ANALOGDEVICES_LUTRAM_DP_ {
|
||||
cost 8;
|
||||
widthscale;
|
||||
option "ABITS" 5 {
|
||||
abits 5;
|
||||
widths 4 global;
|
||||
}
|
||||
option "ABITS" 6 {
|
||||
abits 6;
|
||||
widths 2 global;
|
||||
}
|
||||
option "ABITS" 7 {
|
||||
abits 7;
|
||||
widths 1 global;
|
||||
}
|
||||
init no_undef;
|
||||
prune_rom;
|
||||
port arsw "RW" {
|
||||
clock posedge;
|
||||
}
|
||||
port ar "R" {
|
||||
}
|
||||
}
|
||||
|
||||
# Simple dual port RAMs.
|
||||
|
||||
ram distributed $__ANALOGDEVICES_LUTRAM_SDP_ {
|
||||
cost 8;
|
||||
widthscale 7;
|
||||
option "ABITS" 5 {
|
||||
abits 5;
|
||||
widths 6 global;
|
||||
}
|
||||
option "ABITS" 6 {
|
||||
abits 6;
|
||||
widths 3 global;
|
||||
}
|
||||
init no_undef;
|
||||
prune_rom;
|
||||
port sw "W" {
|
||||
clock posedge;
|
||||
}
|
||||
port ar "R" {
|
||||
}
|
||||
}
|
459
techlibs/analogdevices/lutrams_map.v
Normal file
459
techlibs/analogdevices/lutrams_map.v
Normal file
|
@ -0,0 +1,459 @@
|
|||
// LUT RAMs for Virtex 5, Virtex 6, Spartan 6, Series 7, Ultrascale.
|
||||
// The definitions are in lutrams_xc5v.txt.
|
||||
|
||||
|
||||
module $__ANALOGDEVICES_LUTRAM_SP_ (...);
|
||||
|
||||
parameter INIT = 0;
|
||||
parameter OPTION_ABITS = 5;
|
||||
parameter WIDTH = 8;
|
||||
parameter BITS_USED = 0;
|
||||
|
||||
output [WIDTH-1:0] PORT_RW_RD_DATA;
|
||||
input [WIDTH-1:0] PORT_RW_WR_DATA;
|
||||
input [OPTION_ABITS-1:0] PORT_RW_ADDR;
|
||||
input PORT_RW_WR_EN;
|
||||
input PORT_RW_CLK;
|
||||
|
||||
function [(1 << OPTION_ABITS)-1:0] init_slice;
|
||||
input integer idx;
|
||||
integer i;
|
||||
for (i = 0; i < (1 << OPTION_ABITS); i = i + 1)
|
||||
init_slice[i] = INIT[i * WIDTH + idx];
|
||||
endfunction
|
||||
|
||||
function [(2 << OPTION_ABITS)-1:0] init_slice2;
|
||||
input integer idx;
|
||||
integer i;
|
||||
for (i = 0; i < (1 << OPTION_ABITS); i = i + 1)
|
||||
init_slice2[2 * i +: 2] = INIT[i * WIDTH + idx * 2 +: 2];
|
||||
endfunction
|
||||
|
||||
generate
|
||||
case(OPTION_ABITS)
|
||||
5: if (WIDTH == 8)
|
||||
RAM32M
|
||||
#(
|
||||
.INIT_D(init_slice2(0)),
|
||||
.INIT_C(init_slice2(1)),
|
||||
.INIT_B(init_slice2(2)),
|
||||
.INIT_A(init_slice2(3)),
|
||||
)
|
||||
_TECHMAP_REPLACE_
|
||||
(
|
||||
.DOA(PORT_RW_RD_DATA[7:6]),
|
||||
.DOB(PORT_RW_RD_DATA[5:4]),
|
||||
.DOC(PORT_RW_RD_DATA[3:2]),
|
||||
.DOD(PORT_RW_RD_DATA[1:0]),
|
||||
.DIA(PORT_RW_WR_DATA[7:6]),
|
||||
.DIB(PORT_RW_WR_DATA[5:4]),
|
||||
.DIC(PORT_RW_WR_DATA[3:2]),
|
||||
.DID(PORT_RW_WR_DATA[1:0]),
|
||||
.ADDRA(PORT_RW_ADDR),
|
||||
.ADDRB(PORT_RW_ADDR),
|
||||
.ADDRC(PORT_RW_ADDR),
|
||||
.ADDRD(PORT_RW_ADDR),
|
||||
.WE(PORT_RW_WR_EN),
|
||||
.WCLK(PORT_RW_CLK),
|
||||
);
|
||||
else
|
||||
RAM32M16
|
||||
#(
|
||||
.INIT_H(init_slice2(0)),
|
||||
.INIT_G(init_slice2(1)),
|
||||
.INIT_F(init_slice2(2)),
|
||||
.INIT_E(init_slice2(3)),
|
||||
.INIT_D(init_slice2(4)),
|
||||
.INIT_C(init_slice2(5)),
|
||||
.INIT_B(init_slice2(6)),
|
||||
.INIT_A(init_slice2(7)),
|
||||
)
|
||||
_TECHMAP_REPLACE_
|
||||
(
|
||||
.DOA(PORT_RW_RD_DATA[15:14]),
|
||||
.DOB(PORT_RW_RD_DATA[13:12]),
|
||||
.DOC(PORT_RW_RD_DATA[11:10]),
|
||||
.DOD(PORT_RW_RD_DATA[9:8]),
|
||||
.DOE(PORT_RW_RD_DATA[7:6]),
|
||||
.DOF(PORT_RW_RD_DATA[5:4]),
|
||||
.DOG(PORT_RW_RD_DATA[3:2]),
|
||||
.DOH(PORT_RW_RD_DATA[1:0]),
|
||||
.DIA(PORT_RW_WR_DATA[15:14]),
|
||||
.DIB(PORT_RW_WR_DATA[13:12]),
|
||||
.DIC(PORT_RW_WR_DATA[11:10]),
|
||||
.DID(PORT_RW_WR_DATA[9:8]),
|
||||
.DIE(PORT_RW_WR_DATA[7:6]),
|
||||
.DIF(PORT_RW_WR_DATA[5:4]),
|
||||
.DIG(PORT_RW_WR_DATA[3:2]),
|
||||
.DIH(PORT_RW_WR_DATA[1:0]),
|
||||
.ADDRA(PORT_RW_ADDR),
|
||||
.ADDRB(PORT_RW_ADDR),
|
||||
.ADDRC(PORT_RW_ADDR),
|
||||
.ADDRD(PORT_RW_ADDR),
|
||||
.ADDRE(PORT_RW_ADDR),
|
||||
.ADDRF(PORT_RW_ADDR),
|
||||
.ADDRG(PORT_RW_ADDR),
|
||||
.ADDRH(PORT_RW_ADDR),
|
||||
.WE(PORT_RW_WR_EN),
|
||||
.WCLK(PORT_RW_CLK),
|
||||
);
|
||||
6: begin
|
||||
genvar i;
|
||||
for (i = 0; i < WIDTH; i = i + 1)
|
||||
if (BITS_USED[i])
|
||||
RAM64X1S
|
||||
#(
|
||||
.INIT(init_slice(i)),
|
||||
)
|
||||
slice
|
||||
(
|
||||
.A0(PORT_RW_ADDR[0]),
|
||||
.A1(PORT_RW_ADDR[1]),
|
||||
.A2(PORT_RW_ADDR[2]),
|
||||
.A3(PORT_RW_ADDR[3]),
|
||||
.A4(PORT_RW_ADDR[4]),
|
||||
.A5(PORT_RW_ADDR[5]),
|
||||
.D(PORT_RW_WR_DATA[i]),
|
||||
.O(PORT_RW_RD_DATA[i]),
|
||||
.WE(PORT_RW_WR_EN),
|
||||
.WCLK(PORT_RW_CLK),
|
||||
);
|
||||
end
|
||||
default:
|
||||
$error("invalid OPTION_ABITS/WIDTH combination");
|
||||
endcase
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
module $__ANALOGDEVICES_LUTRAM_DP_ (...);
|
||||
|
||||
parameter INIT = 0;
|
||||
parameter OPTION_ABITS = 5;
|
||||
parameter WIDTH = 4;
|
||||
parameter BITS_USED = 0;
|
||||
|
||||
output [WIDTH-1:0] PORT_RW_RD_DATA;
|
||||
input [WIDTH-1:0] PORT_RW_WR_DATA;
|
||||
input [OPTION_ABITS-1:0] PORT_RW_ADDR;
|
||||
input PORT_RW_WR_EN;
|
||||
input PORT_RW_CLK;
|
||||
|
||||
output [WIDTH-1:0] PORT_R_RD_DATA;
|
||||
input [OPTION_ABITS-1:0] PORT_R_ADDR;
|
||||
|
||||
function [(1 << OPTION_ABITS)-1:0] init_slice;
|
||||
input integer idx;
|
||||
integer i;
|
||||
for (i = 0; i < (1 << OPTION_ABITS); i = i + 1)
|
||||
init_slice[i] = INIT[i * WIDTH + idx];
|
||||
endfunction
|
||||
|
||||
function [(2 << OPTION_ABITS)-1:0] init_slice2;
|
||||
input integer idx;
|
||||
integer i;
|
||||
for (i = 0; i < (1 << OPTION_ABITS); i = i + 1)
|
||||
init_slice2[2 * i +: 2] = INIT[i * WIDTH + idx * 2 +: 2];
|
||||
endfunction
|
||||
|
||||
generate
|
||||
case (OPTION_ABITS)
|
||||
5: if (WIDTH == 4)
|
||||
RAM32M
|
||||
#(
|
||||
.INIT_D(init_slice2(0)),
|
||||
.INIT_C(init_slice2(0)),
|
||||
.INIT_B(init_slice2(1)),
|
||||
.INIT_A(init_slice2(1)),
|
||||
)
|
||||
_TECHMAP_REPLACE_
|
||||
(
|
||||
.DOA(PORT_R_RD_DATA[3:2]),
|
||||
.DOB(PORT_RW_RD_DATA[3:2]),
|
||||
.DOC(PORT_R_RD_DATA[1:0]),
|
||||
.DOD(PORT_RW_RD_DATA[1:0]),
|
||||
.DIA(PORT_RW_WR_DATA[3:2]),
|
||||
.DIB(PORT_RW_WR_DATA[3:2]),
|
||||
.DIC(PORT_RW_WR_DATA[1:0]),
|
||||
.DID(PORT_RW_WR_DATA[1:0]),
|
||||
.ADDRA(PORT_R_ADDR),
|
||||
.ADDRB(PORT_RW_ADDR),
|
||||
.ADDRC(PORT_R_ADDR),
|
||||
.ADDRD(PORT_RW_ADDR),
|
||||
.WE(PORT_RW_WR_EN),
|
||||
.WCLK(PORT_RW_CLK),
|
||||
);
|
||||
else
|
||||
RAM32M16
|
||||
#(
|
||||
.INIT_H(init_slice2(0)),
|
||||
.INIT_G(init_slice2(0)),
|
||||
.INIT_F(init_slice2(1)),
|
||||
.INIT_E(init_slice2(1)),
|
||||
.INIT_D(init_slice2(2)),
|
||||
.INIT_C(init_slice2(2)),
|
||||
.INIT_B(init_slice2(3)),
|
||||
.INIT_A(init_slice2(3)),
|
||||
)
|
||||
_TECHMAP_REPLACE_
|
||||
(
|
||||
.DOA(PORT_R_RD_DATA[7:6]),
|
||||
.DOB(PORT_RW_RD_DATA[7:6]),
|
||||
.DOC(PORT_R_RD_DATA[5:4]),
|
||||
.DOD(PORT_RW_RD_DATA[5:4]),
|
||||
.DOE(PORT_R_RD_DATA[3:2]),
|
||||
.DOF(PORT_RW_RD_DATA[3:2]),
|
||||
.DOG(PORT_R_RD_DATA[1:0]),
|
||||
.DOH(PORT_RW_RD_DATA[1:0]),
|
||||
.DIA(PORT_RW_WR_DATA[7:6]),
|
||||
.DIB(PORT_RW_WR_DATA[7:6]),
|
||||
.DIC(PORT_RW_WR_DATA[5:4]),
|
||||
.DID(PORT_RW_WR_DATA[5:4]),
|
||||
.DIE(PORT_RW_WR_DATA[3:2]),
|
||||
.DIF(PORT_RW_WR_DATA[3:2]),
|
||||
.DIG(PORT_RW_WR_DATA[1:0]),
|
||||
.DIH(PORT_RW_WR_DATA[1:0]),
|
||||
.ADDRA(PORT_R_ADDR),
|
||||
.ADDRB(PORT_RW_ADDR),
|
||||
.ADDRC(PORT_R_ADDR),
|
||||
.ADDRD(PORT_RW_ADDR),
|
||||
.ADDRE(PORT_R_ADDR),
|
||||
.ADDRF(PORT_RW_ADDR),
|
||||
.ADDRG(PORT_R_ADDR),
|
||||
.ADDRH(PORT_RW_ADDR),
|
||||
.WE(PORT_RW_WR_EN),
|
||||
.WCLK(PORT_RW_CLK),
|
||||
);
|
||||
6: begin
|
||||
genvar i;
|
||||
for (i = 0; i < WIDTH; i = i + 1)
|
||||
if (BITS_USED[i])
|
||||
RAM64X1D
|
||||
#(
|
||||
.INIT(init_slice(i)),
|
||||
)
|
||||
slice
|
||||
(
|
||||
.A0(PORT_RW_ADDR[0]),
|
||||
.A1(PORT_RW_ADDR[1]),
|
||||
.A2(PORT_RW_ADDR[2]),
|
||||
.A3(PORT_RW_ADDR[3]),
|
||||
.A4(PORT_RW_ADDR[4]),
|
||||
.A5(PORT_RW_ADDR[5]),
|
||||
.D(PORT_RW_WR_DATA[i]),
|
||||
.SPO(PORT_RW_RD_DATA[i]),
|
||||
.WE(PORT_RW_WR_EN),
|
||||
.WCLK(PORT_RW_CLK),
|
||||
.DPRA0(PORT_R_ADDR[0]),
|
||||
.DPRA1(PORT_R_ADDR[1]),
|
||||
.DPRA2(PORT_R_ADDR[2]),
|
||||
.DPRA3(PORT_R_ADDR[3]),
|
||||
.DPRA4(PORT_R_ADDR[4]),
|
||||
.DPRA5(PORT_R_ADDR[5]),
|
||||
.DPO(PORT_R_RD_DATA[i]),
|
||||
);
|
||||
end
|
||||
7: begin
|
||||
genvar i;
|
||||
for (i = 0; i < WIDTH; i = i + 1)
|
||||
if (BITS_USED[i])
|
||||
RAM128X1D
|
||||
#(
|
||||
.INIT(init_slice(i)),
|
||||
)
|
||||
slice
|
||||
(
|
||||
.A(PORT_RW_ADDR),
|
||||
.D(PORT_RW_WR_DATA[i]),
|
||||
.SPO(PORT_RW_RD_DATA[i]),
|
||||
.WE(PORT_RW_WR_EN),
|
||||
.WCLK(PORT_RW_CLK),
|
||||
.DPRA(PORT_R_ADDR),
|
||||
.DPO(PORT_R_RD_DATA[i]),
|
||||
);
|
||||
end
|
||||
8: begin
|
||||
genvar i;
|
||||
for (i = 0; i < WIDTH; i = i + 1)
|
||||
if (BITS_USED[i])
|
||||
RAM256X1D
|
||||
#(
|
||||
.INIT(init_slice(i)),
|
||||
)
|
||||
slice
|
||||
(
|
||||
.A(PORT_RW_ADDR),
|
||||
.D(PORT_RW_WR_DATA[i]),
|
||||
.SPO(PORT_RW_RD_DATA[i]),
|
||||
.WE(PORT_RW_WR_EN),
|
||||
.WCLK(PORT_RW_CLK),
|
||||
.DPRA(PORT_R_ADDR),
|
||||
.DPO(PORT_R_RD_DATA[i]),
|
||||
);
|
||||
end
|
||||
default:
|
||||
$error("invalid OPTION_ABITS/WIDTH combination");
|
||||
endcase
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
module $__ANALOGDEVICES_LUTRAM_SDP_ (...);
|
||||
|
||||
parameter INIT = 0;
|
||||
parameter OPTION_ABITS = 5;
|
||||
parameter WIDTH = 6;
|
||||
parameter BITS_USED = 0;
|
||||
|
||||
input [WIDTH-1:0] PORT_W_WR_DATA;
|
||||
input [OPTION_ABITS-1:0] PORT_W_ADDR;
|
||||
input PORT_W_WR_EN;
|
||||
input PORT_W_CLK;
|
||||
|
||||
output [WIDTH-1:0] PORT_R_RD_DATA;
|
||||
input [OPTION_ABITS-1:0] PORT_R_ADDR;
|
||||
|
||||
function [(1 << OPTION_ABITS)-1:0] init_slice;
|
||||
input integer idx;
|
||||
integer i;
|
||||
for (i = 0; i < (1 << OPTION_ABITS); i = i + 1)
|
||||
init_slice[i] = INIT[i * WIDTH + idx];
|
||||
endfunction
|
||||
|
||||
function [(2 << OPTION_ABITS)-1:0] init_slice2;
|
||||
input integer idx;
|
||||
integer i;
|
||||
for (i = 0; i < (1 << OPTION_ABITS); i = i + 1)
|
||||
init_slice2[2 * i +: 2] = INIT[i * WIDTH + idx * 2 +: 2];
|
||||
endfunction
|
||||
|
||||
generate
|
||||
case (OPTION_ABITS)
|
||||
5: if (WIDTH == 6)
|
||||
RAM32M
|
||||
#(
|
||||
.INIT_C(init_slice2(0)),
|
||||
.INIT_B(init_slice2(1)),
|
||||
.INIT_A(init_slice2(2)),
|
||||
)
|
||||
_TECHMAP_REPLACE_
|
||||
(
|
||||
.DOA(PORT_R_RD_DATA[5:4]),
|
||||
.DOB(PORT_R_RD_DATA[3:2]),
|
||||
.DOC(PORT_R_RD_DATA[1:0]),
|
||||
.DIA(PORT_W_WR_DATA[5:4]),
|
||||
.DIB(PORT_W_WR_DATA[3:2]),
|
||||
.DIC(PORT_W_WR_DATA[1:0]),
|
||||
.ADDRA(PORT_R_ADDR),
|
||||
.ADDRB(PORT_R_ADDR),
|
||||
.ADDRC(PORT_R_ADDR),
|
||||
.ADDRD(PORT_W_ADDR),
|
||||
.WE(PORT_W_WR_EN),
|
||||
.WCLK(PORT_W_CLK),
|
||||
);
|
||||
else
|
||||
RAM32M16
|
||||
#(
|
||||
.INIT_G(init_slice2(0)),
|
||||
.INIT_F(init_slice2(1)),
|
||||
.INIT_E(init_slice2(2)),
|
||||
.INIT_D(init_slice2(3)),
|
||||
.INIT_C(init_slice2(4)),
|
||||
.INIT_B(init_slice2(5)),
|
||||
.INIT_A(init_slice2(6)),
|
||||
)
|
||||
_TECHMAP_REPLACE_
|
||||
(
|
||||
.DOA(PORT_R_RD_DATA[13:12]),
|
||||
.DOB(PORT_R_RD_DATA[11:10]),
|
||||
.DOC(PORT_R_RD_DATA[9:8]),
|
||||
.DOD(PORT_R_RD_DATA[7:6]),
|
||||
.DOE(PORT_R_RD_DATA[5:4]),
|
||||
.DOF(PORT_R_RD_DATA[3:2]),
|
||||
.DOG(PORT_R_RD_DATA[1:0]),
|
||||
.DIA(PORT_W_WR_DATA[13:12]),
|
||||
.DIB(PORT_W_WR_DATA[11:10]),
|
||||
.DIC(PORT_W_WR_DATA[9:8]),
|
||||
.DID(PORT_W_WR_DATA[7:6]),
|
||||
.DIE(PORT_W_WR_DATA[5:4]),
|
||||
.DIF(PORT_W_WR_DATA[3:2]),
|
||||
.DIG(PORT_W_WR_DATA[1:0]),
|
||||
.ADDRA(PORT_R_ADDR),
|
||||
.ADDRB(PORT_R_ADDR),
|
||||
.ADDRC(PORT_R_ADDR),
|
||||
.ADDRD(PORT_R_ADDR),
|
||||
.ADDRE(PORT_R_ADDR),
|
||||
.ADDRF(PORT_R_ADDR),
|
||||
.ADDRG(PORT_R_ADDR),
|
||||
.ADDRH(PORT_W_ADDR),
|
||||
.WE(PORT_W_WR_EN),
|
||||
.WCLK(PORT_W_CLK),
|
||||
);
|
||||
6: if (WIDTH == 3)
|
||||
RAM64M
|
||||
#(
|
||||
.INIT_C(init_slice(0)),
|
||||
.INIT_B(init_slice(1)),
|
||||
.INIT_A(init_slice(2)),
|
||||
)
|
||||
_TECHMAP_REPLACE_
|
||||
(
|
||||
.DOA(PORT_R_RD_DATA[2]),
|
||||
.DOB(PORT_R_RD_DATA[1]),
|
||||
.DOC(PORT_R_RD_DATA[0]),
|
||||
.DIA(PORT_W_WR_DATA[2]),
|
||||
.DIB(PORT_W_WR_DATA[1]),
|
||||
.DIC(PORT_W_WR_DATA[0]),
|
||||
.ADDRA(PORT_R_ADDR),
|
||||
.ADDRB(PORT_R_ADDR),
|
||||
.ADDRC(PORT_R_ADDR),
|
||||
.ADDRD(PORT_W_ADDR),
|
||||
.WE(PORT_W_WR_EN),
|
||||
.WCLK(PORT_W_CLK),
|
||||
);
|
||||
else
|
||||
RAM64M8
|
||||
#(
|
||||
.INIT_G(init_slice(0)),
|
||||
.INIT_F(init_slice(1)),
|
||||
.INIT_E(init_slice(2)),
|
||||
.INIT_D(init_slice(3)),
|
||||
.INIT_C(init_slice(4)),
|
||||
.INIT_B(init_slice(5)),
|
||||
.INIT_A(init_slice(6)),
|
||||
)
|
||||
_TECHMAP_REPLACE_
|
||||
(
|
||||
.DOA(PORT_R_RD_DATA[6]),
|
||||
.DOB(PORT_R_RD_DATA[5]),
|
||||
.DOC(PORT_R_RD_DATA[4]),
|
||||
.DOD(PORT_R_RD_DATA[3]),
|
||||
.DOE(PORT_R_RD_DATA[2]),
|
||||
.DOF(PORT_R_RD_DATA[1]),
|
||||
.DOG(PORT_R_RD_DATA[0]),
|
||||
.DIA(PORT_W_WR_DATA[6]),
|
||||
.DIB(PORT_W_WR_DATA[5]),
|
||||
.DIC(PORT_W_WR_DATA[4]),
|
||||
.DID(PORT_W_WR_DATA[3]),
|
||||
.DIE(PORT_W_WR_DATA[2]),
|
||||
.DIF(PORT_W_WR_DATA[1]),
|
||||
.DIG(PORT_W_WR_DATA[0]),
|
||||
.ADDRA(PORT_R_ADDR),
|
||||
.ADDRB(PORT_R_ADDR),
|
||||
.ADDRC(PORT_R_ADDR),
|
||||
.ADDRD(PORT_R_ADDR),
|
||||
.ADDRE(PORT_R_ADDR),
|
||||
.ADDRF(PORT_R_ADDR),
|
||||
.ADDRG(PORT_R_ADDR),
|
||||
.ADDRH(PORT_W_ADDR),
|
||||
.WE(PORT_W_WR_EN),
|
||||
.WCLK(PORT_W_CLK),
|
||||
);
|
||||
default:
|
||||
$error("invalid OPTION_ABITS/WIDTH combination");
|
||||
endcase
|
||||
endgenerate
|
||||
|
||||
endmodule
|
74
techlibs/analogdevices/mux_map.v
Normal file
74
techlibs/analogdevices/mux_map.v
Normal file
|
@ -0,0 +1,74 @@
|
|||
/*
|
||||
* yosys -- Yosys Open SYnthesis Suite
|
||||
*
|
||||
* Copyright (C) 2012 Claire Xenia Wolf <claire@yosyshq.com>
|
||||
* 2019 Eddie Hung <eddie@fpgeh.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.
|
||||
*
|
||||
*/
|
||||
|
||||
// The purpose of these mapping rules is to allow preserve all (sufficiently
|
||||
// wide) $shiftx cells during 'techmap' so that they can be mapped to hard
|
||||
// resources, rather than being bit-blasted to gates during 'techmap'
|
||||
// execution
|
||||
|
||||
module \$shiftx (A, B, Y);
|
||||
parameter A_SIGNED = 0;
|
||||
parameter B_SIGNED = 0;
|
||||
parameter A_WIDTH = 1;
|
||||
parameter B_WIDTH = 1;
|
||||
parameter Y_WIDTH = 1;
|
||||
|
||||
(* force_downto *)
|
||||
input [A_WIDTH-1:0] A;
|
||||
(* force_downto *)
|
||||
input [B_WIDTH-1:0] B;
|
||||
(* force_downto *)
|
||||
output [Y_WIDTH-1:0] Y;
|
||||
|
||||
parameter [B_WIDTH-1:0] _TECHMAP_CONSTMSK_B_ = 0;
|
||||
parameter [B_WIDTH-1:0] _TECHMAP_CONSTVAL_B_ = 0;
|
||||
|
||||
generate
|
||||
if (B_SIGNED) begin
|
||||
if (_TECHMAP_CONSTMSK_B_[B_WIDTH-1] && (_TECHMAP_CONSTVAL_B_[B_WIDTH-1] == 1'b0 || _TECHMAP_CONSTVAL_B_[B_WIDTH-1] === 1'bx))
|
||||
// Optimisation to remove B_SIGNED if sign bit of B is constant-0
|
||||
\$shiftx #(
|
||||
.A_SIGNED(A_SIGNED),
|
||||
.B_SIGNED(0),
|
||||
.A_WIDTH(A_WIDTH),
|
||||
.B_WIDTH(B_WIDTH-1'd1),
|
||||
.Y_WIDTH(Y_WIDTH)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.A(A), .B(B[B_WIDTH-2:0]), .Y(Y)
|
||||
);
|
||||
else
|
||||
wire _TECHMAP_FAIL_ = 1;
|
||||
end
|
||||
else begin
|
||||
if (((A_WIDTH + Y_WIDTH - 1) / Y_WIDTH) < `MIN_MUX_INPUTS)
|
||||
wire _TECHMAP_FAIL_ = 1;
|
||||
else
|
||||
\$__XILINX_SHIFTX #(
|
||||
.A_SIGNED(A_SIGNED),
|
||||
.B_SIGNED(B_SIGNED),
|
||||
.A_WIDTH(A_WIDTH),
|
||||
.B_WIDTH(B_WIDTH),
|
||||
.Y_WIDTH(Y_WIDTH)
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.A(A), .B(B), .Y(Y)
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
504
techlibs/analogdevices/synth_analogdevices.cc
Normal file
504
techlibs/analogdevices/synth_analogdevices.cc
Normal file
|
@ -0,0 +1,504 @@
|
|||
/*
|
||||
* yosys -- Yosys Open SYnthesis Suite
|
||||
*
|
||||
* Copyright (C) 2012 Claire Xenia Wolf <claire@yosyshq.com>
|
||||
* (C) 2019 Eddie Hung <eddie@fpgeh.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/register.h"
|
||||
#include "kernel/celltypes.h"
|
||||
#include "kernel/rtlil.h"
|
||||
#include "kernel/log.h"
|
||||
|
||||
USING_YOSYS_NAMESPACE
|
||||
PRIVATE_NAMESPACE_BEGIN
|
||||
|
||||
struct SynthAnalogDevicesPass : public ScriptPass
|
||||
{
|
||||
SynthAnalogDevicesPass() : ScriptPass("synth_analogdevices", "synthesis for Analog Devices FPGAs") { }
|
||||
|
||||
void on_register() override
|
||||
{
|
||||
RTLIL::constpad["synth_analogdevices.abc9.W"] = "300"; // Number with which ABC will map a 6-input gate
|
||||
// to one LUT6 (instead of a LUT5 + LUT2)
|
||||
}
|
||||
|
||||
void help() override
|
||||
{
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
log("\n");
|
||||
log(" synth_analogdevices [options]\n");
|
||||
log("\n");
|
||||
log("This command runs synthesis for Analog Devices FPGAs. This command does not operate on\n");
|
||||
log("partly selected designs.\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(" -nobram\n");
|
||||
log(" do not use block RAM cells in output netlist\n");
|
||||
log("\n");
|
||||
log(" -nolutram\n");
|
||||
log(" do not use distributed RAM cells in output netlist\n");
|
||||
log("\n");
|
||||
log(" -nosrl\n");
|
||||
log(" do not use distributed SRL cells in output netlist\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[7-8] resources to implement LUTs larger than native for\n");
|
||||
log(" the target\n");
|
||||
log("\n");
|
||||
log(" -nodsp\n");
|
||||
log(" do not use DSP48*s to implement multipliers and associated logic\n");
|
||||
log("\n");
|
||||
log(" -noiopad\n");
|
||||
log(" disable I/O buffer insertion (useful for hierarchical or \n");
|
||||
log(" out-of-context flows)\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\n");
|
||||
log(" or above this number of inputs (minimum value 2, recommended value >= 5)\n");
|
||||
log(" default: 0 (no inference)\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(" -dff\n");
|
||||
log(" run 'abc'/'abc9' with -dff option\n");
|
||||
log("\n");
|
||||
log(" -retime\n");
|
||||
log(" run 'abc' with '-D 1' option to enable flip-flop retiming.\n");
|
||||
log(" implies -dff.\n");
|
||||
log("\n");
|
||||
log(" -noabc9\n");
|
||||
log(" disable use of new ABC9 flow\n");
|
||||
log("\n");
|
||||
log("\n");
|
||||
log("The following commands are executed by this synthesis command:\n");
|
||||
help_script();
|
||||
log("\n");
|
||||
}
|
||||
|
||||
std::string top_opt, edif_file, json_file;
|
||||
bool flatten, retime, noiopad, noclkbuf, nobram, nolutram, nosrl, nocarry, nowidelut, nodsp;
|
||||
bool abc9, dff;
|
||||
bool flatten_before_abc;
|
||||
int widemux;
|
||||
int widelut_size;
|
||||
|
||||
void clear_flags() override
|
||||
{
|
||||
top_opt = "-auto-top";
|
||||
edif_file.clear();
|
||||
flatten = true;
|
||||
retime = false;
|
||||
noiopad = false;
|
||||
noclkbuf = false;
|
||||
nocarry = false;
|
||||
nobram = false;
|
||||
nolutram = false;
|
||||
nosrl = false;
|
||||
nocarry = false;
|
||||
nowidelut = false;
|
||||
nodsp = false;
|
||||
abc9 = true;
|
||||
dff = false;
|
||||
flatten_before_abc = false;
|
||||
widemux = 0;
|
||||
}
|
||||
|
||||
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||
{
|
||||
std::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] == "-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] == "-flatten_before_abc") {
|
||||
flatten_before_abc = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-retime") {
|
||||
dff = true;
|
||||
retime = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-nocarry") {
|
||||
nocarry = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-nowidelut") {
|
||||
nowidelut = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-iopad") {
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-noiopad") {
|
||||
noiopad = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-noclkbuf") {
|
||||
noclkbuf = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-nocarry") {
|
||||
nocarry = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-nobram") {
|
||||
nobram = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-nolutram") {
|
||||
nolutram = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-nosrl") {
|
||||
nosrl = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-widemux" && argidx+1 < args.size()) {
|
||||
widemux = atoi(args[++argidx].c_str());
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-noabc9") {
|
||||
abc9 = false;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-nodsp") {
|
||||
nodsp = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-dff") {
|
||||
dff = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-json" && argidx+1 < args.size()) {
|
||||
json_file = args[++argidx];
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
extra_args(args, argidx, design);
|
||||
|
||||
if (widemux != 0 && widemux < 2)
|
||||
log_cmd_error("-widemux value must be 0 or >= 2.\n");
|
||||
|
||||
if (!design->full_selection())
|
||||
log_cmd_error("This command only operates on fully selected designs!\n");
|
||||
|
||||
if (abc9 && retime)
|
||||
log_cmd_error("-retime option not currently compatible with -abc9!\n");
|
||||
|
||||
log_header(design, "Executing SYNTH_ANALOGDEVICES pass.\n");
|
||||
log_push();
|
||||
|
||||
run_script(design, run_from, run_to);
|
||||
|
||||
log_pop();
|
||||
}
|
||||
|
||||
void script() override
|
||||
{
|
||||
if (check_label("begin")) {
|
||||
std::string read_args;
|
||||
read_args += " -lib -specify +/analogdevices/cells_sim.v";
|
||||
run("read_verilog" + read_args);
|
||||
|
||||
run("read_verilog -lib +/analogdevices/cells_xtra.v");
|
||||
|
||||
run(stringf("hierarchy -check %s", top_opt.c_str()));
|
||||
}
|
||||
|
||||
if (check_label("prepare")) {
|
||||
run("proc");
|
||||
if (flatten || help_mode)
|
||||
run("flatten", "(with '-flatten')");
|
||||
if (active_design)
|
||||
active_design->scratchpad_unset("tribuf.added_something");
|
||||
run("tribuf -logic");
|
||||
if (noiopad && active_design && active_design->scratchpad_get_bool("tribuf.added_something"))
|
||||
log_error("Tristate buffers are unsupported without the '-iopad' option.\n");
|
||||
run("deminout");
|
||||
run("opt_expr");
|
||||
run("opt_clean");
|
||||
run("check");
|
||||
run("opt -nodffe -nosdff");
|
||||
run("fsm");
|
||||
run("opt");
|
||||
if (help_mode)
|
||||
run("wreduce [-keepdc]", "(option for '-widemux')");
|
||||
else
|
||||
run("wreduce" + std::string(widemux > 0 ? " -keepdc" : ""));
|
||||
run("peepopt");
|
||||
run("opt_clean");
|
||||
|
||||
if (widemux > 0 || help_mode)
|
||||
run("muxpack", " ('-widemux' only)");
|
||||
|
||||
// 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')");
|
||||
run("clean", " (skip if '-nosrl' and '-widemux=0')");
|
||||
}
|
||||
}
|
||||
|
||||
if (check_label("map_dsp", "(skip if '-nodsp')")) {
|
||||
if (!nodsp || help_mode) {
|
||||
run("memory_dff"); // xilinx_dsp will merge registers, reserve memory port registers first
|
||||
// NB: Xilinx multipliers are signed only
|
||||
if (help_mode)
|
||||
run("techmap -map +/mul2dsp.v -map +/analogdevices/{family}_dsp_map.v {options}");
|
||||
run("techmap -map +/mul2dsp.v -map +/analogdevices/dsp_map.v -D DSP_A_MAXWIDTH=25 -D DSP_B_MAXWIDTH=18 "
|
||||
"-D DSP_A_MAXWIDTH_PARTIAL=18 " // Partial multipliers are intentionally
|
||||
// limited to 18x18 in order to take
|
||||
// advantage of the (PCOUT << 17) -> PCIN
|
||||
// dedicated cascade chain capability
|
||||
"-D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 " // Blocks Nx1 multipliers
|
||||
"-D DSP_Y_MINWIDTH=9 " // UG901 suggests small multiplies are those 4x4 and smaller
|
||||
"-D DSP_SIGNEDONLY=1 -D DSP_NAME=$__MUL25X18");
|
||||
|
||||
run("select a:mul2dsp");
|
||||
run("setattr -unset mul2dsp");
|
||||
run("opt_expr -fine");
|
||||
run("wreduce");
|
||||
run("select -clear");
|
||||
if (help_mode)
|
||||
run("xilinx_dsp -family <family>");
|
||||
else
|
||||
run("xilinx_dsp -family xc7");
|
||||
run("chtype -set $mul t:$__soft_mul");
|
||||
}
|
||||
}
|
||||
|
||||
if (check_label("coarse")) {
|
||||
run("techmap -map +/cmp2lut.v -map +/cmp2lcu.v -D LUT_WIDTH=6");
|
||||
run("alumacc");
|
||||
run("share");
|
||||
run("opt");
|
||||
run("memory -nomap");
|
||||
run("opt_clean");
|
||||
}
|
||||
|
||||
if (check_label("map_memory")) {
|
||||
std::string params = "";
|
||||
std::string lutrams_map = "+/analogdevices/lutrams_<family>_map.v";
|
||||
std::string brams_map = "+/analogdevices/brams_<family>_map.v";
|
||||
if (help_mode) {
|
||||
params = " [...]";
|
||||
} else {
|
||||
params += " -logic-cost-rom 0.015625";
|
||||
params += " -lib +/analogdevices/lutrams.txt";
|
||||
lutrams_map = "+/analogdevices/lutrams_map.v";
|
||||
params += " -lib +/analogdevices/brams.txt";
|
||||
params += " -D HAS_SIZE_36";
|
||||
params += " -D HAS_CASCADE";
|
||||
params += " -D HAS_CONFLICT_BUG";
|
||||
params += " -D HAS_MIXWIDTH_SDP";
|
||||
brams_map = "+/analogdevices/brams_map.v";
|
||||
if (nolutram)
|
||||
params += " -no-auto-distributed";
|
||||
if (nobram)
|
||||
params += " -no-auto-block";
|
||||
}
|
||||
run("memory_libmap" + params);
|
||||
run("techmap -map " + lutrams_map);
|
||||
run("techmap -map " + brams_map);
|
||||
}
|
||||
|
||||
if (check_label("map_ffram")) {
|
||||
if (widemux > 0) {
|
||||
run("opt -fast -mux_bool -undriven -fine"); // Necessary to omit -mux_undef otherwise muxcover
|
||||
// performs less efficiently
|
||||
} else {
|
||||
run("opt -fast -full");
|
||||
}
|
||||
run("memory_map");
|
||||
}
|
||||
|
||||
if (check_label("fine")) {
|
||||
if (help_mode) {
|
||||
run("simplemap t:$mux", "('-widemux' only)");
|
||||
run("muxcover <internal options>", "('-widemux' only)");
|
||||
} else if (widemux > 0) {
|
||||
run("simplemap t:$mux");
|
||||
constexpr int cost_mux2 = 100;
|
||||
std::string muxcover_args = stringf(" -nodecode -mux2=%d", cost_mux2);
|
||||
switch (widemux) {
|
||||
case 2: muxcover_args += stringf(" -mux4=%d -mux8=%d -mux16=%d", cost_mux2+1, cost_mux2+2, cost_mux2+3); break;
|
||||
case 3:
|
||||
case 4: muxcover_args += stringf(" -mux4=%d -mux8=%d -mux16=%d", cost_mux2*(widemux-1)-2, cost_mux2*(widemux-1)-1, cost_mux2*(widemux-1)); break;
|
||||
case 5:
|
||||
case 6:
|
||||
case 7:
|
||||
case 8: muxcover_args += stringf(" -mux8=%d -mux16=%d", cost_mux2*(widemux-1)-1, cost_mux2*(widemux-1)); break;
|
||||
case 9:
|
||||
case 10:
|
||||
case 11:
|
||||
case 12:
|
||||
case 13:
|
||||
case 14:
|
||||
case 15:
|
||||
default: muxcover_args += stringf(" -mux16=%d", cost_mux2*(widemux-1)-1); break;
|
||||
}
|
||||
run("muxcover " + muxcover_args);
|
||||
}
|
||||
run("opt -full");
|
||||
|
||||
if (!nosrl || help_mode)
|
||||
run("xilinx_srl -variable -minlen 3", "(skip if '-nosrl')");
|
||||
|
||||
std::string techmap_args = " -map +/techmap.v -D LUT_SIZE=6";
|
||||
if (help_mode)
|
||||
techmap_args += " [-map +/analogdevices/mux_map.v]";
|
||||
else if (widemux > 0)
|
||||
techmap_args += stringf(" -D MIN_MUX_INPUTS=%d -map +/analogdevices/mux_map.v", widemux);
|
||||
if (!nocarry) {
|
||||
techmap_args += " -map +/analogdevices/arith_map.v";
|
||||
}
|
||||
run("techmap " + techmap_args);
|
||||
run("opt -fast");
|
||||
}
|
||||
|
||||
if (check_label("map_cells")) {
|
||||
// Needs to be done before logic optimization, so that inverters (inserted
|
||||
// here because of negative-polarity output enable) are handled.
|
||||
if (help_mode || !noiopad)
|
||||
run("iopadmap -bits -outpad OUTBUF I:O -inpad INBUF O:I -toutpad OBUFT ~T:I:O -tinoutpad IOBUF ~T:O:I:IO A:top", "(skip if '-noiopad')");
|
||||
std::string techmap_args = "-map +/techmap.v -map +/analogdevices/cells_map.v";
|
||||
if (widemux > 0)
|
||||
techmap_args += stringf(" -D MIN_MUX_INPUTS=%d", widemux);
|
||||
run("techmap " + techmap_args);
|
||||
run("clean");
|
||||
}
|
||||
|
||||
if (check_label("map_ffs")) {
|
||||
run("dfflegalize -cell $_DFFE_?P?P_ 01 -cell $_SDFFE_?P?P_ 01");
|
||||
if (abc9 || help_mode) {
|
||||
if (dff || help_mode)
|
||||
run("zinit -all w:* t:$_SDFFE_*", "('-dff' only)");
|
||||
run("techmap -map +/analogdevices/ff_map.v", "('-abc9' only)");
|
||||
}
|
||||
}
|
||||
|
||||
if (check_label("map_luts")) {
|
||||
run("opt_expr -mux_undef -noclkinv");
|
||||
if (flatten_before_abc)
|
||||
run("flatten");
|
||||
if (help_mode)
|
||||
run("abc -luts 2:2,3,6:5[,10,20] [-dff] [-D 1]", "(option for '-nowidelut', '-dff', '-retime')");
|
||||
else if (abc9) {
|
||||
run("read_verilog -icells -lib -specify +/analogdevices/abc9_model.v");
|
||||
std::string abc9_opts;
|
||||
std::string k = "synth_analogdevices.abc9.W";
|
||||
if (active_design && active_design->scratchpad.count(k))
|
||||
abc9_opts += stringf(" -W %s", active_design->scratchpad_get_string(k).c_str());
|
||||
else {
|
||||
abc9_opts += stringf(" -W %s", RTLIL::constpad.at("synth_analogdevices.abc9.W").c_str());
|
||||
}
|
||||
if (nowidelut)
|
||||
abc9_opts += stringf(" -maxlut 6");
|
||||
if (dff)
|
||||
abc9_opts += " -dff";
|
||||
run("abc9" + abc9_opts);
|
||||
}
|
||||
else {
|
||||
std::string abc_opts;
|
||||
if (nowidelut)
|
||||
abc_opts += " -luts 2:2,3,6:5";
|
||||
else
|
||||
abc_opts += " -luts 2:2,3,6:5,10,20";
|
||||
if (dff)
|
||||
abc_opts += " -dff";
|
||||
if (retime)
|
||||
abc_opts += " -D 1";
|
||||
run("abc" + abc_opts);
|
||||
}
|
||||
run("clean");
|
||||
|
||||
if (help_mode || !abc9)
|
||||
run("techmap -map +/analogdevices/ff_map.v", "(only if not '-abc9')");
|
||||
// This shregmap call infers fixed length shift registers after abc
|
||||
// has performed any necessary retiming
|
||||
if (!nosrl || help_mode)
|
||||
run("xilinx_srl -fixed -minlen 3", "(skip if '-nosrl')");
|
||||
std::string techmap_args = "-map +/analogdevices/lut_map.v -map +/analogdevices/cells_map.v";
|
||||
techmap_args += " -D LUT_WIDTH=6";
|
||||
run("techmap " + techmap_args);
|
||||
run("xilinx_dffopt");
|
||||
run("opt_lut_ins -tech xilinx");
|
||||
}
|
||||
|
||||
if (check_label("finalize")) {
|
||||
if (help_mode || !noclkbuf)
|
||||
run("clkbufmap -buf BUFG O:I", "(skip if '-noclkbuf')");
|
||||
run("clean");
|
||||
}
|
||||
|
||||
if (check_label("check")) {
|
||||
run("hierarchy -check");
|
||||
run("stat -tech xilinx");
|
||||
run("check -noinit");
|
||||
run("blackbox =A:whitebox");
|
||||
}
|
||||
|
||||
if (check_label("edif")) {
|
||||
if (!edif_file.empty() || help_mode)
|
||||
run(stringf("write_edif -pvector bra %s", edif_file.c_str()));
|
||||
}
|
||||
}
|
||||
} SynthAnalogDevicesPass;
|
||||
|
||||
PRIVATE_NAMESPACE_END
|
Loading…
Add table
Add a link
Reference in a new issue