[test] reworking adder mapping flow to validate carry chain mapping
This commit is contained in:
parent
ce71f097b4
commit
dba48fb171
|
@ -0,0 +1,48 @@
|
||||||
|
# Yosys synthesis script for ${TOP_MODULE}
|
||||||
|
# Read verilog files
|
||||||
|
read_verilog ${READ_VERILOG_OPTIONS} ${VERILOG_FILES}
|
||||||
|
|
||||||
|
# Technology mapping
|
||||||
|
hierarchy -top ${TOP_MODULE}
|
||||||
|
proc
|
||||||
|
techmap -D NO_LUT -map +/adff2dff.v
|
||||||
|
|
||||||
|
# Synthesis
|
||||||
|
flatten
|
||||||
|
opt_expr
|
||||||
|
opt_clean
|
||||||
|
check
|
||||||
|
opt -nodffe -nosdff
|
||||||
|
fsm
|
||||||
|
opt -nodffe -nosdff
|
||||||
|
wreduce
|
||||||
|
peepopt
|
||||||
|
opt_clean
|
||||||
|
|
||||||
|
# Map Adders
|
||||||
|
techmap -map +/techmap.v -map ${YOSYS_ADDER_MAP_VERILOG}
|
||||||
|
opt -fast -nodffe -nosdff
|
||||||
|
opt_expr
|
||||||
|
opt_merge
|
||||||
|
opt_clean
|
||||||
|
opt -nodffe -nosdff
|
||||||
|
|
||||||
|
#
|
||||||
|
memory -nomap
|
||||||
|
opt_clean
|
||||||
|
opt -fast -full -nodffe -nosdff
|
||||||
|
memory_map
|
||||||
|
opt -full -nodffe -nosdff
|
||||||
|
techmap
|
||||||
|
opt -fast -nodffe -nosdff
|
||||||
|
clean
|
||||||
|
|
||||||
|
# LUT mapping
|
||||||
|
abc -lut ${LUT_SIZE}
|
||||||
|
|
||||||
|
# Check
|
||||||
|
synth -run check
|
||||||
|
|
||||||
|
# Clean and output blif
|
||||||
|
opt_clean -purge
|
||||||
|
write_blif ${OUTPUT_BLIF}
|
|
@ -1,6 +1,7 @@
|
||||||
//---------------------------------------
|
//---------------------------------------
|
||||||
// 1-bit adder
|
// 1-bit adder
|
||||||
//---------------------------------------
|
//---------------------------------------
|
||||||
|
(* abc9_box, lib_whitebox *)
|
||||||
module adder(
|
module adder(
|
||||||
input cin,
|
input cin,
|
||||||
input a,
|
input a,
|
||||||
|
|
|
@ -1,164 +1,67 @@
|
||||||
//////////////////////////
|
// Arithmetic units: adder
|
||||||
// arithmetic //
|
// Adapt from: https://github.com/chipsalliance/yosys-f4pga-plugins/blob/0ad1af26a29243a9e76379943d735e119dcd0cc6/ql-qlf-plugin/qlf_k6n10/cells_sim.v
|
||||||
//////////////////////////
|
// Many thanks to F4PGA for their contribution
|
||||||
|
|
||||||
module \$alu (A, B, CI, BI, X, Y, CO);
|
(* techmap_celltype = "$alu" *)
|
||||||
|
module _openfpga_alu (A, B, CI, BI, X, Y, CO);
|
||||||
|
|
||||||
parameter A_SIGNED = 0;
|
parameter A_SIGNED = 0;
|
||||||
parameter B_SIGNED = 0;
|
parameter B_SIGNED = 0;
|
||||||
parameter A_WIDTH = 1;
|
parameter A_WIDTH = 1;
|
||||||
parameter B_WIDTH = 1;
|
parameter B_WIDTH = 1;
|
||||||
parameter Y_WIDTH = 1;
|
parameter Y_WIDTH = 1;
|
||||||
|
|
||||||
input [A_WIDTH-1:0] A;
|
input [A_WIDTH-1:0] A;
|
||||||
input [B_WIDTH-1:0] B;
|
input [B_WIDTH-1:0] B;
|
||||||
output [Y_WIDTH:0] X, Y;
|
output [Y_WIDTH-1:0] X, Y;
|
||||||
|
|
||||||
input CI, BI;
|
input CI, BI;
|
||||||
output [Y_WIDTH:0] CO;
|
output [Y_WIDTH-1:0] CO;
|
||||||
|
|
||||||
wire [Y_WIDTH-1:0] AA, BB;
|
wire [1024:0] _TECHMAP_DO_ = "splitnets CARRY; clean";
|
||||||
wire [1024:0] _TECHMAP_DO_ = "splitnets CARRY; clean";
|
|
||||||
|
|
||||||
generate
|
(* force_downto *)
|
||||||
if (A_SIGNED && B_SIGNED) begin:BLOCK1
|
wire [Y_WIDTH-1:0] A_buf, B_buf;
|
||||||
assign AA = $signed(A), BB = BI ? ~$signed(B) : $signed(B);
|
\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(A_buf));
|
||||||
end else begin:BLOCK2
|
\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
|
||||||
assign AA = $unsigned(A), BB = BI ? ~$unsigned(B) : $unsigned(B);
|
|
||||||
end
|
|
||||||
endgenerate
|
|
||||||
|
|
||||||
wire [Y_WIDTH: 0 ] CARRY;
|
(* force_downto *)
|
||||||
assign CARRY[0] = CI;
|
wire [Y_WIDTH-1:0] AA = A_buf;
|
||||||
|
(* force_downto *)
|
||||||
|
wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf;
|
||||||
|
wire [Y_WIDTH: 0 ] CARRY;
|
||||||
|
|
||||||
genvar i;
|
assign CO[Y_WIDTH-1:0] = CARRY[Y_WIDTH:1];
|
||||||
generate for (i = 0; i < Y_WIDTH - 1; i = i+1) begin:gen3
|
// Due to VPR limitations regarding IO connexion to carry chain,
|
||||||
adder my_adder (
|
// we generate the carry chain input signal using an intermediate adder
|
||||||
.cin (CARRY[i]),
|
// since we can connect a & b from io pads, but not cin & cout
|
||||||
.cout (CARRY[i+1]),
|
generate
|
||||||
.a (AA[i]),
|
adder intermediate_adder (
|
||||||
.b (BB[i]),
|
.cin ( ),
|
||||||
.sumout (Y[i])
|
.cout (CARRY[0]),
|
||||||
);
|
.a (CI ),
|
||||||
end endgenerate
|
.b (CI ),
|
||||||
|
.sumout ( )
|
||||||
|
);
|
||||||
|
|
||||||
generate if ((Y_WIDTH -1) % 20 == 0) begin:gen4
|
adder first_adder (
|
||||||
assign Y[Y_WIDTH-1] = CARRY[Y_WIDTH-1];
|
.cin (CARRY[0]),
|
||||||
end else begin:gen5
|
.cout (CARRY[1]),
|
||||||
adder my_adder (
|
.a (AA[0] ),
|
||||||
.cin (CARRY[Y_WIDTH - 1]),
|
.b (BB[0] ),
|
||||||
.cout (CARRY[Y_WIDTH]),
|
.sumout (Y[0] )
|
||||||
.a (1'b0),
|
);
|
||||||
.b (1'b0),
|
endgenerate
|
||||||
.sumout (Y[Y_WIDTH -1])
|
|
||||||
);
|
|
||||||
end
|
|
||||||
endgenerate
|
|
||||||
endmodule
|
|
||||||
|
|
||||||
//---------------------------------------------------------
|
genvar i;
|
||||||
|
generate for (i = 1; i < Y_WIDTH ; i = i+1) begin:gen3
|
||||||
module \$fa (A, B, C, X, Y);
|
adder my_adder (
|
||||||
|
.cin (CARRY[i] ),
|
||||||
parameter A_SIGNED = 0;
|
.cout (CARRY[i+1]),
|
||||||
parameter B_SIGNED = 0;
|
.a (AA[i] ),
|
||||||
parameter A_WIDTH = 1;
|
.b (BB[i] ),
|
||||||
parameter B_WIDTH = 1;
|
.sumout (Y[i] )
|
||||||
parameter Y_WIDTH = 1;
|
);
|
||||||
|
end endgenerate
|
||||||
input [A_WIDTH-1:0] A;
|
assign X = AA ^ BB;
|
||||||
input [B_WIDTH-1:0] B;
|
endmodule
|
||||||
input C;
|
|
||||||
output [Y_WIDTH:0] X, Y;
|
|
||||||
|
|
||||||
wire [Y_WIDTH-1:0] AA, BB;
|
|
||||||
wire [1024:0] _TECHMAP_DO_ = "splitnets CARRY; clean";
|
|
||||||
|
|
||||||
generate
|
|
||||||
if (A_SIGNED && B_SIGNED) begin:BLOCK1
|
|
||||||
assign AA = $signed(A), BB = $signed(B);
|
|
||||||
end else begin:BLOCK2
|
|
||||||
assign AA = $unsigned(A), BB = $unsigned(B);
|
|
||||||
end
|
|
||||||
endgenerate
|
|
||||||
|
|
||||||
wire [Y_WIDTH: 0 ] CARRY;
|
|
||||||
assign CARRY[0] = C;
|
|
||||||
|
|
||||||
genvar i;
|
|
||||||
generate for (i = 0; i < Y_WIDTH - 1; i = i+1) begin:gen3
|
|
||||||
adder my_adder (
|
|
||||||
.cin (CARRY[i]),
|
|
||||||
.cout (CARRY[i+1]),
|
|
||||||
.a (AA[i]),
|
|
||||||
.b (BB[i]),
|
|
||||||
.sumout (Y[i])
|
|
||||||
);
|
|
||||||
end endgenerate
|
|
||||||
|
|
||||||
generate if ((Y_WIDTH -1) % 20 == 0) begin:gen4
|
|
||||||
assign Y[Y_WIDTH-1] = CARRY[Y_WIDTH-1];
|
|
||||||
end else begin:gen5
|
|
||||||
adder my_adder (
|
|
||||||
.cin (CARRY[Y_WIDTH - 1]),
|
|
||||||
.cout (CARRY[Y_WIDTH]),
|
|
||||||
.a (1'b0),
|
|
||||||
.b (1'b0),
|
|
||||||
.sumout (Y[Y_WIDTH -1])
|
|
||||||
);
|
|
||||||
end
|
|
||||||
endgenerate
|
|
||||||
endmodule
|
|
||||||
|
|
||||||
//---------------------------------------------------------
|
|
||||||
|
|
||||||
module \$add (A, B, Y);
|
|
||||||
|
|
||||||
parameter A_SIGNED = 0;
|
|
||||||
parameter B_SIGNED = 0;
|
|
||||||
parameter A_WIDTH = 1;
|
|
||||||
parameter B_WIDTH = 1;
|
|
||||||
parameter Y_WIDTH = 1;
|
|
||||||
|
|
||||||
input [A_WIDTH-1:0] A;
|
|
||||||
input [B_WIDTH-1:0] B;
|
|
||||||
output [Y_WIDTH:0] Y;
|
|
||||||
|
|
||||||
wire [Y_WIDTH-1:0] AA, BB;
|
|
||||||
wire [1024:0] _TECHMAP_DO_ = "splitnets CARRY; clean";
|
|
||||||
|
|
||||||
generate
|
|
||||||
if (A_SIGNED && B_SIGNED) begin:BLOCK1
|
|
||||||
assign AA = $signed(A), BB = $signed(B);
|
|
||||||
end else begin:BLOCK2
|
|
||||||
assign AA = $unsigned(A), BB = $unsigned(B);
|
|
||||||
end
|
|
||||||
endgenerate
|
|
||||||
|
|
||||||
wire [Y_WIDTH: 0 ] CARRY;
|
|
||||||
assign CARRY[0] = 1'b0;
|
|
||||||
|
|
||||||
genvar i;
|
|
||||||
generate for (i = 0; i < Y_WIDTH - 1; i = i+1) begin:gen3
|
|
||||||
adder my_adder (
|
|
||||||
.cin (CARRY[i]),
|
|
||||||
.cout (CARRY[i+1]),
|
|
||||||
.a (AA[i]),
|
|
||||||
.b (BB[i]),
|
|
||||||
.sumout (Y[i])
|
|
||||||
);
|
|
||||||
end endgenerate
|
|
||||||
|
|
||||||
generate if ((Y_WIDTH -1) % 20 == 0) begin:gen4
|
|
||||||
assign Y[Y_WIDTH-1] = CARRY[Y_WIDTH-1];
|
|
||||||
end else begin:gen5
|
|
||||||
adder my_adder (
|
|
||||||
.cin (CARRY[Y_WIDTH - 1]),
|
|
||||||
.cout (CARRY[Y_WIDTH]),
|
|
||||||
.a (1'b0),
|
|
||||||
.b (1'b0),
|
|
||||||
.sumout (Y[Y_WIDTH -1])
|
|
||||||
);
|
|
||||||
end
|
|
||||||
endgenerate
|
|
||||||
endmodule
|
|
||||||
|
|
|
@ -294,6 +294,7 @@ def generate_each_task_actions(taskname):
|
||||||
yosys_params = [
|
yosys_params = [
|
||||||
"read_verilog_options",
|
"read_verilog_options",
|
||||||
"yosys_args",
|
"yosys_args",
|
||||||
|
"yosys_adder_map_verilog",
|
||||||
"yosys_bram_map_rules",
|
"yosys_bram_map_rules",
|
||||||
"yosys_bram_map_verilog",
|
"yosys_bram_map_verilog",
|
||||||
"yosys_cell_sim_verilog",
|
"yosys_cell_sim_verilog",
|
||||||
|
|
|
@ -0,0 +1,4 @@
|
||||||
|
<pin_constraints>
|
||||||
|
<!-- Intend to be empty -->
|
||||||
|
</pin_constraints>
|
||||||
|
|
|
@ -9,29 +9,33 @@
|
||||||
[GENERAL]
|
[GENERAL]
|
||||||
run_engine=openfpga_shell
|
run_engine=openfpga_shell
|
||||||
power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml
|
power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml
|
||||||
power_analysis = true
|
power_analysis = false
|
||||||
spice_output=false
|
spice_output=false
|
||||||
verilog_output=true
|
verilog_output=true
|
||||||
timeout_each_job = 20*60
|
timeout_each_job = 20*60
|
||||||
fpga_flow=vpr_blif
|
fpga_flow=yosys_vpr
|
||||||
|
|
||||||
[OpenFPGA_SHELL]
|
[OpenFPGA_SHELL]
|
||||||
openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/fix_device_example_script.openfpga
|
openfpga_shell_template=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_shell_scripts/example_without_ace_script.openfpga
|
||||||
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k6_frac_N10_adder_chain_40nm_openfpga.xml
|
openfpga_arch_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_arch/k6_frac_N10_adder_chain_40nm_openfpga.xml
|
||||||
openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_sim_openfpga.xml
|
openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml
|
||||||
openfpga_vpr_device_layout=2x2
|
openfpga_pin_constraints_file=${PATH:TASK_DIR}/config/dummy_pin_constraints.xml
|
||||||
|
|
||||||
[ARCHITECTURES]
|
[ARCHITECTURES]
|
||||||
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_chain_40nm.xml
|
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_chain_40nm.xml
|
||||||
|
|
||||||
[BENCHMARKS]
|
[BENCHMARKS]
|
||||||
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.blif
|
bench0=${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/adder/adder_8/adder_8.v
|
||||||
|
|
||||||
[SYNTHESIS_PARAM]
|
[SYNTHESIS_PARAM]
|
||||||
bench0_top = and2
|
# Yosys script parameters
|
||||||
bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.act
|
bench_yosys_cell_sim_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/openfpga_adders_sim.v
|
||||||
bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v
|
bench_yosys_adder_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/openfpga_arith_map.v
|
||||||
bench0_chan_width = 300
|
bench_read_verilog_options_common = -nolatches
|
||||||
|
bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_adder_flow.ys
|
||||||
|
|
||||||
|
# Benchmark information
|
||||||
|
bench0_top = adder_8
|
||||||
|
|
||||||
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
|
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
|
||||||
end_flow_with_test=
|
end_flow_with_test=
|
||||||
|
|
Loading…
Reference in New Issue