Merge pull request #3087 from tgingold-cern/sf2

complete support for microsemi smartfusion2 and igloo2bar
This commit is contained in:
Miodrag Milanović 2022-08-31 09:30:09 +02:00 committed by GitHub
commit d8a383b555
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 305 additions and 6 deletions

84
techlibs/sf2/NOTES.txt Normal file
View File

@ -0,0 +1,84 @@
Using yosys with Libero Soc
===========================
Yosys does synthesis and therefore could be used instead of Synplify in
the Libero workflow. You still have to use LiberoSoc for place, route,
bitsteam generation, timing analysis...
This is unfortunately not trivial, but this is also not too difficult.
When you run the Synthesize step, three tools are executed one after the other.
You'd better to write a simple script, like this one (assuming the top module
is top):
----------- run_yosys.sh --------------
#!/bin/sh
set -e
yosys -p 'read_verilog hdl/top.v; synth_sf2; write_verilog -defparam synthesis/top_yosys.v'
rwnetlist64 --script yosys/rwnetlist.tcl
echo "##### run g4compile"
g4compile --script yosys/run_compile.tcl
libero SCRIPT:run_yosys.tcl
------------------------------------
Yosys will do the synthesis and write a netlist in verilog. Then you have
to call microsemi tools to build the netlist for the P&R tools.
The first one do a file format conversion. During the normal workflow, the
tcl file is created in a temporary file. You can use this one:
------------- tcl/rwnetlist.tcl ---------
set_device -fam SmartFusion2
read_verilog \
-file {../synthesis/top_yosys.v}
write_adl -file {../designer/top/top.adl}
----------------------------------------
Probably, you will have to change the family for Igloo2.
The second command link the netlists. The tcl script is generated by
liberoSoc in designer/top/run_compile.tcl. You can use it as it.
The "Source Files" value could be changed but it looks to have no effect.
This commands create the .afl file.
Then you can use the normal flow. This is done by the run_yosys.tcl:
----------- run_yosys.tcl --------------
open_project -file {./top.prjx}
run_tool -name {PLACEROUTE}
run_tool -name {PROGRAMDEVICE}
-----------------------------------------
Using MSS, HPMS or other IPs
============================
This works. You'd better to configure CCC (~ the PLL) and the MSS using
liberoSoc as the configuration bits are not documented.
Then you have to manually gather the HDL sources generated for the IPs.
They are in the component subdirectory. Sometimes there are both a _syn and
a _pre version of the same file. They are for symplify and precision.
Use only once, the symplify version should be OK. For the MSS, these are the
blackboxes, so you don't need them.
SYSRESET and XTLOSC have one fake port. This is handled, provided you use
the blackbox module declared by Yosys in cell_sim.v. This is OK by default
too.
What is missing
===============
Always flatten your design (this is the default). Hierarchical designs
don't work.
Constraints (SDC files) are not supported by Yosys. Furthermore, due to
flattening and optimization, nets name may change.
More testing...

View File

