#!/usr/bin/python

filename = 'bram_array.v'
num_brams = 16
addr_width = 9
data_width = 128

warning_string = """
/*
   THIS FILE IS AUTO GENERATED BY
   THE 'gen_bram_array.py' SCRIPT
   IN THE 'scripts' DIRECTORY.  

   DO NOT EDIT BY HAND!
*/
"""

comment_string = """
/*
    This is the array of brams used to store the
    gray-coded bit-plane sub images.  One image
    is stored in each bram.

    READING:
    Since the same data is being read from each
    bram (i.e. the same line number is read from
    each bram, and processed in parrallel by the
    motion correlator.

    Therefore, we only need one common read address 
    bus for all the brams, with unique data out
    buses.

    WRITING:
    Since each line of each subimage is written
    individually, we can use a single shared
    write address bus, and a single shared write
    data bus.  Which bram is actually written is
    controlled by the '1 hot' encoded write 
    enable signal.
*/

"""


with open(filename, 'w') as f:
    print >>f, warning_string
    print >>f, ""
    print >>f, comment_string
    print >>f, ""
    print >>f, 'module bram_array('

    print >>f, "\tclk_write,"
    print >>f, "\tclk_read,"
    print >>f, ""
    print >>f, "\tbram_write_addr,"
    print >>f, "\tbram_write_data,"
    print >>f, "\tbram_write_enable,"
    print >>f, ""
    print >>f, "\tbram_read_addr,"
    for i in xrange(num_brams):
        if i != num_brams - 1:
            print >>f, "\tbram_read_data_{0:d},".format(i)
        else:
            #No last comma
            print >>f, "\tbram_read_data_{0:d}".format(i)
    print >>f, "\t);\n"

    print >>f, "\t// Clocks"
    print >>f, "\tinput  clk_write;"
    print >>f, "\tinput  clk_read;"
    print >>f, "\t"
    print >>f, "\t// Write I/Os"
    print >>f, "\tinput   [{0:3d}:0]  bram_write_addr;".format(addr_width-1)
    print >>f, "\tinput   [{0:3d}:0]  bram_write_data;".format(data_width-1)
    print >>f, "\tinput  [{0:3d}:0]  bram_write_enable;".format(num_brams-1)
    print >>f, "\t"
    print >>f, "\t// Read I/Os"
    print >>f, "\tinput   [{0:3d}:0]  bram_read_addr;".format(addr_width-1)
    for i in xrange(num_brams):
        print >>f, "\toutput   [{0:3d}:0]  bram_read_data_{1};".format(data_width-1, i)
    print >>f, ""

    #Bram instantiations
    for i in xrange(num_brams):
        print >>f, "\tbram bram_{0:d}(".format(i)
        print >>f, "\t\t.addra\t(bram_write_addr),"
        print >>f, "\t\t.addrb\t(bram_read_addr),"
        print >>f, "\t\t.clka \t(clk_write),"
        print >>f, "\t\t.clkb \t(clk_read),"
        print >>f, "\t\t.dina \t(bram_write_data),"
        print >>f, "\t\t.doutb\t(bram_read_data_{0:d}),".format(i)
        print >>f, "\t\t.wea  \t(bram_write_enable[{0}])".format(i)
        print >>f, "\t);"
        print >>f, ""



    print >>f, "endmodule"




