diff options
Diffstat (limited to 'techlibs')
-rw-r--r-- | techlibs/anlogic/.gitignore | 2 | ||||
-rw-r--r-- | techlibs/anlogic/Makefile.inc | 22 | ||||
-rw-r--r-- | techlibs/anlogic/brams.txt | 43 | ||||
-rw-r--r-- | techlibs/anlogic/brams_init.py | 21 | ||||
-rw-r--r-- | techlibs/anlogic/brams_map.v | 162 | ||||
-rw-r--r-- | techlibs/anlogic/synth_anlogic.cc | 18 | ||||
-rw-r--r-- | techlibs/common/simlib.v | 72 | ||||
-rw-r--r-- | techlibs/common/techmap.v | 39 | ||||
-rw-r--r-- | techlibs/ecp5/cells_sim.v | 2 | ||||
-rw-r--r-- | techlibs/gowin/cells_sim.v | 277 | ||||
-rw-r--r-- | techlibs/gowin/lutrams_map.v | 5 | ||||
-rw-r--r-- | techlibs/nexus/arith_map.v | 2 | ||||
-rw-r--r-- | techlibs/nexus/cells_sim.v | 4 | ||||
-rw-r--r-- | techlibs/quicklogic/synth_quicklogic.cc | 4 |
14 files changed, 601 insertions, 72 deletions
diff --git a/techlibs/anlogic/.gitignore b/techlibs/anlogic/.gitignore new file mode 100644 index 000000000..d127107db --- /dev/null +++ b/techlibs/anlogic/.gitignore @@ -0,0 +1,2 @@ +brams_init.mk +brams_init_*.vh diff --git a/techlibs/anlogic/Makefile.inc b/techlibs/anlogic/Makefile.inc index 2d8d65e2e..79519c645 100644 --- a/techlibs/anlogic/Makefile.inc +++ b/techlibs/anlogic/Makefile.inc @@ -3,6 +3,22 @@ OBJS += techlibs/anlogic/synth_anlogic.o OBJS += techlibs/anlogic/anlogic_eqn.o OBJS += techlibs/anlogic/anlogic_fixcarry.o +GENFILES += techlibs/anlogic/brams_init_16.vh +GENFILES += techlibs/anlogic/brams_init_9.vh +GENFILES += techlibs/anlogic/brams_init_8.vh + +EXTRA_OBJS += techlibs/anlogic/brams_init.mk +.SECONDARY: techlibs/anlogic/brams_init.mk + +techlibs/anlogic/brams_init.mk: techlibs/anlogic/brams_init.py + $(Q) mkdir -p techlibs/anlogic + $(P) $(PYTHON_EXECUTABLE) $< + $(Q) touch $@ + +techlibs/anlogic/brams_init_16.vh: techlibs/anlogic/brams_init.mk +techlibs/anlogic/brams_init_9.vh: techlibs/anlogic/brams_init.mk +techlibs/anlogic/brams_init_8.vh: techlibs/anlogic/brams_init.mk + $(eval $(call add_share_file,share/anlogic,techlibs/anlogic/cells_map.v)) $(eval $(call add_share_file,share/anlogic,techlibs/anlogic/arith_map.v)) $(eval $(call add_share_file,share/anlogic,techlibs/anlogic/cells_sim.v)) @@ -10,3 +26,9 @@ $(eval $(call add_share_file,share/anlogic,techlibs/anlogic/eagle_bb.v)) $(eval $(call add_share_file,share/anlogic,techlibs/anlogic/lutrams.txt)) $(eval $(call add_share_file,share/anlogic,techlibs/anlogic/lutrams_map.v)) $(eval $(call add_share_file,share/anlogic,techlibs/anlogic/lutram_init_16x4.vh)) +$(eval $(call add_share_file,share/anlogic,techlibs/anlogic/brams.txt)) +$(eval $(call add_share_file,share/anlogic,techlibs/anlogic/brams_map.v)) + +$(eval $(call add_gen_share_file,share/anlogic,techlibs/anlogic/brams_init_16.vh)) +$(eval $(call add_gen_share_file,share/anlogic,techlibs/anlogic/brams_init_9.vh)) +$(eval $(call add_gen_share_file,share/anlogic,techlibs/anlogic/brams_init_8.vh)) diff --git a/techlibs/anlogic/brams.txt b/techlibs/anlogic/brams.txt new file mode 100644 index 000000000..a39701c63 --- /dev/null +++ b/techlibs/anlogic/brams.txt @@ -0,0 +1,43 @@ +bram $__ANLOGIC_BRAM9K_TDP + init 1 + abits 13 @a13d1 + dbits 1 @a13d1 + abits 12 @a12d2 + dbits 2 @a12d2 + abits 11 @a11d4 + dbits 4 @a11d4 + abits 10 @a10d9 + dbits 9 @a10d9 + groups 2 + ports 1 1 + wrmode 0 1 + enable 1 1 + transp 2 0 + clocks 2 3 + clkpol 2 3 +endbram + +bram $__ANLOGIC_BRAM32K + init 1 + abits 11 + dbits 16 + groups 2 + ports 1 1 + wrmode 0 1 + enable 1 2 + transp 0 0 + clocks 2 3 + clkpol 2 3 +endbram + +match $__ANLOGIC_BRAM32K + min efficiency 30 + shuffle_enable B + make_transp + or_next_if_better +endmatch + +match $__ANLOGIC_BRAM9K_TDP + min efficiency 5 + make_transp +endmatch diff --git a/techlibs/anlogic/brams_init.py b/techlibs/anlogic/brams_init.py new file mode 100644 index 000000000..8dda0d33e --- /dev/null +++ b/techlibs/anlogic/brams_init.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python3 + +with open("techlibs/anlogic/brams_init_9.vh", "w") as f: + for i in range(4): + init_snippets = [" INIT[%3d*9+8]" % (k+256*i,) for k in range(255, -1, -1)] + for k in range(4, 256, 4): + init_snippets[k] = "\n " + init_snippets[k] + print(".INITP_%02X({%s})," % (i, ",".join(init_snippets)), file=f) + for i in range(32): + init_snippets = [" INIT[%3d*9 +: 8]" % (k+32*i,) for k in range(31, -1, -1)] + for k in range(4, 32, 4): + init_snippets[k] = "\n " + init_snippets[k] + print(".INIT_%02X({%s})," % (i, ",".join(init_snippets)), file=f) + +with open("techlibs/anlogic/brams_init_8.vh", "w") as f: + for i in range(32): + print(".INIT_%02X(INIT[%3d*256 +: 256])," % (i, i), file=f) + +with open("techlibs/anlogic/brams_init_16.vh", "w") as f: + for i in range(128): + print(".INIT_%02X(INIT[%3d*256 +: 256])," % (i, i), file=f) diff --git a/techlibs/anlogic/brams_map.v b/techlibs/anlogic/brams_map.v new file mode 100644 index 000000000..ee02b6d7c --- /dev/null +++ b/techlibs/anlogic/brams_map.v @@ -0,0 +1,162 @@ +module \$__ANLOGIC_BRAM9K_TDP (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); + parameter CFG_ABITS = 10; + parameter CFG_DBITS = 9; + + parameter CLKPOL2 = 1; + parameter CLKPOL3 = 1; + parameter [9215:0] INIT = 9216'bx; + parameter TRANSP2 = 0; + + input CLK2; + input CLK3; + + input [CFG_ABITS-1:0] A1ADDR; + output [CFG_DBITS-1:0] A1DATA; + input A1EN; + + input [CFG_ABITS-1:0] B1ADDR; + input [CFG_DBITS-1:0] B1DATA; + input B1EN; + + localparam CLKAMUX = CLKPOL2 ? "SIG" : "INV"; + localparam CLKBMUX = CLKPOL3 ? "SIG" : "INV"; + + localparam WRITEMODE_B = TRANSP2 ? "WRITETHROUGH" : "READBEFOREWRITE"; + + localparam DATA_WIDTH = CFG_DBITS == 1 ? "1" : + (CFG_DBITS == 2 ? "2" : + (CFG_DBITS <= 4 ? "4" : "9")); + + localparam APADBITS = $clog2(CFG_DBITS == 9 ? 8 : CFG_DBITS); + + wire [12:0] addra; + wire [12:0] addrb; + + assign addra[12:APADBITS] = A1ADDR; + assign addrb[12:APADBITS] = B1ADDR; + + wire [8:0] doa; + wire [8:0] dib; + + assign A1DATA[CFG_DBITS-1:0] = doa; + assign dib[CFG_DBITS-1:0] = B1DATA; + + generate if (CFG_DBITS == 9) begin + EG_PHY_BRAM #( + .MODE("DP8K"), + .DATA_WIDTH_A(DATA_WIDTH), + .DATA_WIDTH_B(DATA_WIDTH), + .READBACK("OFF"), + .REGMODE_A("NOREG"), + .REGMODE_B("NOREG"), + .WRITEMODE_A("READBEFOREWRITE"), + .WRITEMODE_B(WRITEMODE_B), + .RESETMODE("ASYNC"), + .CEAMUX("SIG"), .CEBMUX("SIG"), + .OCEAMUX("1"), .OCEBMUX("1"), + .RSTAMUX("0"), .RSTBMUX("0"), + .CLKAMUX(CLKAMUX), + .CLKBMUX(CLKBMUX), + .WEAMUX("0"), .WEBMUX("SIG"), + .CSA0("1"), .CSA1("1"), + .CSA2("1"), .CSB0("1"), + .CSB1("1"), .CSB2("1"), + `include "brams_init_9.vh" + ) _TECHMAP_REPLACE_ ( + .doa(doa), .dib(dib), + .addra(addra), .addrb(addrb), + .clka(CLK2), .clkb(CLK3), + .cea(A1EN), .ceb(B1EN), + .ocea(1'b1), .oceb(1'b1), + .rsta(1'b0), .rstb(1'b0), + .wea(1'b0), .web(B1EN), + .csa(3'b111), .csb(3'b111) + ); + end else begin + EG_PHY_BRAM #( + .MODE("DP8K"), + .DATA_WIDTH_A(DATA_WIDTH), + .DATA_WIDTH_B(DATA_WIDTH), + .READBACK("OFF"), + .REGMODE_A("NOREG"), + .REGMODE_B("NOREG"), + .WRITEMODE_A("READBEFOREWRITE"), + .WRITEMODE_B(WRITEMODE_B), + .RESETMODE("ASYNC"), + .CEAMUX("SIG"), .CEBMUX("SIG"), + .OCEAMUX("1"), .OCEBMUX("1"), + .RSTAMUX("0"), .RSTBMUX("0"), + .CLKAMUX(CLKAMUX), + .CLKBMUX(CLKBMUX), + .WEAMUX("0"), .WEBMUX("SIG"), + .CSA0("1"), .CSA1("1"), + .CSA2("1"), .CSB0("1"), + .CSB1("1"), .CSB2("1"), + `include "brams_init_8.vh" + ) _TECHMAP_REPLACE_ ( + .doa(doa), .dib(dib), + .addra(addra), .addrb(addrb), + .clka(CLK2), .clkb(CLK3), + .cea(A1EN), .ceb(B1EN), + .ocea(1'b1), .oceb(1'b1), + .rsta(1'b0), .rstb(1'b0), + .wea(1'b0), .web(B1EN), + .csa(3'b111), .csb(3'b111) + ); + end endgenerate +endmodule + +module \$__ANLOGIC_BRAM32K (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); + parameter CFG_ABITS = 11; + parameter CFG_DBITS = 16; + + parameter CLKPOL2 = 1; + parameter CLKPOL3 = 1; + parameter [32767:0] INIT = 32768'bx; + + input CLK2; + input CLK3; + + input [CFG_ABITS-1:0] A1ADDR; + output [CFG_DBITS-1:0] A1DATA; + input A1EN; + + input [CFG_ABITS-1:0] B1ADDR; + input [CFG_DBITS-1:0] B1DATA; + input [1:0] B1EN; + + localparam CLKAMUX = CLKPOL2 ? "SIG" : "INV"; + localparam CLKBMUX = CLKPOL3 ? "SIG" : "INV"; + + wire byteweb = B1EN[1] ^ B1EN[0]; + wire byteb = B1EN[1]; + + EG_PHY_BRAM32K #( + .MODE("DP16K"), + .DATA_WIDTH_A("16"), + .DATA_WIDTH_B("16"), + .REGMODE_A("NOREG"), + .REGMODE_B("NOREG"), + .WRITEMODE_A("NORMAL"), + .WRITEMODE_B("NORMAL"), + .SRMODE("ASYNC"), + .CSAMUX("SIG"), .CSBMUX("SIG"), + .OCEAMUX("1"), .OCEBMUX("1"), + .RSTAMUX("0"), .RSTBMUX("0"), + .CLKAMUX(CLKAMUX), + .CLKBMUX(CLKBMUX), + .WEAMUX("0"), .WEBMUX("SIG"), + .READBACK("OFF"), + `include "brams_init_16.vh" + ) _TECHMAP_REPLACE_ ( + .doa(A1DATA), .dib(B1DATA), + .addra(A1ADDR), .addrb(B1ADDR), + .bytea(1'b0), .byteb(byteb), + .bytewea(1'b0), .byteweb(byteweb), + .csa(A1EN), .csb(|B1EN), + .wea(1'b0), .web(|B1EN), + .clka(CLK2), .clkb(CLK3), + .rsta(1'b0), .rstb(1'b0), + .ocea(1'b1), .oceb(1'b1) + ); +endmodule diff --git a/techlibs/anlogic/synth_anlogic.cc b/techlibs/anlogic/synth_anlogic.cc index 039cae00e..5da14c26b 100644 --- a/techlibs/anlogic/synth_anlogic.cc +++ b/techlibs/anlogic/synth_anlogic.cc @@ -63,6 +63,9 @@ struct SynthAnlogicPass : public ScriptPass log(" -nolutram\n"); log(" do not use EG_LOGIC_DRAM16X4 cells in output netlist\n"); log("\n"); + log(" -nobram\n"); + log(" do not use EG_PHY_BRAM or EG_PHY_BRAM32K cells in output netlist\n"); + log("\n"); log("\n"); log("The following commands are executed by this synthesis command:\n"); help_script(); @@ -70,7 +73,7 @@ struct SynthAnlogicPass : public ScriptPass } string top_opt, edif_file, json_file; - bool flatten, retime, nolutram; + bool flatten, retime, nolutram, nobram; void clear_flags() override { @@ -80,6 +83,7 @@ struct SynthAnlogicPass : public ScriptPass flatten = true; retime = false; nolutram = false; + nobram = false; } void execute(std::vector<std::string> args, RTLIL::Design *design) override @@ -118,6 +122,10 @@ struct SynthAnlogicPass : public ScriptPass nolutram = true; continue; } + if (args[argidx] == "-nobram") { + nobram = true; + continue; + } if (args[argidx] == "-retime") { retime = true; continue; @@ -158,6 +166,14 @@ struct SynthAnlogicPass : public ScriptPass run("synth -run coarse"); } + if (!nobram && check_label("map_bram", "(skip if -nobram)")) + { + run("memory_bram -rules +/anlogic/brams.txt"); + run("techmap -map +/anlogic/brams_map.v"); + run("setundef -zero -params t:EG_PHY_BRAM"); + run("setundef -zero -params t:EG_PHY_BRAM32K"); + } + if (!nolutram && check_label("map_lutram", "(skip if -nolutram)")) { run("memory_bram -rules +/anlogic/lutrams.txt"); diff --git a/techlibs/common/simlib.v b/techlibs/common/simlib.v index e9129f690..b14488ff4 100644 --- a/techlibs/common/simlib.v +++ b/techlibs/common/simlib.v @@ -1292,6 +1292,33 @@ endmodule // -------------------------------------------------------- +module \$bmux (A, S, Y); + +parameter WIDTH = 0; +parameter S_WIDTH = 0; + +input [(WIDTH << S_WIDTH)-1:0] A; +input [S_WIDTH-1:0] S; +output [WIDTH-1:0] Y; + +wire [WIDTH-1:0] bm0_out, bm1_out; + +generate + if (S_WIDTH > 1) begin:muxlogic + \$bmux #(.WIDTH(WIDTH), .S_WIDTH(S_WIDTH-1)) bm0 (.A(A), .S(S[S_WIDTH-2:0]), .Y(bm0_out)); + \$bmux #(.WIDTH(WIDTH), .S_WIDTH(S_WIDTH-1)) bm1 (.A(A[(WIDTH << S_WIDTH)-1:WIDTH << (S_WIDTH - 1)]), .S(S[S_WIDTH-2:0]), .Y(bm1_out)); + assign Y = S[S_WIDTH-1] ? bm1_out : bm0_out; + end else if (S_WIDTH == 1) begin:simple + assign Y = S ? A[1] : A[0]; + end else begin:passthru + assign Y = A; + end +endgenerate + +endmodule + +// -------------------------------------------------------- + module \$pmux (A, B, S, Y); parameter WIDTH = 0; @@ -1318,6 +1345,26 @@ end endmodule // -------------------------------------------------------- + +module \$demux (A, S, Y); + +parameter WIDTH = 1; +parameter S_WIDTH = 1; + +input [WIDTH-1:0] A; +input [S_WIDTH-1:0] S; +output [(WIDTH << S_WIDTH)-1:0] Y; + +genvar i; +generate + for (i = 0; i < (1 << S_WIDTH); i = i + 1) begin:slices + assign Y[i*WIDTH+:WIDTH] = (S == i) ? A : 0; + end +endgenerate + +endmodule + +// -------------------------------------------------------- `ifndef SIMLIB_NOLUT module \$lut (A, Y); @@ -1326,30 +1373,9 @@ parameter WIDTH = 0; parameter LUT = 0; input [WIDTH-1:0] A; -output reg Y; - -wire lut0_out, lut1_out; +output Y; -generate - if (WIDTH <= 1) begin:simple - assign {lut1_out, lut0_out} = LUT; - end else begin:complex - \$lut #( .WIDTH(WIDTH-1), .LUT(LUT ) ) lut0 ( .A(A[WIDTH-2:0]), .Y(lut0_out) ); - \$lut #( .WIDTH(WIDTH-1), .LUT(LUT >> (2**(WIDTH-1))) ) lut1 ( .A(A[WIDTH-2:0]), .Y(lut1_out) ); - end - - if (WIDTH > 0) begin:lutlogic - always @* begin - casez ({A[WIDTH-1], lut0_out, lut1_out}) - 3'b?11: Y = 1'b1; - 3'b?00: Y = 1'b0; - 3'b0??: Y = lut0_out; - 3'b1??: Y = lut1_out; - default: Y = 1'bx; - endcase - end - end -endgenerate +\$bmux #(.WIDTH(1), .S_WIDTH(WIDTH)) mux(.A(LUT), .S(A), .Y(Y)); endmodule diff --git a/techlibs/common/techmap.v b/techlibs/common/techmap.v index 667773e1b..91d385b80 100644 --- a/techlibs/common/techmap.v +++ b/techlibs/common/techmap.v @@ -59,7 +59,7 @@ module _90_simplemap_compare_ops; endmodule (* techmap_simplemap *) -(* techmap_celltype = "$pos $slice $concat $mux $tribuf" *) +(* techmap_celltype = "$pos $slice $concat $mux $tribuf $bmux" *) module _90_simplemap_various; endmodule @@ -597,6 +597,43 @@ module _90_pmux (A, B, S, Y); assign Y = |S ? Y_B : A; endmodule +// -------------------------------------------------------- +// Demultiplexers +// -------------------------------------------------------- + +(* techmap_celltype = "$demux" *) +module _90_demux (A, S, Y); + parameter WIDTH = 1; + parameter S_WIDTH = 1; + + (* force_downto *) + input [WIDTH-1:0] A; + (* force_downto *) + input [S_WIDTH-1:0] S; + (* force_downto *) + output [(WIDTH << S_WIDTH)-1:0] Y; + + generate + if (S_WIDTH == 0) begin + assign Y = A; + end else if (S_WIDTH == 1) begin + assign Y[0+:WIDTH] = S ? 0 : A; + assign Y[WIDTH+:WIDTH] = S ? A : 0; + end else begin + localparam SPLIT = S_WIDTH / 2; + wire [(1 << (S_WIDTH-SPLIT))-1:0] YH; + wire [(1 << SPLIT)-1:0] YL; + $demux #(.WIDTH(1), .S_WIDTH(SPLIT)) lo (.A(1'b1), .S(S[SPLIT-1:0]), .Y(YL)); + $demux #(.WIDTH(1), .S_WIDTH(S_WIDTH-SPLIT)) hi (.A(1'b1), .S(S[S_WIDTH-1:SPLIT]), .Y(YH)); + genvar i; + for (i = 0; i < (1 << S_WIDTH); i = i + 1) begin + localparam [S_WIDTH-1:0] IDX = i; + assign Y[i*WIDTH+:WIDTH] = (YL[IDX[SPLIT-1:0]] & YH[IDX[S_WIDTH-1:SPLIT]]) ? A : 0; + end + end + endgenerate +endmodule + // -------------------------------------------------------- // LUTs diff --git a/techlibs/ecp5/cells_sim.v b/techlibs/ecp5/cells_sim.v index 357fd9173..a5f905cf8 100644 --- a/techlibs/ecp5/cells_sim.v +++ b/techlibs/ecp5/cells_sim.v @@ -204,7 +204,7 @@ module TRELLIS_DPR16X4 ( integer i; initial begin for (i = 0; i < 16; i = i + 1) - mem[i] <= {INITVAL[i+3], INITVAL[i+2], INITVAL[i+1], INITVAL[i]}; + mem[i] <= INITVAL[4*i +: 4]; end wire muxwck = (WCKMUX == "INV") ? ~WCK : WCK; diff --git a/techlibs/gowin/cells_sim.v b/techlibs/gowin/cells_sim.v index 41398409d..bb4b9e5c5 100644 --- a/techlibs/gowin/cells_sim.v +++ b/techlibs/gowin/cells_sim.v @@ -674,51 +674,250 @@ end endmodule + +module RAM16S1 (DO, DI, AD, WRE, CLK); + +parameter INIT_0 = 16'h0000; + +input [3:0] AD; +input DI; +output DO; +input CLK; +input WRE; + +specify + (AD *> DO) = (270, 405); + $setup(DI, posedge CLK, 62); + $setup(WRE, posedge CLK, 62); + $setup(AD, posedge CLK, 62); + (posedge CLK => (DO : 1'bx)) = (474, 565); +endspecify + +reg [15:0] mem; + +initial begin + mem = INIT_0; +end + +assign DO = mem[AD]; + +always @(posedge CLK) begin + if (WRE) begin + mem[AD] <= DI; + end +end + +endmodule + + +module RAM16S2 (DO, DI, AD, WRE, CLK); + +parameter INIT_0 = 16'h0000; +parameter INIT_1 = 16'h0000; + +input [3:0] AD; +input [1:0] DI; +output [1:0] DO; +input CLK; +input WRE; + +specify + (AD *> DO) = (270, 405); + $setup(DI, posedge CLK, 62); + $setup(WRE, posedge CLK, 62); + $setup(AD, posedge CLK, 62); + (posedge CLK => (DO : 2'bx)) = (474, 565); +endspecify + +reg [15:0] mem0, mem1; + +initial begin + mem0 = INIT_0; + mem1 = INIT_1; +end + +assign DO[0] = mem0[AD]; +assign DO[1] = mem1[AD]; + +always @(posedge CLK) begin + if (WRE) begin + mem0[AD] <= DI[0]; + mem1[AD] <= DI[1]; + end +end + +endmodule + + module RAM16S4 (DO, DI, AD, WRE, CLK); - parameter WIDTH = 4; - parameter INIT_0 = 16'h0000; - parameter INIT_1 = 16'h0000; - parameter INIT_2 = 16'h0000; - parameter INIT_3 = 16'h0000; - - input [WIDTH-1:0] AD; - input [WIDTH-1:0] DI; - output [WIDTH-1:0] DO; - input CLK; - input WRE; - specify - (AD => DO) = (270, 405); +parameter INIT_0 = 16'h0000; +parameter INIT_1 = 16'h0000; +parameter INIT_2 = 16'h0000; +parameter INIT_3 = 16'h0000; + +input [3:0] AD; +input [3:0] DI; +output [3:0] DO; +input CLK; +input WRE; + +specify + (AD *> DO) = (270, 405); $setup(DI, posedge CLK, 62); $setup(WRE, posedge CLK, 62); $setup(AD, posedge CLK, 62); - (posedge CLK => (DO : {WIDTH{1'bx}})) = (474, 565); - endspecify + (posedge CLK => (DO : 4'bx)) = (474, 565); +endspecify + +reg [15:0] mem0, mem1, mem2, mem3; + +initial begin + mem0 = INIT_0; + mem1 = INIT_1; + mem2 = INIT_2; + mem3 = INIT_3; +end + +assign DO[0] = mem0[AD]; +assign DO[1] = mem1[AD]; +assign DO[2] = mem2[AD]; +assign DO[3] = mem3[AD]; + +always @(posedge CLK) begin + if (WRE) begin + mem0[AD] <= DI[0]; + mem1[AD] <= DI[1]; + mem2[AD] <= DI[2]; + mem3[AD] <= DI[3]; + end +end + +endmodule - reg [15:0] mem0, mem1, mem2, mem3; - - initial begin - mem0 = INIT_0; - mem1 = INIT_1; - mem2 = INIT_2; - mem3 = INIT_3; - end - - assign DO[0] = mem0[AD]; - assign DO[1] = mem1[AD]; - assign DO[2] = mem2[AD]; - assign DO[3] = mem3[AD]; - - always @(posedge CLK) begin - if (WRE) begin - mem0[AD] <= DI[0]; - mem1[AD] <= DI[1]; - mem2[AD] <= DI[2]; - mem3[AD] <= DI[3]; - end - end - -endmodule // RAM16S4 + +module RAM16SDP1 (DO, DI, WAD, RAD, WRE, CLK); + +parameter INIT_0 = 16'h0000; + +input [3:0] WAD; +input [3:0] RAD; +input DI; +output DO; +input CLK; +input WRE; + +specify + (RAD *> DO) = (270, 405); + $setup(DI, posedge CLK, 62); + $setup(WRE, posedge CLK, 62); + $setup(WAD, posedge CLK, 62); + (posedge CLK => (DO : 1'bx)) = (474, 565); +endspecify + +reg [15:0] mem; + +initial begin + mem = INIT_0; +end + +assign DO = mem[RAD]; + +always @(posedge CLK) begin + if (WRE) begin + mem[WAD] <= DI; + end +end + +endmodule + + +module RAM16SDP2 (DO, DI, WAD, RAD, WRE, CLK); + +parameter INIT_0 = 16'h0000; +parameter INIT_1 = 16'h0000; + +input [3:0] WAD; +input [3:0] RAD; +input [1:0] DI; +output [1:0] DO; +input CLK; +input WRE; + +specify + (RAD *> DO) = (270, 405); + $setup(DI, posedge CLK, 62); + $setup(WRE, posedge CLK, 62); + $setup(WAD, posedge CLK, 62); + (posedge CLK => (DO : 2'bx)) = (474, 565); +endspecify + +reg [15:0] mem0, mem1; + +initial begin + mem0 = INIT_0; + mem1 = INIT_1; +end + +assign DO[0] = mem0[RAD]; +assign DO[1] = mem1[RAD]; + +always @(posedge CLK) begin + if (WRE) begin + mem0[WAD] <= DI[0]; + mem1[WAD] <= DI[1]; + end +end + +endmodule + + +module RAM16SDP4 (DO, DI, WAD, RAD, WRE, CLK); + +parameter INIT_0 = 16'h0000; +parameter INIT_1 = 16'h0000; +parameter INIT_2 = 16'h0000; +parameter INIT_3 = 16'h0000; + +input [3:0] WAD; +input [3:0] RAD; +input [3:0] DI; +output [3:0] DO; +input CLK; +input WRE; + +specify + (RAD *> DO) = (270, 405); + $setup(DI, posedge CLK, 62); + $setup(WRE, posedge CLK, 62); + $setup(WAD, posedge CLK, 62); + (posedge CLK => (DO : 4'bx)) = (474, 565); +endspecify + +reg [15:0] mem0, mem1, mem2, mem3; + +initial begin + mem0 = INIT_0; + mem1 = INIT_1; + mem2 = INIT_2; + mem3 = INIT_3; +end + +assign DO[0] = mem0[RAD]; +assign DO[1] = mem1[RAD]; +assign DO[2] = mem2[RAD]; +assign DO[3] = mem3[RAD]; + +always @(posedge CLK) begin + if (WRE) begin + mem0[WAD] <= DI[0]; + mem1[WAD] <= DI[1]; + mem2[WAD] <= DI[2]; + mem3[WAD] <= DI[3]; + end +end + +endmodule (* blackbox *) diff --git a/techlibs/gowin/lutrams_map.v b/techlibs/gowin/lutrams_map.v index a50ab365a..e5daab6ae 100644 --- a/techlibs/gowin/lutrams_map.v +++ b/techlibs/gowin/lutrams_map.v @@ -15,13 +15,14 @@ module \$__GW1NR_RAM16S4 (CLK1, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN); `include "brams_init3.vh" - RAM16S4 + RAM16SDP4 #(.INIT_0(INIT_0), .INIT_1(INIT_1), .INIT_2(INIT_2), .INIT_3(INIT_3)) _TECHMAP_REPLACE_ - (.AD(B1ADDR), + (.WAD(B1ADDR), + .RAD(A1ADDR), .DI(B1DATA), .DO(A1DATA), .CLK(CLK1), diff --git a/techlibs/nexus/arith_map.v b/techlibs/nexus/arith_map.v index 9a1fedfc8..81ab7ba54 100644 --- a/techlibs/nexus/arith_map.v +++ b/techlibs/nexus/arith_map.v @@ -90,7 +90,7 @@ module _80_nexus_alu (A, B, CI, BI, X, Y, CO); assign CO[i] = (AA[i] && BB[i]) || ((Y[i] ^ AA[i] ^ BB[i]) && (AA[i] || BB[i])); if (i+1 < Y_WIDTH) begin - assign CO[i + 1] = (AA[i] && BB[i]) || ((Y[i] ^ AA[i] ^ BB[i]) && (AA[i] || BB[i])); + assign CO[i + 1] = (AA[i + 1] && BB[i + 1]) || ((Y[i + 1] ^ AA[i + 1] ^ BB[i + 1]) && (AA[i + 1] || BB[i + 1])); assign Y[i+1] = Y1[i]; end end endgenerate diff --git a/techlibs/nexus/cells_sim.v b/techlibs/nexus/cells_sim.v index 1e876a210..d1c8bf0d7 100644 --- a/techlibs/nexus/cells_sim.v +++ b/techlibs/nexus/cells_sim.v @@ -54,8 +54,8 @@ endmodule // Bidirectional IO buffer module BB(input T, I, output O, (* iopad_external_pin *) inout B); - assign B = T ? 1'bz : O; - assign I = B; + assign B = T ? 1'bz : I; + assign O = B; endmodule // Input buffer diff --git a/techlibs/quicklogic/synth_quicklogic.cc b/techlibs/quicklogic/synth_quicklogic.cc index a67b167b8..754de2de6 100644 --- a/techlibs/quicklogic/synth_quicklogic.cc +++ b/techlibs/quicklogic/synth_quicklogic.cc @@ -225,8 +225,8 @@ struct SynthQuickLogicPass : public ScriptPass { } if (check_label("verilog")) { - if (!verilog_file.empty()) { - run("write_verilog -noattr -nohex " + verilog_file); + if (!verilog_file.empty() || help_mode) { + run(stringf("write_verilog -noattr -nohex %s", help_mode ? "<file-name>" : verilog_file.c_str())); } } } |