@ -17,5 +17,53 @@
*
*/
(* techmap_celltype = "$alu" *)
module \$__SF2_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;
(* 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] AA, BB;
\$pos #(.A_SIGNED(A_SIGNED), .A_WIDTH(A_WIDTH), .Y_WIDTH(Y_WIDTH)) A_conv (.A(A), .Y(AA));
\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(BB));
(* force_downto *)
wire [Y_WIDTH-1:0] C = {CO, CI};
genvar i;
generate for (i = 0; i < Y_WIDTH; i = i + 1) begin:slice
ARI1 #(
// G = F1 = A[i] & (B[i]^BI)
// Y = F0 = A[i]^B[i]^BI
// P = Y
// ADCB
.INIT(20'b 01_11_0010_1000_1001_0110)
) carry (
.A(1'b0),
.B(AA[i]),
.C(BB[i]),
.D(BI),
.FCI(C[i]),
.Y(X[i]),
.S(Y[i]),
.FCO(CO[i])
);
end endgenerate
endmodule
// nothing here yet

View File

@ -152,12 +152,26 @@ module SLE (
assign Q = LAT ? q_latch : q_ff;
endmodule
// module AR1
module ARI1 (
input A, B, C, D, FCI,
output Y, S, FCO
);
parameter [19:0] INIT = 20'h0;
wire [2:0] Fsel = {D, C, B};
wire F0 = INIT[Fsel];
wire F1 = INIT[8 + Fsel];
wire Yout = A ? F1 : F0;
assign Y = Yout;
wire S = FCI ^ Yout;
wire G = INIT[16] ? (INIT[17] ? F1 : F0) : INIT[17];
wire P = INIT[19] ? 1'b1 : (INIT[18] ? Yout : 1'b0);
assign FCO = P ? FCI : G;
endmodule
// module FCEND_BUFF
// module FCINIT_BUFF
// module FLASH_FREEZE
// module OSCILLATOR
// module SYSRESET
// module SYSCTRL_RESET_STATUS
// module LIVE_PROBE_FB
@ -333,6 +347,7 @@ module BIBUF (
inout PAD,
output Y
);
parameter IOSTD = "";
assign PAD = E ? D : 1'bz;
assign Y = PAD;
endmodule
@ -347,6 +362,7 @@ module BIBUF_DIFF (
inout PADN,
output Y
);
parameter IOSTD = "";
endmodule
module CLKBIBUF (
@ -357,6 +373,7 @@ module CLKBIBUF (
(* clkbuf_driver *)
output Y
);
parameter IOSTD = "";
assign PAD = E ? D : 1'bz;
assign Y = PAD;
endmodule
@ -367,6 +384,7 @@ module CLKBUF (
(* clkbuf_driver *)
output Y
);
parameter IOSTD = "";
assign Y = PAD;
endmodule
@ -379,6 +397,7 @@ module CLKBUF_DIFF (
(* clkbuf_driver *)
output Y
);
parameter IOSTD = "";
endmodule
module INBUF (
@ -386,6 +405,7 @@ module INBUF (
input PAD,
output Y
);
parameter IOSTD = "";
assign Y = PAD;
endmodule
@ -397,6 +417,7 @@ module INBUF_DIFF (
input PADN,
output Y
);
parameter IOSTD = "";
endmodule
module OUTBUF (
@ -404,6 +425,7 @@ module OUTBUF (
(* iopad_external_pin *)
output PAD
);
parameter IOSTD = "";
assign PAD = D;
endmodule
@ -415,6 +437,7 @@ module OUTBUF_DIFF (
(* iopad_external_pin *)
output PADN
);
parameter IOSTD = "";
endmodule
module TRIBUFF (
@ -423,6 +446,7 @@ module TRIBUFF (
(* iopad_external_pin *)
output PAD
);
parameter IOSTD = "";
assign PAD = E ? D : 1'bz;
endmodule
@ -435,6 +459,7 @@ module TRIBUFF_DIFF (
(* iopad_external_pin *)
output PADN
);
parameter IOSTD = "";
endmodule
// module DDR_IN
@ -442,3 +467,113 @@ endmodule
// module RAM1K18
// module RAM64x18
// module MACC
(* blackbox *)
module SYSRESET (
(* iopad_external_pin *)
input DEVRST_N,
output POWER_ON_RESET_N);
endmodule
(* blackbox *)
module XTLOSC (
(* iopad_external_pin *)
input XTL,
output CLKOUT);
parameter [1:0] MODE = 2'h3;
parameter real FREQUENCY = 20.0;
endmodule
(* blackbox *)
module RAM1K18 (
input [13:0] A_ADDR,
input [2:0] A_BLK,
(* clkbuf_sink *)
input A_CLK,
input [17:0] A_DIN,
output [17:0] A_DOUT,
input [1:0] A_WEN,
input [2:0] A_WIDTH,
input A_WMODE,
input A_ARST_N,
input A_DOUT_LAT,
input A_DOUT_ARST_N,
(* clkbuf_sink *)
input A_DOUT_CLK,
input A_DOUT_EN,
input A_DOUT_SRST_N,
input [13:0] B_ADDR,
input [2:0] B_BLK,
(* clkbuf_sink *)
input B_CLK,
input [17:0] B_DIN,
output [17:0] B_DOUT,
input [1:0] B_WEN,
input [2:0] B_WIDTH,
input B_WMODE,
input B_ARST_N,
input B_DOUT_LAT,
input B_DOUT_ARST_N,
(* clkbuf_sink *)
input B_DOUT_CLK,
input B_DOUT_EN,
input B_DOUT_SRST_N,
input A_EN,
input B_EN,
input SII_LOCK,
output BUSY);
endmodule
(* blackbox *)
module RAM64x18 (
input [9:0] A_ADDR,
input [1:0] A_BLK,
input [2:0] A_WIDTH,
output [17:0] A_DOUT,
input A_DOUT_ARST_N,
(* clkbuf_sink *)
input A_DOUT_CLK,
input A_DOUT_EN,
input A_DOUT_LAT,
input A_DOUT_SRST_N,
(* clkbuf_sink *)
input A_ADDR_CLK,
input A_ADDR_EN,
input A_ADDR_LAT,
input A_ADDR_SRST_N,
input A_ADDR_ARST_N,
input [9:0] B_ADDR,
input [1:0] B_BLK,
input [2:0] B_WIDTH,
output [17:0] B_DOUT,
input B_DOUT_ARST_N,
(* clkbuf_sink *)
input B_DOUT_CLK,
input B_DOUT_EN,
input B_DOUT_LAT,
input B_DOUT_SRST_N,
(* clkbuf_sink *)
input B_ADDR_CLK,
input B_ADDR_EN,
input B_ADDR_LAT,
input B_ADDR_SRST_N,
input B_ADDR_ARST_N,
input [9:0] C_ADDR,
(* clkbuf_sink *)
input C_CLK,
input [17:0] C_DIN,
input C_WEN,
input [1:0] C_BLK,
input [2:0] C_WIDTH,
input A_EN,
input B_EN,
input C_EN,
input SII_LOCK,
output BUSY);
endmodule

View File

@ -66,6 +66,9 @@ struct SynthSf2Pass : public ScriptPass
log(" -clkbuf\n");
log(" insert direct PAD->global_net buffers\n");
log("\n");
log(" -discard-ffinit\n");
log(" discard FF init value instead of emitting an error\n");
log("\n");
log(" -retime\n");
log(" run 'abc' with '-dff -D 1' options\n");
log("\n");
@ -76,7 +79,7 @@ struct SynthSf2Pass : public ScriptPass
}
string top_opt, edif_file, vlog_file, json_file;
bool flatten, retime, iobs, clkbuf;
bool flatten, retime, iobs, clkbuf, discard_ffinit;
void clear_flags() override
{
@ -88,6 +91,7 @@ struct SynthSf2Pass : public ScriptPass
retime = false;
iobs = true;
clkbuf = false;
discard_ffinit = false;
}
void execute(std::vector<std::string> args, RTLIL::Design *design) override
@ -138,6 +142,10 @@ struct SynthSf2Pass : public ScriptPass
clkbuf = true;
continue;
}
if (args[argidx] == "-discard-ffinit") {
discard_ffinit = true;
continue;
}
break;
}
extra_args(args, argidx, design);
@ -171,6 +179,8 @@ struct SynthSf2Pass : public ScriptPass
if (check_label("coarse"))
{
if (discard_ffinit || help_mode)
run("attrmap -remove init", "(only if -discard-ffinit)");
run("synth -run coarse");
}
@ -218,9 +228,9 @@ struct SynthSf2Pass : public ScriptPass
} else {
run("clkbufmap -buf CLKINT Y:A");
}
run("iopadmap -bits -inpad INBUF Y:PAD -outpad OUTBUF D:PAD -toutpad TRIBUFF E:D:PAD -tinoutpad BIBUF E:Y:D:PAD", "(unless -noiobs");
run("iopadmap -bits -inpad INBUF Y:PAD -outpad OUTBUF D:PAD -toutpad TRIBUFF E:D:PAD -tinoutpad BIBUF E:Y:D:PAD", "(unless -noiobs)");
}
run("clean");
run("clean -purge");
}
if (check_label("check"))

View File

@ -0,0 +1,22 @@
# Our implementation
read_verilog ../arith_map.v
read_verilog ../cells_sim.v
read_verilog -DSIMLIB_NOCHECKS ../../common/simlib.v
rename \$__SF2_ALU gate
hierarchy -top gate -chparam A_WIDTH 4 -chparam B_WIDTH 5 -chparam Y_WIDTH 5
flatten
opt
write_verilog gate.v
# The reference
read_verilog -DSIMLIB_NOCHECKS ../../common/simlib.v
rename \$alu gold
hierarchy -top gold -chparam A_WIDTH 4 -chparam B_WIDTH 5 -chparam Y_WIDTH 5
flatten
proc
clean
write_verilog gold.v
read_verilog gate.v
miter -equiv -flatten -make_outputs gold gate miter
sat -verify -prove trigger 0 -show-ports miter