-
Notifications
You must be signed in to change notification settings - Fork 895
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add synth_nanoxplore for NanoXplore FPGAs
- Loading branch information
1 parent
2f901a8
commit 1c1f19b
Showing
33 changed files
with
26,671 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
|
||
OBJS += techlibs/nanoxplore/synth_nanoxplore.o | ||
|
||
# Techmap | ||
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/abc9_map.v)) | ||
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/abc9_model.v)) | ||
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/abc9_unmap.v)) | ||
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/arith_map.v)) | ||
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/cells_map.v)) | ||
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/cells_sim.v)) | ||
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/drams.txt)) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
// This file exists to map purely-synchronous flops to ABC9 flops, while | ||
// mapping flops with asynchronous-clear as boxes, this is because ABC9 | ||
// doesn't support asynchronous-clear flops in sequential synthesis. | ||
|
||
module NX_DFF(input I, CK, L, R, output O); | ||
|
||
parameter dff_ctxt = 1'bx; | ||
parameter dff_edge = 1'b0; | ||
parameter dff_init = 1'b0; | ||
parameter dff_load = 1'b0; | ||
parameter dff_sync = 1'b0; | ||
parameter dff_type = 1'b0; | ||
|
||
localparam RESETLESS = !dff_init; | ||
localparam SYNC_RESET = dff_init && dff_sync; | ||
|
||
if (RESETLESS || SYNC_RESET) begin | ||
$__NX_DFF_SYNCONLY #(.dff_ctxt(dff_ctxt), .dff_edge(dff_edge), .dff_init(dff_init), .dff_load(dff_load), .dff_type(dff_type)) _TECHMAP_REPLACE_ (.I(I), .CK(CK), .L(L), .R(R), .O(O)); | ||
end else | ||
wire _TECHMAP_FAIL_ = 1; | ||
|
||
endmodule |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
// This is a purely-synchronous flop, that ABC9 can use for sequential synthesis. | ||
(* abc9_flop, lib_whitebox *) | ||
module \$__NX_DFF_SYNCONLY (input I, CK, L, R, output reg O); | ||
|
||
parameter dff_ctxt = 1'bx; | ||
parameter dff_edge = 1'b0; | ||
parameter dff_init = 1'b0; | ||
parameter dff_load = 1'b0; | ||
parameter dff_type = 1'b0; | ||
|
||
specify | ||
(posedge CK => (O : I)) = (247, 281); | ||
$setup(I, posedge CK, 232); | ||
$setup(L, posedge CK, 231); | ||
$setup(R, posedge CK, 209); | ||
endspecify | ||
|
||
initial begin | ||
O = dff_ctxt; | ||
end | ||
|
||
wire clock = CK ^ dff_edge; | ||
wire load = (dff_type == 2) ? (dff_load ? L : 1'bx) : dff_type; | ||
wire sync_reset = dff_init && R; | ||
|
||
always @(posedge clock) | ||
if (sync_reset) O <= load; | ||
else O <= I; | ||
|
||
endmodule |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
// This is a purely-synchronous flop, that ABC9 can use for sequential synthesis. | ||
module \$__NX_DFF_SYNCONLY (input I, CK, L, R, output O); | ||
parameter dff_ctxt = 1'bx; | ||
parameter dff_edge = 1'b0; | ||
parameter dff_init = 1'b0; | ||
parameter dff_load = 1'b0; | ||
parameter dff_type = 1'b0; | ||
NX_DFF #(.dff_ctxt(dff_ctxt), .dff_edge(dff_edge), .dff_init(dff_init), .dff_load(dff_load), .dff_sync(1'b1), .dff_type(dff_type)) _TECHMAP_REPLACE_ (.I(I), .CK(CK), .L(L), .R(R), .O(O)); | ||
endmodule |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,71 @@ | ||
`default_nettype none | ||
|
||
(* techmap_celltype = "$alu" *) | ||
module _80_ecp5_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] 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_up4; | ||
input integer N; | ||
begin | ||
round_up4 = ((N + 3) / 4) * 4; | ||
end | ||
endfunction | ||
|
||
localparam Y_WIDTH4 = round_up4(Y_WIDTH); | ||
|
||
(* force_downto *) | ||
wire [Y_WIDTH4-1:0] AA = A_buf; | ||
(* force_downto *) | ||
wire [Y_WIDTH4-1:0] BB = BI ? ~B_buf : B_buf; | ||
(* force_downto *) | ||
wire [Y_WIDTH4-1:0] BX = B_buf; | ||
(* force_downto *) | ||
wire [Y_WIDTH4:0] C = {CO, CI}; | ||
(* force_downto *) | ||
wire [Y_WIDTH4-1:0] FCO, Y1; | ||
|
||
genvar i; | ||
generate for (i = 0; i < Y_WIDTH4; i = i + 4) begin:slice | ||
NX_CY cy_i ( | ||
.CI(C[i]), | ||
.A1(AA[i]), .A2(AA[i+1]), .A3(AA[i+2]), .A4(AA[i+3]), | ||
.B1(BB[i]), .B2(BB[i+1]), .B3(BB[i+2]), .B4(BB[i+3]), | ||
.S1(Y1[i]), .S2(Y1[i+1]), .S3(Y1[i+2]), .S4(Y1[i+3]), | ||
.CO(FCO[i]) | ||
); | ||
|
||
assign CO[i] = (AA[i] && BB[i]) || (C[i] && (AA[i] || BB[i])); | ||
if (i+1 < Y_WIDTH) | ||
assign CO[i+1] = (AA[i+1] && BB[i+1]) || (C[i+1] && (AA[i+1] || BB[i+1])); | ||
if (i+2 < Y_WIDTH) | ||
assign CO[i+2] = (AA[i+2] && BB[i+2]) || (C[i+2] && (AA[i+2] || BB[i+2])); | ||
if (i+3 < Y_WIDTH) | ||
assign CO[i+3] = FCO[i]; | ||
|
||
end endgenerate | ||
|
||
assign X = AA ^ BB; | ||
assign Y = Y1[Y_WIDTH-1:0]; | ||
endmodule |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
`default_nettype none | ||
|
||
module \$lut (A, Y); | ||
parameter WIDTH = 0; | ||
parameter LUT = 0; | ||
|
||
(* force_downto *) | ||
input [WIDTH-1:0] A; | ||
output Y; | ||
|
||
generate | ||
if (WIDTH == 1) begin | ||
localparam [15:0] INIT = {{8{LUT[1]}}, {8{LUT[0]}}}; | ||
NX_LUT #(.lut_table(INIT)) _TECHMAP_REPLACE_ (.O(Y), | ||
.I1(1'b0), .I2(1'b0), .I3(1'b0), .I4(A[0])); | ||
end else | ||
if (WIDTH == 2) begin | ||
localparam [15:0] INIT = {{4{LUT[3]}}, {4{LUT[2]}}, {4{LUT[1]}}, {4{LUT[0]}}}; | ||
NX_LUT #(.lut_table(INIT)) _TECHMAP_REPLACE_ (.O(Y), | ||
.I1(1'b0), .I2(1'b0), .I3(A[0]), .I4(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]}}}; | ||
NX_LUT #(.lut_table(INIT)) _TECHMAP_REPLACE_ (.O(Y), | ||
.I1(1'b0), .I2(A[0]), .I3(A[1]), .I4(A[2])); | ||
end else | ||
if (WIDTH == 4) begin | ||
NX_LUT #(.lut_table(LUT)) _TECHMAP_REPLACE_ (.O(Y), | ||
.I1(A[0]), .I2(A[1]), .I3(A[2]), .I4(A[3])); | ||
end else begin | ||
wire _TECHMAP_FAIL_ = 1; | ||
end | ||
endgenerate | ||
endmodule | ||
|
||
(* techmap_celltype = "$_DFF_[NP]P[01]_" *) | ||
module dff(input D, C, R, output Q); | ||
parameter _TECHMAP_CELLTYPE = "$_DFF_PP1_"; | ||
localparam dff_edge = _TECHMAP_CELLTYPE[6*8 +: 8] == "N"; | ||
localparam dff_type = _TECHMAP_CELLTYPE[8*8 +: 8] == "1"; | ||
wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; | ||
NX_DFF #(.dff_ctxt(1'b0), .dff_edge(dff_edge), .dff_init(1'b1), .dff_load(1'b0), .dff_sync(1'b0), .dff_type(dff_type)) _TECHMAP_REPLACE_ (.I(D), .CK(C), .L(1'b0), .R(R), .O(Q)); | ||
endmodule | ||
|
||
(* techmap_celltype = "$_ALDFF_[NP]P_" *) | ||
module aldff(input D, C, L, AD, output Q); | ||
parameter _TECHMAP_CELLTYPE = "$_ALDFF_PP_"; | ||
localparam dff_edge = _TECHMAP_CELLTYPE[8*8 +: 8] == "N"; | ||
wire _TECHMAP_REMOVEINIT_Q_ = 1'b1; | ||
NX_DFF #(.dff_ctxt(1'b0), .dff_edge(dff_edge), .dff_init(1'b1), .dff_load(1'b1), .dff_sync(1'b0), .dff_type(2)) _TECHMAP_REPLACE_ (.I(D), .CK(C), .L(AD), .R(L), .O(Q)); | ||
endmodule | ||
|
||
module \$_SDFF_PP0_ (input D, C, R, output Q); | ||
NX_DFF #(.dff_ctxt(1'b0), .dff_edge(1'b0), .dff_init(1'b1), .dff_load(1'b0), .dff_sync(1'b1), .dff_type(1'b0)) _TECHMAP_REPLACE_ (.I(D), .CK(C), .L(1'b0), .R(R), .O(Q)); | ||
endmodule | ||
|
||
module \$_SDFF_PP1_ (input D, C, R, output Q); | ||
NX_DFF #(.dff_ctxt(1'b0), .dff_edge(1'b0), .dff_init(1'b1), .dff_load(1'b0), .dff_sync(1'b1), .dff_type(1'b1)) _TECHMAP_REPLACE_ (.I(D), .CK(C), .L(1'b0), .R(R), .O(Q)); | ||
endmodule | ||
|
||
module \$_SDFF_NP0_ (input D, C, R, output Q); | ||
NX_DFF #(.dff_ctxt(1'b0), .dff_edge(1'b1), .dff_init(1'b1), .dff_load(1'b0), .dff_sync(1'b1), .dff_type(1'b0)) _TECHMAP_REPLACE_ (.I(D), .CK(C), .L(1'b0), .R(R), .O(Q)); | ||
endmodule | ||
|
||
module \$_SDFF_NP1_ (input D, C, R, output Q); | ||
NX_DFF #(.dff_ctxt(1'b0), .dff_edge(1'b1), .dff_init(1'b1), .dff_load(1'b0), .dff_sync(1'b1), .dff_type(1'b1)) _TECHMAP_REPLACE_ (.I(D), .CK(C), .L(1'b0), .R(R), .O(Q)); | ||
endmodule | ||
|
||
|
||
module $__NX_XRFB_64x18_ (input PORT_W_CLK, input [5:0] PORT_W_ADDR, PORT_R_ADDR, input [17:0] PORT_W_WR_DATA, input PORT_W_WR_EN, output [17:0] PORT_R_RD_DATA); | ||
parameter INIT = 1152'bx; | ||
parameter PORT_W_CLK_POL = 1'b1; | ||
NX_XRFB_64x18 #(.mem_ctxt(INIT), .wck_edge(~PORT_W_CLK_POL)) _TECHMAP_REPLACE_ (.WCK(PORT_W_CLK), .I(PORT_W_WR_DATA), .RA(PORT_R_ADDR), .WA(PORT_W_ADDR), .WE(PORT_W_WR_EN), .WEA(1'b1), .O(PORT_R_RD_DATA)); | ||
endmodule | ||
|
||
|
||
module $__NX_XRFB_32x36_ (input PORT_W_CLK, input [4:0] PORT_W_ADDR, PORT_R_ADDR, input [35:0] PORT_W_WR_DATA, input PORT_W_WR_EN, output [35:0] PORT_R_RD_DATA); | ||
parameter INIT = 1152'bx; | ||
parameter PORT_W_CLK_POL = 1'b1; | ||
NX_XRFB_32x36 #(.mem_ctxt(INIT), .wck_edge(~PORT_W_CLK_POL)) _TECHMAP_REPLACE_ (.WCK(PORT_W_CLK), .I(PORT_W_WR_DATA), .RA(PORT_R_ADDR), .WA(PORT_W_ADDR), .WE(PORT_W_WR_EN), .WEA(1'b1), .O(PORT_R_RD_DATA)); | ||
endmodule |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,145 @@ | ||
(* abc9_lut=1 *) | ||
module NX_LUT(input I1, I2, I3, I4, output O); | ||
|
||
parameter lut_table = 16'h0000; | ||
|
||
specify | ||
(I1 => O) = (117, 129); | ||
(I2 => O) = (112, 125); | ||
(I3 => O) = (61, 89); | ||
(I4 => O) = (61, 81); | ||
endspecify | ||
|
||
wire [7:0] s1 = I4 ? lut_table[15:8] : lut_table[7:0]; | ||
wire [3:0] s2 = I3 ? s1[7:4] : s1[3:0]; | ||
wire [1:0] s3 = I2 ? s2[3:2] : s2[1:0]; | ||
assign O = I1 ? s3[1] : s3[0]; | ||
|
||
endmodule | ||
|
||
(* abc9_box, lib_whitebox *) | ||
module NX_DFF(input I, CK, L, R, output reg O); | ||
|
||
parameter dff_ctxt = 1'bx; | ||
parameter dff_edge = 1'b0; | ||
parameter dff_init = 1'b0; | ||
parameter dff_load = 1'b0; | ||
parameter dff_sync = 1'b0; | ||
parameter dff_type = 1'b0; | ||
|
||
specify | ||
(posedge CK => (O : I)) = (247, 281); | ||
if (!dff_sync && dff_init && R) (R => O) = 0; | ||
if (!dff_sync && dff_init && dff_load && R) (L => O) = 0; | ||
$setup(I, posedge CK, 232); | ||
$setup(L, posedge CK, 231); | ||
$setup(R, posedge CK, 209); | ||
endspecify | ||
|
||
initial begin | ||
O = dff_ctxt; | ||
end | ||
|
||
wire clock = CK ^ dff_edge; | ||
wire load = (dff_type == 2) ? (dff_load ? L : 1'bx) : dff_type; | ||
wire async_reset = !dff_sync && dff_init && R; | ||
wire sync_reset = dff_sync && dff_init && R; | ||
|
||
always @(posedge clock, posedge async_reset) | ||
if (async_reset) O <= load; | ||
else if (sync_reset) O <= load; | ||
else O <= I; | ||
|
||
endmodule | ||
|
||
(* abc9_box, lib_whitebox *) | ||
module NX_CY(input A1, A2, A3, A4, B1, B2, B3, B4, (* abc9_carry *) input CI, output S1, S2, S3, S4, (* abc9_carry *) output CO); | ||
|
||
specify | ||
(A1 => CO) = (206, 266); | ||
(A2 => CO) = (210, 282); | ||
(A3 => CO) = (181, 253); | ||
(A4 => CO) = (137, 211); | ||
(B1 => CO) = (152, 205); | ||
(B2 => CO) = (154, 214); | ||
(B3 => CO) = (106, 166); | ||
(B4 => CO) = ( 89, 149); | ||
(CI => CO) = ( 40, 113); | ||
(A1 *> {S4, S3, S2, S1}) = (314, 325); | ||
(A2 *> {S4, S3, S2}) = (236, 248); | ||
(A3 *> {S4, S3}) = (226, 238); | ||
(A4 => S4) = (166, 179); | ||
(B1 *> {S4, S3, S2, S1}) = (262, 274); | ||
(B2 *> {S4, S3, S2}) = (184, 195); | ||
(B3 *> {S4, S3}) = (156, 166); | ||
(B4 => S4) = (105, 117); | ||
(CI *> {S4, S3, S2, S1}) = (268, 291); | ||
endspecify | ||
|
||
assign {CO, S4, S3, S2, S1} = {A4, A3, A2, A1} + {B4, B3, B2, B1} + CI; | ||
|
||
endmodule | ||
|
||
(* abc9_box, lib_whitebox *) | ||
module NX_XRFB_64x18(input WCK, input [17:0] I, input [5:0] RA, WA, input WE, WEA, output [17:0] O); | ||
|
||
parameter wck_edge = 1'b0; | ||
parameter mem_ctxt = 1152'b0; | ||
|
||
specify | ||
(WCK *> O) = 474; | ||
(RA *> O) = 2111; // good enough for now | ||
$setup(I, posedge WCK, 0); | ||
$setup(WA, posedge WCK, 0); | ||
$setup(WE, posedge WCK, 0); | ||
endspecify | ||
|
||
reg [17:0] mem [63:0]; | ||
|
||
integer i; | ||
initial begin | ||
for (i = 0; i < 64; i = i + 1) | ||
mem[i] = mem_ctxt[18*i +: 18]; | ||
end | ||
|
||
wire clock = WCK ^ wck_edge; | ||
|
||
always @(posedge clock) | ||
if (WE && WEA) | ||
mem[WA] <= I; | ||
|
||
assign O = mem[RA]; | ||
|
||
endmodule | ||
|
||
(* abc9_box, lib_whitebox *) | ||
module NX_XRFB_32x36(input WCK, input [35:0] I, input [4:0] RA, WA, input WE, WEA, output [35:0] O); | ||
|
||
parameter wck_edge = 1'b0; | ||
parameter mem_ctxt = 1152'b0; | ||
|
||
specify | ||
(WCK *> O) = 474; | ||
(RA *> O) = 2111; // good enough for now | ||
$setup(I, posedge WCK, 0); | ||
$setup(WA, posedge WCK, 0); | ||
$setup(WE, posedge WCK, 0); | ||
endspecify | ||
|
||
reg [35:0] mem [31:0]; | ||
|
||
integer i; | ||
initial begin | ||
for (i = 0; i < 32; i = i + 1) | ||
mem[i] = mem_ctxt[36*i +: 36]; | ||
end | ||
|
||
wire clock = WCK ^ wck_edge; | ||
|
||
always @(posedge clock) | ||
if (WE && WEA) | ||
mem[WA] <= I; | ||
|
||
assign O = mem[RA]; | ||
|
||
endmodule |
Oops, something went wrong.