# bram.pl
# Copyright (C) 2002 Larry Doolittle <larry\@doolittle.boa.org>

# first arg, data width
$n=16;
if ($ARGV[0]>1 && $ARGV[0]<200) { $n=int($ARGV[0]+.5); }
$n1=$n-1;

# second arg, address bits
$o=10;
if ($ARGV[1]>=8 && $ARGV[1]<=12) { $o=int($ARGV[1]+.5); }
$o1=$o-1;
# capacity in words
$s=1<<$o;
# configuration width of each 4K block RAM
$bw=4096/$s;
$bw1=$bw-1;
$bram="RAMB4_S${bw}_S${bw}";    # component I use
$aggram="ramdp${s}x${n}";       # entity I define

# can't handle fractional block width
if (int($n/$bw)*$bw != $n) {
   die "Can't handle fractional block width";
}

$howmany = $n/$bw;

print "// Verilog $aggram definition
// No copyright is claimed on this machine-generated code.
// Automatically generated from perl bram.pl $n $o
// bram.pl is Copyright (C) 2002 Larry Doolittle <larry\@doolittle.boa.org>

// $s x $n dual port RAM, aggregated from
// $howmany instances of $s x $bw Virtex Block RAM

`timescale 1ns / 1ns

module $aggram(
	ADDRA, RSTA, ENA, WEA, CLKA, DIA, DOA,
	ADDRB, RSTB, ENB, WEB, CLKB, DIB, DOB);

input  [$o1:0] ADDRA;
input  RSTA, ENA, WEA, CLKA;
input  [$n1:0] DIA;
output [$n1:0] DOA;

input  [$o1:0] ADDRB;
input  RSTB, ENB, WEB, CLKB;
input  [$n1:0] DIB;
output [$n1:0] DOB;

wire   [$o1:0] ADDRA;
wire   RSTA, ENA, WEA, CLKA;
wire   [$n1:0] DIA;
wire   [$n1:0] DOA;

wire   [$o1:0] ADDRB;
wire   RSTB, ENB, WEB, CLKB;
wire   [$n1:0] DIB;
wire   [$n1:0] DOB;
";

for ($i=0; $i*$bw<$n; $i++) {
   $y= $i * $bw;
   $x= $y + $bw - 1;
   print "
$bram b$i(
	.ADDRA (ADDRA),
	.RSTA  (RSTA),
	.ENA   (ENA),
	.WEA   (WEA),
	.CLKA  (CLKA),
	.DIA   (DIA[$x:$y]),
	.DOA   (DOA[$x:$y]),

	.ADDRB (ADDRB),
	.RSTB  (RSTB),
	.ENB   (ENB),
	.WEB   (WEB),
	.CLKB  (CLKB),
	.DIB   (DIB[$x:$y]),
	.DOB   (DOB[$x:$y])
);
";}

print "
endmodule
";
