mirror of
https://github.com/YosysHQ/yosys
synced 2025-07-28 23:17:57 +00:00
synth_nexus to synth_lattice
This commit is contained in:
parent
567e803f14
commit
247613e649
21 changed files with 160 additions and 476 deletions
|
@ -4,28 +4,40 @@ OBJS += techlibs/lattice/lattice_gsr.o
|
|||
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_ff.vh))
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_io.vh))
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_map.v))
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_map_trellis.v))
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_map_nexus.v))
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/common_sim.vh))
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/parse_init.vh))
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/ccu2d_sim.vh))
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/ccu2c_sim.vh))
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_sim_ecp5.v))
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_sim_xo2.v))
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_sim_xo3.v))
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_sim_xo3d.v))
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_sim_nexus.v))
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_bb_ecp5.v))
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_bb_xo2.v))
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_bb_xo3.v))
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_bb_xo3d.v))
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/lutrams_map.v))
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/lutrams.txt))
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/cells_bb_nexus.v))
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/lutrams_map_trellis.v))
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/lutrams_trellis.txt))
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/lutrams_map_nexus.v))
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/lutrams_nexus.txt))
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/lrams_map_nexus.v))
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/lrams_nexus.txt))
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/brams_map_16kd.v))
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/brams_16kd.txt))
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/brams_map_8kc.v))
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/brams_8kc.txt))
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/brams_map_nexus.v))
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/brams_nexus.txt))
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/arith_map_ccu2c.v))
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/arith_map_ccu2d.v))
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/arith_map_nexus.v))
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/latches_map.v))
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/dsp_map_18x18.v))
|
||||
$(eval $(call add_share_file,share/lattice,techlibs/lattice/dsp_map_nexus.v))
|
||||
|
||||
|
||||
$(eval $(call add_share_file,share/ecp5,techlibs/lattice/cells_ff.vh))
|
||||
|
@ -34,3 +46,7 @@ $(eval $(call add_share_file,share/ecp5,techlibs/lattice/common_sim.vh))
|
|||
$(eval $(call add_share_file,share/ecp5,techlibs/lattice/ccu2c_sim.vh))
|
||||
$(eval $(call add_share_file_and_rename,share/ecp5,techlibs/lattice/cells_sim_ecp5.v,cells_sim.v))
|
||||
$(eval $(call add_share_file_and_rename,share/ecp5,techlibs/lattice/cells_bb_ecp5.v,cells_bb.v))
|
||||
|
||||
$(eval $(call add_share_file,share/nexus,techlibs/lattice/parse_init.vh))
|
||||
$(eval $(call add_share_file_and_rename,share/nexus,techlibs/lattice/cells_sim_nexus.v,cells_sim.v))
|
||||
$(eval $(call add_share_file_and_rename,share/nexus,techlibs/lattice/cells_bb_nexus.v,cells_xtra.v))
|
||||
|
|
99
techlibs/lattice/arith_map_nexus.v
Normal file
99
techlibs/lattice/arith_map_nexus.v
Normal file
|
@ -0,0 +1,99 @@
|
|||
/*
|
||||
* yosys -- Yosys Open SYnthesis Suite
|
||||
*
|
||||
* Copyright (C) 2012 Claire Xenia Wolf <claire@yosyshq.com>
|
||||
* Copyright (C) 2018 gatecat <gatecat@ds0.me>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
(* techmap_celltype = "$alu" *)
|
||||
module _80_nexus_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 <= 4;
|
||||
|
||||
(* 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));
|
||||
|
||||
function integer round_up2;
|
||||
input integer N;
|
||||
begin
|
||||
round_up2 = ((N + 1) / 2) * 2;
|
||||
end
|
||||
endfunction
|
||||
|
||||
localparam Y_WIDTH2 = round_up2(Y_WIDTH);
|
||||
|
||||
(* force_downto *)
|
||||
wire [Y_WIDTH2-1:0] AA = A_buf;
|
||||
(* force_downto *)
|
||||
wire [Y_WIDTH2-1:0] BB = BI ? ~B_buf : B_buf;
|
||||
(* force_downto *)
|
||||
wire [Y_WIDTH2-1:0] BX = B_buf;
|
||||
(* force_downto *)
|
||||
wire [Y_WIDTH2+1:0] FCO, Y1;
|
||||
|
||||
genvar i;
|
||||
|
||||
// Carry feed-in
|
||||
CCU2 #(
|
||||
.INIT0("0xFFFF"),
|
||||
.INIT1("0x00AA"),
|
||||
.INJECT("NO")
|
||||
) ccu2c_i (
|
||||
.A0(1'b1), .B0(1'b1), .C0(1'b1), .D0(1'b1),
|
||||
.A1(CI), .B1(1'b1), .C1(1'b1), .D1(1'b1),
|
||||
.COUT(FCO[0])
|
||||
);
|
||||
|
||||
generate for (i = 0; i < Y_WIDTH2; i = i + 2) begin:slice
|
||||
CCU2 #(
|
||||
.INIT0("0x96AA"),
|
||||
.INIT1("0x96AA"),
|
||||
.INJECT("NO")
|
||||
) ccu2c_i (
|
||||
.CIN(FCO[i]),
|
||||
.A0(AA[i]), .B0(BX[i]), .C0(BI), .D0(1'b1),
|
||||
.A1(AA[i+1]), .B1(BX[i+1]), .C1(BI), .D1(1'b1),
|
||||
.S0(Y[i]), .S1(Y1[i]),
|
||||
.COUT(FCO[i+2])
|
||||
);
|
||||
|
||||
assign CO[i] = (AA[i] && BB[i]) || ((Y[i] ^ AA[i] ^ BB[i]) && (AA[i] || BB[i]));
|
||||
if (i+1 < Y_WIDTH) begin
|
||||
assign CO[i + 1] = (AA[i + 1] && BB[i + 1]) || ((Y[i + 1] ^ AA[i + 1] ^ BB[i + 1]) && (AA[i + 1] || BB[i + 1]));
|
||||
assign Y[i+1] = Y1[i];
|
||||
end
|
||||
end endgenerate
|
||||
|
||||
assign X = AA ^ BB;
|
||||
endmodule
|
420
techlibs/lattice/brams_map_nexus.v
Normal file
420
techlibs/lattice/brams_map_nexus.v
Normal file
|
@ -0,0 +1,420 @@
|
|||
module $__NX_DP16K_ (...);
|
||||
|
||||
parameter INIT = 0;
|
||||
|
||||
parameter PORT_A_OPTION_RESETMODE = "SYNC";
|
||||
parameter PORT_A_WIDTH = 18;
|
||||
parameter PORT_A_WR_BE_WIDTH = 2;
|
||||
|
||||
input PORT_A_CLK;
|
||||
input PORT_A_CLK_EN;
|
||||
input PORT_A_WR_EN;
|
||||
input PORT_A_RD_SRST;
|
||||
input PORT_A_RD_ARST;
|
||||
input [13:0] PORT_A_ADDR;
|
||||
input [PORT_A_WR_BE_WIDTH-1:0] PORT_A_WR_BE;
|
||||
input [PORT_A_WIDTH-1:0] PORT_A_WR_DATA;
|
||||
output [PORT_A_WIDTH-1:0] PORT_A_RD_DATA;
|
||||
|
||||
parameter PORT_B_OPTION_RESETMODE = "SYNC";
|
||||
parameter PORT_B_WIDTH = 18;
|
||||
parameter PORT_B_WR_BE_WIDTH = 2;
|
||||
|
||||
input PORT_B_CLK;
|
||||
input PORT_B_CLK_EN;
|
||||
input PORT_B_WR_EN;
|
||||
input PORT_B_RD_SRST;
|
||||
input PORT_B_RD_ARST;
|
||||
input [13:0] PORT_B_ADDR;
|
||||
input [PORT_B_WR_BE_WIDTH-1:0] PORT_B_WR_BE;
|
||||
input [PORT_B_WIDTH-1:0] PORT_B_WR_DATA;
|
||||
output [PORT_B_WIDTH-1:0] PORT_B_RD_DATA;
|
||||
|
||||
function [319:0] init_slice;
|
||||
input integer idx;
|
||||
integer i;
|
||||
init_slice = 0;
|
||||
for (i = 0; i < 32; i = i + 1) begin
|
||||
init_slice[i*10+:9] = INIT[(idx * 32 + i) * 9+:9];
|
||||
end
|
||||
endfunction
|
||||
|
||||
wire [17:0] DOA;
|
||||
wire [17:0] DOB;
|
||||
wire [17:0] DIA = PORT_A_WR_DATA;
|
||||
wire [17:0] DIB = PORT_B_WR_DATA;
|
||||
wire [13:0] ADA;
|
||||
wire [13:0] ADB;
|
||||
|
||||
generate
|
||||
|
||||
case(PORT_A_WIDTH)
|
||||
1: assign ADA = PORT_A_ADDR;
|
||||
2: assign ADA = {PORT_A_ADDR[13:1], 1'b1};
|
||||
4: assign ADA = {PORT_A_ADDR[13:2], 2'b11};
|
||||
9: assign ADA = {PORT_A_ADDR[13:3], 3'b111};
|
||||
18: assign ADA = {PORT_A_ADDR[13:4], 2'b11, PORT_A_WR_BE};
|
||||
endcase
|
||||
|
||||
case(PORT_B_WIDTH)
|
||||
1: assign ADB = PORT_B_ADDR;
|
||||
2: assign ADB = {PORT_B_ADDR[13:1], 1'b1};
|
||||
4: assign ADB = {PORT_B_ADDR[13:2], 2'b11};
|
||||
9: assign ADB = {PORT_B_ADDR[13:3], 3'b111};
|
||||
18: assign ADB = {PORT_B_ADDR[13:4], 2'b11, PORT_B_WR_BE};
|
||||
endcase
|
||||
|
||||
endgenerate
|
||||
|
||||
assign PORT_A_RD_DATA = DOA;
|
||||
assign PORT_B_RD_DATA = DOB;
|
||||
|
||||
DP16K #(
|
||||
.INITVAL_00($sformatf("0x%080x", init_slice('h00))),
|
||||
.INITVAL_01($sformatf("0x%080x", init_slice('h01))),
|
||||
.INITVAL_02($sformatf("0x%080x", init_slice('h02))),
|
||||
.INITVAL_03($sformatf("0x%080x", init_slice('h03))),
|
||||
.INITVAL_04($sformatf("0x%080x", init_slice('h04))),
|
||||
.INITVAL_05($sformatf("0x%080x", init_slice('h05))),
|
||||
.INITVAL_06($sformatf("0x%080x", init_slice('h06))),
|
||||
.INITVAL_07($sformatf("0x%080x", init_slice('h07))),
|
||||
.INITVAL_08($sformatf("0x%080x", init_slice('h08))),
|
||||
.INITVAL_09($sformatf("0x%080x", init_slice('h09))),
|
||||
.INITVAL_0A($sformatf("0x%080x", init_slice('h0a))),
|
||||
.INITVAL_0B($sformatf("0x%080x", init_slice('h0b))),
|
||||
.INITVAL_0C($sformatf("0x%080x", init_slice('h0c))),
|
||||
.INITVAL_0D($sformatf("0x%080x", init_slice('h0d))),
|
||||
.INITVAL_0E($sformatf("0x%080x", init_slice('h0e))),
|
||||
.INITVAL_0F($sformatf("0x%080x", init_slice('h0f))),
|
||||
.INITVAL_10($sformatf("0x%080x", init_slice('h10))),
|
||||
.INITVAL_11($sformatf("0x%080x", init_slice('h11))),
|
||||
.INITVAL_12($sformatf("0x%080x", init_slice('h12))),
|
||||
.INITVAL_13($sformatf("0x%080x", init_slice('h13))),
|
||||
.INITVAL_14($sformatf("0x%080x", init_slice('h14))),
|
||||
.INITVAL_15($sformatf("0x%080x", init_slice('h15))),
|
||||
.INITVAL_16($sformatf("0x%080x", init_slice('h16))),
|
||||
.INITVAL_17($sformatf("0x%080x", init_slice('h17))),
|
||||
.INITVAL_18($sformatf("0x%080x", init_slice('h18))),
|
||||
.INITVAL_19($sformatf("0x%080x", init_slice('h19))),
|
||||
.INITVAL_1A($sformatf("0x%080x", init_slice('h1a))),
|
||||
.INITVAL_1B($sformatf("0x%080x", init_slice('h1b))),
|
||||
.INITVAL_1C($sformatf("0x%080x", init_slice('h1c))),
|
||||
.INITVAL_1D($sformatf("0x%080x", init_slice('h1d))),
|
||||
.INITVAL_1E($sformatf("0x%080x", init_slice('h1e))),
|
||||
.INITVAL_1F($sformatf("0x%080x", init_slice('h1f))),
|
||||
.INITVAL_20($sformatf("0x%080x", init_slice('h20))),
|
||||
.INITVAL_21($sformatf("0x%080x", init_slice('h21))),
|
||||
.INITVAL_22($sformatf("0x%080x", init_slice('h22))),
|
||||
.INITVAL_23($sformatf("0x%080x", init_slice('h23))),
|
||||
.INITVAL_24($sformatf("0x%080x", init_slice('h24))),
|
||||
.INITVAL_25($sformatf("0x%080x", init_slice('h25))),
|
||||
.INITVAL_26($sformatf("0x%080x", init_slice('h26))),
|
||||
.INITVAL_27($sformatf("0x%080x", init_slice('h27))),
|
||||
.INITVAL_28($sformatf("0x%080x", init_slice('h28))),
|
||||
.INITVAL_29($sformatf("0x%080x", init_slice('h29))),
|
||||
.INITVAL_2A($sformatf("0x%080x", init_slice('h2a))),
|
||||
.INITVAL_2B($sformatf("0x%080x", init_slice('h2b))),
|
||||
.INITVAL_2C($sformatf("0x%080x", init_slice('h2c))),
|
||||
.INITVAL_2D($sformatf("0x%080x", init_slice('h2d))),
|
||||
.INITVAL_2E($sformatf("0x%080x", init_slice('h2e))),
|
||||
.INITVAL_2F($sformatf("0x%080x", init_slice('h2f))),
|
||||
.INITVAL_30($sformatf("0x%080x", init_slice('h30))),
|
||||
.INITVAL_31($sformatf("0x%080x", init_slice('h31))),
|
||||
.INITVAL_32($sformatf("0x%080x", init_slice('h32))),
|
||||
.INITVAL_33($sformatf("0x%080x", init_slice('h33))),
|
||||
.INITVAL_34($sformatf("0x%080x", init_slice('h34))),
|
||||
.INITVAL_35($sformatf("0x%080x", init_slice('h35))),
|
||||
.INITVAL_36($sformatf("0x%080x", init_slice('h36))),
|
||||
.INITVAL_37($sformatf("0x%080x", init_slice('h37))),
|
||||
.INITVAL_38($sformatf("0x%080x", init_slice('h38))),
|
||||
.INITVAL_39($sformatf("0x%080x", init_slice('h39))),
|
||||
.INITVAL_3A($sformatf("0x%080x", init_slice('h3a))),
|
||||
.INITVAL_3B($sformatf("0x%080x", init_slice('h3b))),
|
||||
.INITVAL_3C($sformatf("0x%080x", init_slice('h3c))),
|
||||
.INITVAL_3D($sformatf("0x%080x", init_slice('h3d))),
|
||||
.INITVAL_3E($sformatf("0x%080x", init_slice('h3e))),
|
||||
.INITVAL_3F($sformatf("0x%080x", init_slice('h3f))),
|
||||
.DATA_WIDTH_A($sformatf("X%d", PORT_A_WIDTH)),
|
||||
.DATA_WIDTH_B($sformatf("X%d", PORT_B_WIDTH)),
|
||||
.OUTREG_A("BYPASSED"),
|
||||
.OUTREG_B("BYPASSED"),
|
||||
.RESETMODE_A(PORT_A_OPTION_RESETMODE),
|
||||
.RESETMODE_B(PORT_B_OPTION_RESETMODE),
|
||||
.ASYNC_RST_RELEASE_A(PORT_A_OPTION_RESETMODE),
|
||||
.ASYNC_RST_RELEASE_B(PORT_B_OPTION_RESETMODE),
|
||||
.CSDECODE_A("111"),
|
||||
.CSDECODE_B("111"),
|
||||
.GSR("DISABLED"),
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.CLKA(PORT_A_CLK),
|
||||
.WEA(PORT_A_WIDTH == 18 ? PORT_A_WR_EN : (PORT_A_WR_EN | PORT_A_WR_BE[0])),
|
||||
.CEA(PORT_A_CLK_EN),
|
||||
.RSTA(PORT_A_OPTION_RESETMODE == "SYNC" ? PORT_A_RD_SRST : PORT_A_RD_ARST),
|
||||
.CSA(3'b111),
|
||||
.DIA(DIA),
|
||||
.DOA(DOA),
|
||||
.ADA(ADA),
|
||||
|
||||
.CLKB(PORT_B_CLK),
|
||||
.WEB(PORT_B_WIDTH == 18 ? PORT_B_WR_EN : (PORT_B_WR_EN | PORT_B_WR_BE[0])),
|
||||
.CEB(PORT_B_CLK_EN),
|
||||
.RSTB(PORT_B_OPTION_RESETMODE == "SYNC" ? PORT_B_RD_SRST : PORT_B_RD_ARST),
|
||||
.CSB(3'b111),
|
||||
.ADB(ADB),
|
||||
.DIB(DIB),
|
||||
.DOB(DOB),
|
||||
);
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
module $__NX_PDP16K_ (...);
|
||||
|
||||
parameter INIT = 0;
|
||||
parameter OPTION_SAME_CLOCK = 1;
|
||||
|
||||
parameter PORT_R_WIDTH = 36;
|
||||
parameter PORT_R_OPTION_RESETMODE = "SYNC";
|
||||
|
||||
input CLK_C;
|
||||
|
||||
input PORT_R_CLK;
|
||||
input PORT_R_CLK_EN;
|
||||
input PORT_R_RD_SRST;
|
||||
input PORT_R_RD_ARST;
|
||||
input [13:0] PORT_R_ADDR;
|
||||
output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA;
|
||||
|
||||
parameter PORT_W_WIDTH = 36;
|
||||
parameter PORT_W_WR_EN_WIDTH = 4;
|
||||
|
||||
input PORT_W_CLK;
|
||||
input PORT_W_CLK_EN;
|
||||
input [13:0] PORT_W_ADDR;
|
||||
input [PORT_W_WR_EN_WIDTH-1:0] PORT_W_WR_EN;
|
||||
input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA;
|
||||
|
||||
function [319:0] init_slice;
|
||||
input integer idx;
|
||||
integer i;
|
||||
init_slice = 0;
|
||||
for (i = 0; i < 32; i = i + 1) begin
|
||||
init_slice[i*10+:9] = INIT[(idx * 32 + i) * 9+:9];
|
||||
end
|
||||
endfunction
|
||||
|
||||
wire [35:0] DI = PORT_W_WR_DATA;
|
||||
wire [35:0] DO;
|
||||
|
||||
assign PORT_R_RD_DATA = DO;
|
||||
|
||||
wire [13:0] ADW;
|
||||
wire [13:0] ADR;
|
||||
|
||||
generate
|
||||
|
||||
case (PORT_W_WIDTH)
|
||||
1: assign ADW = PORT_W_ADDR;
|
||||
2: assign ADW = {PORT_W_ADDR[13:1], 1'b1};
|
||||
4: assign ADW = {PORT_W_ADDR[13:2], 2'b11};
|
||||
9: assign ADW = {PORT_W_ADDR[13:3], 3'b111};
|
||||
18: assign ADW = {PORT_W_ADDR[13:4], 2'b11, PORT_W_WR_EN};
|
||||
36: assign ADW = {PORT_W_ADDR[13:5], 1'b1, PORT_W_WR_EN};
|
||||
endcase
|
||||
|
||||
case (PORT_R_WIDTH)
|
||||
1: assign ADR = PORT_R_ADDR;
|
||||
2: assign ADR = {PORT_R_ADDR[13:1], 1'b1};
|
||||
4: assign ADR = {PORT_R_ADDR[13:2], 2'b11};
|
||||
9: assign ADR = {PORT_R_ADDR[13:3], 3'b111};
|
||||
18: assign ADR = {PORT_R_ADDR[13:4], 4'b1111};
|
||||
36: assign ADR = {PORT_R_ADDR[13:5], 5'b11111};
|
||||
endcase
|
||||
|
||||
if (OPTION_SAME_CLOCK) begin
|
||||
|
||||
PDPSC16K #(
|
||||
.INITVAL_00($sformatf("0x%080x", init_slice('h00))),
|
||||
.INITVAL_01($sformatf("0x%080x", init_slice('h01))),
|
||||
.INITVAL_02($sformatf("0x%080x", init_slice('h02))),
|
||||
.INITVAL_03($sformatf("0x%080x", init_slice('h03))),
|
||||
.INITVAL_04($sformatf("0x%080x", init_slice('h04))),
|
||||
.INITVAL_05($sformatf("0x%080x", init_slice('h05))),
|
||||
.INITVAL_06($sformatf("0x%080x", init_slice('h06))),
|
||||
.INITVAL_07($sformatf("0x%080x", init_slice('h07))),
|
||||
.INITVAL_08($sformatf("0x%080x", init_slice('h08))),
|
||||
.INITVAL_09($sformatf("0x%080x", init_slice('h09))),
|
||||
.INITVAL_0A($sformatf("0x%080x", init_slice('h0a))),
|
||||
.INITVAL_0B($sformatf("0x%080x", init_slice('h0b))),
|
||||
.INITVAL_0C($sformatf("0x%080x", init_slice('h0c))),
|
||||
.INITVAL_0D($sformatf("0x%080x", init_slice('h0d))),
|
||||
.INITVAL_0E($sformatf("0x%080x", init_slice('h0e))),
|
||||
.INITVAL_0F($sformatf("0x%080x", init_slice('h0f))),
|
||||
.INITVAL_10($sformatf("0x%080x", init_slice('h10))),
|
||||
.INITVAL_11($sformatf("0x%080x", init_slice('h11))),
|
||||
.INITVAL_12($sformatf("0x%080x", init_slice('h12))),
|
||||
.INITVAL_13($sformatf("0x%080x", init_slice('h13))),
|
||||
.INITVAL_14($sformatf("0x%080x", init_slice('h14))),
|
||||
.INITVAL_15($sformatf("0x%080x", init_slice('h15))),
|
||||
.INITVAL_16($sformatf("0x%080x", init_slice('h16))),
|
||||
.INITVAL_17($sformatf("0x%080x", init_slice('h17))),
|
||||
.INITVAL_18($sformatf("0x%080x", init_slice('h18))),
|
||||
.INITVAL_19($sformatf("0x%080x", init_slice('h19))),
|
||||
.INITVAL_1A($sformatf("0x%080x", init_slice('h1a))),
|
||||
.INITVAL_1B($sformatf("0x%080x", init_slice('h1b))),
|
||||
.INITVAL_1C($sformatf("0x%080x", init_slice('h1c))),
|
||||
.INITVAL_1D($sformatf("0x%080x", init_slice('h1d))),
|
||||
.INITVAL_1E($sformatf("0x%080x", init_slice('h1e))),
|
||||
.INITVAL_1F($sformatf("0x%080x", init_slice('h1f))),
|
||||
.INITVAL_20($sformatf("0x%080x", init_slice('h20))),
|
||||
.INITVAL_21($sformatf("0x%080x", init_slice('h21))),
|
||||
.INITVAL_22($sformatf("0x%080x", init_slice('h22))),
|
||||
.INITVAL_23($sformatf("0x%080x", init_slice('h23))),
|
||||
.INITVAL_24($sformatf("0x%080x", init_slice('h24))),
|
||||
.INITVAL_25($sformatf("0x%080x", init_slice('h25))),
|
||||
.INITVAL_26($sformatf("0x%080x", init_slice('h26))),
|
||||
.INITVAL_27($sformatf("0x%080x", init_slice('h27))),
|
||||
.INITVAL_28($sformatf("0x%080x", init_slice('h28))),
|
||||
.INITVAL_29($sformatf("0x%080x", init_slice('h29))),
|
||||
.INITVAL_2A($sformatf("0x%080x", init_slice('h2a))),
|
||||
.INITVAL_2B($sformatf("0x%080x", init_slice('h2b))),
|
||||
.INITVAL_2C($sformatf("0x%080x", init_slice('h2c))),
|
||||
.INITVAL_2D($sformatf("0x%080x", init_slice('h2d))),
|
||||
.INITVAL_2E($sformatf("0x%080x", init_slice('h2e))),
|
||||
.INITVAL_2F($sformatf("0x%080x", init_slice('h2f))),
|
||||
.INITVAL_30($sformatf("0x%080x", init_slice('h30))),
|
||||
.INITVAL_31($sformatf("0x%080x", init_slice('h31))),
|
||||
.INITVAL_32($sformatf("0x%080x", init_slice('h32))),
|
||||
.INITVAL_33($sformatf("0x%080x", init_slice('h33))),
|
||||
.INITVAL_34($sformatf("0x%080x", init_slice('h34))),
|
||||
.INITVAL_35($sformatf("0x%080x", init_slice('h35))),
|
||||
.INITVAL_36($sformatf("0x%080x", init_slice('h36))),
|
||||
.INITVAL_37($sformatf("0x%080x", init_slice('h37))),
|
||||
.INITVAL_38($sformatf("0x%080x", init_slice('h38))),
|
||||
.INITVAL_39($sformatf("0x%080x", init_slice('h39))),
|
||||
.INITVAL_3A($sformatf("0x%080x", init_slice('h3a))),
|
||||
.INITVAL_3B($sformatf("0x%080x", init_slice('h3b))),
|
||||
.INITVAL_3C($sformatf("0x%080x", init_slice('h3c))),
|
||||
.INITVAL_3D($sformatf("0x%080x", init_slice('h3d))),
|
||||
.INITVAL_3E($sformatf("0x%080x", init_slice('h3e))),
|
||||
.INITVAL_3F($sformatf("0x%080x", init_slice('h3f))),
|
||||
.DATA_WIDTH_W($sformatf("X%d", PORT_W_WIDTH)),
|
||||
.DATA_WIDTH_R($sformatf("X%d", PORT_R_WIDTH)),
|
||||
.OUTREG("BYPASSED"),
|
||||
.RESETMODE(PORT_R_OPTION_RESETMODE),
|
||||
.ASYNC_RST_RELEASE(PORT_R_OPTION_RESETMODE),
|
||||
.CSDECODE_W("111"),
|
||||
.CSDECODE_R("111"),
|
||||
.ECC("DISABLED"),
|
||||
.GSR("DISABLED"),
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.CLK(CLK_C),
|
||||
|
||||
.CEW(PORT_W_CLK_EN & (|PORT_W_WR_EN)),
|
||||
.CSW(3'b111),
|
||||
.ADW(ADW),
|
||||
.DI(DI),
|
||||
|
||||
.CER(PORT_R_CLK_EN),
|
||||
.RST(PORT_R_OPTION_RESETMODE == "SYNC" ? PORT_R_RD_SRST : PORT_R_RD_ARST),
|
||||
.CSR(3'b111),
|
||||
.ADR(ADR),
|
||||
.DO(DO),
|
||||
);
|
||||
|
||||
end else begin
|
||||
|
||||
PDP16K #(
|
||||
.INITVAL_00($sformatf("0x%080x", init_slice('h00))),
|
||||
.INITVAL_01($sformatf("0x%080x", init_slice('h01))),
|
||||
.INITVAL_02($sformatf("0x%080x", init_slice('h02))),
|
||||
.INITVAL_03($sformatf("0x%080x", init_slice('h03))),
|
||||
.INITVAL_04($sformatf("0x%080x", init_slice('h04))),
|
||||
.INITVAL_05($sformatf("0x%080x", init_slice('h05))),
|
||||
.INITVAL_06($sformatf("0x%080x", init_slice('h06))),
|
||||
.INITVAL_07($sformatf("0x%080x", init_slice('h07))),
|
||||
.INITVAL_08($sformatf("0x%080x", init_slice('h08))),
|
||||
.INITVAL_09($sformatf("0x%080x", init_slice('h09))),
|
||||
.INITVAL_0A($sformatf("0x%080x", init_slice('h0a))),
|
||||
.INITVAL_0B($sformatf("0x%080x", init_slice('h0b))),
|
||||
.INITVAL_0C($sformatf("0x%080x", init_slice('h0c))),
|
||||
.INITVAL_0D($sformatf("0x%080x", init_slice('h0d))),
|
||||
.INITVAL_0E($sformatf("0x%080x", init_slice('h0e))),
|
||||
.INITVAL_0F($sformatf("0x%080x", init_slice('h0f))),
|
||||
.INITVAL_10($sformatf("0x%080x", init_slice('h10))),
|
||||
.INITVAL_11($sformatf("0x%080x", init_slice('h11))),
|
||||
.INITVAL_12($sformatf("0x%080x", init_slice('h12))),
|
||||
.INITVAL_13($sformatf("0x%080x", init_slice('h13))),
|
||||
.INITVAL_14($sformatf("0x%080x", init_slice('h14))),
|
||||
.INITVAL_15($sformatf("0x%080x", init_slice('h15))),
|
||||
.INITVAL_16($sformatf("0x%080x", init_slice('h16))),
|
||||
.INITVAL_17($sformatf("0x%080x", init_slice('h17))),
|
||||
.INITVAL_18($sformatf("0x%080x", init_slice('h18))),
|
||||
.INITVAL_19($sformatf("0x%080x", init_slice('h19))),
|
||||
.INITVAL_1A($sformatf("0x%080x", init_slice('h1a))),
|
||||
.INITVAL_1B($sformatf("0x%080x", init_slice('h1b))),
|
||||
.INITVAL_1C($sformatf("0x%080x", init_slice('h1c))),
|
||||
.INITVAL_1D($sformatf("0x%080x", init_slice('h1d))),
|
||||
.INITVAL_1E($sformatf("0x%080x", init_slice('h1e))),
|
||||
.INITVAL_1F($sformatf("0x%080x", init_slice('h1f))),
|
||||
.INITVAL_20($sformatf("0x%080x", init_slice('h20))),
|
||||
.INITVAL_21($sformatf("0x%080x", init_slice('h21))),
|
||||
.INITVAL_22($sformatf("0x%080x", init_slice('h22))),
|
||||
.INITVAL_23($sformatf("0x%080x", init_slice('h23))),
|
||||
.INITVAL_24($sformatf("0x%080x", init_slice('h24))),
|
||||
.INITVAL_25($sformatf("0x%080x", init_slice('h25))),
|
||||
.INITVAL_26($sformatf("0x%080x", init_slice('h26))),
|
||||
.INITVAL_27($sformatf("0x%080x", init_slice('h27))),
|
||||
.INITVAL_28($sformatf("0x%080x", init_slice('h28))),
|
||||
.INITVAL_29($sformatf("0x%080x", init_slice('h29))),
|
||||
.INITVAL_2A($sformatf("0x%080x", init_slice('h2a))),
|
||||
.INITVAL_2B($sformatf("0x%080x", init_slice('h2b))),
|
||||
.INITVAL_2C($sformatf("0x%080x", init_slice('h2c))),
|
||||
.INITVAL_2D($sformatf("0x%080x", init_slice('h2d))),
|
||||
.INITVAL_2E($sformatf("0x%080x", init_slice('h2e))),
|
||||
.INITVAL_2F($sformatf("0x%080x", init_slice('h2f))),
|
||||
.INITVAL_30($sformatf("0x%080x", init_slice('h30))),
|
||||
.INITVAL_31($sformatf("0x%080x", init_slice('h31))),
|
||||
.INITVAL_32($sformatf("0x%080x", init_slice('h32))),
|
||||
.INITVAL_33($sformatf("0x%080x", init_slice('h33))),
|
||||
.INITVAL_34($sformatf("0x%080x", init_slice('h34))),
|
||||
.INITVAL_35($sformatf("0x%080x", init_slice('h35))),
|
||||
.INITVAL_36($sformatf("0x%080x", init_slice('h36))),
|
||||
.INITVAL_37($sformatf("0x%080x", init_slice('h37))),
|
||||
.INITVAL_38($sformatf("0x%080x", init_slice('h38))),
|
||||
.INITVAL_39($sformatf("0x%080x", init_slice('h39))),
|
||||
.INITVAL_3A($sformatf("0x%080x", init_slice('h3a))),
|
||||
.INITVAL_3B($sformatf("0x%080x", init_slice('h3b))),
|
||||
.INITVAL_3C($sformatf("0x%080x", init_slice('h3c))),
|
||||
.INITVAL_3D($sformatf("0x%080x", init_slice('h3d))),
|
||||
.INITVAL_3E($sformatf("0x%080x", init_slice('h3e))),
|
||||
.INITVAL_3F($sformatf("0x%080x", init_slice('h3f))),
|
||||
.DATA_WIDTH_W($sformatf("X%d", PORT_W_WIDTH)),
|
||||
.DATA_WIDTH_R($sformatf("X%d", PORT_R_WIDTH)),
|
||||
.OUTREG("BYPASSED"),
|
||||
.RESETMODE(PORT_R_OPTION_RESETMODE),
|
||||
.ASYNC_RST_RELEASE(PORT_R_OPTION_RESETMODE),
|
||||
.CSDECODE_W("111"),
|
||||
.CSDECODE_R("111"),
|
||||
.ECC("DISABLED"),
|
||||
.GSR("DISABLED"),
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.CLKW(PORT_W_CLK),
|
||||
.CEW(PORT_W_CLK_EN & (|PORT_W_WR_EN)),
|
||||
.CSW(3'b111),
|
||||
.ADW(ADW),
|
||||
.DI(DI),
|
||||
|
||||
.CLKR(PORT_R_CLK),
|
||||
.CER(PORT_R_CLK_EN),
|
||||
.RST(PORT_R_OPTION_RESETMODE == "SYNC" ? PORT_R_RD_SRST : PORT_R_RD_ARST),
|
||||
.CSR(3'b111),
|
||||
.ADR(ADR),
|
||||
.DO(DO),
|
||||
);
|
||||
|
||||
end
|
||||
|
||||
endgenerate
|
||||
|
||||
endmodule
|
47
techlibs/lattice/brams_nexus.txt
Normal file
47
techlibs/lattice/brams_nexus.txt
Normal file
|
@ -0,0 +1,47 @@
|
|||
ram block $__NX_DP16K_ {
|
||||
abits 14;
|
||||
widths 1 2 4 9 18 per_port;
|
||||
byte 9;
|
||||
cost 129;
|
||||
init no_undef;
|
||||
port srsw "A" "B" {
|
||||
clock posedge;
|
||||
clken;
|
||||
wrbe_separate;
|
||||
rdwr no_change;
|
||||
portoption "RESETMODE" "SYNC" {
|
||||
rdsrst zero gated_clken;
|
||||
}
|
||||
portoption "RESETMODE" "ASYNC" {
|
||||
rdarst zero;
|
||||
}
|
||||
rdinit zero;
|
||||
}
|
||||
}
|
||||
|
||||
ram block $__NX_PDP16K_ {
|
||||
abits 14;
|
||||
widths 1 2 4 9 18 36 per_port;
|
||||
byte 9;
|
||||
option "SAME_CLOCK" 1 cost 128;
|
||||
option "SAME_CLOCK" 0 cost 129;
|
||||
init no_undef;
|
||||
port sr "R" {
|
||||
option "SAME_CLOCK" 1 clock posedge "C";
|
||||
option "SAME_CLOCK" 0 clock posedge;
|
||||
clken;
|
||||
portoption "RESETMODE" "SYNC" {
|
||||
rdsrst zero gated_clken;
|
||||
}
|
||||
portoption "RESETMODE" "ASYNC" {
|
||||
rdarst zero;
|
||||
}
|
||||
rdinit zero;
|
||||
}
|
||||
port sw "W" {
|
||||
option "SAME_CLOCK" 1 clock posedge "C";
|
||||
option "SAME_CLOCK" 0 clock posedge;
|
||||
clken;
|
||||
option "SAME_CLOCK" 1 wrtrans all old;
|
||||
}
|
||||
}
|
10389
techlibs/lattice/cells_bb_nexus.v
Normal file
10389
techlibs/lattice/cells_bb_nexus.v
Normal file
File diff suppressed because it is too large
Load diff
98
techlibs/lattice/cells_map_nexus.v
Normal file
98
techlibs/lattice/cells_map_nexus.v
Normal file
|
@ -0,0 +1,98 @@
|
|||
// Flipflop intermediate map level
|
||||
module \$__FF_NOLSR (input D, C, E, output Q);
|
||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
|
||||
generate
|
||||
if (_TECHMAP_WIREINIT_Q_ === 1'b1)
|
||||
FD1P3JX #(.GSR("DISABLED")) _TECHMAP_REPLACE_ (.D(D), .CK(C), .SP(E), .PD(1'b0), .Q(Q));
|
||||
else
|
||||
FD1P3IX #(.GSR("DISABLED")) _TECHMAP_REPLACE_ (.D(D), .CK(C), .SP(E), .CD(1'b0), .Q(Q));
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
module \$__FF_SYNCLSR (input D, C, E, R, output Q);
|
||||
parameter SR_VAL = 1'b0;
|
||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
|
||||
wire Ci, Ei, Ri, Rg, Dd;
|
||||
generate
|
||||
if (SR_VAL)
|
||||
FD1P3JX #(.GSR("DISABLED")) _TECHMAP_REPLACE_ (.D(D), .CK(C), .SP(E), .PD(R), .Q(Q));
|
||||
else
|
||||
FD1P3IX #(.GSR("DISABLED")) _TECHMAP_REPLACE_ (.D(D), .CK(C), .SP(E), .CD(R), .Q(Q));
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
module \$__FF_ASYNCLSR (input D, C, E, R, output Q);
|
||||
parameter SR_VAL = 1'b0;
|
||||
parameter _TECHMAP_WIREINIT_Q_ = 1'bx;
|
||||
wire _TECHMAP_REMOVEINIT_Q_ = (_TECHMAP_WIREINIT_Q_ === 1'bx || _TECHMAP_WIREINIT_Q_ === SR_VAL);
|
||||
wire Ci, Ei, Ri, Rg, Dd;
|
||||
generate
|
||||
if (SR_VAL)
|
||||
FD1P3BX #(.GSR("DISABLED")) _TECHMAP_REPLACE_ (.D(D), .CK(C), .SP(E), .PD(R), .Q(Q));
|
||||
else
|
||||
FD1P3DX #(.GSR("DISABLED")) _TECHMAP_REPLACE_ (.D(D), .CK(C), .SP(E), .CD(R), .Q(Q));
|
||||
endgenerate
|
||||
endmodule
|
||||
|
||||
|
||||
module \$_DFF_P_ (input D, C, output Q); \$__FF_NOLSR _TECHMAP_REPLACE_ (.D(D), .C(C), .E(1'b1), .Q(Q)); endmodule
|
||||
|
||||
module \$_DFFE_PP_ (input D, C, E, output Q); \$__FF_NOLSR _TECHMAP_REPLACE_ (.D(D), .C(C), .E(E), .Q(Q)); endmodule
|
||||
|
||||
module \$_DFF_PP0_ (input D, C, R, output Q); \$__FF_ASYNCLSR #(0) _TECHMAP_REPLACE_ (.D(D), .C(C), .R(R), .E(1'b1), .Q(Q)); endmodule
|
||||
module \$_DFF_PP1_ (input D, C, R, output Q); \$__FF_ASYNCLSR #(1) _TECHMAP_REPLACE_ (.D(D), .C(C), .R(R), .E(1'b1), .Q(Q)); endmodule
|
||||
|
||||
module \$_SDFF_PP0_ (input D, C, R, output Q); \$__FF_SYNCLSR #(0) _TECHMAP_REPLACE_ (.D(D), .C(C), .R(R), .E(1'b1), .Q(Q)); endmodule
|
||||
module \$_SDFF_PP1_ (input D, C, R, output Q); \$__FF_SYNCLSR #(1) _TECHMAP_REPLACE_ (.D(D), .C(C), .R(R), .E(1'b1), .Q(Q)); endmodule
|
||||
|
||||
module \$_DFFE_PP0P_ (input D, C, E, R, output Q); \$__FF_ASYNCLSR #(0) _TECHMAP_REPLACE_ (.D(D), .C(C), .R(R), .E(E), .Q(Q)); endmodule
|
||||
module \$_DFFE_PP1P_ (input D, C, E, R, output Q); \$__FF_ASYNCLSR #(1) _TECHMAP_REPLACE_ (.D(D), .C(C), .R(R), .E(E), .Q(Q)); endmodule
|
||||
|
||||
module \$_SDFFE_PP0P_ (input D, C, E, R, output Q); \$__FF_SYNCLSR #(0) _TECHMAP_REPLACE_ (.D(D), .C(C), .R(R), .E(E), .Q(Q)); endmodule
|
||||
module \$_SDFFE_PP1P_ (input D, C, E, R, output Q); \$__FF_SYNCLSR #(1) _TECHMAP_REPLACE_ (.D(D), .C(C), .R(R), .E(E), .Q(Q)); endmodule
|
||||
|
||||
`ifndef NO_LUT
|
||||
module \$lut (A, Y);
|
||||
parameter WIDTH = 0;
|
||||
parameter LUT = 0;
|
||||
|
||||
input [WIDTH-1:0] A;
|
||||
output Y;
|
||||
|
||||
generate
|
||||
if (WIDTH == 1) begin
|
||||
if (LUT == 2'b01)
|
||||
INV _TECHMAP_REPLACE_ (.A(A[0]), .Z(Y));
|
||||
else
|
||||
LUT4 #(.INIT($sformatf("0x%04x", {{8{LUT[1]}}, {8{LUT[0]}}}))) _TECHMAP_REPLACE_ (.Z(Y),
|
||||
.D(A[0]));
|
||||
end else
|
||||
if (WIDTH == 2) begin
|
||||
localparam [15:0] INIT = {{4{LUT[3]}}, {4{LUT[2]}}, {4{LUT[1]}}, {4{LUT[0]}}};
|
||||
LUT4 #(.INIT($sformatf("0x%04x", INIT))) _TECHMAP_REPLACE_ (.Z(Y),
|
||||
.C(A[0]), .D(A[1]));
|
||||
end else
|
||||
if (WIDTH == 3) begin
|
||||
localparam [15:0] INIT = {{2{LUT[7]}}, {2{LUT[6]}}, {2{LUT[5]}}, {2{LUT[4]}}, {2{LUT[3]}}, {2{LUT[2]}}, {2{LUT[1]}}, {2{LUT[0]}}};
|
||||
LUT4 #(.INIT($sformatf("0x%04x", INIT))) _TECHMAP_REPLACE_ (.Z(Y),
|
||||
.B(A[0]), .C(A[1]), .D(A[2]));
|
||||
end else
|
||||
if (WIDTH == 4) begin
|
||||
LUT4 #(.INIT($sformatf("0x%04x", LUT))) _TECHMAP_REPLACE_ (.Z(Y),
|
||||
.A(A[0]), .B(A[1]), .C(A[2]), .D(A[3]));
|
||||
end else
|
||||
if (WIDTH == 5) begin
|
||||
WIDEFN9 #(
|
||||
.INIT0($sformatf("0x%04x", LUT[15:0 ])),
|
||||
.INIT1($sformatf("0x%04x", LUT[31:16])),
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.A0(A[0]), .B0(A[1]), .C0(A[2]), .D0(A[3]),
|
||||
.A1(A[0]), .B1(A[1]), .C1(A[2]), .D1(A[3]),
|
||||
.SEL(A[4]), .Z(Y)
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
endmodule
|
||||
`endif
|
1058
techlibs/lattice/cells_sim_nexus.v
Normal file
1058
techlibs/lattice/cells_sim_nexus.v
Normal file
File diff suppressed because it is too large
Load diff
286
techlibs/lattice/cells_xtra_nexus.py
Normal file
286
techlibs/lattice/cells_xtra_nexus.py
Normal file
|
@ -0,0 +1,286 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
# Based on Xilinx cells_xtra.py; modified for Radiant's structure
|
||||
|
||||
from argparse import ArgumentParser
|
||||
from io import StringIO
|
||||
from enum import Enum, auto
|
||||
import os.path
|
||||
import sys
|
||||
import re
|
||||
|
||||
|
||||
class Cell:
|
||||
def __init__(self, name, keep=False, port_attrs={}):
|
||||
self.name = name
|
||||
self.keep = keep
|
||||
self.port_attrs = port_attrs
|
||||
self.found = False
|
||||
|
||||
class State(Enum):
|
||||
OUTSIDE = auto()
|
||||
IN_MODULE = auto()
|
||||
IN_OTHER_MODULE = auto()
|
||||
IN_FUNCTION = auto()
|
||||
IN_TASK = auto()
|
||||
|
||||
devices = [
|
||||
("lifcl", [
|
||||
Cell("ACC54"),
|
||||
Cell("ADC"),
|
||||
Cell("ALUREG"),
|
||||
Cell("BB_ADC", keep=True),
|
||||
Cell("BB_CDR", keep=True),
|
||||
Cell("BB_I3C_A", keep=True),
|
||||
Cell("BFD1P3KX"),
|
||||
Cell("BFD1P3LX"),
|
||||
Cell("BNKREF18", keep=True),
|
||||
Cell("CONFIG_LMMI", keep=True),
|
||||
Cell("DCC"),
|
||||
Cell("DCS"),
|
||||
Cell("DDRDLL"),
|
||||
Cell("DELAYA"),
|
||||
Cell("DELAYB"),
|
||||
Cell("DIFFIO18", keep=True),
|
||||
Cell("DLLDEL"),
|
||||
Cell("DP16K_MODE"),
|
||||
Cell("DP16K"),
|
||||
Cell("DPHY", keep=True),
|
||||
Cell("DPSC512K"),
|
||||
Cell("DQSBUF"),
|
||||
Cell("EBR_CORE"),
|
||||
Cell("EBR"),
|
||||
Cell("ECLKDIV"),
|
||||
Cell("ECLKSYNC"),
|
||||
Cell("FBMUX"),
|
||||
Cell("FIFO16K_MODE"),
|
||||
Cell("FIFO16K"),
|
||||
Cell("GSR"),
|
||||
Cell("HSE"),
|
||||
Cell("I2CFIFO"),
|
||||
Cell("IDDR71"),
|
||||
Cell("IDDRX1"),
|
||||
Cell("IDDRX2DQ"),
|
||||
Cell("IDDRX2"),
|
||||
Cell("IDDRX4DQ"),
|
||||
Cell("IDDRX4"),
|
||||
Cell("IDDRX5"),
|
||||
Cell("IFD1P3BX"),
|
||||
Cell("IFD1P3DX"),
|
||||
Cell("IFD1P3IX"),
|
||||
Cell("IFD1P3JX"),
|
||||
Cell("JTAG", keep=True),
|
||||
Cell("LRAM"),
|
||||
Cell("M18X36"),
|
||||
Cell("MIPI"),
|
||||
Cell("MULT18"),
|
||||
# Cell("MULT18X18"),
|
||||
# Cell("MULT18X36"),
|
||||
Cell("MULT36"),
|
||||
# Cell("MULT36X36"),
|
||||
Cell("MULT9"),
|
||||
# Cell("MULT9X9"),
|
||||
# Cell("MULTADDSUB18X18"),
|
||||
Cell("MULTADDSUB18X18WIDE"),
|
||||
# Cell("MULTADDSUB18X36"),
|
||||
# Cell("MULTADDSUB36X36"),
|
||||
Cell("MULTADDSUB9X9WIDE"),
|
||||
Cell("MULTIBOOT", keep=True),
|
||||
# Cell("MULTPREADD18X18"),
|
||||
# Cell("MULTPREADD9X9"),
|
||||
Cell("ODDR71"),
|
||||
Cell("ODDRX1"),
|
||||
Cell("ODDRX2DQS"),
|
||||
Cell("ODDRX2DQ"),
|
||||
Cell("ODDRX2"),
|
||||
Cell("ODDRX4DQS"),
|
||||
Cell("ODDRX4DQ"),
|
||||
Cell("ODDRX4"),
|
||||
Cell("ODDRX5"),
|
||||
Cell("OFD1P3BX"),
|
||||
Cell("OFD1P3DX"),
|
||||
Cell("OFD1P3IX"),
|
||||
Cell("OFD1P3JX"),
|
||||
Cell("OSC"),
|
||||
Cell("OSCA"),
|
||||
Cell("OSHX2"),
|
||||
Cell("OSHX4"),
|
||||
Cell("PCIE"),
|
||||
Cell("PCLKDIV"),
|
||||
Cell("PCLKDIVSP"),
|
||||
Cell("PDP16K_MODE"),
|
||||
Cell("PDP16K"),
|
||||
Cell("PDPSC16K_MODE"),
|
||||
Cell("PDPSC16K"),
|
||||
Cell("PDPSC512K"),
|
||||
Cell("PLL"),
|
||||
Cell("PREADD9"),
|
||||
Cell("PUR", keep=True),
|
||||
Cell("REFMUX"),
|
||||
Cell("REG18"),
|
||||
Cell("SEDC", keep=True),
|
||||
Cell("SEIO18"),
|
||||
Cell("SEIO33"),
|
||||
Cell("SGMIICDR"),
|
||||
Cell("SP16K_MODE"),
|
||||
Cell("SP16K"),
|
||||
Cell("SP512K"),
|
||||
Cell("TSALLA"),
|
||||
Cell("TSHX2DQS"),
|
||||
Cell("TSHX2DQ"),
|
||||
Cell("TSHX4DQS"),
|
||||
Cell("TSHX4DQ"),
|
||||
Cell("WDT", keep=True),
|
||||
|
||||
Cell("ACC54_CORE"),
|
||||
Cell("ADC_CORE"),
|
||||
Cell("ALUREG_CORE"),
|
||||
Cell("BNKREF18_CORE"),
|
||||
Cell("BNKREF33_CORE"),
|
||||
Cell("DIFFIO18_CORE"),
|
||||
Cell("CONFIG_CLKRST_CORE", keep=True),
|
||||
Cell("CONFIG_HSE_CORE", keep=True),
|
||||
Cell("CONFIG_IP_CORE", keep=True),
|
||||
Cell("CONFIG_JTAG_CORE", keep=True),
|
||||
Cell("CONFIG_LMMI_CORE", keep=True),
|
||||
Cell("CONFIG_MULTIBOOT_CORE", keep=True),
|
||||
Cell("CONFIG_SEDC_CORE", keep=True),
|
||||
Cell("CONFIG_WDT_CORE", keep=True),
|
||||
Cell("DDRDLL_CORE"),
|
||||
Cell("DLLDEL_CORE"),
|
||||
Cell("DPHY_CORE"),
|
||||
Cell("DQSBUF_CORE"),
|
||||
Cell("ECLKDIV_CORE"),
|
||||
Cell("ECLKSYNC_CORE"),
|
||||
Cell("FBMUX_CORE"),
|
||||
Cell("GSR_CORE"),
|
||||
Cell("I2CFIFO_CORE"),
|
||||
Cell("LRAM_CORE"),
|
||||
Cell("MULT18_CORE"),
|
||||
Cell("MULT18X36_CORE"),
|
||||
Cell("MULT36_CORE"),
|
||||
Cell("MULT9_CORE"),
|
||||
Cell("OSC_CORE"),
|
||||
Cell("PCIE_CORE"),
|
||||
Cell("PLL_CORE"),
|
||||
Cell("PREADD9_CORE"),
|
||||
Cell("REFMUX_CORE"),
|
||||
Cell("REG18_CORE"),
|
||||
Cell("SEIO18_CORE"),
|
||||
Cell("SEIO33_CORE"),
|
||||
Cell("SGMIICDR_CORE"),
|
||||
])
|
||||
]
|
||||
|
||||
def xtract_cells_decl(device, cells, dirs, outf):
|
||||
fname = os.path.join(dir, device + '.v')
|
||||
with open(fname) as f:
|
||||
state = State.OUTSIDE
|
||||
# Probably the most horrible Verilog "parser" ever written.
|
||||
cell = None
|
||||
for l in f:
|
||||
l, _, comment = l.partition('//')
|
||||
l = l.strip()
|
||||
if l.startswith("module "):
|
||||
cell_name = l[7:l.find('(')].strip()
|
||||
cell = None
|
||||
module_ports = []
|
||||
iopad_pin = set()
|
||||
if state != State.OUTSIDE:
|
||||
print('Nested modules in {}.'.format(fname))
|
||||
sys.exit(1)
|
||||
for c in cells:
|
||||
if c.name != cell_name:
|
||||
continue
|
||||
cell = c
|
||||
state = State.IN_MODULE
|
||||
if cell.keep:
|
||||
outf.write('(* keep *)\n')
|
||||
outf.write('module {} (...);\n'.format(cell.name))
|
||||
cell.found = True
|
||||
|
||||
m = re.search(r'synthesis .*black_box_pad_pin="([^"]*)"', comment)
|
||||
if m:
|
||||
iopad_pin = set(m.group(1).split(","))
|
||||
|
||||
if cell is None:
|
||||
state = State.IN_OTHER_MODULE
|
||||
elif l.startswith('task '):
|
||||
if state == State.IN_MODULE:
|
||||
state = State.IN_TASK
|
||||
elif l.startswith('function '):
|
||||
if state == State.IN_MODULE:
|
||||
state = State.IN_FUNCTION
|
||||
elif l == 'endtask':
|
||||
if state == State.IN_TASK:
|
||||
state = State.IN_MODULE
|
||||
elif l == 'endfunction':
|
||||
if state == State.IN_FUNCTION:
|
||||
state = State.IN_MODULE
|
||||
elif l == 'endmodule':
|
||||
if state == State.IN_MODULE:
|
||||
for kind, rng, port in module_ports:
|
||||
for attr in cell.port_attrs.get(port, []):
|
||||
outf.write(' (* {} *)\n'.format(attr))
|
||||
if port in iopad_pin:
|
||||
outf.write(' (* iopad_external_pin *)\n')
|
||||
if rng is None:
|
||||
outf.write(' {} {};\n'.format(kind, port))
|
||||
else:
|
||||
outf.write(' {} {} {};\n'.format(kind, rng, port))
|
||||
outf.write(l + '\n')
|
||||
outf.write('\n')
|
||||
elif state != State.IN_OTHER_MODULE:
|
||||
print('endmodule in weird place in {}.'.format(cell.name, fname))
|
||||
sys.exit(1)
|
||||
state = State.OUTSIDE
|
||||
elif l.startswith(('input ', 'output ', 'inout ')) and state == State.IN_MODULE:
|
||||
if l.endswith((';', ',')):
|
||||
l = l[:-1]
|
||||
if ';' in l:
|
||||
print('Weird port line in {} [{}].'.format(fname, l))
|
||||
sys.exit(1)
|
||||
kind, _, ports = l.partition(' ')
|
||||
for port in ports.split(','):
|
||||
port = port.strip()
|
||||
if port.startswith('['):
|
||||
rng, port = port.split()
|
||||
else:
|
||||
rng = None
|
||||
module_ports.append((kind, rng, port))
|
||||
elif l.startswith('parameter ') and state == State.IN_MODULE:
|
||||
if l.endswith((';', ',')):
|
||||
l = l[:-1]
|
||||
while ' ' in l:
|
||||
l = l.replace(' ', ' ')
|
||||
if ';' in l:
|
||||
print('Weird parameter line in {} [{}].'.format(fname, l))
|
||||
sys.exit(1)
|
||||
outf.write(' {};\n'.format(l))
|
||||
|
||||
if state != State.OUTSIDE:
|
||||
print('endmodule not found in {}.'.format(fname))
|
||||
sys.exit(1)
|
||||
for cell in cells:
|
||||
if not cell.found:
|
||||
print('cell {} not found in {}.'.format(cell.name, fname))
|
||||
if __name__ == '__main__':
|
||||
parser = ArgumentParser(description='Extract Lattice blackbox cell definitions from Radiant.')
|
||||
parser.add_argument('radiant_dir', nargs='?', default='/opt/lscc/radiant/2.0/')
|
||||
args = parser.parse_args()
|
||||
|
||||
dirs = [
|
||||
os.path.join(args.radiant_dir, 'cae_library/synthesis/verilog/'),
|
||||
]
|
||||
for dir in dirs:
|
||||
if not os.path.isdir(dir):
|
||||
print('{} is not a directory'.format(dir))
|
||||
|
||||
out = StringIO()
|
||||
for device, cells in devices:
|
||||
xtract_cells_decl(device, cells, dirs, out)
|
||||
|
||||
with open('cells_bb_nexus.v', 'w') as f:
|
||||
f.write('// Created by cells_xtra_nexus.py from Lattice models\n')
|
||||
f.write('\n')
|
||||
f.write(out.getvalue())
|
79
techlibs/lattice/dsp_map_nexus.v
Normal file
79
techlibs/lattice/dsp_map_nexus.v
Normal file
|
@ -0,0 +1,79 @@
|
|||
module \$__NX_MUL36X36 (input [35:0] A, input [35:0] B, output [71:0] Y);
|
||||
|
||||
parameter A_WIDTH = 36;
|
||||
parameter B_WIDTH = 36;
|
||||
parameter Y_WIDTH = 72;
|
||||
parameter A_SIGNED = 0;
|
||||
parameter B_SIGNED = 0;
|
||||
|
||||
MULT36X36 #(
|
||||
.REGINPUTA("BYPASS"),
|
||||
.REGINPUTB("BYPASS"),
|
||||
.REGOUTPUT("BYPASS")
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.A(A), .B(B),
|
||||
.SIGNEDA(A_SIGNED ? 1'b1 : 1'b0),
|
||||
.SIGNEDB(B_SIGNED ? 1'b1 : 1'b0),
|
||||
.Z(Y)
|
||||
);
|
||||
endmodule
|
||||
|
||||
module \$__NX_MUL36X18 (input [35:0] A, input [17:0] B, output [53:0] Y);
|
||||
|
||||
parameter A_WIDTH = 36;
|
||||
parameter B_WIDTH = 18;
|
||||
parameter Y_WIDTH = 54;
|
||||
parameter A_SIGNED = 0;
|
||||
parameter B_SIGNED = 0;
|
||||
|
||||
MULT18X36 #(
|
||||
.REGINPUTA("BYPASS"),
|
||||
.REGINPUTB("BYPASS"),
|
||||
.REGOUTPUT("BYPASS")
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.A(B), .B(A),
|
||||
.SIGNEDA(B_SIGNED ? 1'b1 : 1'b0),
|
||||
.SIGNEDB(A_SIGNED ? 1'b1 : 1'b0),
|
||||
.Z(Y)
|
||||
);
|
||||
endmodule
|
||||
|
||||
module \$__NX_MUL18X18 (input [17:0] A, input [17:0] B, output [35:0] Y);
|
||||
|
||||
parameter A_WIDTH = 18;
|
||||
parameter B_WIDTH = 18;
|
||||
parameter Y_WIDTH = 36;
|
||||
parameter A_SIGNED = 0;
|
||||
parameter B_SIGNED = 0;
|
||||
|
||||
MULT18X18 #(
|
||||
.REGINPUTA("BYPASS"),
|
||||
.REGINPUTB("BYPASS"),
|
||||
.REGOUTPUT("BYPASS")
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.A(A), .B(B),
|
||||
.SIGNEDA(A_SIGNED ? 1'b1 : 1'b0),
|
||||
.SIGNEDB(B_SIGNED ? 1'b1 : 1'b0),
|
||||
.Z(Y)
|
||||
);
|
||||
endmodule
|
||||
|
||||
module \$__NX_MUL9X9 (input [8:0] A, input [8:0] B, output [17:0] Y);
|
||||
|
||||
parameter A_WIDTH = 9;
|
||||
parameter B_WIDTH = 9;
|
||||
parameter Y_WIDTH = 18;
|
||||
parameter A_SIGNED = 0;
|
||||
parameter B_SIGNED = 0;
|
||||
|
||||
MULT9X9 #(
|
||||
.REGINPUTA("BYPASS"),
|
||||
.REGINPUTB("BYPASS"),
|
||||
.REGOUTPUT("BYPASS")
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.A(A), .B(B),
|
||||
.SIGNEDA(A_SIGNED ? 1'b1 : 1'b0),
|
||||
.SIGNEDB(B_SIGNED ? 1'b1 : 1'b0),
|
||||
.Z(Y)
|
||||
);
|
||||
endmodule
|
194
techlibs/lattice/lrams_map_nexus.v
Normal file
194
techlibs/lattice/lrams_map_nexus.v
Normal file
|
@ -0,0 +1,194 @@
|
|||
module $__NX_DPSC512K_ (...);
|
||||
|
||||
parameter INIT = 0;
|
||||
parameter OPTION_RESETMODE = "SYNC";
|
||||
|
||||
input CLK_C;
|
||||
|
||||
input PORT_A_CLK;
|
||||
input PORT_A_CLK_EN;
|
||||
input PORT_A_WR_EN;
|
||||
input PORT_A_RD_SRST;
|
||||
input PORT_A_RD_ARST;
|
||||
input [13:0] PORT_A_ADDR;
|
||||
input [3:0] PORT_A_WR_BE;
|
||||
input [31:0] PORT_A_WR_DATA;
|
||||
output [31:0] PORT_A_RD_DATA;
|
||||
|
||||
input PORT_B_CLK;
|
||||
input PORT_B_CLK_EN;
|
||||
input PORT_B_WR_EN;
|
||||
input PORT_B_RD_SRST;
|
||||
input PORT_B_RD_ARST;
|
||||
input [13:0] PORT_B_ADDR;
|
||||
input [3:0] PORT_B_WR_BE;
|
||||
input [31:0] PORT_B_WR_DATA;
|
||||
output [31:0] PORT_B_RD_DATA;
|
||||
|
||||
function [5119:0] init_slice;
|
||||
input integer idx;
|
||||
integer i, j;
|
||||
init_slice = 0;
|
||||
for (i = 0; i < 128; i = i + 1) begin
|
||||
init_slice[i*40+:32] = INIT[(idx * 128 + i) * 32+:32];
|
||||
end
|
||||
endfunction
|
||||
|
||||
DPSC512K #(
|
||||
.INITVAL_00($sformatf("0x%01280x", init_slice('h00))),
|
||||
.INITVAL_01($sformatf("0x%01280x", init_slice('h01))),
|
||||
.INITVAL_02($sformatf("0x%01280x", init_slice('h02))),
|
||||
.INITVAL_03($sformatf("0x%01280x", init_slice('h03))),
|
||||
.INITVAL_04($sformatf("0x%01280x", init_slice('h04))),
|
||||
.INITVAL_05($sformatf("0x%01280x", init_slice('h05))),
|
||||
.INITVAL_06($sformatf("0x%01280x", init_slice('h06))),
|
||||
.INITVAL_07($sformatf("0x%01280x", init_slice('h07))),
|
||||
.INITVAL_08($sformatf("0x%01280x", init_slice('h08))),
|
||||
.INITVAL_09($sformatf("0x%01280x", init_slice('h09))),
|
||||
.INITVAL_0A($sformatf("0x%01280x", init_slice('h0a))),
|
||||
.INITVAL_0B($sformatf("0x%01280x", init_slice('h0b))),
|
||||
.INITVAL_0C($sformatf("0x%01280x", init_slice('h0c))),
|
||||
.INITVAL_0D($sformatf("0x%01280x", init_slice('h0d))),
|
||||
.INITVAL_0E($sformatf("0x%01280x", init_slice('h0e))),
|
||||
.INITVAL_0F($sformatf("0x%01280x", init_slice('h0f))),
|
||||
.INITVAL_10($sformatf("0x%01280x", init_slice('h10))),
|
||||
.INITVAL_11($sformatf("0x%01280x", init_slice('h11))),
|
||||
.INITVAL_12($sformatf("0x%01280x", init_slice('h12))),
|
||||
.INITVAL_13($sformatf("0x%01280x", init_slice('h13))),
|
||||
.INITVAL_14($sformatf("0x%01280x", init_slice('h14))),
|
||||
.INITVAL_15($sformatf("0x%01280x", init_slice('h15))),
|
||||
.INITVAL_16($sformatf("0x%01280x", init_slice('h16))),
|
||||
.INITVAL_17($sformatf("0x%01280x", init_slice('h17))),
|
||||
.INITVAL_18($sformatf("0x%01280x", init_slice('h18))),
|
||||
.INITVAL_19($sformatf("0x%01280x", init_slice('h19))),
|
||||
.INITVAL_1A($sformatf("0x%01280x", init_slice('h1a))),
|
||||
.INITVAL_1B($sformatf("0x%01280x", init_slice('h1b))),
|
||||
.INITVAL_1C($sformatf("0x%01280x", init_slice('h1c))),
|
||||
.INITVAL_1D($sformatf("0x%01280x", init_slice('h1d))),
|
||||
.INITVAL_1E($sformatf("0x%01280x", init_slice('h1e))),
|
||||
.INITVAL_1F($sformatf("0x%01280x", init_slice('h1f))),
|
||||
.INITVAL_20($sformatf("0x%01280x", init_slice('h20))),
|
||||
.INITVAL_21($sformatf("0x%01280x", init_slice('h21))),
|
||||
.INITVAL_22($sformatf("0x%01280x", init_slice('h22))),
|
||||
.INITVAL_23($sformatf("0x%01280x", init_slice('h23))),
|
||||
.INITVAL_24($sformatf("0x%01280x", init_slice('h24))),
|
||||
.INITVAL_25($sformatf("0x%01280x", init_slice('h25))),
|
||||
.INITVAL_26($sformatf("0x%01280x", init_slice('h26))),
|
||||
.INITVAL_27($sformatf("0x%01280x", init_slice('h27))),
|
||||
.INITVAL_28($sformatf("0x%01280x", init_slice('h28))),
|
||||
.INITVAL_29($sformatf("0x%01280x", init_slice('h29))),
|
||||
.INITVAL_2A($sformatf("0x%01280x", init_slice('h2a))),
|
||||
.INITVAL_2B($sformatf("0x%01280x", init_slice('h2b))),
|
||||
.INITVAL_2C($sformatf("0x%01280x", init_slice('h2c))),
|
||||
.INITVAL_2D($sformatf("0x%01280x", init_slice('h2d))),
|
||||
.INITVAL_2E($sformatf("0x%01280x", init_slice('h2e))),
|
||||
.INITVAL_2F($sformatf("0x%01280x", init_slice('h2f))),
|
||||
.INITVAL_30($sformatf("0x%01280x", init_slice('h30))),
|
||||
.INITVAL_31($sformatf("0x%01280x", init_slice('h31))),
|
||||
.INITVAL_32($sformatf("0x%01280x", init_slice('h32))),
|
||||
.INITVAL_33($sformatf("0x%01280x", init_slice('h33))),
|
||||
.INITVAL_34($sformatf("0x%01280x", init_slice('h34))),
|
||||
.INITVAL_35($sformatf("0x%01280x", init_slice('h35))),
|
||||
.INITVAL_36($sformatf("0x%01280x", init_slice('h36))),
|
||||
.INITVAL_37($sformatf("0x%01280x", init_slice('h37))),
|
||||
.INITVAL_38($sformatf("0x%01280x", init_slice('h38))),
|
||||
.INITVAL_39($sformatf("0x%01280x", init_slice('h39))),
|
||||
.INITVAL_3A($sformatf("0x%01280x", init_slice('h3a))),
|
||||
.INITVAL_3B($sformatf("0x%01280x", init_slice('h3b))),
|
||||
.INITVAL_3C($sformatf("0x%01280x", init_slice('h3c))),
|
||||
.INITVAL_3D($sformatf("0x%01280x", init_slice('h3d))),
|
||||
.INITVAL_3E($sformatf("0x%01280x", init_slice('h3e))),
|
||||
.INITVAL_3F($sformatf("0x%01280x", init_slice('h3f))),
|
||||
.INITVAL_40($sformatf("0x%01280x", init_slice('h40))),
|
||||
.INITVAL_41($sformatf("0x%01280x", init_slice('h41))),
|
||||
.INITVAL_42($sformatf("0x%01280x", init_slice('h42))),
|
||||
.INITVAL_43($sformatf("0x%01280x", init_slice('h43))),
|
||||
.INITVAL_44($sformatf("0x%01280x", init_slice('h44))),
|
||||
.INITVAL_45($sformatf("0x%01280x", init_slice('h45))),
|
||||
.INITVAL_46($sformatf("0x%01280x", init_slice('h46))),
|
||||
.INITVAL_47($sformatf("0x%01280x", init_slice('h47))),
|
||||
.INITVAL_48($sformatf("0x%01280x", init_slice('h48))),
|
||||
.INITVAL_49($sformatf("0x%01280x", init_slice('h49))),
|
||||
.INITVAL_4A($sformatf("0x%01280x", init_slice('h4a))),
|
||||
.INITVAL_4B($sformatf("0x%01280x", init_slice('h4b))),
|
||||
.INITVAL_4C($sformatf("0x%01280x", init_slice('h4c))),
|
||||
.INITVAL_4D($sformatf("0x%01280x", init_slice('h4d))),
|
||||
.INITVAL_4E($sformatf("0x%01280x", init_slice('h4e))),
|
||||
.INITVAL_4F($sformatf("0x%01280x", init_slice('h4f))),
|
||||
.INITVAL_50($sformatf("0x%01280x", init_slice('h50))),
|
||||
.INITVAL_51($sformatf("0x%01280x", init_slice('h51))),
|
||||
.INITVAL_52($sformatf("0x%01280x", init_slice('h52))),
|
||||
.INITVAL_53($sformatf("0x%01280x", init_slice('h53))),
|
||||
.INITVAL_54($sformatf("0x%01280x", init_slice('h54))),
|
||||
.INITVAL_55($sformatf("0x%01280x", init_slice('h55))),
|
||||
.INITVAL_56($sformatf("0x%01280x", init_slice('h56))),
|
||||
.INITVAL_57($sformatf("0x%01280x", init_slice('h57))),
|
||||
.INITVAL_58($sformatf("0x%01280x", init_slice('h58))),
|
||||
.INITVAL_59($sformatf("0x%01280x", init_slice('h59))),
|
||||
.INITVAL_5A($sformatf("0x%01280x", init_slice('h5a))),
|
||||
.INITVAL_5B($sformatf("0x%01280x", init_slice('h5b))),
|
||||
.INITVAL_5C($sformatf("0x%01280x", init_slice('h5c))),
|
||||
.INITVAL_5D($sformatf("0x%01280x", init_slice('h5d))),
|
||||
.INITVAL_5E($sformatf("0x%01280x", init_slice('h5e))),
|
||||
.INITVAL_5F($sformatf("0x%01280x", init_slice('h5f))),
|
||||
.INITVAL_60($sformatf("0x%01280x", init_slice('h60))),
|
||||
.INITVAL_61($sformatf("0x%01280x", init_slice('h61))),
|
||||
.INITVAL_62($sformatf("0x%01280x", init_slice('h62))),
|
||||
.INITVAL_63($sformatf("0x%01280x", init_slice('h63))),
|
||||
.INITVAL_64($sformatf("0x%01280x", init_slice('h64))),
|
||||
.INITVAL_65($sformatf("0x%01280x", init_slice('h65))),
|
||||
.INITVAL_66($sformatf("0x%01280x", init_slice('h66))),
|
||||
.INITVAL_67($sformatf("0x%01280x", init_slice('h67))),
|
||||
.INITVAL_68($sformatf("0x%01280x", init_slice('h68))),
|
||||
.INITVAL_69($sformatf("0x%01280x", init_slice('h69))),
|
||||
.INITVAL_6A($sformatf("0x%01280x", init_slice('h6a))),
|
||||
.INITVAL_6B($sformatf("0x%01280x", init_slice('h6b))),
|
||||
.INITVAL_6C($sformatf("0x%01280x", init_slice('h6c))),
|
||||
.INITVAL_6D($sformatf("0x%01280x", init_slice('h6d))),
|
||||
.INITVAL_6E($sformatf("0x%01280x", init_slice('h6e))),
|
||||
.INITVAL_6F($sformatf("0x%01280x", init_slice('h6f))),
|
||||
.INITVAL_70($sformatf("0x%01280x", init_slice('h70))),
|
||||
.INITVAL_71($sformatf("0x%01280x", init_slice('h71))),
|
||||
.INITVAL_72($sformatf("0x%01280x", init_slice('h72))),
|
||||
.INITVAL_73($sformatf("0x%01280x", init_slice('h73))),
|
||||
.INITVAL_74($sformatf("0x%01280x", init_slice('h74))),
|
||||
.INITVAL_75($sformatf("0x%01280x", init_slice('h75))),
|
||||
.INITVAL_76($sformatf("0x%01280x", init_slice('h76))),
|
||||
.INITVAL_77($sformatf("0x%01280x", init_slice('h77))),
|
||||
.INITVAL_78($sformatf("0x%01280x", init_slice('h78))),
|
||||
.INITVAL_79($sformatf("0x%01280x", init_slice('h79))),
|
||||
.INITVAL_7A($sformatf("0x%01280x", init_slice('h7a))),
|
||||
.INITVAL_7B($sformatf("0x%01280x", init_slice('h7b))),
|
||||
.INITVAL_7C($sformatf("0x%01280x", init_slice('h7c))),
|
||||
.INITVAL_7D($sformatf("0x%01280x", init_slice('h7d))),
|
||||
.INITVAL_7E($sformatf("0x%01280x", init_slice('h7e))),
|
||||
.INITVAL_7F($sformatf("0x%01280x", init_slice('h7f))),
|
||||
.OUTREG_A("NO_REG"),
|
||||
.OUTREG_B("NO_REG"),
|
||||
.ECC_BYTE_SEL("BYTE_EN"),
|
||||
.GSR("DISABLED"),
|
||||
.RESETMODE(OPTION_RESETMODE),
|
||||
.ASYNC_RESET_RELEASE(OPTION_RESETMODE),
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.CLK(CLK_C),
|
||||
|
||||
.WEA(PORT_A_WR_EN),
|
||||
.CEA(PORT_A_CLK_EN),
|
||||
.RSTA(OPTION_RESETMODE == "SYNC" ? PORT_A_RD_SRST : PORT_A_RD_ARST),
|
||||
.CSA(1'b1),
|
||||
.ADA(PORT_A_ADDR),
|
||||
.BENA_N(~PORT_A_WR_BE),
|
||||
.DIA(PORT_A_WR_DATA),
|
||||
.DOA(PORT_A_RD_DATA),
|
||||
|
||||
.WEB(PORT_B_WR_EN),
|
||||
.CEB(PORT_B_CLK_EN),
|
||||
.RSTB(OPTION_RESETMODE == "SYNC" ? PORT_B_RD_SRST : PORT_B_RD_ARST),
|
||||
.CSB(1'b1),
|
||||
.BENB_N(~PORT_B_WR_BE),
|
||||
.ADB(PORT_B_ADDR),
|
||||
.DIB(PORT_B_WR_DATA),
|
||||
.DOB(PORT_B_RD_DATA),
|
||||
);
|
||||
|
||||
endmodule
|
21
techlibs/lattice/lrams_nexus.txt
Normal file
21
techlibs/lattice/lrams_nexus.txt
Normal file
|
@ -0,0 +1,21 @@
|
|||
ram huge $__NX_DPSC512K_ {
|
||||
abits 14;
|
||||
width 32;
|
||||
byte 8;
|
||||
cost 2048;
|
||||
init no_undef;
|
||||
port srsw "A" "B" {
|
||||
clock posedge "C";
|
||||
clken;
|
||||
wrbe_separate;
|
||||
rdwr no_change;
|
||||
option "RESETMODE" "SYNC" {
|
||||
rdsrst zero gated_clken;
|
||||
}
|
||||
option "RESETMODE" "ASYNC" {
|
||||
rdarst zero;
|
||||
}
|
||||
rdinit zero;
|
||||
wrtrans all old;
|
||||
}
|
||||
}
|
23
techlibs/lattice/lutrams_map_nexus.v
Normal file
23
techlibs/lattice/lutrams_map_nexus.v
Normal file
|
@ -0,0 +1,23 @@
|
|||
module $__NEXUS_DPR16X4_ (...);
|
||||
parameter INIT = 64'b0;
|
||||
|
||||
input PORT_W_CLK;
|
||||
input [3:0] PORT_W_ADDR;
|
||||
input [3:0] PORT_W_WR_DATA;
|
||||
input PORT_W_WR_EN;
|
||||
|
||||
input [3:0] PORT_R_ADDR;
|
||||
output [3:0] PORT_R_RD_DATA;
|
||||
|
||||
DPR16X4 #(
|
||||
.INITVAL($sformatf("0x%08x", INIT))
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.RAD(PORT_R_ADDR),
|
||||
.DO(PORT_R_RD_DATA),
|
||||
|
||||
.WAD(PORT_W_ADDR),
|
||||
.DI(PORT_W_WR_DATA),
|
||||
.WCK(PORT_W_CLK),
|
||||
.WRE(PORT_W_WR_EN)
|
||||
);
|
||||
endmodule
|
12
techlibs/lattice/lutrams_nexus.txt
Normal file
12
techlibs/lattice/lutrams_nexus.txt
Normal file
|
@ -0,0 +1,12 @@
|
|||
ram distributed $__NEXUS_DPR16X4_ {
|
||||
abits 4;
|
||||
width 4;
|
||||
cost 4;
|
||||
init no_undef;
|
||||
prune_rom;
|
||||
port sw "W" {
|
||||
clock posedge;
|
||||
}
|
||||
port ar "R" {
|
||||
}
|
||||
}
|
33
techlibs/lattice/parse_init.vh
Normal file
33
techlibs/lattice/parse_init.vh
Normal file
|
@ -0,0 +1,33 @@
|
|||
function [15:0] parse_init;
|
||||
input [((2+(16/4))*8)-1:0] init;
|
||||
reg [7:0] c;
|
||||
integer i;
|
||||
begin
|
||||
for (i = 0; i < (16/4); i = i + 1) begin
|
||||
c = init[(i * 8) +: 8];
|
||||
if (c >= "0" && c <= "9")
|
||||
parse_init[(i * 4) +: 4] = (c - "0");
|
||||
else if (c >= "A" && c <= "F")
|
||||
parse_init[(i * 4) +: 4] = (c - "A") + 10;
|
||||
else if (c >= "a" && c <= "f")
|
||||
parse_init[(i * 4) +: 4] = (c - "a") + 10;
|
||||
end
|
||||
end
|
||||
endfunction
|
||||
|
||||
function [63:0] parse_init_64;
|
||||
input [((2+(64/4))*8)-1:0] init;
|
||||
reg [7:0] c;
|
||||
integer i;
|
||||
begin
|
||||
for (i = 0; i < (64/4); i = i + 1) begin
|
||||
c = init[(i * 8) +: 8];
|
||||
if (c >= "0" && c <= "9")
|
||||
parse_init_64[(i * 4) +: 4] = (c - "0");
|
||||
else if (c >= "A" && c <= "F")
|
||||
parse_init_64[(i * 4) +: 4] = (c - "A") + 10;
|
||||
else if (c >= "a" && c <= "f")
|
||||
parse_init_64[(i * 4) +: 4] = (c - "a") + 10;
|
||||
end
|
||||
end
|
||||
endfunction
|
|
@ -35,13 +35,32 @@ struct SynthLatticePass : public ScriptPass
|
|||
RTLIL::constpad["synth_lattice.abc9.W"] = "300";
|
||||
}
|
||||
|
||||
struct DSPRule {
|
||||
int a_maxwidth;
|
||||
int b_maxwidth;
|
||||
int a_minwidth;
|
||||
int b_minwidth;
|
||||
std::string prim;
|
||||
};
|
||||
|
||||
const std::vector<DSPRule> dsp_rules_nexus = {
|
||||
{36, 36, 22, 22, "$__NX_MUL36X36"},
|
||||
{36, 18, 22, 10, "$__NX_MUL36X18"},
|
||||
{18, 18, 10, 4, "$__NX_MUL18X18"},
|
||||
{18, 18, 4, 10, "$__NX_MUL18X18"},
|
||||
{ 9, 9, 4, 4, "$__NX_MUL9X9"},
|
||||
};
|
||||
const std::vector<DSPRule> dsp_rules_ecp5 = {
|
||||
{18, 18, 2, 2, "$__MUL18X18"},
|
||||
};
|
||||
|
||||
void help() override
|
||||
{
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
log("\n");
|
||||
log(" synth_lattice [options]\n");
|
||||
log("\n");
|
||||
log("This command runs synthesis for Lattice FPGAs (excluding iCE40 and Nexus).\n");
|
||||
log("This command runs synthesis for Lattice FPGAs (excluding iCE40).\n");
|
||||
log("\n");
|
||||
log(" -top <module>\n");
|
||||
log(" use the specified module as top module\n");
|
||||
|
@ -54,6 +73,8 @@ struct SynthLatticePass : public ScriptPass
|
|||
log(" - xo2: MachXO2\n");
|
||||
log(" - xo3: MachXO3L/LF\n");
|
||||
log(" - xo3d: MachXO3D\n");
|
||||
log(" - lifcl: CrossLink-NX\n");
|
||||
log(" - lfd2nx: Certus-NX\n");
|
||||
//log(" - xo: MachXO (EXPERIMENTAL)\n");
|
||||
//log(" - pm: Platform Manager (EXPERIMENTAL)\n");
|
||||
//log(" - pm2: Platform Manager 2 (EXPERIMENTAL)\n");
|
||||
|
@ -118,9 +139,13 @@ struct SynthLatticePass : public ScriptPass
|
|||
log("\n");
|
||||
log(" -iopad\n");
|
||||
log(" insert IO buffers\n");
|
||||
log(" (by default enabled on Nexus FPGAs)\n");
|
||||
log("\n");
|
||||
log(" -noiopad\n");
|
||||
log(" do not insert IO buffers\n");
|
||||
log("\n");
|
||||
log(" -nodsp\n");
|
||||
log(" do not map multipliers to MULT18X18D\n");
|
||||
log(" do not infer DSP multipliers\n");
|
||||
log("\n");
|
||||
log(" -no-rw-check\n");
|
||||
log(" marks all recognized read ports as \"return don't-care value on\n");
|
||||
|
@ -140,7 +165,9 @@ struct SynthLatticePass : public ScriptPass
|
|||
string top_opt, edif_file, json_file, family;
|
||||
bool noccu2, nodffe, nobram, nolutram, nowidelut, asyncprld, flatten, dff, retime, abc2, abc9, iopad, nodsp, no_rw_check, have_dsp;
|
||||
bool cmp2softlogic;
|
||||
string postfix, arith_map, brams_map, dsp_map;
|
||||
string postfix, arith_map, brams_map, dsp_map, cells_map, map_ram_default, widelut_abc;
|
||||
bool is_nexus;
|
||||
std::vector<DSPRule> dsp_rules;
|
||||
|
||||
void clear_flags() override
|
||||
{
|
||||
|
@ -168,6 +195,10 @@ struct SynthLatticePass : public ScriptPass
|
|||
dsp_map = "";
|
||||
have_dsp = false;
|
||||
cmp2softlogic = false;
|
||||
is_nexus = false;
|
||||
map_ram_default = "";
|
||||
cells_map = "";
|
||||
widelut_abc = "4:7";
|
||||
}
|
||||
|
||||
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||
|
@ -175,6 +206,7 @@ struct SynthLatticePass : public ScriptPass
|
|||
string run_from, run_to;
|
||||
bool force_abc9 = false;
|
||||
bool force_widelut = false;
|
||||
bool force_iopad = false;
|
||||
clear_flags();
|
||||
|
||||
size_t argidx;
|
||||
|
@ -266,6 +298,12 @@ struct SynthLatticePass : public ScriptPass
|
|||
}
|
||||
if (args[argidx] == "-iopad") {
|
||||
iopad = true;
|
||||
force_iopad = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-noiopad") {
|
||||
iopad = false;
|
||||
force_iopad = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-nodsp") {
|
||||
|
@ -292,7 +330,9 @@ struct SynthLatticePass : public ScriptPass
|
|||
arith_map = "_ccu2c";
|
||||
brams_map = "_16kd";
|
||||
dsp_map = "_18x18";
|
||||
dsp_rules = dsp_rules_ecp5;
|
||||
have_dsp = true;
|
||||
cells_map = "_trellis";
|
||||
} else if (family == "xo2" ||
|
||||
family == "xo3" ||
|
||||
family == "xo3d" /* ||
|
||||
|
@ -300,9 +340,24 @@ struct SynthLatticePass : public ScriptPass
|
|||
postfix = "_" + family;
|
||||
arith_map = "_ccu2d";
|
||||
brams_map = "_8kc";
|
||||
cells_map = "_trellis";
|
||||
have_dsp = false;
|
||||
if (!force_widelut) nowidelut = true;
|
||||
if (!force_abc9) abc9 = false;
|
||||
} else if (family == "lifcl" ||
|
||||
family == "lfd2nx") {
|
||||
is_nexus = true;
|
||||
postfix = "_nexus";
|
||||
arith_map = "_nexus";
|
||||
brams_map = "_nexus";
|
||||
dsp_map = "_nexus";
|
||||
dsp_rules = dsp_rules_nexus;
|
||||
have_dsp = true;
|
||||
map_ram_default = " -no-auto-huge";
|
||||
cells_map = "_nexus";
|
||||
widelut_abc = "4:5";
|
||||
if (!force_iopad) iopad = true;
|
||||
if (!force_abc9) abc9 = false;
|
||||
/* } else if (family == "xo" ||
|
||||
family == "pm") {
|
||||
} else if (family == "xp" ||
|
||||
|
@ -366,10 +421,19 @@ struct SynthLatticePass : public ScriptPass
|
|||
run("techmap -map +/cmp2lut.v -D LUT_WIDTH=4");
|
||||
run("opt_expr");
|
||||
run("opt_clean");
|
||||
if (have_dsp && !nodsp) {
|
||||
run("techmap -map +/mul2dsp.v -map +/lattice/dsp_map" + dsp_map + ".v -D DSP_A_MAXWIDTH=18 -D DSP_B_MAXWIDTH=18 -D DSP_A_MINWIDTH=2 -D DSP_B_MINWIDTH=2 -D DSP_NAME=$__MUL18X18", "(unless -nodsp)");
|
||||
run("chtype -set $mul t:$__soft_mul", "(unless -nodsp)");
|
||||
|
||||
if (help_mode) {
|
||||
run("techmap -map +/mul2dsp.v [...]", "(unless -nodsp)");
|
||||
run("techmap -map +/lattice/dsp_map" + dsp_map + ".v", "(unless -nodsp)");
|
||||
} else if (have_dsp && !nodsp) {
|
||||
for (const auto &rule : dsp_rules) {
|
||||
run(stringf("techmap -map +/mul2dsp.v -D DSP_A_MAXWIDTH=%d -D DSP_B_MAXWIDTH=%d -D DSP_A_MINWIDTH=%d -D DSP_B_MINWIDTH=%d -D DSP_NAME=%s",
|
||||
rule.a_maxwidth, rule.b_maxwidth, rule.a_minwidth, rule.b_minwidth, rule.prim.c_str()));
|
||||
run("chtype -set $mul t:$__soft_mul");
|
||||
}
|
||||
run("techmap -map +/lattice/dsp_map" + dsp_map + ".v");
|
||||
}
|
||||
|
||||
run("alumacc");
|
||||
run("opt");
|
||||
run("memory -nomap" + no_rw_check_opt);
|
||||
|
@ -378,15 +442,20 @@ struct SynthLatticePass : public ScriptPass
|
|||
|
||||
if (check_label("map_ram"))
|
||||
{
|
||||
std::string args = "";
|
||||
std::string args = map_ram_default;
|
||||
if (nobram)
|
||||
args += " -no-auto-block";
|
||||
if (nolutram)
|
||||
args += " -no-auto-distributed";
|
||||
if (help_mode)
|
||||
args += " [-no-auto-block] [-no-auto-distributed]";
|
||||
run("memory_libmap -lib +/lattice/lutrams.txt -lib +/lattice/brams" + brams_map + ".txt" + args, "(-no-auto-block if -nobram, -no-auto-distributed if -nolutram)");
|
||||
run("techmap -map +/lattice/lutrams_map.v -map +/lattice/brams_map" + brams_map + ".v");
|
||||
if (!is_nexus) {
|
||||
run("memory_libmap -lib +/lattice/lutrams" + cells_map + ".txt -lib +/lattice/brams" + brams_map + ".txt" + args, "(-no-auto-block if -nobram, -no-auto-distributed if -nolutram)");
|
||||
run("techmap -map +/lattice/lutrams_map" + cells_map + ".v -map +/lattice/brams_map" + brams_map + ".v");
|
||||
} else {
|
||||
run("memory_libmap -lib +/lattice/lutrams" + cells_map + ".txt -lib +/lattice/brams" + brams_map + ".txt -lib +/lattice/lrams_nexus.txt" + args, "(-no-auto-block if -nobram, -no-auto-distributed if -nolutram)");
|
||||
run("techmap -map +/lattice/lutrams_map" + cells_map + ".v -map +/lattice/brams_map" + brams_map + ".v -map +/lattice/lrams_map_nexus.v");
|
||||
}
|
||||
}
|
||||
|
||||
if (check_label("map_ffram"))
|
||||
|
@ -415,27 +484,37 @@ struct SynthLatticePass : public ScriptPass
|
|||
if (check_label("map_ffs"))
|
||||
{
|
||||
run("opt_clean");
|
||||
std::string dfflegalize_args = " -cell $_DFF_?_ 01 -cell $_DFF_?P?_ r -cell $_SDFF_?P?_ r";
|
||||
if (help_mode) {
|
||||
dfflegalize_args += " [-cell $_DFFE_??_ 01 -cell $_DFFE_?P??_ r -cell $_SDFFE_?P??_ r]";
|
||||
} else if (!nodffe) {
|
||||
dfflegalize_args += " -cell $_DFFE_??_ 01 -cell $_DFFE_?P??_ r -cell $_SDFFE_?P??_ r";
|
||||
}
|
||||
if (help_mode) {
|
||||
dfflegalize_args += " [-cell $_ALDFF_?P_ x -cell $_ALDFFE_?P?_ x] [-cell $_DLATCH_?_ x]";
|
||||
} else if (asyncprld) {
|
||||
dfflegalize_args += " -cell $_ALDFF_?P_ x -cell $_ALDFFE_?P?_ x";
|
||||
if (!is_nexus) {
|
||||
std::string dfflegalize_args = " -cell $_DFF_?_ 01 -cell $_DFF_?P?_ r -cell $_SDFF_?P?_ r";
|
||||
if (help_mode) {
|
||||
dfflegalize_args += " [-cell $_DFFE_??_ 01 -cell $_DFFE_?P??_ r -cell $_SDFFE_?P??_ r]";
|
||||
} else if (!nodffe) {
|
||||
dfflegalize_args += " -cell $_DFFE_??_ 01 -cell $_DFFE_?P??_ r -cell $_SDFFE_?P??_ r";
|
||||
}
|
||||
if (help_mode) {
|
||||
dfflegalize_args += " [-cell $_ALDFF_?P_ x -cell $_ALDFFE_?P?_ x] [-cell $_DLATCH_?_ x]";
|
||||
} else if (asyncprld) {
|
||||
dfflegalize_args += " -cell $_ALDFF_?P_ x -cell $_ALDFFE_?P?_ x";
|
||||
} else {
|
||||
dfflegalize_args += " -cell $_DLATCH_?_ x";
|
||||
}
|
||||
run("dfflegalize" + dfflegalize_args, "($_ALDFF_*_ only if -asyncprld, $_DLATCH_* only if not -asyncprld, $_*DFFE_* only if not -nodffe)");
|
||||
} else {
|
||||
dfflegalize_args += " -cell $_DLATCH_?_ x";
|
||||
}
|
||||
run("dfflegalize" + dfflegalize_args, "($_ALDFF_*_ only if -asyncprld, $_DLATCH_* only if not -asyncprld, $_*DFFE_* only if not -nodffe)");
|
||||
std::string dfflegalize_args = " -cell $_DFF_P_ 01 -cell $_DFF_PP?_ r -cell $_SDFF_PP?_ r -cell $_DLATCH_?_ x";
|
||||
if (help_mode) {
|
||||
dfflegalize_args += " [-cell $_DFFE_PP_ 01 -cell $_DFFE_PP?P_ r -cell $_SDFFE_PP?P_ r]";
|
||||
} else if (!nodffe) {
|
||||
dfflegalize_args += " -cell $_DFFE_PP_ 01 -cell $_DFFE_PP?P_ r -cell $_SDFFE_PP?P_ r";
|
||||
}
|
||||
run("dfflegalize" + dfflegalize_args, "($_*DFFE_* only if not -nodffe)");
|
||||
}
|
||||
run("opt_merge");
|
||||
if ((abc9 && dff) || help_mode)
|
||||
run("zinit -all w:* t:$_DFF_?_ t:$_DFFE_??_ t:$_SDFF*", "(only if -abc9 and -dff)");
|
||||
run("techmap -D NO_LUT -map +/lattice/cells_map.v");
|
||||
run("techmap -D NO_LUT -map +/lattice/cells_map" + cells_map + ".v");
|
||||
run("opt_expr -undriven -mux_undef");
|
||||
run("simplemap");
|
||||
run("lattice_gsr");
|
||||
if (!is_nexus) run("lattice_gsr");
|
||||
run("attrmvcp -copy -attr syn_useioff");
|
||||
run("opt_clean");
|
||||
}
|
||||
|
@ -466,7 +545,7 @@ struct SynthLatticePass : public ScriptPass
|
|||
if (nowidelut)
|
||||
abc_args += " -lut 4";
|
||||
else
|
||||
abc_args += " -lut 4:7";
|
||||
abc_args += " -lut " + widelut_abc;
|
||||
if (dff)
|
||||
abc_args += " -dff";
|
||||
run("abc" + abc_args);
|
||||
|
@ -476,8 +555,14 @@ struct SynthLatticePass : public ScriptPass
|
|||
|
||||
if (check_label("map_cells"))
|
||||
{
|
||||
run("techmap -map +/lattice/cells_map.v");
|
||||
run("opt_lut_ins -tech lattice");
|
||||
run("techmap -map +/lattice/cells_map" + cells_map + ".v");
|
||||
if (is_nexus) {
|
||||
// This is needed for Radiant, but perhaps not optimal for nextpnr...
|
||||
run("setundef -zero");
|
||||
run("hilomap -singleton -hicell VHI Z -locell VLO Z");
|
||||
} else {
|
||||
run("opt_lut_ins -tech lattice");
|
||||
}
|
||||
run("clean");
|
||||
}
|
||||
|
||||
|
@ -504,6 +589,33 @@ struct SynthLatticePass : public ScriptPass
|
|||
}
|
||||
} SynthLatticePass;
|
||||
|
||||
struct SynthNexusPass : public Pass
|
||||
{
|
||||
SynthNexusPass() : Pass("synth_nexus", "synthesis for Nexus FPGAs") { }
|
||||
|
||||
void help() override
|
||||
{
|
||||
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
|
||||
log("\n");
|
||||
log(" synth_nexus [options]\n");
|
||||
log("\n");
|
||||
log("This command runs synthesis for Nexus FPGAs.\n");
|
||||
log("\n");
|
||||
log("This is a wrapper pass, for details take a look at help message for synth_lattice.\n");
|
||||
log("\n");
|
||||
}
|
||||
|
||||
void execute(std::vector<std::string> args, RTLIL::Design *design) override
|
||||
{
|
||||
args[0] = "synth_lattice";
|
||||
args.insert(args.begin()+1, std::string());
|
||||
args.insert(args.begin()+1, std::string());
|
||||
args[1] = "-family";
|
||||
args[2] = "lifcl";
|
||||
Pass::call(design, args);
|
||||
}
|
||||
} SynthNexusPass;
|
||||
|
||||
struct SynthEcp5Pass : public Pass
|
||||
{
|
||||
SynthEcp5Pass() : Pass("synth_ecp5", "synthesis for ECP5 FPGAs") { }
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue