mirror of https://github.com/YosysHQ/yosys.git
Merge pull request #5698 from YosysHQ/lofty/analogdevices
synth_analogdevices: synthesis for Analog Devices EFLX FPGAs [sc-273]
This commit is contained in:
commit
050483a6b2
1
Makefile
1
Makefile
|
|
@ -920,6 +920,7 @@ endif
|
||||||
|
|
||||||
# Tests that generate .mk with tests/gen-tests-makefile.sh
|
# Tests that generate .mk with tests/gen-tests-makefile.sh
|
||||||
MK_TEST_DIRS =
|
MK_TEST_DIRS =
|
||||||
|
MK_TEST_DIRS += tests/arch/analogdevices
|
||||||
MK_TEST_DIRS += tests/arch/anlogic
|
MK_TEST_DIRS += tests/arch/anlogic
|
||||||
MK_TEST_DIRS += tests/arch/ecp5
|
MK_TEST_DIRS += tests/arch/ecp5
|
||||||
MK_TEST_DIRS += tests/arch/efinix
|
MK_TEST_DIRS += tests/arch/efinix
|
||||||
|
|
|
||||||
|
|
@ -561,7 +561,7 @@ struct statdata_t {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tech == "xilinx") {
|
if (tech == "xilinx" || tech == "analogdevices") {
|
||||||
log("\n");
|
log("\n");
|
||||||
log(" Estimated number of LCs: %10u\n", estimate_xilinx_lc());
|
log(" Estimated number of LCs: %10u\n", estimate_xilinx_lc());
|
||||||
}
|
}
|
||||||
|
|
@ -628,7 +628,7 @@ struct statdata_t {
|
||||||
first_line = false;
|
first_line = false;
|
||||||
}
|
}
|
||||||
log("\n }\n");
|
log("\n }\n");
|
||||||
if (tech == "xilinx") {
|
if (tech == "xilinx" || tech == "analogdevices") {
|
||||||
log(" \"estimated_num_lc\": %u,\n", estimate_xilinx_lc());
|
log(" \"estimated_num_lc\": %u,\n", estimate_xilinx_lc());
|
||||||
}
|
}
|
||||||
if (tech == "cmos") {
|
if (tech == "cmos") {
|
||||||
|
|
@ -710,7 +710,7 @@ struct statdata_t {
|
||||||
log("\n");
|
log("\n");
|
||||||
log(" }");
|
log(" }");
|
||||||
}
|
}
|
||||||
if (tech == "xilinx") {
|
if (tech == "xilinx" || tech == "analogdevices") {
|
||||||
log(",\n");
|
log(",\n");
|
||||||
log(" \"estimated_num_lc\": %u", estimate_xilinx_lc());
|
log(" \"estimated_num_lc\": %u", estimate_xilinx_lc());
|
||||||
}
|
}
|
||||||
|
|
@ -908,7 +908,7 @@ struct StatPass : public Pass {
|
||||||
log("\n");
|
log("\n");
|
||||||
log(" -tech <technology>\n");
|
log(" -tech <technology>\n");
|
||||||
log(" print area estimate for the specified technology. Currently supported\n");
|
log(" print area estimate for the specified technology. Currently supported\n");
|
||||||
log(" values for <technology>: xilinx, cmos\n");
|
log(" values for <technology>: xilinx, analogdevices, cmos\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
log(" -width\n");
|
log(" -width\n");
|
||||||
log(" annotate internal cell types with their word width.\n");
|
log(" annotate internal cell types with their word width.\n");
|
||||||
|
|
@ -968,7 +968,7 @@ struct StatPass : public Pass {
|
||||||
if (!json_mode)
|
if (!json_mode)
|
||||||
log_header(design, "Printing statistics.\n");
|
log_header(design, "Printing statistics.\n");
|
||||||
|
|
||||||
if (techname != "" && techname != "xilinx" && techname != "cmos" && !json_mode)
|
if (techname != "" && techname != "xilinx" && techname != "analogdevices" && techname != "cmos" && !json_mode)
|
||||||
log_cmd_error("Unsupported technology: '%s'\n", techname);
|
log_cmd_error("Unsupported technology: '%s'\n", techname);
|
||||||
|
|
||||||
if (json_mode) {
|
if (json_mode) {
|
||||||
|
|
|
||||||
|
|
@ -39,7 +39,8 @@ struct OptLutInsPass : public Pass {
|
||||||
log("\n");
|
log("\n");
|
||||||
log(" -tech <technology>\n");
|
log(" -tech <technology>\n");
|
||||||
log(" Instead of generic $lut cells, operate on LUT cells specific\n");
|
log(" Instead of generic $lut cells, operate on LUT cells specific\n");
|
||||||
log(" to the given technology. Valid values are: xilinx, lattice, gowin.\n");
|
log(" to the given technology. Valid values are: xilinx, lattice,\n");
|
||||||
|
log(" gowin, analogdevices.\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
}
|
}
|
||||||
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||||
|
|
@ -58,7 +59,7 @@ struct OptLutInsPass : public Pass {
|
||||||
}
|
}
|
||||||
extra_args(args, argidx, design);
|
extra_args(args, argidx, design);
|
||||||
|
|
||||||
if (techname != "" && techname != "xilinx" && techname != "lattice" && techname != "ecp5" && techname != "gowin")
|
if (techname != "" && techname != "xilinx" && techname != "lattice" && techname != "analogdevices" && techname != "gowin")
|
||||||
log_cmd_error("Unsupported technology: '%s'\n", techname);
|
log_cmd_error("Unsupported technology: '%s'\n", techname);
|
||||||
|
|
||||||
for (auto module : design->selected_modules())
|
for (auto module : design->selected_modules())
|
||||||
|
|
@ -81,7 +82,7 @@ struct OptLutInsPass : public Pass {
|
||||||
inputs = cell->getPort(ID::A);
|
inputs = cell->getPort(ID::A);
|
||||||
output = cell->getPort(ID::Y);
|
output = cell->getPort(ID::Y);
|
||||||
lut = cell->getParam(ID::LUT);
|
lut = cell->getParam(ID::LUT);
|
||||||
} else if (techname == "xilinx" || techname == "gowin") {
|
} else if (techname == "xilinx" || techname == "gowin" || techname == "analogdevices") {
|
||||||
if (cell->type == ID(LUT1)) {
|
if (cell->type == ID(LUT1)) {
|
||||||
inputs = {
|
inputs = {
|
||||||
cell->getPort(ID(I0)),
|
cell->getPort(ID(I0)),
|
||||||
|
|
@ -126,11 +127,11 @@ struct OptLutInsPass : public Pass {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
lut = cell->getParam(ID::INIT);
|
lut = cell->getParam(ID::INIT);
|
||||||
if (techname == "xilinx")
|
if (techname == "xilinx" || techname == "analogdevices")
|
||||||
output = cell->getPort(ID::O);
|
output = cell->getPort(ID::O);
|
||||||
else
|
else
|
||||||
output = cell->getPort(ID::F);
|
output = cell->getPort(ID::F);
|
||||||
} else if (techname == "lattice" || techname == "ecp5") {
|
} else if (techname == "lattice") {
|
||||||
if (cell->type == ID(LUT4)) {
|
if (cell->type == ID(LUT4)) {
|
||||||
inputs = {
|
inputs = {
|
||||||
cell->getPort(ID::A),
|
cell->getPort(ID::A),
|
||||||
|
|
@ -236,7 +237,7 @@ struct OptLutInsPass : public Pass {
|
||||||
} else {
|
} else {
|
||||||
// xilinx, gowin
|
// xilinx, gowin
|
||||||
cell->setParam(ID::INIT, new_lut);
|
cell->setParam(ID::INIT, new_lut);
|
||||||
if (techname == "xilinx")
|
if (techname == "xilinx" || techname == "analogdevices")
|
||||||
log_assert(GetSize(new_inputs) <= 6);
|
log_assert(GetSize(new_inputs) <= 6);
|
||||||
else
|
else
|
||||||
log_assert(GetSize(new_inputs) <= 4);
|
log_assert(GetSize(new_inputs) <= 4);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,21 @@
|
||||||
|
|
||||||
|
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/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))
|
||||||
|
|
@ -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 \$__ANALOGDEVICES_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
|
||||||
|
|
@ -0,0 +1,173 @@
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
wire INITCO;
|
||||||
|
|
||||||
|
CRY4INIT init
|
||||||
|
(
|
||||||
|
.CYINIT(CI),
|
||||||
|
.CO (INITCO)
|
||||||
|
);
|
||||||
|
|
||||||
|
CRY4 carry4
|
||||||
|
(
|
||||||
|
.CYINIT(1'd0),
|
||||||
|
.CI (INITCO),
|
||||||
|
.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
|
||||||
|
wire INITCO;
|
||||||
|
|
||||||
|
CRY4INIT init
|
||||||
|
(
|
||||||
|
.CYINIT(CI),
|
||||||
|
.CO (INITCO)
|
||||||
|
);
|
||||||
|
|
||||||
|
CRY4 carry4
|
||||||
|
(
|
||||||
|
.CYINIT(1'd0),
|
||||||
|
.CI (INITCO),
|
||||||
|
.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
|
||||||
|
|
||||||
|
|
@ -0,0 +1,285 @@
|
||||||
|
ifdef IS_T16FFC {
|
||||||
|
ram block $__ANALOGDEVICES_BLOCKRAM_FULL_ {
|
||||||
|
option "ERR" "ECC" {
|
||||||
|
style "ECC";
|
||||||
|
option "SIZE" "2048x32" {
|
||||||
|
abits 11;
|
||||||
|
width 32;
|
||||||
|
byte 32;
|
||||||
|
option "MODE" "TDP" cost 4502;
|
||||||
|
option "MODE" "SDP" forbid;
|
||||||
|
option "MODE" "SP" forbid;
|
||||||
|
}
|
||||||
|
option "SIZE" "1024x32" {
|
||||||
|
abits 10;
|
||||||
|
width 32;
|
||||||
|
byte 32;
|
||||||
|
option "MODE" "TDP" forbid;
|
||||||
|
option "MODE" "SDP" cost 2402;
|
||||||
|
option "MODE" "SP" forbid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
option "ERR" "BP" {
|
||||||
|
style "BP";
|
||||||
|
option "SIZE" "2048x36" {
|
||||||
|
abits 11;
|
||||||
|
width 36;
|
||||||
|
byte 9;
|
||||||
|
option "MODE" "TDP" cost 4504;
|
||||||
|
option "MODE" "SDP" forbid;
|
||||||
|
option "MODE" "SP" forbid;
|
||||||
|
}
|
||||||
|
option "SIZE" "1024x36" {
|
||||||
|
abits 10;
|
||||||
|
width 36;
|
||||||
|
byte 9;
|
||||||
|
option "MODE" "TDP" forbid;
|
||||||
|
option "MODE" "SDP" cost 2404;
|
||||||
|
option "MODE" "SP" forbid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
option "ERR" "FP" {
|
||||||
|
style "FP";
|
||||||
|
option "SIZE" "2048x18" {
|
||||||
|
abits 11;
|
||||||
|
width 18;
|
||||||
|
byte 18;
|
||||||
|
option "MODE" "TDP" cost 2501;
|
||||||
|
option "MODE" "SDP" cost 2401;
|
||||||
|
option "MODE" "SP" forbid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
option "ERR" "NONE" {
|
||||||
|
option "SIZE" "8192x05" {
|
||||||
|
abits 13;
|
||||||
|
width 5;
|
||||||
|
byte 1;
|
||||||
|
option "MODE" "TDP" cost 2505;
|
||||||
|
option "MODE" "SDP" forbid;
|
||||||
|
option "MODE" "SP" forbid;
|
||||||
|
}
|
||||||
|
option "SIZE" "4096x09" {
|
||||||
|
abits 12;
|
||||||
|
width 9;
|
||||||
|
byte 1;
|
||||||
|
option "MODE" "TDP" cost 2509;
|
||||||
|
option "MODE" "SDP" forbid;
|
||||||
|
option "MODE" "SP" forbid;
|
||||||
|
}
|
||||||
|
option "SIZE" "4096x10" {
|
||||||
|
abits 12;
|
||||||
|
width 10;
|
||||||
|
byte 1;
|
||||||
|
option "MODE" "TDP" forbid;
|
||||||
|
option "MODE" "SDP" cost 2410;
|
||||||
|
option "MODE" "SP" forbid;
|
||||||
|
}
|
||||||
|
option "SIZE" "2048x20" {
|
||||||
|
abits 11;
|
||||||
|
width 20;
|
||||||
|
byte 1;
|
||||||
|
option "MODE" "TDP" forbid;
|
||||||
|
option "MODE" "SDP" forbid;
|
||||||
|
option "MODE" "SP" cost 2320;
|
||||||
|
}
|
||||||
|
option "SIZE" "2048x40" {
|
||||||
|
abits 11;
|
||||||
|
width 40;
|
||||||
|
byte 8;
|
||||||
|
option "MODE" "TDP" cost 4505;
|
||||||
|
option "MODE" "SDP" forbid;
|
||||||
|
option "MODE" "SP" forbid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# supports any initialization value, but need to export memory files
|
||||||
|
init any;
|
||||||
|
|
||||||
|
option "MODE" "TDP" {
|
||||||
|
port srsw "A" {
|
||||||
|
clock anyedge;
|
||||||
|
clken;
|
||||||
|
rdwr no_change;
|
||||||
|
}
|
||||||
|
port srsw "B" {
|
||||||
|
clock anyedge;
|
||||||
|
clken;
|
||||||
|
rdwr no_change;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
option "MODE" "SDP" {
|
||||||
|
port sw "A" {
|
||||||
|
clock anyedge;
|
||||||
|
clken;
|
||||||
|
}
|
||||||
|
port sr "B" {
|
||||||
|
clock anyedge;
|
||||||
|
clken;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
option "MODE" "SP" {
|
||||||
|
port srsw "A" {
|
||||||
|
clock anyedge;
|
||||||
|
clken;
|
||||||
|
rdwr no_change;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ram block $__ANALOGDEVICES_BLOCKRAM_HALF_ {
|
||||||
|
option "ERR" "ECC" {
|
||||||
|
style "ECC";
|
||||||
|
option "SIZE" "1024x32" {
|
||||||
|
abits 10;
|
||||||
|
width 32;
|
||||||
|
byte 32;
|
||||||
|
option "MODE" "SDP" cost 2402;
|
||||||
|
option "MODE" "SP" forbid;
|
||||||
|
option "MODE" "SP2" forbid;
|
||||||
|
}
|
||||||
|
option "SIZE" "512x32" {
|
||||||
|
abits 9;
|
||||||
|
width 32;
|
||||||
|
byte 32;
|
||||||
|
option "MODE" "SDP" forbid;
|
||||||
|
option "MODE" "SP" cost 2302;
|
||||||
|
option "MODE" "SP2" forbid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
option "ERR" "BP" {
|
||||||
|
style "BP";
|
||||||
|
option "SIZE" "1024x36" {
|
||||||
|
abits 10;
|
||||||
|
width 36;
|
||||||
|
byte 9;
|
||||||
|
option "MODE" "SDP" cost 2404;
|
||||||
|
option "MODE" "SP" forbid;
|
||||||
|
option "MODE" "SP2" forbid;
|
||||||
|
}
|
||||||
|
option "SIZE" "512x36" {
|
||||||
|
abits 9;
|
||||||
|
width 36;
|
||||||
|
byte 9;
|
||||||
|
option "MODE" "SDP" forbid;
|
||||||
|
option "MODE" "SP" cost 2304;
|
||||||
|
option "MODE" "SP2" forbid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
option "ERR" "FP" {
|
||||||
|
style "FP";
|
||||||
|
option "SIZE" "1024x18" {
|
||||||
|
abits 10;
|
||||||
|
width 18;
|
||||||
|
byte 18;
|
||||||
|
option "MODE" "SDP" forbid;
|
||||||
|
option "MODE" "SP" forbid;
|
||||||
|
option "MODE" "SP2" cost 2301;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
option "ERR" "NONE" {
|
||||||
|
option "SIZE" "4096x05" {
|
||||||
|
abits 12;
|
||||||
|
width 5;
|
||||||
|
byte 1;
|
||||||
|
option "MODE" "SDP" cost 2405;
|
||||||
|
option "MODE" "SP" cost 2305;
|
||||||
|
option "MODE" "SP2" forbid;
|
||||||
|
}
|
||||||
|
option "SIZE" "2048x09" {
|
||||||
|
abits 11;
|
||||||
|
width 9;
|
||||||
|
byte 1;
|
||||||
|
option "MODE" "SDP" cost 2409;
|
||||||
|
option "MODE" "SP" forbid;
|
||||||
|
option "MODE" "SP2" cost 2309;
|
||||||
|
}
|
||||||
|
option "SIZE" "2048x10" {
|
||||||
|
abits 11;
|
||||||
|
width 10;
|
||||||
|
byte 1;
|
||||||
|
option "MODE" "SDP" cost 2410;
|
||||||
|
option "MODE" "SP" forbid;
|
||||||
|
option "MODE" "SP2" forbid;
|
||||||
|
}
|
||||||
|
option "SIZE" "1024x20" {
|
||||||
|
abits 10;
|
||||||
|
width 20;
|
||||||
|
byte 1;
|
||||||
|
option "MODE" "SDP" forbid;
|
||||||
|
option "MODE" "SP" cost 2320;
|
||||||
|
option "MODE" "SP2" forbid;
|
||||||
|
}
|
||||||
|
option "SIZE" "1024x40" {
|
||||||
|
abits 10;
|
||||||
|
width 40;
|
||||||
|
byte 8;
|
||||||
|
option "MODE" "SDP" cost 2405;
|
||||||
|
option "MODE" "SP" forbid;
|
||||||
|
option "MODE" "SP2" forbid;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
option "MODE" "SDP" {
|
||||||
|
ifdef IS_T16FFC forbid;
|
||||||
|
port sw "A" {
|
||||||
|
clock anyedge;
|
||||||
|
clken;
|
||||||
|
}
|
||||||
|
port sr "B" {
|
||||||
|
clock anyedge;
|
||||||
|
clken;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
option "MODE" "SP" {
|
||||||
|
ifdef IS_T16FFC forbid;
|
||||||
|
port srsw "A" {
|
||||||
|
clock anyedge;
|
||||||
|
clken;
|
||||||
|
rdwr no_change;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
option "MODE" "SP2" {
|
||||||
|
ifdef IS_T40LP forbid;
|
||||||
|
port srsw "A" {
|
||||||
|
clock anyedge;
|
||||||
|
clken;
|
||||||
|
rdwr no_change;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ifdef IS_T40LP {
|
||||||
|
ram block $__ANALOGDEVICES_BLOCKRAM_QUARTER_ {
|
||||||
|
option "ERR" "BP" {
|
||||||
|
style "BP";
|
||||||
|
option "SIZE" "512x18" {
|
||||||
|
abits 9;
|
||||||
|
width 18;
|
||||||
|
byte 9;
|
||||||
|
option "MODE" "SP2" cost 2202;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
option "ERR" "NONE" {
|
||||||
|
option "SIZE" "2048x05" {
|
||||||
|
abits 11;
|
||||||
|
width 5;
|
||||||
|
byte 1;
|
||||||
|
option "MODE" "SP2" cost 2205;
|
||||||
|
}
|
||||||
|
option "SIZE" "1024x09" {
|
||||||
|
abits 10;
|
||||||
|
width 9;
|
||||||
|
byte 1;
|
||||||
|
option "MODE" "SP2" cost 2209;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
option "MODE" "SP2" {
|
||||||
|
port srsw "A" {
|
||||||
|
clock anyedge;
|
||||||
|
clken;
|
||||||
|
rdwr no_change;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -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
|
||||||
|
|
@ -0,0 +1,238 @@
|
||||||
|
module $__ANALOGDEVICES_BLOCKRAM_FULL_ (...);
|
||||||
|
// libmap params
|
||||||
|
parameter INIT = 0;
|
||||||
|
parameter OPTION_MODE = "NONE";
|
||||||
|
parameter OPTION_SIZE = "NONE";
|
||||||
|
parameter OPTION_ERR = "NONE";
|
||||||
|
parameter PORT_A_WR_EN_WIDTH = 1;
|
||||||
|
parameter PORT_A_CLK_POL = 1;
|
||||||
|
parameter PORT_B_WR_EN_WIDTH = PORT_A_WR_EN_WIDTH;
|
||||||
|
parameter PORT_B_CLK_POL = 1;
|
||||||
|
|
||||||
|
// needs -force-params
|
||||||
|
parameter WIDTH = 40;
|
||||||
|
parameter ABITS = 13;
|
||||||
|
|
||||||
|
// non libmap params
|
||||||
|
`ifdef IS_T40LP
|
||||||
|
localparam NODE = "T40LP_Gen2.4";
|
||||||
|
`endif
|
||||||
|
`ifdef IS_T16FFC
|
||||||
|
localparam NODE = "T16FFC_Gen2.4";
|
||||||
|
`endif
|
||||||
|
// localparam BRAM_MODE = "SDP_2048x36_BP";
|
||||||
|
localparam BRAM_MODE = (OPTION_ERR!="NONE") ? {OPTION_MODE, "_", OPTION_SIZE, "_", OPTION_ERR} :
|
||||||
|
{OPTION_MODE, "_", OPTION_SIZE};
|
||||||
|
localparam PBITS = (OPTION_ERR=="BP") ? PORT_A_WR_EN_WIDTH : 1;
|
||||||
|
|
||||||
|
// libmap ports
|
||||||
|
input PORT_A_CLK;
|
||||||
|
input PORT_A_CLK_EN;
|
||||||
|
input [ABITS-1:0] PORT_A_ADDR;
|
||||||
|
input [WIDTH-1:0] PORT_A_WR_DATA;
|
||||||
|
output [WIDTH-1:0] PORT_A_RD_DATA;
|
||||||
|
input [PORT_A_WR_EN_WIDTH-1:0] PORT_A_WR_EN;
|
||||||
|
|
||||||
|
input PORT_B_CLK;
|
||||||
|
input PORT_B_CLK_EN;
|
||||||
|
input [ABITS-1:0] PORT_B_ADDR;
|
||||||
|
input [WIDTH-1:0] PORT_B_WR_DATA;
|
||||||
|
output [WIDTH-1:0] PORT_B_RD_DATA;
|
||||||
|
input [PORT_B_WR_EN_WIDTH-1:0] PORT_B_WR_EN;
|
||||||
|
|
||||||
|
`ifdef IS_T40LP
|
||||||
|
RBRAM
|
||||||
|
`endif
|
||||||
|
`ifdef IS_T16FFC
|
||||||
|
RBRAM2
|
||||||
|
`endif
|
||||||
|
#(
|
||||||
|
.TARGET_NODE(NODE),
|
||||||
|
.BRAM_MODE(BRAM_MODE),
|
||||||
|
.QA_REG((OPTION_ERR=="ECC") ? 1 : 0),
|
||||||
|
.QB_REG((OPTION_ERR=="ECC") ? 1 : 0),
|
||||||
|
.CLKA_INV(!PORT_A_CLK_POL),
|
||||||
|
.CLKB_INV(!PORT_B_CLK_POL),
|
||||||
|
.DATA_WIDTH(WIDTH),
|
||||||
|
.ADDR_WIDTH(ABITS),
|
||||||
|
.WE_WIDTH(PORT_A_WR_EN_WIDTH),
|
||||||
|
.PERR_WIDTH(PBITS),
|
||||||
|
)
|
||||||
|
_TECHMAP_REPLACE_
|
||||||
|
(
|
||||||
|
.QA(PORT_A_RD_DATA),
|
||||||
|
.DA(PORT_A_WR_DATA),
|
||||||
|
.CEA(PORT_A_CLK_EN),
|
||||||
|
.WEA(PORT_A_WR_EN),
|
||||||
|
.AA(PORT_A_ADDR),
|
||||||
|
.CLKA(PORT_A_CLK),
|
||||||
|
.QB(PORT_B_RD_DATA),
|
||||||
|
.DB(PORT_B_WR_DATA),
|
||||||
|
.CEB(PORT_B_CLK_EN),
|
||||||
|
.WEB(PORT_B_WR_EN),
|
||||||
|
.AB(PORT_B_ADDR),
|
||||||
|
.CLKB(PORT_B_CLK),
|
||||||
|
);
|
||||||
|
|
||||||
|
// check config
|
||||||
|
generate
|
||||||
|
if (PORT_A_WR_EN_WIDTH == PORT_B_WR_EN_WIDTH)
|
||||||
|
case (BRAM_MODE)
|
||||||
|
`ifdef IS_T40LP
|
||||||
|
"SDP_1024x18_FP",
|
||||||
|
"SDP_1024x16_BP",
|
||||||
|
"SDP_2048x09",
|
||||||
|
"SDP_4096x05",
|
||||||
|
"SDP_1024x32_ECC",
|
||||||
|
"SDP_1024x40",
|
||||||
|
"SDP_1024x36_BP",
|
||||||
|
"SDP_512x32_ECC",
|
||||||
|
"SDP_512x36_BP",
|
||||||
|
"SDP_2048x10",
|
||||||
|
"SP_512x32_ECC",
|
||||||
|
"SP_512x36_BP",
|
||||||
|
"SP_1024x20",
|
||||||
|
"SP2_512x18_BP",
|
||||||
|
"SP2_1024x09",
|
||||||
|
"SP2_2048x05": wire _TECHMAP_FAIL_ = 0;
|
||||||
|
`endif
|
||||||
|
`ifdef IS_T16FFC
|
||||||
|
"TDP_2048x18_FP",
|
||||||
|
"TDP_2048x16_BP",
|
||||||
|
"TDP_4096x09",
|
||||||
|
"TDP_8192x05",
|
||||||
|
"TDP_2048x32_ECC",
|
||||||
|
"TDP_2048x40",
|
||||||
|
"TDP_2048x36_BP",
|
||||||
|
"SDP_2048x18_FP",
|
||||||
|
"SDP_2048x16_BP",
|
||||||
|
// The following are rejected in eXpreso
|
||||||
|
// "SDP_4096x09",
|
||||||
|
// "SDP_8192x05",
|
||||||
|
// "SDP_2048x32_ECC",
|
||||||
|
// "SDP_2048x40",
|
||||||
|
// "SDP_2048x36_BP",
|
||||||
|
"SDP_1024x32_ECC",
|
||||||
|
"SDP_1024x36_BP",
|
||||||
|
"SDP_4096x10",
|
||||||
|
"SP_1024x32_ECC",
|
||||||
|
"SP_1024x36_BP",
|
||||||
|
"SP_2048x20",
|
||||||
|
"SP2_1024x18_BP",
|
||||||
|
"SP2_2048x09",
|
||||||
|
"SP2_4096x05": wire _TECHMAP_FAIL_ = 0;
|
||||||
|
`endif
|
||||||
|
default: wire _TECHMAP_FAIL_ = 1;
|
||||||
|
endcase
|
||||||
|
else
|
||||||
|
wire _TECHMAP_FAIL_ = 1;
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module $__ANALOGDEVICES_BLOCKRAM_HALF_ (...);
|
||||||
|
// libmap params
|
||||||
|
parameter INIT = 0;
|
||||||
|
parameter OPTION_MODE = "NONE";
|
||||||
|
parameter OPTION_SIZE = "NONE";
|
||||||
|
parameter OPTION_ERR = "NONE";
|
||||||
|
parameter PORT_A_WR_EN_WIDTH = 1;
|
||||||
|
parameter PORT_A_CLK_POL = 1;
|
||||||
|
parameter PORT_B_WR_EN_WIDTH = PORT_A_WR_EN_WIDTH;
|
||||||
|
parameter PORT_B_CLK_POL = 1;
|
||||||
|
|
||||||
|
// needs -force-params
|
||||||
|
parameter WIDTH = 40;
|
||||||
|
parameter ABITS = 13;
|
||||||
|
|
||||||
|
// libmap ports
|
||||||
|
input PORT_A_CLK;
|
||||||
|
input PORT_A_CLK_EN;
|
||||||
|
input [ABITS-1:0] PORT_A_ADDR;
|
||||||
|
input [WIDTH-1:0] PORT_A_WR_DATA;
|
||||||
|
output [WIDTH-1:0] PORT_A_RD_DATA;
|
||||||
|
input [PORT_A_WR_EN_WIDTH-1:0] PORT_A_WR_EN;
|
||||||
|
|
||||||
|
input PORT_B_CLK;
|
||||||
|
input PORT_B_CLK_EN;
|
||||||
|
input [ABITS-1:0] PORT_B_ADDR;
|
||||||
|
input [WIDTH-1:0] PORT_B_WR_DATA;
|
||||||
|
output [WIDTH-1:0] PORT_B_RD_DATA;
|
||||||
|
input [PORT_B_WR_EN_WIDTH-1:0] PORT_B_WR_EN;
|
||||||
|
|
||||||
|
$__ANALOGDEVICES_BLOCKRAM_FULL_
|
||||||
|
# (
|
||||||
|
.INIT(INIT),
|
||||||
|
.OPTION_MODE(OPTION_MODE),
|
||||||
|
.OPTION_SIZE(OPTION_SIZE),
|
||||||
|
.OPTION_ERR(OPTION_ERR),
|
||||||
|
.PORT_A_WR_EN_WIDTH(PORT_A_WR_EN_WIDTH),
|
||||||
|
.PORT_A_CLK_POL(PORT_A_CLK_POL),
|
||||||
|
.PORT_B_WR_EN_WIDTH(PORT_B_WR_EN_WIDTH),
|
||||||
|
.PORT_B_CLK_POL(PORT_B_CLK_POL),
|
||||||
|
.WIDTH(WIDTH),
|
||||||
|
.ABITS(ABITS)
|
||||||
|
)
|
||||||
|
_TECHMAP_REPLACE_
|
||||||
|
(
|
||||||
|
.PORT_A_CLK(PORT_A_CLK),
|
||||||
|
.PORT_A_CLK_EN(PORT_A_CLK_EN),
|
||||||
|
.PORT_A_ADDR(PORT_A_ADDR),
|
||||||
|
.PORT_A_WR_DATA(PORT_A_WR_DATA),
|
||||||
|
.PORT_A_RD_DATA(PORT_A_RD_DATA),
|
||||||
|
.PORT_A_WR_EN(PORT_A_WR_EN),
|
||||||
|
.PORT_B_CLK(PORT_B_CLK),
|
||||||
|
.PORT_B_CLK_EN(PORT_B_CLK_EN),
|
||||||
|
.PORT_B_ADDR(PORT_B_ADDR),
|
||||||
|
.PORT_B_WR_DATA(PORT_B_WR_DATA),
|
||||||
|
.PORT_B_RD_DATA(PORT_B_RD_DATA),
|
||||||
|
.PORT_B_WR_EN(PORT_B_WR_EN)
|
||||||
|
);
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module $__ANALOGDEVICES_BLOCKRAM_QUARTER_ (...);
|
||||||
|
// libmap params
|
||||||
|
parameter INIT = 0;
|
||||||
|
parameter OPTION_MODE = "NONE";
|
||||||
|
parameter OPTION_SIZE = "NONE";
|
||||||
|
parameter OPTION_ERR = "NONE";
|
||||||
|
parameter PORT_A_WR_EN_WIDTH = 1;
|
||||||
|
parameter PORT_A_CLK_POL = 1;
|
||||||
|
parameter PORT_B_WR_EN_WIDTH = PORT_A_WR_EN_WIDTH;
|
||||||
|
parameter PORT_B_CLK_POL = 1;
|
||||||
|
|
||||||
|
// needs -force-params
|
||||||
|
parameter WIDTH = 40;
|
||||||
|
parameter ABITS = 13;
|
||||||
|
|
||||||
|
// libmap ports
|
||||||
|
input PORT_A_CLK;
|
||||||
|
input PORT_A_CLK_EN;
|
||||||
|
input [ABITS-1:0] PORT_A_ADDR;
|
||||||
|
input [WIDTH-1:0] PORT_A_WR_DATA;
|
||||||
|
output [WIDTH-1:0] PORT_A_RD_DATA;
|
||||||
|
input [PORT_A_WR_EN_WIDTH-1:0] PORT_A_WR_EN;
|
||||||
|
|
||||||
|
$__ANALOGDEVICES_BLOCKRAM_FULL_
|
||||||
|
# (
|
||||||
|
.INIT(INIT),
|
||||||
|
.OPTION_MODE(OPTION_MODE),
|
||||||
|
.OPTION_SIZE(OPTION_SIZE),
|
||||||
|
.OPTION_ERR(OPTION_ERR),
|
||||||
|
.PORT_A_WR_EN_WIDTH(PORT_A_WR_EN_WIDTH),
|
||||||
|
.PORT_A_CLK_POL(PORT_A_CLK_POL),
|
||||||
|
.PORT_B_WR_EN_WIDTH(PORT_B_WR_EN_WIDTH),
|
||||||
|
.PORT_B_CLK_POL(PORT_B_CLK_POL),
|
||||||
|
.WIDTH(WIDTH),
|
||||||
|
.ABITS(ABITS)
|
||||||
|
)
|
||||||
|
_TECHMAP_REPLACE_
|
||||||
|
(
|
||||||
|
.PORT_A_CLK(PORT_A_CLK),
|
||||||
|
.PORT_A_CLK_EN(PORT_A_CLK_EN),
|
||||||
|
.PORT_A_ADDR(PORT_A_ADDR),
|
||||||
|
.PORT_A_WR_DATA(PORT_A_WR_DATA),
|
||||||
|
.PORT_A_RD_DATA(PORT_A_RD_DATA),
|
||||||
|
.PORT_A_WR_EN(PORT_A_WR_EN),
|
||||||
|
);
|
||||||
|
endmodule
|
||||||
|
|
@ -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;
|
||||||
|
|
||||||
|
\$__XILINX_SHREG_ #(.DEPTH(DEPTH), .INIT(INIT), .CLKPOL(CLKPOL), .ENPOL(ENPOL)) _TECHMAP_REPLACE_ (.C(C), .D(D), .L(DEPTH-1), .E(E), .Q(Q));
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module \$__XILINX_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)
|
||||||
|
FFRE #(.INIT(INIT_R)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(CE), .R(1'b0));
|
||||||
|
else
|
||||||
|
FFRE_N #(.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));
|
||||||
|
\$__XILINX_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));
|
||||||
|
\$__XILINX_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));
|
||||||
|
\$__XILINX_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;
|
||||||
|
\$__XILINX_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));
|
||||||
|
\$__XILINX_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_)
|
||||||
|
\$__XILINX_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++)
|
||||||
|
\$__XILINX_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)
|
||||||
|
\$__XILINX_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
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,60 @@
|
||||||
|
module \$__MUL22X22 (input [21:0] A, input [21:0] B, output [43: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;
|
||||||
|
RBBDSP #(
|
||||||
|
// Disable all registers
|
||||||
|
.AI_SEL_IN(1'b0),
|
||||||
|
.BC_CI(2'b00),
|
||||||
|
.BI_SEL(1'b0),
|
||||||
|
.BI_SEL_IN(1'b0),
|
||||||
|
.CE_A(1'b0),
|
||||||
|
.CE_ADD(1'b0),
|
||||||
|
.CE_B(1'b0),
|
||||||
|
.CE_C(1'b0),
|
||||||
|
.CE_CRY(1'b0),
|
||||||
|
.CE_D(2'b0),
|
||||||
|
.CE_M(1'b0),
|
||||||
|
.CE_OPCODE(1'b0),
|
||||||
|
.CE_PADD(1'b0),
|
||||||
|
.CE_RST(1'b1),
|
||||||
|
.CE_SEL(1'b0),
|
||||||
|
.CE_SFT(1'b0),
|
||||||
|
.CI_SEL(4'd3),
|
||||||
|
.DI_SEL(1'b0),
|
||||||
|
.DI_SEL_IN(1'b0),
|
||||||
|
.OPCODE_SEL(1'b0),
|
||||||
|
.OP_ADD(10'b0),
|
||||||
|
.OP_CPLX(1'b0),
|
||||||
|
.OP_MULT(2'b11),
|
||||||
|
.OP_PADD(10'b0000000000),
|
||||||
|
.OP_SFT(6'b000000),
|
||||||
|
.OP_X(4'b1010),
|
||||||
|
.OP_Y(4'b0101),
|
||||||
|
.OP_Z(4'b0000),
|
||||||
|
.PO_LOC_SEL(1'b1),
|
||||||
|
.PO_NWK_SEL(1'b1),
|
||||||
|
.REG_A(1'b0),
|
||||||
|
.REG_ADD(1'b0),
|
||||||
|
.REG_B(1'b0),
|
||||||
|
.REG_C(1'b0),
|
||||||
|
.REG_CRY(1'b0),
|
||||||
|
.REG_D(2'b0),
|
||||||
|
.REG_M(1'b0),
|
||||||
|
.REG_OPCODE(1'b0),
|
||||||
|
.REG_PADD(1'b0),
|
||||||
|
.REG_SFT(1'b0),
|
||||||
|
.RST_SEL(1'b0),
|
||||||
|
.FF_SYNC_RST(1'b0),
|
||||||
|
) _TECHMAP_REPLACE_ (
|
||||||
|
.P(P_48),
|
||||||
|
.A(A),
|
||||||
|
.B(B),
|
||||||
|
.D(48'b0)
|
||||||
|
);
|
||||||
|
assign Y = P_48;
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,63 @@
|
||||||
|
/*
|
||||||
|
* 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);
|
||||||
|
FFCE_N #(.INIT(1'b0)) _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);
|
||||||
|
FFCE #(.INIT(1'b0)) _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);
|
||||||
|
FFPE_N #(.INIT(1'b1)) _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);
|
||||||
|
FFPE #(.INIT(1'b1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .PRE(R));
|
||||||
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
// Sync reset, enable.
|
||||||
|
|
||||||
|
module \$_SDFFE_NP0P_ (input D, C, E, R, output Q);
|
||||||
|
FFRE_N #(.INIT(1'b0)) _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);
|
||||||
|
FFRE #(.INIT(1'b0)) _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);
|
||||||
|
FFSE_N #(.INIT(1'b1)) _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);
|
||||||
|
FFSE #(.INIT(1'b1)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .C(C), .CE(E), .S(R));
|
||||||
|
wire _TECHMAP_REMOVEINIT_Q_ = 1;
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
`endif
|
||||||
|
|
||||||
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* 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
|
||||||
|
LUT1 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y),
|
||||||
|
.I0(A[0]));
|
||||||
|
end else
|
||||||
|
if (WIDTH == 2) begin
|
||||||
|
LUT2 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.O(Y),
|
||||||
|
.I0(A[0]), .I1(A[1]));
|
||||||
|
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
|
||||||
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
ram distributed $__ANALOGDEVICES_LUTRAM_ {
|
||||||
|
option "SIZE" 32 abits 5;
|
||||||
|
option "SIZE" 64 abits 6;
|
||||||
|
width 1;
|
||||||
|
init no_undef;
|
||||||
|
prune_rom;
|
||||||
|
port arsw "RW" {
|
||||||
|
clock posedge;
|
||||||
|
}
|
||||||
|
option "MODE" "SP" {
|
||||||
|
option "SIZE" 32 cost 2;
|
||||||
|
option "SIZE" 64 cost 2;
|
||||||
|
}
|
||||||
|
option "MODE" "DP" {
|
||||||
|
option "SIZE" 32 cost 4;
|
||||||
|
option "SIZE" 64 cost 8;
|
||||||
|
port ar "R" {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,139 @@
|
||||||
|
module $__ANALOGDEVICES_LUTRAM_ (...);
|
||||||
|
|
||||||
|
parameter INIT = 0;
|
||||||
|
parameter OPTION_SIZE = 32;
|
||||||
|
parameter OPTION_MODE = "SP";
|
||||||
|
parameter ABITS = 5;
|
||||||
|
parameter WIDTH = 1;
|
||||||
|
|
||||||
|
output PORT_RW_RD_DATA;
|
||||||
|
input PORT_RW_WR_DATA;
|
||||||
|
input [ABITS-1:0] PORT_RW_ADDR;
|
||||||
|
input PORT_RW_WR_EN;
|
||||||
|
input PORT_RW_CLK;
|
||||||
|
|
||||||
|
output PORT_R_RD_DATA;
|
||||||
|
input [ABITS-1:0] PORT_R_ADDR;
|
||||||
|
|
||||||
|
generate
|
||||||
|
if (OPTION_MODE=="SP")
|
||||||
|
case(OPTION_SIZE)
|
||||||
|
32:
|
||||||
|
RAMS32X1
|
||||||
|
#(
|
||||||
|
.INIT(INIT)
|
||||||
|
)
|
||||||
|
_TECHMAP_REPLACE_
|
||||||
|
(
|
||||||
|
.O(PORT_RW_RD_DATA),
|
||||||
|
.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]),
|
||||||
|
.D(PORT_RW_WR_DATA),
|
||||||
|
.WCLK(PORT_RW_CLK),
|
||||||
|
.WE(PORT_RW_WR_EN)
|
||||||
|
);
|
||||||
|
64:
|
||||||
|
RAMS64X1
|
||||||
|
#(
|
||||||
|
.INIT(INIT)
|
||||||
|
)
|
||||||
|
_TECHMAP_REPLACE_
|
||||||
|
(
|
||||||
|
.O(PORT_RW_RD_DATA),
|
||||||
|
.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),
|
||||||
|
.WCLK(PORT_RW_CLK),
|
||||||
|
.WE(PORT_RW_WR_EN)
|
||||||
|
);
|
||||||
|
default:
|
||||||
|
$error("invalid SIZE/MODE combination");
|
||||||
|
endcase
|
||||||
|
else if (OPTION_MODE=="DP")
|
||||||
|
case (OPTION_SIZE)
|
||||||
|
32:
|
||||||
|
RAMD32X1
|
||||||
|
#(
|
||||||
|
.INIT(INIT)
|
||||||
|
)
|
||||||
|
_TECHMAP_REPLACE_
|
||||||
|
(
|
||||||
|
.DPO(PORT_R_RD_DATA),
|
||||||
|
.SPO(PORT_RW_RD_DATA),
|
||||||
|
.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]),
|
||||||
|
.D(PORT_RW_WR_DATA),
|
||||||
|
.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]),
|
||||||
|
.WCLK(PORT_RW_CLK),
|
||||||
|
.WE(PORT_RW_WR_EN)
|
||||||
|
);
|
||||||
|
64:
|
||||||
|
RAMD64X1
|
||||||
|
#(
|
||||||
|
.INIT(INIT)
|
||||||
|
)
|
||||||
|
_TECHMAP_REPLACE_
|
||||||
|
(
|
||||||
|
.DPO(PORT_R_RD_DATA),
|
||||||
|
.SPO(PORT_RW_RD_DATA),
|
||||||
|
.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),
|
||||||
|
.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]),
|
||||||
|
.WCLK(PORT_RW_CLK),
|
||||||
|
.WE(PORT_RW_WR_EN)
|
||||||
|
);
|
||||||
|
default:
|
||||||
|
$error("invalid SIZE/MODE combination");
|
||||||
|
endcase
|
||||||
|
else
|
||||||
|
wire _TECHMAP_FAIL_ = 1;
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
|
||||||
|
module $__ANALOGDEVICES_LUTRAM_DP_ (...);
|
||||||
|
|
||||||
|
parameter INIT = 0;
|
||||||
|
parameter OPTION_SIZE = 32;
|
||||||
|
parameter ABITS = 5;
|
||||||
|
parameter WIDTH = 1;
|
||||||
|
|
||||||
|
output PORT_RW_RD_DATA;
|
||||||
|
input PORT_RW_WR_DATA;
|
||||||
|
input [ABITS-1:0] PORT_RW_ADDR;
|
||||||
|
input PORT_RW_WR_EN;
|
||||||
|
input PORT_RW_CLK;
|
||||||
|
|
||||||
|
output PORT_R_RD_DATA;
|
||||||
|
input [ABITS-1:0] PORT_R_ADDR;
|
||||||
|
|
||||||
|
generate
|
||||||
|
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
@ -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
|
||||||
|
\$__ANALOGDEVICES_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
|
||||||
|
|
@ -0,0 +1,49 @@
|
||||||
|
module FF (input C, D, output Q);
|
||||||
|
parameter INIT = 1'b0;
|
||||||
|
if (INIT === 1'b1) begin
|
||||||
|
FFPE _TECHMAP_REPLACE_ (.C(C), .D(D), .PRE(1'b0), .CE(1'b1), .Q(Q));
|
||||||
|
end else begin
|
||||||
|
FFCE _TECHMAP_REPLACE_ (.C(C), .D(D), .CLR(1'b0), .CE(1'b1), .Q(Q));
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module FF_N (input C, D, output Q);
|
||||||
|
parameter INIT = 1'b0;
|
||||||
|
if (INIT === 1'b1) begin
|
||||||
|
FFPE_N _TECHMAP_REPLACE_ (.C(C), .D(D), .PRE(1'b0), .CE(1'b1), .Q(Q));
|
||||||
|
end else begin
|
||||||
|
FFCE_N _TECHMAP_REPLACE_ (.C(C), .D(D), .CLR(1'b0), .CE(1'b1), .Q(Q));
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module FFC (input C, D, CLR, output Q);
|
||||||
|
FFCE _TECHMAP_REPLACE_ (.C(C), .D(D), .CLR(CLR), .CE(1'b1), .Q(Q));
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module FFC_N (input C, D, CLR, output Q);
|
||||||
|
FFCE_N _TECHMAP_REPLACE_ (.C(C), .D(D), .CLR(CLR), .CE(1'b1), .Q(Q));
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module FFP (input C, D, PRE, output Q);
|
||||||
|
FFPE _TECHMAP_REPLACE_ (.C(C), .D(D), .PRE(PRE), .CE(1'b1), .Q(Q));
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module FFP_N (input C, D, CLR, output Q);
|
||||||
|
FFPE_N _TECHMAP_REPLACE_ (.C(C), .D(D), .PRE(PRE), .CE(1'b1), .Q(Q));
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module FFR (input C, D, R, output Q);
|
||||||
|
FFRE _TECHMAP_REPLACE_ (.C(C), .D(D), .R(R), .CE(1'b1), .Q(Q));
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module FFR_N (input C, D, R, output Q);
|
||||||
|
FFRE_N _TECHMAP_REPLACE_ (.C(C), .D(D), .R(R), .CE(1'b1), .Q(Q));
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module FFS (input C, D, S, output Q);
|
||||||
|
FFSE _TECHMAP_REPLACE_ (.C(C), .D(D), .S(S), .CE(1'b1), .Q(Q));
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module FFS_N (input C, D, S, output Q);
|
||||||
|
FFSE_N _TECHMAP_REPLACE_ (.C(C), .D(D), .S(S), .CE(1'b1), .Q(Q));
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,516 @@
|
||||||
|
/*
|
||||||
|
* 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(" -tech <tech>\n");
|
||||||
|
log(" run synthesis for the specified ADI technology process\n");
|
||||||
|
log(" currently only affects the type of BRAM used.\n");
|
||||||
|
log(" supported values:\n");
|
||||||
|
log(" - t40lp (RBRAM)\n");
|
||||||
|
log(" - t16ffc (RBRAM2, default)\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, tech, tech_param;
|
||||||
|
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();
|
||||||
|
tech = "t16ffc";
|
||||||
|
tech_param = " -D IS_T16FFC";
|
||||||
|
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] == "-tech" && argidx+1 < args.size()) {
|
||||||
|
tech = args[++argidx];
|
||||||
|
if (tech == "t16ffc")
|
||||||
|
tech_param = " -D IS_T16FFC";
|
||||||
|
else if (tech == "t40lp")
|
||||||
|
tech_param = " -D IS_T40LP";
|
||||||
|
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 (!(tech == "t16ffc" || tech == "t40lp"))
|
||||||
|
log_cmd_error("Invalid ADI -tech setting: '%s'.\n", tech);
|
||||||
|
|
||||||
|
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")) {
|
||||||
|
run(stringf("read_verilog -lib -specify %s +/analogdevices/cells_sim.v", tech_param));
|
||||||
|
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: Analog Devices 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=22 -D DSP_B_MAXWIDTH=22 "
|
||||||
|
"-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=$__MUL22X22");
|
||||||
|
|
||||||
|
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_map.v";
|
||||||
|
std::string brams_map = "+/analogdevices/brams_map.v";
|
||||||
|
if (help_mode) {
|
||||||
|
params = " [...]";
|
||||||
|
} else {
|
||||||
|
params += " -logic-cost-rom 0.015625";
|
||||||
|
params += " -force-params";
|
||||||
|
params += " -lib +/analogdevices/lutrams.txt";
|
||||||
|
params += " -lib +/analogdevices/brams.txt";
|
||||||
|
params += tech_param;
|
||||||
|
brams_map += tech_param;
|
||||||
|
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 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_ r -cell $_SDFFE_?P?P_ r");
|
||||||
|
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 -dress" + 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 analogdevices");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_label("finalize")) {
|
||||||
|
run("clean");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_label("check")) {
|
||||||
|
run("hierarchy -check");
|
||||||
|
run("stat -tech analogdevices");
|
||||||
|
run("check -noinit");
|
||||||
|
run("blackbox =A:whitebox");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (check_label("edif")) {
|
||||||
|
if (!edif_file.empty() || help_mode) {
|
||||||
|
run("delete t:$assert t:$scopeinfo");
|
||||||
|
run(stringf("write_edif %s", edif_file.c_str()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} SynthAnalogDevicesPass;
|
||||||
|
|
||||||
|
PRIVATE_NAMESPACE_END
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
t_*.ys
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
read_verilog ../common/add_sub.v
|
||||||
|
hierarchy -top top
|
||||||
|
proc
|
||||||
|
design -save orig
|
||||||
|
|
||||||
|
equiv_opt -assert -map +/analogdevices/cells_sim.v synth_analogdevices -noiopad # equivalency check
|
||||||
|
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||||
|
cd top # Constrain all select calls below inside the top module
|
||||||
|
stat
|
||||||
|
select -assert-count 8 t:LUT2
|
||||||
|
select -assert-count 2 t:CRY4
|
||||||
|
select -assert-count 2 t:CRY4INIT
|
||||||
|
select -assert-none t:LUT2 t:CRY4 t:CRY4INIT %% t:* %D
|
||||||
|
|
@ -0,0 +1,47 @@
|
||||||
|
read_verilog ../common/adffs.v
|
||||||
|
design -save read
|
||||||
|
|
||||||
|
hierarchy -top adff
|
||||||
|
proc
|
||||||
|
equiv_opt -async2sync -assert -map +/analogdevices/cells_sim.v synth_analogdevices -noiopad # equivalency check
|
||||||
|
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||||
|
cd adff # Constrain all select calls below inside the top module
|
||||||
|
select -assert-count 1 t:FFCE
|
||||||
|
|
||||||
|
select -assert-none t:FFCE %% t:* %D
|
||||||
|
|
||||||
|
|
||||||
|
design -load read
|
||||||
|
hierarchy -top adffn
|
||||||
|
proc
|
||||||
|
equiv_opt -async2sync -assert -map +/analogdevices/cells_sim.v synth_analogdevices -noiopad # equivalency check
|
||||||
|
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||||
|
cd adffn # Constrain all select calls below inside the top module
|
||||||
|
select -assert-count 1 t:FFCE
|
||||||
|
select -assert-count 1 t:LUT1
|
||||||
|
|
||||||
|
select -assert-none t:FFCE t:LUT1 %% t:* %D
|
||||||
|
|
||||||
|
|
||||||
|
design -load read
|
||||||
|
hierarchy -top dffs
|
||||||
|
proc
|
||||||
|
equiv_opt -async2sync -assert -map +/analogdevices/cells_sim.v synth_analogdevices -noiopad # equivalency check
|
||||||
|
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||||
|
cd dffs # Constrain all select calls below inside the top module
|
||||||
|
select -assert-count 1 t:FFRE
|
||||||
|
select -assert-count 1 t:LUT2
|
||||||
|
stat
|
||||||
|
select -assert-none t:FFRE t:LUT2 %% t:* %D
|
||||||
|
|
||||||
|
|
||||||
|
design -load read
|
||||||
|
hierarchy -top ndffnr
|
||||||
|
proc
|
||||||
|
equiv_opt -async2sync -assert -map +/analogdevices/cells_sim.v synth_analogdevices -noiopad # equivalency check
|
||||||
|
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||||
|
cd ndffnr # Constrain all select calls below inside the top module
|
||||||
|
select -assert-count 1 t:FFRE_N
|
||||||
|
select -assert-count 1 t:LUT1
|
||||||
|
|
||||||
|
select -assert-none t:FFRE_N t:LUT1 %% t:* %D
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
# Memory bits <= 18K; Data width <= 36; Address width <= 14: -> RBRAM2
|
||||||
|
|
||||||
|
# w4b | r16b
|
||||||
|
design -reset
|
||||||
|
read_verilog asym_ram_sdp_read_wider.v
|
||||||
|
synth_analogdevices -top asym_ram_sdp_read_wider -noiopad
|
||||||
|
select -assert-count 1 t:RBRAM2
|
||||||
|
|
||||||
|
# w8b | r16b
|
||||||
|
design -reset
|
||||||
|
read_verilog asym_ram_sdp_read_wider.v
|
||||||
|
chparam -set WIDTHA 8 -set SIZEA 512 -set ADDRWIDTHA 9 asym_ram_sdp_read_wider
|
||||||
|
synth_analogdevices -top asym_ram_sdp_read_wider -noiopad
|
||||||
|
select -assert-count 1 t:RBRAM2
|
||||||
|
|
||||||
|
# w4b | r32b
|
||||||
|
design -reset
|
||||||
|
read_verilog asym_ram_sdp_read_wider.v
|
||||||
|
chparam -set WIDTHB 32 -set SIZEB 128 -set ADDRWIDTHB 7 asym_ram_sdp_read_wider
|
||||||
|
synth_analogdevices -top asym_ram_sdp_read_wider -noiopad
|
||||||
|
select -assert-count 2 t:RBRAM2
|
||||||
|
|
||||||
|
# w16b | r4b
|
||||||
|
design -reset
|
||||||
|
read_verilog asym_ram_sdp_write_wider.v
|
||||||
|
synth_analogdevices -top asym_ram_sdp_write_wider -noiopad
|
||||||
|
select -assert-count 1 t:RBRAM2
|
||||||
|
|
||||||
|
# w16b | r8b
|
||||||
|
design -reset
|
||||||
|
read_verilog asym_ram_sdp_write_wider.v
|
||||||
|
chparam -set WIDTHB 8 -set SIZEB 512 -set ADDRWIDTHB 9 asym_ram_sdp_read_wider
|
||||||
|
synth_analogdevices -top asym_ram_sdp_write_wider -noiopad
|
||||||
|
select -assert-count 1 t:RBRAM2
|
||||||
|
|
||||||
|
# w32b | r4b
|
||||||
|
design -reset
|
||||||
|
read_verilog asym_ram_sdp_write_wider.v
|
||||||
|
chparam -set WIDTHA 32 -set SIZEA 128 -set ADDRWIDTHA 7 asym_ram_sdp_read_wider
|
||||||
|
synth_analogdevices -top asym_ram_sdp_write_wider -noiopad
|
||||||
|
select -assert-count 1 t:RBRAM2
|
||||||
|
|
||||||
|
# w4b | r24b
|
||||||
|
design -reset
|
||||||
|
read_verilog asym_ram_sdp_read_wider.v
|
||||||
|
chparam -set SIZEA 768
|
||||||
|
chparam -set WIDTHB 24 -set SIZEB 128 -set ADDRWIDTHB 7 asym_ram_sdp_read_wider
|
||||||
|
synth_analogdevices -top asym_ram_sdp_read_wider -noiopad
|
||||||
|
select -assert-count 2 t:RBRAM2
|
||||||
|
|
||||||
|
|
@ -0,0 +1,73 @@
|
||||||
|
// Asymmetric port RAM
|
||||||
|
// Read Wider than Write. Read Statement in loop
|
||||||
|
//asym_ram_sdp_read_wider.v
|
||||||
|
module asym_ram_sdp_read_wider (clkA, clkB, enaA, weA, enaB, addrA, addrB, diA, doB);
|
||||||
|
parameter WIDTHA = 4;
|
||||||
|
parameter SIZEA = 1024;
|
||||||
|
parameter ADDRWIDTHA = 10;
|
||||||
|
|
||||||
|
parameter WIDTHB = 16;
|
||||||
|
parameter SIZEB = 256;
|
||||||
|
parameter ADDRWIDTHB = 8;
|
||||||
|
|
||||||
|
input clkA;
|
||||||
|
input clkB;
|
||||||
|
input weA;
|
||||||
|
input enaA, enaB;
|
||||||
|
input [ADDRWIDTHA-1:0] addrA;
|
||||||
|
input [ADDRWIDTHB-1:0] addrB;
|
||||||
|
input [WIDTHA-1:0] diA;
|
||||||
|
output [WIDTHB-1:0] doB;
|
||||||
|
|
||||||
|
`define max(a,b) {(a) > (b) ? (a) : (b)}
|
||||||
|
`define min(a,b) {(a) < (b) ? (a) : (b)}
|
||||||
|
|
||||||
|
function integer log2;
|
||||||
|
input integer value;
|
||||||
|
reg [31:0] shifted;
|
||||||
|
integer res;
|
||||||
|
begin
|
||||||
|
if (value < 2)
|
||||||
|
log2 = value;
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
shifted = value-1;
|
||||||
|
for (res=0; shifted>0; res=res+1)
|
||||||
|
shifted = shifted>>1;
|
||||||
|
log2 = res;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
localparam maxSIZE = `max(SIZEA, SIZEB);
|
||||||
|
localparam maxWIDTH = `max(WIDTHA, WIDTHB);
|
||||||
|
localparam minWIDTH = `min(WIDTHA, WIDTHB);
|
||||||
|
|
||||||
|
localparam RATIO = maxWIDTH / minWIDTH;
|
||||||
|
localparam log2RATIO = log2(RATIO);
|
||||||
|
|
||||||
|
(* ram_style="block" *)
|
||||||
|
reg [minWIDTH-1:0] RAM [0:maxSIZE-1];
|
||||||
|
reg [WIDTHB-1:0] readB;
|
||||||
|
|
||||||
|
always @(posedge clkA)
|
||||||
|
begin
|
||||||
|
if (enaA) begin
|
||||||
|
if (weA)
|
||||||
|
RAM[addrA] <= diA;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(posedge clkB)
|
||||||
|
begin : ramread
|
||||||
|
integer i;
|
||||||
|
reg [log2RATIO-1:0] lsbaddr;
|
||||||
|
if (enaB) begin
|
||||||
|
for (i = 0; i < RATIO; i = i+1) begin
|
||||||
|
lsbaddr = i;
|
||||||
|
readB[(i+1)*minWIDTH-1 -: minWIDTH] <= RAM[{addrB, lsbaddr}];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
assign doB = readB;
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,72 @@
|
||||||
|
// Asymmetric port RAM
|
||||||
|
// Write wider than Read. Write Statement in a loop.
|
||||||
|
// asym_ram_sdp_write_wider.v
|
||||||
|
module asym_ram_sdp_write_wider (clkA, clkB, weA, enaA, enaB, addrA, addrB, diA, doB);
|
||||||
|
parameter WIDTHB = 4;
|
||||||
|
parameter SIZEB = 1024;
|
||||||
|
parameter ADDRWIDTHB = 10;
|
||||||
|
|
||||||
|
parameter WIDTHA = 16;
|
||||||
|
parameter SIZEA = 256;
|
||||||
|
parameter ADDRWIDTHA = 8;
|
||||||
|
|
||||||
|
input clkA;
|
||||||
|
input clkB;
|
||||||
|
input weA;
|
||||||
|
input enaA, enaB;
|
||||||
|
input [ADDRWIDTHA-1:0] addrA;
|
||||||
|
input [ADDRWIDTHB-1:0] addrB;
|
||||||
|
input [WIDTHA-1:0] diA;
|
||||||
|
output [WIDTHB-1:0] doB;
|
||||||
|
|
||||||
|
`define max(a,b) {(a) > (b) ? (a) : (b)}
|
||||||
|
`define min(a,b) {(a) < (b) ? (a) : (b)}
|
||||||
|
|
||||||
|
function integer log2;
|
||||||
|
input integer value;
|
||||||
|
reg [31:0] shifted;
|
||||||
|
integer res;
|
||||||
|
begin
|
||||||
|
if (value < 2)
|
||||||
|
log2 = value;
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
shifted = value-1;
|
||||||
|
for (res=0; shifted>0; res=res+1)
|
||||||
|
shifted = shifted>>1;
|
||||||
|
log2 = res;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
localparam maxSIZE = `max(SIZEA, SIZEB);
|
||||||
|
localparam maxWIDTH = `max(WIDTHA, WIDTHB);
|
||||||
|
localparam minWIDTH = `min(WIDTHA, WIDTHB);
|
||||||
|
|
||||||
|
localparam RATIO = maxWIDTH / minWIDTH;
|
||||||
|
localparam log2RATIO = log2(RATIO);
|
||||||
|
|
||||||
|
(* ram_style="block" *)
|
||||||
|
reg [minWIDTH-1:0] RAM [0:maxSIZE-1];
|
||||||
|
reg [WIDTHB-1:0] readB;
|
||||||
|
|
||||||
|
always @(posedge clkB) begin
|
||||||
|
if (enaB) begin
|
||||||
|
readB <= RAM[addrB];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
assign doB = readB;
|
||||||
|
|
||||||
|
always @(posedge clkA)
|
||||||
|
begin : ramwrite
|
||||||
|
integer i;
|
||||||
|
reg [log2RATIO-1:0] lsbaddr;
|
||||||
|
for (i=0; i< RATIO; i= i+ 1) begin : write1
|
||||||
|
lsbaddr = i;
|
||||||
|
if (enaA) begin
|
||||||
|
if (weA)
|
||||||
|
RAM[{addrA, lsbaddr}] <= diA[(i+1)*minWIDTH-1 -: minWIDTH];
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,39 @@
|
||||||
|
# Check that blockram memory without parameters is not modified
|
||||||
|
read_verilog ../common/memory_attributes/attributes_test.v
|
||||||
|
hierarchy -top block_ram
|
||||||
|
synth_analogdevices -top block_ram -noiopad
|
||||||
|
cd block_ram # Constrain all select calls below inside the top module
|
||||||
|
# select -assert-count 1 t:RBRAM2 # This currently infers LUTRAM because BRAM is expensive.
|
||||||
|
|
||||||
|
# Check that distributed memory without parameters is not modified
|
||||||
|
design -reset
|
||||||
|
read_verilog ../common/memory_attributes/attributes_test.v
|
||||||
|
hierarchy -top distributed_ram
|
||||||
|
synth_analogdevices -top distributed_ram -noiopad
|
||||||
|
cd distributed_ram # Constrain all select calls below inside the top module
|
||||||
|
select -assert-count 8 t:RAMS64X1
|
||||||
|
select -assert-count 8 t:FFRE
|
||||||
|
|
||||||
|
# Set ram_style distributed to blockram memory; will be implemented as distributed
|
||||||
|
design -reset
|
||||||
|
read_verilog ../common/memory_attributes/attributes_test.v
|
||||||
|
setattr -set ram_style "distributed" block_ram/m:*
|
||||||
|
synth_analogdevices -top block_ram -noiopad
|
||||||
|
cd block_ram # Constrain all select calls below inside the top module
|
||||||
|
select -assert-count 64 t:RAMS64X1
|
||||||
|
select -assert-count 4 t:FFRE
|
||||||
|
|
||||||
|
# Set synthesis, logic_block to blockram memory; will be implemented as distributed
|
||||||
|
design -reset
|
||||||
|
read_verilog ../common/memory_attributes/attributes_test.v
|
||||||
|
setattr -set logic_block 1 block_ram/m:*
|
||||||
|
synth_analogdevices -top block_ram -noiopad
|
||||||
|
cd block_ram # Constrain all select calls below inside the top module
|
||||||
|
select -assert-count 0 t:RBRAM2
|
||||||
|
|
||||||
|
# Set ram_style block to a distributed memory; will be implemented as blockram
|
||||||
|
design -reset
|
||||||
|
read_verilog ../common/memory_attributes/attributes_test.v
|
||||||
|
synth_analogdevices -top distributed_ram_manual -noiopad
|
||||||
|
cd distributed_ram_manual # Constrain all select calls below inside the top module
|
||||||
|
# select -assert-count 1 t:RBRAM2 # This gets implemented in logic instead
|
||||||
|
|
@ -0,0 +1,77 @@
|
||||||
|
### TODO: Not running equivalence checking because BRAM models does not exists
|
||||||
|
### currently. Checking instance counts instead.
|
||||||
|
# Memory bits <= 18K; Data width <= 36; Address width <= 14: -> RBRAM2
|
||||||
|
read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 12 -set DATA_WIDTH 1 sync_ram_sdp
|
||||||
|
setattr -set ram_style "block" sync_ram_sdp
|
||||||
|
synth_analogdevices -top sync_ram_sdp -noiopad
|
||||||
|
cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:RBRAM2
|
||||||
|
|
||||||
|
design -reset
|
||||||
|
read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 8 -set DATA_WIDTH 18 sync_ram_sdp
|
||||||
|
setattr -set ram_style "block" sync_ram_sdp
|
||||||
|
synth_analogdevices -top sync_ram_sdp -noiopad
|
||||||
|
cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:RBRAM2
|
||||||
|
|
||||||
|
design -reset
|
||||||
|
read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 14 -set DATA_WIDTH 1 sync_ram_sdp
|
||||||
|
setattr -set ram_style "block" sync_ram_sdp
|
||||||
|
synth_analogdevices -top sync_ram_sdp -noiopad
|
||||||
|
cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:RBRAM2
|
||||||
|
|
||||||
|
design -reset
|
||||||
|
read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 9 -set DATA_WIDTH 36 sync_ram_sdp
|
||||||
|
synth_analogdevices -top sync_ram_sdp -noiopad
|
||||||
|
cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:RBRAM2
|
||||||
|
|
||||||
|
# Anything memory bits < 1024 -> LUTRAM
|
||||||
|
design -reset
|
||||||
|
read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 8 -set DATA_WIDTH 2 sync_ram_sdp
|
||||||
|
synth_analogdevices -top sync_ram_sdp -noiopad
|
||||||
|
cd sync_ram_sdp
|
||||||
|
select -assert-count 0 t:RBRAM2
|
||||||
|
select -assert-count 8 t:RAMD64X1
|
||||||
|
select -assert-count 2 t:FFRE
|
||||||
|
|
||||||
|
# More than 18K bits, data width <= 36 (TDP), and address width from 10 to 15b (non-cascaded) -> RAMB36E1
|
||||||
|
design -reset
|
||||||
|
read_verilog ../common/blockram.v
|
||||||
|
chparam -set ADDRESS_WIDTH 10 -set DATA_WIDTH 36 sync_ram_sdp
|
||||||
|
synth_analogdevices -top sync_ram_sdp -noiopad
|
||||||
|
cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:RBRAM2
|
||||||
|
|
||||||
|
|
||||||
|
### With parameters
|
||||||
|
|
||||||
|
design -reset
|
||||||
|
read_verilog ../common/blockram.v
|
||||||
|
hierarchy -top sync_ram_sdp -chparam ADDRESS_WIDTH 12 -chparam DATA_WIDTH 1
|
||||||
|
setattr -set ram_style "block" m:memory
|
||||||
|
synth_analogdevices -top sync_ram_sdp -noiopad
|
||||||
|
cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:RBRAM2
|
||||||
|
|
||||||
|
design -reset
|
||||||
|
read_verilog ../common/blockram.v
|
||||||
|
hierarchy -top sync_ram_sdp -chparam ADDRESS_WIDTH 12 -chparam DATA_WIDTH 1
|
||||||
|
setattr -set logic_block 1 m:memory
|
||||||
|
synth_analogdevices -top sync_ram_sdp -noiopad
|
||||||
|
cd sync_ram_sdp
|
||||||
|
select -assert-count 0 t:RBRAM2
|
||||||
|
|
||||||
|
design -reset
|
||||||
|
read_verilog ../common/blockram.v
|
||||||
|
hierarchy -top sync_ram_sdp -chparam ADDRESS_WIDTH 8 -chparam DATA_WIDTH 1
|
||||||
|
setattr -set ram_style "block" m:memory
|
||||||
|
synth_analogdevices -top sync_ram_sdp -noiopad
|
||||||
|
cd sync_ram_sdp
|
||||||
|
select -assert-count 1 t:RBRAM2
|
||||||
|
|
@ -0,0 +1,34 @@
|
||||||
|
read_verilog <<EOT
|
||||||
|
module register_file(
|
||||||
|
input wire clk,
|
||||||
|
input wire write_enable,
|
||||||
|
input wire [63:0] write_data,
|
||||||
|
input wire [4:0] write_reg,
|
||||||
|
input wire [4:0] read1_reg,
|
||||||
|
input wire [4:0] read2_reg,
|
||||||
|
input wire [4:0] read3_reg,
|
||||||
|
output reg [63:0] read1_data,
|
||||||
|
output reg [63:0] read2_data,
|
||||||
|
output reg [63:0] read3_data
|
||||||
|
);
|
||||||
|
|
||||||
|
reg [63:0] registers[0:31];
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
if (write_enable == 1'b1) begin
|
||||||
|
registers[write_reg] <= write_data;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
always @(all) begin
|
||||||
|
read1_data <= registers[read1_reg];
|
||||||
|
read2_data <= registers[read2_reg];
|
||||||
|
read3_data <= registers[read3_reg];
|
||||||
|
end
|
||||||
|
endmodule
|
||||||
|
EOT
|
||||||
|
|
||||||
|
synth_analogdevices -noiopad
|
||||||
|
cd register_file
|
||||||
|
select -assert-count 192 t:RAMD32X1
|
||||||
|
select -assert-none t:RAMD32X1 %% t:* %D
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
read_verilog << EOF
|
||||||
|
module top(...);
|
||||||
|
input wire [31:0] A;
|
||||||
|
output wire [31:0] P;
|
||||||
|
|
||||||
|
assign P = A * 32'h12300000;
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
EOF
|
||||||
|
|
||||||
|
synth_analogdevices
|
||||||
|
|
@ -0,0 +1,18 @@
|
||||||
|
read_verilog << EOF
|
||||||
|
module top(...);
|
||||||
|
|
||||||
|
input signed [17:0] A;
|
||||||
|
input signed [17:0] B;
|
||||||
|
output X;
|
||||||
|
output Y;
|
||||||
|
|
||||||
|
wire [35:0] P;
|
||||||
|
assign P = A * B;
|
||||||
|
|
||||||
|
assign X = P[0];
|
||||||
|
assign Y = P[35];
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
EOF
|
||||||
|
|
||||||
|
synth_analogdevices
|
||||||
|
|
@ -0,0 +1,16 @@
|
||||||
|
read_verilog <<EOT
|
||||||
|
module led_blink (
|
||||||
|
input clk,
|
||||||
|
output ledc
|
||||||
|
);
|
||||||
|
|
||||||
|
reg [6:0] led_counter = 0;
|
||||||
|
always @( posedge clk ) begin
|
||||||
|
led_counter <= led_counter + 1;
|
||||||
|
end
|
||||||
|
assign ledc = !led_counter[ 6:3 ];
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
EOT
|
||||||
|
proc
|
||||||
|
equiv_opt -assert -map +/analogdevices/cells_sim.v synth_analogdevices
|
||||||
|
|
@ -0,0 +1,13 @@
|
||||||
|
read_verilog ../common/counter.v
|
||||||
|
hierarchy -top top
|
||||||
|
proc
|
||||||
|
flatten
|
||||||
|
equiv_opt -async2sync -assert -map +/analogdevices/cells_sim.v synth_analogdevices -noiopad # equivalency check
|
||||||
|
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||||
|
cd top # Constrain all select calls below inside the top module
|
||||||
|
stat
|
||||||
|
select -assert-count 8 t:FFCE
|
||||||
|
select -assert-count 1 t:LUT1
|
||||||
|
select -assert-count 2 t:CRY4
|
||||||
|
select -assert-count 1 t:CRY4INIT
|
||||||
|
select -assert-none t:FFCE t:LUT1 t:CRY4 t:CRY4INIT %% t:* %D
|
||||||
|
|
@ -0,0 +1,41 @@
|
||||||
|
read_verilog ../common/dffs.v
|
||||||
|
design -save read
|
||||||
|
|
||||||
|
hierarchy -top dff
|
||||||
|
proc
|
||||||
|
equiv_opt -assert -map +/analogdevices/cells_sim.v synth_analogdevices -noiopad # equivalency check
|
||||||
|
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||||
|
cd dff # Constrain all select calls below inside the top module
|
||||||
|
select -assert-count 1 t:FFRE
|
||||||
|
select -assert-none t:FFRE %% t:* %D
|
||||||
|
|
||||||
|
|
||||||
|
design -load read
|
||||||
|
hierarchy -top dffe
|
||||||
|
proc
|
||||||
|
equiv_opt -assert -map +/analogdevices/cells_sim.v synth_analogdevices -noiopad # equivalency check
|
||||||
|
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||||
|
cd dffe # Constrain all select calls below inside the top module
|
||||||
|
select -assert-count 1 t:FFRE
|
||||||
|
select -assert-none t:FFRE %% t:* %D
|
||||||
|
|
||||||
|
|
||||||
|
design -load read
|
||||||
|
hierarchy -top dff
|
||||||
|
proc
|
||||||
|
equiv_opt -assert -map +/analogdevices/cells_sim.v synth_analogdevices -dff -noiopad # equivalency check
|
||||||
|
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||||
|
cd dff # Constrain all select calls below inside the top module
|
||||||
|
select -assert-count 1 t:FFRE
|
||||||
|
select -assert-none t:FFRE %% t:* %D
|
||||||
|
|
||||||
|
|
||||||
|
design -load read
|
||||||
|
hierarchy -top dffe
|
||||||
|
proc
|
||||||
|
equiv_opt -assert -map +/analogdevices/cells_sim.v synth_analogdevices -dff -noiopad # equivalency check
|
||||||
|
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||||
|
cd dffe # Constrain all select calls below inside the top module
|
||||||
|
select -assert-count 1 t:FFRE
|
||||||
|
select -assert-none t:FFRE %% t:* %D
|
||||||
|
|
||||||
|
|
@ -0,0 +1,42 @@
|
||||||
|
logger -nowarn "Yosys has only limited support for tri-state logic at the moment\. .*"
|
||||||
|
logger -nowarn "Ignoring boxed module .*\."
|
||||||
|
|
||||||
|
read_verilog <<EOT
|
||||||
|
module top(input [24:0] A, input [17:0] B, output [47:0] P);
|
||||||
|
DSP48E1 #(.PREG(0)) dsp(.A(A), .B(B), .P(P));
|
||||||
|
endmodule
|
||||||
|
EOT
|
||||||
|
techmap -autoproc -wb -map +/analogdevices/cells_sim.v
|
||||||
|
opt
|
||||||
|
scc -expect 0
|
||||||
|
|
||||||
|
|
||||||
|
design -reset
|
||||||
|
read_verilog <<EOT
|
||||||
|
module top(input signed [24:0] A, input signed [17:0] B, output [47:0] P);
|
||||||
|
assign P = A * B;
|
||||||
|
endmodule
|
||||||
|
EOT
|
||||||
|
synth_analogdevices
|
||||||
|
techmap -autoproc -wb -map +/analogdevices/cells_sim.v
|
||||||
|
opt -full -fine
|
||||||
|
select -assert-count 2 t:$mul
|
||||||
|
select -assert-count 0 t:* t:$mul %D
|
||||||
|
|
||||||
|
|
||||||
|
design -reset
|
||||||
|
read_verilog -icells -formal <<EOT
|
||||||
|
module top(output [43:0] P);
|
||||||
|
\$__MUL22X22 mul (.A(42), .B(42), .Y(P));
|
||||||
|
assert property (P == 42*42);
|
||||||
|
endmodule
|
||||||
|
EOT
|
||||||
|
async2sync
|
||||||
|
techmap -map +/analogdevices/dsp_map.v
|
||||||
|
verilog_defaults -add -D ALLOW_WHITEBOX_DSP48E1
|
||||||
|
synth_analogdevices
|
||||||
|
techmap -autoproc -wb -map +/analogdevices/cells_sim.v
|
||||||
|
opt -full -fine
|
||||||
|
select -assert-count 0 t:* t:$assert %d
|
||||||
|
sat -verify -prove-asserts
|
||||||
|
|
||||||
|
|
@ -0,0 +1,20 @@
|
||||||
|
read_verilog ../common/fsm.v
|
||||||
|
hierarchy -top fsm
|
||||||
|
proc
|
||||||
|
flatten
|
||||||
|
|
||||||
|
design -save orig
|
||||||
|
|
||||||
|
equiv_opt -run :prove -map +/analogdevices/cells_sim.v synth_analogdevices -noiopad
|
||||||
|
miter -equiv -make_assert -flatten gold gate miter
|
||||||
|
sat -verify -prove-asserts -show-public -set-at 1 in_reset 1 -seq 20 -prove-skip 1 miter
|
||||||
|
|
||||||
|
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||||
|
cd fsm # Constrain all select calls below inside the top module
|
||||||
|
stat
|
||||||
|
select -assert-count 6 t:FFRE
|
||||||
|
select -assert-count 1 t:LUT1
|
||||||
|
select -assert-count 1 t:LUT3
|
||||||
|
select -assert-count 1 t:LUT4
|
||||||
|
select -assert-count 5 t:LUT5
|
||||||
|
select -assert-none t:FFRE t:LUT1 t:LUT3 t:LUT4 t:LUT5 %% t:* %D
|
||||||
|
|
@ -0,0 +1,11 @@
|
||||||
|
read_verilog ../common/logic.v
|
||||||
|
hierarchy -top top
|
||||||
|
proc
|
||||||
|
equiv_opt -assert -map +/analogdevices/cells_sim.v synth_analogdevices -noiopad # equivalency check
|
||||||
|
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||||
|
cd top # Constrain all select calls below inside the top module
|
||||||
|
|
||||||
|
select -assert-count 1 t:LUT1
|
||||||
|
select -assert-count 6 t:LUT2
|
||||||
|
select -assert-count 2 t:LUT4
|
||||||
|
select -assert-none t:LUT1 t:LUT2 t:LUT4 %% t:* %D
|
||||||
|
|
@ -0,0 +1,113 @@
|
||||||
|
design -reset
|
||||||
|
read_verilog ../common/lutram.v
|
||||||
|
hierarchy -top lutram_1w1r -chparam A_WIDTH 5
|
||||||
|
proc
|
||||||
|
memory -nomap
|
||||||
|
equiv_opt -run :prove -map +/analogdevices/cells_sim.v synth_analogdevices -noiopad
|
||||||
|
memory
|
||||||
|
opt -full
|
||||||
|
|
||||||
|
miter -equiv -flatten -make_assert -make_outputs gold gate miter
|
||||||
|
sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter
|
||||||
|
|
||||||
|
design -load postopt
|
||||||
|
cd lutram_1w1r
|
||||||
|
select -assert-count 8 t:FFRE
|
||||||
|
select -assert-count 8 t:RAMS64X1
|
||||||
|
select -assert-none t:FFRE t:RAMS64X1 %% t:* %D
|
||||||
|
|
||||||
|
|
||||||
|
design -reset
|
||||||
|
read_verilog ../common/lutram.v
|
||||||
|
hierarchy -top lutram_1w1r
|
||||||
|
proc
|
||||||
|
memory -nomap
|
||||||
|
equiv_opt -run :prove -map +/analogdevices/cells_sim.v synth_analogdevices -noiopad
|
||||||
|
memory
|
||||||
|
opt -full
|
||||||
|
|
||||||
|
miter -equiv -flatten -make_assert -make_outputs gold gate miter
|
||||||
|
sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter
|
||||||
|
|
||||||
|
design -load postopt
|
||||||
|
cd lutram_1w1r
|
||||||
|
dump
|
||||||
|
select -assert-count 8 t:FFRE
|
||||||
|
select -assert-count 8 t:RAMS64X1
|
||||||
|
select -assert-none t:FFRE t:RAMS64X1 %% t:* %D
|
||||||
|
|
||||||
|
|
||||||
|
design -reset
|
||||||
|
read_verilog ../common/lutram.v
|
||||||
|
hierarchy -top lutram_1w3r
|
||||||
|
proc
|
||||||
|
memory -nomap
|
||||||
|
equiv_opt -run :prove -map +/analogdevices/cells_sim.v synth_analogdevices -noiopad
|
||||||
|
memory
|
||||||
|
opt -full
|
||||||
|
|
||||||
|
miter -equiv -flatten -make_assert -make_outputs gold gate miter
|
||||||
|
sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter
|
||||||
|
|
||||||
|
design -load postopt
|
||||||
|
cd lutram_1w3r
|
||||||
|
select -assert-count 24 t:FFRE
|
||||||
|
select -assert-count 16 t:RAMD32X1
|
||||||
|
select -assert-none t:FFRE t:RAMD32X1 %% t:* %D
|
||||||
|
|
||||||
|
|
||||||
|
design -reset
|
||||||
|
read_verilog ../common/lutram.v
|
||||||
|
hierarchy -top lutram_1w3r -chparam A_WIDTH 6
|
||||||
|
proc
|
||||||
|
memory -nomap
|
||||||
|
equiv_opt -run :prove -map +/analogdevices/cells_sim.v synth_analogdevices -noiopad
|
||||||
|
memory
|
||||||
|
opt -full
|
||||||
|
|
||||||
|
miter -equiv -flatten -make_assert -make_outputs gold gate miter
|
||||||
|
sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter
|
||||||
|
|
||||||
|
design -load postopt
|
||||||
|
cd lutram_1w3r
|
||||||
|
select -assert-count 24 t:FFRE
|
||||||
|
select -assert-count 16 t:RAMD64X1
|
||||||
|
select -assert-none t:FFRE t:RAMD64X1 %% t:* %D
|
||||||
|
|
||||||
|
|
||||||
|
design -reset
|
||||||
|
read_verilog ../common/lutram.v
|
||||||
|
hierarchy -top lutram_1w1r -chparam A_WIDTH 5 -chparam D_WIDTH 6
|
||||||
|
proc
|
||||||
|
memory -nomap
|
||||||
|
equiv_opt -run :prove -map +/analogdevices/cells_sim.v synth_analogdevices -noiopad
|
||||||
|
memory
|
||||||
|
opt -full
|
||||||
|
|
||||||
|
miter -equiv -flatten -make_assert -make_outputs gold gate miter
|
||||||
|
sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter
|
||||||
|
|
||||||
|
design -load postopt
|
||||||
|
cd lutram_1w1r
|
||||||
|
select -assert-count 6 t:FFRE
|
||||||
|
select -assert-count 6 t:RAMS64X1
|
||||||
|
select -assert-none t:FFRE t:RAMS64X1 %% t:* %D
|
||||||
|
|
||||||
|
|
||||||
|
design -reset
|
||||||
|
read_verilog ../common/lutram.v
|
||||||
|
hierarchy -top lutram_1w1r -chparam A_WIDTH 6 -chparam D_WIDTH 6
|
||||||
|
proc
|
||||||
|
memory -nomap
|
||||||
|
equiv_opt -run :prove -map +/analogdevices/cells_sim.v synth_analogdevices -noiopad
|
||||||
|
memory
|
||||||
|
opt -full
|
||||||
|
|
||||||
|
miter -equiv -flatten -make_assert -make_outputs gold gate miter
|
||||||
|
sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter
|
||||||
|
|
||||||
|
design -load postopt
|
||||||
|
cd lutram_1w1r
|
||||||
|
select -assert-count 6 t:FFRE
|
||||||
|
select -assert-count 6 t:RAMS64X1
|
||||||
|
select -assert-none t:FFRE t:RAMS64X1 %% t:* %D
|
||||||
|
|
@ -0,0 +1,121 @@
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
from dataclasses import dataclass
|
||||||
|
|
||||||
|
|
||||||
|
blockram_template = """# ======================================
|
||||||
|
log ** GENERATING TEST {top} WITH PARAMS{param_str}
|
||||||
|
design -reset; read_verilog -defer ../common/blockram.v
|
||||||
|
chparam{param_str} {top}
|
||||||
|
hierarchy -top {top}
|
||||||
|
echo on
|
||||||
|
debug synth_analogdevices -tech {tech} -top {top} {opts} -run :map_ffram
|
||||||
|
stat; echo off
|
||||||
|
"""
|
||||||
|
inference_tests: "list[tuple[str, list[tuple[str, int]], str, list[str], list[str]]]" = [
|
||||||
|
# RBRAM2 has TDP and SDP for 8192x5bit, 4096x9bit, and 2048x40bit
|
||||||
|
("t16ffc", [("ADDRESS_WIDTH", 13), ("DATA_WIDTH", 5)], "sync_ram_*dp", ["-assert-count 1 t:RBRAM2"], []),
|
||||||
|
("t16ffc", [("ADDRESS_WIDTH", 12), ("DATA_WIDTH", 9)], "sync_ram_*dp", ["-assert-count 1 t:RBRAM2"], []),
|
||||||
|
("t16ffc", [("ADDRESS_WIDTH", 11), ("DATA_WIDTH", 40)], "sync_ram_*dp", ["-assert-count 1 t:RBRAM2"], []),
|
||||||
|
# LUTRAM is generally cheaper than BRAM for undersized (SDP) memories
|
||||||
|
("t16ffc", [("ADDRESS_WIDTH", 6), ("DATA_WIDTH", 1)], "sync_ram_sdp", ["-assert-count 1 t:RAMD64X1"], []),
|
||||||
|
("t16ffc", [("ADDRESS_WIDTH", 6), ("DATA_WIDTH", 8)], "sync_ram_sdp", ["-assert-count 8 t:RAMD64X1"], []),
|
||||||
|
("t16ffc", [("ADDRESS_WIDTH", 10), ("DATA_WIDTH", 8)], "sync_ram_sdp", ["-assert-count 128 t:RAMD64X1"], []),
|
||||||
|
("t16ffc", [("ADDRESS_WIDTH", 10), ("DATA_WIDTH", 16)], "sync_ram_sdp", ["-assert-count 256 t:RAMD64X1"], []),
|
||||||
|
# RBRAM is half the depth of RBRAM2, and doesn't have TDP, also LUTRAM is cheaper, so we need to specify not to use it
|
||||||
|
("t40lp", [("ADDRESS_WIDTH", 13), ("DATA_WIDTH", 5)], "sync_ram_sdp", ["-assert-count 2 t:RBRAM"], ["-nolutram"]),
|
||||||
|
("t40lp", [("ADDRESS_WIDTH", 12), ("DATA_WIDTH", 5)], "sync_ram_sdp", ["-assert-count 1 t:RBRAM"], ["-nolutram"]),
|
||||||
|
("t40lp", [("ADDRESS_WIDTH", 11), ("DATA_WIDTH", 9)], "sync_ram_sdp", ["-assert-count 1 t:RBRAM"], ["-nolutram"]),
|
||||||
|
("t40lp", [("ADDRESS_WIDTH", 10), ("DATA_WIDTH", 40)], "sync_ram_sdp", ["-assert-count 1 t:RBRAM"], ["-nolutram"]),
|
||||||
|
# 2048x32 and 2048x36bit are also valid
|
||||||
|
("t16ffc", [("ADDRESS_WIDTH", 11), ("DATA_WIDTH", 32)], "sync_ram_*dp", ["-assert-count 1 t:RBRAM2"], []),
|
||||||
|
("t16ffc", [("ADDRESS_WIDTH", 11), ("DATA_WIDTH", 36)], "sync_ram_*dp", ["-assert-count 1 t:RBRAM2"], []),
|
||||||
|
("t40lp", [("ADDRESS_WIDTH", 10), ("DATA_WIDTH", 32)], "sync_ram_sdp", ["-assert-count 1 t:RBRAM"], ["-nolutram"]),
|
||||||
|
("t40lp", [("ADDRESS_WIDTH", 10), ("DATA_WIDTH", 36)], "sync_ram_sdp", ["-assert-count 1 t:RBRAM"], ["-nolutram"]),
|
||||||
|
|
||||||
|
# 4096x16/18bit can be mapped to a single 2048x32/36bit
|
||||||
|
("t16ffc", [("ADDRESS_WIDTH", 12), ("DATA_WIDTH", 16)], "sync_ram_*dp", ["-assert-count 1 t:RBRAM2"], []),
|
||||||
|
("t16ffc", [("ADDRESS_WIDTH", 12), ("DATA_WIDTH", 18)], "sync_ram_*dp", ["-assert-count 1 t:RBRAM2"], []),
|
||||||
|
("t40lp", [("ADDRESS_WIDTH", 11), ("DATA_WIDTH", 16)], "sync_ram_sdp", ["-assert-count 1 t:RBRAM"], ["-nolutram"]),
|
||||||
|
("t40lp", [("ADDRESS_WIDTH", 11), ("DATA_WIDTH", 18)], "sync_ram_sdp", ["-assert-count 1 t:RBRAM"], ["-nolutram"]),
|
||||||
|
# same for 8192x8/9bit
|
||||||
|
("t16ffc", [("ADDRESS_WIDTH", 13), ("DATA_WIDTH", 8)], "sync_ram_*dp", ["-assert-count 1 t:RBRAM2"], []),
|
||||||
|
("t16ffc", [("ADDRESS_WIDTH", 13), ("DATA_WIDTH", 9)], "sync_ram_*dp", ["-assert-count 1 t:RBRAM2"], []),
|
||||||
|
("t40lp", [("ADDRESS_WIDTH", 12), ("DATA_WIDTH", 8)], "sync_ram_sdp", ["-assert-count 1 t:RBRAM"], ["-nolutram"]),
|
||||||
|
("t40lp", [("ADDRESS_WIDTH", 12), ("DATA_WIDTH", 9)], "sync_ram_sdp", ["-assert-count 1 t:RBRAM"], ["-nolutram"]),
|
||||||
|
# but 4096x20bit requires extra memories because 2048x40bit has 8bit byte enables (which doesn't divide 20bit evenly)
|
||||||
|
("t16ffc", [("ADDRESS_WIDTH", 12), ("DATA_WIDTH", 20)], "sync_ram_sdp", ["-assert-count 2 t:RBRAM2"], []),
|
||||||
|
("t40lp", [("ADDRESS_WIDTH", 11), ("DATA_WIDTH", 20)], "sync_ram_sdp", ["-assert-count 2 t:RBRAM"], ["-nolutram"]),
|
||||||
|
]
|
||||||
|
|
||||||
|
@dataclass
|
||||||
|
class TestClass:
|
||||||
|
params: dict[str, int]
|
||||||
|
top: str
|
||||||
|
assertions: list[str]
|
||||||
|
test_steps: None | list[dict[str, int]]
|
||||||
|
opts: list[str]
|
||||||
|
tech: str = "t16ffc"
|
||||||
|
|
||||||
|
sim_tests: list[TestClass] = []
|
||||||
|
|
||||||
|
for (tech, params, top, assertions, opts) in inference_tests:
|
||||||
|
sim_test = TestClass(
|
||||||
|
params=dict(params),
|
||||||
|
top=top,
|
||||||
|
assertions=assertions,
|
||||||
|
test_steps=None,
|
||||||
|
opts=opts,
|
||||||
|
tech=tech,
|
||||||
|
)
|
||||||
|
sim_tests.append(sim_test)
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
j = 0
|
||||||
|
max_j = 16
|
||||||
|
f = None
|
||||||
|
for sim_test in sim_tests:
|
||||||
|
# format params
|
||||||
|
param_str = ""
|
||||||
|
for (key, val) in sim_test.params.items():
|
||||||
|
param_str += f" -set {key} {val}"
|
||||||
|
|
||||||
|
# resolve top module wildcards
|
||||||
|
top_list = [sim_test.top]
|
||||||
|
if "*dp" in sim_test.top:
|
||||||
|
top_list += [
|
||||||
|
sim_test.top.replace("*dp", dp_sub) for dp_sub in ["sdp", "tdp"]
|
||||||
|
]
|
||||||
|
if "w*r" in sim_test.top:
|
||||||
|
top_list += [
|
||||||
|
sim_test.top.replace("w*r", wr_sub) for wr_sub in ["wwr", "wrr"]
|
||||||
|
]
|
||||||
|
if len(top_list) > 1:
|
||||||
|
top_list.pop(0)
|
||||||
|
|
||||||
|
# iterate over string substitutions
|
||||||
|
for top in top_list:
|
||||||
|
# limit number of tests per file to allow parallel make
|
||||||
|
if not f:
|
||||||
|
fn = f"t_mem{i}.ys"
|
||||||
|
f = open(fn, mode="w")
|
||||||
|
j = 0
|
||||||
|
|
||||||
|
# output yosys script test file
|
||||||
|
print(
|
||||||
|
blockram_template.format(param_str=param_str, top=top, tech=sim_test.tech, opts=" ".join(sim_test.opts)),
|
||||||
|
file=f
|
||||||
|
)
|
||||||
|
for assertion in sim_test.assertions:
|
||||||
|
print(f"log ** CHECKING CELL COUNTS FOR TEST {top} WITH PARAMS{param_str} ON TECH {sim_test.tech}", file=f)
|
||||||
|
print(f"select {assertion}", file=f)
|
||||||
|
print("", file=f)
|
||||||
|
|
||||||
|
# increment test counter
|
||||||
|
j += 1
|
||||||
|
if j >= max_j:
|
||||||
|
f = f.close()
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
if f:
|
||||||
|
f.close()
|
||||||
|
|
@ -0,0 +1,9 @@
|
||||||
|
read_verilog ../common/mul.v
|
||||||
|
hierarchy -top top
|
||||||
|
proc
|
||||||
|
equiv_opt -assert -map +/analogdevices/cells_sim.v synth_analogdevices -noiopad # equivalency check
|
||||||
|
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||||
|
cd top # Constrain all select calls below inside the top module
|
||||||
|
|
||||||
|
select -assert-count 1 t:RBBDSP
|
||||||
|
select -assert-none t:RBBDSP %% t:* %D
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
Example from: https://www.xilinx.com/support/documentation/sw_manuals/xilinx2019_1/ug901-vivado-synthesis.pdf [p. 89].
|
||||||
|
*/
|
||||||
|
|
||||||
|
// Unsigned 16x24-bit Multiplier
|
||||||
|
// 1 latency stage on operands
|
||||||
|
// 3 latency stage after the multiplication
|
||||||
|
// File: multipliers2.v
|
||||||
|
//
|
||||||
|
module mul_unsigned (clk, A, B, RES);
|
||||||
|
parameter WIDTHA = /*16*/ 6;
|
||||||
|
parameter WIDTHB = /*24*/ 9;
|
||||||
|
input clk;
|
||||||
|
input [WIDTHA-1:0] A;
|
||||||
|
input [WIDTHB-1:0] B;
|
||||||
|
output [WIDTHA+WIDTHB-1:0] RES;
|
||||||
|
reg [WIDTHA-1:0] rA;
|
||||||
|
reg [WIDTHB-1:0] rB;
|
||||||
|
reg [WIDTHA+WIDTHB-1:0] M [3:0];
|
||||||
|
integer i;
|
||||||
|
always @(posedge clk)
|
||||||
|
begin
|
||||||
|
rA <= A;
|
||||||
|
rB <= B;
|
||||||
|
M[0] <= rA * rB;
|
||||||
|
for (i = 0; i < 3; i = i+1)
|
||||||
|
M[i+1] <= M[i];
|
||||||
|
end
|
||||||
|
assign RES = M[3];
|
||||||
|
endmodule
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
read_verilog mul_unsigned.v
|
||||||
|
hierarchy -top mul_unsigned
|
||||||
|
proc
|
||||||
|
|
||||||
|
equiv_opt -assert -map +/analogdevices/cells_sim.v synth_analogdevices -noiopad # equivalency check
|
||||||
|
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||||
|
cd mul_unsigned # Constrain all select calls below inside the top module
|
||||||
|
select -assert-count 1 t:RBBDSP
|
||||||
|
select -assert-count 75 t:FFRE
|
||||||
|
select -assert-none t:RBBDSP t:FFRE %% t:* %D
|
||||||
|
|
@ -0,0 +1,50 @@
|
||||||
|
read_verilog ../common/mux.v
|
||||||
|
design -save read
|
||||||
|
|
||||||
|
hierarchy -top mux2
|
||||||
|
proc
|
||||||
|
equiv_opt -assert -map +/analogdevices/cells_sim.v synth_analogdevices -noiopad # equivalency check
|
||||||
|
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||||
|
cd mux2 # Constrain all select calls below inside the top module
|
||||||
|
select -assert-count 1 t:LUT3
|
||||||
|
|
||||||
|
select -assert-none t:LUT3 %% t:* %D
|
||||||
|
|
||||||
|
|
||||||
|
design -load read
|
||||||
|
hierarchy -top mux4
|
||||||
|
proc
|
||||||
|
equiv_opt -assert -map +/analogdevices/cells_sim.v synth_analogdevices -noiopad # equivalency check
|
||||||
|
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||||
|
cd mux4 # Constrain all select calls below inside the top module
|
||||||
|
select -assert-count 1 t:LUT6
|
||||||
|
|
||||||
|
select -assert-none t:LUT6 %% t:* %D
|
||||||
|
|
||||||
|
|
||||||
|
design -load read
|
||||||
|
hierarchy -top mux8
|
||||||
|
proc
|
||||||
|
equiv_opt -assert -map +/analogdevices/cells_sim.v synth_analogdevices -noiopad # equivalency check
|
||||||
|
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||||
|
cd mux8 # Constrain all select calls below inside the top module
|
||||||
|
select -assert-count 1 t:LUT3
|
||||||
|
select -assert-count 2 t:LUT6
|
||||||
|
|
||||||
|
select -assert-none t:LUT3 t:LUT6 %% t:* %D
|
||||||
|
|
||||||
|
|
||||||
|
design -load read
|
||||||
|
hierarchy -top mux16
|
||||||
|
proc
|
||||||
|
equiv_opt -assert -map +/analogdevices/cells_sim.v synth_analogdevices -noiopad # equivalency check
|
||||||
|
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||||
|
cd mux16 # Constrain all select calls below inside the top module
|
||||||
|
select -assert-max 2 t:LUT3
|
||||||
|
select -assert-max 2 t:LUT4
|
||||||
|
select -assert-min 4 t:LUT6
|
||||||
|
select -assert-max 7 t:LUT6
|
||||||
|
select -assert-max 2 t:LUTMUX7
|
||||||
|
dump
|
||||||
|
|
||||||
|
select -assert-none t:LUT6 t:LUT4 t:LUT3 t:LUTMUX7 %% t:* %D
|
||||||
|
|
@ -0,0 +1,26 @@
|
||||||
|
read_rtlil << EOF
|
||||||
|
|
||||||
|
module \top
|
||||||
|
|
||||||
|
wire width 4 input 1 \A
|
||||||
|
|
||||||
|
wire output 2 \O
|
||||||
|
|
||||||
|
cell \LUT4 $0
|
||||||
|
parameter \INIT 16'1111110011000000
|
||||||
|
connect \I0 \A [0]
|
||||||
|
connect \I1 \A [1]
|
||||||
|
connect \I2 \A [2]
|
||||||
|
connect \I3 \A [3]
|
||||||
|
connect \O \O
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
EOF
|
||||||
|
|
||||||
|
read_verilog -lib +/analogdevices/cells_sim.v
|
||||||
|
equiv_opt -assert -map +/analogdevices/cells_sim.v opt_lut_ins -tech analogdevices
|
||||||
|
|
||||||
|
design -load postopt
|
||||||
|
|
||||||
|
select -assert-count 1 t:LUT3
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
#!/usr/bin/env bash
|
||||||
|
set -eu
|
||||||
|
python3 mem_gen.py
|
||||||
|
source ../../gen-tests-makefile.sh
|
||||||
|
generate_mk --yosys-scripts --bash
|
||||||
|
|
@ -0,0 +1,10 @@
|
||||||
|
read_verilog ../common/shifter.v
|
||||||
|
hierarchy -top top
|
||||||
|
proc
|
||||||
|
flatten
|
||||||
|
equiv_opt -assert -map +/analogdevices/cells_sim.v synth_analogdevices -noiopad # equivalency check
|
||||||
|
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
|
||||||
|
cd top # Constrain all select calls below inside the top module
|
||||||
|
|
||||||
|
select -assert-count 8 t:FFRE
|
||||||
|
select -assert-none t:FFRE %% t:* %D
|
||||||
|
|
@ -22,6 +22,30 @@ module sync_ram_sp #(parameter DATA_WIDTH=8, ADDRESS_WIDTH=10)
|
||||||
endmodule // sync_ram_sp
|
endmodule // sync_ram_sp
|
||||||
|
|
||||||
|
|
||||||
|
module sync_ram_sp_nochange #(parameter DATA_WIDTH=8, ADDRESS_WIDTH=10)
|
||||||
|
(input wire write_enable, clk,
|
||||||
|
input wire [DATA_WIDTH-1:0] data_in,
|
||||||
|
input wire [ADDRESS_WIDTH-1:0] address_in,
|
||||||
|
output wire [DATA_WIDTH-1:0] data_out);
|
||||||
|
|
||||||
|
localparam WORD = (DATA_WIDTH-1);
|
||||||
|
localparam DEPTH = (2**ADDRESS_WIDTH-1);
|
||||||
|
|
||||||
|
reg [WORD:0] data_out_r;
|
||||||
|
reg [WORD:0] memory [0:DEPTH];
|
||||||
|
|
||||||
|
always @(posedge clk) begin
|
||||||
|
if (write_enable)
|
||||||
|
memory[address_in] <= data_in;
|
||||||
|
else
|
||||||
|
data_out_r <= memory[address_in];
|
||||||
|
end
|
||||||
|
|
||||||
|
assign data_out = data_out_r;
|
||||||
|
|
||||||
|
endmodule // sync_ram_sp_nochange
|
||||||
|
|
||||||
|
|
||||||
module sync_ram_sdp #(parameter DATA_WIDTH=8, ADDRESS_WIDTH=10)
|
module sync_ram_sdp #(parameter DATA_WIDTH=8, ADDRESS_WIDTH=10)
|
||||||
(input wire clk, write_enable,
|
(input wire clk, write_enable,
|
||||||
input wire [DATA_WIDTH-1:0] data_in,
|
input wire [DATA_WIDTH-1:0] data_in,
|
||||||
|
|
@ -112,6 +136,62 @@ module sync_ram_sdp_wrr #(parameter DATA_WIDTH=8, ADDRESS_WIDTH=10, SHIFT_VAL=1)
|
||||||
endmodule // sync_ram_sdp_wrr
|
endmodule // sync_ram_sdp_wrr
|
||||||
|
|
||||||
|
|
||||||
|
module double_sync_ram_sp #(parameter DATA_WIDTH=8, ADDRESS_WIDTH=10, USE_TDP=0)
|
||||||
|
(
|
||||||
|
input wire write_enable_a, clk_a,
|
||||||
|
input wire [DATA_WIDTH-1:0] data_in_a,
|
||||||
|
input wire [ADDRESS_WIDTH-1:0] address_in_a,
|
||||||
|
output wire [DATA_WIDTH-1:0] data_out_a,
|
||||||
|
|
||||||
|
input wire write_enable_b, clk_b,
|
||||||
|
input wire [DATA_WIDTH-1:0] data_in_b,
|
||||||
|
input wire [ADDRESS_WIDTH-1:0] address_in_b,
|
||||||
|
output wire [DATA_WIDTH-1:0] data_out_b
|
||||||
|
);
|
||||||
|
|
||||||
|
generate
|
||||||
|
if (USE_TDP) begin
|
||||||
|
|
||||||
|
sync_ram_tdp #(
|
||||||
|
.DATA_WIDTH(DATA_WIDTH),
|
||||||
|
.ADDRESS_WIDTH(ADDRESS_WIDTH+1)
|
||||||
|
) ram (
|
||||||
|
.clk_a(clk_a), .clk_b(clk_b),
|
||||||
|
.write_enable_a(write_enable_a), .write_enable_b(write_enable_b),
|
||||||
|
.write_data_a(data_in_a), .write_data_b(data_in_b),
|
||||||
|
.addr_a({1'b0, address_in_a}), .addr_b({1'b1, address_in_b}),
|
||||||
|
.read_data_a(data_out_a), .read_data_b(data_out_b)
|
||||||
|
);
|
||||||
|
|
||||||
|
end else begin
|
||||||
|
|
||||||
|
sync_ram_sp #(
|
||||||
|
.DATA_WIDTH(DATA_WIDTH),
|
||||||
|
.ADDRESS_WIDTH(ADDRESS_WIDTH)
|
||||||
|
) a_ram (
|
||||||
|
.write_enable(write_enable_a),
|
||||||
|
.clk(clk_a),
|
||||||
|
.data_in(data_in_a),
|
||||||
|
.address_in(address_in_a),
|
||||||
|
.data_out(data_out_a)
|
||||||
|
);
|
||||||
|
|
||||||
|
sync_ram_sp #(
|
||||||
|
.DATA_WIDTH(DATA_WIDTH),
|
||||||
|
.ADDRESS_WIDTH(ADDRESS_WIDTH)
|
||||||
|
) b_ram (
|
||||||
|
.write_enable(write_enable_b),
|
||||||
|
.clk(clk_b),
|
||||||
|
.data_in(data_in_b),
|
||||||
|
.address_in(address_in_b),
|
||||||
|
.data_out(data_out_b)
|
||||||
|
);
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
endmodule // double_sync_ram_sp
|
||||||
|
|
||||||
|
|
||||||
module double_sync_ram_sdp #(parameter DATA_WIDTH_A=8, ADDRESS_WIDTH_A=10, DATA_WIDTH_B=8, ADDRESS_WIDTH_B=10)
|
module double_sync_ram_sdp #(parameter DATA_WIDTH_A=8, ADDRESS_WIDTH_A=10, DATA_WIDTH_B=8, ADDRESS_WIDTH_B=10)
|
||||||
(
|
(
|
||||||
input wire write_enable_a, clk_a,
|
input wire write_enable_a, clk_a,
|
||||||
|
|
|
||||||
|
|
@ -23,7 +23,7 @@ EOF
|
||||||
|
|
||||||
read_verilog -lib +/ecp5/cells_sim.v
|
read_verilog -lib +/ecp5/cells_sim.v
|
||||||
|
|
||||||
equiv_opt -assert -map +/ecp5/cells_sim.v opt_lut_ins -tech ecp5
|
equiv_opt -assert -map +/ecp5/cells_sim.v opt_lut_ins -tech lattice
|
||||||
|
|
||||||
design -load postopt
|
design -load postopt
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue