From a3baf1f57c668f4e743084ef6e65995f6db6507f Mon Sep 17 00:00:00 2001 From: John McMaster Date: Tue, 19 Dec 2017 19:12:04 -0800 Subject: [PATCH] 018-clbram: clean up to solve remaining bits Signed-off-by: John McMaster --- fuzzers/018-clbram/generate.py | 133 ++++-- fuzzers/018-clbram/top.py | 721 +++++++++++++++------------------ 2 files changed, 424 insertions(+), 430 deletions(-) diff --git a/fuzzers/018-clbram/generate.py b/fuzzers/018-clbram/generate.py index 915008b1..c3c6d118 100644 --- a/fuzzers/018-clbram/generate.py +++ b/fuzzers/018-clbram/generate.py @@ -1,10 +1,5 @@ #!/usr/bin/env python3 -# FIXME: getting two bits -# 00_40 31_46 -# Can we find instance where they are not aliased? -WA7USED = 0 - import sys, re, os sys.path.append("../../../utils/") @@ -35,55 +30,103 @@ greedy_modules = [ print("Loading tags") ''' module,loc,bela,belb,belc,beld -my_ram_N,SLICE_X12Y100,SRL16E,SRLC32E,SRLC32E,SRLC32E -my_ram_N,SLICE_X12Y101,SRLC32E,SRL16E,SRL16E,SRLC32E -my_ram_N,SLICE_X12Y102,SRLC32E,SRL16E,SRLC32E,RAM32X1S -my_RAM256X1S,SLICE_X12Y103,,,, +my_ram_N,SLICE_X12Y100,SRLC32E,SRL16E,SRLC32E,LUT6 +my_ram_N,SLICE_X12Y101,SRLC32E,SRLC32E,SRLC32E,SRLC32E +my_RAM256X1S,SLICE_X12Y102,None,0,, ''' f = open('params.csv', 'r') f.readline() for l in f: l = l.strip() - module,loc,bela,belb,belc,beld = l.split(',') - bels = [bela,belb,belc,beld] - if module in greedy_modules: - ''' - my_RAM128X1D #(.LOC("SLICE_X12Y100")) - WA7USED - my_RAM128X1S #(.LOC("SLICE_X12Y102")) - WA7USED - my_RAM256X1S #(.LOC("SLICE_X12Y103")) - WA7USED, WA8USED - ''' - which = 'D' - WA7USED and segmk.addtag(loc, "WA7USED", 1) - segmk.addtag(loc, "WA8USED", module == 'my_RAM256X1S') - else: - ''' - LUTD - 01_23 01_59 30_47 31_47 - SRL16E 1 1 1 - SRLC32E 1 1 - RAM32X1S 1 1 1 - RAM64X1S 1 1 + module,loc,p0,p1,p2,p3 = l.split(',') - 01_23: WEMUX.CE (more info needed) - 01_59: half sized memory - 30_47: SRL mode - 31_47: RAM mode - ''' - for which, bel in zip('ABCD', bels): - segmk.addtag(loc, "%sLUT.SMALL" % which, bel in ('SRL16E', 'RAM32X1S')) - segmk.addtag(loc, "%sLUT.SRL" % which, bel in ('SRL16E', 'SRLC32E')) - # Only valid in D - if which == 'D': - segmk.addtag(loc, "%sLUT.RAM" % which, bel in ('RAM32X1S', 'RAM64X1S')) - WA7USED and segmk.addtag(loc, "WA7USED", 0) - segmk.addtag(loc, "WA8USED", 0) + segmk.addtag(loc, "WA7USED", module in ('my_RAM128X1D', 'my_RAM128X1S', 'my_RAM256X1S')) + segmk.addtag(loc, "WA8USED", module == 'my_RAM256X1S') + + # (a, b, c, d) + # Size set for RAM32X1S, RAM32X1D, and SRL16E + size = [0, 0, 0, 0] + # SRL set for SRL* primitives + srl = [0, 0, 0, 0] + # RAM set for RAM* primitives + ram = [0, 0, 0, 0] + + if module == 'my_ram_N': + # Each one of: SRL16E, SRLC32E, LUT6 + bels = [p0,p1,p2,p3] + + # Clock Enable (CE) clock gate only enabled if we have clocked elements + # A pure LUT6 does not, but everything else should segmk.addtag(loc, "WEMUX.CE", bels != ['LUT6', 'LUT6', 'LUT6', 'LUT6']) + beli = 0 + for which, bel in zip('ABCD', bels): + if bel == 'SRL16E': + size[beli] = 1 + if bel in ('SRL16E', 'SRLC32E'): + srl[beli] = 1 + beli += 1 + else: + n = p0 + if n: + n = int(n) + # Unused. Just to un-alias mux + #_ff = int(p1) + + # Can pack 4 into a CLB + # D is always occupied first (due to WA/A sharing on D) + # TODO: maybe investigate ROM primitive for completeness + pack4 = [ + # (a, b, c, d) + (0, 0, 0, 1), + (1, 0, 0, 1), + (1, 1, 0, 1), + (1, 1, 1, 1), + ] + # Uses CD first + pack2 = [ + (0, 0, 1, 1), + (1, 1, 1, 1), + ] + + # Always use all 4 sites + if module in ('my_RAM32M', 'my_RAM64M', 'my_RAM128X1D', 'my_RAM256X1S'): + ram = [1, 1, 1, 1] + # Only can occupy CD I guess + elif module == 'my_RAM32X1D': + ram = [0, 0, 1, 1] + # Uses 2 sites at a time + elif module in ('my_RAM64X1D_N', 'my_RAM128X1S_N'): + ram = pack2[n - 1] + # Uses 1 site at a time + elif module in ('my_RAM32X1S_N', 'my_RAM64X1S_N'): + ram = pack4[n - 1] + else: + assert(0) + + # All entries here requiare D + assert(ram[3]) + + if module == 'my_RAM32X1D': + # Occupies CD + size[2] = 1 + size[3] = 1 + elif module == 'my_RAM32M': + size = [1, 1, 1, 1] + elif module == 'my_RAM32X1S_N': + size = pack4[n - 1] + else: + assert(not module.startswith('my_RAM32')) + + # Now commit bits after marking 1's + for beli, bel in enumerate('ABCD'): + segmk.addtag(loc, "%sLUT.RAM" % bel, ram[beli]) + segmk.addtag(loc, "%sLUT.SRL" % bel, srl[beli]) + # FIXME + module == segmk.addtag(loc, "%sLUT.SMALL" % bel, size[beli]) + def bitfilter(frame_idx, bit_idx): - # Hack to remove aliased PIP bits + # Hack to remove aliased PIP bits on CE # We should either mix up routing more or exclude previous DB entries assert os.getenv("XRAY_DATABASE") == "artix7" return (frame_idx, bit_idx) not in [(0, 27), (1, 25), (1, 26), (1, 29)] diff --git a/fuzzers/018-clbram/top.py b/fuzzers/018-clbram/top.py index 5ec87ef8..84a6fd40 100644 --- a/fuzzers/018-clbram/top.py +++ b/fuzzers/018-clbram/top.py @@ -1,3 +1,20 @@ +''' +Need coverage for the following: +RAM32X1S_N +RAM32X1D +RAM32M +RAM64X1S_N +RAM64X1D_N +RAM64M +RAM128X1S_N +RAM128X1D +RAM256X1S +SRL16E_N +SRLC32E_N + +Note: LUT6 was added to try to simplify reduction, although it might not be needed +''' + import random random.seed(0) import os @@ -78,80 +95,73 @@ f = open('params.csv', 'w') f.write('module,loc,bela,belb,belc,beld\n') slices = gen_slicems() print('module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (DIN_N - 1, DOUT_N - 1)) -multis = 0 +randluts = 0 for clbi in range(CLBN): - bel = '' - - # Can fit 4 per CLB - # BELable - multi_bels_by = [ - 'SRL16E', - 'SRLC32E', - 'LUT6', - ] - # Not BELable - multi_bels_bn = [ - 'RAM32X1S', - 'RAM64X1S', - ] - - # Those requiring special resources - # Just make one per module - greedy_modules = [ - 'my_RAM128X1D', - 'my_RAM128X1S', - 'my_RAM256X1S', - ] - loc = next(slices) params = '' cparams = '' # Multi module - if random.randint(0, 3) > 0: + # Fill with random assortment of SRL16E and SRLC32E + if random.randint(0, 1): params = '' module = 'my_ram_N' - # Pick one un-LOCable and then fill in with LOCable - ''' - CRITICAL WARNING: [Constraints 18-5] Cannot loc instance '\''roi/clb_2/lutd'\'' - at site SLICE_X12Y102, Instance roi/clb_2/lutd can not be placed in D6LUT - of site SLICE_X12Y102 because the bel is occupied by roi/clb_2/RAM64X1S/SP(port:). - This could be caused by bel constraint conflict + # Can fit 4 per CLB + # BELable + bel_opts = [ + 'SRL16E', + 'SRLC32E', + 'LUT6', + ] - Hmm I guess they have to go in LUTD after all - Unclear to me why this is - ''' - #unbel_beli = random.randint(0, 3) - unbel_beli = 3 - if random.randint(0, 1): - unbel_beli = None bels = [] for beli in range(4): belc = chr(ord('A') + beli) - if beli == unbel_beli: - # Chose a BEL instance that will get implicitly placed - bel = random.choice(multi_bels_bn) - params += ', .N_%s(1)' % bel + if randluts: + bel = random.choice(bel_opts) else: - bel = random.choice(multi_bels_by) - if multis == 0: - # Force an all LUT6 SLICE - bel = 'LUT6' - params += ', .%c_%s(1)' % (belc, bel) + # Force one without memory elements to bring CE bit low + bel = 'LUT6' + params += ', .%c_%s(1)' % (belc, bel) bels.append(bel) # Record the BELs we chose in the module (A, B, C, D) cparams = ',' + (','.join(bels)) - multis += 1 + randluts += 1 # Greedy module # Don't place anything else in it # For solving muxes vs previous results else: - module = random.choice(greedy_modules) - ff = random.randint(0, 1) - params = ',.FF(%d)' % ff - cparams = ',,,,' + modules = [ + # (module, N max, FF opt) + ('my_RAM32X1S_N', 4, 0), + ('my_RAM32X1D', None, 0), + ('my_RAM32M', None, 0), + ('my_RAM64X1S_N', 4, 0), + ('my_RAM64X1D_N', 2, 0), + ('my_RAM64M', None, 0), + ('my_RAM128X1S_N', 2, 1), + ('my_RAM128X1D', None, 1), + ('my_RAM256X1S', None, 1), + ] + + module, nmax, ff_param = random.choice(modules) + + n = '' + if nmax: + n = random.randint(1, nmax) + params += ',.N(%d)' % n + cparams += ',%s' % n + + ff = '' + if ff_param: + ff = random.randint(0, 1) + params += ',.FF(%d)' % ff + cparams += ',%s' % ff + + # Pad to match above CSV size + cparams += ",," print(' %s' % module) print(' #(.LOC("%s")%s)' % (loc, params)) @@ -167,316 +177,9 @@ print('''endmodule print(''' -//*************************************************************** -//Supermodule - -//BEL: yes -module my_ram_N (input clk, input [7:0] din, output [7:0] dout); - parameter LOC = ""; - parameter D_SRL16E=0; - parameter D_SRLC32E=0; - parameter D_LUT6=0; - - parameter C_SRL16E=0; - parameter C_SRLC32E=0; - parameter C_LUT6=0; - - parameter B_SRL16E=0; - parameter B_SRLC32E=0; - parameter B_LUT6=0; - - parameter A_SRL16E=0; - parameter A_SRLC32E=0; - parameter A_LUT6=0; - - parameter N_RAM32X1S=0; - parameter N_RAM64X1S=0; - - parameter SRLINIT = 32'h00000000; - //parameter LUTINIT6 = 64'h0000_0000_0000_0000; - parameter LUTINIT6 = 64'hFFFF_FFFF_FFFF_FFFF; - - wire ce = din[4]; - - generate - if (D_SRL16E) begin - (* LOC=LOC, BEL="D6LUT", KEEP, DONT_TOUCH *) - SRL16E #( - ) lutd ( - .Q(dout[3]), - .A0(din[0]), - .A1(din[1]), - .A2(din[2]), - .A3(din[3]), - .CE(ce), - .CLK(clk), - .D(din[6])); - end - if (D_SRLC32E) begin - (* LOC=LOC, BEL="D6LUT", KEEP, DONT_TOUCH *) - SRLC32E #( - .INIT(SRLINIT), - .IS_CLK_INVERTED(1'b0) - ) lutd ( - .Q(dout[3]), - .Q31(), - .A(din[4:0]), - .CE(ce), - .CLK(clk), - .D(din[7])); - end - if (D_LUT6) begin - (* LOC=LOC, BEL="D6LUT", KEEP, DONT_TOUCH *) - LUT6_2 #( - .INIT(LUTINIT6) - ) lutd ( - .I0(din[0]), - .I1(din[1]), - .I2(din[2]), - .I3(din[3]), - .I4(din[4]), - .I5(din[5]), - .O5(), - .O6(dout[3])); - end - - if (C_SRL16E) begin - (* LOC=LOC, BEL="C6LUT", KEEP, DONT_TOUCH *) - SRL16E #( - ) lutc ( - .Q(dout[2]), - .A0(din[0]), - .A1(din[1]), - .A2(din[2]), - .A3(din[3]), - .CE(ce), - .CLK(clk), - .D(din[6])); - end - if (C_SRLC32E) begin - (* LOC=LOC, BEL="C6LUT", KEEP, DONT_TOUCH *) - SRLC32E #( - .INIT(SRLINIT), - .IS_CLK_INVERTED(1'b0) - ) lutc ( - .Q(dout[2]), - .Q31(), - .A(din[4:0]), - .CE(ce), - .CLK(clk), - .D(din[7])); - end - if (C_LUT6) begin - (* LOC=LOC, BEL="C6LUT", KEEP, DONT_TOUCH *) - LUT6_2 #( - .INIT(LUTINIT6) - ) lutc ( - .I0(din[0]), - .I1(din[1]), - .I2(din[2]), - .I3(din[3]), - .I4(din[4]), - .I5(din[5]), - .O5(), - .O6(dout[2])); - end - - if (B_SRL16E) begin - (* LOC=LOC, BEL="B6LUT", KEEP, DONT_TOUCH *) - SRL16E #( - ) lutb ( - .Q(dout[1]), - .A0(din[0]), - .A1(din[1]), - .A2(din[2]), - .A3(din[3]), - .CE(ce), - .CLK(clk), - .D(din[6])); - end - if (B_SRLC32E) begin - (* LOC=LOC, BEL="B6LUT", KEEP, DONT_TOUCH *) - SRLC32E #( - .INIT(SRLINIT), - .IS_CLK_INVERTED(1'b0) - ) lutb ( - .Q(dout[1]), - .Q31(), - .A(din[4:0]), - .CE(ce), - .CLK(clk), - .D(din[7])); - end - if (B_LUT6) begin - (* LOC=LOC, BEL="B6LUT", KEEP, DONT_TOUCH *) - LUT6_2 #( - .INIT(LUTINIT6) - ) lutb ( - .I0(din[0]), - .I1(din[1]), - .I2(din[2]), - .I3(din[3]), - .I4(din[4]), - .I5(din[5]), - .O5(), - .O6(dout[1])); - end - - if (A_SRL16E) begin - (* LOC=LOC, BEL="A6LUT", KEEP, DONT_TOUCH *) - SRL16E #( - ) luta ( - .Q(dout[0]), - .A0(din[0]), - .A1(din[1]), - .A2(din[2]), - .A3(din[3]), - .CE(ce), - .CLK(clk), - .D(din[6])); - end - if (A_SRLC32E) begin - (* LOC=LOC, BEL="A6LUT", KEEP, DONT_TOUCH *) - SRLC32E #( - .INIT(SRLINIT), - .IS_CLK_INVERTED(1'b0) - ) luta ( - .Q(dout[0]), - .Q31(), - .A(din[4:0]), - .CE(ce), - .CLK(clk), - .D(din[7])); - end - if (A_LUT6) begin - (* LOC=LOC, BEL="A6LUT", KEEP, DONT_TOUCH *) - LUT6_2 #( - .INIT(LUTINIT6) - ) luta ( - .I0(din[0]), - .I1(din[1]), - .I2(din[2]), - .I3(din[3]), - .I4(din[4]), - .I5(din[5]), - .O5(), - .O6(dout[0])); - end - - if (N_RAM32X1S) begin - (* LOC=LOC, KEEP, DONT_TOUCH *) - RAM32X1S #( - ) RAM32X1S ( - .O(dout[4]), - .A0(din[0]), - .A1(din[1]), - .A2(din[2]), - .A3(din[3]), - .A4(din[4]), - .D(din[5]), - .WCLK(clk), - .WE(ce)); - end - if (N_RAM64X1S) begin - (* LOC=LOC, KEEP, DONT_TOUCH *) - RAM64X1S #( - ) RAM64X1S ( - .O(dout[4]), - .A0(din[0]), - .A1(din[1]), - .A2(din[2]), - .A3(din[3]), - .A4(din[4]), - .A5(din[5]), - .D(din[6]), - .WCLK(clk), - .WE(ce)); - end - endgenerate -endmodule - - //*************************************************************** //Basic -//BEL: yes -module my_SRL16E (input clk, input [7:0] din, output [7:0] dout); - parameter LOC = ""; - parameter BEL="A6LUT"; - - (* LOC=LOC, BEL=BEL, KEEP, DONT_TOUCH *) - SRL16E #( - ) SRL16E ( - .Q(dout[0]), - .A0(din[0]), - .A1(din[1]), - .A2(din[2]), - .A3(din[3]), - .CE(din[4]), - .CLK(din[5]), - .D(din[6])); -endmodule - -//BEL: yes -module my_SRLC32E (input clk, input [7:0] din, output [7:0] dout); - parameter LOC = ""; - parameter BEL="A6LUT"; - - wire mc31c; - - (* LOC=LOC, BEL=BEL, KEEP, DONT_TOUCH *) - SRLC32E #( - .INIT(32'h00000000), - .IS_CLK_INVERTED(1'b0) - ) lut ( - .Q(dout[0]), - .Q31(mc31c), - .A(din[4:0]), - .CE(din[5]), - .CLK(din[6]), - .D(din[7])); -endmodule - -//BEL: can't -module my_RAM32X1S (input clk, input [7:0] din, output [7:0] dout); - parameter LOC = ""; - - (* LOC=LOC, KEEP, DONT_TOUCH *) - RAM32X1S #( - ) RAM32X1S ( - .O(dout[0]), - .A0(din[0]), - .A1(din[1]), - .A2(din[2]), - .A3(din[3]), - .A4(din[4]), - .D(din[5]), - .WCLK(din[6]), - .WE(din[7])); -endmodule - -//BEL: can't -module my_RAM64X1S (input clk, input [7:0] din, output [7:0] dout); - parameter LOC = ""; - - (* LOC=LOC, KEEP, DONT_TOUCH *) - RAM64X1S #( - ) RAM64X1S ( - .O(dout[0]), - .A0(din[0]), - .A1(din[1]), - .A2(din[2]), - .A3(din[3]), - .A4(din[4]), - .A5(din[5]), - .D(din[6]), - .WCLK(clk), - .WE(din[0])); -endmodule - -//*************************************************************** -//WA*USED - module maybe_ff (input clk, din, dout); parameter FF = 0; @@ -493,7 +196,187 @@ module maybe_ff (input clk, din, dout); endgenerate endmodule -//Dedicated LOC +module my_RAM32X1S_N (input clk, input [7:0] din, output [7:0] dout); + parameter LOC = ""; + //1-4 + parameter N=1; + + genvar i; + generate + for (i = 0; i < N; i = i + 1) begin : loop + (* LOC=LOC, KEEP, DONT_TOUCH *) + RAM32X1S #( + ) RAM32X1S ( + .O(dout[i]), + .A0(din[0]), + .A1(din[1]), + .A2(din[2]), + .A3(din[3]), + .A4(din[4]), + .D(din[5]), + .WCLK(clk), + .WE(ce)); + end + endgenerate +endmodule + +module my_RAM32X1D (input clk, input [7:0] din, output [7:0] dout); + parameter LOC = ""; + + (* LOC=LOC, KEEP, DONT_TOUCH *) + RAM32X1D #( + ) RAM32X1D ( + .DPO(dout[0]), + .SPO(dout[1]), + .A0(din[0]), + .A1(din[1]), + .A2(din[2]), + .A3(din[3]), + .A4(din[4]), + .D(din[5]), + .DPRA0(din[6]), + .DPRA1(din[7]), + .DPRA2(din[0]), + .DPRA3(din[1]), + .DPRA4(din[2]), + .WCLK(din[3]), + .WE(din[4])); +endmodule + +module my_RAM32M (input clk, input [7:0] din, output [7:0] dout); + parameter LOC = ""; + + (* LOC=LOC, KEEP, DONT_TOUCH *) + RAM32M #( + ) RAM32M ( + .DOA(dout[1:0]), + .DOB(dout[3:2]), + .DOC(dout[5:4]), + .DOD(dout[7:6]), + .ADDRA(din[4:0]), + .ADDRB(din[4:0]), + .ADDRC(din[4:0]), + .ADDRD(din[4:0]), + .DIA(din[5:4]), + .DIB(din[6:5]), + .DIC(din[7:6]), + .DID(din[1:0]), + .WCLK(din[1]), + .WE(din[2])); +endmodule + +module my_RAM64X1S_N (input clk, input [7:0] din, output [7:0] dout); + parameter LOC = ""; + //1-4 + parameter N=1; + + genvar i; + generate + for (i = 0; i < N; i = i + 1) begin : loop + (* LOC=LOC, KEEP, DONT_TOUCH *) + RAM64X1S #( + ) RAM64X1S ( + .O(dout[i]), + .A0(din[0]), + .A1(din[1]), + .A2(din[2]), + .A3(din[3]), + .A4(din[4]), + .A5(din[5]), + .D(din[6]), + .WCLK(clk), + .WE(ce)); + end + endgenerate +endmodule + +module my_RAM64X1D_N (input clk, input [7:0] din, output [7:0] dout); + parameter LOC = ""; + //1-2 + parameter N=1; + + genvar i; + generate + for (i = 0; i < N; i = i + 1) begin : loop + (* LOC=LOC, KEEP, DONT_TOUCH *) + RAM64X1D #( + .INIT(64'h0), + .IS_WCLK_INVERTED(1'b0) + ) ramb ( + .DPO(dout[i]), + .D(din[0]), + .WCLK(clk), + .WE(din[2]), + .A0(din[3]), + .A1(din[4]), + .A2(din[5]), + .A3(din[6]), + .A4(din[7]), + .A5(din[0]), + .DPRA0(din[1]), + .DPRA1(din[2]), + .DPRA2(din[3]), + .DPRA3(din[4]), + .DPRA4(din[5]), + .DPRA5(din[6])); + end + endgenerate +endmodule + +module my_RAM64M (input clk, input [7:0] din, output [7:0] dout); + parameter LOC = ""; + parameter BEL="A6LUT"; + + (* LOC=LOC, BEL=BEL, KEEP, DONT_TOUCH *) + RAM64M #( + ) RAM64M ( + .DOA(dout[0]), + .DOB(dout[1]), + .DOC(dout[2]), + .DOD(dout[3]), + .ADDRA(din[0]), + .ADDRB(din[1]), + .ADDRC(din[2]), + .ADDRD(din[3]), + .DIA(din[4]), + .DIB(din[5]), + .DIC(din[6]), + .DID(din[7]), + .WCLK(clk), + .WE(din[1])); +endmodule + +module my_RAM128X1S_N (input clk, input [7:0] din, output [7:0] dout); + parameter LOC = ""; + //1-2 + parameter N=1; + parameter FF = 0; + + genvar i; + generate + for (i = 0; i < N; i = i + 1) begin : loop + wire o; + + (* LOC=LOC, KEEP, DONT_TOUCH *) + RAM128X1S #( + ) RAM128X1S ( + .O(o), + .A0(din[0]), + .A1(din[1]), + .A2(din[2]), + .A3(din[3]), + .A4(din[4]), + .A5(din[5]), + .A6(din[6]), + .D(din[7]), + .WCLK(din[0]), + .WE(din[1])); + + maybe_ff #(.FF(FF)) ff (.clk(clk), .din(o), .dout(dout[i])); + end + endgenerate +endmodule + module my_RAM128X1D (input clk, input [7:0] din, output [7:0] dout); parameter LOC = ""; parameter FF = 0; @@ -515,31 +398,6 @@ module my_RAM128X1D (input clk, input [7:0] din, output [7:0] dout); maybe_ff #(.FF(FF)) ff1 (.clk(clk), .din(spo), .dout(dout[1])); endmodule -//Dedicated LOC -module my_RAM128X1S (input clk, input [7:0] din, output [7:0] dout); - parameter LOC = ""; - parameter FF = 0; - - wire o; - - (* LOC=LOC, KEEP, DONT_TOUCH *) - RAM128X1S #( - ) RAM128X1S ( - .O(o), - .A0(din[0]), - .A1(din[1]), - .A2(din[2]), - .A3(din[3]), - .A4(din[4]), - .A5(din[5]), - .A6(din[6]), - .D(din[7]), - .WCLK(din[0]), - .WE(din[1])); - - maybe_ff #(.FF(FF)) ff (.clk(clk), .din(o), .dout(dout[0])); -endmodule - //Dedicated LOC module my_RAM256X1S (input clk, input [7:0] din, output [7:0] dout); parameter LOC = ""; @@ -558,5 +416,98 @@ module my_RAM256X1S (input clk, input [7:0] din, output [7:0] dout); maybe_ff #(.FF(FF)) ff (.clk(clk), .din(o), .dout(dout[0])); endmodule + +//*************************************************************** + +module my_ram_N_inst (input clk, input [7:0] din, output dout); + parameter LOC=""; + parameter BEL=""; + parameter N_SRL16E=0; + parameter N_SRLC32E=0; + parameter N_LUT6=0; + + parameter SRLINIT = 32'h00000000; + parameter LUTINIT6 = 64'h0000_0000_0000_0000; + + wire ce = din[4]; + + generate + //******************** + if (N_SRL16E) begin + (* LOC=LOC, BEL=BEL, KEEP, DONT_TOUCH *) + SRL16E #( + ) lut ( + .Q(dout), + .A0(din[0]), + .A1(din[1]), + .A2(din[2]), + .A3(din[3]), + .CE(ce), + .CLK(clk), + .D(din[6])); + end + if (N_SRLC32E) begin + (* LOC=LOC, BEL=BEL, KEEP, DONT_TOUCH *) + SRLC32E #( + .INIT(SRLINIT), + .IS_CLK_INVERTED(1'b0) + ) lut ( + .Q(dout), + .Q31(), + .A(din[4:0]), + .CE(ce), + .CLK(clk), + .D(din[7])); + end + if (N_LUT6) begin + (* LOC=LOC, BEL=BEL, KEEP, DONT_TOUCH *) + LUT6_2 #( + .INIT(LUTINIT6) + ) lut ( + .I0(din[0]), + .I1(din[1]), + .I2(din[2]), + .I3(din[3]), + .I4(din[4]), + .I5(din[5]), + .O5(), + .O6(dout)); + end + endgenerate +endmodule + +/* +Supermodule for LOC'able prims +Mix and match as needed +Specify at most one function generator per LUT +*/ +module my_ram_N (input clk, input [7:0] din, output [7:0] dout); + parameter LOC = ""; + parameter D_SRL16E=0; + parameter D_SRLC32E=0; + parameter D_LUT6=0; + + parameter C_SRL16E=0; + parameter C_SRLC32E=0; + parameter C_LUT6=0; + + parameter B_SRL16E=0; + parameter B_SRLC32E=0; + parameter B_LUT6=0; + + parameter A_SRL16E=0; + parameter A_SRLC32E=0; + parameter A_LUT6=0; + + my_ram_N_inst #(.LOC(LOC), .BEL("D6LUT"), .N_SRL16E(D_SRL16E), .N_SRLC32E(D_SRLC32E), .N_LUT6(D_LUT6)) + lutd(.clk(clk), .din(din), .dout(dout[3])); + my_ram_N_inst #(.LOC(LOC), .BEL("C6LUT"), .N_SRL16E(C_SRL16E), .N_SRLC32E(C_SRLC32E), .N_LUT6(C_LUT6)) + lutc(.clk(clk), .din(din), .dout(dout[2])); + my_ram_N_inst #(.LOC(LOC), .BEL("B6LUT"), .N_SRL16E(B_SRL16E), .N_SRLC32E(B_SRLC32E), .N_LUT6(B_LUT6)) + lutb(.clk(clk), .din(din), .dout(dout[1])); + my_ram_N_inst #(.LOC(LOC), .BEL("A6LUT"), .N_SRL16E(A_SRL16E), .N_SRLC32E(A_SRLC32E), .N_LUT6(A_LUT6)) + luta(.clk(clk), .din(din), .dout(dout[0])); +endmodule + ''')