#!/usr/bin/env python3 # -*- coding: utf-8 -*- # # Copyright (C) 2017-2020 The Project X-Ray Authors. # # Use of this source code is governed by a ISC-style # license that can be found in the LICENSE file or at # https://opensource.org/licenses/ISC # # SPDX-License-Identifier: ISC import os import random random.seed(int(os.getenv("SEED"), 16)) from prjxray import util from prjxray import verilog from prjxray.verilog import vrandbit, vrandbits import json def gen_bram18(): ''' sample: "sites": { "RAMB18_X0Y50": "FIFO18E1", "RAMB18_X0Y51": "RAMB18E1", "RAMB36_X0Y25": "RAMBFIFO36E1" }, ''' for _tile_name, site_name, _site_type in sorted(util.get_roi().gen_sites( ['RAMB18E1', 'FIFO18E1'])): yield site_name def gen_bram36(): for _tile_name, site_name, _site_type in util.get_roi().gen_sites( ['RAMBFIFO36E1']): yield site_name def gen_brams(): ''' Correctly assign a site to either bram36 or 2x bram18 ''' # XXX: mix 18 and 36? for site in gen_bram18(): yield ('RAMB18E1', site) def place_bram18(site, loci): ports = { 'clk': 'clk', 'din': 'din[ %d +: 8]' % (8 * loci, ), 'dout': 'dout[ %d +: 8]' % (8 * loci, ), } write_modes = ["WRITE_FIRST", "READ_FIRST", "NO_CHANGE"] collisions = ["DELAYED_WRITE", "PERFORMANCE"] priorities = ["RSTREG", "REGCE"] # Datasheet says 72 is legal in some cases, but think its a copy paste error from BRAM36 # also 0 and 36 aren't real sizes # Bias choice to 18 as its needed to solve certain bits quickly widths = [1, 2, 4, 9, 18, 18, 36] mode = '"TDP"' read_width_a = random.choice(widths) write_width_b = random.choice(widths) if read_width_a >= 36 or write_width_b >= 36: read_width_b = 0 write_width_a = 0 mode = '"SDP"' doa_reg = vrandbit() dob_reg = doa_reg write_modes = ["WRITE_FIRST", "READ_FIRST"] rstreg_priority_a = verilog.quote(random.choice(priorities)) rstreg_priority_b = rstreg_priority_a else: read_width_b = random.choice(widths) write_width_a = random.choice(widths) doa_reg = vrandbit() dob_reg = vrandbit() rstreg_priority_a = verilog.quote(random.choice(priorities)) rstreg_priority_b = verilog.quote(random.choice(priorities)) params = { 'LOC': verilog.quote(site), 'IS_CLKARDCLK_INVERTED': vrandbit(), 'IS_CLKBWRCLK_INVERTED': vrandbit(), 'IS_ENARDEN_INVERTED': vrandbit(), 'IS_ENBWREN_INVERTED': vrandbit(), 'IS_RSTRAMARSTRAM_INVERTED': vrandbit(), 'IS_RSTRAMB_INVERTED': vrandbit(), 'IS_RSTREGARSTREG_INVERTED': vrandbit(), 'IS_RSTREGB_INVERTED': vrandbit(), 'RAM_MODE': mode, 'WRITE_MODE_A': verilog.quote(random.choice(write_modes)), 'WRITE_MODE_B': verilog.quote(random.choice(write_modes)), "DOA_REG": doa_reg, "DOB_REG": dob_reg, "SRVAL_A": vrandbits(18), "SRVAL_B": vrandbits(18), "INIT_A": vrandbits(18), "INIT_B": vrandbits(18), "READ_WIDTH_A": read_width_a, "READ_WIDTH_B": read_width_b, "WRITE_WIDTH_A": write_width_a, "WRITE_WIDTH_B": write_width_b, "RDADDR_COLLISION_HWCONFIG": verilog.quote(random.choice(collisions)), "RSTREG_PRIORITY_A": rstreg_priority_a, "RSTREG_PRIORITY_B": rstreg_priority_b, } return ('my_RAMB18E1', ports, params) def main(): brams = list(gen_brams()) DUTN = len(brams) DIN_N = DUTN * 8 DOUT_N = DUTN * 8 verilog.top_harness(DIN_N, DOUT_N) f = open('params.jl', 'w') f.write('module,loc,params\n') print( 'module roi(input clk, input [%d:0] din, output [%d:0] dout);' % (DIN_N - 1, DOUT_N - 1)) for loci, (site_type, site) in enumerate(brams): modname, ports, params = { 'RAMB18E1': place_bram18, #'RAMBFIFO36E1': place_bram36, }[site_type](site, loci) verilog.instance(modname, 'inst_%u' % loci, ports, params=params) j = {'module': modname, 'i': loci, 'params': params} f.write('%s\n' % (json.dumps(j))) print('') f.close() print( '''endmodule // --------------------------------------------------------------------- ''') # RAMB18E1 print( ''' module my_RAMB18E1 (input clk, input [7:0] din, output [7:0] dout); parameter LOC = ""; parameter IS_CLKARDCLK_INVERTED = 1'b0; parameter IS_CLKBWRCLK_INVERTED = 1'b0; parameter IS_ENARDEN_INVERTED = 1'b0; parameter IS_ENBWREN_INVERTED = 1'b0; parameter IS_RSTRAMARSTRAM_INVERTED = 1'b0; parameter IS_RSTRAMB_INVERTED = 1'b0; parameter IS_RSTREGARSTREG_INVERTED = 1'b0; parameter IS_RSTREGB_INVERTED = 1'b0; parameter RAM_MODE = "TDP"; parameter WRITE_MODE_A = "WRITE_FIRST"; parameter WRITE_MODE_B = "WRITE_FIRST"; parameter RDADDR_COLLISION_HWCONFIG = "DELAYED_WRITE"; parameter RSTREG_PRIORITY_A = "RSTREG"; parameter RSTREG_PRIORITY_B = "RSTREG"; parameter DOA_REG = 1'b0; parameter DOB_REG = 1'b0; parameter SRVAL_A = 18'b0; parameter SRVAL_B = 18'b0; parameter INIT_A = 18'b0; parameter INIT_B = 18'b0; parameter READ_WIDTH_A = 0; parameter READ_WIDTH_B = 0; parameter WRITE_WIDTH_A = 0; parameter WRITE_WIDTH_B = 0; ''') print('''\ (* LOC=LOC *) RAMB18E1 #(''') for i in range(8): print(" .INITP_%02X(256'b0)," % (i, )) print('') for i in range(0x40): print(" .INIT_%02X(256'b0)," % (i, )) print('') print( ''' .IS_CLKARDCLK_INVERTED(IS_CLKARDCLK_INVERTED), .IS_CLKBWRCLK_INVERTED(IS_CLKBWRCLK_INVERTED), .IS_ENARDEN_INVERTED(IS_ENARDEN_INVERTED), .IS_ENBWREN_INVERTED(IS_ENBWREN_INVERTED), .IS_RSTRAMARSTRAM_INVERTED(IS_RSTRAMARSTRAM_INVERTED), .IS_RSTRAMB_INVERTED(IS_RSTRAMB_INVERTED), .IS_RSTREGARSTREG_INVERTED(IS_RSTREGARSTREG_INVERTED), .IS_RSTREGB_INVERTED(IS_RSTREGB_INVERTED), .RAM_MODE(RAM_MODE), .WRITE_MODE_A(WRITE_MODE_A), .WRITE_MODE_B(WRITE_MODE_B), .DOA_REG(DOA_REG), .DOB_REG(DOB_REG), .SRVAL_A(SRVAL_A), .SRVAL_B(SRVAL_B), .INIT_A(INIT_A), .INIT_B(INIT_B), .READ_WIDTH_A(READ_WIDTH_A), .READ_WIDTH_B(READ_WIDTH_B), .WRITE_WIDTH_A(WRITE_WIDTH_A), .WRITE_WIDTH_B(WRITE_WIDTH_B), .RDADDR_COLLISION_HWCONFIG(RDADDR_COLLISION_HWCONFIG), .RSTREG_PRIORITY_A(RSTREG_PRIORITY_A), .RSTREG_PRIORITY_B(RSTREG_PRIORITY_B) ) ram ( .CLKARDCLK(din[0]), .CLKBWRCLK(din[1]), .ENARDEN(din[2]), .ENBWREN(din[3]), .REGCEAREGCE(din[4]), .REGCEB(din[5]), .RSTRAMARSTRAM(din[6]), .RSTRAMB(din[7]), .RSTREGARSTREG(din[0]), .RSTREGB(din[1]), .ADDRARDADDR(din[2]), .ADDRBWRADDR(din[3]), .DIADI(din[4]), .DIBDI(din[5]), .DIPADIP(din[6]), .DIPBDIP(din[7]), .WEA(1'b0), .WEBWE(din[1]), .DOADO(dout[0]), .DOBDO(dout[1]), .DOPADOP(dout[2]), .DOPBDOP(dout[3])); endmodule ''') if __name__ == "__main__": main()