Added ice40 bram support
This commit is contained in:
parent
11f77205f5
commit
d6f7698f59
4 changed files with 192 additions and 1 deletions
|
@ -5,4 +5,6 @@ OBJS += techlibs/ice40/ice40_ffssr.o
|
|||
$(eval $(call add_share_file,share/ice40,techlibs/ice40/arith_map.v))
|
||||
$(eval $(call add_share_file,share/ice40,techlibs/ice40/cells_map.v))
|
||||
$(eval $(call add_share_file,share/ice40,techlibs/ice40/cells_sim.v))
|
||||
$(eval $(call add_share_file,share/ice40,techlibs/ice40/brams.txt))
|
||||
$(eval $(call add_share_file,share/ice40,techlibs/ice40/brams_map.v))
|
||||
|
||||
|
|
40
techlibs/ice40/brams.txt
Normal file
40
techlibs/ice40/brams.txt
Normal file
|
@ -0,0 +1,40 @@
|
|||
bram $__ICE40_RAM4K_M0
|
||||
init 0
|
||||
abits 8
|
||||
dbits 16
|
||||
groups 2
|
||||
ports 1 1
|
||||
wrmode 0 1
|
||||
enable 0 16
|
||||
transp 0 0
|
||||
clocks 2 3
|
||||
clkpol 2 3
|
||||
endbram
|
||||
|
||||
bram $__ICE40_RAM4K_M123
|
||||
init 0
|
||||
abits 9 @M1
|
||||
dbits 8 @M1
|
||||
abits 10 @M2
|
||||
dbits 4 @M2
|
||||
abits 11 @M3
|
||||
dbits 2 @M3
|
||||
groups 2
|
||||
ports 1 1
|
||||
wrmode 0 1
|
||||
enable 0 1
|
||||
transp 0 0
|
||||
clocks 2 3
|
||||
clkpol 2 3
|
||||
endbram
|
||||
|
||||
match $__ICE40_RAM4K_M0
|
||||
min efficiency 10
|
||||
make_transp
|
||||
or_next_if_better
|
||||
endmatch
|
||||
|
||||
match $__ICE40_RAM4K_M123
|
||||
min efficiency 10
|
||||
make_transp
|
||||
endmatch
|
99
techlibs/ice40/brams_map.v
Normal file
99
techlibs/ice40/brams_map.v
Normal file
|
@ -0,0 +1,99 @@
|
|||
|
||||
module \$__ICE40_RAM4K_M0 (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
|
||||
parameter [0:0] CLKPOL2 = 1;
|
||||
parameter [0:0] CLKPOL3 = 1;
|
||||
|
||||
input CLK2;
|
||||
input CLK3;
|
||||
|
||||
input [7:0] A1ADDR;
|
||||
output [15:0] A1DATA;
|
||||
|
||||
input [7:0] B1ADDR;
|
||||
input [15:0] B1DATA;
|
||||
input [15:0] B1EN;
|
||||
|
||||
wire [10:0] A1ADDR_11 = A1ADDR;
|
||||
wire [10:0] B1ADDR_11 = B1ADDR;
|
||||
|
||||
generate
|
||||
case ({CLKPOL2, CLKPOL3})
|
||||
2'b00:
|
||||
SB_RAM40_4KNRNW #(.WRITE_MODE(0), .READ_MODE(0)) _TECHMAP_REPLACE_ (
|
||||
.RDATA(A1DATA), .RADDR(A1ADDR_11), .RCLK(CLK2), .RCLKE(1'b1), .RE(1'b1),
|
||||
.WDATA(B1DATA), .WADDR(B1ADDR_11), .WMASK(B1EN), .WCLK(CLK3), .WCLKE(1'b1), .WE(|B1EN)
|
||||
);
|
||||
2'b01:
|
||||
SB_RAM40_4KNR #(.WRITE_MODE(0), .READ_MODE(0)) _TECHMAP_REPLACE_ (
|
||||
.RDATA(A1DATA), .RADDR(A1ADDR_11), .RCLK(CLK2), .RCLKE(1'b1), .RE(1'b1),
|
||||
.WDATA(B1DATA), .WADDR(B1ADDR_11), .WMASK(B1EN), .WCLK(CLK3), .WCLKE(1'b1), .WE(|B1EN)
|
||||
);
|
||||
2'b10:
|
||||
SB_RAM40_4KNW #(.WRITE_MODE(0), .READ_MODE(0)) _TECHMAP_REPLACE_ (
|
||||
.RDATA(A1DATA), .RADDR(A1ADDR_11), .RCLK(CLK2), .RCLKE(1'b1), .RE(1'b1),
|
||||
.WDATA(B1DATA), .WADDR(B1ADDR_11), .WMASK(B1EN), .WCLK(CLK3), .WCLKE(1'b1), .WE(|B1EN)
|
||||
);
|
||||
2'b11:
|
||||
SB_RAM40_4K #(.WRITE_MODE(0), .READ_MODE(0)) _TECHMAP_REPLACE_ (
|
||||
.RDATA(A1DATA), .RADDR(A1ADDR_11), .RCLK(CLK2), .RCLKE(1'b1), .RE(1'b1),
|
||||
.WDATA(B1DATA), .WADDR(B1ADDR_11), .WMASK(B1EN), .WCLK(CLK3), .WCLKE(1'b1), .WE(|B1EN)
|
||||
);
|
||||
endcase
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
module \$__ICE40_RAM4K_M123 (CLK2, CLK3, A1ADDR, A1DATA, B1ADDR, B1DATA, B1EN);
|
||||
parameter CFG_ABITS = 9;
|
||||
parameter CFG_DBITS = 8;
|
||||
|
||||
parameter [0:0] CLKPOL2 = 1;
|
||||
parameter [0:0] CLKPOL3 = 1;
|
||||
|
||||
localparam MODE =
|
||||
CFG_ABITS == 9 ? 1 :
|
||||
CFG_ABITS == 10 ? 2 :
|
||||
CFG_ABITS == 11 ? 3 : 'bx;
|
||||
|
||||
input CLK2;
|
||||
input CLK3;
|
||||
|
||||
input [CFG_ABITS-1:0] A1ADDR;
|
||||
output [CFG_DBITS-1:0] A1DATA;
|
||||
|
||||
input [CFG_ABITS-1:0] B1ADDR;
|
||||
input [CFG_DBITS-1:0] B1DATA;
|
||||
input B1EN;
|
||||
|
||||
wire [10:0] A1ADDR_11 = A1ADDR;
|
||||
wire [10:0] B1ADDR_11 = B1ADDR;
|
||||
|
||||
wire [15:0] A1DATA_16;
|
||||
wire [15:0] B1DATA_16 = B1DATA;
|
||||
assign A1DATA = A1DATA_16;
|
||||
|
||||
generate
|
||||
case ({CLKPOL2, CLKPOL3})
|
||||
2'b00:
|
||||
SB_RAM40_4KNRNW #(.WRITE_MODE(MODE), .READ_MODE(MODE)) _TECHMAP_REPLACE_ (
|
||||
.RDATA(A1DATA_16), .RADDR(A1ADDR_11), .RCLK(CLK2), .RCLKE(1'b1), .RE(1'b1),
|
||||
.WDATA(B1DATA_16), .WADDR(B1ADDR_11), .WCLK(CLK3), .WCLKE(1'b1), .WE(B1EN)
|
||||
);
|
||||
2'b01:
|
||||
SB_RAM40_4KNR #(.WRITE_MODE(MODE), .READ_MODE(MODE)) _TECHMAP_REPLACE_ (
|
||||
.RDATA(A1DATA_16), .RADDR(A1ADDR_11), .RCLK(CLK2), .RCLKE(1'b1), .RE(1'b1),
|
||||
.WDATA(B1DATA_16), .WADDR(B1ADDR_11), .WCLK(CLK3), .WCLKE(1'b1), .WE(B1EN)
|
||||
);
|
||||
2'b10:
|
||||
SB_RAM40_4RNW #(.WRITE_MODE(MODE), .READ_MODE(MODE)) _TECHMAP_REPLACE_ (
|
||||
.RDATA(A1DATA_16), .RADDR(A1ADDR_11), .RCLK(CLK2), .RCLKE(1'b1), .RE(1'b1),
|
||||
.WDATA(B1DATA_16), .WADDR(B1ADDR_11), .WCLK(CLK3), .WCLKE(1'b1), .WE(B1EN)
|
||||
);
|
||||
2'b11:
|
||||
SB_RAM40_4K #(.WRITE_MODE(MODE), .READ_MODE(MODE)) _TECHMAP_REPLACE_ (
|
||||
.RDATA(A1DATA_16), .RADDR(A1ADDR_11), .RCLK(CLK2), .RCLKE(1'b1), .RE(1'b1),
|
||||
.WDATA(B1DATA_16), .WADDR(B1ADDR_11), .WCLK(CLK3), .WCLKE(1'b1), .WE(B1EN)
|
||||
);
|
||||
endcase
|
||||
endgenerate
|
||||
endmodule
|
||||
|
|
@ -52,6 +52,18 @@ struct SynthIce40Pass : public Pass {
|
|||
log(" from label is synonymous to 'begin', and empty to label is\n");
|
||||
log(" synonymous to the end of the command list.\n");
|
||||
log("\n");
|
||||
log(" -flatten\n");
|
||||
log(" flatten design before synthesis\n");
|
||||
log("\n");
|
||||
log(" -retime\n");
|
||||
log(" run 'abc' with -dff option\n");
|
||||
log("\n");
|
||||
log(" -nocarry\n");
|
||||
log(" do not use SB_CARRY cells in output netlist\n");
|
||||
log("\n");
|
||||
log(" -nobram\n");
|
||||
log(" do not use SB_RAM40_4K* cells in output netlist\n");
|
||||
log("\n");
|
||||
log("\n");
|
||||
log("The following commands are executed by this synthesis command:\n");
|
||||
log("\n");
|
||||
|
@ -59,14 +71,23 @@ struct SynthIce40Pass : public Pass {
|
|||
log(" read_verilog -lib +/ice40/cells_sim.v\n");
|
||||
log(" hierarchy -check -top <top>\n");
|
||||
log("\n");
|
||||
log(" flatten: (only if -flatten)\n");
|
||||
log(" proc\n");
|
||||
log(" flatten\n");
|
||||
log("\n");
|
||||
log(" coarse:\n");
|
||||
log(" synth -run coarse\n");
|
||||
log("\n");
|
||||
log(" bram: (skip if -nobram)\n");
|
||||
log(" memory_bram -rules +/ice40/brams.txt\n");
|
||||
log(" techmap -map +/ice40/brams_map.v\n");
|
||||
log("\n");
|
||||
log(" fine:\n");
|
||||
log(" opt -fast -mux_undef -undriven -fine\n");
|
||||
log(" memory_map\n");
|
||||
log(" opt -undriven -fine\n");
|
||||
log(" techmap -map +/techmap.v -map +/ice40/arith_map.v\n");
|
||||
log(" techmap -map +/techmap.v [-map +/ice40/arith_map.v]\n");
|
||||
log(" abc -dff (only if -retime)\n");
|
||||
log(" opt -fast\n");
|
||||
log("\n");
|
||||
log(" map_ffs:\n");
|
||||
|
@ -96,6 +117,9 @@ struct SynthIce40Pass : public Pass {
|
|||
std::string top_opt = "-auto-top";
|
||||
std::string run_from, run_to;
|
||||
bool nocarry = false;
|
||||
bool nobram = false;
|
||||
bool flatten = false;
|
||||
bool retime = false;
|
||||
|
||||
size_t argidx;
|
||||
for (argidx = 1; argidx < args.size(); argidx++)
|
||||
|
@ -112,10 +136,22 @@ struct SynthIce40Pass : public Pass {
|
|||
run_to = args[argidx].substr(pos+1);
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-flatten") {
|
||||
flatten = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-retime") {
|
||||
retime = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-nocarry") {
|
||||
nocarry = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-nobram") {
|
||||
nobram = true;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
extra_args(args, argidx, design);
|
||||
|
@ -134,11 +170,23 @@ struct SynthIce40Pass : public Pass {
|
|||
Pass::call(design, stringf("hierarchy -check %s", top_opt.c_str()));
|
||||
}
|
||||
|
||||
if (flatten && check_label(active, run_from, run_to, "flatten"))
|
||||
{
|
||||
Pass::call(design, "proc");
|
||||
Pass::call(design, "flatten");
|
||||
}
|
||||
|
||||
if (check_label(active, run_from, run_to, "coarse"))
|
||||
{
|
||||
Pass::call(design, "synth -run coarse");
|
||||
}
|
||||
|
||||
if (!nobram && check_label(active, run_from, run_to, "bram"))
|
||||
{
|
||||
Pass::call(design, "memory_bram -rules +/ice40/brams.txt");
|
||||
Pass::call(design, "techmap -map +/ice40/brams_map.v");
|
||||
}
|
||||
|
||||
if (check_label(active, run_from, run_to, "fine"))
|
||||
{
|
||||
Pass::call(design, "opt -fast -mux_undef -undriven -fine");
|
||||
|
@ -148,6 +196,8 @@ struct SynthIce40Pass : public Pass {
|
|||
Pass::call(design, "techmap");
|
||||
else
|
||||
Pass::call(design, "techmap -map +/techmap.v -map +/ice40/arith_map.v");
|
||||
if (retime)
|
||||
Pass::call(design, "abc -dff");
|
||||
Pass::call(design, "opt -fast");
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue