mirror of
https://github.com/YosysHQ/yosys
synced 2025-04-24 01:25:33 +00:00
Merge pull request #1449 from pepijndevos/gowin
Improvements for gowin support
This commit is contained in:
commit
7ea0a5937b
27 changed files with 842 additions and 90 deletions
|
@ -15,3 +15,13 @@ $(eval $(call add_share_file,share/gowin,techlibs/gowin/dram.txt))
|
|||
|
||||
$(eval $(call add_share_file,share/gowin,techlibs/gowin/brams_init3.vh))
|
||||
|
||||
EXTRA_OBJS += techlibs/gowin/brams_init.mk
|
||||
.SECONDARY: techlibs/gowin/brams_init.mk
|
||||
|
||||
techlibs/gowin/brams_init.mk: techlibs/gowin/brams_init.py
|
||||
$(Q) mkdir -p techlibs/gowin
|
||||
$(P) python3 $<
|
||||
$(Q) touch $@
|
||||
|
||||
techlibs/gowin/bram_init_16.vh: techlibs/gowin/brams_init.mk
|
||||
$(eval $(call add_gen_share_file,share/gowin,techlibs/gowin/bram_init_16.vh))
|
||||
|
|
|
@ -40,15 +40,15 @@ module _80_gw1n_alu(A, B, CI, BI, X, Y, CO);
|
|||
\$pos #(.A_SIGNED(B_SIGNED), .A_WIDTH(B_WIDTH), .Y_WIDTH(Y_WIDTH)) B_conv (.A(B), .Y(B_buf));
|
||||
|
||||
wire [Y_WIDTH-1:0] AA = A_buf;
|
||||
wire [Y_WIDTH-1:0] BB = BI ? ~B_buf : B_buf;
|
||||
wire [Y_WIDTH-1:0] BB = B_buf;
|
||||
wire [Y_WIDTH-1:0] C = {CO, CI};
|
||||
|
||||
genvar i;
|
||||
generate for (i = 0; i < Y_WIDTH; i = i + 1) begin:slice
|
||||
ALU #(.ALU_MODE(32'b0))
|
||||
ALU #(.ALU_MODE(2)) // ADDSUB I3 ? add : sub
|
||||
alu(.I0(AA[i]),
|
||||
.I1(BB[i]),
|
||||
.I3(1'b0),
|
||||
.I3(~BI),
|
||||
.CIN(C[i]),
|
||||
.COUT(CO[i]),
|
||||
.SUM(Y[i])
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
bram $__GW1NR_SDP
|
||||
# uncomment when done
|
||||
# init 1
|
||||
init 1
|
||||
abits 9 @a9d36
|
||||
dbits 32 @a9d36
|
||||
abits 10 @a10d18
|
||||
dbits 16 @a10d18
|
||||
abits 11 @a11d9
|
||||
|
@ -14,7 +15,8 @@ bram $__GW1NR_SDP
|
|||
groups 2
|
||||
ports 1 1
|
||||
wrmode 1 0
|
||||
enable 1 1 @a10d18
|
||||
enable 4 1 @a9d36
|
||||
enable 2 1 @a10d18
|
||||
enable 1 1 @a11d9 @a12d4 @a13d2 @a14d1
|
||||
transp 0 0
|
||||
clocks 2 3
|
||||
|
@ -24,6 +26,6 @@ endbram
|
|||
match $__GW1NR_SDP
|
||||
min bits 2048
|
||||
min efficiency 5
|
||||
shuffle_enable B
|
||||
shuffle_enable A
|
||||
make_transp
|
||||
endmatch
|
||||
|
|
8
techlibs/gowin/brams_init.py
Executable file
8
techlibs/gowin/brams_init.py
Executable file
|
@ -0,0 +1,8 @@
|
|||
#!/usr/bin/env python3
|
||||
|
||||
with open("techlibs/gowin/bram_init_16.vh", "w") as f:
|
||||
for i in range(0, 0x40):
|
||||
low = i << 8
|
||||
hi = ((i+1) << 8)-1
|
||||
snippet = "INIT[%d:%d]" % (hi, low)
|
||||
print(".INIT_RAM_%02X({%s})," % (i, snippet), file=f)
|
|
@ -8,26 +8,28 @@
|
|||
module \$__GW1NR_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
||||
parameter CFG_ABITS = 10;
|
||||
parameter CFG_DBITS = 16;
|
||||
parameter CFG_ENABLE_A = 3;
|
||||
|
||||
parameter [16383:0] INIT = 16384'hx;
|
||||
parameter CLKPOL2 = 1;
|
||||
parameter CLKPOL3 = 1;
|
||||
parameter CFG_ENABLE_A = 1;
|
||||
parameter [16383:0] INIT = 16384'hx;
|
||||
parameter CLKPOL2 = 1;
|
||||
parameter CLKPOL3 = 1;
|
||||
|
||||
input CLK2;
|
||||
input CLK3;
|
||||
|
||||
input [CFG_ABITS-1:0] A1ADDR;
|
||||
input [CFG_DBITS-1:0] A1DATA;
|
||||
input [CFG_ENABLE_A-1:0] A1EN;
|
||||
input [CFG_ENABLE_A-1:0] A1EN;
|
||||
|
||||
input [CFG_ABITS-1:0] B1ADDR;
|
||||
output [CFG_DBITS-1:0] B1DATA;
|
||||
input B1EN;
|
||||
|
||||
wire [31-CFG_DBITS:0] open;
|
||||
|
||||
|
||||
generate if (CFG_DBITS == 1) begin
|
||||
SDP #(
|
||||
`include "bram_init_16.vh"
|
||||
.READ_MODE(0),
|
||||
.BIT_WIDTH_0(1),
|
||||
.BIT_WIDTH_1(1),
|
||||
|
@ -38,10 +40,14 @@ module \$__GW1NR_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
|||
.WREA(A1EN), .OCE(1'b0), .CEA(1'b1),
|
||||
.WREB(1'b0), .CEB(B1EN),
|
||||
.RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000),
|
||||
.DI(A1DATA), .DO(B1DATA), .ADA(A1ADDR), .ADB(B1ADDR)
|
||||
.DI({{(32-CFG_DBITS){1'b0}}, A1DATA}),
|
||||
.DO({open, B1DATA}),
|
||||
.ADA({A1ADDR, {(14-CFG_ABITS){1'b0}}}),
|
||||
.ADB({B1ADDR, {(14-CFG_ABITS){1'b0}}})
|
||||
);
|
||||
end else if (CFG_DBITS == 2) begin
|
||||
SDP #(
|
||||
`include "bram_init_16.vh"
|
||||
.READ_MODE(0),
|
||||
.BIT_WIDTH_0(2),
|
||||
.BIT_WIDTH_1(2),
|
||||
|
@ -52,10 +58,14 @@ module \$__GW1NR_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
|||
.WREA(A1EN), .OCE(1'b0), .CEA(1'b1),
|
||||
.WREB(1'b0), .CEB(B1EN),
|
||||
.RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000),
|
||||
.DI(A1DATA), .DO(B1DATA), .ADA(A1ADDR), .ADB(B1ADDR)
|
||||
.DI({{(32-CFG_DBITS){1'b0}}, A1DATA}),
|
||||
.DO({open, B1DATA}),
|
||||
.ADA({A1ADDR, {(14-CFG_ABITS){1'b0}}}),
|
||||
.ADB({B1ADDR, {(14-CFG_ABITS){1'b0}}})
|
||||
);
|
||||
end else if (CFG_DBITS <= 4) begin
|
||||
SDP #(
|
||||
`include "bram_init_16.vh"
|
||||
.READ_MODE(0),
|
||||
.BIT_WIDTH_0(4),
|
||||
.BIT_WIDTH_1(4),
|
||||
|
@ -66,10 +76,14 @@ module \$__GW1NR_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
|||
.WREA(A1EN), .OCE(1'b0),
|
||||
.WREB(1'b0), .CEB(B1EN), .CEA(1'b1),
|
||||
.RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000),
|
||||
.DI(A1DATA), .DO(B1DATA), .ADA(A1ADDR), .ADB(B1ADDR)
|
||||
.DI({{(32-CFG_DBITS){1'b0}}, A1DATA}),
|
||||
.DO({open, B1DATA}),
|
||||
.ADA({A1ADDR, {(14-CFG_ABITS){1'b0}}}),
|
||||
.ADB({B1ADDR, {(14-CFG_ABITS){1'b0}}})
|
||||
);
|
||||
end else if (CFG_DBITS <= 8) begin
|
||||
SDP #(
|
||||
`include "bram_init_16.vh"
|
||||
.READ_MODE(0),
|
||||
.BIT_WIDTH_0(8),
|
||||
.BIT_WIDTH_1(8),
|
||||
|
@ -80,10 +94,14 @@ module \$__GW1NR_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
|||
.WREA(A1EN), .OCE(1'b0), .CEA(1'b1),
|
||||
.WREB(1'b0), .CEB(B1EN),
|
||||
.RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000),
|
||||
.DI(A1DATA), .DO(B1DATA), .ADA(A1ADDR), .ADB(B1ADDR)
|
||||
.DI({{(32-CFG_DBITS){1'b0}}, A1DATA}),
|
||||
.DO({open, B1DATA}),
|
||||
.ADA({A1ADDR, {(14-CFG_ABITS){1'b0}}}),
|
||||
.ADB({B1ADDR, {(14-CFG_ABITS){1'b0}}})
|
||||
);
|
||||
end else if (CFG_DBITS <= 16) begin
|
||||
SDP #(
|
||||
`include "bram_init_16.vh"
|
||||
.READ_MODE(0),
|
||||
.BIT_WIDTH_0(16),
|
||||
.BIT_WIDTH_1(16),
|
||||
|
@ -91,10 +109,31 @@ module \$__GW1NR_SDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
|
|||
.RESET_MODE("SYNC")
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.CLKA(CLK2), .CLKB(CLK3),
|
||||
.WREA(A1EN), .OCE(1'b0),
|
||||
.WREA(|A1EN), .OCE(1'b0),
|
||||
.WREB(1'b0), .CEB(B1EN), .CEA(1'b1),
|
||||
.RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000),
|
||||
.DI(A1DATA), .DO(B1DATA), .ADA(A1ADDR), .ADB(B1ADDR)
|
||||
.DI({{(32-CFG_DBITS){1'b0}}, A1DATA}),
|
||||
.DO({open, B1DATA}),
|
||||
.ADA({A1ADDR, {(12-CFG_ABITS){1'b0}}, A1EN}),
|
||||
.ADB({B1ADDR, {(14-CFG_ABITS){1'b0}}})
|
||||
);
|
||||
end else if (CFG_DBITS <= 32) begin
|
||||
SDP #(
|
||||
`include "bram_init_16.vh"
|
||||
.READ_MODE(0),
|
||||
.BIT_WIDTH_0(32),
|
||||
.BIT_WIDTH_1(32),
|
||||
.BLK_SEL(3'b000),
|
||||
.RESET_MODE("SYNC")
|
||||
) _TECHMAP_REPLACE_ (
|
||||
.CLKA(CLK2), .CLKB(CLK3),
|
||||
.WREA(|A1EN), .OCE(1'b0),
|
||||
.WREB(1'b0), .CEB(B1EN), .CEA(1'b1),
|
||||
.RESETA(1'b0), .RESETB(1'b0), .BLKSEL(3'b000),
|
||||
.DI(A1DATA),
|
||||
.DO(B1DATA),
|
||||
.ADA({A1ADDR, {(10-CFG_ABITS){1'b0}}, A1EN}),
|
||||
.ADB({B1ADDR, {(14-CFG_ABITS){1'b0}}})
|
||||
);
|
||||
end else begin
|
||||
wire TECHMAP_FAIL = 1'b1;
|
||||
|
|
|
@ -1,9 +1,83 @@
|
|||
module \$_DFF_N_ (input D, C, output Q); DFFN _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C)); endmodule
|
||||
module \$_DFF_P_ #(parameter INIT = 1'b0) (input D, C, output Q); DFF #(.INIT(INIT)) _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C)); endmodule
|
||||
//All DFF* have INIT, but the hardware is always initialised to the reset
|
||||
//value regardless. The parameter is ignored.
|
||||
|
||||
// DFFN D Flip-Flop with Negative-Edge Clock
|
||||
module \$_DFF_N_ (input D, C, output Q); DFFN _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C)); endmodule
|
||||
// DFF D Flip-Flop
|
||||
module \$_DFF_P_ (input D, C, output Q); DFF _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C)); endmodule
|
||||
|
||||
// DFFE D Flip-Flop with Clock Enable
|
||||
module \$_DFFE_PP_ (input D, C, E, output Q); DFFE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(E)); endmodule
|
||||
module \$_DFFE_PN_ (input D, C, E, output Q); DFFE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(!E)); endmodule
|
||||
|
||||
// DFFNE D Flip-Flop with Negative-Edge Clock and Clock Enable
|
||||
module \$_DFFE_NP_ (input D, C, E, output Q); DFFNE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(E)); endmodule
|
||||
module \$_DFFE_NN_ (input D, C, E, output Q); DFFNE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CE(!E)); endmodule
|
||||
|
||||
// DFFR D Flip-Flop with Synchronous Reset
|
||||
module \$__DFFS_PN0_ (input D, C, R, output Q); DFFR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(!R)); endmodule
|
||||
module \$__DFFS_PP0_ (input D, C, R, output Q); DFFR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R)); endmodule
|
||||
module \$__DFFS_PP1_ (input D, C, R, output Q); DFFR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R)); endmodule
|
||||
|
||||
// DFFNR D Flip-Flop with Negative-Edge Clock and Synchronous Reset
|
||||
module \$__DFFS_NN0_ (input D, C, R, output Q); DFFNR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(!R)); endmodule
|
||||
module \$__DFFS_NP0_ (input D, C, R, output Q); DFFNR _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R)); endmodule
|
||||
|
||||
// DFFRE D Flip-Flop with Clock Enable and Synchronous Reset
|
||||
module \$__DFFSE_PN0 (input D, C, R, E, output Q); DFFRE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(!R), .CE(E)); endmodule
|
||||
module \$__DFFSE_PP0 (input D, C, R, E, output Q); DFFRE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R), .CE(E)); endmodule
|
||||
|
||||
// DFFNRE D Flip-Flop with Negative-Edge Clock,Clock Enable, and Synchronous Reset
|
||||
module \$__DFFNSE_PN0 (input D, C, R, E, output Q); DFFNRE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(!R), .CE(E)); endmodule
|
||||
module \$__DFFNSE_PP0 (input D, C, R, E, output Q); DFFNRE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .RESET(R), .CE(E)); endmodule
|
||||
|
||||
// DFFS D Flip-Flop with Synchronous Set
|
||||
module \$__DFFS_PN1_ (input D, C, R, output Q); DFFS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(!R)); endmodule
|
||||
module \$__DFFS_PP1_ (input D, C, R, output Q); DFFS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(R)); endmodule
|
||||
|
||||
// DFFNS D Flip-Flop with Negative-Edge Clock and Synchronous Set
|
||||
module \$__DFFS_NN1_ (input D, C, R, output Q); DFFNS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(!R)); endmodule
|
||||
module \$__DFFS_NP1_ (input D, C, R, output Q); DFFNS _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(R)); endmodule
|
||||
|
||||
// DFFSE D Flip-Flop with Clock Enable and Synchronous Set
|
||||
module \$__DFFSE_PN1 (input D, C, R, E, output Q); DFFSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(!R), .CE(E)); endmodule
|
||||
module \$__DFFSE_PP1 (input D, C, R, E, output Q); DFFSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(R), .CE(E)); endmodule
|
||||
|
||||
// DFFNSE D Flip-Flop with Negative-Edge Clock,Clock Enable,and Synchronous Set
|
||||
module \$__DFFSE_NN1 (input D, C, R, E, output Q); DFFNSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(!R), .CE(E)); endmodule
|
||||
module \$__DFFSE_NP1 (input D, C, R, E, output Q); DFFNSE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .SET(R), .CE(E)); endmodule
|
||||
|
||||
// DFFP D Flip-Flop with Asynchronous Preset
|
||||
module \$_DFF_PP1_ (input D, C, R, output Q); DFFP _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(R)); endmodule
|
||||
module \$_DFF_PN1_ (input D, C, R, output Q); DFFP _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(!R)); endmodule
|
||||
|
||||
// DFFNP D Flip-Flop with Negative-Edge Clock and Asynchronous Preset
|
||||
module \$_DFF_NP1_ (input D, C, R, output Q); DFFNP _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(R)); endmodule
|
||||
module \$_DFF_NN1_ (input D, C, R, output Q); DFFNP _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(!R)); endmodule
|
||||
|
||||
// DFFC D Flip-Flop with Asynchronous Clear
|
||||
module \$_DFF_PP0_ (input D, C, R, output Q); DFFC _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(R)); endmodule
|
||||
module \$_DFF_PN0_ (input D, C, R, output Q); DFFC _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(!R)); endmodule
|
||||
|
||||
// DFFNC D Flip-Flop with Negative-Edge Clock and Asynchronous Clear
|
||||
module \$_DFF_NP0_ (input D, C, R, output Q); DFFNC _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(R)); endmodule
|
||||
module \$_DFF_NN0_ (input D, C, R, output Q); DFFNC _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(!R)); endmodule
|
||||
|
||||
// DFFPE D Flip-Flop with Clock Enable and Asynchronous Preset
|
||||
module \$__DFFE_PP1 (input D, C, R, E, output Q); DFFPE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(R), .CE(E)); endmodule
|
||||
module \$__DFFE_PN1 (input D, C, R, E, output Q); DFFPE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(!R), .CE(E)); endmodule
|
||||
|
||||
// DFFNPE D Flip-Flop with Negative-Edge Clock,Clock Enable, and Asynchronous Preset
|
||||
module \$__DFFE_NP1 (input D, C, R, E, output Q); DFFNPE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(R), .CE(E)); endmodule
|
||||
module \$__DFFE_NN1 (input D, C, R, E, output Q); DFFNPE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .PRESET(!R), .CE(E)); endmodule
|
||||
|
||||
// DFFCE D Flip-Flop with Clock Enable and Asynchronous Clear
|
||||
module \$__DFFE_PP0 (input D, C, R, E, output Q); DFFCE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(R), .CE(E)); endmodule
|
||||
module \$__DFFE_PN0 (input D, C, R, E, output Q); DFFCE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(!R), .CE(E)); endmodule
|
||||
|
||||
// DFFNCE D Flip-Flop with Negative-Edge Clock,Clock Enable and Asynchronous Clear
|
||||
module \$__DFFE_NP0 (input D, C, R, E, output Q); DFFNCE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(R), .CE(E)); endmodule
|
||||
module \$__DFFE_NN0 (input D, C, R, E, output Q); DFFNCE _TECHMAP_REPLACE_ (.D(D), .Q(Q), .CLK(C), .CLEAR(!R), .CE(E)); endmodule
|
||||
|
||||
|
||||
module \$lut (A, Y);
|
||||
parameter WIDTH = 0;
|
||||
|
@ -28,6 +102,30 @@ module \$lut (A, Y);
|
|||
if (WIDTH == 4) begin
|
||||
LUT4 #(.INIT(LUT)) _TECHMAP_REPLACE_ (.F(Y),
|
||||
.I0(A[0]), .I1(A[1]), .I2(A[2]), .I3(A[3]));
|
||||
end else
|
||||
if (WIDTH == 5) begin
|
||||
wire f0, f1;
|
||||
\$lut #(.LUT(LUT[15: 0]), .WIDTH(4)) lut0 (.A(A[3:0]), .Y(f0));
|
||||
\$lut #(.LUT(LUT[31:16]), .WIDTH(4)) lut1 (.A(A[3:0]), .Y(f1));
|
||||
MUX2_LUT5 mux5(.I0(f0), .I1(f1), .S0(A[4]), .O(Y));
|
||||
end else
|
||||
if (WIDTH == 6) begin
|
||||
wire f0, f1;
|
||||
\$lut #(.LUT(LUT[31: 0]), .WIDTH(5)) lut0 (.A(A[4:0]), .Y(f0));
|
||||
\$lut #(.LUT(LUT[63:32]), .WIDTH(5)) lut1 (.A(A[4:0]), .Y(f1));
|
||||
MUX2_LUT6 mux6(.I0(f0), .I1(f1), .S0(A[5]), .O(Y));
|
||||
end else
|
||||
if (WIDTH == 7) begin
|
||||
wire f0, f1;
|
||||
\$lut #(.LUT(LUT[63: 0]), .WIDTH(6)) lut0 (.A(A[5:0]), .Y(f0));
|
||||
\$lut #(.LUT(LUT[127:64]), .WIDTH(6)) lut1 (.A(A[5:0]), .Y(f1));
|
||||
MUX2_LUT7 mux7(.I0(f0), .I1(f1), .S0(A[6]), .O(Y));
|
||||
end else
|
||||
if (WIDTH == 8) begin
|
||||
wire f0, f1;
|
||||
\$lut #(.LUT(LUT[127: 0]), .WIDTH(7)) lut0 (.A(A[6:0]), .Y(f0));
|
||||
\$lut #(.LUT(LUT[255:128]), .WIDTH(7)) lut1 (.A(A[6:0]), .Y(f1));
|
||||
MUX2_LUT8 mux8(.I0(f0), .I1(f1), .S0(A[7]), .O(Y));
|
||||
end else begin
|
||||
wire _TECHMAP_FAIL_ = 1;
|
||||
end
|
||||
|
|
|
@ -24,6 +24,41 @@ module LUT4(output F, input I0, I1, I2, I3);
|
|||
assign F = I0 ? s1[1] : s1[0];
|
||||
endmodule
|
||||
|
||||
module MUX2 (O, I0, I1, S0);
|
||||
input I0,I1;
|
||||
input S0;
|
||||
output O;
|
||||
assign O = S0 ? I1 : I0;
|
||||
endmodule
|
||||
|
||||
module MUX2_LUT5 (O, I0, I1, S0);
|
||||
input I0,I1;
|
||||
input S0;
|
||||
output O;
|
||||
MUX2 mux2_lut5 (O, I0, I1, S0);
|
||||
endmodule
|
||||
|
||||
module MUX2_LUT6 (O, I0, I1, S0);
|
||||
input I0,I1;
|
||||
input S0;
|
||||
output O;
|
||||
MUX2 mux2_lut6 (O, I0, I1, S0);
|
||||
endmodule
|
||||
|
||||
module MUX2_LUT7 (O, I0, I1, S0);
|
||||
input I0,I1;
|
||||
input S0;
|
||||
output O;
|
||||
MUX2 mux2_lut7 (O, I0, I1, S0);
|
||||
endmodule
|
||||
|
||||
module MUX2_LUT8 (O, I0, I1, S0);
|
||||
input I0,I1;
|
||||
input S0;
|
||||
output O;
|
||||
MUX2 mux2_lut8 (O, I0, I1, S0);
|
||||
endmodule
|
||||
|
||||
module DFF (output reg Q, input CLK, D);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
|
@ -31,6 +66,112 @@ module DFF (output reg Q, input CLK, D);
|
|||
Q <= D;
|
||||
endmodule
|
||||
|
||||
module DFFE (output reg Q, input D, CLK, CE);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
always @(posedge CLK) begin
|
||||
if (CE)
|
||||
Q <= D;
|
||||
end
|
||||
endmodule // DFFE (positive clock edge; clock enable)
|
||||
|
||||
|
||||
module DFFS (output reg Q, input D, CLK, SET);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
always @(posedge CLK) begin
|
||||
if (SET)
|
||||
Q <= 1'b1;
|
||||
else
|
||||
Q <= D;
|
||||
end
|
||||
endmodule // DFFS (positive clock edge; synchronous set)
|
||||
|
||||
|
||||
module DFFSE (output reg Q, input D, CLK, CE, SET);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
always @(posedge CLK) begin
|
||||
if (SET)
|
||||
Q <= 1'b1;
|
||||
else if (CE)
|
||||
Q <= D;
|
||||
end
|
||||
endmodule // DFFSE (positive clock edge; synchronous set takes precedence over clock enable)
|
||||
|
||||
|
||||
module DFFR (output reg Q, input D, CLK, RESET);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
always @(posedge CLK) begin
|
||||
if (RESET)
|
||||
Q <= 1'b0;
|
||||
else
|
||||
Q <= D;
|
||||
end
|
||||
endmodule // DFFR (positive clock edge; synchronous reset)
|
||||
|
||||
|
||||
module DFFRE (output reg Q, input D, CLK, CE, RESET);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
always @(posedge CLK) begin
|
||||
if (RESET)
|
||||
Q <= 1'b0;
|
||||
else if (CE)
|
||||
Q <= D;
|
||||
end
|
||||
endmodule // DFFRE (positive clock edge; synchronous reset takes precedence over clock enable)
|
||||
|
||||
|
||||
module DFFP (output reg Q, input D, CLK, PRESET);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
always @(posedge CLK or posedge PRESET) begin
|
||||
if(PRESET)
|
||||
Q <= 1'b1;
|
||||
else
|
||||
Q <= D;
|
||||
end
|
||||
endmodule // DFFP (positive clock edge; asynchronous preset)
|
||||
|
||||
|
||||
module DFFPE (output reg Q, input D, CLK, CE, PRESET);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
always @(posedge CLK or posedge PRESET) begin
|
||||
if(PRESET)
|
||||
Q <= 1'b1;
|
||||
else if (CE)
|
||||
Q <= D;
|
||||
end
|
||||
endmodule // DFFPE (positive clock edge; asynchronous preset; clock enable)
|
||||
|
||||
|
||||
module DFFC (output reg Q, input D, CLK, CLEAR);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
always @(posedge CLK or posedge CLEAR) begin
|
||||
if(CLEAR)
|
||||
Q <= 1'b0;
|
||||
else
|
||||
Q <= D;
|
||||
end
|
||||
endmodule // DFFC (positive clock edge; asynchronous clear)
|
||||
|
||||
|
||||
module DFFCE (output reg Q, input D, CLK, CE, CLEAR);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
always @(posedge CLK or posedge CLEAR) begin
|
||||
if(CLEAR)
|
||||
Q <= 1'b0;
|
||||
else if (CE)
|
||||
Q <= D;
|
||||
end
|
||||
endmodule // DFFCE (positive clock edge; asynchronous clear; clock enable)
|
||||
|
||||
|
||||
module DFFN (output reg Q, input CLK, D);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
|
@ -38,16 +179,112 @@ module DFFN (output reg Q, input CLK, D);
|
|||
Q <= D;
|
||||
endmodule
|
||||
|
||||
module DFFR (output reg Q, input D, CLK, RESET);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
always @(posedge CLK) begin
|
||||
if (RESET)
|
||||
Q <= 1'b0;
|
||||
else
|
||||
Q <= D;
|
||||
end
|
||||
endmodule // DFFR (positive clock edge; synchronous reset)
|
||||
module DFFNE (output reg Q, input D, CLK, CE);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
always @(negedge CLK) begin
|
||||
if (CE)
|
||||
Q <= D;
|
||||
end
|
||||
endmodule // DFFNE (negative clock edge; clock enable)
|
||||
|
||||
|
||||
module DFFNS (output reg Q, input D, CLK, SET);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
always @(negedge CLK) begin
|
||||
if (SET)
|
||||
Q <= 1'b1;
|
||||
else
|
||||
Q <= D;
|
||||
end
|
||||
endmodule // DFFNS (negative clock edge; synchronous set)
|
||||
|
||||
|
||||
module DFFNSE (output reg Q, input D, CLK, CE, SET);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
always @(negedge CLK) begin
|
||||
if (SET)
|
||||
Q <= 1'b1;
|
||||
else if (CE)
|
||||
Q <= D;
|
||||
end
|
||||
endmodule // DFFNSE (negative clock edge; synchronous set takes precedence over clock enable)
|
||||
|
||||
|
||||
module DFFNR (output reg Q, input D, CLK, RESET);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
always @(negedge CLK) begin
|
||||
if (RESET)
|
||||
Q <= 1'b0;
|
||||
else
|
||||
Q <= D;
|
||||
end
|
||||
endmodule // DFFNR (negative clock edge; synchronous reset)
|
||||
|
||||
|
||||
module DFFNRE (output reg Q, input D, CLK, CE, RESET);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
always @(negedge CLK) begin
|
||||
if (RESET)
|
||||
Q <= 1'b0;
|
||||
else if (CE)
|
||||
Q <= D;
|
||||
end
|
||||
endmodule // DFFNRE (negative clock edge; synchronous reset takes precedence over clock enable)
|
||||
|
||||
|
||||
module DFFNP (output reg Q, input D, CLK, PRESET);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
always @(negedge CLK or posedge PRESET) begin
|
||||
if(PRESET)
|
||||
Q <= 1'b1;
|
||||
else
|
||||
Q <= D;
|
||||
end
|
||||
endmodule // DFFNP (negative clock edge; asynchronous preset)
|
||||
|
||||
|
||||
module DFFNPE (output reg Q, input D, CLK, CE, PRESET);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
always @(negedge CLK or posedge PRESET) begin
|
||||
if(PRESET)
|
||||
Q <= 1'b1;
|
||||
else if (CE)
|
||||
Q <= D;
|
||||
end
|
||||
endmodule // DFFNPE (negative clock edge; asynchronous preset; clock enable)
|
||||
|
||||
|
||||
module DFFNC (output reg Q, input D, CLK, CLEAR);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
always @(negedge CLK or posedge CLEAR) begin
|
||||
if(CLEAR)
|
||||
Q <= 1'b0;
|
||||
else
|
||||
Q <= D;
|
||||
end
|
||||
endmodule // DFFNC (negative clock edge; asynchronous clear)
|
||||
|
||||
|
||||
module DFFNCE (output reg Q, input D, CLK, CE, CLEAR);
|
||||
parameter [0:0] INIT = 1'b0;
|
||||
initial Q = INIT;
|
||||
always @(negedge CLK or posedge CLEAR) begin
|
||||
if(CLEAR)
|
||||
Q <= 1'b0;
|
||||
else if (CE)
|
||||
Q <= D;
|
||||
end
|
||||
endmodule // DFFNCE (negative clock edge; asynchronous clear; clock enable)
|
||||
|
||||
// TODO add more DFF sim cells
|
||||
|
||||
module VCC(output V);
|
||||
assign V = 1;
|
||||
|
@ -65,14 +302,98 @@ module OBUF(output O, input I);
|
|||
assign O = I;
|
||||
endmodule
|
||||
|
||||
module TBUF (O, I, OEN);
|
||||
input I, OEN;
|
||||
output O;
|
||||
assign O = OEN ? I : 1'bz;
|
||||
endmodule
|
||||
|
||||
module IOBUF (O, IO, I, OEN);
|
||||
input I,OEN;
|
||||
output O;
|
||||
inout IO;
|
||||
assign IO = OEN ? I : 1'bz;
|
||||
assign I = IO;
|
||||
endmodule
|
||||
|
||||
module GSR (input GSRI);
|
||||
wire GSRO = GSRI;
|
||||
endmodule
|
||||
|
||||
module ALU (input I0, input I1, input I3, input CIN, output COUT, output SUM);
|
||||
parameter [3:0] ALU_MODE = 0; // default 0 = ADD
|
||||
assign {COUT, SUM} = CIN + I1 + I0;
|
||||
endmodule // alu
|
||||
module ALU (SUM, COUT, I0, I1, I3, CIN);
|
||||
|
||||
input I0;
|
||||
input I1;
|
||||
input I3;
|
||||
input CIN;
|
||||
output SUM;
|
||||
output COUT;
|
||||
|
||||
localparam ADD = 0;
|
||||
localparam SUB = 1;
|
||||
localparam ADDSUB = 2;
|
||||
localparam NE = 3;
|
||||
localparam GE = 4;
|
||||
localparam LE = 5;
|
||||
localparam CUP = 6;
|
||||
localparam CDN = 7;
|
||||
localparam CUPCDN = 8;
|
||||
localparam MULT = 9;
|
||||
|
||||
parameter ALU_MODE = 0;
|
||||
|
||||
reg S, C;
|
||||
|
||||
assign SUM = S ^ CIN;
|
||||
assign COUT = S? CIN : C;
|
||||
|
||||
always @* begin
|
||||
case (ALU_MODE)
|
||||
ADD: begin
|
||||
S = I0 ^ I1;
|
||||
C = I0;
|
||||
end
|
||||
SUB: begin
|
||||
S = I0 ^ ~I1;
|
||||
C = I0;
|
||||
end
|
||||
ADDSUB: begin
|
||||
S = I3? I0 ^ I1 : I0 ^ ~I1;
|
||||
C = I0;
|
||||
end
|
||||
NE: begin
|
||||
S = I0 ^ ~I1;
|
||||
C = 1'b1;
|
||||
end
|
||||
GE: begin
|
||||
S = I0 ^ ~I1;
|
||||
C = I0;
|
||||
end
|
||||
LE: begin
|
||||
S = ~I0 ^ I1;
|
||||
C = I1;
|
||||
end
|
||||
CUP: begin
|
||||
S = I0;
|
||||
C = 1'b0;
|
||||
end
|
||||
CDN: begin
|
||||
S = ~I0;
|
||||
C = 1'b1;
|
||||
end
|
||||
CUPCDN: begin
|
||||
S = I3? I0 : ~I0;
|
||||
C = I0;
|
||||
end
|
||||
MULT: begin
|
||||
S = I0 & I1;
|
||||
C = I0 & I1;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
|
||||
module RAM16S4 (DO, DI, AD, WRE, CLK);
|
||||
parameter WIDTH = 4;
|
||||
|
|
|
@ -64,6 +64,12 @@ struct SynthGowinPass : public ScriptPass
|
|||
log(" -retime\n");
|
||||
log(" run 'abc' with -dff option\n");
|
||||
log("\n");
|
||||
log(" -nowidelut\n");
|
||||
log(" do not use muxes to implement LUTs larger than LUT4s\n");
|
||||
log("\n");
|
||||
log(" -abc9\n");
|
||||
log(" use new ABC9 flow (EXPERIMENTAL)\n");
|
||||
log("\n");
|
||||
log("\n");
|
||||
log("The following commands are executed by this synthesis command:\n");
|
||||
help_script();
|
||||
|
@ -71,7 +77,7 @@ struct SynthGowinPass : public ScriptPass
|
|||
}
|
||||
|
||||
string top_opt, vout_file;
|
||||
bool retime, nobram, nodram, flatten, nodffe;
|
||||
bool retime, nobram, nodram, flatten, nodffe, nowidelut, abc9;
|
||||
|
||||
void clear_flags() YS_OVERRIDE
|
||||
{
|
||||
|
@ -82,6 +88,8 @@ struct SynthGowinPass : public ScriptPass
|
|||
nobram = false;
|
||||
nodffe = false;
|
||||
nodram = false;
|
||||
nowidelut = false;
|
||||
abc9 = false;
|
||||
}
|
||||
|
||||
void execute(std::vector<std::string> args, RTLIL::Design *design) YS_OVERRIDE
|
||||
|
@ -128,6 +136,14 @@ struct SynthGowinPass : public ScriptPass
|
|||
flatten = false;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-nowidelut") {
|
||||
nowidelut = true;
|
||||
continue;
|
||||
}
|
||||
if (args[argidx] == "-abc9") {
|
||||
abc9 = true;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
extra_args(args, argidx, design);
|
||||
|
@ -163,8 +179,8 @@ struct SynthGowinPass : public ScriptPass
|
|||
{
|
||||
run("synth -run coarse");
|
||||
}
|
||||
|
||||
if (!nobram && check_label("bram", "(skip if -nobram)"))
|
||||
|
||||
if (!nobram && check_label("bram", "(skip if -nobram)"))
|
||||
{
|
||||
run("memory_bram -rules +/gowin/bram.txt");
|
||||
run("techmap -map +/gowin/brams_map.v -map +/gowin/cells_sim.v");
|
||||
|
@ -186,6 +202,7 @@ struct SynthGowinPass : public ScriptPass
|
|||
run("techmap -map +/techmap.v");
|
||||
if (retime || help_mode)
|
||||
run("abc -dff", "(only if -retime)");
|
||||
run("splitnets");
|
||||
}
|
||||
|
||||
if (check_label("map_ffs"))
|
||||
|
@ -202,16 +219,25 @@ struct SynthGowinPass : public ScriptPass
|
|||
|
||||
if (check_label("map_luts"))
|
||||
{
|
||||
run("abc -lut 4");
|
||||
if (nowidelut && abc9) {
|
||||
run("abc9 -lut 4");
|
||||
} else if (nowidelut && !abc9) {
|
||||
run("abc -lut 4");
|
||||
} else if (!nowidelut && abc9) {
|
||||
run("abc9 -lut 4:8");
|
||||
} else if (!nowidelut && !abc9) {
|
||||
run("abc -lut 4:8");
|
||||
}
|
||||
run("clean");
|
||||
}
|
||||
|
||||
if (check_label("map_cells"))
|
||||
{
|
||||
run("techmap -map +/gowin/cells_map.v");
|
||||
run("hilomap -hicell VCC V -locell GND G");
|
||||
run("iopadmap -bits -inpad IBUF O:I -outpad OBUF I:O", "(unless -noiopads)");
|
||||
run("dffinit -ff DFF Q INIT");
|
||||
run("setundef -undriven -params -zero");
|
||||
run("hilomap -singleton -hicell VCC V -locell GND G");
|
||||
run("iopadmap -bits -inpad IBUF O:I -outpad OBUF I:O "
|
||||
"-toutpad TBUF OEN:I:O -tinoutpad IOBUF OEN:O:I:IO", "(unless -noiopads)");
|
||||
run("clean");
|
||||
|
||||
}
|
||||
|
@ -226,7 +252,7 @@ struct SynthGowinPass : public ScriptPass
|
|||
if (check_label("vout"))
|
||||
{
|
||||
if (!vout_file.empty() || help_mode)
|
||||
run(stringf("write_verilog -nodec -attr2comment -defparam -renameprefix gen %s",
|
||||
run(stringf("write_verilog -decimal -attr2comment -defparam -renameprefix gen %s",
|
||||
help_mode ? "<file-name>" : vout_file.c_str()));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue