mirror of https://github.com/YosysHQ/yosys.git
synth_quicklogic: add -dspv2 to opt into v2 DSP blocks
This commit is contained in:
parent
fa8fc08621
commit
23924902a7
|
@ -38,9 +38,11 @@ $(eval $(call add_share_file,share/quicklogic/qlf_k6n10f,techlibs/quicklogic/qlf
|
||||||
$(eval $(call add_gen_share_file,share/quicklogic/qlf_k6n10f,techlibs/quicklogic/qlf_k6n10f/bram_types_sim.v))
|
$(eval $(call add_gen_share_file,share/quicklogic/qlf_k6n10f,techlibs/quicklogic/qlf_k6n10f/bram_types_sim.v))
|
||||||
$(eval $(call add_share_file,share/quicklogic/qlf_k6n10f,techlibs/quicklogic/qlf_k6n10f/cells_sim.v))
|
$(eval $(call add_share_file,share/quicklogic/qlf_k6n10f,techlibs/quicklogic/qlf_k6n10f/cells_sim.v))
|
||||||
$(eval $(call add_share_file,share/quicklogic/qlf_k6n10f,techlibs/quicklogic/qlf_k6n10f/ffs_map.v))
|
$(eval $(call add_share_file,share/quicklogic/qlf_k6n10f,techlibs/quicklogic/qlf_k6n10f/ffs_map.v))
|
||||||
$(eval $(call add_share_file,share/quicklogic/qlf_k6n10f,techlibs/quicklogic/qlf_k6n10f/dsp_sim.v))
|
$(eval $(call add_share_file,share/quicklogic/qlf_k6n10f,techlibs/quicklogic/qlf_k6n10f/dspv1_sim.v))
|
||||||
$(eval $(call add_share_file,share/quicklogic/qlf_k6n10f,techlibs/quicklogic/qlf_k6n10f/dsp_map.v))
|
$(eval $(call add_share_file,share/quicklogic/qlf_k6n10f,techlibs/quicklogic/qlf_k6n10f/dspv1_map.v))
|
||||||
$(eval $(call add_share_file,share/quicklogic/qlf_k6n10f,techlibs/quicklogic/qlf_k6n10f/dsp_final_map.v))
|
$(eval $(call add_share_file,share/quicklogic/qlf_k6n10f,techlibs/quicklogic/qlf_k6n10f/dspv1_final_map.v))
|
||||||
|
$(eval $(call add_share_file,share/quicklogic/qlf_k6n10f,techlibs/quicklogic/qlf_k6n10f/dspv2_sim.v))
|
||||||
|
$(eval $(call add_share_file,share/quicklogic/qlf_k6n10f,techlibs/quicklogic/qlf_k6n10f/dspv2_map.v))
|
||||||
$(eval $(call add_share_file,share/quicklogic/qlf_k6n10f,techlibs/quicklogic/qlf_k6n10f/TDP18K_FIFO.v))
|
$(eval $(call add_share_file,share/quicklogic/qlf_k6n10f,techlibs/quicklogic/qlf_k6n10f/TDP18K_FIFO.v))
|
||||||
$(eval $(call add_share_file,share/quicklogic/qlf_k6n10f,techlibs/quicklogic/qlf_k6n10f/ufifo_ctl.v))
|
$(eval $(call add_share_file,share/quicklogic/qlf_k6n10f,techlibs/quicklogic/qlf_k6n10f/ufifo_ctl.v))
|
||||||
$(eval $(call add_share_file,share/quicklogic/qlf_k6n10f,techlibs/quicklogic/qlf_k6n10f/sram1024x18_mem.v))
|
$(eval $(call add_share_file,share/quicklogic/qlf_k6n10f,techlibs/quicklogic/qlf_k6n10f/sram1024x18_mem.v))
|
|
@ -0,0 +1,102 @@
|
||||||
|
// Copyright 2020-2022 F4PGA Authors
|
||||||
|
//
|
||||||
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
// you may not use this file except in compliance with the License.
|
||||||
|
// You may obtain a copy of the License at
|
||||||
|
//
|
||||||
|
// http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
//
|
||||||
|
// Unless required by applicable law or agreed to in writing, software
|
||||||
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
// See the License for the specific language governing permissions and
|
||||||
|
// limitations under the License.
|
||||||
|
//
|
||||||
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
|
module \$__QL_MUL20X18 (input [19:0] A, input [17:0] B, output [37:0] Y);
|
||||||
|
parameter A_SIGNED = 0;
|
||||||
|
parameter B_SIGNED = 0;
|
||||||
|
parameter A_WIDTH = 0;
|
||||||
|
parameter B_WIDTH = 0;
|
||||||
|
parameter Y_WIDTH = 0;
|
||||||
|
|
||||||
|
wire [19:0] a;
|
||||||
|
wire [17:0] b;
|
||||||
|
wire [37:0] z;
|
||||||
|
|
||||||
|
assign a = (A_WIDTH == 20) ? A :
|
||||||
|
(A_SIGNED) ? {{(20 - A_WIDTH){A[A_WIDTH-1]}}, A} :
|
||||||
|
{{(20 - A_WIDTH){1'b0}}, A};
|
||||||
|
|
||||||
|
assign b = (B_WIDTH == 18) ? B :
|
||||||
|
(B_SIGNED) ? {{(18 - B_WIDTH){B[B_WIDTH-1]}}, B} :
|
||||||
|
{{(18 - B_WIDTH){1'b0}}, B};
|
||||||
|
|
||||||
|
(* is_inferred=1 *)
|
||||||
|
dsp_t1_20x18x64_cfg_ports _TECHMAP_REPLACE_ (
|
||||||
|
.a_i (a),
|
||||||
|
.b_i (b),
|
||||||
|
.acc_fir_i (6'd0),
|
||||||
|
.z_o (z),
|
||||||
|
|
||||||
|
.feedback_i (3'd0),
|
||||||
|
.load_acc_i (1'b0),
|
||||||
|
.unsigned_a_i (!A_SIGNED),
|
||||||
|
.unsigned_b_i (!B_SIGNED),
|
||||||
|
|
||||||
|
.output_select_i (3'd0),
|
||||||
|
.saturate_enable_i (1'b0),
|
||||||
|
.shift_right_i (6'd0),
|
||||||
|
.round_i (1'b0),
|
||||||
|
.subtract_i (1'b0),
|
||||||
|
.register_inputs_i (1'b0)
|
||||||
|
);
|
||||||
|
|
||||||
|
assign Y = z;
|
||||||
|
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module \$__QL_MUL10X9 (input [9:0] A, input [8:0] B, output [18:0] Y);
|
||||||
|
parameter A_SIGNED = 0;
|
||||||
|
parameter B_SIGNED = 0;
|
||||||
|
parameter A_WIDTH = 0;
|
||||||
|
parameter B_WIDTH = 0;
|
||||||
|
parameter Y_WIDTH = 0;
|
||||||
|
|
||||||
|
wire [ 9:0] a;
|
||||||
|
wire [ 8:0] b;
|
||||||
|
wire [18:0] z;
|
||||||
|
|
||||||
|
assign a = (A_WIDTH == 10) ? A :
|
||||||
|
(A_SIGNED) ? {{(10 - A_WIDTH){A[A_WIDTH-1]}}, A} :
|
||||||
|
{{(10 - A_WIDTH){1'b0}}, A};
|
||||||
|
|
||||||
|
assign b = (B_WIDTH == 9) ? B :
|
||||||
|
(B_SIGNED) ? {{( 9 - B_WIDTH){B[B_WIDTH-1]}}, B} :
|
||||||
|
{{( 9 - B_WIDTH){1'b0}}, B};
|
||||||
|
|
||||||
|
(* is_inferred=1 *)
|
||||||
|
dsp_t1_10x9x32_cfg_ports _TECHMAP_REPLACE_ (
|
||||||
|
.a_i (a),
|
||||||
|
.b_i (b),
|
||||||
|
.acc_fir_i (6'd0),
|
||||||
|
.z_o (z),
|
||||||
|
|
||||||
|
.feedback_i (3'd0),
|
||||||
|
.load_acc_i (1'b0),
|
||||||
|
.unsigned_a_i (!A_SIGNED),
|
||||||
|
.unsigned_b_i (!B_SIGNED),
|
||||||
|
|
||||||
|
.output_select_i (3'd0),
|
||||||
|
.saturate_enable_i (1'b0),
|
||||||
|
.shift_right_i (6'd0),
|
||||||
|
.round_i (1'b0),
|
||||||
|
.subtract_i (1'b0),
|
||||||
|
.register_inputs_i (1'b0)
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
assign Y = z;
|
||||||
|
|
||||||
|
endmodule
|
File diff suppressed because it is too large
Load Diff
|
@ -27,6 +27,12 @@ PRIVATE_NAMESPACE_BEGIN
|
||||||
|
|
||||||
struct SynthQuickLogicPass : public ScriptPass {
|
struct SynthQuickLogicPass : public ScriptPass {
|
||||||
|
|
||||||
|
enum DSPKind {
|
||||||
|
None,
|
||||||
|
V1,
|
||||||
|
V2,
|
||||||
|
};
|
||||||
|
|
||||||
SynthQuickLogicPass() : ScriptPass("synth_quicklogic", "Synthesis for QuickLogic FPGAs") {}
|
SynthQuickLogicPass() : ScriptPass("synth_quicklogic", "Synthesis for QuickLogic FPGAs") {}
|
||||||
|
|
||||||
void help() override
|
void help() override
|
||||||
|
@ -50,6 +56,10 @@ struct SynthQuickLogicPass : public ScriptPass {
|
||||||
log(" do not use dsp_t1_* to implement multipliers and associated logic\n");
|
log(" do not use dsp_t1_* to implement multipliers and associated logic\n");
|
||||||
log(" (qlf_k6n10f only).\n");
|
log(" (qlf_k6n10f only).\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
|
log(" -dspv2\n");
|
||||||
|
log(" synthesize for the v2 DSP block model instead of v1\n");
|
||||||
|
log(" (qlf_k6n10f only).\n");
|
||||||
|
log("\n");
|
||||||
log(" -nocarry\n");
|
log(" -nocarry\n");
|
||||||
log(" do not use adder_carry cells in output netlist.\n");
|
log(" do not use adder_carry cells in output netlist.\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
|
@ -78,7 +88,8 @@ struct SynthQuickLogicPass : public ScriptPass {
|
||||||
}
|
}
|
||||||
|
|
||||||
string top_opt, blif_file, edif_file, family, currmodule, verilog_file, lib_path;
|
string top_opt, blif_file, edif_file, family, currmodule, verilog_file, lib_path;
|
||||||
bool abc9, inferAdder, nobram, bramTypes, dsp;
|
bool abc9, inferAdder, nobram, bramTypes;
|
||||||
|
DSPKind dsp;
|
||||||
|
|
||||||
void clear_flags() override
|
void clear_flags() override
|
||||||
{
|
{
|
||||||
|
@ -93,7 +104,7 @@ struct SynthQuickLogicPass : public ScriptPass {
|
||||||
nobram = false;
|
nobram = false;
|
||||||
bramTypes = false;
|
bramTypes = false;
|
||||||
lib_path = "+/quicklogic/";
|
lib_path = "+/quicklogic/";
|
||||||
dsp = true;
|
dsp = V1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void set_scratchpad_defaults(RTLIL::Design *design) {
|
void set_scratchpad_defaults(RTLIL::Design *design) {
|
||||||
|
@ -155,7 +166,11 @@ struct SynthQuickLogicPass : public ScriptPass {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if (args[argidx] == "-nodsp" || args[argidx] == "-no_dsp") {
|
if (args[argidx] == "-nodsp" || args[argidx] == "-no_dsp") {
|
||||||
dsp = false;
|
dsp = None;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (args[argidx] == "-dspv2") {
|
||||||
|
dsp = V2;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
@ -193,8 +208,10 @@ struct SynthQuickLogicPass : public ScriptPass {
|
||||||
read_simlibs += stringf(" %sqlf_k6n10f/brams_sim.v", lib_path.c_str());
|
read_simlibs += stringf(" %sqlf_k6n10f/brams_sim.v", lib_path.c_str());
|
||||||
if (bramTypes)
|
if (bramTypes)
|
||||||
read_simlibs += stringf(" %sqlf_k6n10f/bram_types_sim.v", lib_path.c_str());
|
read_simlibs += stringf(" %sqlf_k6n10f/bram_types_sim.v", lib_path.c_str());
|
||||||
if (dsp)
|
if (dsp == V1)
|
||||||
read_simlibs += stringf(" %sqlf_k6n10f/dsp_sim.v", lib_path.c_str());
|
read_simlibs += stringf(" %sqlf_k6n10f/dspv1_sim.v", lib_path.c_str());
|
||||||
|
else if (dsp == V2)
|
||||||
|
read_simlibs += stringf(" %sqlf_k6n10f/dspv2_sim.v", lib_path.c_str());
|
||||||
}
|
}
|
||||||
run(read_simlibs);
|
run(read_simlibs);
|
||||||
run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
|
run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
|
||||||
|
@ -220,23 +237,31 @@ struct SynthQuickLogicPass : public ScriptPass {
|
||||||
}
|
}
|
||||||
|
|
||||||
if (check_label("map_dsp", "(for qlf_k6n10f, skip if -nodsp)")
|
if (check_label("map_dsp", "(for qlf_k6n10f, skip if -nodsp)")
|
||||||
&& ((dsp && family == "qlf_k6n10f") || help_mode)) {
|
&& (((dsp != None) && family == "qlf_k6n10f") || help_mode)) {
|
||||||
run("wreduce t:$mul");
|
run("wreduce t:$mul");
|
||||||
//run("ql_dsp_macc");
|
|
||||||
|
|
||||||
|
if (dsp == V1) {
|
||||||
|
run("ql_dsp_macc");
|
||||||
|
|
||||||
run("techmap -map +/mul2dsp.v -map " + lib_path + family + "/dsp_map.v -D USE_DSP_CFG_PARAMS=0 -D DSP_SIGNEDONLY "
|
run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=20 -D DSP_B_MAXWIDTH=18 -D DSP_A_MINWIDTH=11 -D DSP_B_MINWIDTH=10 -D DSP_NAME=$__QL_MUL20X18");
|
||||||
"-D DSP_A_MAXWIDTH=32 -D DSP_B_MAXWIDTH=18 -D DSP_A_MINWIDTH=10 -D DSP_B_MINWIDTH=10 -D DSP_NAME=$__MUL32X18");
|
run("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=10 -D DSP_B_MAXWIDTH=9 -D DSP_A_MINWIDTH=4 -D DSP_B_MINWIDTH=4 -D DSP_NAME=$__QL_MUL10X9");
|
||||||
run("chtype -set $mul t:$__soft_mul");
|
run("chtype -set $mul t:$__soft_mul");
|
||||||
run("techmap -map +/mul2dsp.v -map " + lib_path + family + "/dsp_map.v -D USE_DSP_CFG_PARAMS=0 -D DSP_SIGNEDONLY "
|
|
||||||
"-D DSP_A_MAXWIDTH=16 -D DSP_B_MAXWIDTH=9 -D DSP_A_MINWIDTH=4 -D DSP_B_MINWIDTH=4 -D DSP_NAME=$__MUL16X9");
|
|
||||||
run("chtype -set $mul t:$__soft_mul");
|
|
||||||
|
|
||||||
run("ql_dsp");
|
run("techmap -map " + lib_path + family + "/dspv1_map.v -D USE_DSP_CFG_PARAMS=0");
|
||||||
|
run("ql_dsp_simd");
|
||||||
//run("ql_dsp_simd");
|
run("techmap -map " + lib_path + family + "/dspv1_final_map.v");
|
||||||
//run("techmap -map " + lib_path + family + "/dsp_final_map.v");
|
run("ql_dsp_io_regs");
|
||||||
//run("ql_dsp_io_regs");
|
} else if (dsp == V2) {
|
||||||
|
run("techmap -map +/mul2dsp.v -map " + lib_path + family + "/dspv2_map.v -D USE_DSP_CFG_PARAMS=0 -D DSP_SIGNEDONLY "
|
||||||
|
"-D DSP_A_MAXWIDTH=32 -D DSP_B_MAXWIDTH=18 -D DSP_A_MINWIDTH=10 -D DSP_B_MINWIDTH=10 -D DSP_NAME=$__MUL32X18");
|
||||||
|
run("chtype -set $mul t:$__soft_mul");
|
||||||
|
run("techmap -map +/mul2dsp.v -map " + lib_path + family + "/dspv2_map.v -D USE_DSP_CFG_PARAMS=0 -D DSP_SIGNEDONLY "
|
||||||
|
"-D DSP_A_MAXWIDTH=16 -D DSP_B_MAXWIDTH=9 -D DSP_A_MINWIDTH=4 -D DSP_B_MINWIDTH=4 -D DSP_NAME=$__MUL16X9");
|
||||||
|
run("chtype -set $mul t:$__soft_mul");
|
||||||
|
run("ql_dspv2");
|
||||||
|
} else {
|
||||||
|
log_assert(false);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (check_label("coarse")) {
|
if (check_label("coarse")) {
|
||||||
|
|
|
@ -12,7 +12,7 @@ module top(input signed [16:0] ar, input signed [16:0] ai, input signed [16:0] b
|
||||||
endmodule
|
endmodule
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
synth_quicklogic -family qlf_k6n10f -run :coarse
|
synth_quicklogic -family qlf_k6n10f -dspv2 -run :coarse
|
||||||
check -assert
|
check -assert
|
||||||
read_verilog +/quicklogic/qlf_k6n10f/dsp_sim.v
|
read_verilog +/quicklogic/qlf_k6n10f/dsp_sim.v
|
||||||
prep -top top -flatten
|
prep -top top -flatten
|
||||||
|
|
|
@ -11,7 +11,7 @@ module top(input [16:0] a, input [16:0] b, output reg [33:0] o, input clk, input
|
||||||
endmodule
|
endmodule
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
synth_quicklogic -family qlf_k6n10f -run :coarse
|
synth_quicklogic -family qlf_k6n10f -dspv2 -run :coarse
|
||||||
check
|
check
|
||||||
opt_clean
|
opt_clean
|
||||||
dump
|
dump
|
||||||
|
|
|
@ -5,7 +5,7 @@ module top(input [16:0] a, input [16:0] b, input [16:0] c, input [16:0] d, outpu
|
||||||
endmodule
|
endmodule
|
||||||
EOF
|
EOF
|
||||||
|
|
||||||
synth_quicklogic -family qlf_k6n10f -run :coarse
|
synth_quicklogic -family qlf_k6n10f -dspv2 -run :coarse
|
||||||
read_verilog +/quicklogic/qlf_k6n10f/dsp_sim.v
|
read_verilog +/quicklogic/qlf_k6n10f/dsp_sim.v
|
||||||
prep -top top -flatten
|
prep -top top -flatten
|
||||||
opt_clean -purge
|
opt_clean -purge
|
||||||
|
|
Loading…
Reference in New Issue