Merge pull request #1226 from lnis-uofu/xt_adder
Enable Adder mapping and validation on FPGA architecture using hard adders
This commit is contained in:
commit
8d62ac1ec0
|
@ -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,15 +1,15 @@
|
|||
//---------------------------------------
|
||||
// 1-bit adder
|
||||
//---------------------------------------
|
||||
(* abc9_box, lib_whitebox *)
|
||||
module adder(
|
||||
input cin,
|
||||
input a,
|
||||
input b,
|
||||
output cout,
|
||||
output sumout );
|
||||
|
||||
|
||||
assign sumout = a ^ b ^ cin;
|
||||
assign cout = (a & b) | ((a | b) & cin);
|
||||
output sumout,
|
||||
output cout,
|
||||
input a,
|
||||
input b,
|
||||
input cin
|
||||
);
|
||||
assign sumout = a ^ b ^ cin;
|
||||
assign cout = (a & b) | ((a | b) & cin);
|
||||
|
||||
endmodule
|
||||
|
|
|
@ -1,164 +1,67 @@
|
|||
//////////////////////////
|
||||
// arithmetic //
|
||||
//////////////////////////
|
||||
// Arithmetic units: adder
|
||||
// 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 _80_quicklogic_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 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] X, Y;
|
||||
input [A_WIDTH-1:0] A;
|
||||
input [B_WIDTH-1:0] B;
|
||||
output [Y_WIDTH-1:0] X, Y;
|
||||
|
||||
input CI, BI;
|
||||
output [Y_WIDTH:0] CO;
|
||||
input CI, BI;
|
||||
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
|
||||
if (A_SIGNED && B_SIGNED) begin:BLOCK1
|
||||
assign AA = $signed(A), BB = BI ? ~$signed(B) : $signed(B);
|
||||
end else begin:BLOCK2
|
||||
assign AA = $unsigned(A), BB = BI ? ~$unsigned(B) : $unsigned(B);
|
||||
end
|
||||
endgenerate
|
||||
(* 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));
|
||||
|
||||
wire [Y_WIDTH: 0 ] CARRY;
|
||||
assign CARRY[0] = CI;
|
||||
(* force_downto *)
|
||||
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;
|
||||
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
|
||||
assign CO[Y_WIDTH-1:0] = CARRY[Y_WIDTH:1];
|
||||
// Due to VPR limitations regarding IO connexion to carry chain,
|
||||
// we generate the carry chain input signal using an intermediate adder
|
||||
// since we can connect a & b from io pads, but not cin & cout
|
||||
generate
|
||||
adder intermediate_adder (
|
||||
.cin ( ),
|
||||
.cout (CARRY[0]),
|
||||
.a (CI ),
|
||||
.b (CI ),
|
||||
.sumout ( )
|
||||
);
|
||||
|
||||
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
|
||||
adder first_adder (
|
||||
.cin (CARRY[0]),
|
||||
.cout (CARRY[1]),
|
||||
.a (AA[0] ),
|
||||
.b (BB[0] ),
|
||||
.sumout (Y[0] )
|
||||
);
|
||||
endgenerate
|
||||
|
||||
//---------------------------------------------------------
|
||||
|
||||
module \$fa (A, B, C, X, 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;
|
||||
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
|
||||
genvar i;
|
||||
generate for (i = 1; i < Y_WIDTH ; 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
|
||||
assign X = AA ^ BB;
|
||||
endmodule
|
||||
|
|
|
@ -294,6 +294,7 @@ def generate_each_task_actions(taskname):
|
|||
yosys_params = [
|
||||
"read_verilog_options",
|
||||
"yosys_args",
|
||||
"yosys_adder_map_verilog",
|
||||
"yosys_bram_map_rules",
|
||||
"yosys_bram_map_verilog",
|
||||
"yosys_cell_sim_verilog",
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
<pin_constraints>
|
||||
<!-- Intend to be empty -->
|
||||
</pin_constraints>
|
||||
|
|
@ -9,29 +9,34 @@
|
|||
[GENERAL]
|
||||
run_engine=openfpga_shell
|
||||
power_tech_file = ${PATH:OPENFPGA_PATH}/openfpga_flow/tech/PTM_45nm/45nm.xml
|
||||
power_analysis = true
|
||||
power_analysis = false
|
||||
spice_output=false
|
||||
verilog_output=true
|
||||
timeout_each_job = 20*60
|
||||
fpga_flow=vpr_blif
|
||||
fpga_flow=yosys_vpr
|
||||
|
||||
[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_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/auto_sim_openfpga.xml
|
||||
openfpga_vpr_device_layout=2x2
|
||||
openfpga_sim_setting_file=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_simulation_settings/fixed_sim_openfpga.xml
|
||||
openfpga_pin_constraints_file=${PATH:TASK_DIR}/config/dummy_pin_constraints.xml
|
||||
|
||||
[ARCHITECTURES]
|
||||
arch0=${PATH:OPENFPGA_PATH}/openfpga_flow/vpr_arch/k6_frac_N10_tileable_adder_chain_40nm.xml
|
||||
|
||||
[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]
|
||||
bench0_top = and2
|
||||
bench0_act = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.act
|
||||
bench0_verilog = ${PATH:OPENFPGA_PATH}/openfpga_flow/benchmarks/micro_benchmark/and2/and2.v
|
||||
bench0_chan_width = 300
|
||||
# Yosys script parameters
|
||||
bench_yosys_cell_sim_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/openfpga_adders_sim.v
|
||||
bench_yosys_adder_map_verilog_common=${PATH:OPENFPGA_PATH}/openfpga_flow/openfpga_yosys_techlib/openfpga_arith_map.v
|
||||
bench_read_verilog_options_common = -nolatches
|
||||
bench_yosys_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_adder_flow.ys
|
||||
bench_yosys_rewrite_common=${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_yosys_vpr_flow_with_rewrite.ys;${PATH:OPENFPGA_PATH}/openfpga_flow/misc/ys_tmpl_rewrite_flow.ys
|
||||
|
||||
# Benchmark information
|
||||
bench0_top = adder_8
|
||||
|
||||
[SCRIPT_PARAM_MIN_ROUTE_CHAN_WIDTH]
|
||||
end_flow_with_test=
|
||||
|
|
Loading…
Reference in New Issue