diff options
Diffstat (limited to 'techlibs/gowin')
| -rw-r--r-- | techlibs/gowin/Makefile.inc | 10 | ||||
| -rw-r--r-- | techlibs/gowin/arith_map.v | 6 | ||||
| -rw-r--r-- | techlibs/gowin/bram.txt | 10 | ||||
| -rwxr-xr-x | techlibs/gowin/brams_init.py | 8 | ||||
| -rw-r--r-- | techlibs/gowin/brams_map.v | 63 | ||||
| -rw-r--r-- | techlibs/gowin/cells_map.v | 99 | ||||
| -rw-r--r-- | techlibs/gowin/cells_sim.v | 349 | ||||
| -rw-r--r-- | techlibs/gowin/synth_gowin.cc | 33 | 
8 files changed, 538 insertions, 40 deletions
diff --git a/techlibs/gowin/Makefile.inc b/techlibs/gowin/Makefile.inc index 6f2159349..d2853704b 100644 --- a/techlibs/gowin/Makefile.inc +++ b/techlibs/gowin/Makefile.inc @@ -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)) diff --git a/techlibs/gowin/arith_map.v b/techlibs/gowin/arith_map.v index e15de6423..b6f9e8c38 100644 --- a/techlibs/gowin/arith_map.v +++ b/techlibs/gowin/arith_map.v @@ -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]) diff --git a/techlibs/gowin/bram.txt b/techlibs/gowin/bram.txt index b5f9a981c..e406f9c51 100644 --- a/techlibs/gowin/bram.txt +++ b/techlibs/gowin/bram.txt @@ -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 diff --git a/techlibs/gowin/brams_init.py b/techlibs/gowin/brams_init.py new file mode 100755 index 000000000..b78eb8da5 --- /dev/null +++ b/techlibs/gowin/brams_init.py @@ -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) diff --git a/techlibs/gowin/brams_map.v b/techlibs/gowin/brams_map.v index e963cfa88..fbebc4af8 100644 --- a/techlibs/gowin/brams_map.v +++ b/techlibs/gowin/brams_map.v @@ -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({{(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), .ADB(B1ADDR) +			.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; diff --git a/techlibs/gowin/cells_map.v b/techlibs/gowin/cells_map.v index ebdc88a0a..881c2e9bb 100644 --- a/techlibs/gowin/cells_map.v +++ b/techlibs/gowin/cells_map.v @@ -1,9 +1,82 @@ +//TODO all DFF* have INIT + +// 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_ #(parameter INIT = 1'b0) (input D, C, output Q); DFF  #(.INIT(INIT)) _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 +101,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 diff --git a/techlibs/gowin/cells_sim.v b/techlibs/gowin/cells_sim.v index ebb238bad..a67855dab 100644 --- a/techlibs/gowin/cells_sim.v +++ b/techlibs/gowin/cells_sim.v @@ -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; diff --git a/techlibs/gowin/synth_gowin.cc b/techlibs/gowin/synth_gowin.cc index ac3dbfb29..a70ff93bb 100644 --- a/techlibs/gowin/synth_gowin.cc +++ b/techlibs/gowin/synth_gowin.cc @@ -71,7 +71,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 +82,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 +130,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); @@ -164,7 +174,7 @@ 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 +196,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,15 +213,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("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("dffinit  -ff DFF Q INIT");  			run("clean"); @@ -226,7 +247,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()));  		}  	}  | 
