ice40: Use `memory_libmap` pass.
authorMarcelina Kościelnicka <mwk@0x04.net>
Sun, 27 Feb 2022 08:29:26 +0000 (09:29 +0100)
committerMarcelina Kościelnicka <mwk@0x04.net>
Wed, 18 May 2022 15:32:56 +0000 (17:32 +0200)
techlibs/ice40/.gitignore [deleted file]
techlibs/ice40/Makefile.inc
techlibs/ice40/brams.txt
techlibs/ice40/brams_init.py [deleted file]
techlibs/ice40/brams_map.v
techlibs/ice40/spram.txt [new file with mode: 0644]
techlibs/ice40/spram_map.v [new file with mode: 0644]
techlibs/ice40/synth_ice40.cc
tests/arch/ice40/memories.ys

diff --git a/techlibs/ice40/.gitignore b/techlibs/ice40/.gitignore
deleted file mode 100644 (file)
index 6bf3b67..0000000
+++ /dev/null
@@ -1,4 +0,0 @@
-brams_init.mk
-brams_init1.vh
-brams_init2.vh
-brams_init3.vh
index 8ce3cb024573c5c253ef785254ab263aa7d11fb9..4bf8e4e86f08275139cb5c973dd04229e59c0758 100644 (file)
@@ -3,22 +3,6 @@ OBJS += techlibs/ice40/synth_ice40.o
 OBJS += techlibs/ice40/ice40_braminit.o
 OBJS += techlibs/ice40/ice40_opt.o
 
-GENFILES += techlibs/ice40/brams_init1.vh
-GENFILES += techlibs/ice40/brams_init2.vh
-GENFILES += techlibs/ice40/brams_init3.vh
-
-EXTRA_OBJS += techlibs/ice40/brams_init.mk
-.SECONDARY: techlibs/ice40/brams_init.mk
-
-techlibs/ice40/brams_init.mk: techlibs/ice40/brams_init.py
-       $(Q) mkdir -p techlibs/ice40
-       $(P) $(PYTHON_EXECUTABLE) $<
-       $(Q) touch techlibs/ice40/brams_init.mk
-
-techlibs/ice40/brams_init1.vh: techlibs/ice40/brams_init.mk
-techlibs/ice40/brams_init2.vh: techlibs/ice40/brams_init.mk
-techlibs/ice40/brams_init3.vh: techlibs/ice40/brams_init.mk
-
 $(eval $(call add_share_file,share/ice40,techlibs/ice40/arith_map.v))
 $(eval $(call add_share_file,share/ice40,techlibs/ice40/cells_map.v))
 $(eval $(call add_share_file,share/ice40,techlibs/ice40/ff_map.v))
@@ -26,10 +10,7 @@ $(eval $(call add_share_file,share/ice40,techlibs/ice40/cells_sim.v))
 $(eval $(call add_share_file,share/ice40,techlibs/ice40/latches_map.v))
 $(eval $(call add_share_file,share/ice40,techlibs/ice40/brams.txt))
 $(eval $(call add_share_file,share/ice40,techlibs/ice40/brams_map.v))
+$(eval $(call add_share_file,share/ice40,techlibs/ice40/spram.txt))
+$(eval $(call add_share_file,share/ice40,techlibs/ice40/spram_map.v))
 $(eval $(call add_share_file,share/ice40,techlibs/ice40/dsp_map.v))
 $(eval $(call add_share_file,share/ice40,techlibs/ice40/abc9_model.v))
-
-$(eval $(call add_gen_share_file,share/ice40,techlibs/ice40/brams_init1.vh))
-$(eval $(call add_gen_share_file,share/ice40,techlibs/ice40/brams_init2.vh))
-$(eval $(call add_gen_share_file,share/ice40,techlibs/ice40/brams_init3.vh))
-
index 36dfddab25bbe87f2f4058c6c8c6bb984bebec7e..518972c2ae9f711cf29f1d64a6a95cd96937cdc3 100644 (file)
-bram $__ICE40_RAM4K_M0
-  init 1
-  abits 8
-  dbits 16
-  groups 2
-  ports  1  1
-  wrmode 0  1
-  enable 1 16
-  transp 0  0
-  clocks 2  3
-  clkpol 2  3
-endbram
-
-bram $__ICE40_RAM4K_M123
-  init 1
-  abits  9 @M1
-  dbits  8 @M1
-  abits 10 @M2
-  dbits  4 @M2
-  abits 11 @M3
-  dbits  2 @M3
-  groups 2
-  ports  1 1
-  wrmode 0 1
-  enable 1 1
-  transp 0 0
-  clocks 2 3
-  clkpol 2 3
-endbram
-
-# The syn_* attributes are described in:
-# https://www.latticesemi.com/-/media/LatticeSemi/Documents/Tutorials/AK/LatticeDiamondTutorial311.ashx
-attr_icase 1
-
-match $__ICE40_RAM4K_M0
-  # implicitly requested RAM or ROM
-  attribute !syn_ramstyle syn_ramstyle=auto
-  attribute !syn_romstyle syn_romstyle=auto
-  attribute !ram_block
-  attribute !rom_block
-  attribute !logic_block
-  min efficiency 2
-  make_transp
-  or_next_if_better
-endmatch
-
-match $__ICE40_RAM4K_M0
-  # explicitly requested RAM
-  attribute syn_ramstyle=block_ram ram_block
-  attribute !syn_romstyle
-  attribute !rom_block
-  attribute !logic_block
-  min wports 1
-  make_transp
-  or_next_if_better
-endmatch
-
-match $__ICE40_RAM4K_M0
-  # explicitly requested ROM
-  attribute syn_romstyle=ebr rom_block
-  attribute !syn_ramstyle
-  attribute !ram_block
-  attribute !logic_block
-  max wports 0
-  make_transp
-  or_next_if_better
-endmatch
-
-match $__ICE40_RAM4K_M123
-  # implicitly requested RAM or ROM
-  attribute !syn_ramstyle syn_ramstyle=auto
-  attribute !syn_romstyle syn_romstyle=auto
-  attribute !ram_block
-  attribute !rom_block
-  attribute !logic_block
-  min efficiency 2
-  make_transp
-  or_next_if_better
-endmatch
-
-match $__ICE40_RAM4K_M123
-  # explicitly requested RAM
-  attribute syn_ramstyle=block_ram ram_block
-  attribute !syn_romstyle
-  attribute !rom_block
-  attribute !logic_block
-  min wports 1
-  make_transp
-  or_next_if_better
-endmatch
-
-match $__ICE40_RAM4K_M123
-  # explicitly requested ROM
-  attribute syn_romstyle=ebr rom_block
-  attribute !syn_ramstyle
-  attribute !ram_block
-  attribute !logic_block
-  max wports 0
-  make_transp
-endmatch
+ram block $__ICE40_RAM4K_ {
+       abits 11;
+       widths 2 4 8 16 per_port;
+       cost 64;
+       option "HAS_BE" 1 {
+               byte 1;
+       }
+       init any;
+       port sw "W" {
+               option "HAS_BE" 0 {
+                       width 2 4 8;
+               }
+               option "HAS_BE" 1 {
+                       width 16;
+                       wrbe_separate;
+               }
+               clock anyedge;
+       }
+       port sr "R" {
+               clock anyedge;
+               rden;
+       }
+}
diff --git a/techlibs/ice40/brams_init.py b/techlibs/ice40/brams_init.py
deleted file mode 100644 (file)
index 4a14851..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/usr/bin/env python3
-
-def write_init_vh(filename, initbits):
-    with open(filename, "w") as f:
-        for i in range(16):
-            print("localparam [255:0] INIT_%X = {" % i, file=f)
-            for k in range(32):
-                print("  %s%s" % (", ".join(["INIT[%4d]" % initbits[i*256 + 255 - k*8 - l] for l in range(8)]), "," if k != 31 else ""), file=f)
-            print("};", file=f);
-
-write_init_vh("techlibs/ice40/brams_init1.vh", [i//2 + 2048*(i%2) for i in range(4096)])
-write_init_vh("techlibs/ice40/brams_init2.vh", [i//4 + 1024*(i%4) for i in range(4096)])
-write_init_vh("techlibs/ice40/brams_init3.vh", [i//8 +  512*(i%8) for i in range(4096)])
-
index db9f5d8ce5965cd74a4d1d9515b79b6ca12fa865..9d7b793e1e89b28195bf3a6c92363a4dd71a64d6 100644 (file)
-
-module \$__ICE40_RAM4K (
-       output [15:0] RDATA,
-       input         RCLK, RCLKE, RE,
-       input  [10:0] RADDR,
-       input         WCLK, WCLKE, WE,
-       input  [10:0] WADDR,
-       input  [15:0] MASK, WDATA
-);
-       parameter [1:0] READ_MODE = 0;
-       parameter [1:0] WRITE_MODE = 0;
-       parameter [0:0] NEGCLK_R = 0;
-       parameter [0:0] NEGCLK_W = 0;
-
-       parameter [255:0] INIT_0 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-       parameter [255:0] INIT_1 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-       parameter [255:0] INIT_2 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-       parameter [255:0] INIT_3 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-       parameter [255:0] INIT_4 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-       parameter [255:0] INIT_5 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-       parameter [255:0] INIT_6 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-       parameter [255:0] INIT_7 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-       parameter [255:0] INIT_8 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-       parameter [255:0] INIT_9 = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-       parameter [255:0] INIT_A = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-       parameter [255:0] INIT_B = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-       parameter [255:0] INIT_C = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-       parameter [255:0] INIT_D = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-       parameter [255:0] INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-       parameter [255:0] INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000;
-
-       generate
-               case ({NEGCLK_R, NEGCLK_W})
-                       2'b00:
-                               SB_RAM40_4K #(
-                                       .READ_MODE(READ_MODE),
-                                       .WRITE_MODE(WRITE_MODE),
-                                       .INIT_0(INIT_0),
-                                       .INIT_1(INIT_1),
-                                       .INIT_2(INIT_2),
-                                       .INIT_3(INIT_3),
-                                       .INIT_4(INIT_4),
-                                       .INIT_5(INIT_5),
-                                       .INIT_6(INIT_6),
-                                       .INIT_7(INIT_7),
-                                       .INIT_8(INIT_8),
-                                       .INIT_9(INIT_9),
-                                       .INIT_A(INIT_A),
-                                       .INIT_B(INIT_B),
-                                       .INIT_C(INIT_C),
-                                       .INIT_D(INIT_D),
-                                       .INIT_E(INIT_E),
-                                       .INIT_F(INIT_F)
-                               ) _TECHMAP_REPLACE_ (
-                                       .RDATA(RDATA),
-                                       .RCLK (RCLK ),
-                                       .RCLKE(RCLKE),
-                                       .RE   (RE   ),
-                                       .RADDR(RADDR),
-                                       .WCLK (WCLK ),
-                                       .WCLKE(WCLKE),
-                                       .WE   (WE   ),
-                                       .WADDR(WADDR),
-                                       .MASK (MASK ),
-                                       .WDATA(WDATA)
-                               );
-                       2'b01:
-                               SB_RAM40_4KNW #(
-                                       .READ_MODE(READ_MODE),
-                                       .WRITE_MODE(WRITE_MODE),
-                                       .INIT_0(INIT_0),
-                                       .INIT_1(INIT_1),
-                                       .INIT_2(INIT_2),
-                                       .INIT_3(INIT_3),
-                                       .INIT_4(INIT_4),
-                                       .INIT_5(INIT_5),
-                                       .INIT_6(INIT_6),
-                                       .INIT_7(INIT_7),
-                                       .INIT_8(INIT_8),
-                                       .INIT_9(INIT_9),
-                                       .INIT_A(INIT_A),
-                                       .INIT_B(INIT_B),
-                                       .INIT_C(INIT_C),
-                                       .INIT_D(INIT_D),
-                                       .INIT_E(INIT_E),
-                                       .INIT_F(INIT_F)
-                               ) _TECHMAP_REPLACE_ (
-                                       .RDATA(RDATA),
-                                       .RCLK (RCLK ),
-                                       .RCLKE(RCLKE),
-                                       .RE   (RE   ),
-                                       .RADDR(RADDR),
-                                       .WCLKN(WCLK ),
-                                       .WCLKE(WCLKE),
-                                       .WE   (WE   ),
-                                       .WADDR(WADDR),
-                                       .MASK (MASK ),
-                                       .WDATA(WDATA)
-                               );
-                       2'b10:
-                               SB_RAM40_4KNR #(
-                                       .READ_MODE(READ_MODE),
-                                       .WRITE_MODE(WRITE_MODE),
-                                       .INIT_0(INIT_0),
-                                       .INIT_1(INIT_1),
-                                       .INIT_2(INIT_2),
-                                       .INIT_3(INIT_3),
-                                       .INIT_4(INIT_4),
-                                       .INIT_5(INIT_5),
-                                       .INIT_6(INIT_6),
-                                       .INIT_7(INIT_7),
-                                       .INIT_8(INIT_8),
-                                       .INIT_9(INIT_9),
-                                       .INIT_A(INIT_A),
-                                       .INIT_B(INIT_B),
-                                       .INIT_C(INIT_C),
-                                       .INIT_D(INIT_D),
-                                       .INIT_E(INIT_E),
-                                       .INIT_F(INIT_F)
-                               ) _TECHMAP_REPLACE_ (
-                                       .RDATA(RDATA),
-                                       .RCLKN(RCLK ),
-                                       .RCLKE(RCLKE),
-                                       .RE   (RE   ),
-                                       .RADDR(RADDR),
-                                       .WCLK (WCLK ),
-                                       .WCLKE(WCLKE),
-                                       .WE   (WE   ),
-                                       .WADDR(WADDR),
-                                       .MASK (MASK ),
-                                       .WDATA(WDATA)
-                               );
-                       2'b11:
-                               SB_RAM40_4KNRNW #(
-                                       .READ_MODE(READ_MODE),
-                                       .WRITE_MODE(WRITE_MODE),
-                                       .INIT_0(INIT_0),
-                                       .INIT_1(INIT_1),
-                                       .INIT_2(INIT_2),
-                                       .INIT_3(INIT_3),
-                                       .INIT_4(INIT_4),
-                                       .INIT_5(INIT_5),
-                                       .INIT_6(INIT_6),
-                                       .INIT_7(INIT_7),
-                                       .INIT_8(INIT_8),
-                                       .INIT_9(INIT_9),
-                                       .INIT_A(INIT_A),
-                                       .INIT_B(INIT_B),
-                                       .INIT_C(INIT_C),
-                                       .INIT_D(INIT_D),
-                                       .INIT_E(INIT_E),
-                                       .INIT_F(INIT_F)
-                               ) _TECHMAP_REPLACE_ (
-                                       .RDATA(RDATA),
-                                       .RCLKN(RCLK ),
-                                       .RCLKE(RCLKE),
-                                       .RE   (RE   ),
-                                       .RADDR(RADDR),
-                                       .WCLKN(WCLK ),
-                                       .WCLKE(WCLKE),
-                                       .WE   (WE   ),
-                                       .WADDR(WADDR),
-                                       .MASK (MASK ),
-                                       .WDATA(WDATA)
-                               );
-               endcase
-       endgenerate
-endmodule
-
-
-module \$__ICE40_RAM4K_M0 (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
-       parameter [0:0] CLKPOL2 = 1;
-       parameter [0:0] CLKPOL3 = 1;
-
-       parameter [4095:0] INIT = 4096'bx;
-
-       input CLK2;
-       input CLK3;
-
-       input [7:0] A1ADDR;
-       output [15:0] A1DATA;
-       input A1EN;
-
-       input [7:0] B1ADDR;
-       input [15:0] B1DATA;
-       input [15:0] B1EN;
-
-       wire [10:0] A1ADDR_11 = A1ADDR;
-       wire [10:0] B1ADDR_11 = B1ADDR;
-
-       \$__ICE40_RAM4K #(
-               .READ_MODE(0),
-               .WRITE_MODE(0),
-               .NEGCLK_R(!CLKPOL2),
-               .NEGCLK_W(!CLKPOL3),
-               .INIT_0(INIT[ 0*256 +: 256]),
-               .INIT_1(INIT[ 1*256 +: 256]),
-               .INIT_2(INIT[ 2*256 +: 256]),
-               .INIT_3(INIT[ 3*256 +: 256]),
-               .INIT_4(INIT[ 4*256 +: 256]),
-               .INIT_5(INIT[ 5*256 +: 256]),
-               .INIT_6(INIT[ 6*256 +: 256]),
-               .INIT_7(INIT[ 7*256 +: 256]),
-               .INIT_8(INIT[ 8*256 +: 256]),
-               .INIT_9(INIT[ 9*256 +: 256]),
-               .INIT_A(INIT[10*256 +: 256]),
-               .INIT_B(INIT[11*256 +: 256]),
-               .INIT_C(INIT[12*256 +: 256]),
-               .INIT_D(INIT[13*256 +: 256]),
-               .INIT_E(INIT[14*256 +: 256]),
-               .INIT_F(INIT[15*256 +: 256])
-       ) _TECHMAP_REPLACE_ (
-               .RDATA(A1DATA),
-               .RADDR(A1ADDR_11),
-               .RCLK(CLK2),
-               .RCLKE(A1EN),
-               .RE(1'b1),
-               .WDATA(B1DATA),
-               .WADDR(B1ADDR_11),
-               .MASK(~B1EN),
-               .WCLK(CLK3),
-               .WCLKE(|B1EN),
-               .WE(1'b1)
-       );
-endmodule
-
-module \$__ICE40_RAM4K_M123 (CLK2, CLK3, A1ADDR, A1DATA, A1EN, B1ADDR, B1DATA, B1EN);
-       parameter CFG_ABITS = 9;
-       parameter CFG_DBITS = 8;
-
-       parameter [0:0] CLKPOL2 = 1;
-       parameter [0:0] CLKPOL3 = 1;
-
-       parameter [4095:0] INIT = 4096'bx;
-
-       localparam MODE =
-               CFG_ABITS ==  9 ? 1 :
-               CFG_ABITS == 10 ? 2 :
-               CFG_ABITS == 11 ? 3 : '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 B1EN;
-
-       wire [10:0] A1ADDR_11 = A1ADDR;
-       wire [10:0] B1ADDR_11 = B1ADDR;
-
-       wire [15:0] A1DATA_16, B1DATA_16;
-
-`define INSTANCE \
-       \$__ICE40_RAM4K #( \
-               .READ_MODE(MODE), \
-               .WRITE_MODE(MODE), \
-               .NEGCLK_R(!CLKPOL2), \
-               .NEGCLK_W(!CLKPOL3), \
-               .INIT_0(INIT_0), \
-               .INIT_1(INIT_1), \
-               .INIT_2(INIT_2), \
-               .INIT_3(INIT_3), \
-               .INIT_4(INIT_4), \
-               .INIT_5(INIT_5), \
-               .INIT_6(INIT_6), \
-               .INIT_7(INIT_7), \
-               .INIT_8(INIT_8), \
-               .INIT_9(INIT_9), \
-               .INIT_A(INIT_A), \
-               .INIT_B(INIT_B), \
-               .INIT_C(INIT_C), \
-               .INIT_D(INIT_D), \
-               .INIT_E(INIT_E), \
-               .INIT_F(INIT_F) \
+module $__ICE40_RAM4K_ (...);
+
+parameter INIT = 0;
+parameter OPTION_HAS_BE = 1;
+parameter PORT_R_WIDTH = 16;
+parameter PORT_W_WIDTH = 16;
+parameter PORT_W_WR_BE_WIDTH = 16;
+parameter PORT_R_CLK_POL = 1;
+parameter PORT_W_CLK_POL = 1;
+
+input PORT_R_CLK;
+input PORT_R_RD_EN;
+input [10:0] PORT_R_ADDR;
+output [PORT_R_WIDTH-1:0] PORT_R_RD_DATA;
+
+input PORT_W_CLK;
+input PORT_W_WR_EN;
+input [15:0] PORT_W_WR_BE;
+input [10:0] PORT_W_ADDR;
+input [PORT_W_WIDTH-1:0] PORT_W_WR_DATA;
+
+wire [15:0] RDATA;
+wire [15:0] WDATA;
+wire [15:0] MASK;
+wire [10:0] RADDR = {PORT_R_ADDR[0], PORT_R_ADDR[1], PORT_R_ADDR[2], PORT_R_ADDR[10:3]};
+wire [10:0] WADDR = {PORT_W_ADDR[0], PORT_W_ADDR[1], PORT_W_ADDR[2], PORT_W_ADDR[10:3]};
+
+function [1:0] mode;
+       input integer width;
+       case (width)
+       16: mode = 0;
+       8: mode = 1;
+       4: mode = 2;
+       2: mode = 3;
+       endcase
+endfunction
+
+function [255:0] slice_init;
+       input [3:0] idx;
+       integer i;
+       reg [7:0] ri;
+       reg [11:0] a;
+       for (i = 0; i < 256; i = i + 1) begin
+               ri = i;
+               a = {idx, ri[7:4], ri[0], ri[1], ri[2], ri[3]};
+               slice_init[i] = INIT[a];
+       end
+endfunction
+
+`define INSTANCE(type, rclk, wclk) \
+       type #( \
+               .INIT_0(slice_init(0)), \
+               .INIT_1(slice_init(1)), \
+               .INIT_2(slice_init(2)), \
+               .INIT_3(slice_init(3)), \
+               .INIT_4(slice_init(4)), \
+               .INIT_5(slice_init(5)), \
+               .INIT_6(slice_init(6)), \
+               .INIT_7(slice_init(7)), \
+               .INIT_8(slice_init(8)), \
+               .INIT_9(slice_init(9)), \
+               .INIT_A(slice_init(10)), \
+               .INIT_B(slice_init(11)), \
+               .INIT_C(slice_init(12)), \
+               .INIT_D(slice_init(13)), \
+               .INIT_E(slice_init(14)), \
+               .INIT_F(slice_init(15)), \
+               .READ_MODE(mode(PORT_R_WIDTH)), \
+               .WRITE_MODE(mode(PORT_W_WIDTH)) \
        ) _TECHMAP_REPLACE_ ( \
-               .RDATA(A1DATA_16), \
-               .RADDR(A1ADDR_11), \
-               .RCLK(CLK2), \
-               .RCLKE(A1EN), \
+               .RDATA(RDATA), \
+               .rclk(PORT_R_CLK), \
+               .RCLKE(PORT_R_RD_EN), \
                .RE(1'b1), \
-               .WDATA(B1DATA_16), \
-               .WADDR(B1ADDR_11), \
-               .WCLK(CLK3), \
-               .WCLKE(|B1EN), \
-               .WE(1'b1) \
+               .RADDR(RADDR), \
+               .WDATA(WDATA), \
+               .wclk(PORT_W_CLK), \
+               .WCLKE(PORT_W_WR_EN), \
+               .WE(1'b1), \
+               .WADDR(WADDR), \
+               .MASK(MASK), \
        );
 
-       generate
-               if (MODE == 1) begin
-                       assign A1DATA = {A1DATA_16[14], A1DATA_16[12], A1DATA_16[10], A1DATA_16[ 8],
-                                        A1DATA_16[ 6], A1DATA_16[ 4], A1DATA_16[ 2], A1DATA_16[ 0]};
-                       assign {B1DATA_16[14], B1DATA_16[12], B1DATA_16[10], B1DATA_16[ 8],
-                               B1DATA_16[ 6], B1DATA_16[ 4], B1DATA_16[ 2], B1DATA_16[ 0]} = B1DATA;
-                       `include "brams_init1.vh"
-                       `INSTANCE
-               end
-               if (MODE == 2) begin
-                       assign A1DATA = {A1DATA_16[13], A1DATA_16[9], A1DATA_16[5], A1DATA_16[1]};
-                       assign {B1DATA_16[13], B1DATA_16[9], B1DATA_16[5], B1DATA_16[1]} = B1DATA;
-                       `include "brams_init2.vh"
-                       `INSTANCE
-               end
-               if (MODE == 3) begin
-                       assign A1DATA = {A1DATA_16[11], A1DATA_16[3]};
-                       assign {B1DATA_16[11], B1DATA_16[3]} = B1DATA;
-                       `include "brams_init3.vh"
-                       `INSTANCE
-               end
-       endgenerate
-
-`undef INSTANCE
+generate
+
+case(PORT_R_WIDTH)
+       2: begin
+               assign PORT_R_RD_DATA = {
+                       RDATA[11],
+                       RDATA[3]
+               };
+       end
+       4: begin
+               assign PORT_R_RD_DATA = {
+                       RDATA[13],
+                       RDATA[5],
+                       RDATA[9],
+                       RDATA[1]
+               };
+       end
+       8: begin
+               assign PORT_R_RD_DATA = {
+                       RDATA[14],
+                       RDATA[6],
+                       RDATA[10],
+                       RDATA[2],
+                       RDATA[12],
+                       RDATA[4],
+                       RDATA[8],
+                       RDATA[0]
+               };
+       end
+       16: begin
+               assign PORT_R_RD_DATA = {
+                       RDATA[15],
+                       RDATA[7],
+                       RDATA[11],
+                       RDATA[3],
+                       RDATA[13],
+                       RDATA[5],
+                       RDATA[9],
+                       RDATA[1],
+                       RDATA[14],
+                       RDATA[6],
+                       RDATA[10],
+                       RDATA[2],
+                       RDATA[12],
+                       RDATA[4],
+                       RDATA[8],
+                       RDATA[0]
+               };
+       end
+endcase
+
+case(PORT_W_WIDTH)
+       2: begin
+               assign {
+                       WDATA[11],
+                       WDATA[3]
+               } = PORT_W_WR_DATA;
+       end
+       4: begin
+               assign {
+                       WDATA[13],
+                       WDATA[5],
+                       WDATA[9],
+                       WDATA[1]
+               } = PORT_W_WR_DATA;
+       end
+       8: begin
+               assign {
+                       WDATA[14],
+                       WDATA[6],
+                       WDATA[10],
+                       WDATA[2],
+                       WDATA[12],
+                       WDATA[4],
+                       WDATA[8],
+                       WDATA[0]
+               } = PORT_W_WR_DATA;
+       end
+       16: begin
+               assign WDATA = {
+                       PORT_W_WR_DATA[15],
+                       PORT_W_WR_DATA[7],
+                       PORT_W_WR_DATA[11],
+                       PORT_W_WR_DATA[3],
+                       PORT_W_WR_DATA[13],
+                       PORT_W_WR_DATA[5],
+                       PORT_W_WR_DATA[9],
+                       PORT_W_WR_DATA[1],
+                       PORT_W_WR_DATA[14],
+                       PORT_W_WR_DATA[6],
+                       PORT_W_WR_DATA[10],
+                       PORT_W_WR_DATA[2],
+                       PORT_W_WR_DATA[12],
+                       PORT_W_WR_DATA[4],
+                       PORT_W_WR_DATA[8],
+                       PORT_W_WR_DATA[0]
+               };
+               assign MASK = ~{
+                       PORT_W_WR_BE[15],
+                       PORT_W_WR_BE[7],
+                       PORT_W_WR_BE[11],
+                       PORT_W_WR_BE[3],
+                       PORT_W_WR_BE[13],
+                       PORT_W_WR_BE[5],
+                       PORT_W_WR_BE[9],
+                       PORT_W_WR_BE[1],
+                       PORT_W_WR_BE[14],
+                       PORT_W_WR_BE[6],
+                       PORT_W_WR_BE[10],
+                       PORT_W_WR_BE[2],
+                       PORT_W_WR_BE[12],
+                       PORT_W_WR_BE[4],
+                       PORT_W_WR_BE[8],
+                       PORT_W_WR_BE[0]
+               };
+       end
+endcase
+
+if (PORT_R_CLK_POL) begin
+       if (PORT_W_CLK_POL) begin
+               `INSTANCE(SB_RAM40_4K, RCLK, WCLK)
+       end else begin
+               `INSTANCE(SB_RAM40_4KNW, RCLK, WCLKN)
+       end
+end else begin
+       if (PORT_W_CLK_POL) begin
+               `INSTANCE(SB_RAM40_4KNR, RCLKN, WCLK)
+       end else begin
+               `INSTANCE(SB_RAM40_4KNRNW, RCLKN, WCLKN)
+       end
+end
+
+endgenerate
 
 endmodule
-
diff --git a/techlibs/ice40/spram.txt b/techlibs/ice40/spram.txt
new file mode 100644 (file)
index 0000000..ed0699f
--- /dev/null
@@ -0,0 +1,12 @@
+ram huge $__ICE40_SPRAM_ {
+       abits 14;
+       width 16;
+       cost 2048;
+       byte 4;
+       port srsw "A" {
+               clock posedge;
+               clken;
+               wrbe_separate;
+               rdwr no_change;
+       }
+}
diff --git a/techlibs/ice40/spram_map.v b/techlibs/ice40/spram_map.v
new file mode 100644 (file)
index 0000000..ae89195
--- /dev/null
@@ -0,0 +1,24 @@
+module $__ICE40_SPRAM_ (...);
+
+input PORT_A_CLK;
+input PORT_A_CLK_EN;
+input PORT_A_WR_EN;
+input [3:0] PORT_A_WR_BE;
+input [13:0] PORT_A_ADDR;
+input [15:0] PORT_A_WR_DATA;
+output [15:0] PORT_A_RD_DATA;
+
+SB_SPRAM256KA _TECHMAP_REPLACE_ (
+       .ADDRESS(PORT_A_ADDR),
+       .DATAIN(PORT_A_WR_DATA),
+       .MASKWREN(PORT_A_WR_BE),
+       .WREN(PORT_A_WR_EN),
+       .CHIPSELECT(PORT_A_CLK_EN),
+       .CLOCK(PORT_A_CLK),
+       .STANDBY(1'b0),
+       .SLEEP(1'b0),
+       .POWEROFF(1'b1),
+       .DATAOUT(PORT_A_RD_DATA),
+);
+
+endmodule
index 421ec3b4e2edc36256ec12c3f7b319aeba44a89a..c10b7003eecc2cddf22feeda1f16e610bc220e5e 100644 (file)
@@ -90,6 +90,9 @@ struct SynthIce40Pass : public ScriptPass
                log("    -nobram\n");
                log("        do not use SB_RAM40_4K* cells in output netlist\n");
                log("\n");
+               log("    -spram\n");
+               log("        enable automatic inference of SB_SPRAM256KA\n");
+               log("\n");
                log("    -dsp\n");
                log("        use iCE40 UltraPlus DSP cells for large arithmetic\n");
                log("\n");
@@ -116,7 +119,7 @@ struct SynthIce40Pass : public ScriptPass
        }
 
        string top_opt, blif_file, edif_file, json_file, device_opt;
-       bool nocarry, nodffe, nobram, dsp, flatten, retime, noabc, abc2, vpr, abc9, dff, flowmap;
+       bool nocarry, nodffe, nobram, spram, dsp, flatten, retime, noabc, abc2, vpr, abc9, dff, flowmap;
        int min_ce_use;
 
        void clear_flags() override
@@ -129,6 +132,7 @@ struct SynthIce40Pass : public ScriptPass
                nodffe = false;
                min_ce_use = -1;
                nobram = false;
+               spram = false;
                dsp = false;
                flatten = true;
                retime = false;
@@ -204,6 +208,10 @@ struct SynthIce40Pass : public ScriptPass
                                nobram = true;
                                continue;
                        }
+                       if (args[argidx] == "-spram") {
+                               spram = true;
+                               continue;
+                       }
                        if (args[argidx] == "-dsp") {
                                dsp = true;
                                continue;
@@ -322,19 +330,24 @@ struct SynthIce40Pass : public ScriptPass
                        run("opt_clean");
                }
 
-               if (!nobram && check_label("map_bram", "(skip if -nobram)"))
+               if (check_label("map_ram"))
                {
-                       run("memory_bram -rules +/ice40/brams.txt");
-                       run("techmap -map +/ice40/brams_map.v");
+                       std::string args = "";
+                       if (!spram)
+                               args += " -no-auto-huge";
+                       if (nobram)
+                               args += " -no-auto-block";
+                       if (help_mode)
+                               args += " [-no-auto-huge] [-no-auto-block]";
+                       run("memory_libmap -lib +/ice40/brams.txt -lib +/ice40/spram.txt" + args, "(-no-auto-huge unless -spram, -no-auto-block if -nobram)");
+                       run("techmap -map +/ice40/brams_map.v -map +/ice40/spram_map.v");
                        run("ice40_braminit");
                }
 
                if (check_label("map_ffram"))
                {
                        run("opt -fast -mux_undef -undriven -fine");
-                       run("memory_map -iattr -attr !ram_block -attr !rom_block -attr logic_block "
-                           "-attr syn_ramstyle=auto -attr syn_ramstyle=registers "
-                           "-attr syn_romstyle=auto -attr syn_romstyle=logic");
+                       run("memory_map");
                        run("opt -undriven -fine");
                }
 
index 4920a45e35d76e025c1abf8baf8475ba6fcd36ec..d480a3abe100b18944ab672c4d8386fa3be05e00 100644 (file)
@@ -71,34 +71,6 @@ synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp
 select -assert-count 0 t:SB_RAM40_4K # requested FFRAM explicitly
 select -assert-min 1 t:SB_DFFE
 
-design -reset; read_verilog -defer ../common/blockram.v
-chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp
-hierarchy -top sync_ram_sdp
-setattr -set syn_romstyle "ebr" m:memory
-synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp
-select -assert-count 1 t:$mem_v2 # requested BROM but this is a RAM
-
-design -reset; read_verilog -defer ../common/blockram.v
-chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp
-hierarchy -top sync_ram_sdp
-setattr -set rom_block 1 m:memory
-synth_ice40 -top sync_ram_sdp; cd sync_ram_sdp
-select -assert-count 1 t:$mem_v2 # requested BROM but this is a RAM
-
-design -reset; read_verilog -defer ../common/blockram.v
-chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp
-hierarchy -top sync_ram_sdp
-setattr -set syn_ramstyle "block_ram" m:memory
-synth_ice40 -top sync_ram_sdp -nobram; cd sync_ram_sdp
-select -assert-count 1 t:$mem_v2 # requested BRAM but BRAM is disabled
-
-design -reset; read_verilog -defer ../common/blockram.v
-chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_ram_sdp
-hierarchy -top sync_ram_sdp
-setattr -set ram_block 1 m:memory
-synth_ice40 -top sync_ram_sdp -nobram; cd sync_ram_sdp
-select -assert-count 1 t:$mem_v2 # requested BRAM but BRAM is disabled
-
 # ================================ ROM ================================
 # ROM bits <= 4K; Data width <= 16; Address width <= 11: -> SB_RAM40_4K
 
@@ -164,31 +136,3 @@ setattr -set logic_block 1 m:memory
 synth_ice40 -top sync_rom; cd sync_rom
 select -assert-count 0 t:SB_RAM40_4K # requested LUTROM explicitly
 select -assert-min 1 t:SB_LUT4
-
-design -reset; read_verilog -defer ../common/blockrom.v
-chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom
-hierarchy -top sync_rom
-setattr -set syn_ramstyle "block_ram" m:memory
-synth_ice40 -top sync_rom; cd sync_rom
-select -assert-count 1 t:$mem_v2 # requested BRAM but this is a ROM
-
-design -reset; read_verilog -defer ../common/blockrom.v
-chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom
-hierarchy -top sync_rom
-setattr -set ram_block 1 m:memory
-synth_ice40 -top sync_rom; cd sync_rom
-select -assert-count 1 t:$mem_v2 # requested BRAM but this is a ROM
-
-design -reset; read_verilog -defer ../common/blockrom.v
-chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom
-hierarchy -top sync_rom
-setattr -set syn_romstyle "ebr" m:memory
-synth_ice40 -top sync_rom -nobram; cd sync_rom
-select -assert-count 1 t:$mem_v2 # requested BROM but BRAM is disabled
-
-design -reset; read_verilog -defer ../common/blockrom.v
-chparam -set ADDRESS_WIDTH 2 -set DATA_WIDTH 8 sync_rom
-hierarchy -top sync_rom
-setattr -set rom_block 1 m:memory
-synth_ice40 -top sync_rom -nobram; cd sync_rom
-select -assert-count 1 t:$mem_v2 # requested BROM but BRAM is disabled