3
0
Fork 0
mirror of https://github.com/YosysHQ/yosys synced 2025-04-07 09:55:20 +00:00

Merge pull request from YosysHQ/nanoxplore

NanoXplore synthesis
This commit is contained in:
Miodrag Milanović 2024-09-03 10:19:44 +02:00 committed by GitHub
commit 598d010349
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
44 changed files with 16161 additions and 0 deletions

View file

@ -877,6 +877,7 @@ endif
+cd tests/arch/anlogic && bash run-test.sh $(SEEDOPT)
+cd tests/arch/gowin && bash run-test.sh $(SEEDOPT)
+cd tests/arch/intel_alm && bash run-test.sh $(SEEDOPT)
+cd tests/arch/nanoxplore && bash run-test.sh $(SEEDOPT)
+cd tests/arch/nexus && bash run-test.sh $(SEEDOPT)
+cd tests/arch/quicklogic/pp3 && bash run-test.sh $(SEEDOPT)
+cd tests/arch/quicklogic/qlf_k6n10f && bash run-test.sh $(SEEDOPT)

View file

@ -0,0 +1,31 @@
OBJS += techlibs/nanoxplore/synth_nanoxplore.o
OBJS += techlibs/nanoxplore/nx_carry.o
# Techmap
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/arith_map.v))
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/brams_init.vh))
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/brams_map.v))
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/brams.txt))
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/cells_bb.v))
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/cells_bb_l.v))
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/cells_bb_m.v))
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/cells_bb_u.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/cells_sim_l.v))
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/cells_sim_m.v))
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/cells_sim_u.v))
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/cells_wrap.v))
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/cells_wrap_l.v))
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/cells_wrap_m.v))
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/cells_wrap_u.v))
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/io_map.v))
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/latches_map.v))
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/rf_init.vh))
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/rf_rams_l.txt))
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/rf_rams_m.txt))
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/rf_rams_u.txt))
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/rf_rams_map_l.v))
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/rf_rams_map_m.v))
$(eval $(call add_share_file,share/nanoxplore,techlibs/nanoxplore/rf_rams_map_u.v))

View file

