mirror of https://github.com/YosysHQ/yosys.git
Merge pull request #3120 from Icenowy/anlogic-bram
anlogic: support BRAM mapping
This commit is contained in:
commit
4525e419f6
|
@ -0,0 +1,2 @@
|
||||||
|
brams_init.mk
|
||||||
|
brams_init_*.vh
|
|
@ -3,6 +3,22 @@ OBJS += techlibs/anlogic/synth_anlogic.o
|
||||||
OBJS += techlibs/anlogic/anlogic_eqn.o
|
OBJS += techlibs/anlogic/anlogic_eqn.o
|
||||||
OBJS += techlibs/anlogic/anlogic_fixcarry.o
|
OBJS += techlibs/anlogic/anlogic_fixcarry.o
|
||||||
|
|
||||||
|
GENFILES += techlibs/anlogic/brams_init_16.vh
|
||||||
|
GENFILES += techlibs/anlogic/brams_init_9.vh
|
||||||
|
GENFILES += techlibs/anlogic/brams_init_8.vh
|
||||||
|
|
||||||
|
EXTRA_OBJS += techlibs/anlogic/brams_init.mk
|
||||||
|
.SECONDARY: techlibs/anlogic/brams_init.mk
|
||||||
|
|
||||||
|
techlibs/anlogic/brams_init.mk: techlibs/anlogic/brams_init.py
|
||||||
|
$(Q) mkdir -p techlibs/anlogic
|
||||||
|
$(P) $(PYTHON_EXECUTABLE) $<
|
||||||
|
$(Q) touch $@
|
||||||
|
|
||||||
|
techlibs/anlogic/brams_init_16.vh: techlibs/anlogic/brams_init.mk
|
||||||
|
techlibs/anlogic/brams_init_9.vh: techlibs/anlogic/brams_init.mk
|
||||||
|
techlibs/anlogic/brams_init_8.vh: techlibs/anlogic/brams_init.mk
|
||||||
|
|
||||||
$(eval $(call add_share_file,share/anlogic,techlibs/anlogic/cells_map.v))
|
$(eval $(call add_share_file,share/anlogic,techlibs/anlogic/cells_map.v))
|
||||||
$(eval $(call add_share_file,share/anlogic,techlibs/anlogic/arith_map.v))
|
$(eval $(call add_share_file,share/anlogic,techlibs/anlogic/arith_map.v))
|
||||||
$(eval $(call add_share_file,share/anlogic,techlibs/anlogic/cells_sim.v))
|
$(eval $(call add_share_file,share/anlogic,techlibs/anlogic/cells_sim.v))
|
||||||
|
@ -10,3 +26,9 @@ $(eval $(call add_share_file,share/anlogic,techlibs/anlogic/eagle_bb.v))
|
||||||
$(eval $(call add_share_file,share/anlogic,techlibs/anlogic/lutrams.txt))
|
$(eval $(call add_share_file,share/anlogic,techlibs/anlogic/lutrams.txt))
|
||||||
$(eval $(call add_share_file,share/anlogic,techlibs/anlogic/lutrams_map.v))
|
$(eval $(call add_share_file,share/anlogic,techlibs/anlogic/lutrams_map.v))
|
||||||
$(eval $(call add_share_file,share/anlogic,techlibs/anlogic/lutram_init_16x4.vh))
|
$(eval $(call add_share_file,share/anlogic,techlibs/anlogic/lutram_init_16x4.vh))
|
||||||
|
$(eval $(call add_share_file,share/anlogic,techlibs/anlogic/brams.txt))
|
||||||
|
$(eval $(call add_share_file,share/anlogic,techlibs/anlogic/brams_map.v))
|
||||||
|
|
||||||
|
$(eval $(call add_gen_share_file,share/anlogic,techlibs/anlogic/brams_init_16.vh))
|
||||||
|
$(eval $(call add_gen_share_file,share/anlogic,techlibs/anlogic/brams_init_9.vh))
|
||||||
|
$(eval $(call add_gen_share_file,share/anlogic,techlibs/anlogic/brams_init_8.vh))
|
||||||
|
|
|
@ -0,0 +1,45 @@
|
||||||
|
bram $__ANLOGIC_BRAM9K_TDP
|
||||||
|
init 1
|
||||||
|
abits 13 @a13d1
|
||||||
|
dbits 1 @a13d1
|
||||||
|
abits 12 @a12d2
|
||||||
|
dbits 2 @a12d2
|
||||||
|
abits 11 @a11d4
|
||||||
|
dbits 4 @a11d4
|
||||||
|
abits 10 @a10d8
|
||||||
|
dbits 8 @a10d8
|
||||||
|
abits 10 @a10d9
|
||||||
|
dbits 9 @a10d9
|
||||||
|
groups 2
|
||||||
|
ports 1 1
|
||||||
|
wrmode 0 1
|
||||||
|
enable 1 1
|
||||||
|
transp 2 0
|
||||||
|
clocks 2 3
|
||||||
|
clkpol 2 3
|
||||||
|
endbram
|
||||||
|
|
||||||
|
bram $__ANLOGIC_BRAM32K
|
||||||
|
init 1
|
||||||
|
abits 11
|
||||||
|
dbits 16
|
||||||
|
groups 2
|
||||||
|
ports 1 1
|
||||||
|
wrmode 0 1
|
||||||
|
enable 1 2
|
||||||
|
transp 0 0
|
||||||
|
clocks 2 3
|
||||||
|
clkpol 2 3
|
||||||
|
endbram
|
||||||
|
|
||||||
|
match $__ANLOGIC_BRAM32K
|
||||||
|
min efficiency 30
|
||||||
|
shuffle_enable B
|
||||||
|
make_transp
|
||||||
|
or_next_if_better
|
||||||
|
endmatch
|
||||||
|
|
||||||
|
match $__ANLOGIC_BRAM9K_TDP
|
||||||
|
min efficiency 5
|
||||||
|
make_transp
|
||||||
|
endmatch
|
|
@ -0,0 +1,21 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
with open("techlibs/anlogic/brams_init_9.vh", "w") as f:
|
||||||
|
for i in range(4):
|
||||||
|
init_snippets = [" INIT[%3d*9+8]" % (k+256*i,) for k in range(255, -1, -1)]
|
||||||
|
for k in range(4, 256, 4):
|
||||||
|
init_snippets[k] = "\n " + init_snippets[k]
|
||||||
|
print(".INITP_%02X({%s})," % (i, ",".join(init_snippets)), file=f)
|
||||||
|
for i in range(32):
|
||||||
|
init_snippets = [" INIT[%3d*9 +: 8]" % (k+32*i,) for k in range(31, -1, -1)]
|
||||||
|
for k in range(4, 32, 4):
|
||||||
|
init_snippets[k] = "\n " + init_snippets[k]
|
||||||
|
print(".INIT_%02X({%s})," % (i, ",".join(init_snippets)), file=f)
|
||||||
|
|
||||||
|
with open("techlibs/anlogic/brams_init_8.vh", "w") as f:
|
||||||
|
for i in range(32):
|
||||||
|
print(".INIT_%02X(INIT[%3d*256 +: 256])," % (i, i), file=f)
|
||||||
|
|
||||||
|
with open("techlibs/anlogic/brams_init_16.vh", "w") as f:
|
||||||
|
for i in range(128):
|
||||||
|
print(".INIT_%02X(INIT[%3d*256 +: 256])," % (i, i), file=f)
|
|
@ -0,0 +1,162 @@
|
||||||
|
module \$__ANLOGIC_BRAM9K_TDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
||||||
|
parameter CFG_ABITS = 10;
|
||||||
|
parameter CFG_DBITS = 9;
|
||||||
|
|
||||||
|
parameter CLKPOL2 = 1;
|
||||||
|
parameter CLKPOL3 = 1;
|
||||||
|
parameter [9215:0] INIT = 9216'bx;
|
||||||
|
parameter TRANSP2 = 0;
|
||||||
|
|
||||||
|
input CLK2;
|
||||||
|
input CLK3;
|
||||||
|
|
||||||
|
input [CFG_ABITS-1:0] A1ADDR;
|
||||||
|
output [CFG_DBITS-1:0] A1DATA;
|
||||||
|
input A1EN;
|
||||||
|
|
||||||
|
input [CFG_ABITS-1:0] B1ADDR;
|
||||||
|
input [CFG_DBITS-1:0] B1DATA;
|
||||||
|
input B1EN;
|
||||||
|
|
||||||
|
localparam CLKAMUX = CLKPOL2 ? "SIG" : "INV";
|
||||||
|
localparam CLKBMUX = CLKPOL3 ? "SIG" : "INV";
|
||||||
|
|
||||||
|
localparam WRITEMODE_B = TRANSP2 ? "WRITETHROUGH" : "READBEFOREWRITE";
|
||||||
|
|
||||||
|
localparam DATA_WIDTH = CFG_DBITS == 1 ? "1" :
|
||||||
|
(CFG_DBITS == 2 ? "2" :
|
||||||
|
(CFG_DBITS <= 4 ? "4" : "9"));
|
||||||
|
|
||||||
|
localparam APADBITS = $clog2(CFG_DBITS == 9 ? 8 : CFG_DBITS);
|
||||||
|
|
||||||
|
wire [12:0] addra;
|
||||||
|
wire [12:0] addrb;
|
||||||
|
|
||||||
|
assign addra[12:APADBITS] = A1ADDR;
|
||||||
|
assign addrb[12:APADBITS] = B1ADDR;
|
||||||
|
|
||||||
|
wire [8:0] doa;
|
||||||
|
wire [8:0] dib;
|
||||||
|
|
||||||
|
assign A1DATA[CFG_DBITS-1:0] = doa;
|
||||||
|
assign dib[CFG_DBITS-1:0] = B1DATA;
|
||||||
|
|
||||||
|
generate if (CFG_DBITS == 9) begin
|
||||||
|
EG_PHY_BRAM #(
|
||||||
|
.MODE("DP8K"),
|
||||||
|
.DATA_WIDTH_A(DATA_WIDTH),
|
||||||
|
.DATA_WIDTH_B(DATA_WIDTH),
|
||||||
|
.READBACK("OFF"),
|
||||||
|
.REGMODE_A("NOREG"),
|
||||||
|
.REGMODE_B("NOREG"),
|
||||||
|
.WRITEMODE_A("READBEFOREWRITE"),
|
||||||
|
.WRITEMODE_B(WRITEMODE_B),
|
||||||
|
.RESETMODE("ASYNC"),
|
||||||
|
.CEAMUX("SIG"), .CEBMUX("SIG"),
|
||||||
|
.OCEAMUX("1"), .OCEBMUX("1"),
|
||||||
|
.RSTAMUX("0"), .RSTBMUX("0"),
|
||||||
|
.CLKAMUX(CLKAMUX),
|
||||||
|
.CLKBMUX(CLKBMUX),
|
||||||
|
.WEAMUX("0"), .WEBMUX("SIG"),
|
||||||
|
.CSA0("1"), .CSA1("1"),
|
||||||
|
.CSA2("1"), .CSB0("1"),
|
||||||
|
.CSB1("1"), .CSB2("1"),
|
||||||
|
`include "brams_init_9.vh"
|
||||||
|
) _TECHMAP_REPLACE_ (
|
||||||
|
.doa(doa), .dib(dib),
|
||||||
|
.addra(addra), .addrb(addrb),
|
||||||
|
.clka(CLK2), .clkb(CLK3),
|
||||||
|
.cea(A1EN), .ceb(B1EN),
|
||||||
|
.ocea(1'b1), .oceb(1'b1),
|
||||||
|
.rsta(1'b0), .rstb(1'b0),
|
||||||
|
.wea(1'b0), .web(B1EN),
|
||||||
|
.csa(3'b111), .csb(3'b111)
|
||||||
|
);
|
||||||
|
end else begin
|
||||||
|
EG_PHY_BRAM #(
|
||||||
|
.MODE("DP8K"),
|
||||||
|
.DATA_WIDTH_A(DATA_WIDTH),
|
||||||
|
.DATA_WIDTH_B(DATA_WIDTH),
|
||||||
|
.READBACK("OFF"),
|
||||||
|
.REGMODE_A("NOREG"),
|
||||||
|
.REGMODE_B("NOREG"),
|
||||||
|
.WRITEMODE_A("READBEFOREWRITE"),
|
||||||
|
.WRITEMODE_B(WRITEMODE_B),
|
||||||
|
.RESETMODE("ASYNC"),
|
||||||
|
.CEAMUX("SIG"), .CEBMUX("SIG"),
|
||||||
|
.OCEAMUX("1"), .OCEBMUX("1"),
|
||||||
|
.RSTAMUX("0"), .RSTBMUX("0"),
|
||||||
|
.CLKAMUX(CLKAMUX),
|
||||||
|
.CLKBMUX(CLKBMUX),
|
||||||
|
.WEAMUX("0"), .WEBMUX("SIG"),
|
||||||
|
.CSA0("1"), .CSA1("1"),
|
||||||
|
.CSA2("1"), .CSB0("1"),
|
||||||
|
.CSB1("1"), .CSB2("1"),
|
||||||
|
`include "brams_init_8.vh"
|
||||||
|
) _TECHMAP_REPLACE_ (
|
||||||
|
.doa(doa), .dib(dib),
|
||||||
|
.addra(addra), .addrb(addrb),
|
||||||
|
.clka(CLK2), .clkb(CLK3),
|
||||||
|
.cea(A1EN), .ceb(B1EN),
|
||||||
|
.ocea(1'b1), .oceb(1'b1),
|
||||||
|
.rsta(1'b0), .rstb(1'b0),
|
||||||
|
.wea(1'b0), .web(B1EN),
|
||||||
|
.csa(3'b111), .csb(3'b111)
|
||||||
|
);
|
||||||
|
end endgenerate
|
||||||
|
endmodule
|
||||||
|
|
||||||
|
module \$__ANLOGIC_BRAM32K (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
||||||
|
parameter CFG_ABITS = 11;
|
||||||
|
parameter CFG_DBITS = 16;
|
||||||
|
|
||||||
|
parameter CLKPOL2 = 1;
|
||||||
|
parameter CLKPOL3 = 1;
|
||||||
|
parameter [32767:0] INIT = 32768'bx;
|
||||||
|
|
||||||
|
input CLK2;
|
||||||
|
input CLK3;
|
||||||
|
|
||||||
|
input [CFG_ABITS-1:0] A1ADDR;
|
||||||
|
output [CFG_DBITS-1:0] A1DATA;
|
||||||
|
input A1EN;
|
||||||
|
|
||||||
|
input [CFG_ABITS-1:0] B1ADDR;
|
||||||
|
input [CFG_DBITS-1:0] B1DATA;
|
||||||
|
input [1:0] B1EN;
|
||||||
|
|
||||||
|
localparam CLKAMUX = CLKPOL2 ? "SIG" : "INV";
|
||||||
|
localparam CLKBMUX = CLKPOL3 ? "SIG" : "INV";
|
||||||
|
|
||||||
|
wire byteweb = B1EN[1] ^ B1EN[0];
|
||||||
|
wire byteb = B1EN[1];
|
||||||
|
|
||||||
|
EG_PHY_BRAM32K #(
|
||||||
|
.MODE("DP16K"),
|
||||||
|
.DATA_WIDTH_A("16"),
|
||||||
|
.DATA_WIDTH_B("16"),
|
||||||
|
.REGMODE_A("NOREG"),
|
||||||
|
.REGMODE_B("NOREG"),
|
||||||
|
.WRITEMODE_A("NORMAL"),
|
||||||
|
.WRITEMODE_B("NORMAL"),
|
||||||
|
.SRMODE("ASYNC"),
|
||||||
|
.CSAMUX("SIG"), .CSBMUX("SIG"),
|
||||||
|
.OCEAMUX("1"), .OCEBMUX("1"),
|
||||||
|
.RSTAMUX("0"), .RSTBMUX("0"),
|
||||||
|
.CLKAMUX(CLKAMUX),
|
||||||
|
.CLKBMUX(CLKBMUX),
|
||||||
|
.WEAMUX("0"), .WEBMUX("SIG"),
|
||||||
|
.READBACK("OFF"),
|
||||||
|
`include "brams_init_16.vh"
|
||||||
|
) _TECHMAP_REPLACE_ (
|
||||||
|
.doa(A1DATA), .dib(B1DATA),
|
||||||
|
.addra(A1ADDR), .addrb(B1ADDR),
|
||||||
|
.bytea(1'b0), .byteb(byteb),
|
||||||
|
.bytewea(1'b0), .byteweb(byteweb),
|
||||||
|
.csa(A1EN), .csb(|B1EN),
|
||||||
|
.wea(1'b0), .web(|B1EN),
|
||||||
|
.clka(CLK2), .clkb(CLK3),
|
||||||
|
.rsta(1'b0), .rstb(1'b0),
|
||||||
|
.ocea(1'b1), .oceb(1'b1)
|
||||||
|
);
|
||||||
|
endmodule
|
|
@ -63,6 +63,9 @@ struct SynthAnlogicPass : public ScriptPass
|
||||||
log(" -nolutram\n");
|
log(" -nolutram\n");
|
||||||
log(" do not use EG_LOGIC_DRAM16X4 cells in output netlist\n");
|
log(" do not use EG_LOGIC_DRAM16X4 cells in output netlist\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
|
log(" -nobram\n");
|
||||||
|
log(" do not use EG_PHY_BRAM or EG_PHY_BRAM32K cells in output netlist\n");
|
||||||
|
log("\n");
|
||||||
log("\n");
|
log("\n");
|
||||||
log("The following commands are executed by this synthesis command:\n");
|
log("The following commands are executed by this synthesis command:\n");
|
||||||
help_script();
|
help_script();
|
||||||
|
@ -70,7 +73,7 @@ struct SynthAnlogicPass : public ScriptPass
|
||||||
}
|
}
|
||||||
|
|
||||||
string top_opt, edif_file, json_file;
|
string top_opt, edif_file, json_file;
|
||||||
bool flatten, retime, nolutram;
|
bool flatten, retime, nolutram, nobram;
|
||||||
|
|
||||||
void clear_flags() override
|
void clear_flags() override
|
||||||
{
|
{
|
||||||
|
@ -80,6 +83,7 @@ struct SynthAnlogicPass : public ScriptPass
|
||||||
flatten = true;
|
flatten = true;
|
||||||
retime = false;
|
retime = false;
|
||||||
nolutram = false;
|
nolutram = false;
|
||||||
|
nobram = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||||
|
@ -118,6 +122,10 @@ struct SynthAnlogicPass : public ScriptPass
|
||||||
nolutram = true;
|
nolutram = true;
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
if (args[argidx] == "-nobram") {
|
||||||
|
nobram = true;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
if (args[argidx] == "-retime") {
|
if (args[argidx] == "-retime") {
|
||||||
retime = true;
|
retime = true;
|
||||||
continue;
|
continue;
|
||||||
|
@ -158,6 +166,14 @@ struct SynthAnlogicPass : public ScriptPass
|
||||||
run("synth -run coarse");
|
run("synth -run coarse");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!nobram && check_label("map_bram", "(skip if -nobram)"))
|
||||||
|
{
|
||||||
|
run("memory_bram -rules +/anlogic/brams.txt");
|
||||||
|
run("techmap -map +/anlogic/brams_map.v");
|
||||||
|
run("setundef -zero -params t:EG_PHY_BRAM");
|
||||||
|
run("setundef -zero -params t:EG_PHY_BRAM32K");
|
||||||
|
}
|
||||||
|
|
||||||
if (!nolutram && check_label("map_lutram", "(skip if -nolutram)"))
|
if (!nolutram && check_label("map_lutram", "(skip if -nolutram)"))
|
||||||
{
|
{
|
||||||
run("memory_bram -rules +/anlogic/lutrams.txt");
|
run("memory_bram -rules +/anlogic/lutrams.txt");
|
||||||
|
|
|
@ -0,0 +1,13 @@
|
||||||
|
read_verilog ../common/blockram.v
|
||||||
|
hierarchy -top sync_ram_sp
|
||||||
|
proc
|
||||||
|
memory -nomap
|
||||||
|
equiv_opt -run :prove -map +/anlogic/cells_sim.v synth_anlogic
|
||||||
|
memory
|
||||||
|
opt -full
|
||||||
|
|
||||||
|
design -load postopt
|
||||||
|
cd sync_ram_sp
|
||||||
|
|
||||||
|
select -assert-count 1 t:EG_PHY_BRAM
|
||||||
|
select -assert-none t:EG_PHY_BRAM %% t:* %D
|
|
@ -2,7 +2,7 @@ read_verilog ../common/lutram.v
|
||||||
hierarchy -top lutram_1w1r
|
hierarchy -top lutram_1w1r
|
||||||
proc
|
proc
|
||||||
memory -nomap
|
memory -nomap
|
||||||
equiv_opt -run :prove -map +/anlogic/cells_sim.v synth_anlogic
|
equiv_opt -run :prove -map +/anlogic/cells_sim.v synth_anlogic -nobram
|
||||||
memory
|
memory
|
||||||
opt -full
|
opt -full
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue