From 1277d1bcb8c325d1c7addafee9da90b521bc0da6 Mon Sep 17 00:00:00 2001 From: Clifford Wolf Date: Sun, 19 Apr 2015 21:37:40 +0200 Subject: [PATCH] iCE40: Added SB_RAM40_4K{,NR,NW,NRNW}* models --- techlibs/ice40/cells_sim.v | 302 +++++++++++++++++++++++++++++++++++-- 1 file changed, 289 insertions(+), 13 deletions(-) diff --git a/techlibs/ice40/cells_sim.v b/techlibs/ice40/cells_sim.v index def878216..4a11e4a9e 100644 --- a/techlibs/ice40/cells_sim.v +++ b/techlibs/ice40/cells_sim.v @@ -243,13 +243,293 @@ module SB_DFFNES (output reg Q, input C, E, S, D); Q <= D; endmodule -// Packed IceStorm Logic Cells +// SiliconBlue RAM Cells -module ICESTORM_CARRYCONST (output COUT); - parameter [0:0] CARRYCONST = 0; - assign COUT = CARRYCONST; +module SB_RAM40_4K ( + output reg [15:0] RDATA, + input RCLK, RCLKE, RE, + input [10:0] RADDR, + input WCLK, WCLKE, WE, + input [10:0] WADDR, + input [15:0] MASK, WDATA +); + // MODE 0: 256 x 16 + // MODE 1: 512 x 8 + // MODE 2: 1024 x 4 + // MODE 3: 2048 x 2 + parameter WRITE_MODE = 0; + parameter READ_MODE = 0; + + parameter INIT_0 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_1 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_2 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_3 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_4 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_5 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_6 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_7 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_8 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_9 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + +`ifndef BLACKBOX + integer i; + reg [15:0] memory [0:255]; + + initial begin + for (i=0; i<16; i=i+1) begin + memory[ 0*16 + i] <= INIT_0[16*i +: 16]; + memory[ 1*16 + i] <= INIT_1[16*i +: 16]; + memory[ 2*16 + i] <= INIT_2[16*i +: 16]; + memory[ 3*16 + i] <= INIT_3[16*i +: 16]; + memory[ 4*16 + i] <= INIT_4[16*i +: 16]; + memory[ 5*16 + i] <= INIT_5[16*i +: 16]; + memory[ 6*16 + i] <= INIT_6[16*i +: 16]; + memory[ 7*16 + i] <= INIT_7[16*i +: 16]; + memory[ 8*16 + i] <= INIT_8[16*i +: 16]; + memory[ 9*16 + i] <= INIT_9[16*i +: 16]; + memory[10*16 + i] <= INIT_A[16*i +: 16]; + memory[11*16 + i] <= INIT_B[16*i +: 16]; + memory[12*16 + i] <= INIT_C[16*i +: 16]; + memory[13*16 + i] <= INIT_D[16*i +: 16]; + memory[14*16 + i] <= INIT_E[16*i +: 16]; + memory[15*16 + i] <= INIT_F[16*i +: 16]; + end + end + + always @(posedge WCLK) begin + if (WE && WCLKE) begin + if (WRITE_MODE == 0) begin + for (i=0; i<16; i=i+1) + if (MASK[i]) memory[WADDR[7:0]][i] <= WDATA[i]; + end + if (WRITE_MODE == 1) begin + for (i=0; i<2; i=i+1) + if (WADDR[0] == i) memory[WADDR[8:1]][i*8 +: 8] <= WDATA[i][7:0]; + end + if (WRITE_MODE == 2) begin + for (i=0; i<4; i=i+1) + if (WADDR[1:0] == i) memory[WADDR[9:2]][i*4 +: 4] <= WDATA[i][3:0]; + end + if (WRITE_MODE == 3) begin + for (i=0; i<8; i=i+1) + if (WADDR[2:0] == i) memory[WADDR[10:3]][i*2 +: 2] <= WDATA[i][1:0]; + end + end + end + + always @(posedge RCLK) begin + if (RE && RCLKE) begin + if (READ_MODE == 0) begin + RDATA <= memory[RADDR[7:0]]; + end + if (READ_MODE == 1) begin + RDATA <= memory[RADDR[8:1]][RADDR[0]*8 +: 8]; + end + if (READ_MODE == 2) begin + RDATA <= memory[RADDR[9:2]][RADDR[1:0]*4 +: 4]; + end + if (READ_MODE == 3) begin + RDATA <= memory[RADDR[10:3]][RADDR[2:0]*2 +: 2]; + end + end + end +`endif endmodule +module SB_RAM40_4KNR ( + 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 WRITE_MODE = 0; + parameter READ_MODE = 0; + + parameter INIT_0 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_1 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_2 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_3 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_4 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_5 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_6 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_7 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_8 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_9 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + + SB_RAM40_4K #( + .WRITE_MODE(WRITE_MODE), + .READ_MODE (READ_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 ) + ) RAM ( + .RDATA(RDATA), + .RCLK (~RCLK), + .RCLKE(RCLKE), + .RE (RE ), + .RADDR(RADDR), + .WCLK (WCLK ), + .WCLKE(WCLKE), + .WE (WE ), + .WADDR(WADDR), + .MASK (MASK ), + .WDATA(WDATA) + ); +endmodule + +module SB_RAM40_4KNW ( + 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 WRITE_MODE = 0; + parameter READ_MODE = 0; + + parameter INIT_0 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_1 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_2 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_3 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_4 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_5 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_6 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_7 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_8 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_9 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + + SB_RAM40_4K #( + .WRITE_MODE(WRITE_MODE), + .READ_MODE (READ_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 ) + ) RAM ( + .RDATA(RDATA), + .RCLK (RCLK ), + .RCLKE(RCLKE), + .RE (RE ), + .RADDR(RADDR), + .WCLK (~WCLK), + .WCLKE(WCLKE), + .WE (WE ), + .WADDR(WADDR), + .MASK (MASK ), + .WDATA(WDATA) + ); +endmodule + +module SB_RAM40_4KNRNW ( + 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 WRITE_MODE = 0; + parameter READ_MODE = 0; + + parameter INIT_0 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_1 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_2 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_3 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_4 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_5 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_6 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_7 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_8 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_9 = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_A = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_B = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_C = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_D = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_E = 256'h0000000000000000000000000000000000000000000000000000000000000000; + parameter INIT_F = 256'h0000000000000000000000000000000000000000000000000000000000000000; + + SB_RAM40_4K #( + .WRITE_MODE(WRITE_MODE), + .READ_MODE (READ_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 ) + ) RAM ( + .RDATA(RDATA), + .RCLK (~RCLK), + .RCLKE(RCLKE), + .RE (RE ), + .RADDR(RADDR), + .WCLK (~WCLK), + .WCLKE(WCLKE), + .WE (WE ), + .WADDR(WADDR), + .MASK (MASK ), + .WDATA(WDATA) + ); +endmodule + +// Packed IceStorm Logic Cells + module ICESTORM_LC ( input I0, I1, I2, I3, CIN, CLK, CEN, SR, output O, COUT @@ -272,20 +552,16 @@ module ICESTORM_LC ( wire polarized_clk; assign polarized_clk = CLK ^ NEG_CLK; - wire filtered_cen, filtered_sr; - assign filtered_cen = CEN === 1'bz ? 1'b1 : CEN; - assign filtered_sr = SR === 1'bz ? 1'b0 : SR; - reg o_reg; always @(posedge polarized_clk) - if (filtered_cen) - o_reg <= filtered_sr ? SET_NORESET : lut_o; + if (CEN) + o_reg <= SR ? SET_NORESET : lut_o; reg o_reg_async; - always @(posedge polarized_clk, posedge filtered_sr) - if (filtered_sr) + always @(posedge polarized_clk, posedge SR) + if (SR) o_reg <= SET_NORESET; - else if (filtered_cen) + else if (CEN) o_reg <= lut_o; assign O = DFF_ENABLE ? ASYNC_SR ? o_reg_async : o_reg : lut_o;