@ -0,0 +1,76 @@
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2024 Miodrag Milanovic <micko@yosyshq.com>
*
* 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_nx_cy_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;
(* force_downto *)
wire [Y_WIDTH-1:0] COx;
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));
(* force_downto *)
wire [Y_WIDTH-1:0] AA = A_buf;
(* force_downto *)
wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf;
genvar i;
generate for (i = 0; i < Y_WIDTH; i = i + 1) begin: slice
NX_CY_1BIT #(.first(i==0))
alu_i (
.CI(i==0 ? CI : COx[i-1]),
.A(AA[i]),
.B(BB[i]),
.S(Y[i]),
.CO(COx[i])
);
end: slice
endgenerate
NX_CY_1BIT alu_cout(
.CI(COx[Y_WIDTH-1]),
.A(1'b0),
.B(1'b0),
.S(CO[Y_WIDTH-1])
);
/* End implementation */
assign X = AA ^ BB;
endmodule

View file

@ -0,0 +1,50 @@
ram block $__NX_RAM_ {
option "STD_MODE" "NOECC_48kx1" {
# only 32k used
abits 15;
widths 1 per_port;
}
option "STD_MODE" "NOECC_24kx2" {
# only 16k used
abits 14;
widths 2 per_port;
}
ifndef IS_NG_MEDIUM {
option "STD_MODE" "NOECC_16kx3" {
abits 14;
widths 3 per_port;
}
}
option "STD_MODE" "NOECC_12kx4" {
# only 8k used
abits 13;
widths 4 per_port;
}
ifndef IS_NG_MEDIUM {
option "STD_MODE" "NOECC_8kx6" {
abits 13;
widths 6 per_port;
}
}
option "STD_MODE" "NOECC_6kx8" {
# only 4k used
abits 12;
widths 8 per_port;
}
option "STD_MODE" "NOECC_4kx12" {
abits 12;
widths 12 per_port;
}
option "STD_MODE" "NOECC_2kx24" {
abits 11;
widths 24 per_port;
}
cost 64;
init no_undef;
port srsw "A" "B" {
clock anyedge;
clken;
rdwr no_change;
rdinit none;
}
}

View file

@ -0,0 +1,23 @@
function [409600-1:0] bram_init_to_string;
input [49152-1:0] array;
input integer blocks;
input integer width;
reg [409600-1:0] temp; // (49152+2048)*8 48K bit data + 2k commas
reg [24-1:0] temp2;
integer i;
integer j;
begin
temp = "";
for (i = 0; i < 2048; i = i + 1) begin
if (i != 0) begin
temp = {temp, ","};
end
temp2 = 24'b0;
for (j = 0; j < blocks; j = j + 1) begin
temp2[j*width +: width] = array[{j, i[10:0]}*width +: width];
end
temp = {temp, $sformatf("%b",temp2[23:0])};
end
bram_init_to_string = temp;
end
endfunction

View file

@ -0,0 +1,84 @@
module $__NX_RAM_ (...);
parameter INIT = 0;
parameter OPTION_STD_MODE = "NOECC_24kx2";
parameter PORT_A_WIDTH = 24;
parameter PORT_B_WIDTH = 24;
parameter PORT_A_CLK_POL = 1;
input PORT_A_CLK;
input PORT_A_CLK_EN;
input PORT_A_WR_EN;
input [15:0] PORT_A_ADDR;
input [PORT_A_WIDTH-1:0] PORT_A_WR_DATA;
wire [24-1:0] A_DATA;
output [PORT_A_WIDTH-1:0] PORT_A_RD_DATA;
parameter PORT_B_CLK_POL = 1;
input PORT_B_CLK;
input PORT_B_CLK_EN;
input PORT_B_WR_EN;
input [15:0] PORT_B_ADDR;
input [PORT_B_WIDTH-1:0] PORT_B_WR_DATA;
wire [24-1:0] B_DATA;
output [PORT_B_WIDTH-1:0] PORT_B_RD_DATA;
`include "brams_init.vh"
localparam raw_config1_val = OPTION_STD_MODE == "NOECC_48kx1" ? 16'b0000000000000000:
OPTION_STD_MODE == "NOECC_24kx2" ? 16'b0000001001001001:
OPTION_STD_MODE == "NOECC_16kx3" ? 16'b0000110110110110:
OPTION_STD_MODE == "NOECC_12kx4" ? 16'b0000010010010010:
OPTION_STD_MODE == "NOECC_8kx6" ? 16'b0000111111111111:
OPTION_STD_MODE == "NOECC_6kx8" ? 16'b0000011011011011:
OPTION_STD_MODE == "NOECC_4kx12" ? 16'b0000100100100100:
OPTION_STD_MODE == "NOECC_2kx24" ? 16'b0000101101101101:
16'bx;
localparam A_REPEAT = 24 / PORT_A_WIDTH;
localparam B_REPEAT = 24 / PORT_B_WIDTH;
assign A_DATA = {A_REPEAT{PORT_A_WR_DATA[PORT_A_WIDTH-1:0]}};
assign B_DATA = {B_REPEAT{PORT_B_WR_DATA[PORT_B_WIDTH-1:0]}};
NX_RAM_WRAP #(
.std_mode(OPTION_STD_MODE),
.mcka_edge(PORT_A_CLK_POL == 1 ? 1'b0 : 1'b1),
.mckb_edge(PORT_B_CLK_POL == 1 ? 1'b0 : 1'b1),
.pcka_edge(PORT_A_CLK_POL == 1 ? 1'b0 : 1'b1),
.pckb_edge(PORT_B_CLK_POL == 1 ? 1'b0 : 1'b1),
.raw_config0(4'b0000),
.raw_config1(raw_config1_val[15:0]),
.mem_ctxt($sformatf("%s",bram_init_to_string(INIT,A_REPEAT,PORT_A_WIDTH))),
) _TECHMAP_REPLACE_ (
.ACK(PORT_A_CLK),
//.ACKS(PORT_A_CLK),
//.ACKD(), // Not used in Non-ECC modes
//.ACKR(),
//.AR(),
//.ACOR(),
//.AERR(),
.ACS(PORT_A_CLK_EN),
.AWE(PORT_A_WR_EN),
.AA(PORT_A_ADDR),
.AI(A_DATA),
.AO(PORT_A_RD_DATA),
.BCK(PORT_B_CLK),
//.BCKC(PORT_B_CLK),
//.BCKD(), // Not used in Non-ECC modes
//.BCKR()
//.BR(),
//.BCOR(),
//.BERR(),
.BCS(PORT_B_CLK_EN),
.BWE(PORT_B_WR_EN),
.BA(PORT_B_ADDR),
.BI(B_DATA),
.BO(PORT_B_RD_DATA)
);
endmodule

View file

@ -0,0 +1,127 @@
// NX_RAM related
(* blackbox *)
module NX_ECC(CKD, CHK, COR, ERR);
input CHK;
input CKD;
output COR;
output ERR;
endmodule
//TODO
(* blackbox *)
module NX_IOM_BIN2GRP(GS, DS, GVON, GVIN, GVDN, PA, LA);
input [1:0] DS;
input GS;
output [2:0] GVDN;
output [2:0] GVIN;
output [2:0] GVON;
input [5:0] LA;
output [3:0] PA;
endmodule
//TODO
(* blackbox *)
module NX_SER(FCK, SCK, R, IO, DCK, DRL, I, DS, DRA, DRI, DRO, DID);
input DCK;
output [5:0] DID;
input [5:0] DRA;
input [5:0] DRI;
input DRL;
output [5:0] DRO;
input [1:0] DS;
input FCK;
input [4:0] I;
output IO;
input R;
input SCK;
parameter data_size = 5;
parameter differential = "";
parameter drive = "";
parameter location = "";
parameter locked = 1'b0;
parameter outputCapacity = "";
parameter outputDelayLine = "";
parameter slewRate = "";
parameter spath_dynamic = 1'b0;
parameter standard = "";
endmodule
//TODO
(* blackbox *)
module NX_DES(FCK, SCK, R, IO, DCK, DRL, DIG, FZ, FLD, FLG, O, DS, DRA, DRI, DRO, DID);
input DCK;
output [5:0] DID;
input DIG;
input [5:0] DRA;
input [5:0] DRI;
input DRL;
output [5:0] DRO;
input [1:0] DS;
input FCK;
output FLD;
output FLG;
input FZ;
input IO;
output [4:0] O;
input R;
input SCK;
parameter data_size = 5;
parameter differential = "";
parameter dpath_dynamic = 1'b0;
parameter drive = "";
parameter inputDelayLine = "";
parameter inputSignalSlope = "";
parameter location = "";
parameter locked = 1'b0;
parameter standard = "";
parameter termination = "";
parameter terminationReference = "";
parameter turbo = "";
parameter weakTermination = "";
endmodule
//TODO
(* blackbox *)
module NX_SERDES(FCK, SCK, RTX, RRX, CI, CCK, CL, CR, IO, DCK, DRL, DIG, FZ, FLD, FLG, I, O, DS, DRA, DRI, DRO
, DID);
input CCK;
input CI;
input CL;
input CR;
input DCK;
output [5:0] DID;
input DIG;
input [5:0] DRA;
input [5:0] DRI;
input DRL;
output [5:0] DRO;
input [1:0] DS;
input FCK;
output FLD;
output FLG;
input FZ;
input [4:0] I;
inout IO;
output [4:0] O;
input RRX;
input RTX;
input SCK;
parameter cpath_registered = 1'b0;
parameter data_size = 5;
parameter differential = "";
parameter dpath_dynamic = 1'b0;
parameter drive = "";
parameter inputDelayLine = "";
parameter inputSignalSlope = "";
parameter location = "";
parameter locked = 1'b0;
parameter outputCapacity = "";
parameter outputDelayLine = "";
parameter slewRate = "";
parameter spath_dynamic = 1'b0;
parameter standard = "";
parameter termination = "";
parameter terminationReference = "";
parameter turbo = "";
parameter weakTermination = "";
endmodule

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,95 @@
`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 = {{2{LUT[1:0]}}, {2{LUT[1:0]}}, {2{LUT[1:0]}}, {2{LUT[1:0]}},
{2{LUT[1:0]}}, {2{LUT[1:0]}}, {2{LUT[1:0]}}, {2{LUT[1:0]}}};
NX_LUT #(.lut_table(INIT)) _TECHMAP_REPLACE_ (.O(Y),
.I1(A[0]), .I2(1'b0), .I3(1'b0), .I4(1'b0));
end else
if (WIDTH == 2) begin
localparam [15:0] INIT = {{4{LUT[3:0]}}, {4{LUT[3:0]}}, {4{LUT[3:0]}}, {4{LUT[3:0]}}};
NX_LUT #(.lut_table(INIT)) _TECHMAP_REPLACE_ (.O(Y),
.I1(A[0]), .I2(A[1]), .I3(1'b0), .I4(1'b0), );
end else
if (WIDTH == 3) begin
localparam [15:0] INIT = {{8{LUT[7:0]}}, {8{LUT[7:0]}}};
NX_LUT #(.lut_table(INIT)) _TECHMAP_REPLACE_ (.O(Y),
.I1(A[0]), .I2(A[1]), .I3(A[2]), .I4(1'b0));
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_xxxx_ (input D, C, R, output Q);
parameter _TECHMAP_CELLTYPE_ = "";
localparam dff_edge = _TECHMAP_CELLTYPE_[3*8 +: 8] == "N";
localparam dff_type = _TECHMAP_CELLTYPE_[1*8 +: 8] == "1";
wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
NX_DFF #(.dff_ctxt(dff_type), .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'b1), .R(R), .O(Q));
endmodule
(* techmap_celltype = "$_SDFF_[NP]P[01]_" *)
module \$_SDFF_xxxx_ (input D, C, R, output Q);
parameter _TECHMAP_CELLTYPE_ = "";
localparam dff_edge = _TECHMAP_CELLTYPE_[3*8 +: 8] == "N";
localparam dff_type = _TECHMAP_CELLTYPE_[1*8 +: 8] == "1";
wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
NX_DFF #(.dff_ctxt(dff_type), .dff_edge(dff_edge), .dff_init(1'b1), .dff_load(1'b0), .dff_sync(1'b1), .dff_type(dff_type)) _TECHMAP_REPLACE_ (.I(D), .CK(C), .L(1'b1), .R(R), .O(Q));
endmodule
(* techmap_celltype = "$_DFFE_[NP]P[01]P_" *)
module \$_DFFE_xxxx_ (input D, C, R, E, output Q);
parameter _TECHMAP_CELLTYPE_ = "";
localparam dff_edge = _TECHMAP_CELLTYPE_[4*8 +: 8] == "N";
localparam dff_type = _TECHMAP_CELLTYPE_[2*8 +: 8] == "1";
wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
NX_DFF #(.dff_ctxt(dff_type), .dff_edge(dff_edge), .dff_init(1'b1), .dff_load(1'b1), .dff_sync(1'b0), .dff_type(dff_type)) _TECHMAP_REPLACE_ (.I(D), .CK(C), .L(E), .R(R), .O(Q));
endmodule
(* techmap_celltype = "$_SDFFE_[NP]P[01]P_" *)
module \$_SDFFE_xxxx_ (input D, C, R, E, output Q);
parameter _TECHMAP_CELLTYPE_ = "";
localparam dff_edge = _TECHMAP_CELLTYPE_[4*8 +: 8] == "N";
localparam dff_type = _TECHMAP_CELLTYPE_[2*8 +: 8] == "1";
wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
NX_DFF #(.dff_ctxt(dff_type), .dff_edge(dff_edge), .dff_init(1'b1), .dff_load(1'b1), .dff_sync(1'b1), .dff_type(dff_type)) _TECHMAP_REPLACE_ (.I(D), .CK(C), .L(E), .R(R), .O(Q));
endmodule
module \$_DFF_P_ (input D, C, output Q);
parameter _TECHMAP_WIREINIT_Q_ = 1'b0;
wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
NX_DFF #(.dff_ctxt(_TECHMAP_WIREINIT_Q_), .dff_edge(1'b0), .dff_init(1'b0), .dff_load(1'b0), .dff_sync(1'b0), .dff_type(1'b0)) _TECHMAP_REPLACE_ (.I(D), .CK(C), .L(1'b1), .R(1'b0), .O(Q));
endmodule
module \$_DFF_N_ (input D, C, output Q);
parameter _TECHMAP_WIREINIT_Q_ = 1'b0;
wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
NX_DFF #(.dff_ctxt(_TECHMAP_WIREINIT_Q_), .dff_edge(1'b1), .dff_init(1'b0), .dff_load(1'b0), .dff_sync(1'b0), .dff_type(1'b0)) _TECHMAP_REPLACE_ (.I(D), .CK(C), .L(1'b1), .R(1'b0), .O(Q));
endmodule
module \$_DFFE_PP_ (input D, C, E, output Q);
parameter _TECHMAP_WIREINIT_Q_ = 1'b0;
wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
NX_DFF #(.dff_ctxt(_TECHMAP_WIREINIT_Q_), .dff_edge(1'b0), .dff_init(1'b0), .dff_load(1'b1), .dff_sync(1'b0), .dff_type(1'b0)) _TECHMAP_REPLACE_ (.I(D), .CK(C), .L(E), .R(1'b0), .O(Q));
endmodule
module \$_DFFE_NP_ (input D, C, E, output Q);
parameter _TECHMAP_WIREINIT_Q_ = 1'b0;
wire _TECHMAP_REMOVEINIT_Q_ = 1'b1;
NX_DFF #(.dff_ctxt(_TECHMAP_WIREINIT_Q_), .dff_edge(1'b1), .dff_init(1'b0), .dff_load(1'b1), .dff_sync(1'b0), .dff_type(1'b0)) _TECHMAP_REPLACE_ (.I(D), .CK(C), .L(E), .R(1'b0), .O(Q));
endmodule

View file

@ -0,0 +1,421 @@
(* abc9_lut=1 *)
module NX_LUT(input I1, I2, I3, I4, output O);
parameter lut_table = 16'h0000;
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;
initial begin
O = dff_ctxt;
end
wire clock = CK ^ dff_edge;
wire load = dff_load ? L : 1'b1;
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 <= dff_type;
else if (sync_reset) O <= dff_type;
else if (load) O <= I;
endmodule
(* abc9_box, lib_whitebox *)
module NX_DFR(input I, CK, L, R, output O);
parameter data_inv = 1'b0;
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;
parameter iobname = "";
parameter location = "";
parameter mode = 0;
parameter path = 0;
parameter ring = 0;
wire clock = CK ^ dff_edge;
wire load = dff_load ? L : 1'b1;
wire async_reset = !dff_sync && dff_init && R;
wire sync_reset = dff_sync && dff_init && R;
reg O_reg;
always @(posedge clock, posedge async_reset)
if (async_reset) O_reg <= dff_type;
else if (sync_reset) O_reg <= dff_type;
else if (load) O_reg <= I;
assign O = data_inv ? O_reg : ~O_reg;
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);
parameter add_carry = 0;
wire CI_1;
wire CO1, CO2, CO3;
assign CI_1 = (add_carry==2) ? CI : ((add_carry==1) ? 1'b1 : 1'b0);
assign { CO1, S1 } = A1 + B1 + CI_1;
assign { CO2, S2 } = A2 + B2 + CO1;
assign { CO3, S3 } = A3 + B3 + CO2;
assign { CO, S4 } = A4 + B4 + CO3;
endmodule
module NX_IOB(I, C, T, O, IO);
input C;
input I;
(* iopad_external_pin *)
inout IO;
output O;
input T;
parameter differential = "";
parameter drive = "";
parameter dynDrive = "";
parameter dynInput = "";
parameter dynTerm = "";
parameter extra = 3;
parameter inputDelayLine = "";
parameter inputDelayOn = "";
parameter inputSignalSlope = "";
parameter location = "";
parameter locked = 1'b0;
parameter outputCapacity = "";
parameter outputDelayLine = "";
parameter outputDelayOn = "";
parameter slewRate = "";
parameter standard = "";
parameter termination = "";
parameter terminationReference = "";
parameter turbo = "";
parameter weakTermination = "";
assign O = IO;
assign IO = C ? I : 1'bz;
endmodule
module NX_IOB_I(C, T, IO, O);
input C;
(* iopad_external_pin *)
input IO;
output O;
input T;
parameter differential = "";
parameter drive = "";
parameter dynDrive = "";
parameter dynInput = "";
parameter dynTerm = "";
parameter extra = 1;
parameter inputDelayLine = "";
parameter inputDelayOn = "";
parameter inputSignalSlope = "";
parameter location = "";
parameter locked = 1'b0;
parameter outputCapacity = "";
parameter outputDelayLine = "";
parameter outputDelayOn = "";
parameter slewRate = "";
parameter standard = "";
parameter termination = "";
parameter terminationReference = "";
parameter turbo = "";
parameter weakTermination = "";
assign O = IO;
endmodule
module NX_IOB_O(I, C, T, IO);
input C;
input I;
(* iopad_external_pin *)
output IO;
input T;
parameter differential = "";
parameter drive = "";
parameter dynDrive = "";
parameter dynInput = "";
parameter dynTerm = "";
parameter extra = 2;
parameter inputDelayLine = "";
parameter inputDelayOn = "";
parameter inputSignalSlope = "";
parameter location = "";
parameter locked = 1'b0;
parameter outputCapacity = "";
parameter outputDelayLine = "";
parameter outputDelayOn = "";
parameter slewRate = "";
parameter standard = "";
parameter termination = "";
parameter terminationReference = "";
parameter turbo = "";
parameter weakTermination = "";
assign IO = C ? I : 1'bz;
endmodule
(* abc9_box, lib_whitebox *)
module NX_CY_1BIT(CI, A, B, S, CO);
(* abc9_carry *)
input CI;
input A;
input B;
output S;
(* abc9_carry *)
output CO;
parameter first = 1'b0;
assign {CO, S} = A + B + CI;
endmodule
module NX_BD(I, O);
input I;
output O;
parameter mode = "global_lowskew";
assign O = I;
endmodule
module NX_BFF(I, O);
input I;
output O;
assign O = I;
endmodule
module NX_BFR(I, O);
input I;
output O;
parameter data_inv = 1'b0;
parameter iobname = "";
parameter location = "";
parameter mode = 0;
parameter path = 0;
parameter ring = 0;
assign O = data_inv ? ~I : I;
endmodule
(* abc9_box, lib_whitebox *)
module NX_RAM(ACK, ACKC, ACKD, ACKR, BCK, BCKC, BCKD, BCKR, AI1, AI2, AI3, AI4, AI5, AI6, AI7, AI8, AI9, AI10, AI11, AI12, AI13
, AI14, AI15, AI16, AI17, AI18, AI19, AI20, AI21, AI22, AI23, AI24, BI1, BI2, BI3, BI4, BI5, BI6, BI7, BI8, BI9, BI10
, BI11, BI12, BI13, BI14, BI15, BI16, BI17, BI18, BI19, BI20, BI21, BI22, BI23, BI24, ACOR, AERR, BCOR, BERR, AO1, AO2, AO3
, AO4, AO5, AO6, AO7, AO8, AO9, AO10, AO11, AO12, AO13, AO14, AO15, AO16, AO17, AO18, AO19, AO20, AO21, AO22, AO23, AO24
, BO1, BO2, BO3, BO4, BO5, BO6, BO7, BO8, BO9, BO10, BO11, BO12, BO13, BO14, BO15, BO16, BO17, BO18, BO19, BO20, BO21
, BO22, BO23, BO24, AA1, AA2, AA3, AA4, AA5, AA6, AA7, AA8, AA9, AA10, AA11, AA12, AA13, AA14, AA15, AA16, ACS, AWE
, AR, BA1, BA2, BA3, BA4, BA5, BA6, BA7, BA8, BA9, BA10, BA11, BA12, BA13, BA14, BA15, BA16, BCS, BWE, BR);
input AA1;
input AA10;
input AA11;
input AA12;
input AA13;
input AA14;
input AA15;
input AA16;
input AA2;
input AA3;
input AA4;
input AA5;
input AA6;
input AA7;
input AA8;
input AA9;
input ACK;
input ACKC;
input ACKD;
input ACKR;
output ACOR;
input ACS;
output AERR;
input AI1;
input AI10;
input AI11;
input AI12;
input AI13;
input AI14;
input AI15;
input AI16;
input AI17;
input AI18;
input AI19;
input AI2;
input AI20;
input AI21;
input AI22;
input AI23;
input AI24;
input AI3;
input AI4;
input AI5;
input AI6;
input AI7;
input AI8;
input AI9;
output reg AO1;
output reg AO10;
output reg AO11;
output reg AO12;
output reg AO13;
output reg AO14;
output reg AO15;
output reg AO16;
output reg AO17;
output reg AO18;
output reg AO19;
output reg AO2;
output reg AO20;
output reg AO21;
output reg AO22;
output reg AO23;
output reg AO24;
output reg AO3;
output reg AO4;
output reg AO5;
output reg AO6;
output reg AO7;
output reg AO8;
output reg AO9;
input AR;
input AWE;
input BA1;
input BA10;
input BA11;
input BA12;
input BA13;
input BA14;
input BA15;
input BA16;
input BA2;
input BA3;
input BA4;
input BA5;
input BA6;
input BA7;
input BA8;
input BA9;
input BCK;
input BCKC;
input BCKD;
input BCKR;
output BCOR;
input BCS;
output BERR;
input BI1;
input BI10;
input BI11;
input BI12;
input BI13;
input BI14;
input BI15;
input BI16;
input BI17;
input BI18;
input BI19;
input BI2;
input BI20;
input BI21;
input BI22;
input BI23;
input BI24;
input BI3;
input BI4;
input BI5;
input BI6;
input BI7;
input BI8;
input BI9;
output reg BO1;
output reg BO10;
output reg BO11;
output reg BO12;
output reg BO13;
output reg BO14;
output reg BO15;
output reg BO16;
output reg BO17;
output reg BO18;
output reg BO19;
output reg BO2;
output reg BO20;
output reg BO21;
output reg BO22;
output reg BO23;
output reg BO24;
output reg BO3;
output reg BO4;
output reg BO5;
output reg BO6;
output reg BO7;
output reg BO8;
output reg BO9;
input BR;
input BWE;
parameter mcka_edge = 1'b0;
parameter mckb_edge = 1'b0;
parameter mem_ctxt = "";
parameter pcka_edge = 1'b0;
parameter pckb_edge = 1'b0;
parameter pipe_ia = 1'b0;
parameter pipe_ib = 1'b0;
parameter pipe_oa = 1'b0;
parameter pipe_ob = 1'b0;
parameter raw_config0 = 4'b0000;
parameter raw_config1 = 16'b0000000000000000;
//parameter raw_l_enable = 1'b0;
//parameter raw_l_extend = 4'b0000;
//parameter raw_u_enable = 1'b0;
//parameter raw_u_extend = 8'b00000000;
parameter std_mode = "";
reg [24-1:0] mem [2048-1:0]; // 48 Kbit of memory
/*integer i;
initial begin
for (i = 0; i < 2048; i = i + 1)
mem[i] = 24'b0;
end*/
wire [15:0] AA = { AA16, AA15, AA14, AA13, AA12, AA11, AA10, AA9, AA8, AA7, AA6, AA5, AA4, AA3, AA2, AA1 };
wire [23:0] AI = { AI24, AI23, AI22, AI21, AI20, AI19, AI18, AI17, AI16, AI15, AI14, AI13, AI12, AI11, AI10, AI9, AI8, AI7, AI6, AI5, AI4, AI3, AI2, AI1 };
wire [23:0] AO = { AO24, AO23, AO22, AO21, AO20, AO19, AO18, AO17, AO16, AO15, AO14, AO13, AO12, AO11, AO10, AO9, AO8, AO7, AO6, AO5, AO4, AO3, AO2, AO1 };
wire [15:0] BA = { BA16, BA15, BA14, BA13, BA12, BA11, BA10, BA9, BA8, BA7, BA6, BA5, BA4, BA3, BA2, BA1 };
wire [23:0] BI = { BI24, BI23, BI22, BI21, BI20, BI19, BI18, BI17, BI16, BI15, BI14, BI13, BI12, BI11, BI10, BI9, BI8, BI7, BI6, BI5, BI4, BI3, BI2, BI1 };
wire [23:0] BO = { BO24, BO23, BO22, BO21, BO20, BO19, BO18, BO17, BO16, BO15, BO14, BO13, BO12, BO11, BO10, BO9, BO8, BO7, BO6, BO5, BO4, BO3, BO2, BO1 };
always @(posedge ACK)
if (AWE)
mem[AA[10:0]] <= AI;
else
{ AO24, AO23, AO22, AO21, AO20, AO19, AO18, AO17, AO16, AO15, AO14, AO13, AO12, AO11, AO10, AO9, AO8, AO7, AO6, AO5, AO4, AO3, AO2, AO1 } <= mem[AA[10:0]];
assign ACOR = 1'b0;
assign AERR = 1'b0;
always @(posedge BCK)
if (BWE)
mem[BA[10:0]] <= BI;
else
{ BO24, BO23, BO22, BO21, BO20, BO19, BO18, BO17, BO16, BO15, BO14, BO13, BO12, BO11, BO10, BO9, BO8, BO7, BO6, BO5, BO4, BO3, BO2, BO1 } <= mem[BA[10:0]];
assign BCOR = 1'b0;
assign BERR = 1'b0;
endmodule

View file

View file

View file

@ -0,0 +1,306 @@
(* abc9_box, lib_whitebox *)
module NX_GCK_U(SI1, SI2, CMD, SO);
input CMD;
input SI1;
input SI2;
output SO;
parameter inv_in = 1'b0;
parameter inv_out = 1'b0;
parameter std_mode = "BYPASS";
wire SI1_int = inv_in ? ~SI1 : SI1;
wire SI2_int = inv_in ? ~SI2 : SI2;
wire SO_int;
generate
if (std_mode == "BYPASS") begin
assign SO_int = SI1_int;
end
else if (std_mode == "MUX") begin
assign SO_int = CMD ? SI1_int : SI2_int;
end
else if (std_mode == "CKS") begin
assign SO_int = CMD ? SI1_int : 1'b0;
end
else if (std_mode == "CSC") begin
assign SO_int = CMD;
end
else
$error("Unrecognised std_mode");
endgenerate
assign SO = inv_out ? ~SO_int : SO_int;
endmodule
(* abc9_box, lib_whitebox *)
module NX_RFB_U(WCK, I1, I2, I3, I4, I5, I6, I7, I8, I9, I10, I11, I12, I13, I14, I15, I16, I17, I18, I19, I20
, I21, I22, I23, I24, I25, I26, I27, I28, I29, I30, I31, I32, I33, I34, I35, I36, O1, O2, O3, O4, O5
, O6, O7, O8, O9, O10, O11, O12, O13, O14, O15, O16, O17, O18, O19, O20, O21, O22, O23, O24, O25, O26
, O27, O28, O29, O30, O31, O32, O33, O34, O35, O36, RA1, RA2, RA3, RA4, RA5, RA6, RA7, RA8, RA9, RA10, WA1
, WA2, WA3, WA4, WA5, WA6, WE, WEA);
input I1;
input I10;
input I11;
input I12;
input I13;
input I14;
input I15;
input I16;
input I17;
input I18;
input I19;
input I2;
input I20;
input I21;
input I22;
input I23;
input I24;
input I25;
input I26;
input I27;
input I28;
input I29;
input I3;
input I30;
input I31;
input I32;
input I33;
input I34;
input I35;
input I36;
input I4;
input I5;
input I6;
input I7;
input I8;
input I9;
output O1;
output O10;
output O11;
output O12;
output O13;
output O14;
output O15;
output O16;
output O17;
output O18;
output O19;
output O2;
output O20;
output O21;
output O22;
output O23;
output O24;
output O25;
output O26;
output O27;
output O28;
output O29;
output O3;
output O30;
output O31;
output O32;
output O33;
output O34;
output O35;
output O36;
output O4;
output O5;
output O6;
output O7;
output O8;
output O9;
input RA1;
input RA10;
input RA2;
input RA3;
input RA4;
input RA5;
input RA6;
input RA7;
input RA8;
input RA9;
input WA1;
input WA2;
input WA3;
input WA4;
input WA5;
input WA6;
input WCK;
input WE;
input WEA;
parameter mem_ctxt = "";
parameter mode = 0;
parameter wck_edge = 1'b0;
wire clock = WCK ^ wck_edge;
localparam MEM_SIZE = mode == 2 ? 64 : 32;
localparam MEM_WIDTH = mode == 3 ? 36 : 18;
localparam ADDR_WIDTH = mode == 2 ? 6 : 5;
localparam DATA_SIZE = MEM_SIZE * MEM_WIDTH;
localparam MAX_SIZE = DATA_SIZE + MEM_SIZE + 1;
reg [MEM_WIDTH-1:0] mem [MEM_SIZE-1:0];
function [DATA_SIZE-1:0] convert_initval;
input [8*MAX_SIZE-1:0] hex_initval;
reg done;
reg [DATA_SIZE-1:0] temp;
reg [7:0] char;
integer i,j;
begin
done = 1'b0;
temp = 0;
j = 0;
for (i = 0; i < MAX_SIZE; i = i + 1) begin
char = hex_initval[8*i +: 8];
if (char >= "0" && char <= "1") begin
temp[j] = char - "0";
j = j + 1;
end
end
convert_initval = temp;
end
endfunction
integer i;
reg [DATA_SIZE-1:0] mem_data;
initial begin
mem_data = convert_initval(mem_ctxt);
for (i = 0; i < MEM_SIZE; i = i + 1)
mem[i] = mem_data[MEM_WIDTH*(MEM_SIZE-i-1) +: MEM_WIDTH];
end
wire [ADDR_WIDTH-1:0] WA = (mode==2) ? { WA6, WA5, WA4, WA3, WA2, WA1 } : { WA5, WA4, WA3, WA2, WA1 };
wire [36-1:0] O = { O36, O35, O34, O33, O32, O31, O30, O29, O28,
O27, O26, O25, O24, O23, O22, O21, O20, O19,
O18, O17, O16, O15, O14, O13, O12, O11, O10,
O9, O8, O7, O6, O5, O4, O3, O2, O1 };
wire [36-1:0] I = { I36, I35, I34, I33, I32, I31, I30, I29, I28,
I27, I26, I25, I24, I23, I22, I21, I20, I19,
I18, I17, I16, I15, I14, I13, I12, I11, I10,
I9, I8, I7, I6, I5, I4, I3, I2, I1 };
generate
if (mode==0) begin
assign O = mem[{ RA5, RA4, RA3, RA2, RA1 }];
end
else if (mode==1) begin
assign O = mem[{ WA5, WA4, WA3, WA2, WA1 }];
end
else if (mode==2) begin
assign O = mem[{ RA6, RA5, RA4, RA3, RA2, RA1 }];
end
else if (mode==3) begin
assign O = mem[{ RA5, RA4, RA3, RA2, RA1 }];
end
else if (mode==4) begin
assign O = { mem[{ RA10, RA9, RA8, RA7, RA6 }], mem[{ RA5, RA4, RA3, RA2, RA1 }] };
end
else
$error("Unknown NX_RFB_U mode");
endgenerate
always @(posedge clock)
if (WE)
mem[WA] <= I[MEM_WIDTH-1:0];
endmodule
(* abc9_box, lib_whitebox *)
module NX_WFG_U(R, SI, ZI, SO, ZO);
input R;
input SI;
output SO;
input ZI;
output ZO;
parameter delay = 0;
parameter delay_on = 1'b0;
parameter div_phase = 1'b0;
parameter div_ratio = 0;
parameter location = "";
parameter mode = 0;
parameter pattern = 16'b0000000000000000;
parameter pattern_end = 0;
parameter reset_on_cal_lock_n = 1'b0;
parameter reset_on_pll_lock_n = 1'b0;
parameter reset_on_pll_locka_n = 1'b0;
parameter wfg_edge = 1'b0;
generate
if (mode==0) begin
assign SO = SI;
end
else if (mode==1) begin
wire clock = ZI ^ wfg_edge;
wire reset = R || SI;
reg [3:0] counter = 0;
reg [15:0] rom = pattern;
always @(posedge clock)
begin
if (reset)
counter <= 4'b0;
else
counter <= counter + 1;
end
assign SO = counter == pattern_end;
assign ZO = rom[counter];
end
else if (mode==2) begin
end
else
$error("Unknown NX_WFG_U mode");
endgenerate
endmodule
module NX_DDFR_U(CK,CKF,R,I,I2,L,O,O2);
input CK;
input CKF;
input R;
input I;
input I2;
input L;
output O;
output O2;
parameter location = "";
parameter path = 0;
parameter dff_type = 1'b0;
parameter dff_sync = 1'b0;
parameter dff_load = 1'b0;
wire load = dff_load ? 1'b1 : L; // reversed when compared to DFF
wire async_reset = !dff_sync && R;
wire sync_reset = dff_sync && R;
generate
if (path==1) begin
// IDDFR
always @(posedge CK, posedge async_reset)
if (async_reset) O <= dff_type;
else if (sync_reset) O <= dff_type;
else if (load) O <= I;
always @(posedge CKF, posedge async_reset)
if (async_reset) O2 <= dff_type;
else if (sync_reset) O2 <= dff_type;
else if (load) O2 <= I;
end
else if (path==0 || path==2) begin
reg q1, q2;
// ODDFR
always @(posedge CK, posedge async_reset)
if (async_reset) q1 <= dff_type;
else if (sync_reset) q1 <= dff_type;
else if (load) q1 <= I;
always @(posedge CKF, posedge async_reset)
if (async_reset) q2 <= dff_type;
else if (sync_reset) q2 <= dff_type;
else if (load) q2 <= I2;
assign O = CK ? q1 : q2;
end
else
$error("Unknown NX_DDFR_U path");
endgenerate
endmodule

View file

@ -0,0 +1,201 @@
module NX_RAM_WRAP(ACK, ACKD, ACKR, BCK, BCKD, BCKR, ACOR, AERR, BCOR, BERR, ACS, AWE, AR, BCS, BWE, BR, BI, AO, BO, AI, AA
, BA);
input [15:0] AA;
input ACK;
input ACKD;
input ACKR;
output ACOR;
input ACS;
output AERR;
input [23:0] AI;
output [23:0] AO;
input AR;
input AWE;
input [15:0] BA;
input BCK;
input BCKD;
input BCKR;
output BCOR;
input BCS;
output BERR;
input [23:0] BI;
output [23:0] BO;
input BR;
input BWE;
parameter mcka_edge = 1'b0;
parameter mckb_edge = 1'b0;
parameter mem_ctxt = "";
parameter pcka_edge = 1'b0;
parameter pckb_edge = 1'b0;
parameter pipe_ia = 1'b0;
parameter pipe_ib = 1'b0;
parameter pipe_oa = 1'b0;
parameter pipe_ob = 1'b0;
parameter raw_config0 = 4'b0000;
parameter raw_config1 = 16'b0000000000000000;
parameter std_mode = "";
NX_RAM #(
.mcka_edge(mcka_edge),
.mckb_edge(mckb_edge),
.mem_ctxt(mem_ctxt),
.pcka_edge(pcka_edge),
.pckb_edge(pckb_edge),
.pipe_ia(pipe_ia),
.pipe_ib(pipe_ib),
.pipe_oa(pipe_oa),
.pipe_ob(pipe_ob),
.raw_config0(raw_config0),
.raw_config1(raw_config1),
.std_mode(std_mode)
) ram (
.AA1(AA[0]),
.AA10(AA[9]),
.AA11(AA[10]),
.AA12(AA[11]),
.AA13(AA[12]),
.AA14(AA[13]),
.AA15(AA[14]),
.AA16(AA[15]),
.AA2(AA[1]),
.AA3(AA[2]),
.AA4(AA[3]),
.AA5(AA[4]),
.AA6(AA[5]),
.AA7(AA[6]),
.AA8(AA[7]),
.AA9(AA[8]),
.ACK(ACK),
.ACKC(ACK),
.ACKD(ACKD),
.ACKR(ACKR),
.ACOR(ACOR),
.ACS(ACS),
.AERR(AERR),
.AI1(AI[0]),
.AI10(AI[9]),
.AI11(AI[10]),
.AI12(AI[11]),
.AI13(AI[12]),
.AI14(AI[13]),
.AI15(AI[14]),
.AI16(AI[15]),
.AI17(AI[16]),
.AI18(AI[17]),
.AI19(AI[18]),
.AI2(AI[1]),
.AI20(AI[19]),
.AI21(AI[20]),
.AI22(AI[21]),
.AI23(AI[22]),
.AI24(AI[23]),
.AI3(AI[2]),
.AI4(AI[3]),
.AI5(AI[4]),
.AI6(AI[5]),
.AI7(AI[6]),
.AI8(AI[7]),
.AI9(AI[8]),
.AO1(AO[0]),
.AO10(AO[9]),
.AO11(AO[10]),
.AO12(AO[11]),
.AO13(AO[12]),
.AO14(AO[13]),
.AO15(AO[14]),
.AO16(AO[15]),
.AO17(AO[16]),
.AO18(AO[17]),
.AO19(AO[18]),
.AO2(AO[1]),
.AO20(AO[19]),
.AO21(AO[20]),
.AO22(AO[21]),
.AO23(AO[22]),
.AO24(AO[23]),
.AO3(AO[2]),
.AO4(AO[3]),
.AO5(AO[4]),
.AO6(AO[5]),
.AO7(AO[6]),
.AO8(AO[7]),
.AO9(AO[8]),
.AR(AR),
.AWE(AWE),
.BA1(BA[0]),
.BA10(BA[9]),
.BA11(BA[10]),
.BA12(BA[11]),
.BA13(BA[12]),
.BA14(BA[13]),
.BA15(BA[14]),
.BA16(BA[15]),
.BA2(BA[1]),
.BA3(BA[2]),
.BA4(BA[3]),
.BA5(BA[4]),
.BA6(BA[5]),
.BA7(BA[6]),
.BA8(BA[7]),
.BA9(BA[8]),
.BCK(BCK),
.BCKC(BCK),
.BCKD(BCKD),
.BCKR(BCKR),
.BCOR(BCOR),
.BCS(BCS),
.BERR(BERR),
.BI1(BI[0]),
.BI10(BI[9]),
.BI11(BI[10]),
.BI12(BI[11]),
.BI13(BI[12]),
.BI14(BI[13]),
.BI15(BI[14]),
.BI16(BI[15]),
.BI17(BI[16]),
.BI18(BI[17]),
.BI19(BI[18]),
.BI2(BI[1]),
.BI20(BI[19]),
.BI21(BI[20]),
.BI22(BI[21]),
.BI23(BI[22]),
.BI24(BI[23]),
.BI3(BI[2]),
.BI4(BI[3]),
.BI5(BI[4]),
.BI6(BI[5]),
.BI7(BI[6]),
.BI8(BI[7]),
.BI9(BI[8]),
.BO1(BO[0]),
.BO10(BO[9]),
.BO11(BO[10]),
.BO12(BO[11]),
.BO13(BO[12]),
.BO14(BO[13]),
.BO15(BO[14]),
.BO16(BO[15]),
.BO17(BO[16]),
.BO18(BO[17]),
.BO19(BO[18]),
.BO2(BO[1]),
.BO20(BO[19]),
.BO21(BO[20]),
.BO22(BO[21]),
.BO23(BO[22]),
.BO24(BO[23]),
.BO3(BO[2]),
.BO4(BO[3]),
.BO5(BO[4]),
.BO6(BO[5]),
.BO7(BO[6]),
.BO8(BO[7]),
.BO9(BO[8]),
.BR(BR),
.BWE(BWE)
);
endmodule

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,15 @@
module \$__BEYOND_IBUF (input PAD, output O);
NX_IOB_I _TECHMAP_REPLACE_ (.IO(PAD), .O(O), .C(1'b0));
endmodule
module \$__BEYOND_OBUF (output PAD, input I);
NX_IOB_O _TECHMAP_REPLACE_ (.IO(PAD), .I(I), .C(1'b1));
endmodule
module \$__BEYOND_TOBUF (output PAD, input I, input C);
NX_IOB _TECHMAP_REPLACE_ (.IO(PAD), .I(I), .C(C));
endmodule
module \$__BEYOND_IOBUF (output PAD, input I, output O, output C);
NX_IOB _TECHMAP_REPLACE_ (.IO(PAD), .I(I), .O(O), .C(C));
endmodule

View file

@ -0,0 +1,11 @@
module \$_DLATCH_N_ (E, D, Q);
wire [1023:0] _TECHMAP_DO_ = "simplemap; opt";
input E, D;
output Q = !E ? D : Q;
endmodule
module \$_DLATCH_P_ (E, D, Q);
wire [1023:0] _TECHMAP_DO_ = "simplemap; opt";
input E, D;
output Q = E ? D : Q;
endmodule

View file

@ -0,0 +1,164 @@
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2024 Miodrag Milanovic <micko@yosyshq.com>
*
* 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.
*
*/
#include "kernel/yosys.h"
#include "kernel/sigtools.h"
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
static SigBit get_bit_or_zero(const SigSpec &sig)
{
if (GetSize(sig) == 0)
return State::S0;
return sig[0];
}
static void nx_carry_chain(Module *module)
{
SigMap sigmap(module);
dict<SigBit,Cell*> carry;
for (auto cell : module->cells())
{
if (cell->type == ID(NX_CY_1BIT)) {
if (cell->getParam(ID(first)).as_int() == 1) continue;
if (!cell->hasPort(ID(CI)))
log_error("Not able to find connected carry.\n");
SigBit ci = sigmap(cell->getPort(ID(CI)).as_bit());
carry[ci] = cell;
}
}
dict<Cell*,vector<Cell*>> carry_chains;
log("Detecting carry chains\n");
for (auto cell : module->cells())
{
if (cell->type == ID(NX_CY_1BIT)) {
if (cell->getParam(ID(first)).as_int() == 0) continue;
vector<Cell*> chain;
Cell *current = cell;
chain.push_back(current);
SigBit co = sigmap(cell->getPort(ID(CO)).as_bit());
while (co.is_wire())
{
if (carry.count(co)==0)
break;
//log_error("Not able to find connected carry.\n");
current = carry[co];
chain.push_back(current);
if (!current->hasPort(ID(CO))) break;
co = sigmap(current->getPort(ID(CO)).as_bit());
}
carry_chains[cell] = chain;
}
}
log("Creating NX_CY cells.\n");
for(auto& c : carry_chains) {
Cell *cell = nullptr;
int j = 0;
int cnt = 0;
IdString names_A[] = { ID(A1), ID(A2), ID(A3), ID(A4) };
IdString names_B[] = { ID(B1), ID(B2), ID(B3), ID(B4) };
IdString names_S[] = { ID(S1), ID(S2), ID(S3), ID(S4) };
if (!c.second.at(0)->getPort(ID(CI)).is_fully_const()) {
cell = module->addCell(NEW_ID, ID(NX_CY));
cell->setParam(ID(add_carry), Const(1,2));
cell->setPort(ID(CI), State::S1);
cell->setPort(names_A[0], c.second.at(0)->getPort(ID(CI)).as_bit());
cell->setPort(names_B[0], State::S0);
j++;
}
for (size_t i=0 ; i<c.second.size(); i++) {
if (j==0) {
cell = module->addCell(NEW_ID, ID(NX_CY));
SigBit ci = c.second.at(i)->getPort(ID(CI)).as_bit();
cell->setPort(ID(CI), ci);
if (ci.is_wire()) {
cell->setParam(ID(add_carry), Const(2,2));
} else {
if (ci == State::S0)
cell->setParam(ID(add_carry), Const(0,2));
else
cell->setParam(ID(add_carry), Const(1,2));
}
}
if (j==3) {
if (cnt !=0 && (cnt % 24 == 0)) {
SigBit new_co = module->addWire(NEW_ID);
cell->setPort(ID(A4), State::S0);
cell->setPort(ID(B4), State::S0);
cell->setPort(ID(S4), new_co);
cell = module->addCell(NEW_ID, ID(NX_CY));
cell->setParam(ID(add_carry), Const(1,2));
cell->setPort(ID(CI), State::S1);
cell->setPort(ID(A1), new_co);
cell->setPort(ID(B1), State::S0);
j = 1;
} else {
if (c.second.at(i)->hasPort(ID(CO)))
cell->setPort(ID(CO), c.second.at(i)->getPort(ID(CO)));
}
cnt++;
}
cell->setPort(names_A[j], get_bit_or_zero(c.second.at(i)->getPort(ID(A))));
cell->setPort(names_B[j], get_bit_or_zero(c.second.at(i)->getPort(ID(B))));
if (c.second.at(i)->hasPort(ID(S)))
cell->setPort(names_S[j], c.second.at(i)->getPort(ID(S)));
j = (j + 1) % 4;
module->remove(c.second.at(i));
}
}
}
struct NXCarryPass : public Pass {
NXCarryPass() : Pass("nx_carry", "NanoXplore: create carry cells") { }
void help() override
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
log(" nx_carry [options] [selection]\n");
log("\n");
log("Fixes carry chain if needed, break it on 24 elements and group by 4 into NX_CY.\n");
log("\n");
}
void execute(std::vector<std::string> args, RTLIL::Design *design) override
{
log_header(design, "Executing NX_CARRY pass.\n");
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++)
{
break;
}
extra_args(args, argidx, design);
for (auto module : design->selected_modules())
nx_carry_chain(module);
}
} NXCarryPass;
PRIVATE_NAMESPACE_END

View file

@ -0,0 +1,17 @@
function [9728-1:0] rf_init_to_string;
input [1152-1:0] array;
input integer blocks;
input integer width;
reg [9728-1:0] temp; // (1152+1152/18)*8
integer i;
begin
temp = "";
for (i = 0; i < blocks; i = i + 1) begin
if (i != 0) begin
temp = {temp, ","};
end
temp = {temp, $sformatf("%b",array[(i+1)*width-1: i*width])};
end
rf_init_to_string = temp;
end
endfunction

View file

@ -0,0 +1,15 @@
ram distributed $__NX_RFB_L_ {
abits 6;
width 16;
cost 10;
init no_undef;
prune_rom;
port sw "W" {
clock anyedge;
}
port sr "R" {
clock anyedge;
rden;
}
}

View file

@ -0,0 +1,15 @@
ram distributed $__NX_RFB_M_ {
abits 6;
width 16;
cost 10;
init no_undef;
prune_rom;
port sw "W" {
clock anyedge;
}
port sr "R" {
clock anyedge;
rden;
}
}

View file

@ -0,0 +1,30 @@
module $__NX_RFB_L_ (
input PORT_W_CLK,
input PORT_W_WR_EN,
input [5:0] PORT_W_ADDR,
input [15:0] PORT_W_WR_DATA,
input PORT_R_CLK,
input PORT_R_RD_EN,
input [5:0] PORT_R_ADDR,
output [15:0] PORT_R_RD_DATA,
);
parameter INIT = 1152'bx;
parameter PORT_W_CLK_POL = 1'b1;
parameter PORT_R_CLK_POL = 1'b1;
NX_RFB_L_WRAP #(
.mode(0),
.mem_ctxt(INIT),
.rck_edge(~PORT_R_CLK_POL),
.wck_edge(~PORT_W_CLK_POL)
) _TECHMAP_REPLACE_ (
.RCK(PORT_R_CLK),
.WCK(PORT_W_CLK),
.I(PORT_W_WR_DATA),
.RA(PORT_R_ADDR),
.WA(PORT_W_ADDR),
.RE(PORT_R_RD_EN),
.WE(PORT_W_WR_EN),
.O(PORT_R_RD_DATA)
);
endmodule

View file

@ -0,0 +1,30 @@
module $__NX_RFB_M_ (
input PORT_W_CLK,
input PORT_W_WR_EN,
input [5:0] PORT_W_ADDR,
input [15:0] PORT_W_WR_DATA,
input PORT_R_CLK,
input PORT_R_RD_EN,
input [5:0] PORT_R_ADDR,
output [15:0] PORT_R_RD_DATA,
);
parameter INIT = 1152'bx;
parameter PORT_W_CLK_POL = 1'b1;
parameter PORT_R_CLK_POL = 1'b1;
NX_RFB_M_WRAP #(
.mode(0),
.mem_ctxt(INIT),
.rck_edge(~PORT_R_CLK_POL),
.wck_edge(~PORT_W_CLK_POL)
) _TECHMAP_REPLACE_ (
.RCK(PORT_R_CLK),
.WCK(PORT_W_CLK),
.I(PORT_W_WR_DATA),
.RA(PORT_R_ADDR),
.WA(PORT_W_ADDR),
.RE(PORT_R_RD_EN),
.WE(PORT_W_WR_EN),
.O(PORT_R_RD_DATA)
);
endmodule

View file

@ -0,0 +1,345 @@
module $__NX_RFB_U_DPREG_ (
input PORT_W_CLK,
input [6-1:0] PORT_W_ADDR,
input [6-1:0] PORT_R_ADDR,
input [36-1:0] PORT_W_WR_DATA,
input PORT_W_WR_EN,
output [36-1:0] PORT_R_RD_DATA
);
parameter INIT = 1152'bx;
parameter PORT_W_CLK_POL = 1'b1;
parameter OPTION_MODE = 0;
parameter WIDTH = 18;
parameter BITS_USED = 0;
localparam BLOCK_NUM = OPTION_MODE == 2 ? 64 : 32;
localparam BLOCK_SIZE = OPTION_MODE == 3 ? 36 : 18;
`include "rf_init.vh"
// mode 0 - DPREG
// mode 2 - NX_XRFB_64x18
// mode 3 - NX_XRFB_32x36
NX_RFB_U #(
.mode(OPTION_MODE),
.mem_ctxt($sformatf("%s",rf_init_to_string(INIT, BLOCK_NUM, BLOCK_SIZE))),
.wck_edge(PORT_W_CLK_POL == 1 ? 1'b0 : 1'b1)
) _TECHMAP_REPLACE_ (
.WCK(PORT_W_CLK),
.I1(PORT_W_WR_DATA[0]),
.I2(PORT_W_WR_DATA[1]),
.I3(PORT_W_WR_DATA[2]),
.I4(PORT_W_WR_DATA[3]),
.I5(PORT_W_WR_DATA[4]),
.I6(PORT_W_WR_DATA[5]),
.I7(PORT_W_WR_DATA[6]),
.I8(PORT_W_WR_DATA[7]),
.I9(PORT_W_WR_DATA[8]),
.I10(PORT_W_WR_DATA[9]),
.I11(PORT_W_WR_DATA[10]),
.I12(PORT_W_WR_DATA[11]),
.I13(PORT_W_WR_DATA[12]),
.I14(PORT_W_WR_DATA[13]),
.I15(PORT_W_WR_DATA[14]),
.I16(PORT_W_WR_DATA[15]),
.I17(PORT_W_WR_DATA[16]),
.I18(PORT_W_WR_DATA[17]),
.I19(PORT_W_WR_DATA[18]),
.I20(PORT_W_WR_DATA[19]),
.I21(PORT_W_WR_DATA[20]),
.I22(PORT_W_WR_DATA[21]),
.I23(PORT_W_WR_DATA[22]),
.I24(PORT_W_WR_DATA[23]),
.I25(PORT_W_WR_DATA[24]),
.I26(PORT_W_WR_DATA[25]),
.I27(PORT_W_WR_DATA[26]),
.I28(PORT_W_WR_DATA[27]),
.I29(PORT_W_WR_DATA[28]),
.I30(PORT_W_WR_DATA[29]),
.I31(PORT_W_WR_DATA[30]),
.I32(PORT_W_WR_DATA[31]),
.I33(PORT_W_WR_DATA[32]),
.I34(PORT_W_WR_DATA[33]),
.I35(PORT_W_WR_DATA[34]),
.I36(PORT_W_WR_DATA[35]),
.O1(PORT_R_RD_DATA[0]),
.O2(PORT_R_RD_DATA[1]),
.O3(PORT_R_RD_DATA[2]),
.O4(PORT_R_RD_DATA[3]),
.O5(PORT_R_RD_DATA[4]),
.O6(PORT_R_RD_DATA[5]),
.O7(PORT_R_RD_DATA[6]),
.O8(PORT_R_RD_DATA[7]),
.O9(PORT_R_RD_DATA[8]),
.O10(PORT_R_RD_DATA[9]),
.O11(PORT_R_RD_DATA[10]),
.O12(PORT_R_RD_DATA[11]),
.O13(PORT_R_RD_DATA[12]),
.O14(PORT_R_RD_DATA[13]),
.O15(PORT_R_RD_DATA[14]),
.O16(PORT_R_RD_DATA[15]),
.O17(PORT_R_RD_DATA[16]),
.O18(PORT_R_RD_DATA[17]),
.O19(PORT_R_RD_DATA[18]),
.O20(PORT_R_RD_DATA[19]),
.O21(PORT_R_RD_DATA[20]),
.O22(PORT_R_RD_DATA[21]),
.O23(PORT_R_RD_DATA[22]),
.O24(PORT_R_RD_DATA[23]),
.O25(PORT_R_RD_DATA[24]),
.O26(PORT_R_RD_DATA[25]),
.O27(PORT_R_RD_DATA[26]),
.O28(PORT_R_RD_DATA[27]),
.O29(PORT_R_RD_DATA[28]),
.O30(PORT_R_RD_DATA[29]),
.O31(PORT_R_RD_DATA[30]),
.O32(PORT_R_RD_DATA[31]),
.O33(PORT_R_RD_DATA[32]),
.O34(PORT_R_RD_DATA[33]),
.O35(PORT_R_RD_DATA[34]),
.O36(PORT_R_RD_DATA[35]),
.RA1(PORT_R_ADDR[0]),
.RA2(PORT_R_ADDR[1]),
.RA3(PORT_R_ADDR[2]),
.RA4(PORT_R_ADDR[3]),
.RA5(PORT_R_ADDR[4]),
.RA6(PORT_R_ADDR[5]),
.RA7(),
.RA8(),
.RA9(),
.RA10(),
.WA1(PORT_W_ADDR[0]),
.WA2(PORT_W_ADDR[1]),
.WA3(PORT_W_ADDR[2]),
.WA4(PORT_W_ADDR[3]),
.WA5(PORT_W_ADDR[4]),
.WA6(PORT_W_ADDR[5]),
.WE(PORT_W_WR_EN),
.WEA(1'b0)
);
endmodule
module $__NX_RFB_U_SPREG_ (
input PORT_RW_CLK,
input [4:0] PORT_RW_ADDR,
input [17:0] PORT_RW_WR_DATA,
input PORT_RW_WR_EN,
output [17:0] PORT_RW_RD_DATA
);
parameter INIT = 576'bx;
parameter PORT_RW_CLK_POL = 1'b1;
parameter BITS_USED = 0;
`include "rf_init.vh"
NX_RFB_U #(
.mode(1),
.mem_ctxt($sformatf("%s",rf_init_to_string(INIT, 32, 18))),
.wck_edge(PORT_RW_CLK_POL == 1 ? 1'b0 : 1'b1)
) _TECHMAP_REPLACE_ (
.WCK(PORT_RW_CLK),
.I1(PORT_RW_WR_DATA[0]),
.I2(PORT_RW_WR_DATA[1]),
.I3(PORT_RW_WR_DATA[2]),
.I4(PORT_RW_WR_DATA[3]),
.I5(PORT_RW_WR_DATA[4]),
.I6(PORT_RW_WR_DATA[5]),
.I7(PORT_RW_WR_DATA[6]),
.I8(PORT_RW_WR_DATA[7]),
.I9(PORT_RW_WR_DATA[8]),
.I10(PORT_RW_WR_DATA[9]),
.I11(PORT_RW_WR_DATA[10]),
.I12(PORT_RW_WR_DATA[11]),
.I13(PORT_RW_WR_DATA[12]),
.I14(PORT_RW_WR_DATA[13]),
.I15(PORT_RW_WR_DATA[14]),
.I16(PORT_RW_WR_DATA[15]),
.I17(PORT_RW_WR_DATA[16]),
.I18(PORT_RW_WR_DATA[17]),
.I19(),
.I20(),
.I21(),
.I22(),
.I23(),
.I24(),
.I25(),
.I26(),
.I27(),
.I28(),
.I29(),
.I30(),
.I31(),
.I32(),
.I33(),
.I34(),
.I35(),
.I36(),
.O1(PORT_RW_RD_DATA[0]),
.O2(PORT_RW_RD_DATA[1]),
.O3(PORT_RW_RD_DATA[2]),
.O4(PORT_RW_RD_DATA[3]),
.O5(PORT_RW_RD_DATA[4]),
.O6(PORT_RW_RD_DATA[5]),
.O7(PORT_RW_RD_DATA[6]),
.O8(PORT_RW_RD_DATA[7]),
.O9(PORT_RW_RD_DATA[8]),
.O10(PORT_RW_RD_DATA[9]),
.O11(PORT_RW_RD_DATA[10]),
.O12(PORT_RW_RD_DATA[11]),
.O13(PORT_RW_RD_DATA[12]),
.O14(PORT_RW_RD_DATA[13]),
.O15(PORT_RW_RD_DATA[14]),
.O16(PORT_RW_RD_DATA[15]),
.O17(PORT_RW_RD_DATA[16]),
.O18(PORT_RW_RD_DATA[17]),
.O19(),
.O20(),
.O21(),
.O22(),
.O23(),
.O24(),
.O25(),
.O26(),
.O27(),
.O28(),
.O29(),
.O30(),
.O31(),
.O32(),
.O33(),
.O34(),
.O35(),
.O36(),
.RA1(),
.RA2(),
.RA3(),
.RA4(),
.RA5(),
.RA6(),
.RA7(),
.RA8(),
.RA9(),
.RA10(),
.WA1(PORT_RW_ADDR[0]),
.WA2(PORT_RW_ADDR[1]),
.WA3(PORT_RW_ADDR[2]),
.WA4(PORT_RW_ADDR[3]),
.WA5(PORT_RW_ADDR[4]),
.WA6(),
.WE(PORT_RW_WR_EN),
.WEA(1'b0)
);
endmodule
module $__NX_XRFB_2R_1W_ (
input PORT_W_CLK,
input [4:0] PORT_W_ADDR,
input [4:0] PORT_A_ADDR,
input [4:0] PORT_B_ADDR,
input [17:0] PORT_W_WR_DATA,
input PORT_W_WR_EN,
output [17:0] PORT_A_RD_DATA,
output [17:0] PORT_B_RD_DATA
);
parameter INIT = 576'bx;
parameter PORT_W_CLK_POL = 1'b1;
parameter BITS_USED = 0;
`include "rf_init.vh"
NX_RFB_U #(
.mode(4),
.mem_ctxt($sformatf("%s",rf_init_to_string(INIT, 32, 18))),
.wck_edge(PORT_W_CLK_POL == 1 ? 1'b0 : 1'b1)
) _TECHMAP_REPLACE_ (
.WCK(PORT_W_CLK),
.I1(PORT_W_WR_DATA[0]),
.I2(PORT_W_WR_DATA[1]),
.I3(PORT_W_WR_DATA[2]),
.I4(PORT_W_WR_DATA[3]),
.I5(PORT_W_WR_DATA[4]),
.I6(PORT_W_WR_DATA[5]),
.I7(PORT_W_WR_DATA[6]),
.I8(PORT_W_WR_DATA[7]),
.I9(PORT_W_WR_DATA[8]),
.I10(PORT_W_WR_DATA[9]),
.I11(PORT_W_WR_DATA[10]),
.I12(PORT_W_WR_DATA[11]),
.I13(PORT_W_WR_DATA[12]),
.I14(PORT_W_WR_DATA[13]),
.I15(PORT_W_WR_DATA[14]),
.I16(PORT_W_WR_DATA[15]),
.I17(PORT_W_WR_DATA[16]),
.I18(PORT_W_WR_DATA[17]),
.I19(),
.I20(),
.I21(),
.I22(),
.I23(),
.I24(),
.I25(),
.I26(),
.I27(),
.I28(),
.I29(),
.I30(),
.I31(),
.I32(),
.I33(),
.I34(),
.I35(),
.I36(),
.O1(PORT_A_RD_DATA[0]),
.O2(PORT_A_RD_DATA[1]),
.O3(PORT_A_RD_DATA[2]),
.O4(PORT_A_RD_DATA[3]),
.O5(PORT_A_RD_DATA[4]),
.O6(PORT_A_RD_DATA[5]),
.O7(PORT_A_RD_DATA[6]),
.O8(PORT_A_RD_DATA[7]),
.O9(PORT_A_RD_DATA[8]),
.O10(PORT_A_RD_DATA[9]),
.O11(PORT_A_RD_DATA[10]),
.O12(PORT_A_RD_DATA[11]),
.O13(PORT_A_RD_DATA[12]),
.O14(PORT_A_RD_DATA[13]),
.O15(PORT_A_RD_DATA[14]),
.O16(PORT_A_RD_DATA[15]),
.O17(PORT_A_RD_DATA[16]),
.O18(PORT_A_RD_DATA[17]),
.O19(PORT_B_RD_DATA[0]),
.O20(PORT_B_RD_DATA[1]),
.O21(PORT_B_RD_DATA[2]),
.O22(PORT_B_RD_DATA[3]),
.O23(PORT_B_RD_DATA[4]),
.O24(PORT_B_RD_DATA[5]),
.O25(PORT_B_RD_DATA[6]),
.O26(PORT_B_RD_DATA[7]),
.O27(PORT_B_RD_DATA[8]),
.O28(PORT_B_RD_DATA[9]),
.O29(PORT_B_RD_DATA[10]),
.O30(PORT_B_RD_DATA[11]),
.O31(PORT_B_RD_DATA[12]),
.O32(PORT_B_RD_DATA[13]),
.O33(PORT_B_RD_DATA[14]),
.O34(PORT_B_RD_DATA[15]),
.O35(PORT_B_RD_DATA[16]),
.O36(PORT_B_RD_DATA[17]),
.RA1(PORT_A_ADDR[0]),
.RA2(PORT_A_ADDR[1]),
.RA3(PORT_A_ADDR[2]),
.RA4(PORT_A_ADDR[3]),
.RA5(PORT_A_ADDR[4]),
.RA6(PORT_B_ADDR[0]),
.RA7(PORT_B_ADDR[1]),
.RA8(PORT_B_ADDR[2]),
.RA9(PORT_B_ADDR[3]),
.RA10(PORT_B_ADDR[4]),
.WA1(PORT_W_ADDR[0]),
.WA2(PORT_W_ADDR[1]),
.WA3(PORT_W_ADDR[2]),
.WA4(PORT_W_ADDR[3]),
.WA5(PORT_W_ADDR[4]),
.WA6(),
.WE(PORT_W_WR_EN),
.WEA(1'b0)
);
endmodule

View file

@ -0,0 +1,66 @@
# Register-File RAMs for NanoXplore NG-ULTRA
# Dual-port RAMs.
# NX_RFB_U in mode 0 (DPREG)
# NX_RFB_U in mode 2 (NX_XRFB_64x18)
# NX_RFB_U in mode 3 (NX_XRFB_32x36)
ram distributed $__NX_RFB_U_DPREG_ {
option "MODE" 0 {
cost 30;
widthscale 30;
abits 5;
widths 18 global;
}
option "MODE" 2 {
cost 50;
widthscale 30;
abits 6;
widths 18 global;
}
option "MODE" 3 {
cost 50;
widthscale 30;
abits 5;
widths 36 global;
}
init no_undef;
port sw "W" {
clock anyedge;
}
port ar "R" {
}
}
# Single-port RAMs.
# NX_RFB_U in mode 1 (SPREG)
ram distributed $__NX_RFB_U_SPREG_ {
cost 30;
widthscale;
abits 5;
width 18;
init no_undef;
port arsw "RW" {
clock anyedge;
}
}
# Single write dual read RAMs.
# NX_RFB_U in mode 4 (NX_XRFB_2R_1W)
ram distributed $__NX_XRFB_2R_1W_ {
cost 40;
widthscale 30;
abits 5;
width 18;
init no_undef;
port sw "W" {
clock anyedge;
}
port ar "A" {
}
port ar "B" {
}
}

View file

@ -0,0 +1,370 @@
/*
* yosys -- Yosys Open SYnthesis Suite
*
* Copyright (C) 2024 Hannah Ravensloft <lofty@yosyshq.com>
* Copyright (C) 2024 Miodrag Milanovic <micko@yosyshq.com>
*
* 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.
*
*/
#include "kernel/register.h"
#include "kernel/celltypes.h"
#include "kernel/rtlil.h"
#include "kernel/log.h"
USING_YOSYS_NAMESPACE
PRIVATE_NAMESPACE_BEGIN
struct SynthNanoXplorePass : public ScriptPass
{
SynthNanoXplorePass() : ScriptPass("synth_nanoxplore", "synthesis for NanoXplore FPGAs") { }
void on_register() override
{
RTLIL::constpad["synth_nanoxplore.abc9.W"] = "300";
}
void help() override
{
// |---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|---v---|
log("\n");
log(" synth_nanoxplore [options]\n");
log("\n");
log("This command runs synthesis for NanoXplore FPGAs.\n");
log("\n");
log(" -top <module>\n");
log(" use the specified module as top module\n");
log("\n");
log(" -family <family>\n");
log(" run synthesis for the specified NanoXplore architecture\n");
log(" generate the synthesis netlist for the specified family.\n");
log(" supported values:\n");
log(" - medium: NG-Medium\n");
log(" - large: NG-Large\n");
log(" - ultra: NG-Ultra\n");
log("\n");
log(" -json <file>\n");
log(" write the design to the specified JSON file. writing of an output file\n");
log(" is omitted if this parameter is not specified.\n");
log("\n");
log(" -run <from_label>:<to_label>\n");
log(" only run the commands between the labels (see below). an empty\n");
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(" -noflatten\n");
log(" do not flatten design before synthesis\n");
log("\n");
log(" -abc9\n");
log(" use new ABC9 flow (EXPERIMENTAL)\n");
log("\n");
log(" -nocy\n");
log(" do not map adders to CY cells\n");
log("\n");
log(" -nodffe\n");
log(" do not use flipflops with L in output netlist\n");
log("\n");
log(" -min_ce_use <min_ce_use>\n");
log(" do not use flip-flops with load signal if the resulting count is less\n");
log(" than min_ce_use in output netlist\n");
log("\n");
log(" -min_srst_use <min_srst_use>\n");
log(" do not use flip-flops with async reset signal if the resulting count is less\n");
log(" than min_srst_use in output netlist\n");
log("\n");
log(" -norfram\n");
log(" do not use Register File RAM cells in output netlist\n");
log("\n");
log(" -nobram\n");
log(" do not use block NX_RAM cells in output netlist\n");
log("\n");
log(" -noiopad\n");
log(" do not insert IO buffers\n");
log("\n");
log(" -no-rw-check\n");
log(" marks all recognized read ports as \"return don't-care value on\n");
log(" read/write collision\" (same result as setting the no_rw_check\n");
log(" attribute on all memories).\n");
log("\n");
log("\n");
log("The following commands are executed by this synthesis command:\n");
help_script();
log("\n");
}
string top_opt, json_file, family;
bool flatten, abc9, nocy, nodffe, norfram, nobram, noiopad, no_rw_check;
std::string postfix;
int min_ce_use, min_srst_use;
void clear_flags() override
{
top_opt = "-auto-top";
json_file = "";
family = "";
flatten = true;
abc9 = false;
nocy = false;
nodffe = false;
norfram = false;
nobram = false;
noiopad = false;
no_rw_check = false;
postfix = "";
min_ce_use = 8;
min_srst_use = 8;
}
void execute(std::vector<std::string> args, RTLIL::Design *design) override
{
string run_from, run_to;
clear_flags();
size_t argidx;
for (argidx = 1; argidx < args.size(); argidx++)
{
if (args[argidx] == "-top" && argidx+1 < args.size()) {
top_opt = "-top " + args[++argidx];
continue;
}
if ((args[argidx] == "-family" || args[argidx] == "-arch") && argidx+1 < args.size()) {
family = args[++argidx];
continue;
}
if (args[argidx] == "-json" && argidx+1 < args.size()) {
json_file = args[++argidx];
continue;
}
if (args[argidx] == "-run" && argidx+1 < args.size()) {
size_t pos = args[argidx+1].find(':');
if (pos == std::string::npos)
break;
run_from = args[++argidx].substr(0, pos);
run_to = args[argidx].substr(pos+1);
continue;
}
if (args[argidx] == "-flatten") {
flatten = true;
continue;
}
if (args[argidx] == "-noflatten") {
flatten = false;
continue;
}
if (args[argidx] == "-abc9") {
abc9 = true;
continue;
}
if (args[argidx] == "-nocy") {
nocy = true;
continue;
}
if (args[argidx] == "-nodffe") {
nodffe = true;
continue;
}
if (args[argidx] == "-min_ce_use" && argidx+1 < args.size()) {
min_ce_use = atoi(args[++argidx].c_str());
continue;
}
if (args[argidx] == "-min_srst_use" && argidx+1 < args.size()) {
min_srst_use = atoi(args[++argidx].c_str());
continue;
}
if (args[argidx] == "-norfram") {
norfram = true;
continue;
}
if (args[argidx] == "-nobram") {
nobram = true;
continue;
}
if (args[argidx] == "-iopad") {
noiopad = false;
continue;
}
if (args[argidx] == "-noiopad") {
noiopad = true;
continue;
}
if (args[argidx] == "-no-rw-check") {
no_rw_check = true;
continue;
}
break;
}
extra_args(args, argidx, design);
if (family.empty()) {
//log_warning("NanoXplore family not set, setting it to NG-ULTRA.\n");
family = "ultra";
}
if (family == "ultra") {
postfix = "_u";
} else if (family == "medium") {
postfix = "_m";
} else if (family == "large") {
postfix = "_l";
} else
log_cmd_error("Invalid NanoXplore -family setting: '%s'.\n", family.c_str());
if (!design->full_selection())
log_cmd_error("This command only operates on fully selected designs!\n");
log_header(design, "Executing SYNTH_NANOXPLORE pass.\n");
log_push();
run_script(design, run_from, run_to);
log_pop();
}
void script() override
{
std::string no_rw_check_opt = "";
if (no_rw_check)
no_rw_check_opt = " -no-rw-check";
if (help_mode)
no_rw_check_opt = " [-no-rw-check]";
if (check_label("begin"))
{
run("read_verilog -lib -specify +/nanoxplore/cells_sim.v +/nanoxplore/cells_sim" + postfix + ".v +/nanoxplore/cells_bb.v +/nanoxplore/cells_bb" + postfix + ".v");
run("techmap -map +/nanoxplore/cells_wrap.v");
run("techmap -map +/nanoxplore/cells_wrap" + postfix + ".v");
run(stringf("hierarchy -check %s", help_mode ? "-top <top>" : top_opt.c_str()));
}
if (check_label("coarse"))
{
run("proc");
if (flatten || help_mode)
run("flatten", "(skip if -noflatten)");
run("tribuf -logic");
run("deminout");
run("opt_expr");
run("opt_clean");
run("check");
run("opt -nodffe -nosdff");
run("fsm");
run("opt");
run("wreduce");
run("peepopt");
run("opt_clean");
run("share");
run("techmap -map +/cmp2lut.v -D LUT_WIDTH=4");
run("opt_expr");
run("opt_clean");
run("alumacc");
run("opt");
run("memory -nomap" + no_rw_check_opt);
run("opt_clean");
}
if (check_label("map_ram"))
{
std::string args = "";
if (family == "medium")
args += " -D IS_NG_MEDIUM";
if (nobram)
args += " -no-auto-block";
if (norfram)
args += " -no-auto-distributed";
if (help_mode)
args += " [-no-auto-block] [-no-auto-distributed]";
run("memory_libmap -lib +/nanoxplore/rf_rams"+ postfix + ".txt -lib +/nanoxplore/brams.txt" + args, "(-no-auto-block if -nobram, -no-auto-distributed if -norfram)");
run("techmap -map +/nanoxplore/rf_rams_map"+ postfix + ".v -map +/nanoxplore/brams_map.v");
run("techmap -map +/nanoxplore/cells_wrap.v t:NX_RAM*");
run("techmap -map +/nanoxplore/cells_wrap" + postfix + ".v t:NX_XRFB* t:NX_RFB*");
}
if (check_label("map_ffram"))
{
run("opt -fast -mux_undef -undriven -fine");
run("memory_map");
run("opt -undriven -fine -mux_undef");
}
if (check_label("map_gates"))
{
if (nocy)
run("techmap");
else {
run("techmap -map +/techmap.v -map +/nanoxplore/arith_map.v");
run("nx_carry");
}
if (help_mode || !noiopad) {
run("iopadmap -bits -outpad $__BEYOND_OBUF I:PAD -toutpad $__BEYOND_TOBUF C:I:PAD -inpad $__BEYOND_IBUF O:PAD -tinoutpad $__BEYOND_IOBUF C:O:I:PAD A:top", "(skip if '-noiopad')");
run("techmap -map +/nanoxplore/io_map.v");
}
run("opt -fast");
}
if (check_label("map_ffs"))
{
std::string dfflegalize_args = " -cell $_DFF_?_ 01 -cell $_DFF_?P?_ r -cell $_SDFF_?P?_ r";
if (help_mode) {
dfflegalize_args += " [-cell $_DFFE_?P_ 01 -cell $_DFFE_?P?P_ r -cell $_SDFFE_?P?P_ r]";
} else if (!nodffe) {
dfflegalize_args += " -cell $_DFFE_?P_ 01 -cell $_DFFE_?P?P_ r -cell $_SDFFE_?P?P_ r";
}
dfflegalize_args += stringf(" -cell $_DLATCH_?_ x -mince %d -minsrst %d", min_ce_use, min_srst_use);
run("dfflegalize" + dfflegalize_args,"($_*DFFE_* only if not -nodffe)");
run("opt_merge");
run("techmap -map +/nanoxplore/latches_map.v");
run("techmap -map +/nanoxplore/cells_map.v");
run("opt_expr -undriven -mux_undef");
run("clean -purge");
}
if (check_label("map_luts"))
{
if (abc9) {
std::string abc9_opts = " -maxlut 4";
std::string k = "synth_nanoxplore.abc9.W";
if (active_design && active_design->scratchpad.count(k))
abc9_opts += stringf(" -W %s", active_design->scratchpad_get_string(k).c_str());
else
abc9_opts += stringf(" -W %s", RTLIL::constpad.at(k).c_str());
run("abc9" + abc9_opts);
} else {
std::string abc_args = " -dress";
abc_args += " -lut 4";
run("abc" + abc_args);
}
run("techmap -map +/nanoxplore/cells_map.v t:$lut");
run("opt -fast");
run("clean");
}
if (check_label("check"))
{
run("autoname");
run("hierarchy -check");
run("stat");
run("check -noinit");
run("blackbox =A:whitebox");
run("setundef -zero -undriven");
}
if (check_label("json"))
{
if (!json_file.empty() || help_mode)
run(stringf("write_json %s", help_mode ? "<file-name>" : json_file.c_str()));
}
}
} SynthNanoXplorePass;
PRIVATE_NAMESPACE_END

2
tests/arch/nanoxplore/.gitignore vendored Normal file
View file

@ -0,0 +1,2 @@
*.log
/run-test.mk

View file

@ -0,0 +1,71 @@
read_verilog ../common/add_sub.v
hierarchy -top top
proc
equiv_opt -run :prove -map +/nanoxplore/cells_sim.v -map +/nanoxplore/cells_sim_u.v synth_nanoxplore -noiopad
opt -full
miter -equiv -flatten -make_assert -make_outputs gold gate miter
sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd top # Constrain all select calls below inside the top module
select -assert-count 2 t:NX_CY
select -assert-count 4 t:NX_LUT
select -assert-none t:NX_CY t:NX_LUT %% t:* %D
design -reset
read_verilog <<EOT
module top
(
input [5:0] x,
input [5:0] y,
output [5:0] A,
input CI,
output CO
);
assign {CO, A} = x + y + CI;
endmodule
EOT
hierarchy -top top
proc
equiv_opt -run :prove -map +/nanoxplore/cells_sim.v -map +/nanoxplore/cells_sim_u.v synth_nanoxplore -noiopad
opt -full
miter -equiv -flatten -make_assert -make_outputs gold gate miter
sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter
design -load postopt
cd top
stat
select -assert-count 2 t:NX_CY
select -assert-none t:NX_CY %% t:* %D
design -reset
read_verilog <<EOT
module top
(
input [189:0] x,
input [189:0] y,
output [189:0] A
);
assign A = x + y;
endmodule
EOT
hierarchy -top top
proc
equiv_opt -run :prove -map +/nanoxplore/cells_sim.v -map +/nanoxplore/cells_sim_u.v synth_nanoxplore -noiopad
opt -full
miter -equiv -flatten -make_assert -make_outputs gold gate miter
sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter
design -load postopt
cd top
stat
select -assert-count 48 t:NX_CY
select -assert-none t:NX_CY %% t:* %D

View file

@ -0,0 +1,47 @@
read_verilog ../common/adffs.v
design -save read
hierarchy -top adff
proc
equiv_opt -async2sync -assert -map +/nanoxplore/cells_sim.v synth_nanoxplore -noiopad # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd adff # Constrain all select calls below inside the top module
select -assert-count 1 t:NX_DFF
select -assert-none t:NX_DFF %% t:* %D
design -load read
hierarchy -top adffn
proc
equiv_opt -async2sync -assert -map +/nanoxplore/cells_sim.v synth_nanoxplore -noiopad # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd adffn # Constrain all select calls below inside the top module
select -assert-count 1 t:NX_DFF
select -assert-count 1 t:NX_LUT
select -assert-none t:NX_DFF t:NX_LUT %% t:* %D
design -load read
hierarchy -top dffs
proc
equiv_opt -async2sync -assert -map +/nanoxplore/cells_sim.v synth_nanoxplore -noiopad # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd dffs # Constrain all select calls below inside the top module
select -assert-count 1 t:NX_DFF
select -assert-count 1 t:NX_LUT
select -assert-none t:NX_DFF t:NX_LUT %% t:* %D
design -load read
hierarchy -top ndffnr
proc
equiv_opt -async2sync -assert -map +/nanoxplore/cells_sim.v synth_nanoxplore -noiopad # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd ndffnr # Constrain all select calls below inside the top module
select -assert-count 1 t:NX_DFF
select -assert-count 1 t:NX_LUT
select -assert-none t:NX_DFF t:NX_LUT %% t:* %D

View file

@ -0,0 +1,22 @@
read_verilog ../common/dffs.v
design -save read
hierarchy -top dff
proc
equiv_opt -assert -async2sync -map +/nanoxplore/cells_sim.v synth_nanoxplore -noiopad # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd dff # Constrain all select calls below inside the top module
select -assert-count 1 t:NX_DFF
select -assert-none t:NX_DFF %% t:* %D
design -load read
hierarchy -top dffe
proc
equiv_opt -assert -async2sync -map +/nanoxplore/cells_sim.v synth_nanoxplore -noiopad -min_ce_use 0 # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd dffe # Constrain all select calls below inside the top module
stat
select -assert-count 1 t:NX_DFF
select -assert-none t:NX_DFF %% t:* %D

View file

@ -0,0 +1,16 @@
read_verilog ../common/fsm.v
hierarchy -top fsm
proc
flatten
equiv_opt -run :prove -map +/nanoxplore/cells_sim.v synth_nanoxplore -noiopad
async2sync
miter -equiv -make_assert -flatten gold gate miter
sat -verify -prove-asserts -show-public -set-at 1 in_reset 1 -seq 20 -prove-skip 1 miter
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd fsm # Constrain all select calls below inside the top module
select -assert-count 6 t:NX_DFF
select -assert-min 13 t:NX_LUT
select -assert-none t:NX_DFF t:NX_LUT %% t:* %D

View file

@ -0,0 +1,33 @@
read_verilog ../common/latches.v
design -save read
hierarchy -top latchp
proc
# Can't run any sort of equivalence check because latches are blown to LUTs
synth_nanoxplore -noiopad
cd latchp # Constrain all select calls below inside the top module
select -assert-count 1 t:NX_LUT
select -assert-none t:NX_LUT %% t:* %D
design -load read
hierarchy -top latchn
proc
# Can't run any sort of equivalence check because latches are blown to LUTs
synth_nanoxplore -noiopad
cd latchn # Constrain all select calls below inside the top module
select -assert-count 1 t:NX_LUT
select -assert-none t:NX_LUT %% t:* %D
design -load read
hierarchy -top latchsr
proc
# Can't run any sort of equivalence check because latches are blown to LUTs
synth_nanoxplore -noiopad
cd latchsr # Constrain all select calls below inside the top module
select -assert-count 2 t:NX_LUT
select -assert-none t:NX_LUT %% t:* %D

View file

@ -0,0 +1,9 @@
read_verilog ../common/logic.v
hierarchy -top top
proc
equiv_opt -assert -map +/nanoxplore/cells_sim.v synth_nanoxplore -noiopad # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd top # Constrain all select calls below inside the top module
select -assert-count 9 t:NX_LUT
select -assert-none t:NX_LUT %% t:* %D

View file

@ -0,0 +1,145 @@
# Dual-port RAMs.
# NX_RFB_U in mode 0 (DPREG)
read_verilog <<EOT
module lutram_dpreg
#(parameter D_WIDTH=18, A_WIDTH=5)
(
input [D_WIDTH-1:0] data,
input [A_WIDTH:1] addr_w, addr_r,
input we, clk,
output reg [D_WIDTH-1:0] q
);
// Declare the RAM variable
reg [D_WIDTH-1:0] ram[(2**A_WIDTH)-1:0];
// Port A
always @ (posedge clk)
begin
if (we)
ram[addr_w] <= data;
q <= ram[addr_r];
end
endmodule
EOT
hierarchy -top lutram_dpreg
proc
memory -nomap
equiv_opt -run :prove -map +/nanoxplore/cells_sim.v -map +/nanoxplore/cells_sim_u.v synth_nanoxplore -noiopad
memory
opt -full
miter -equiv -flatten -make_assert -make_outputs gold gate miter
sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter
design -load postopt
cd lutram_dpreg
stat
select -assert-count 1 t:NX_RFB_U r:mode=0 %i
select -assert-count 18 t:NX_DFF
select -assert-none t:NX_RFB_U t:NX_DFF %% t:* %D
# Single-port RAMs.
# NX_RFB_U in mode 1 (SPREG)
design -reset
read_verilog ../common/lutram.v
hierarchy -top lutram_1w1r -chparam A_WIDTH 5 -chparam D_WIDTH 18
proc
memory -nomap
equiv_opt -run :prove -map +/nanoxplore/cells_sim.v -map +/nanoxplore/cells_sim_u.v synth_nanoxplore -noiopad
memory
opt -full
miter -equiv -flatten -make_assert -make_outputs gold gate miter
sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter
design -load postopt
cd lutram_1w1r
select -assert-count 1 t:NX_RFB_U r:mode=1 %i
select -assert-count 18 t:NX_DFF
select -assert-none t:NX_RFB_U t:NX_DFF %% t:* %D
# Dual-port RAMs.
# NX_RFB_U in mode 2 (NX_XRFB_64x18)
design -reset
read_verilog ../common/lutram.v
hierarchy -top lutram_1w1r -chparam A_WIDTH 6 -chparam D_WIDTH 18
proc
memory -nomap
equiv_opt -run :prove -map +/nanoxplore/cells_sim.v -map +/nanoxplore/cells_sim_u.v synth_nanoxplore -noiopad
memory
opt -full
miter -equiv -flatten -make_assert -make_outputs gold gate miter
sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter
design -load postopt
cd lutram_1w1r
select -assert-count 1 t:NX_RFB_U r:mode=2 %i
select -assert-count 18 t:NX_DFF
select -assert-none t:NX_RFB_U t:NX_DFF %% t:* %D
# Dual-port RAMs.
# NX_RFB_U in mode 3 (NX_XRFB_32x36)
design -reset
read_verilog ../common/lutram.v
hierarchy -top lutram_1w1r -chparam A_WIDTH 5 -chparam D_WIDTH 36
proc
memory -nomap
equiv_opt -run :prove -map +/nanoxplore/cells_sim.v -map +/nanoxplore/cells_sim_u.v synth_nanoxplore -noiopad
memory
opt -full
miter -equiv -flatten -make_assert -make_outputs gold gate miter
sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter
design -load postopt
cd lutram_1w1r
select -assert-count 1 t:NX_RFB_U r:mode=3 %i
select -assert-count 36 t:NX_DFF
select -assert-none t:NX_RFB_U t:NX_DFF %% t:* %D
# Single write dual read RAMs.
# NX_RFB_U in mode 4 (NX_XRFB_2R_1W)
design -reset
read_verilog <<EOT
module lutram_1w2r
#(parameter D_WIDTH=8, A_WIDTH=5)
(
input [D_WIDTH-1:0] data_a, data_b,
input [A_WIDTH:1] addr_a, addr_b,
input we_a, clk,
output reg [D_WIDTH-1:0] q_a, q_b
);
// Declare the RAM variable
reg [D_WIDTH-1:0] ram[(2**A_WIDTH)-1:0];
// Port A
always @ (posedge clk)
begin
if (we_a)
ram[addr_a] <= data_a;
q_a <= ram[addr_a];
q_b <= ram[addr_b];
end
endmodule
EOT
hierarchy -top lutram_1w2r -chparam A_WIDTH 5 -chparam D_WIDTH 18
proc
memory -nomap
equiv_opt -run :prove -map +/nanoxplore/cells_sim.v -map +/nanoxplore/cells_sim_u.v synth_nanoxplore -noiopad
memory
opt -full
miter -equiv -flatten -make_assert -make_outputs gold gate miter
sat -verify -prove-asserts -seq 3 -set-init-zero -show-inputs -show-outputs miter
design -load postopt
cd lutram_1w2r
select -assert-count 1 t:NX_RFB_U r:mode=4 %i
select -assert-count 36 t:NX_DFF
select -assert-none t:NX_RFB_U t:NX_DFF %% t:* %D

View file

@ -0,0 +1,50 @@
module top(clk);
parameter DEPTH_LOG2 = 10;
parameter WIDTH = 36;
parameter PRIME = 237481091;
localparam DEPTH = 2**DEPTH_LOG2;
input wire clk;
(* syn_ramstyle = "distributed" *)
reg [WIDTH-1:0] mem [DEPTH-1:0];
integer i;
initial begin
for (i = 0; i < DEPTH; i = i + 1) begin
// Make up data by multiplying a large prime with the address,
// then cropping and retaining the lower bits
mem[i] = PRIME * (i*2+1);
end
end
reg [DEPTH_LOG2-1:0] counter = 0;
reg done = 1'b0;
reg did_read = 1'b0;
reg [DEPTH_LOG2-1:0] read_addr;
reg [WIDTH-1:0] read_val;
always @(posedge clk) begin
if (!done) begin
did_read <= 1'b1;
read_addr <= counter;
read_val <= mem[counter];
end else begin
did_read <= 1'b0;
end
if (!done)
counter = counter + 1;
if (counter == 0)
done = 1;
end
wire [WIDTH-1:0] expect_val = PRIME * (read_addr*2+1);
always @(posedge clk) begin
if (did_read) begin
$display("addr %x expected %x actual %x", read_addr, expect_val, read_val);
assert(read_val == expect_val);
end
end
endmodule

View file

@ -0,0 +1,44 @@
read_verilog -sv meminit.v
chparam -set DEPTH_LOG2 5 -set WIDTH 36
prep
opt_dff
prep -rdff
synth_nanoxplore
clean_zerowidth
select -assert-none t:$mem_v2 t:$mem
read_verilog +/nanoxplore/cells_sim.v +/nanoxplore/cells_sim_u.v
prep
async2sync
hierarchy -top top
sim -assert -q -n 66 -clock clk
design -reset
read_verilog -sv meminit.v
chparam -set DEPTH_LOG2 6 -set WIDTH 18
prep
opt_dff
prep -rdff
synth_nanoxplore
clean_zerowidth
select -assert-none t:$mem_v2 t:$mem
read_verilog +/nanoxplore/cells_sim.v +/nanoxplore/cells_sim_u.v
prep
async2sync
hierarchy -top top
sim -assert -q -n 34 -clock clk
design -reset
read_verilog -sv meminit.v
chparam -set DEPTH_LOG2 8 -set WIDTH 18
prep
opt_dff
prep -rdff
synth_nanoxplore
clean_zerowidth
select -assert-none t:$mem_v2 t:$mem
read_verilog +/nanoxplore/cells_sim.v +/nanoxplore/cells_sim_u.v
prep
async2sync
hierarchy -top top
sim -assert -q -n 258 -clock clk

View file

@ -0,0 +1,41 @@
read_verilog ../common/mux.v
design -save read
hierarchy -top mux2
proc
equiv_opt -assert -map +/nanoxplore/cells_sim.v synth_nanoxplore -noiopad # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd mux2 # Constrain all select calls below inside the top module
select -assert-count 1 t:NX_LUT
select -assert-none t:NX_LUT %% t:* %D
design -load read
hierarchy -top mux4
proc
equiv_opt -assert -map +/nanoxplore/cells_sim.v synth_nanoxplore -noiopad # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd mux4 # Constrain all select calls below inside the top module
#select -assert-count 2 t:NX_LUT
select -assert-none t:NX_LUT %% t:* %D
design -load read
hierarchy -top mux8
proc
equiv_opt -assert -map +/nanoxplore/cells_sim.v synth_nanoxplore -noiopad # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd mux8 # Constrain all select calls below inside the top module
#select -assert-count 5 t:NX_LUT
select -assert-none t:NX_LUT %% t:* %D
design -load read
hierarchy -top mux16
proc
equiv_opt -assert -map +/nanoxplore/cells_sim.v synth_nanoxplore -noiopad # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd mux16 # Constrain all select calls below inside the top module
select -assert-max 13 t:NX_LUT
select -assert-none t:NX_LUT %% t:* %D

View file

@ -0,0 +1,4 @@
#!/usr/bin/env bash
set -eu
source ../../gen-tests-makefile.sh
run_tests --yosys-scripts --bash --yosys-args "-w 'Yosys has only limited support for tri-state logic at the moment.'"

View file

@ -0,0 +1,10 @@
read_verilog ../common/shifter.v
hierarchy -top top
proc
flatten
equiv_opt -async2sync -assert -map +/nanoxplore/cells_sim.v synth_nanoxplore -noiopad # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd top # Constrain all select calls below inside the top module
select -assert-count 8 t:NX_DFF
select -assert-none t:NX_DFF %% t:* %D

View file

@ -0,0 +1,13 @@
read_verilog ../common/tribuf.v
hierarchy -top tristate
proc
tribuf
flatten
synth
equiv_opt -assert -map +/nanoxplore/cells_sim.v -map +/simcells.v synth_nanoxplore # equivalency check
design -load postopt # load the post-opt design (otherwise equiv_opt loads the pre-opt design)
cd tristate # Constrain all select calls below inside the top module
#Internal cell type used. Need support it.
select -assert-count 1 t:NX_IOB
select -assert-count 2 t:NX_IOB_I
select -assert-none t:NX_IOB t:NX_IOB_I %% t:* %D