OpenCores
URL https://opencores.org/ocsvn/ahb_system_generator/ahb_system_generator/trunk

Subversion Repositories ahb_system_generator

Compare Revisions

  • This comparison shows the changes necessary to convert path
    /
    from Rev 1 to Rev 2
    Reverse comparison

Rev 1 → Rev 2

/trunk/references/m###.ref
0,0 → 1,124
640 ns MEM 0 DATA 0
1600 ns MEM 0 DATA 0
1610 ns MEM 1 DATA 1
1640 ns MEM 2 DATA 2
1690 ns MEM 3 DATA 3
2560 ns MEM 0 DATA 0
2570 ns MEM 1 DATA 1
2600 ns MEM 2 DATA 2
2610 ns MEM 3 DATA 3
4020 ns MEM 0 DATA 0
4030 ns MEM 1 DATA 1
4060 ns MEM 2 DATA 2
4070 ns MEM 3 DATA 3
4100 ns MEM 4 DATA 4
4170 ns MEM 5 DATA 5
4180 ns MEM 6 DATA 6
4210 ns MEM 7 DATA 7
5590 ns MEM 0 DATA 0
5600 ns MEM 1 DATA 1
5630 ns MEM 2 DATA 2
5640 ns MEM 3 DATA 3
5670 ns MEM 4 DATA 4
5680 ns MEM 5 DATA 5
5710 ns MEM 6 DATA 6
5720 ns MEM 7 DATA 7
8040 ns MEM 0 DATA 0
8050 ns MEM 1 DATA 1
8080 ns MEM 2 DATA 2
8090 ns MEM 3 DATA 3
8120 ns MEM 4 DATA 4
8130 ns MEM 5 DATA 5
8160 ns MEM 6 DATA 6
8170 ns MEM 7 DATA 7
8200 ns MEM 8 DATA 8
8210 ns MEM 9 DATA 9
8240 ns MEM 10 DATA 10
8290 ns MEM 11 DATA 11
8300 ns MEM 12 DATA 12
8330 ns MEM 13 DATA 13
8340 ns MEM 14 DATA 14
8370 ns MEM 15 DATA 15
10680 ns MEM 0 DATA 0
10690 ns MEM 1 DATA 1
10720 ns MEM 2 DATA 2
10730 ns MEM 3 DATA 3
10760 ns MEM 4 DATA 4
10770 ns MEM 5 DATA 5
10800 ns MEM 6 DATA 6
10810 ns MEM 7 DATA 7
10840 ns MEM 8 DATA 8
10850 ns MEM 9 DATA 9
10880 ns MEM 10 DATA 10
10890 ns MEM 11 DATA 11
10920 ns MEM 12 DATA 12
10930 ns MEM 13 DATA 13
10960 ns MEM 14 DATA 14
10970 ns MEM 15 DATA 15
11500 ns MEM 0 DATA 0
12940 ns MEM 0 DATA 0
12950 ns MEM 1 DATA 1
12980 ns MEM 2 DATA 2
12990 ns MEM 3 DATA 3
13020 ns MEM 4 DATA 4
13030 ns MEM 5 DATA 5
13060 ns MEM 6 DATA 6
13070 ns MEM 7 DATA 7
13100 ns MEM 8 DATA 8
14120 ns MEM 0 DATA 0
14130 ns MEM 1 DATA 1
14160 ns MEM 2 DATA 2
14200 ns MEM 3 DATA 3
15090 ns MEM 0 DATA 0
15100 ns MEM 1 DATA 1
15130 ns MEM 2 DATA 2
15140 ns MEM 3 DATA 3
16680 ns MEM 0 DATA 0
16690 ns MEM 1 DATA 1
16720 ns MEM 2 DATA 2
16730 ns MEM 3 DATA 3
16760 ns MEM 4 DATA 4
16810 ns MEM 5 DATA 5
16820 ns MEM 6 DATA 6
16850 ns MEM 7 DATA 7
18180 ns MEM 0 DATA 0
18190 ns MEM 1 DATA 1
18220 ns MEM 2 DATA 2
18230 ns MEM 3 DATA 3
18260 ns MEM 4 DATA 4
18270 ns MEM 5 DATA 5
18300 ns MEM 6 DATA 6
18310 ns MEM 7 DATA 7
20680 ns MEM 0 DATA 0
20690 ns MEM 1 DATA 1
20720 ns MEM 2 DATA 2
20760 ns MEM 3 DATA 3
20770 ns MEM 4 DATA 4
20800 ns MEM 5 DATA 5
20810 ns MEM 6 DATA 6
20840 ns MEM 7 DATA 7
20850 ns MEM 8 DATA 8
20880 ns MEM 9 DATA 9
20890 ns MEM 10 DATA 10
20920 ns MEM 11 DATA 11
20930 ns MEM 12 DATA 12
20960 ns MEM 13 DATA 13
20970 ns MEM 14 DATA 14
21000 ns MEM 15 DATA 15
23130 ns MEM 0 DATA 0
23140 ns MEM 1 DATA 1
23170 ns MEM 2 DATA 2
23180 ns MEM 3 DATA 3
23210 ns MEM 4 DATA 4
23220 ns MEM 5 DATA 5
23250 ns MEM 6 DATA 6
23260 ns MEM 7 DATA 7
23290 ns MEM 8 DATA 8
23300 ns MEM 9 DATA 9
23330 ns MEM 10 DATA 10
23340 ns MEM 11 DATA 11
23370 ns MEM 12 DATA 12
23380 ns MEM 13 DATA 13
23410 ns MEM 14 DATA 14
23420 ns MEM 15 DATA 15
23930 ns MEM 0 DATA 0
/trunk/simulate/cds.lib
0,0 → 1,2
DEFINE work ../compile
SOFTINCLUDE $CADENCEDIR/ncsim/tools/inca/files/cds.lib
/trunk/simulate/hdl.var
0,0 → 1,5
softinclude $CDS_INST_DIR/inca/files/hdl.var
define LIB_MAP ( $LIB_MAP, + => work )
DEFINE NCELABOPTS -timescale "1ns / 100 ps"
DEFINE NCVHDLOPTS -errormax 100
define WORK work
/trunk/conf/ahb_5mst_2slv_1arb.conf
0,0 → 1,18
# ahb_master 0: module,name,fifo_length,fifo_he,fifo_hf,num_bits_adds,write_burst,read_burst,write_lat,read_lat,UUT_BaseAddr
ahb_master,ahb_mst0,8,1,7,4,1,0,2,2,0
# ahb_master 1: module,name,fifo_length,fifo_he,fifo_hf,num_bits_adds,write_burst,read_burst,write_lat,read_lat,UUT_BaseAddr
ahb_master,ahb_mst1,4,1,3,4,1,1,2,2,128
# ahb_master 2: module,name,fifo_length,fifo_he,fifo_hf,num_bits_adds,write_burst,read_burst,write_lat,read_lat,UUT_BaseAddr
ahb_master,ahb_mst2,4,1,2,4,0,1,2,2,256
# ahb_master 3: module,name,fifo_length,fifo_he,fifo_hf,num_bits_adds,write_burst,read_burst,write_lat,read_lat,UUT_BaseAddr
ahb_master,ahb_mst3,8,1,7,4,1,1,2,2,1024
# ahb_master 4: module,name,fifo_length,fifo_he,fifo_hf,num_bits_adds,write_burst,read_burst,write_lat,read_lat,UUT_BaseAddr
ahb_master,ahb_mst4,4,1,3,4,1,1,1,2,1280
# ahb_slave 0:
# module,name,NOT_USED,type,add_h,add_l,remap add_h,remap add_l,NOT_USED,fifo_le,fifo_he,fifo_hf,num_bits_adds,write_burst,read_burst,write_lat,read_lat
ahb_slave,ahb_slv0,(SLAVE_LIST),wait,1023,0,1023,0,0,8,1,7,8,1,0,2,2
# ahb_slave 1:
# module,name,NOT_USED,type,add_h,add_l,remap add_h,remap add_l,NOT_USED,fifo_le,fifo_he,fifo_hf,num_bits_adds,write_burst,read_burst,write_lat,read_lat
ahb_slave,ahb_slv1,(SLAVE_LIST),wait,2047,1024,2047,1024,0,8,1,7,8,1,1,3,1
# ahb_arbiter 0: module,name,default master,master_list,slave_list,arbitration type
ahb_arbiter,ahb_arb0,2,(4,1,0,2,3),(1,0),2
/trunk/conf/ahb_generate.conf --- trunk/conf/ahb_3mst_1slv.conf (nonexistent) +++ trunk/conf/ahb_3mst_1slv.conf (revision 2) @@ -0,0 +1,11 @@ +# ahb_master 0: module,name,fifo_length,fifo_he,fifo_hf,num_bits_adds,write_burst,read_burst,write_lat,read_lat,UUT_BaseAddr +ahb_master,ahb_mst0,4,1,3,4,1,1,1,1,0 +# ahb_master 1: module,name,fifo_length,fifo_he,fifo_hf,num_bits_adds,write_burst,read_burst,write_lat,read_lat,UUT_BaseAddr +ahb_master,ahb_mst1,8,1,7,4,1,1,3,4,128 +# ahb_master 2: module,name,fifo_length,fifo_he,fifo_hf,num_bits_adds,write_burst,read_burst,write_lat,read_lat,UUT_BaseAddr +ahb_master,ahb_mst2,4,1,3,4,1,1,2,1,256 +# ahb_slave 0: +# module,name,NOT_USED,type,add_h,add_l,remap add_h,remap add_l,NOT_USED,fifo_le,fifo_he,fifo_hf,num_bits_adds,write_burst,read_burst,write_lat,read_lat +ahb_slave,ahb_slv0,(SLAVE_LIST),wait,1023,0,1023,0,0,8,1,7,7,1,1,2,2 +# ahb_arbiter 0: module,name,default master,master_list,slave_list,arbitration type +ahb_arbiter,ahb_arb0,1,(0,2,1),(0),0
/trunk/conf/ahb_6mst_1slv.conf
0,0 → 1,17
# ahb_master 0: module,name,fifo_length,fifo_he,fifo_hf,num_bits_adds,write_burst,read_burst,write_lat,read_lat,UUT_BaseAddr
ahb_master,ahb_mst0,8,1,7,4,0,0,2,2,0
# ahb_master 1: module,name,fifo_length,fifo_he,fifo_hf,num_bits_adds,write_burst,read_burst,write_lat,read_lat,UUT_BaseAddr
ahb_master,ahb_mst1,8,1,7,4,0,0,2,2,128
# ahb_master 2: module,name,fifo_length,fifo_he,fifo_hf,num_bits_adds,write_burst,read_burst,write_lat,read_lat,UUT_BaseAddr
ahb_master,ahb_mst2,8,1,7,4,0,0,2,2,256
# ahb_master 3: module,name,fifo_length,fifo_he,fifo_hf,num_bits_adds,write_burst,read_burst,write_lat,read_lat,UUT_BaseAddr
ahb_master,ahb_mst3,8,1,7,4,0,0,2,2,384
# ahb_master 4: module,name,fifo_length,fifo_he,fifo_hf,num_bits_adds,write_burst,read_burst,write_lat,read_lat,UUT_BaseAddr
ahb_master,ahb_mst4,8,1,7,4,0,0,2,2,512
# ahb_master 5: module,name,fifo_length,fifo_he,fifo_hf,num_bits_adds,write_burst,read_burst,write_lat,read_lat,UUT_BaseAddr
ahb_master,ahb_mst5,8,1,7,4,0,0,2,2,640
# ahb_slave 0:
# module,name,NOT_USED,type,add_h,add_l,remap add_h,remap add_l,NOT_USED,fifo_le,fifo_he,fifo_hf,num_bits_adds,write_burst,read_burst,write_lat,read_lat
ahb_slave,ahb_slv0,(SLAVE_LIST),wait,1023,0,1023,0,0,8,1,7,8,0,0,2,2
# ahb_arbiter 0: module,name,default master,master_list,slave_list,arbitration type
ahb_arbiter,ahb_arb0,0,(0,1,2,3,4,5),(0),0
/trunk/conf/ahb_6mst_3slv.conf
0,0 → 1,23
# ahb_master 0: module,name,fifo_length,fifo_he,fifo_hf,num_bits_adds,write_burst,read_burst,write_lat,read_lat,UUT_BaseAddr
ahb_master,ahb_mst0,4,1,3,4,1,1,1,1,0
# ahb_master 1: module,name,fifo_length,fifo_he,fifo_hf,num_bits_adds,write_burst,read_burst,write_lat,read_lat,UUT_BaseAddr
ahb_master,ahb_mst1,8,1,7,4,0,1,2,2,128
# ahb_master 2: module,name,fifo_length,fifo_he,fifo_hf,num_bits_adds,write_burst,read_burst,write_lat,read_lat,UUT_BaseAddr
ahb_master,ahb_mst2,2,1,1,4,1,0,1,3,256
# ahb_master 3: module,name,fifo_length,fifo_he,fifo_hf,num_bits_adds,write_burst,read_burst,write_lat,read_lat,UUT_BaseAddr
ahb_master,ahb_mst3,8,1,7,4,1,1,2,2,384
# ahb_master 4: module,name,fifo_length,fifo_he,fifo_hf,num_bits_adds,write_burst,read_burst,write_lat,read_lat,UUT_BaseAddr
ahb_master,ahb_mst4,8,1,7,4,0,1,1,4,1024
# ahb_master 5: module,name,fifo_length,fifo_he,fifo_hf,num_bits_adds,write_burst,read_burst,write_lat,read_lat,UUT_BaseAddr
ahb_master,ahb_mst5,2,1,1,4,1,0,2,1,1152
# ahb_slave 0:
# module,name,NOT_USED,type,add_h,add_l,remap add_h,remap add_l,NOT_USED,fifo_le,fifo_he,fifo_hf,num_bits_adds,write_burst,read_burst,write_lat,read_lat
ahb_slave,ahb_slv0,(SLAVE_LIST),wait,1023,0,1023,0,0,8,1,7,8,0,0,2,2
# ahb_slave 1:
# module,name,NOT_USED,type,add_h,add_l,remap add_h,remap add_l,NOT_USED,fifo_le,fifo_he,fifo_hf,num_bits_adds,write_burst,read_burst,write_lat,read_lat
ahb_slave,ahb_slv1,(SLAVE_LIST),wait,1023,0,1023,0,0,8,1,7,8,0,0,2,2
# ahb_slave 2:
# module,name,NOT_USED,type,add_h,add_l,remap add_h,remap add_l,NOT_USED,fifo_le,fifo_he,fifo_hf,num_bits_adds,write_burst,read_burst,write_lat,read_lat
ahb_slave,ahb_slv2,(SLAVE_LIST),wait,1023,0,1023,0,0,8,1,7,8,0,0,2,2
# ahb_arbiter 0: module,name,default master,master_list,slave_list,arbitration type
ahb_arbiter,ahb_arb0,0,(5,4,3,2,1,0),(2,1,0),0
/trunk/scripts/vdiff.pl
0,0 → 1,50
#!/usr/bin/perl
 
open(FIL1,"<$ARGV[0]")|| die "## cannot open reference $ARGV[0]\nUSAGE: vdiff.pl ref_file out_file\n";
open(FIL2,"<$ARGV[1]")|| die "## cannot open log file $ARGV[1]\nUSAGE: vdiff.pl ref_file out_file\n";
$ok=1;
$lines=0;
 
 
while(<FIL1>){
$lines++;
if(/(\w+)\s+\w+\s+\w+\s+(\w+)\s+\w+\s+(\w+)/){
$timel=$1;
$addrl=$2;
$valuel=$3;
# print "$1=$timel $2=$addrl $3=$valuel\n";
$line=<FIL2>;
 
if($line=~/(\w+)\s+\w+\s+\w+\s+(\w+)\s+\w+\s+(\w+)/){
$timer=$1;
$addrr=$2;
$valuer=$3;
# print "$1=$timer $2=$addrr $3=$valuer\n";
if(!("$addrl" eq "$addrr")){
print "#### (line:$lines) < $_ (line:$lines)> $line";
$ok=0;
}
if((!($valuel=~/U+/)) && (!($valuel eq $valuer))){
print "#### ------------ $timer $addrr $valuel $valuer \n";
print "#### (line:$lines)< $_ (line:$lines)> $line";
$ok=0;
}
 
# if((!($valr=~/U+/)) && (!($valr eq $valrr))){
# print "++++++++++ $addr $vall $valr $1 $2 $3\n";
# print " (line:$lines)< $_ (line:$lines)> $line";
# $ok=0;
# }
 
}
else {
print "#### log missing from (line:$lines) !!!\n";
$ok=0;
exit($ok);
}
}
}
exit($ok);
 
#exit(-99);
/trunk/scripts/AHB_GENERATE.pl
0,0 → 1,2496
#!/usr/bin/perl
use Tk;
use Time::Local;
 
use strict;
use strict 'subs';
#use warnings;
 
 
#LOCAL VARIABLES
 
my $infile=$ENV{DSN}."/scripts/ahb_generate.conf";
 
my $conffile=$ENV{DSN}."/src/ahb_configure.vhd";
my $matfile=$ENV{DSN}."/src/ahb_matrix.vhd";
my $sysfile=$ENV{DSN}."/src/ahb_system.vhd";
my $tbfile=$ENV{DSN}."/src/ahb_tb.vhd";
 
 
my @master_list;
my @slave_list;
 
my @mst_list;
my @slv_list;
my @pslv_list;
 
my $inst_name;
my $entity;
 
my $num_arb;
my $num_arb_msts;
my $def_arb_mst;
my @arb_master_list;
my @arb_slave_list;
 
my $num_brg;
my $num_brg_slvs;
my $def_brg_slv;
my $brg_master;
my @brg_slave_list;
 
my $num_apb;
my $num_apb_slvs;
my $apb_max_addr;
my $apb_slave_id;
my @apb_slave_list;
 
 
my $alg_number;
my @alg_list = qw/"Fixed" "Round-Robin" "Pseudo-Random" "Locked-Fixed" "Locked-R-R" "Locked-P-R"/;
 
my @gen_signal;
my @gen_ahb_signal;
my @gen_conf;
my @gen_comp;
my @gen_tbcomp;
my @gen_uut;
my @ass_signal;
 
my $curr_line;
my $cnt;
my $item;
 
my $chk=0;
my @tmp_chk;
my @tmp_lst;
my $tmp;
 
 
my $mat;
my @matrix;
 
 
# GUI SHAPING
my (@pt)=qw/-side top -fill both -anchor n -pady 10/;
my (@pc)=qw/-side top -fill both -anchor center -pady 10/;
my (@pw)=qw/-side left -fill both -anchor w -padx 10/;
my (@pe)=qw/-side right -fill both -anchor e -padx 10/;
 
# GUI FSM
my $state='WinGlobal';
my $i=0;
my $j;
 
my $a;
my $b;
my $c;
my $d;
my $e;
my $f;
 
my $mw;
my $frame;
 
my $done='disabled';
 
my $masters=-1;
my $slaves=-1;
my $pslaves=-1;
my $arbs=-1;
my $ahbs=-1;
my $apbs=-1;
 
my @master;
my @slave;
my @pslave;
my @arb;
my @ahb;
my @apb;
my @uut;
 
my @tmp_mat;
 
sub ResetConf
 
{
$state='WinGlobal';
$masters=-1;
$slaves=-1;
$pslaves=-1;
$arbs=-1;
$ahbs=-1;
$apbs=-1;
$#master=-1;
$#slave=-1;
$#pslave=-1;
$#arb=-1;
$#ahb=-1;
$#apb=-1;
}
 
sub ReadConf
{
 
$state='WinGlobal';
seek(file1,0,0);
$masters=-1;
$slaves=-1;
$pslaves=-1;
$arbs=-1;
$ahbs=-1;
$apbs=-1;
 
 
while(defined($curr_line=<file1>)) {
chop $curr_line;
if($curr_line =~ /^#/) {
print "# Comment skipped ...\n";
} elsif($curr_line =~ /^(ahb_master),(\w+),(\d+),(\d+),(\d+),(\d+),(\d+),(\d+),(\d+),(\d+),(\d+)$/){
$masters++;
print "Reading AHB Master $masters...\n";
$master[$masters]{"module"}=$1;
$master[$masters]{"name"}=$2;
$master[$masters]{"id"}=$masters;
$master[$masters]{"fifo_ln"}=$3;
$master[$masters]{"fifo_he"}=$4;
$master[$masters]{"fifo_hf"}=$5;
$master[$masters]{"num_bits_addr"}=$6;
$master[$masters]{"write_burst"}=$7;
$master[$masters]{"read_burst"}=$8;
$master[$masters]{"write_lat"}=$9;
$master[$masters]{"read_lat"}=$10;
$uut[$masters]{"base_addr"}=$11;
} elsif($curr_line =~ /^(ahb_slave),(\w+),\((.*)\),(\w+),(\d+),(\d+),(\d+),(\d+),(\d+),(\d+),(\d+),(\d+),(\d+),(\d+),(\d+),(\d+),(\d+)$/){
$slaves++;
print "Reading AHB Slave $slaves...\n";
$slave[$slaves]{"module"}=$1;
$slave[$slaves]{"name"}=$2;
foreach $item (split(',',$3)) {
$slave[$slaves]{"list"} .= " $item";
}
$slave[$slaves]{"id"}=$slaves;
$slave[$slaves]{"type"}=$4;
$slave[$slaves]{"add_h"}=$5;
$slave[$slaves]{"add_l"}=$6;
$slave[$slaves]{"add_hh"}=$7;
$slave[$slaves]{"add_ll"}=$8;
$slave[$slaves]{"alg"}=$9;
$slave[$slaves]{"fifo_ln"}=$10;
$slave[$slaves]{"fifo_he"}=$11;
$slave[$slaves]{"fifo_hf"}=$12;
$slave[$slaves]{"num_bits_addr"}=$13;
$slave[$slaves]{"write_burst"}=$14;
$slave[$slaves]{"read_burst"}=$15;
$slave[$slaves]{"write_lat"}=$16;
$slave[$slaves]{"read_lat"}=$17;
} elsif($curr_line =~ /^(apb_slave),(\w+),(\d+),(\d+),(\d+),(\d+),(\d+)$/){
$pslaves++;
print "Reading APB Slave $pslaves...\n";
$pslave[$pslaves]{"module"}=$1;
$pslave[$pslaves]{"name"}=$2;
$pslave[$pslaves]{"id"}=$pslaves;
$pslave[$pslaves]{"add_h"}=$3;
$pslave[$pslaves]{"add_l"}=$4;
$pslave[$pslaves]{"add_hh"}=$5;
$pslave[$pslaves]{"add_ll"}=$6;
$pslave[$pslaves]{"num_bits_addr"}=$7;
} elsif($curr_line =~ /^(ahb_arbiter),(\w+),(\d+),\((.*)\),\((.*)\),(\d+)$/){
$arbs++;
print "Reading AHB Arbiter $arbs...\n";
$arb[$arbs]{"module"}=$1;
$arb[$arbs]{"name"}=$2;
$arb[$arbs]{"id"}=$arbs;
$arb[$arbs]{"def"}=$3;
foreach $item (split(',',$4)) {
$arb[$arbs]{"m_list"} .= " $item";
}
foreach $item (split(',',$5)) {
$arb[$arbs]{"s_list"} .= " $item";
}
$arb[$arbs]{"alg"}=$6;
} elsif($curr_line =~ /^(ahb_bridge),(\w+),(\d+),(\d+),\((.*)\),(\d+)$/){
$ahbs++;
print "Reading AHB Bridge $ahbs...\n";
$ahb[$ahbs]{"module"}=$1;
$ahb[$ahbs]{"name"}=$2;
$ahb[$ahbs]{"id"}=$ahbs;
$ahb[$ahbs]{"alg"}=$3;
$ahb[$ahbs]{"def"}=$4;
foreach $item (split(',',$5)) {
$ahb[$ahbs]{"list"} .= " $item";
}
$ahb[$ahbs]{"mst"}=$6;
} elsif($curr_line =~ /^(apb_bridge),(\w+),(\d+),(\d+),\((.*)\)$/){
$apbs++;
print "Reading APB Bridge $apbs...\n";
$apb[$apbs]{"module"}=$1;
$apb[$apbs]{"name"}=$2;
$apb[$apbs]{"id"}=$apbs;
$apb[$apbs]{"num_bits_addr"}=$3;
$apb[$apbs]{"slv"}=$4;
foreach $item (split(',',$5)) {
$apb[$apbs]{"list"} .= " $item";
}
 
} else {
print "#### wrong format!!!\n";
}
# close(file1);
}
 
 
sub SaveConf
{
 
$state='WinGlobal';
open(file1,">$infile")|| die "Cannot write ahb configuration output file $infile\n";
 
 
$i=0;
while($i<=$masters) {
print file1 "# ahb_master $i: module,name,fifo_length,fifo_he,fifo_hf,num_bits_adds,write_burst,read_burst,write_lat,read_lat,UUT_BaseAddr\n";
print file1 "$master[$i]{\"module\"},";
print file1 "$master[$i]{\"name\"},";
print file1 "$master[$i]{\"fifo_ln\"},";
print file1 "$master[$i]{\"fifo_he\"},";
print file1 "$master[$i]{\"fifo_hf\"},";
print file1 "$master[$i]{\"num_bits_addr\"},";
print file1 "$master[$i]{\"write_burst\"},";
print file1 "$master[$i]{\"read_burst\"},";
print file1 "$master[$i]{\"write_lat\"},";
print file1 "$master[$i]{\"read_lat\"},";
print file1 "$uut[$i]{\"base_addr\"}\n";
$i++;
}
$i=0;
while($i<=$slaves) {
print file1 "# ahb_slave $i:
# module,name,NOT_USED,type,add_h,add_l,remap add_h,remap add_l,NOT_USED,fifo_le,fifo_he,fifo_hf,num_bits_adds,write_burst,read_burst,write_lat,read_lat\n";
print file1 "$slave[$i]{\"module\"},";
print file1 "$slave[$i]{\"name\"},";
print file1 "(";
$_=$slave[$i]{"list"};
s/^[ ]+//g;
s/[ ]+$//g;
s/[ ]+/,/g;
print file1 "$_),";
# print file1 "$slave[$i]{\"id\"},";
print file1 "$slave[$i]{\"type\"},";
print file1 "$slave[$i]{\"add_h\"},";
print file1 "$slave[$i]{\"add_l\"},";
print file1 "$slave[$i]{\"add_hh\"},";
print file1 "$slave[$i]{\"add_ll\"},";
print file1 "$slave[$i]{\"alg\"},";
print file1 "$slave[$i]{\"fifo_ln\"},";
print file1 "$slave[$i]{\"fifo_he\"},";
print file1 "$slave[$i]{\"fifo_hf\"},";
print file1 "$slave[$i]{\"num_bits_addr\"},";
print file1 "$slave[$i]{\"write_burst\"},";
print file1 "$slave[$i]{\"read_burst\"},";
print file1 "$slave[$i]{\"write_lat\"},";
print file1 "$slave[$i]{\"read_lat\"}\n";
$i++;
}
 
$i=0;
while($i<=$pslaves) {
print file1 "# apb_slave $i: module,name,add_h,add_l,remap add_h,remap add_l,num_bits_adds\n";
print file1 "$pslave[$i]{\"module\"},";
print file1 "$pslave[$i]{\"name\"},";
# print file1 "$pslave[$i]{\"id\"},";
print file1 "$pslave[$i]{\"add_h\"},";
print file1 "$pslave[$i]{\"add_l\"},";
print file1 "$pslave[$i]{\"add_hh\"},";
print file1 "$pslave[$i]{\"add_ll\"},";
print file1 "$pslave[$i]{\"num_bits_addr\"}\n";
$i++;
}
 
$i=0;
while($i<=$arbs) {
print file1 "# ahb_arbiter $i: module,name,default master,master_list,slave_list,arbitration type\n";
print file1 "$arb[$i]{\"module\"},";
print file1 "$arb[$i]{\"name\"},";
# print file1 "$arb[$i]{\"id\"},";
print file1 "$arb[$i]{\"def\"},";
print file1 "(";
$_=$arb[$i]{"m_list"};
s/^[ ]+//g;
s/[ ]+$//g;
s/[ ]+/,/g;
print file1 "$_),";
print file1 "(";
$_=$arb[$i]{"s_list"};
s/^[ ]+//g;
s/[ ]+$//g;
s/[ ]+/,/g;
print file1 "$_),";
print file1 "$arb[$i]{\"alg\"}\n";
$i++;
}
$i=0;
while($i<=$ahbs) {
print file1 "# ahb_bridge $i: module,name,arbitration type,default slave,slave_list,master\n";
print file1 "$ahb[$i]{\"module\"},";
print file1 "$ahb[$i]{\"name\"},";
# print file1 "$ahb[$i]{\"id\"},";
print file1 "$ahb[$i]{\"alg\"},";
print file1 "$ahb[$i]{\"def\"},";
print file1 "(";
$_=$ahb[$i]{"list"};
s/^[ ]+//g;
s/[ ]+$//g;
s/[ ]+/,/g;
print file1 "$_),";
print file1 "$ahb[$ahbs]{\"mst\"}\n";
$i++;
}
$i=0;
while($i<=$apbs) {
print file1 "# apb_bridge $i: module,name,num_bits_adds,slave,periph list\n";
print file1 "$apb[$i]{\"module\"},";
print file1 "$apb[$i]{\"name\"},";
# print file1 "$apb[$i]{\"id\"},";
print file1 "$apb[$i]{\"num_bits_addr\"},";
print file1 "$apb[$i]{\"slv\"},";
print file1 "(";
$_=$apb[$i]{"list"};
s/^[ ]+//g;
s/[ ]+$//g;
s/[ ]+/,/g;
print file1 "$_)\n";
$i++;
}
 
}
 
 
sub gen_master
{
 
my $tmp_mst=shift(@_);
@gen_tbcomp = (@gen_tbcomp, "
$tmp_mst->{\"name\"}: ahb_master
generic map(
fifohempty_level => $tmp_mst->{\"fifo_he\"},
fifohfull_level => $tmp_mst->{\"fifo_hf\"},
fifo_length => $tmp_mst->{\"fifo_ln\"})
port map (
hresetn => hresetn,
hclk => hclk,
mst_in => ahb_mst_$tmp_mst->{\"id\"}_in,
mst_out => ahb_mst_$tmp_mst->{\"id\"}_out,
dma_start => dma_start($tmp_mst->{\"id\"}),
m_wrap_out => m_wrap_out($tmp_mst->{\"id\"}),
m_wrap_in => m_wrap_in($tmp_mst->{\"id\"}),
eot_int => eot_int($tmp_mst->{\"id\"}),
slv_running => zero,
mst_running => open);
 
$tmp_mst->{\"name\"}_wrap: mst_wrap
generic map(
--synopsys translate_off
dump_file => \"m$tmp_mst->{\"id\"}.log\",
dump_type => dump_all,
--synopsys translate_on
ahb_max_addr => $tmp_mst->{\"num_bits_addr\"},
m_const_lat_write => $tmp_mst->{\"write_lat\"},
m_const_lat_read => $tmp_mst->{\"read_lat\"},
m_write_burst => $tmp_mst->{\"write_burst\"},
m_read_burst => $tmp_mst->{\"read_burst\"})
port map(
hresetn => hresetn,
clk => hclk,
conf => conf($tmp_mst->{\"id\"}),
dma_start => dma_start($tmp_mst->{\"id\"}),
m_wrap_in => m_wrap_out($tmp_mst->{\"id\"}),
m_wrap_out => m_wrap_in($tmp_mst->{\"id\"}));
");
 
 
@gen_uut = (@gen_uut, "
uut_stimulator_$tmp_mst->{\"id\"}: uut_stimulator
generic map(
enable => 1,
stim_type => stim_$tmp_mst->{\"id\"},
eot_enable => 1)
port map(
hclk => hclk,
hresetn => hresetn,
amba_error => zero,
eot_int => eot_int($tmp_mst->{\"id\"}),
conf => conf($tmp_mst->{\"id\"}),
sim_end => sim_end($tmp_mst->{\"id\"}));
 
");
 
 
}
 
sub gen_slave {
 
my $tmp_slv=shift(@_);
 
#if ($tmp_slv->{"type"}=='wait') {
#@gen_tbcomp = (@gen_tbcomp, "
#$tmp_slv->{\"name\"}: ahb_single_slave");
#} else {
@gen_tbcomp = (@gen_tbcomp, "
$tmp_slv->{\"name\"}: ahb_slave_$tmp_slv->{\"type\"}");
#};
 
@gen_tbcomp = (@gen_tbcomp, "
generic map(
num_slv => $tmp_slv->{\"id\"},
fifohempty_level => $tmp_slv->{\"fifo_he\"},
fifohfull_level => $tmp_slv->{\"fifo_hf\"},
fifo_length => $tmp_slv->{\"fifo_ln\"})
port map (
hresetn => hresetn,
hclk => hclk,
remap => remap,
slv_in => ahb_slv_$tmp_slv->{\"id\"}_in,
slv_out => ahb_slv_$tmp_slv->{\"id\"}_out,
s_wrap_out => s_wrap_out($tmp_slv->{\"id\"}),
s_wrap_in => s_wrap_in($tmp_slv->{\"id\"}),
mst_running => zero,
prior_in => zero,
slv_running => open,
slv_err => open);
 
 
$tmp_slv->{\"name\"}_wrap: slv_mem
generic map(
--synopsys translate_off
dump_file => \"s$tmp_slv->{\"id\"}.log\",
dump_type => dump_all,
--synopsys translate_on
ahb_max_addr => $tmp_slv->{\"num_bits_addr\"},
s_const_lat_write => $tmp_slv->{\"write_lat\"},
s_const_lat_read => $tmp_slv->{\"read_lat\"},
s_write_burst => $tmp_slv->{\"write_burst\"},
s_read_burst => $tmp_slv->{\"read_burst\"})
port map(
hresetn => hresetn,
clk => hclk,
conf => no_conf_s,
dma_start => open,
s_wrap_in => s_wrap_out($tmp_slv->{\"id\"}),
s_wrap_out => s_wrap_in($tmp_slv->{\"id\"}));
 
");
 
 
}
 
 
 
sub gen_pslave
{
my $tmp_pslv=shift(@_);
@gen_tbcomp = (@gen_tbcomp, "
$tmp_pslv->{\"name\"}: apb_slave
generic map(
--synopsys translate_off
dump_file => \"p$tmp_pslv->{\"id\"}.log\",
--synopsys translate_on
apb_slv_addr => $tmp_pslv->{\"num_bits_addr\"})
port map (
hresetn => hresetn,
hclk => hclk,
apb_in => apb_slv_$tmp_pslv->{\"id\"}_in,
apb_out => apb_slv_$tmp_pslv->{\"id\"}_out);
");
 
 
}
 
 
 
sub gen_arbiter
{
my $tmp_arb=shift(@_);
 
@arb_master_list = split(' ',$tmp_arb->{"m_list"});
$def_arb_mst = $arb_master_list[0];
$num_arb_msts = $#arb_master_list+1;
@arb_slave_list = split(' ',$tmp_arb->{"s_list"});
print "\nModule/ID: $tmp_arb->{\"module\"}, $tmp_arb->{\"id\"}";
print "\nName: $tmp_arb->{\"name\"}";
print "\nMasters'list:\n(@arb_master_list)";
print "\nDefault master: $tmp_arb->{\"def\"}";
print "\nType of arbitration: ".$alg_list[$tmp_arb->{"alg"}];
print "\nSlaves'list:\n(@arb_slave_list)\n\n";
$cnt=0;
foreach $item (@arb_master_list) {
++$mst_list[$item];
if ($item==$tmp_arb->{"def"}) {$def_arb_mst=$cnt;}
$cnt++;
}
foreach $item (@arb_slave_list) {++$slv_list[$item];}
 
@gen_comp = (@gen_comp,"
$tmp_arb->{\"name\"}: $tmp_arb->{\"module\"}
generic map(
num_arb => $tmp_arb->{\"id\"},
num_arb_msts => $num_arb_msts,
num_slvs => ".($#arb_slave_list+1).",
def_arb_mst => $def_arb_mst,
alg_number => $tmp_arb->{\"alg\"})
port map(
hresetn => hresetn,
hclk => hclk,
remap => remap,
mst_in_v => mst_in_arb_$tmp_arb->{\"id\"}_v(".($num_arb_msts-1)." downto 0),
mst_out_v => mst_out_arb_$tmp_arb->{\"id\"}_v(".($num_arb_msts-1)." downto 0),
slv_in_v => slv_in_arb_$tmp_arb->{\"id\"}_v($#arb_slave_list downto 0),
slv_out_v => slv_out_arb_$tmp_arb->{\"id\"}_v($#arb_slave_list downto 0));
 
");
@gen_signal = (@gen_signal,
"signal mst_out_arb_$tmp_arb->{\"id\"}_v: mst_in_v_t(".($num_arb_msts-1)." downto 0);
signal mst_in_arb_$tmp_arb->{\"id\"}_v: mst_out_v_t(".($num_arb_msts-1)." downto 0);
signal slv_out_arb_$tmp_arb->{\"id\"}_v: slv_in_v_t($#arb_slave_list downto 0);
signal slv_in_arb_$tmp_arb->{\"id\"}_v: slv_out_v_t($#arb_slave_list downto 0);
");
$cnt = $#arb_master_list;
foreach $item (@arb_master_list){
@ass_signal = (@ass_signal, "ahb_mst_".$item."_in <= mst_out_arb_$tmp_arb->{\"id\"}_v($cnt);\n");
@ass_signal = (@ass_signal, "mst_in_arb_$tmp_arb->{\"id\"}_v($cnt) <= ahb_mst_".$item."_out;\n");
$cnt--;
}
$cnt = $#arb_slave_list;
foreach $item (@arb_slave_list){
@ass_signal = (@ass_signal, "ahb_slv_".$item."_in <= slv_out_arb_$tmp_arb->{\"id\"}_v($cnt);\n");
@ass_signal = (@ass_signal, "slv_in_arb_$tmp_arb->{\"id\"}_v($cnt) <= ahb_slv_".$item."_out;\n");
$cnt--;
}
}
 
 
sub gen_bridge
{
 
my $tmp_brg=shift(@_);
 
@brg_slave_list = split(' ',$tmp_brg->{"list"});
$def_brg_slv=$brg_slave_list[0];
$num_brg_slvs = $#brg_slave_list+1;
 
 
print "Module/ID: $tmp_brg->{\"module\"}, $tmp_brg->{\"id\"}";
print "\nName: $tmp_brg->{\"name\"}";
print "\nSlaves'list:\n(@brg_slave_list)";
print "\nDefault slave: $tmp_brg->{\"def\"}";
print "\nType of arbitration: ".$alg_list[$tmp_brg->{"alg"}];
print "\nMaster: $tmp_brg->{\"mst\"}\n\n";
--$mst_list[$tmp_brg->{"mst"}];
@gen_signal = (@gen_signal, "signal ahb_mst_$tmp_brg->{\"mst\"}_in: mst_in_t;\n");
@gen_signal = (@gen_signal, "signal ahb_mst_$tmp_brg->{\"mst\"}_out: mst_out_t;\n");
$cnt = 0;
foreach $item (@brg_slave_list) {
--$slv_list[$item];
@gen_signal = (@gen_signal, "signal ahb_slv_".$item."_in: slv_in_t;\n");
@gen_signal = (@gen_signal, "signal ahb_slv_".$item."_out: slv_out_t;\n");
if ($item==$tmp_brg->{"def"}) {$def_brg_slv=$cnt;}
$cnt++;
}
 
@gen_comp = (@gen_comp, "\n$tmp_brg->{\"name\"}: $tmp_brg->{\"module\"}\n");
@gen_comp = (@gen_comp, "generic map(\n");
@gen_comp = (@gen_comp, "num_brg => $tmp_brg->{\"id\"},\n");
@gen_comp = (@gen_comp, "num_brg_slvs => $num_brg_slvs,\n");
@gen_comp = (@gen_comp, "def_brg_slv => $def_brg_slv,\n");
@gen_comp = (@gen_comp, "alg_number => $tmp_brg->{\"alg\"})\n");
@gen_comp = (@gen_comp, "port map(\n");
@gen_comp = (@gen_comp, " hresetn => hresetn,\n");
@gen_comp = (@gen_comp, " hclk => hclk,\n");
@gen_comp = (@gen_comp, " remap => remap,\n");
@gen_comp = (@gen_comp, " slv_in_v => slv_in_brg_$tmp_brg->{\"id\"}_v($#brg_slave_list downto 0),\n");
@gen_comp = (@gen_comp, " slv_out_v => slv_out_brg_$tmp_brg->{\"id\"}_v($#brg_slave_list downto 0),\n");
@gen_comp = (@gen_comp, " mst_in => mst_in_brg_$tmp_brg->{\"id\"},\n");
@gen_comp = (@gen_comp, " mst_out => mst_out_brg_$tmp_brg->{\"id\"},\n");
@gen_comp = (@gen_comp, " slv_err => open,\n");
@gen_comp = (@gen_comp, " mst_err => open);\n");
@gen_comp = (@gen_comp, "\n\n");
 
@gen_signal = (@gen_signal, "signal mst_out_brg_$tmp_brg->{\"id\"}: mst_out_t;\n");
@gen_signal = (@gen_signal, "signal mst_in_brg_$tmp_brg->{\"id\"}: mst_in_t;\n");
@gen_signal = (@gen_signal, "signal slv_out_brg_$tmp_brg->{\"id\"}_v: slv_out_v_t($#brg_slave_list downto 0);\n");
@gen_signal = (@gen_signal, "signal slv_in_brg_$tmp_brg->{\"id\"}_v: slv_in_v_t($#brg_slave_list downto 0);\n");
 
@ass_signal = (@ass_signal, "ahb_mst_$tmp_brg->{\"mst\"}_out <= mst_out_brg_$tmp_brg->{\"id\"};\n");
@ass_signal = (@ass_signal, "mst_in_brg_$tmp_brg->{\"id\"} <= ahb_mst_$tmp_brg->{\"mst\"}_in;\n");
 
$cnt = $#brg_slave_list;
foreach $item (@brg_slave_list){
@ass_signal = (@ass_signal, "ahb_slv_".$item."_out <= slv_out_brg_$tmp_brg->{\"id\"}_v($cnt);\n");
@ass_signal = (@ass_signal, "slv_in_brg_$tmp_brg->{\"id\"}_v($cnt) <= ahb_slv_".$item."_in;\n");
$cnt--;
}
}
 
 
sub gen_apb
{
my $tmp_apb=shift(@_);
 
@apb_slave_list = split(' ',$tmp_apb->{"list"});
 
print "Module/ID: $tmp_apb->{\"module\"}, $tmp_apb->{\"id\"}";
print "\nName: $tmp_apb->{\"name\"}";
print "\nNumber of address bits to decode: $tmp_apb->{\"num_bits_addr\"}";
print "\nAHB Slave: $tmp_apb->{\"slv\"}";
print "\nSlaves'list:\n(@apb_slave_list)\n\n";
 
 
--$slv_list[$tmp_apb->{"slv"}];
@gen_signal = (@gen_signal, "signal ahb_slv_$tmp_apb->{\"slv\"}_in: slv_in_t;\n");
@gen_signal = (@gen_signal, "signal ahb_slv_$tmp_apb->{\"slv\"}_out: slv_out_t;\n");
 
 
@gen_comp = (@gen_comp, "$tmp_apb->{\"name\"}: $tmp_apb->{\"module\"}\n");
@gen_comp = (@gen_comp, "generic map(\n");
@gen_comp = (@gen_comp, "num_brg => $tmp_apb->{\"id\"},\n");
@gen_comp = (@gen_comp, "num_brg_slvs => ".($#apb_slave_list+1).",\n");
@gen_comp = (@gen_comp, "apb_max_addr => $tmp_apb->{\"num_bits_addr\"})\n");
@gen_comp = (@gen_comp, "port map(\n");
@gen_comp = (@gen_comp, " hresetn => hresetn,\n");
@gen_comp = (@gen_comp, " hclk => hclk,\n");
@gen_comp = (@gen_comp, " remap => remap,\n");
@gen_comp = (@gen_comp, " slv_in => slv_in_apb_$tmp_apb->{\"id\"},\n");
@gen_comp = (@gen_comp, " slv_out => slv_out_apb_$tmp_apb->{\"id\"},\n");
@gen_comp = (@gen_comp, " apb_mst_in => apb_slv_$tmp_apb->{\"id\"}_out_v(".($#apb_slave_list)." downto 0),\n");
@gen_comp = (@gen_comp, " apb_mst_out => apb_slv_$tmp_apb->{\"id\"}_in_v(".($#apb_slave_list)." downto 0));\n");
@gen_comp = (@gen_comp, "\n\n");
 
@gen_signal = (@gen_signal, "signal slv_in_apb_$tmp_apb->{\"id\"}: slv_in_t;\n");
@gen_signal = (@gen_signal, "signal slv_out_apb_$tmp_apb->{\"id\"}: slv_out_t;\n");
@gen_signal = (@gen_signal, "signal apb_slv_$tmp_apb->{\"id\"}_out_v: apb_out_v_t($#apb_slave_list downto 0);\n");
@gen_signal = (@gen_signal, "signal apb_slv_$tmp_apb->{\"id\"}_in_v: apb_in_v_t($#apb_slave_list downto 0);\n");
 
@ass_signal = (@ass_signal, "slv_in_apb_$tmp_apb->{\"id\"} <= ahb_slv_$tmp_apb->{\"slv\"}_in;\n");
@ass_signal = (@ass_signal, "ahb_slv_$tmp_apb->{\"slv\"}_out <= slv_out_apb_$tmp_apb->{\"id\"};\n");
 
$cnt = $#apb_slave_list;
foreach $item (@apb_slave_list){
@ass_signal = (@ass_signal, "apb_slv_$tmp_apb->{\"id\"}_out_v($cnt) <= apb_slv_${item}_out;\n");
@ass_signal = (@ass_signal, "apb_slv_${item}_in <= apb_slv_$tmp_apb->{\"id\"}_in_v($cnt);\n");
++$pslv_list[$item];
$cnt--;
}
}
 
sub gen_lib()
{
 
print file3 (
"
--*******************************************************************
--** ****
--** AHB system generator ****
--** ****
--** Author: Federico Aglietti ****
--** federico.aglietti\@opencores.org ****
--** ****
--*******************************************************************
--** ****
--** Copyright (C) 2004 Federico Aglietti ****
--** federico.aglietti\@opencores.org ****
--** ****
--** This source file may be used and distributed without ****
--** restriction provided that this copyright statement is not ****
--** removed from the file and that any derivative work contains ****
--** the original copyright notice and the associated disclaimer.****
--** ****
--** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ****
--** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ****
--** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ****
--** FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ****
--** OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ****
--** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ****
--** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ****
--** GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ****
--** BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ****
--** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ****
--** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ****
--** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ****
--** POSSIBILITY OF SUCH DAMAGE. ****
--** ****
--*******************************************************************
library ieee;
use ieee.std_logic_arith.all;
use ieee.std_logic_misc.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_1164.all;
 
use work.ahb_package.all;
use work.ahb_configure.all;
use work.ahb_components.all;
");
 
print file4 (
"
--*******************************************************************
--** ****
--** AHB system generator ****
--** ****
--** Author: Federico Aglietti ****
--** federico.aglietti\@opencores.org ****
--** ****
--*******************************************************************
--** ****
--** Copyright (C) 2004 Federico Aglietti ****
--** federico.aglietti\@opencores.org ****
--** ****
--** This source file may be used and distributed without ****
--** restriction provided that this copyright statement is not ****
--** removed from the file and that any derivative work contains ****
--** the original copyright notice and the associated disclaimer.****
--** ****
--** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ****
--** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ****
--** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ****
--** FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ****
--** OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ****
--** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ****
--** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ****
--** GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ****
--** BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ****
--** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ****
--** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ****
--** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ****
--** POSSIBILITY OF SUCH DAMAGE. ****
--** ****
--*******************************************************************
library ieee;
use ieee.std_logic_arith.all;
use ieee.std_logic_misc.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_1164.all;
use IEEE.std_logic_textio.all;
 
use work.ahb_package.all;
use work.ahb_configure.all;
use work.ahb_components.all;
");
 
print file5 (
"
--*******************************************************************
--** ****
--** AHB system generator ****
--** ****
--** Author: Federico Aglietti ****
--** federico.aglietti\@opencores.org ****
--** ****
--*******************************************************************
--** ****
--** Copyright (C) 2004 Federico Aglietti ****
--** federico.aglietti\@opencores.org ****
--** ****
--** This source file may be used and distributed without ****
--** restriction provided that this copyright statement is not ****
--** removed from the file and that any derivative work contains ****
--** the original copyright notice and the associated disclaimer.****
--** ****
--** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ****
--** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ****
--** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ****
--** FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ****
--** OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ****
--** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ****
--** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ****
--** GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ****
--** BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ****
--** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ****
--** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ****
--** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ****
--** POSSIBILITY OF SUCH DAMAGE. ****
--** ****
--*******************************************************************
library ieee;
use ieee.std_logic_arith.all;
use ieee.std_logic_misc.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_1164.all;
use IEEE.std_logic_textio.all;
 
use work.ahb_package.all;
use work.ahb_configure.all;
use work.ahb_components.all;
");
 
}
 
sub gen_ent()
{
print file3 ("
entity ahb_matrix is
port(
hresetn: in std_logic;
hclk: in std_logic;
");
$cnt=0;
foreach $item (@mst_list){
if ($item > 0) {
print file3 ("
ahb_mst_${cnt}_out: in mst_out_t;
ahb_mst_${cnt}_in: out mst_in_t;
");
@gen_ahb_signal = (@gen_ahb_signal, "
signal ahb_mst_${cnt}_out: mst_out_t;
signal ahb_mst_${cnt}_in: mst_in_t;
");
};
$cnt++;
};
$cnt=0;
foreach $item (@slv_list){
if ($item > 0) {
print file3 ("
ahb_slv_${cnt}_out: in slv_out_t;
ahb_slv_${cnt}_in: out slv_in_t;
");
@gen_ahb_signal = (@gen_ahb_signal, "
signal ahb_slv_${cnt}_out: slv_out_t;
signal ahb_slv_${cnt}_in: slv_in_t;
");
};
$cnt++;
};
$cnt=0;
foreach $item (@pslv_list){
if ($item > 0) {
print file3 ("
apb_slv_${cnt}_out: in apb_out_t;
apb_slv_${cnt}_in: out apb_in_t;
");
@gen_ahb_signal = (@gen_ahb_signal, "
signal apb_slv_${cnt}_out: apb_out_t;
signal apb_slv_${cnt}_in: apb_in_t;
");
};
$cnt++;
};
print file3 ("
remap: in std_logic
);
end;
 
architecture rtl of ahb_matrix is
 
");
 
print file4 ("
entity ahb_system is
port(
hresetn: in std_logic;
hclk: in std_logic;
 
eot_int: out std_logic_vector($masters downto 0);
conf: in conf_type_v($masters downto 0);
 
remap: in std_logic
);
end;
 
architecture rtl of ahb_system is
 
 
");
 
print file5 ("
entity ahb_tb is
end;
 
architecture rtl of ahb_tb is
 
 
");
 
}
 
sub gen_arrays {
 
@gen_conf = "
library ieee;
 
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use work.ahb_package.all;
 
package ahb_configure is
 
--***************************************************************
-- definition of custom amba system parameters
--***************************************************************
 
--***************************************************************
-- AMBA SLAVES address configuration space
--***************************************************************
--For every slave define HIGH and LOW address, before and after (r)emap
 
constant n_u: addr_t := (0, 0);\n\n";
 
 
#### PERIPHERAL SLAVES
 
for $i (0 .. $pslaves) {@gen_conf = (@gen_conf, "constant $pslave[$i]->{\"name\"}: addr_t := ($pslave[$i]->{\"add_h\"}, $pslave[$i]->{add_l});\n");}
for $i (0 .. $pslaves) {@gen_conf = (@gen_conf, "constant r$pslave[$i]->{\"name\"}: addr_t := ($pslave[$i]->{\"add_hh\"}, $pslave[$i]->{add_ll});\n");}
 
#### PERIPHERAL SLAVES ARRAY
 
for $i (0 .. 15) {
if ($i <= $pslaves) {$tmp_mat[$i] = ("r$pslave[$i]->{\"name\"}");} else {$tmp_mat[$i] = ("n_u");};
};
 
@gen_conf = (@gen_conf, "\nconstant pslv_matrix: addr_matrix_t(1 downto 0) := (\n(");
$i=15;
while ($i > 0) {@gen_conf = (@gen_conf, "$tmp_mat[$i],");$i--;}
@gen_conf = (@gen_conf, "$tmp_mat[0]),\n(");
 
for $i (0 .. 15) {
if ($i <= $pslaves) {$tmp_mat[$i] = ("$pslave[$i]->{\"name\"}");} else {$tmp_mat[$i] = ("n_u");};
};
 
$i=15;
while ($i > 0) {@gen_conf = (@gen_conf, "$tmp_mat[$i],");$i--;}
@gen_conf = (@gen_conf, "$tmp_mat[0]));\n\n");
 
#### SLAVES
 
for $i (0 .. $slaves) {@gen_conf = (@gen_conf, "constant $slave[$i]->{\"name\"}: addr_t := ($slave[$i]->{\"add_h\"}, $slave[$i]->{add_l});\n");}
for $i (0 .. $slaves) {@gen_conf = (@gen_conf, "constant r$slave[$i]->{\"name\"}: addr_t := ($slave[$i]->{\"add_hh\"}, $slave[$i]->{add_ll});\n");}
 
#### SLAVES ARRAY
 
for $i (0 .. 15) {
if ($i <= $slaves) {
$tmp_mat[$i] = ("r$slave[$i]->{\"name\"}");
} else {
$tmp_mat[$i] = ("n_u");
};
};
 
@gen_conf = (@gen_conf, "\nconstant slv_matrix: addr_matrix_t(1 downto 0) := (\n(");
$i=15;
while ($i > 0) {@gen_conf = (@gen_conf, "$tmp_mat[$i],");$i--;}
@gen_conf = (@gen_conf, "$tmp_mat[0]),\n(");
 
for $i (0 .. 15) {
if ($i <= $slaves) {
$tmp_mat[$i] = ("$slave[$i]->{\"name\"}");
} else {
$tmp_mat[$i] = ("n_u");
};
};
 
$i=15;
while ($i > 0) {@gen_conf = (@gen_conf, "$tmp_mat[$i],");$i--;}
@gen_conf = (@gen_conf, "$tmp_mat[0]));\n\n");
 
 
#### AHB ARBITERS ARRAY
 
if ($arbs>0) {
@gen_conf = (@gen_conf, "constant arb_matrix: addr_matrix_t($arbs downto 0):= (\n");
@gen_signal = (@gen_signal, "signal addr_arb_matrix: addr_matrix_t($arbs downto 0);\n");
} elsif ($arbs==0) {
@gen_conf = (@gen_conf, "constant arb_matrix: addr_matrix_t(1 downto 0):= (\n");
@gen_signal = (@gen_signal, "signal addr_arb_matrix: addr_matrix_t($arbs downto 0);\n");
}
 
 
if ($arbs==0) {
@arb_slave_list = split(' ',$arb[$0]->{"s_list"});
$j=15;
while ($j>$#arb_slave_list) {$tmp_mat[$j] = ("n_u");$j--;}
while ($j>=0) {$tmp_mat[$j] = ("ahb_slv".shift(@arb_slave_list));$j--;}
$j=15;
@gen_conf = (@gen_conf, "(");
while ($j>0) {@gen_conf = (@gen_conf, "$tmp_mat[$j],");$j--;}
@gen_conf = (@gen_conf, "$tmp_mat[$0]),\n");
$j=15;
@gen_conf = (@gen_conf, "(");
while ($j>0) {@gen_conf = (@gen_conf, "$tmp_mat[$j],");$j--;}
@gen_conf = (@gen_conf, "$tmp_mat[$0]\)\);\n\n");
} else {
$i=$arbs;
while ($i>=0) {
@arb_slave_list = split(' ',$arb[$i]->{"s_list"});
$j=15;
while ($j>$#arb_slave_list) {$tmp_mat[$j] = ("n_u");$j--;}
while ($j>=0) {$tmp_mat[$j] = ("ahb_slv".shift(@arb_slave_list));$j--;}
$j=15;
@gen_conf = (@gen_conf, "(");
while ($j>0) {@gen_conf = (@gen_conf, "$tmp_mat[$j],");$j--;}
if ($i==0) {@gen_conf = (@gen_conf, "$tmp_mat[$0]));\n\n");}
else {@gen_conf = (@gen_conf, "$tmp_mat[$0]),\n");}
$i--;
};
};
 
 
if ($arbs>0) {
@gen_conf = (@gen_conf, "constant rarb_matrix: addr_matrix_t($arbs downto 0):= (\n");
} elsif ($arbs==0) {
@gen_conf = (@gen_conf, "constant rarb_matrix: addr_matrix_t(1 downto 0):= (\n");
};
 
 
if ($arbs==0) {
@arb_slave_list = split(' ',$arb[$0]->{"s_list"});
$j=15;
while ($j>$#arb_slave_list) {$tmp_mat[$j] = ("n_u");$j--;}
while ($j>=0) {$tmp_mat[$j] = ("rahb_slv".shift(@arb_slave_list));$j--;}
$j=15;
@gen_conf = (@gen_conf, "(");
while ($j>0) {@gen_conf = (@gen_conf, "$tmp_mat[$j],");$j--;}
@gen_conf = (@gen_conf, "$tmp_mat[$0]),\n");
$j=15;
@gen_conf = (@gen_conf, "(");
while ($j>0) {@gen_conf = (@gen_conf, "$tmp_mat[$j],");$j--;}
@gen_conf = (@gen_conf, "$tmp_mat[$0]\)\);\n\n");
} else {
$i=$arbs;
while ($i>=0) {
 
@arb_slave_list = split(' ',$arb[$i]->{"s_list"});
$j=15;
while ($j>$#arb_slave_list) {$tmp_mat[$j] = ("n_u");$j--;}
while ($j>=0) {$tmp_mat[$j] = ("rahb_slv".shift(@arb_slave_list));$j--;}
$j=15;
@gen_conf = (@gen_conf, "(");
while ($j>0) {@gen_conf = (@gen_conf, "$tmp_mat[$j],");$j--;}
if ($i==0) {@gen_conf = (@gen_conf, "$tmp_mat[$0]));\n\n");}
else {@gen_conf = (@gen_conf, "$tmp_mat[$0]),\n");}
$i--;
}
}
 
 
 
#### AHB-AHB BRIDGES ARRAY
 
if ($ahbs>0) {
@gen_conf = (@gen_conf, "constant ahbbrg_matrix: addr_matrix_t($ahbs downto 0):= (\n");
@gen_signal = (@gen_signal, "signal addr_ahbbrg_matrix: addr_matrix_t($ahbs downto 0);\n");
} elsif ($ahbs==0) {
@gen_conf = (@gen_conf, "constant ahbbrg_matrix: addr_matrix_t(1 downto 0):= (\n");
@gen_signal = (@gen_signal, "signal addr_ahbbrg_matrix: addr_matrix_t(1 downto 0);\n");
} else {
@gen_conf = (@gen_conf,
"constant ahbbrg_matrix: addr_matrix_t(1 downto 0) := (
(n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u),
(n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u));
 
constant rahbbrg_matrix: addr_matrix_t(1 downto 0) := (
(n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u),
(n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u));
 
");
@gen_signal = (@gen_signal, "signal addr_ahbbrg_matrix: addr_matrix_t(1 downto 0);\n");
}
 
if ($ahbs==0) {
@brg_slave_list = split(' ',$ahb[$0]->{"list"});
$j=15;
while ($j>$#brg_slave_list) {$tmp_mat[$j] = ("n_u");$j--;}
while ($j>=0) {$tmp_mat[$j] = ("ahb_slv".shift(@brg_slave_list));$j--;}
$j=15;
@gen_conf = (@gen_conf, "(");
while ($j>0) {@gen_conf = (@gen_conf, "$tmp_mat[$j],");$j--;}
@gen_conf = (@gen_conf, "$tmp_mat[$0]),\n");
$j=15;
@gen_conf = (@gen_conf, "(");
while ($j>0) {@gen_conf = (@gen_conf, "$tmp_mat[$j],");$j--;}
@gen_conf = (@gen_conf, "$tmp_mat[$0]\)\);\n\n");
} else {
$i=$ahbs;
while ($i>=0) {
 
@brg_slave_list = split(' ',$ahb[$i]->{"list"});
$j=15;
while ($j>$#brg_slave_list) {$tmp_mat[$j] = ("n_u");$j--;}
while ($j>=0) {$tmp_mat[$j] = ("ahb_slv".shift(@brg_slave_list));$j--;}
$j=15;
@gen_conf = (@gen_conf, "(");
while ($j>0) {@gen_conf = (@gen_conf, "$tmp_mat[$j],");$j--;}
if ($i==0) {@gen_conf = (@gen_conf, "$tmp_mat[$0]));\n\n");}
else {@gen_conf = (@gen_conf, "$tmp_mat[$0]),\n");}
$i--;
};
}
 
if ($ahbs>0) {
@gen_conf = (@gen_conf, "constant rahbbrg_matrix: addr_matrix_t($ahbs downto 0):= (\n");
} elsif ($ahbs==0) {
@gen_conf = (@gen_conf, "constant rahbbrg_matrix: addr_matrix_t(1 downto 0):= (\n");
};
 
if ($ahbs==0) {
@brg_slave_list = split(' ',$ahb[$0]->{"list"});
$j=15;
while ($j>$#brg_slave_list) {$tmp_mat[$j] = ("n_u");$j--;}
while ($j>=0) {$tmp_mat[$j] = ("rahb_slv".shift(@brg_slave_list));$j--;}
$j=15;
@gen_conf = (@gen_conf, "(");
while ($j>0) {@gen_conf = (@gen_conf, "$tmp_mat[$j],");$j--;}
@gen_conf = (@gen_conf, "$tmp_mat[$0]),\n");
$j=15;
@gen_conf = (@gen_conf, "(");
while ($j>0) {@gen_conf = (@gen_conf, "$tmp_mat[$j],");$j--;}
@gen_conf = (@gen_conf, "$tmp_mat[$0]\)\);\n\n");
} else {
$i=$ahbs;
while ($i>=0) {
 
@brg_slave_list = split(' ',$ahb[$i]->{"list"});
$j=15;
while ($j>$#brg_slave_list) {$tmp_mat[$j] = ("n_u");$j--;}
while ($j>=0) {$tmp_mat[$j] = ("rahb_slv".shift(@brg_slave_list));$j--;}
$j=15;
@gen_conf = (@gen_conf, "(");
while ($j>0) {@gen_conf = (@gen_conf, "$tmp_mat[$j],");$j--;}
if ($i==0) {@gen_conf = (@gen_conf, "$tmp_mat[$0]));\n\n");}
else {@gen_conf = (@gen_conf, "$tmp_mat[$0]),\n");}
$i--;
};
};
 
#### APB BRIDGES ARRAY
 
if ($apbs>0) {
@gen_conf = (@gen_conf, "constant apbbrg_matrix: addr_matrix_t($apbs downto 0):= (\n");
@gen_signal = (@gen_signal, "signal addr_apbbrg_matrix: addr_matrix_t($apbs downto 0);\n");
} elsif ($apbs==0) {
@gen_conf = (@gen_conf, "constant apbbrg_matrix: addr_matrix_t(1 downto 0):= (\n");
@gen_signal = (@gen_signal, "signal addr_apbbrg_matrix: addr_matrix_t(1 downto 0);\n");
} else {
@gen_conf = (@gen_conf,
"constant apbbrg_matrix: addr_matrix_t(1 downto 0) := (
(n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u),
(n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u));
 
constant rapbbrg_matrix: addr_matrix_t(1 downto 0) := (
(n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u),
(n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u,n_u));
 
");
@gen_signal = (@gen_signal, "signal addr_apbbrg_matrix: addr_matrix_t(1 downto 0);\n");
};
 
if ($apbs==0) {
@apb_slave_list = split(' ',$apb[$0]->{"list"});
$j=15;
while ($j>$#apb_slave_list) {$tmp_mat[$j] = ("n_u");$j--;}
while ($j>=0) {$tmp_mat[$j] = ("apb_slv".shift(@apb_slave_list));$j--;}
$j=15;
@gen_conf = (@gen_conf, "(");
while ($j>0) {@gen_conf = (@gen_conf, "$tmp_mat[$j],");$j--;}
@gen_conf = (@gen_conf, "$tmp_mat[$0]),\n");
$j=15;
@gen_conf = (@gen_conf, "(");
while ($j>0) {@gen_conf = (@gen_conf, "$tmp_mat[$j],");$j--;}
@gen_conf = (@gen_conf, "$tmp_mat[$0]\)\);\n\n");
} elsif ($apbs>0) {
$i=$apbs;
while ($i>=0) {
 
@apb_slave_list = split(' ',$apb[$i]->{"list"});
$j=15;
while ($j>$#apb_slave_list) {$tmp_mat[$j] = ("n_u");$j--;}
while ($j>=0) {$tmp_mat[$j] = ("apb_slv".shift(@apb_slave_list));$j--;}
$j=15;
@gen_conf = (@gen_conf, "(");
while ($j>0) {@gen_conf = (@gen_conf, "$tmp_mat[$j],");$j--;}
if ($i==0) {@gen_conf = (@gen_conf, "$tmp_mat[$0]));\n\n");}
else {@gen_conf = (@gen_conf, "$tmp_mat[$0]),\n");}
$i--;
};
} else {
;
};
 
if ($apbs>0) {
@gen_conf = (@gen_conf, "constant rapbbrg_matrix: addr_matrix_t($apbs downto 0):= (\n");
} elsif ($apbs==0) {
@gen_conf = (@gen_conf, "constant rapbbrg_matrix: addr_matrix_t(1 downto 0):= (\n");
};
 
if ($apbs==0) {
@apb_slave_list = split(' ',$apb[$0]->{"list"});
$j=15;
while ($j>$#apb_slave_list) {$tmp_mat[$j] = ("n_u");$j--;}
while ($j>=0) {$tmp_mat[$j] = ("rapb_slv".shift(@apb_slave_list));$j--;}
$j=15;
@gen_conf = (@gen_conf, "(");
while ($j>0) {@gen_conf = (@gen_conf, "$tmp_mat[$j],");$j--;}
@gen_conf = (@gen_conf, "$tmp_mat[$0]),\n");
$j=15;
@gen_conf = (@gen_conf, "(");
while ($j>0) {@gen_conf = (@gen_conf, "$tmp_mat[$j],");$j--;}
@gen_conf = (@gen_conf, "$tmp_mat[$0]\)\);\n\n");
} elsif ($apbs>0) {
$i=$apbs;
while ($i>=0) {
 
@apb_slave_list = split(' ',$apb[$i]->{"list"});
$j=15;
while ($j>$#apb_slave_list) {$tmp_mat[$j] = ("n_u");$j--;}
while ($j>=0) {$tmp_mat[$j] = ("rapb_slv".shift(@apb_slave_list));$j--;}
$j=15;
@gen_conf = (@gen_conf, "(");
while ($j>0) {@gen_conf = (@gen_conf, "$tmp_mat[$j],");$j--;}
if ($i==0) {@gen_conf = (@gen_conf, "$tmp_mat[$0]));\n\n");}
else {@gen_conf = (@gen_conf, "$tmp_mat[$0]),\n");}
$i--;
};
} else {
;
};
#### END OF FILE
 
@gen_conf = (@gen_conf,"
 
end;
 
package body ahb_configure is
end;
 
");
 
};
 
sub master_init {
$masters += 1;
$master[$masters]{"module"}='ahb_master';
$master[$masters]{"name"}='ahb_mst'.$masters;
$master[$masters]{"id"}=$masters;
$master[$masters]{"fifo_ln"}='8';
$master[$masters]{"fifo_he"}='1';
$master[$masters]{"fifo_hf"}='7';
$master[$masters]{"num_bits_addr"}='4';
$master[$masters]{"write_burst"}='0';
$master[$masters]{"read_burst"}='0';
$master[$masters]{"write_lat"}='2';
$master[$masters]{"read_lat"}='2';
$uut[$masters]{"base_addr"}='2048';
};
 
sub slave_init {
$slaves += 1;
$slave[$slaves]{"module"}='ahb_slave';
$slave[$slaves]{"name"}='ahb_slv'.$slaves;
$slave[$slaves]{"list"}=('SLAVE_LIST');
$slave[$slaves]{"id"}=$slaves;
$slave[$slaves]{"type"}='wait';
$slave[$slaves]{"add_h"}='0';
$slave[$slaves]{"add_l"}='0';
$slave[$slaves]{"add_hh"}='0';
$slave[$slaves]{"add_ll"}='0';
$slave[$slaves]{"alg"}=0;
$slave[$slaves]{"fifo_ln"}='8';
$slave[$slaves]{"fifo_he"}='1';
$slave[$slaves]{"fifo_hf"}='7';
$slave[$slaves]{"num_bits_addr"}='4';
$slave[$slaves]{"write_burst"}='0';
$slave[$slaves]{"read_burst"}='0';
$slave[$slaves]{"write_lat"}='2';
$slave[$slaves]{"read_lat"}='2';
};
 
sub pslave_init {
$pslaves += 1;
$pslave[$pslaves]{"module"}='apb_slave';
$pslave[$pslaves]{"name"}='apb_slv'.$pslaves;
$pslave[$pslaves]{"id"}=$pslaves;
$pslave[$pslaves]{"add_h"}='0';
$pslave[$pslaves]{"add_l"}='0';
$pslave[$pslaves]{"add_hh"}='0';
$pslave[$pslaves]{"add_ll"}='0';
$pslave[$pslaves]{"num_bits_addr"}='4';
};
 
sub arb_init {
$arbs += 1;
$arb[$arbs]{"module"}='ahb_arbiter';
$arb[$arbs]{"name"}='ahb_arb'.$arbs;
$arb[$arbs]{"id"}=$arbs;
$arb[$arbs]{"def"}='DEFAULT_MASTER';
$arb[$arbs]{"m_list"}=('MASTER_LIST');
$arb[$arbs]{"s_list"}=('SLAVE_LIST');
$arb[$arbs]{"alg"}=0;
};
 
sub ahb_init {
$ahbs += 1;
$ahb[$ahbs]{"module"}='ahb_bridge';
$ahb[$ahbs]{"name"}='ahb_brg'.$ahbs;
$ahb[$ahbs]{"id"}=$ahbs;
$ahb[$ahbs]{"alg"}=0;
$ahb[$ahbs]{"def"}='DEFAULT_SLAVE';
$ahb[$ahbs]{"list"}=('SLAVE_LIST');
$ahb[$ahbs]{"mst"}='BRIDGE_MASTER';
};
 
sub apb_init {
$apbs += 1;
$apb[$apbs]{"module"}='apb_bridge';
$apb[$apbs]{"name"}='apb_brg'.$apbs;
$apb[$apbs]{"id"}=$apbs;
$apb[$apbs]{"num_bits_addr"}='4';
$apb[$apbs]{"slv"}='BRIDGE_SLAVE';
$apb[$apbs]{"list"}=('SLAVE_LIST');
};
 
 
# GUI FUNCTIONS
 
sub WinGlobalExit {
$mw->destroy();
};
 
 
sub WinAddMaster {
$state='WinGlobal';
&master_init;
$mw = MainWindow->new;
$frame=$mw->Frame(-label=>"New AHB Master");
# AHB Master
$frame->pack(@pt);
$frame->Label(-text => "AHB Master name: ")->pack(@pw);
$frame->Entry(-textvariable => \$master[$masters]{"name"})->pack(@pe);
# id
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "AHB Master number: ")->pack(@pw);
$frame->Entry(-state => 'disabled', -textvariable => \$master[$masters]{"id"})->pack(@pe);
 
$frame=$mw->Frame(-label=>"AHB Master internal fifo");
# fifo length
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "Fifo length: ")->pack(@pw);
$frame->Entry(-textvariable => \$master[$masters]{"fifo_ln"})->pack(@pe);
$frame=$mw->Frame();
# fifo half empty
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "Fifo half-empty level: ")->pack(@pw);
$frame->Entry(-textvariable => \$master[$masters]{"fifo_he"})->pack(@pe);
$frame=$mw->Frame();
# fifo half full
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "Fifo half-full level: ")->pack(@pw);
$frame->Entry(-textvariable => \$master[$masters]{"fifo_hf"})->pack(@pe);
$frame=$mw->Frame();
# number of addressable bits
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "Number of addr bits: ")->pack(@pw);
$frame->Entry(-textvariable => \$master[$masters]{"num_bits_addr"})->pack(@pe);
$frame=$mw->Frame();
# burst capability in write
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "Write burst capability: ")->pack(@pw);
$a = $frame->Radiobutton ( -variable => \$master[$masters]{"write_burst"}, -text => 'YES', -value => '1')->pack(@pw);
$b = $frame->Radiobutton ( -variable => \$master[$masters]{"write_burst"}, -text => 'NO', -value => '0')->pack(@pe);
# burst capability in read
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "Read burst capability: ")->pack(@pw);
$c = $frame->Radiobutton ( -variable => \$master[$masters]{"read_burst"}, -text => 'YES', -value => '1')->pack(@pw);
$d = $frame->Radiobutton ( -variable => \$master[$masters]{"read_burst"}, -text => 'NO', -value => '0')->pack(@pe);
# write latency
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "Write access latency: ")->pack(@pw);
$frame->Entry(-textvariable => \$master[$masters]{"write_lat"})->pack(@pe);
$frame=$mw->Frame();
# read latency
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "Read access latency: ")->pack(@pw);
$frame->Entry(-textvariable => \$master[$masters]{"read_lat"})->pack(@pe);
$frame=$mw->Frame();
# UUT base address
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "UUT Base Address: ")->pack(@pw);
$frame->Entry(-textvariable => \$uut[$masters]{"base_addr"})->pack(@pe);
$frame=$mw->Frame();
 
# exit
$frame=$mw->Frame(-label=>"\n");
$frame->pack(@pt);
$frame->Button(-text => "cancel", -command =>sub {WinGlobalExit(); $state='WinGlobal'; $masters--;})->pack (@pw);
$frame->Button(-text => "done", -command =>sub {WinGlobalExit(); $state='WinGlobal';})->pack (@pe);
MainLoop;
};
 
 
sub WinAddSlave {
$state='WinGlobal';
&slave_init;
$mw = MainWindow->new;
$frame=$mw->Frame(-label=>"New AHB Slave");
# AHB Slave
$frame->pack(@pt);
$frame->Label(-text => "AHB Slave name: ")->pack(@pw);
$frame->Entry(-textvariable => \$slave[$slaves]{"name"})->pack(@pe);
 
# type:multi/wait/retry/split
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "Slave type: ")->pack(@pw);
$a = $frame->Radiobutton (-state => 'disabled', -variable => \$slave[$slaves]{"type"}, -text => 'Multi slave', -value => 'multi')->pack(@pw);
$b = $frame->Radiobutton ( -variable => \$slave[$slaves]{"type"}, -text => 'Single slave, wait', -value => 'wait')->pack(@pw);
$c = $frame->Radiobutton (-state => 'disabled', -variable => \$slave[$slaves]{"type"}, -text => 'Single slave, retry', -value => 'retry')->pack(@pw);
$d = $frame->Radiobutton (-state => 'disabled', -variable => \$slave[$slaves]{"type"}, -text => 'Single slave, split', -value => 'split')->pack(@pw);
# exit
$frame=$mw->Frame(-label=>"\n");
$frame->pack(@pt);
$frame->Button(-text => "cancel", -command =>sub {WinGlobalExit(); $slaves--;})->pack (@pw);
$frame->Button(-text => "done", -command =>sub {WinGlobalExit(); WinDefSlave(); })->pack (@pe);
MainLoop;
}
 
sub WinDefSlave {
 
$state='WinGlobal';
 
$mw = MainWindow->new;
if ($slave[$slaves]{"type"} eq 'multi') {
# slave list: first is default
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "Slave list: ")->pack(@pw);
$frame->Entry(-textvariable => \$slave[$slaves]{"list"})->pack(@pe);
$frame=$mw->Frame();
# algorithm number: 0,1,2
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "Arbitration type: ")->pack(@pw);
$a = $frame->Radiobutton ( -variable => \$slave[$slaves]{"alg"}, -text => 'Fixed ', -value => '0')->pack(@pw);
$b = $frame->Radiobutton ( -variable => \$slave[$slaves]{"alg"}, -text => 'Round Robin ', -value => '1')->pack(@pw);
$c = $frame->Radiobutton ( -variable => \$slave[$slaves]{"alg"}, -text => 'Pseudo Random', -value => '2')->pack(@pw);
$frame=$mw->Frame();
 
} else {
# id
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "AHB Slave number: ")->pack(@pw);
$frame->Entry(-state => 'disabled', -textvariable => \$slave[$slaves]{"id"})->pack(@pe);
 
if (($slave[$slaves]{"type"} eq 'retry') or ($slave[$slaves]{"type"} eq 'split')) {
 
# fifo length
$frame=$mw->Frame(-label=>"AHB Slave internal fifo");
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "Fifo length: ")->pack(@pw);
$frame->Entry( -textvariable => \$slave[$slaves]{"fifo_ln"})->pack(@pe);
$frame=$mw->Frame();
# fifo half empty
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "Fifo half-empty level: ")->pack(@pw);
$frame->Entry( -textvariable => \$slave[$slaves]{"fifo_he"})->pack(@pe);
$frame=$mw->Frame();
# fifo half full
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "Fifo half-full level: ")->pack(@pw);
$frame->Entry( -textvariable => \$slave[$slaves]{"fifo_hf"})->pack(@pe);
$frame=$mw->Frame();
}
 
# add before remap
$frame=$mw->Frame(-label=>"ADDRESS before remap");
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "Add high-low: ")->pack(@pt);
$frame->Entry(-textvariable => \$slave[$slaves]{"add_h"})->pack(@pw);
$frame->Entry(-textvariable => \$slave[$slaves]{"add_l"})->pack(@pe);
 
# add after remap
$frame=$mw->Frame(-label=>"ADDRESS after remap");
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "Add high-low after remap: ")->pack(@pt);
$frame->Entry(-textvariable => \$slave[$slaves]{"add_hh"})->pack(@pw);
$frame->Entry(-textvariable => \$slave[$slaves]{"add_ll"})->pack(@pe);
# number of addressable bits
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "Number of addr bits: ")->pack(@pw);
$frame->Entry(-textvariable => \$slave[$slaves]{"num_bits_addr"})->pack(@pe);
$frame=$mw->Frame();
# burst capability in write
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "Write burst capability: ")->pack(@pw);
$a = $frame->Radiobutton ( -variable => \$slave[$slaves]{"write_burst"}, -text => 'YES', -value => '1')->pack(@pw);
$b = $frame->Radiobutton ( -variable => \$slave[$slaves]{"write_burst"}, -text => 'NO', -value => '0')->pack(@pe);
# burst capability in read
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "Read burst capability: ")->pack(@pw);
$c = $frame->Radiobutton ( -variable => \$slave[$slaves]{"read_burst"}, -text => 'YES', -value => '1')->pack(@pw);
$d = $frame->Radiobutton ( -variable => \$slave[$slaves]{"read_burst"}, -text => 'NO', -value => '0')->pack(@pe);
# write latency
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "Write access latency: ")->pack(@pw);
$frame->Entry(-textvariable => \$slave[$slaves]{"write_lat"})->pack(@pe);
$frame=$mw->Frame();
# read latency
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "Read access latency: ")->pack(@pw);
$frame->Entry(-textvariable => \$slave[$slaves]{"read_lat"})->pack(@pe);
$frame=$mw->Frame();
 
# exit
$frame=$mw->Frame(-label=>"\n");
$frame->pack(@pt);
$frame->Button(-text => "cancel", -command =>sub {WinGlobalExit(); $slaves--; WinAddSlave();})->pack (@pw);
$frame->Button(-text => "done", -command =>sub {WinGlobalExit(); })->pack (@pe);
MainLoop;
}
};
 
 
sub WinAddPslave {
 
$state='WinGlobal';
&pslave_init;
$mw = MainWindow->new;
$frame=$mw->Frame(-label=>"New APB Slave");
# APB Slave
$frame->pack(@pt);
$frame->Label(-text => "APB Salve name: ")->pack(@pw);
$frame->Entry(-textvariable => \$pslave[$pslaves]{"name"})->pack(@pe);
 
# id
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "APB Slave number: ")->pack(@pw);
$frame->Entry(-state => 'disabled', -textvariable => \$pslave[$pslaves]{"id"})->pack(@pe);
 
# add before remap
$frame=$mw->Frame(-label=>"ADDRESS before remap");
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "Add high-low: ")->pack(@pt);
$frame->Entry(-textvariable => \$pslave[$pslaves]{"add_h"})->pack(@pw);
$frame->Entry(-textvariable => \$pslave[$pslaves]{"add_l"})->pack(@pe);
 
# add after remap
$frame=$mw->Frame(-label=>"ADDRESS after remap");
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "Add high-low after remap: ")->pack(@pt);
$frame->Entry(-textvariable => \$pslave[$pslaves]{"add_hh"})->pack(@pw);
$frame->Entry(-textvariable => \$pslave[$pslaves]{"add_ll"})->pack(@pe);
 
# number of addressable bits
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "Number of addr bits: ")->pack(@pw);
$frame->Entry(-textvariable => \$pslave[$pslaves]{"num_bits_addr"})->pack(@pe);
$frame=$mw->Frame();
 
# exit
$frame=$mw->Frame(-label=>"\n");
$frame->pack(@pt);
$frame->Button(-text => "cancel", -command =>sub {WinGlobalExit(); $pslaves--;})->pack (@pw);
$frame->Button(-text => "done", -command =>sub {WinGlobalExit(); })->pack (@pe);
MainLoop;
};
 
 
sub WinAddArbiter {
$state='WinGlobal';
&arb_init;
$mw = MainWindow->new;
$frame=$mw->Frame(-label=>"New AHB Arbiter");
# AHB Arbiter
$frame->pack(@pt);
$frame->Label(-text => "AHB Arbiter name: ")->pack(@pw);
$frame->Entry(-textvariable => \$arb[$arbs]{"name"})->pack(@pe);
 
# id
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "AHB Arbiter number: ")->pack(@pw);
$frame->Entry(-state => 'disabled', -textvariable => \$arb[$arbs]{"id"})->pack(@pe);
 
# Default master
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "Default Master: ")->pack(@pw);
$frame->Entry(-textvariable => \$arb[$arbs]{"def"})->pack(@pe);
# master list: first is default
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "Master list: ")->pack(@pw);
$frame->Entry(-textvariable => \$arb[$arbs]{"m_list"})->pack(@pe);
$frame=$mw->Frame();
 
# algorithm number: 0,1,2,3,4,5
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "Arbitration type: ")->pack(@pt);
$a = $frame->Radiobutton ( -variable => \$arb[$arbs]{"alg"}, -text => 'Fixed ', -value => '0')->pack(@pw);
$b = $frame->Radiobutton ( -variable => \$arb[$arbs]{"alg"}, -text => 'Round Robin ', -value => '1')->pack(@pw);
$c = $frame->Radiobutton ( -variable => \$arb[$arbs]{"alg"}, -text => 'Pseudo Random', -value => '2')->pack(@pw);
$d = $frame->Radiobutton ( -variable => \$arb[$arbs]{"alg"}, -text => 'Fixed Modif. ', -value => '3')->pack(@pe);
$e = $frame->Radiobutton ( -variable => \$arb[$arbs]{"alg"}, -text => 'RR Modif. ', -value => '4')->pack(@pe);
$f = $frame->Radiobutton ( -variable => \$arb[$arbs]{"alg"}, -text => 'PR Modif. ', -value => '5')->pack(@pe);
$frame=$mw->Frame();
 
# slave list
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "Slave list: ")->pack(@pw);
$frame->Entry(-textvariable => \$arb[$arbs]{"s_list"})->pack(@pe);
$frame=$mw->Frame();
 
# exit
$frame=$mw->Frame(-label=>"\n");
$frame->pack(@pt);
$frame->Button(-text => "cancel", -command =>sub {WinGlobalExit(); $arbs--;})->pack (@pw);
$frame->Button(-text => "done", -command =>sub {WinGlobalExit(); })->pack (@pe);
MainLoop;
};
 
 
sub WinAddAhb {
$state='WinGlobal';
&ahb_init;
$mw = MainWindow->new;
$frame=$mw->Frame(-label=>"New AHB Bridge");
# AHB Bridge
$frame->pack(@pt);
$frame->Label(-text => "AHB Bridge name: ")->pack(@pw);
$frame->Entry(-textvariable => \$ahb[$ahbs]{"name"})->pack(@pe);
 
# id
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "AHB Bridge number: ")->pack(@pw);
$frame->Entry(-state => 'disabled', -textvariable => \$ahb[$ahbs]{"id"})->pack(@pe);
 
# Default slave
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "Default Slave: ")->pack(@pw);
$frame->Entry(-textvariable => \$ahb[$ahbs]{"def"})->pack(@pe);
# slave list
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "Slave list: ")->pack(@pw);
$frame->Entry(-textvariable => \$ahb[$ahbs]{"list"})->pack(@pe);
$frame=$mw->Frame();
 
# master
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "Master: ")->pack(@pw);
$frame->Entry(-textvariable => \$ahb[$ahbs]{"mst"})->pack(@pe);
$frame=$mw->Frame();
 
# algorithm number: 0,1,2
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "Arbitration type: ")->pack(@pt);
$a = $frame->Radiobutton ( -variable => \$ahb[$ahbs]{"alg"}, -text => 'Fixed ', -value => '0')->pack(@pw);
$b = $frame->Radiobutton ( -variable => \$ahb[$ahbs]{"alg"}, -text => 'Round Robin ', -value => '1')->pack(@pw);
$c = $frame->Radiobutton ( -variable => \$ahb[$ahbs]{"alg"}, -text => 'Pseudo Random', -value => '2')->pack(@pw);
$frame=$mw->Frame();
 
# exit
$frame=$mw->Frame(-label=>"\n");
$frame->pack(@pt);
$frame->Button(-text => "cancel", -command =>sub {WinGlobalExit(); $ahbs--;})->pack (@pw);
$frame->Button(-text => "done", -command =>sub {WinGlobalExit(); })->pack (@pe);
MainLoop;
};
 
 
sub WinAddApb {
 
$state='WinGlobal';
&apb_init;
$mw = MainWindow->new;
$frame=$mw->Frame(-label=>"New APB Bridge");
# APB Bridge
$frame->pack(@pt);
$frame->Label(-text => "APB Bridge name: ")->pack(@pw);
$frame->Entry(-textvariable => \$apb[$apbs]{"name"})->pack(@pe);
 
# id
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "AHB Bridge number: ")->pack(@pw);
$frame->Entry(-state => 'disabled', -textvariable => \$apb[$apbs]{"id"})->pack(@pe);
 
# number of addressable bits
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "Number of addr bits: ")->pack(@pw);
$frame->Entry(-textvariable => \$apb[$apbs]{"num_bits_addr"})->pack(@pe);
$frame=$mw->Frame();
 
# slave
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "AHB Slave: ")->pack(@pw);
$frame->Entry(-textvariable => \$apb[$apbs]{"slv"})->pack(@pe);
# slave list
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "APB Slave list: ")->pack(@pw);
$frame->Entry(-textvariable => \$apb[$apbs]{"list"})->pack(@pe);
$frame=$mw->Frame();
 
# exit
$frame=$mw->Frame(-label=>"\n");
$frame->pack(@pt);
$frame->Button(-text => "cancel", -command =>sub {WinGlobalExit(); $apbs--;})->pack (@pw);
$frame->Button(-text => "done", -command =>sub {WinGlobalExit(); })->pack (@pe);
MainLoop;
};
 
 
sub WinCheck {
 
$mw = MainWindow->new;
 
$state='WinGlobal';
@gen_signal=();
@ass_signal=();
@gen_comp=();
@gen_tbcomp=();
@gen_uut=();
$chk=0;
@tmp_chk=();
 
print "\n*******************************************\n*******************************************\n";
# check for masters:
if ($masters >= 0) {$chk++;for $j ( 0 .. $masters ) {&gen_master($master[$j]);}} else
{
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "## ERROR: No AHB Masters")->pack(@pt);
}
# check for slaves:
if ($slaves >= 0) {$chk++;} else
{
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "## ERROR: No AHB Slaves")->pack(@pt);
}
 
# check for per slaves:
if ($pslaves >= 0) {for $j ( 0 .. $pslaves ) {&gen_pslave($pslave[$j]);}} else {
if ($apbs >= 0) {
$chk--;
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "## ERROR: No APB Peripherals")->pack(@pt);
}
}
 
if ($arbs >= 0) {$chk++;for $j ( 0 .. $arbs ) {&gen_arbiter($arb[$j]);}} else
{
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "## ERROR: No AHB Arbiters")->pack(@pt);
}
# CONNECTION CHECKS:
# Masters:
for $i (0 .. $masters) {$tmp_chk[$i]=0};
for $i (0 .. $ahbs) {$tmp_chk[$ahb[$i]{'mst'}]=0};
for $i (0 .. $arbs) {
@tmp_lst=split(' ',$arb[$i]{'m_list'});
foreach (@tmp_lst) {
if ($_>$#tmp_chk) {
$chk--;
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "## ERROR: MASTER $_ used in ARBITER but not declared!")->pack(@pt);
} else {
$tmp_chk[$_]++;
};
};
};
for $i (0 .. $ahbs) {
$tmp_chk[$ahb[$i]{'mst'}]+=10;
};
for $i (0 .. $#tmp_chk) {
if ($tmp_chk[$i]==0) {
$chk--;
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "## ERROR: MASTER $i not connected to any AHB ARBITER!")->pack(@pt);
} elsif ($tmp_chk[$i]>1 and $tmp_chk[$i]<10 and $i<=$masters) {
$chk--;
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "## ERROR: MASTER $i connected to more than one AHB ARBITER!")->pack(@pt);
} elsif ($tmp_chk[$i]>=10 and $i<=$masters) {
$chk--;
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "## ERROR: MASTER $i cannot be used as AHB BRIDGE master!")->pack(@pt);
} elsif ($tmp_chk[$i]>=20 and $i>$masters) {
$chk--;
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "## ERROR: MASTER $i used more than one AHB BRIDGE!")->pack(@pt);
};
};
# Slaves:
$#tmp_chk=-1;
for $i (0 .. $slaves) {$tmp_chk[$i]=0};
for $i (0 .. $arbs) {
@tmp_lst=split(' ',$arb[$i]{'s_list'});
foreach (@tmp_lst) {
if ($_>$slaves) {
$chk--;
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "## ERROR: SLAVE $_ still not declared!")->pack(@pt);
} else {
$tmp_chk[$_]++;
};
};
};
for $i (0 .. $slaves) {
if ($tmp_chk[$i]==0) {
$chk--;
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "## ERROR: SLAVE $i not connected to any AHB ARBITER!")->pack(@pt);
};
};
for $i (0 .. $slaves) {$tmp_chk[$i]=0};
for $i (0 .. $ahbs) {
@tmp_lst=split(' ',$ahb[$i]{'s_list'});
foreach (@tmp_lst) {$tmp_chk[$_]++;}
};
for $i (0 .. $apbs) {
if ($i>$slaves) {
$chk--;
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "## ERROR: SLAVE $_ still not declared!")->pack(@pt);
} else {
$tmp_chk[$apb[$i]{'slv'}]++;
};
};
for $i (0 .. $slaves) {
if ($tmp_chk[$i]>1) {
$chk--;
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "## ERROR: SLAVE $i cannot be connected to more than one BRIDGE!")->pack(@pt);
};
};
 
# APB Peripherals:
$#tmp_chk=-1;
for $i (0 .. $pslaves) {$tmp_chk[$i]=0};
for $i (0 .. $apbs) {
@tmp_lst=split(' ',$apb[$i]{'list'});
foreach (@tmp_lst) {
if ($_>$pslaves) {
$chk--;
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "## ERROR: APB Peripheral $_ still not declared!")->pack(@pt);
} else {
$tmp_chk[$_]++;
};
};
};
for $i (0 .. $pslaves) {
if ($tmp_chk[$i]==0) {
$chk--;
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "## ERROR: APB Peripheral $i not assigned to any APB master!")->pack(@pt);
} elsif ($tmp_chk[$i]>1) {
$chk--;
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "## ERROR: APB Peripheral $i connected more than once!")->pack(@pt);
};
};
 
# WARNINGS on missing AHBAHB and AHBAPB BRIDGES
if ($apbs >= 0) {
for $j ( 0 .. $apbs ) {&gen_apb($apb[$j]);}
} else {
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "** WARNING: No APB Bridges")->pack(@pt);
}
 
if ($ahbs >= 0) {for $j ( 0 .. $ahbs ) {&gen_bridge($ahb[$j]);}} else
{
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "** WARNING: No AHB/AHB Bridges")->pack(@pt);
}
 
# number '$chk' should indicate 'all checks OK!!'
$done='disabled';
if ($chk>=3) {
$done='normal';
$frame=$mw->Frame();
$frame->pack(@pt);
$frame->Label(-text => "**** CHECK PASSED ****")->pack(@pt);
};
# exit
$frame=$mw->Frame(-label=>"\n");
$frame->pack(@pt);
$frame->Button(-text => "done", -command =>sub {WinGlobalExit(); })->pack (@pt);
MainLoop;
};
 
 
}
 
 
 
 
 
 
# global assignments
sub WinGlobal {
$mw = MainWindow->new;
$mw->title ("AHB system generator");
$frame=$mw->Frame(-label=>"Main menu\n");
$frame->pack(@pt);
$frame->Button(
# -default=>'normal',
# -foreground=>'black',-background=>'grey',
# -state=>'active',-activeforeground=>'blue',-activebackground=>'white',
# -disabledforeground=>'black',
-text=>"add master",-command=>sub {WinGlobalExit(); $state='WinAddMaster';})->pack (@pw);
$frame->Button(
-text=>"add slave",-command=>sub {WinGlobalExit(); $state='WinAddSlave';})->pack (@pw);
$frame->Button(
-text=>"add arbiter",-command=>sub {WinGlobalExit(); $state='WinAddArbiter';})->pack (@pw);
 
$frame->Button(-state=>'disabled',
-text=>"add per. slave",-command=>sub {WinGlobalExit(); $state='WinAddPslave';})->pack (@pe);
$frame->Button(-state=>'disabled',
-text=>"add apb bridge",-command=>sub {WinGlobalExit(); $state='WinAddApb';})->pack (@pe);
 
$frame->Button(-state=>'disabled',
-text=>"add ahb bridge",-command=>sub {WinGlobalExit(); $state='WinAddAhb';})->pack (@pe);
$frame=$mw->Frame(-label=>"\n");
$frame->pack(@pt);
$frame->Button(
-text=>"RESET conf",-command=>sub {WinGlobalExit(); $state='ResetConf';})->pack (@pt);
 
$frame->Button(
-text=>"READ conf",-command=>sub {WinGlobalExit(); $state='ReadConf';})->pack (@pt);
 
$frame->Button(
-text=>"SAVE conf",-command=>sub {WinGlobalExit(); $state='SaveConf';})->pack (@pt);
# check and elaborate
$frame->Button(
-text=>"check/generate",-command=>sub {WinGlobalExit(); $state='WinCheck';})->pack (@pt);
# exit
$frame->Button(
-state=>$done,-activeforeground=>'red',-activebackground=>'blue',
-text=>"done",-command => sub {WinGlobalExit(); $state='quit';})->pack (@pt);
MainLoop;
};
 
 
 
# GUI FSM
 
sub gui_fsm {
$i=1;
until ($state eq "quit") {
if ($state eq 'WinGlobal') {
&WinGlobal;
} elsif ($state eq 'WinAddMaster') {
&WinAddMaster;
} elsif ($state eq 'WinAddSlave') {
&WinAddSlave;
} elsif ($state eq 'WinAddPslave') {
&WinAddPslave;
} elsif ($state eq 'WinAddArbiter') {
&WinAddArbiter;
} elsif ($state eq 'WinAddAhb') {
&WinAddAhb;
} elsif ($state eq 'WinAddApb') {
&WinAddApb;
} elsif ($state eq 'WinCheck') {
&WinCheck;
} elsif ($state eq 'SaveConf') {
&SaveConf;
} elsif ($state eq 'ReadConf') {
&ReadConf;
} elsif ($state eq 'ResetConf') {
&ResetConf;
} else {
print "Bye!\n";
};
};
};
 
 
sub NoWinCheck {
 
@gen_signal=();
@ass_signal=();
@gen_comp=();
@gen_tbcomp=();
@gen_uut=();
$chk=0;
@tmp_chk=();
 
print "\n*******************************************\n*******************************************\n";
# check for masters:
if ($masters >= 0) {$chk++;for $j ( 0 .. $masters ) {&gen_master($master[$j]);}} else
{
print "## ERROR: No AHB Masters\n\n";
}
# check for slaves:
if ($slaves >= 0) {$chk++;} else
{
print "## ERROR: No AHB Slaves\n\n";
}
 
# check for per slaves:
if ($pslaves >= 0) {for $j ( 0 .. $pslaves ) {
&gen_pslave($pslave[$j]);}
} else {
if ($apbs >= 0) {
$chk--;
print "## ERROR: No APB Peripheralss\n\n";
}
}
 
if ($arbs >= 0) {$chk++;for $j ( 0 .. $arbs ) {&gen_arbiter($arb[$j]);}} else
{
print "## ERROR: No AHB Arbiters\n\n";
}
# CONNECTION CHECKS:
# Masters:
for $i (0 .. $masters) {$tmp_chk[$i]=0};
for $i (0 .. $ahbs) {$tmp_chk[$ahb[$i]{'mst'}]=0};
for $i (0 .. $arbs) {
@tmp_lst=split(' ',$arb[$i]{'m_list'});
foreach (@tmp_lst) {
if ($_>$#tmp_chk) {
$chk--;
print "## ERROR: MASTER $_ used in ARBITER but not declared!\n\n";
} else {
$tmp_chk[$_]++;
};
};
};
for $i (0 .. $ahbs) {
$tmp_chk[$ahb[$i]{'mst'}]+=10;
};
for $i (0 .. $#tmp_chk) {
if ($tmp_chk[$i]==0) {
$chk--;
print "## ERROR: MASTER $i not connected to any AHB ARBITER!\n\n";
} elsif ($tmp_chk[$i]>1 and $tmp_chk[$i]<10 and $i<=$masters) {
$chk--;
print "## ERROR: MASTER $i connected to more than 1 AHB ARBITER!\n\n";
} elsif ($tmp_chk[$i]>=10 and $i<=$masters) {
$chk--;
print "## ERROR: MASTER $i cannot be used as AHB BRIDGE master!\n\n";
} elsif ($tmp_chk[$i]>=20 and $i>$masters) {
$chk--;
print "## ERROR: MASTER $i used in 2 or more AHB BRIDGE!\n\n";
};
};
# Slaves:
$#tmp_chk=-1;
for $i (0 .. $slaves) {$tmp_chk[$i]=0};
for $i (0 .. $arbs) {
@tmp_lst=split(' ',$arb[$i]{'s_list'});
foreach (@tmp_lst) {
if ($_>$slaves) {
$chk--;
print "## ERROR: SLAVE $_ still not declared!\n\n";
} else {
$tmp_chk[$_]++;
};
};
};
for $i (0 .. $slaves) {
if ($tmp_chk[$i]==0) {
$chk--;
print "## ERROR: SLAVE $i not connected to any AHB ARBITER!\n\n";
};
};
for $i (0 .. $slaves) {$tmp_chk[$i]=0};
for $i (0 .. $ahbs) {
@tmp_lst=split(' ',$ahb[$i]{'s_list'});
foreach (@tmp_lst) {$tmp_chk[$_]++;}
};
for $i (0 .. $apbs) {
if ($i>$slaves) {
$chk--;
print "## ERROR: SLAVE $_ still not declared!\n\n";
} else {
$tmp_chk[$apb[$i]{'slv'}]++;
};
};
for $i (0 .. $slaves) {
if ($tmp_chk[$i]>1) {
$chk--;
print "## ERROR: SLAVE $i cannot be connected to more than 1 BRIDGE!\n\n";
};
};
 
# APB Peripherals:
$#tmp_chk=-1;
for $i (0 .. $pslaves) {$tmp_chk[$i]=0};
for $i (0 .. $apbs) {
@tmp_lst=split(' ',$apb[$i]{'list'});
foreach (@tmp_lst) {
if ($_>$pslaves) {
$chk--;
print "## ERROR: APB Peripheral $_ still not declared!\n\n";
} else {
$tmp_chk[$_]++;
};
};
};
for $i (0 .. $pslaves) {
if ($tmp_chk[$i]==0) {
$chk--;
print "## ERROR: APB Peripheral $i not assigned to any APB master!\n\n";
} elsif ($tmp_chk[$i]>1) {
$chk--;
print "## ERROR: APB Peripheral $i connected 2 or more times!\n\n";
};
};
 
# WARNINGS on missing AHBAHB and AHBAPB BRIDGES
 
if ($apbs >= 0) {
for $j ( 0 .. $apbs ) {&gen_apb($apb[$j]);}
} else {
print "** WARNING: No APB Bridges\n\n";
}
 
if ($ahbs >= 0) {for $j ( 0 .. $ahbs ) {&gen_bridge($ahb[$j]);}} else
{
print "** WARNING: No AHB/AHB Bridges\n\n";
}
 
# number '$chk' should indicate 'all checks OK!!'
if ($chk>=3) {
print "**** CHECK PASSED ****\n\n";
} else {
print "#### CHECK NOT PASSED!!\n\n"
};
};
 
 
 
 
print "\nAHB system generator version 1.0\n\n";
 
if (!defined($ENV{DSN})) {
die "Env variable DSN should point to project home\n";
}
 
#the ahb_system.vhd file is made of header, signal part, component
open(file2,">$conffile")|| die "Cannot open output file $conffile\n";
open(file3,">$matfile")|| die "Cannot open output file $matfile\n";
open(file4,">$sysfile")|| die "Cannot open output file $sysfile\n";
open(file5,">$tbfile")|| die "Cannot open output file $tbfile\n";
 
 
#USAGE: AHB_SYS_VERIF.pl [-nogui] [filename]
# if no file is specified "$DSN/scripts/ahb_generate.conf"
#open(file1,"<$infile")|| die "Cannot open ahb configuration input file $infile\n";
$tmp=shift;
if ($tmp eq "-nogui") {
$infile = shift;
open(file1,"<$infile")|| die "Cannot open ahb configuration input file $infile\n";
print "Reading configuration in $infile .....\n\n";
&ReadConf;
print "Generating configuration read by $infile .....\n\n";
&NoWinCheck;
} else {
if ($tmp ne <undef>) {
$infile=$tmp;
open(file1,"<$infile")|| die "Cannot open ahb configuration input file $infile\n";
print "Reading configuration in $infile .....\n\n";
&ReadConf;
} else {
print "No configuration read; using ahb_generate.conf as output file\n"
};
&gui_fsm;
};
 
&gen_lib();
&gen_ent();
&gen_arrays();
 
 
##### GENERATION ON CONFIGURATION FILE
print file2 @gen_conf;
 
 
##### GENERATION ON AHB_MATRIX FILE
print file3 @gen_signal;
print file3 "\nbegin\n\n";
print file3 @ass_signal;
print file3 @gen_comp;
print file3 "\nend rtl;\n\n";
 
 
 
##### GENERATION ON SLAVE COMPONENTS (in @gen_tbcomp)
$cnt=0;
foreach $item (@slv_list){
if ($item == 1) {&gen_slave($slave[$cnt]);}
$cnt++;}
#####
 
##### GENERATION ON AHB_SYSTEM FILE
print file4 @gen_signal;
print file4 @gen_ahb_signal;
print file4 "
signal dma_start : start_type_v($masters downto 0);
 
signal m_wrap_out : wrap_out_v($masters downto 0);
signal m_wrap_in : wrap_in_v($masters downto 0);
signal s_wrap_out : wrap_out_v($slaves downto 0);
signal s_wrap_in : wrap_in_v($slaves downto 0);
 
signal zero : std_logic;
signal no_conf_s : conf_type_t;
constant no_conf_c: conf_type_t:= ('0',\"0000\",\"00000000000000000000000000000000\");
 
begin
 
zero <= '0';
no_conf_s <= no_conf_c;
 
";
 
print file4 @ass_signal;
print file4 @gen_comp;
print file4 @gen_tbcomp;
print file4 "\nend rtl;\n\n";
 
 
##### GENERATION ON AHB_TB FILE
 
print file5 @gen_signal;
print file5 @gen_ahb_signal;
print file5 "
signal conf : conf_type_v($masters downto 0);
signal dma_start : start_type_v($masters downto 0);
signal eot_int : std_logic_vector($masters downto 0);
signal sim_end : std_logic_vector($masters downto 0);
 
signal m_wrap_out : wrap_out_v($masters downto 0);
signal m_wrap_in : wrap_in_v($masters downto 0);
signal s_wrap_out : wrap_out_v($slaves downto 0);
signal s_wrap_in : wrap_in_v($slaves downto 0);
 
signal hresetn: std_logic;
signal hclk: std_logic;
signal remap: std_logic;
 
signal zero : std_logic;
signal no_conf_s : conf_type_t;
constant no_conf_c: conf_type_t:= ('0',\"0000\",\"00000000000000000000000000000000\");
";
 
for $i (0 .. $masters) {
print file5 "constant stim_$i: uut_params_t:= (bits32,retry,master,'0',single,2,4,hprot_posted,$uut[$i]{\"base_addr\"},1,0,'0');\n"
}
 
print file5 "
begin
 
zero <= '0';
no_conf_s <= no_conf_c;
 
";
print file5 @ass_signal;
print file5 @gen_comp;
print file5 @gen_tbcomp;
print file5 @gen_uut;
 
print file5 "
clock_pr:process
begin
if hclk='1' then
hclk <= '0';
wait for 5 ns;
else
hclk <= '1';
wait for 5 ns;
end if;
end process;
 
reset_pr:process
begin
hresetn<= '0';
wait for 20 ns;
hresetn <= '1';
wait;
end process;
 
remap_pr:process
begin
remap <= '0';
wait for 2000 ns;
remap <= '1';
wait;
end process;
 
";
 
print file5 "assert (not(";
if ($masters >0) {
$i = $masters;
while ($i > 0) {print file5 "sim_end($i)='1' and ";$i--;}
}
print file5 "sim_end(0)='1')) report \"*** SIMULATION ENDED ***\" severity failure;\n";
print file5 "\nend rtl;\n\n";
 
 
exit;
 
/trunk/scripts/ahb_simulate.do
0,0 → 1,26
#!/bin/tcsh
if !(${?DSN}) then
echo "Please set DSN variable to design path!"
endif
if !(${?SIMULATOR}) then
echo "Please set SIMULATOR variable to 'vcom' or 'ncvhdl'!"
endif
$SIMULATOR $DSN/src/ahb_package.vhd
$SIMULATOR $DSN/src/ahb_configure.vhd
$SIMULATOR $DSN/src/ahb_funct.vhd
$SIMULATOR $DSN/src/fifo.vhd
$SIMULATOR $DSN/src/slv_mem.vhd
$SIMULATOR $DSN/src/ahb_slave_wait.vhd
$SIMULATOR $DSN/src/mst_wrap.vhd
$SIMULATOR $DSN/src/ahb_master.vhd
$SIMULATOR $DSN/src/ahb_arbiter.vhd
$SIMULATOR $DSN/src/uut_stimulator.vhd
$SIMULATOR $DSN/src/ahb_components.vhd
$SIMULATOR $DSN/src/ahb_matrix.vhd
$SIMULATOR $DSN/src/ahb_system.vhd
$SIMULATOR $DSN/src/ahb_tb.vhd
if ($SIMULATOR == ncvhdl) then
ncelab work.ahb_tb:rtl -access r
else
vsim work.ahb_tb(rtl) -t 100 ps
endif
/trunk/src/ahb_components.vhd
0,0 → 1,148
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
 
use work.ahb_package.all;
use work.ahb_funct.all;
use work.ahb_configure.all;
 
package ahb_components is
 
component fifo
generic (
fifohempty_level: in integer:= 1;
fifohfull_level: in integer:= 3;
fifo_length: in integer:= 4);
port (
hresetn: in std_logic;
clk: in std_logic;
fifo_reset: in std_logic;
fifo_write: in std_logic;
fifo_read: in std_logic;
fifo_count: out std_logic_vector(nb_bits(fifo_length)-1 downto 0);
fifo_full: out std_logic;
fifo_hfull: out std_logic;
fifo_empty: out std_logic;
fifo_hempty: out std_logic;
fifo_datain: in std_logic_vector(31 downto 0);
fifo_dataout: out std_logic_vector(31 downto 0)
);
end component;
 
component ahb_master
generic (
fifohempty_level: in integer;
fifohfull_level: in integer;
fifo_length: in integer);
port (
hresetn: in std_logic;
hclk: in std_logic;
mst_in: in mst_in_t;
mst_out: out mst_out_t;
dma_start: in start_type_t;
m_wrap_out: out wrap_out_t;
m_wrap_in: in wrap_in_t;
slv_running: in std_logic;
mst_running: out std_logic;
eot_int: out std_logic);
end component;
 
component ahb_arbiter
generic(
num_arb: in integer;
num_arb_msts: in integer range 1 to 15;
def_arb_mst: in integer range 0 to 15;
num_slvs: in integer range 1 to 15;
alg_number: in integer range 0 to 5);
port(
hresetn: in std_logic;
hclk: in std_logic;
remap: in std_logic;
mst_in_v: in mst_out_v_t(num_arb_msts-1 downto 0);
mst_out_v: out mst_in_v_t(num_arb_msts-1 downto 0);
slv_out_v: out slv_in_v_t(num_slvs-1 downto 0);
slv_in_v: in slv_out_v_t(num_slvs-1 downto 0));
end component;
 
component ahb_slave_wait
generic (
num_slv: in integer range 0 to 15:= 1;
fifohempty_level: in integer:= 2;
fifohfull_level: in integer:= 5;
fifo_length: in integer:= 8);
port(
hresetn: in std_logic;
hclk: in std_logic;
remap: in std_logic;
slv_in: in slv_in_t;
slv_out: out slv_out_t;
mst_running: in std_logic;
prior_in: in std_logic;
slv_running: out std_logic;
slv_err: out std_logic;
s_wrap_out: out wrap_out_t;
s_wrap_in: in wrap_in_t);
end component;
 
component mst_wrap
generic (
--synopsys translate_off
dump_file: in string:= "mst_wrap.log";
dump_type: in integer;
--synopsys translate_on
ahb_max_addr: in integer:= 4;
m_const_lat_write: in integer;
m_const_lat_read: in integer;
m_write_burst: in integer;
m_read_burst: in integer);
port (
hresetn: in std_logic;
clk: in std_logic;
conf: in conf_type_t;
dma_start: out start_type_t;
m_wrap_in: in wrap_out_t;
m_wrap_out: out wrap_in_t);
end component;
 
component slv_mem
generic (
--synopsys translate_off
dump_file: in string:= "slv_wrap.log";
dump_type: in integer;
--synopsys translate_on
ahb_max_addr: in integer:= 8;
s_const_lat_write: in integer;
s_const_lat_read: in integer;
s_write_burst: in integer;
s_read_burst: in integer);
port (
hresetn: in std_logic;
clk: in std_logic;
conf: in conf_type_t;
dma_start: out start_type_t;
s_wrap_in: in wrap_out_t;
s_wrap_out: out wrap_in_t
);
end component;
 
component uut_stimulator
generic (
stim_type: in uut_params_t;
enable: in integer;
eot_enable: in integer);
port(
hclk : in std_logic;
hresetn : in std_logic;
amba_error: in std_logic;
eot_int: in std_logic;
conf: out conf_type_t;
sim_end: out std_logic);
end component;
 
end;
 
package body ahb_components is
end;
 
 
 
/trunk/src/uut_stimulator.vhd
0,0 → 1,154
use STD.textio.all;--added for time and strings
 
library ieee;
use ieee.std_logic_arith.all;
use ieee.std_logic_misc.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_1164.all;
use IEEE.std_logic_textio.all;--added for time and strings
 
-- Add your library and packages declaration here ...
use work.ahb_package.all;
 
entity uut_stimulator is
generic (
stim_type: in uut_params_t:= (bits32,retry,master,'0',single,2,4,hprot_posted,2048,1,0,'0');
enable: in integer:= 0;
eot_enable: in integer:= 0);
port(
hclk : in std_logic;
hresetn : in std_logic;
amba_error: in std_logic;
eot_int: in std_logic;
conf: out conf_type_t;
sim_end: out std_logic
);
end uut_stimulator;
 
--}} End of automatically maintained section
 
architecture rtl of uut_stimulator is
signal cycle : std_logic;
signal counter: integer range 0 to 127;
 
begin
 
process
begin
if hresetn = '0' then
counter <= 1;
else
if(counter > 15) then
assert false report "* Simulator Exit.." severity warning;
sim_end <= '1';
wait;
else
sim_end <= '0';
counter <= counter+1;
end if;
end if;
 
if (eot_enable/=1) then
wait for 4000 ns;
else
wait until (eot_int='1' or amba_error='1');--write
wait until (eot_int='1' or amba_error='1');--read
end if;
end process;
 
cycle_pr:process
begin
if cycle/='1' then
cycle <= '1';
if (eot_enable/=1) then
wait for 2000 ns;
else
wait until (eot_int='1' or amba_error='1');
end if;
else
cycle <= '0';
if (eot_enable/=1) then
wait for 2000 ns;
else
wait until (eot_int='1' or amba_error='1');
end if;
end if;
end process;
 
process
variable hburst: std_logic_vector(2 downto 0);
begin
if (counter<=16) then
 
conf.write <= '0';
wait for 30 ns;
conf.write <= '1';
 
conf.addr <= dma_type_addr;
case stim_type.hburst_cycle is
when '1' =>
hburst := stim_type.hburst_tb;
when others =>
hburst := conv_std_logic_vector(counter,3);
end case;
conf.wdata <= "000000000000000000"&
stim_type.split_tb&stim_type.prior_tb&stim_type.hsize_tb&hburst&stim_type.hprot_tb&cycle&stim_type.locked_request;
wait for 10 ns;
conf.addr <= dma_extadd_addr;
--conf.wdata(31 downto 12)<=stim_type.high_addr_tb;
case stim_type.ext_addr_incr_tb is
when 1 =>--fixed ext addr
conf.wdata(31 downto 0)<= conv_std_logic_vector(stim_type.base_tb ,32);
when 2 =>--increasing by 4, page fault if base near end of slave address space
conf.wdata(31 downto 0)<= conv_std_logic_vector(stim_type.base_tb+(counter-1)*4 ,32);
when others =>--growing by incr_tb-4 (0,1,2,3,4,5, ETC.)
conf.wdata(31 downto 0)<= conv_std_logic_vector(stim_type.base_tb+(counter-1)*(stim_type.ext_addr_incr_tb-4) ,32);
end case;
wait for 10 ns;--external address
 
conf.addr <= dma_intadd_addr;
case stim_type.int_addr_incr_tb is
when 1 =>--fixed int addr
conf.wdata(31 downto 0)<= conv_std_logic_vector(stim_type.int_base_tb,32);
when 2 =>--increasing by 4, page fault if base near end of slave address space
conf.wdata(31 downto 0)<= conv_std_logic_vector(stim_type.int_base_tb+(counter-1)*4 ,32);
when others =>--growing by incr_tb-4 (0,1,2,3,4,5, ETC.)
conf.wdata(31 downto 0)<= conv_std_logic_vector(stim_type.int_base_tb+(counter-1)*(stim_type.int_addr_incr_tb-4) ,32);
end case;
wait for 10 ns;--internal address
 
conf.addr <= dma_intmod_addr;
conf.wdata <= conv_std_logic_vector(stim_type.intmod_tb ,32);
wait for 10 ns;--modifier
 
if enable=1 then
conf.addr <= dma_count_addr;
conf.wdata <= conv_std_logic_vector(counter,32);
wait for 10 ns;--dma count
else
wait for 10 ns;--dma count
end if;
 
conf.write <= '0';
conf.addr <= "0000";
conf.wdata <= (others => '-');
 
if (eot_enable/=1) then
wait until cycle'event;
else
wait until (eot_int='1' or amba_error='1');
end if;
else
wait;
end if;
--if counter=16 then wait; end if;
end process;
assert (amba_error/='1') report "###ERROR in AMBA operation!!!" severity error;
end rtl;
/trunk/src/ahb_arbiter.vhd
0,0 → 1,447
 
--*******************************************************************
--** ****
--** AHB system generator ****
--** ****
--** Author: Federico Aglietti ****
--** federico.aglietti\@opencores.org ****
--** ****
--*******************************************************************
--** ****
--** Copyright (C) 2004 Federico Aglietti ****
--** federico.aglietti\@opencores.org ****
--** ****
--** This source file may be used and distributed without ****
--** restriction provided that this copyright statement is not ****
--** removed from the file and that any derivative work contains ****
--** the original copyright notice and the associated disclaimer.****
--** ****
--** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ****
--** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ****
--** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ****
--** FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ****
--** OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ****
--** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ****
--** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ****
--** GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ****
--** BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ****
--** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ****
--** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ****
--** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ****
--** POSSIBILITY OF SUCH DAMAGE. ****
--** ****
--*******************************************************************
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
 
use work.ahb_funct.all;
use work.ahb_package.all;
use work.ahb_configure.all;
--use work.ahb_matrix.all;
 
entity ahb_arbiter is
generic(
num_arb: in integer:= 2;
num_arb_msts: in integer range 1 to 15:= 4;
def_arb_mst: in integer range 0 to 15:= 2;
num_slvs: in integer range 1 to 15:= 3;
alg_number: in integer range 0 to 5:= 2);
port(
hresetn: in std_logic;
hclk: in std_logic;
remap: in std_logic;
mst_in_v: in mst_out_v_t(num_arb_msts-1 downto 0);
mst_out_v: out mst_in_v_t(num_arb_msts-1 downto 0);
slv_out_v: out slv_in_v_t(num_slvs-1 downto 0);
slv_in_v: in slv_out_v_t(num_slvs-1 downto 0));
end;
 
 
architecture rtl of ahb_arbiter is
 
--*******************************************************************
--******************** SIGNAL DECLARATION ***************************
--*******************************************************************
 
signal s_grant_master, grant_master: integer range 0 to 15;
signal s_master_sel, master_sel: std_logic_vector(3 downto 0);
signal s_r_master_sel, r_master_sel: std_logic_vector(3 downto 0);
signal r_master_busy: std_logic_vector(1 downto 0);
 
signal turn, s_turn: integer range 0 to num_arb_msts-1;
signal random: integer range 0 to 2**(nb_bits(num_arb_msts));
signal seed, s_seed: std_logic_vector(9 downto 0);
 
type vecran is array (2**(nb_bits(num_arb_msts)) downto 0) of integer;
signal vect_ran: vecran;
signal vect_ran_round: vecran;
 
 
signal haddr_page: std_logic_vector(31 downto 0);
signal htrans_reg: std_logic_vector(1 downto 0);--"00"|"01"|"10"
signal hsel: std_logic_vector(num_slvs-1 downto 0);
 
 
signal s_dec_hready: std_logic;
signal req_ored: std_logic;
signal hbusreq_msk: std_logic_vector(num_arb_msts-1 downto 0);
 
signal split_reg: std_logic_vector(num_arb_msts-1 downto 0);
 
signal r_slv_in_v: slv_in_v_t(num_slvs-1 downto 0);
signal mst_in_sel: slv_in_t;
signal slv_in_sel: mst_in_t;
 
--DEAFULT SLAVE BEHAVIOUR
 
signal r_def_slave_hsel, def_slave_hsel: std_logic;
signal def_slave_hready: std_logic;
 
signal addr_arb_matrix: addr_matrix_t(0 downto 0);
 
--*******************************************************************
--***************** END OF SIGNAL DECLARATION ************************
--*******************************************************************
 
begin
 
addr_arb_matrix(0)(num_slvs-1 downto 0) <= arb_matrix(num_arb)(num_slvs-1 downto 0) when (remap='0') else rarb_matrix(num_arb)(num_slvs-1 downto 0);
 
req_ored_pr:process(hbusreq_msk)
variable v_req_ored: std_logic;
begin
v_req_ored := '0';
for i in 0 to num_arb_msts-1 loop
v_req_ored := v_req_ored or hbusreq_msk(i);
end loop;
req_ored <= v_req_ored;
end process;
 
bus_req_mask_pr:process(split_reg, grant_master, mst_in_v)
begin
for i in 0 to num_arb_msts-1 loop
if (mst_in_v(i).htrans=busy or split_reg(i)='1' or (grant_master/=num_arb_msts and grant_master/=i and mst_in_v(grant_master).hlock='1')) then
hbusreq_msk(i) <= '0';
else
hbusreq_msk(i) <= mst_in_v(i).hbusreq;
end if;
end loop;
end process;
 
 
--********************************************************
-- synchronization processes (flip flops)
--********************************************************
s_master_sel <= conv_std_logic_vector(s_grant_master, 4) when (s_dec_hready='1') else master_sel;
s_r_master_sel <= master_sel when (s_dec_hready='1' and htrans_reg/=busy) else r_master_sel;
 
master_pr:process(hresetn, hclk)
begin
if hresetn='0' then
grant_master <= def_arb_mst;
master_sel <= conv_std_logic_vector(def_arb_mst, 4);
r_master_sel <= conv_std_logic_vector(def_arb_mst, 4);
turn <= 0;
htrans_reg <= idle;
elsif hclk'event and hclk='1' then
grant_master <= s_grant_master after 1 ns;
master_sel <= s_master_sel after 1 ns;
r_master_sel <= s_r_master_sel after 1 ns;
turn <= s_turn after 1 ns;
if conv_integer(master_sel) /= num_arb_msts then
htrans_reg <= mst_in_sel.htrans after 1 ns;
else
htrans_reg <= idle;
end if;
end if;
end process;
 
update_pr:process(
req_ored,
hbusreq_msk,
grant_master,
mst_in_v,
htrans_reg,
mst_in_sel,
slv_in_sel,
split_reg,
turn,
random)
variable t_turn, t_grant_master: integer;
begin
t_turn := turn;
t_grant_master := grant_master;
--nohready=> grant no change
--hready&busy(real master)=> grant no change
--hready&nobusy&req => arbitration
--hready&nobusy&noreq&default master not splitted => default master
--hready&nobusy&noreq&default master splitted => dummy master
if (slv_in_sel.hready='1') then
if ((grant_master/=num_arb_msts and mst_in_v(grant_master).htrans/=busy and htrans_reg/=busy) or (grant_master=num_arb_msts)) then
if (req_ored='1') then
case alg_number is
when 0 => --fixed
fixed_priority(t_turn, t_grant_master, hbusreq_msk, turn);
when 1 => --round robin
round_robin(def_arb_mst, t_turn, t_grant_master, hbusreq_msk, turn);
when 2 => --random
random_priority(def_arb_mst, t_turn, t_grant_master, random, hbusreq_msk, turn);
when 3 => --fair1
if (grant_master/=num_arb_msts and hbusreq_msk(grant_master)='0') or (grant_master=num_arb_msts) then
fixed_priority(t_turn, t_grant_master, hbusreq_msk, turn);
end if;
when 4 => --fair2
if (grant_master/=num_arb_msts and hbusreq_msk(grant_master)='0') or (grant_master=num_arb_msts) then
round_robin(def_arb_mst, t_turn, t_grant_master, hbusreq_msk, turn);
end if;
when 5 => --fair3
if (grant_master/=num_arb_msts and hbusreq_msk(grant_master)='0') or (grant_master=num_arb_msts) then
random_priority(def_arb_mst, t_turn, t_grant_master, random, hbusreq_msk, turn);
end if;
when others => --NOT IMPLEMENTED
assert FALSE report "### NOT IMPLEMENTED!" severity FAILURE;
end case;
elsif (split_reg(def_arb_mst)='0') then--ready+no_busy+no_req=> default if not splitted!!
t_grant_master := def_arb_mst;
t_turn := def_arb_mst;
else--ready+no_busy+no_req+def_master splitted => dummy_master!!
t_grant_master := num_arb_msts;
end if;
--else (busy) then SAME MASTER
end if;
--else (no_ready) then SAME MASTER
end if;
s_grant_master <= t_grant_master;
s_turn <= t_turn;
end process;
 
s_seed_pr:process(seed)
begin
for i in 9 downto 1 loop
s_seed(i) <= seed(i-1);
end loop;
s_seed(0) <= not(seed(9) xor seed(6));
end process;
 
seed_pr:process(hresetn, hclk)
variable v_random: integer range 0 to 2**(nb_bits(num_arb_msts));
begin
if hresetn='0' then
seed <= (others => '0');--"1101010001";
random <= 0;
--synopsys translate_off
for i in 0 to 2**(nb_bits(num_arb_msts)) loop
vect_ran(i) <= 0;
vect_ran_round(i) <= 0;
end loop;
--synopsys translate_on
elsif hclk'event and hclk='1' then
seed <= s_seed after 1 ns;
v_random := conv_integer(seed(nb_bits(num_arb_msts)+3 downto 4));
if v_random < num_arb_msts then
random <= v_random after 1 ns;
else
random <= turn after 1 ns;--(v_random - num_arb_msts);
end if;
--synopsys translate_off
vect_ran(v_random) <= vect_ran(v_random) + 1;
vect_ran_round(random) <= vect_ran_round(random) + 1;
--synopsys translate_on
end if;
end process;
 
 
 
--synopsys translate_off
assert not (hclk'event and hclk='1' and master_sel=num_arb_msts) report "DUMMY MASTER selection!!!" severity WARNING;
assert not (hclk'event and hclk='1' and master_sel=def_arb_mst) report "DEFAULT MASTER selection!!!" severity WARNING;
assert not (hclk'event and hclk='1' and (master_sel>num_arb_msts or r_master_sel>num_arb_msts)) report "####ERROR in MASTER selection!!!" severity FAILURE;
--synopsys translate_on
 
 
--*********************************************************
-- MASTER MUXES
--*********************************************************
 
add_pr:process(master_sel, r_master_sel, mst_in_v)
variable def_addr: std_logic_vector(31 downto 0);
begin
 
haddr_page(31 downto 10) <= mst_in_v(def_arb_mst).haddr(31 downto 10);
 
mst_in_sel.hwdata <= mst_in_v(def_arb_mst).hwdata;
mst_in_sel.haddr <= mst_in_v(def_arb_mst).haddr;
mst_in_sel.hwrite <= mst_in_v(def_arb_mst).hwrite;
mst_in_sel.hsize <= mst_in_v(def_arb_mst).hsize;
mst_in_sel.hburst <= mst_in_v(def_arb_mst).hburst;
mst_in_sel.hprot <= mst_in_v(def_arb_mst).hprot;
mst_in_sel.htrans <= mst_in_v(def_arb_mst).htrans;
for i in 0 to num_arb_msts-1 loop
if i=conv_integer(r_master_sel) then
mst_in_sel.hwdata <= mst_in_v(i).hwdata;
end if;
if i=conv_integer(master_sel) then
haddr_page(31 downto 10) <= mst_in_v(i).haddr(31 downto 10);
mst_in_sel.haddr <= mst_in_v(i).haddr;
mst_in_sel.hwrite <= mst_in_v(i).hwrite;
mst_in_sel.hsize <= mst_in_v(i).hsize;
mst_in_sel.hburst <= mst_in_v(i).hburst;
mst_in_sel.hprot <= mst_in_v(i).hprot;
mst_in_sel.htrans <= mst_in_v(i).htrans;
end if;
end loop;
if master_sel=num_arb_msts then
mst_in_sel.htrans <= idle;
end if;
end process;
 
process(slv_in_sel, s_grant_master)--N.B.: Request=>Grant comb. path!
begin
for i in 0 to num_arb_msts-1 loop
mst_out_v(i).hready <= slv_in_sel.hready;
mst_out_v(i).hresp <= slv_in_sel.hresp;
mst_out_v(i).hrdata <= slv_in_sel.hrdata;
if (s_grant_master=i) then
mst_out_v(i).hgrant <= '1';
else
mst_out_v(i).hgrant <= '0';
end if;
end loop;
end process;
 
--*********************************************************
-- SLAVE MUXES
--*********************************************************
 
process(hresetn, hclk)
variable v_hready: std_logic;
begin
if hresetn='0' then
for i in num_slvs-1 downto 0 loop
r_slv_in_v(i).hsel <= '0';
end loop;
elsif hclk='1' and hclk'event then
if s_dec_hready='1' then
r_def_slave_hsel <= def_slave_hsel;
for i in num_slvs-1 downto 0 loop
r_slv_in_v(i).hsel <= hsel(i) after 1 ns;
end loop;
end if;
end if;
end process;
 
process(r_slv_in_v, slv_in_v, def_slave_hready)
begin
s_dec_hready <= def_slave_hready;
for i in num_slvs-1 downto 0 loop
if(r_slv_in_v(i).hsel='1') then
s_dec_hready <= slv_in_v(i).hready;
end if;
end loop;
-- hready_t <= slv_in_v(num_slvs).hready;--ready ....
slv_in_sel.hready <= def_slave_hready;
slv_in_sel.hrdata <= (others => '-');--for LOW POWER!!!
slv_in_sel.hresp <= error_resp;--.... and ERROR ....
for i in num_slvs-1 downto 0 loop
if r_slv_in_v(i).hsel='1' then
-- hready_t <= slv_in_v(i).hready;
slv_in_sel.hready <= slv_in_v(i).hready;
slv_in_sel.hresp <= slv_in_v(i).hresp;
slv_in_sel.hrdata <= slv_in_v(i).hrdata;
end if;
end loop;
end process;
 
 
--*********************************************************
-- SPLIT handling
--*********************************************************
 
process(hresetn, hclk)
variable v_split_reg: std_logic_vector(num_arb_msts-1 downto 0);
begin
if hresetn='0' then
split_reg <= (others => '0');
elsif hclk'event and hclk='1' then
v_split_reg := split_reg;
for j in num_slvs-1 downto 0 loop
for i in num_arb_msts-1 downto 0 loop
v_split_reg(i) := v_split_reg(i) and not slv_in_v(j).hsplit(i);
end loop;
if (r_slv_in_v(j).hsel='1') then
if (slv_in_v(j).hready='1' and slv_in_v(j).hresp=split_resp and master_sel/=num_arb_msts) then
v_split_reg(conv_integer(master_sel)) := '1';
end if;
end if;
end loop;
split_reg <= v_split_reg after 1 ns;
end if;
end process;
 
--*********************************************************
-- AHB DECODER
--*********************************************************
-- min 1KB of address space for each slave:
process(haddr_page, master_sel, mst_in_v, mst_in_sel, s_dec_hready, addr_arb_matrix)
variable addr_low_std : std_logic_vector(31 downto 0);
variable addr_high_std : std_logic_vector(31 downto 0);
variable v_hmastlock: std_logic;
begin
v_hmastlock := '0';
for i in num_arb_msts-1 downto 0 loop
if (v_hmastlock='0' and master_sel=conv_std_logic_Vector(i,4) and mst_in_v(i).hlock='1') then
v_hmastlock := '1';
end if;
end loop;
def_slave_hsel <= '1'; --default slave selected
for i in num_slvs-1 downto 0 loop
slv_out_v(i).hmastlock <= v_hmastlock;
slv_out_v(i).haddr <= mst_in_sel.haddr;
slv_out_v(i).hmaster <= master_sel;
slv_out_v(i).hready <= s_dec_hready;
slv_out_v(i).hwrite <= mst_in_sel.hwrite;
slv_out_v(i).hwdata <= mst_in_sel.hwdata;
slv_out_v(i).hsize <= mst_in_sel.hsize;
slv_out_v(i).hburst <= mst_in_sel.hburst;
slv_out_v(i).hprot <= mst_in_sel.hprot;
slv_out_v(i).htrans <= mst_in_sel.htrans;
addr_low_std := conv_std_logic_vector(addr_arb_matrix(0)(i).low, 32);
addr_high_std := conv_std_logic_vector(addr_arb_matrix(0)(i).high, 32);
if (haddr_page(31 downto 10) >= addr_low_std(31 downto 10) and (haddr_page(31 downto 10) <= addr_high_std(31 downto 10))) then
hsel(i) <= '1';
def_slave_hsel <= '0';
slv_out_v(i).hsel <= '1';
else
hsel(i) <= '0';
slv_out_v(i).hsel <= '0';
end if;
end loop;
end process;
 
 
--DEFAULT SLAVE BEHAVIOUR
 
process(hresetn, hclk)
begin
if hresetn='0' then
def_slave_hready <= '1';
elsif hclk'event and hclk='1' then
if (def_slave_hsel='1' and s_dec_hready='1' and mst_in_sel.htrans/=idle) then
def_slave_hready <= '0' after 1 ns;
else
def_slave_hready <= '1' after 1 ns;
end if;
end if;
end process;
 
 
 
--synopsys translate_off
assert not(hclk'event and hclk='1' and r_def_slave_hsel='1') report "####ERROR: NO SLAVE SELECTED!!!" severity error;
--synopsys translate_on
 
end rtl;
/trunk/src/slv_mem.vhd
0,0 → 1,229
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_misc.all;
use ieee.std_logic_arith.all;
 
use std.textio.all;
 
use work.ahb_package.all;
 
entity slv_mem is
generic (
--synopsys translate_off
dump_file: in string:= "slv_wrap.log";
dump_type: in integer:= dump_no;
--synopsys translate_on
ahb_max_addr: in integer:= 8;
--***************************************************************
--parameters for slave access
--***************************************************************
s_const_lat_write: in integer:= 1;--1 cycle to save data
s_const_lat_read: in integer:= 2;--2 cycles to retreave data
s_write_burst: in integer := no_burst_support;--slave doesn't accept bursts in write!!!
s_read_burst: in integer:= no_burst_support--slave doesn't accept bursts in read!!!
);
port (
hresetn: in std_logic;
clk: in std_logic;
conf: in conf_type_t;
dma_start: out start_type_t;
s_wrap_in: in wrap_out_t;
s_wrap_out: out wrap_in_t);
end slv_mem;
 
architecture rtl of slv_mem is
 
--synopsys translate_off
--***************************************************************
--**** DUMP OF MEMORY *******************************************
--***************************************************************
file file_descriptor : TEXT open write_mode is dump_file;
constant msg1: string(1 to 4):= "MEM ";
constant msg2: string(1 to 4):= "REG ";
constant msg3: string(1 to 5):= "DATA ";
procedure Write_Message(msg1:string; addr:in integer; msg2:string; value:in integer) is
variable STR : line;
begin
write(STR,now);
write(STR,STRING'(" "));
write (STR, msg1);
write (STR, addr);
write(STR,STRING'(" "));
write (STR, msg2);
write (STR, value);
writeLine(file_descriptor, STR);
writeLine(OUTPUT, STR);
end Write_Message;
--***************************************************************
--***************************************************************
--synopsys translate_on
 
--***************************************************************
--configuration registers
--***************************************************************
signal start_hprot: std_logic_vector(3 downto 0);
signal start_hsize: std_logic_Vector(2 downto 0);
signal start_hburst: std_logic_Vector(2 downto 0);
signal start_hwrite: std_logic;
signal start_hlocked: std_logic;
signal start_prior: std_logic;
signal hsize_reg: std_logic_Vector(2 downto 0);
signal priority_reg: std_logic;
signal hburst_reg: std_logic_Vector(2 downto 0);
signal hprot_reg: std_logic_Vector(3 downto 0);
signal hlock_reg: std_logic;
signal trx_dir_reg: std_logic;
signal extaddr: std_logic_Vector(31 downto 0);
signal intaddr: std_logic_Vector(15 downto 0);
signal intmod: std_logic_Vector(15 downto 0);
signal count_reg: std_logic_Vector(15 downto 0);
signal dma_go: std_logic;
--***************************************************************
--***************************************************************
 
type vect_32 is array (2**ahb_max_addr-1 downto 0) of std_logic_vector (31 downto 0);
signal mem : vect_32;
 
 
 
signal s_lat_write_ok, s_lat_read_ok: std_logic;
signal s_lat_write: integer range 0 to s_const_lat_write;
signal s_lat_read: integer range 0 to s_const_lat_read;
--***************************************************************
--***************************************************************
 
 
begin
 
--***************************************************************
--***************************************************************
--** slave part: could be a memory, fifo or register bank *******
--** here it's only a configuration register bank ***************
--***************************************************************
 
process(clk, hresetn)
begin
if hresetn='0' then
for i in 0 to 2**ahb_max_addr-1 loop
mem(i) <= conv_std_logic_vector(i, 32);
end loop;--i
elsif clk'event and clk='1' then
if (s_wrap_in.take='1' and s_lat_write_ok='1') then
mem(conv_integer(s_wrap_in.addr(ahb_max_addr-1+2 downto 2))) <= s_wrap_in.wdata after 1 ns;
--synopsys translate_off
if dump_type/=dump_no then Write_Message(msg1, conv_integer(s_wrap_in.addr(ahb_max_addr-1+2 downto 2)), msg3, conv_integer(s_wrap_in.wdata)); end if;
--synopsys translate_on
end if;
end if;
end process;
 
s_wrap_out.rdata <= mem(conv_integer(s_wrap_in.addr(ahb_max_addr-1+2 downto 2))) when (s_wrap_in.ask='1' and s_lat_read_ok='1') else (others => '-');
 
 
process(clk, hresetn)
begin
if hresetn='0' then
s_lat_write <= s_const_lat_write;
elsif clk'event and clk='1' then
if (s_wrap_in.take='1') then
if (s_lat_write_ok='0') then
s_lat_write <= s_lat_write-1 after 1 ns;
elsif (s_write_burst=1) then--accepts bursts .....
s_lat_write <= 0 after 1 ns;
else
s_lat_write <= s_const_lat_write after 1 ns;
end if;
else
s_lat_write <= s_const_lat_write after 1 ns;
end if;
end if;
end process;
 
s_lat_write_ok <= '1' when (s_lat_write=0) else '0';
s_wrap_out.take_ok <= '1' when (s_wrap_in.take='1' and s_lat_write_ok='1') else '0';
process(clk, hresetn)
begin
if hresetn='0' then
s_lat_read <= s_const_lat_read;
elsif clk'event and clk='1' then
if (s_wrap_in.ask='1') then
if (s_lat_read_ok='0') then
s_lat_read <= s_lat_read-1 after 1 ns;
elsif (s_read_burst=1) then--accepts bursts .....
s_lat_read <= 0 after 1 ns;
else
s_lat_read <= s_const_lat_read after 1 ns;
end if;
else
s_lat_read <= s_const_lat_read after 1 ns;
end if;
end if;
end process;
 
s_lat_read_ok <= '1' when (s_lat_read=0) else '0';
s_wrap_out.ask_ok <= '1' when (s_wrap_in.ask='1' and s_lat_read_ok='1') else '0';
 
--**************************************************************************
-- configuration registers write
--**************************************************************************
 
conf_reg_pr:process(hresetn, clk)
variable addr: std_logic_Vector(3 downto 0);
begin
if hresetn='0' then
hsize_reg <= bits32;
priority_reg <= slave;
hburst_reg <= incr;
hprot_reg <= "0011";
trx_dir_reg <= '0';
hlock_reg <= locked;
extaddr <= zeroes;
intaddr <= zeroes(15 downto 0);
intmod <= conv_std_logic_vector(4, intmod'length);--mod=+4(+1 word32)
count_reg <= zeroes(15 downto 0);
dma_go <= '0';
elsif clk'event and clk='1' then
if (conf.write='1') then
case conf.addr is
when dma_extadd_addr =>
extaddr <= conf.wdata;
when dma_intadd_addr =>
intaddr <= conf.wdata(15 downto 0);
when dma_intmod_addr =>
intmod <= conf.wdata(15 downto 0);
when dma_type_addr =>
priority_reg <= conf.wdata(12);
hsize_reg <= conf.wdata(11 downto 9);
hburst_reg <= conf.wdata(8 downto 6);
hprot_reg <= conf.wdata(5 downto 2);
trx_dir_reg <= conf.wdata(1);
hlock_reg <= conf.wdata(0);
when dma_count_addr =>
count_reg <= conf.wdata(15 downto 0);
when others => null;
end case;
end if;
if (conf.write='1' and conf.addr=dma_count_addr) then
dma_go <= '1';
else
dma_go <= '0';
end if;
end if;
end process;
--**************************************************************************
--**************************************************************************
 
--**************************************************************************
--**************************************************************************
dma_start.extaddr <= extaddr;
dma_start.intaddr <= intaddr;
dma_start.intmod <= intmod;
dma_start.hparams <= "000"&priority_reg&hsize_reg&hburst_reg&hprot_reg&trx_dir_reg&hlock_reg;
dma_start.count <= count_reg;
dma_start.start <= dma_go;
 
end rtl;
/trunk/src/fifo.vhd
0,0 → 1,85
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_misc.all;
use ieee.std_logic_arith.all;
 
use work.ahb_funct.all;
use work.ahb_package.all;
 
entity fifo is
generic (
fifohempty_level: in integer:= 1;
fifohfull_level: in integer:= 3;
fifo_length: in integer:= 4);
port (
hresetn: in std_logic;
clk: in std_logic;
fifo_reset: in std_logic;
fifo_write: in std_logic;
fifo_read: in std_logic;
fifo_count: out std_logic_vector(nb_bits(fifo_length)-1 downto 0);
fifo_full: out std_logic;
fifo_hfull: out std_logic;
fifo_empty: out std_logic;
fifo_hempty: out std_logic;
fifo_datain: in std_logic_vector(31 downto 0);
fifo_dataout: out std_logic_vector(31 downto 0)
);
end fifo;
 
architecture rtl of fifo is
 
 
 
signal fifo_full_s, fifo_empty_s: std_logic;
signal fifo_count_s : std_logic_vector(nb_bits(fifo_length)-1 downto 0);--log2 fifo_length + 1
signal rptr, wptr: std_logic_vector(nb_bits(fifo_length)-1 downto 0);
type vect_fifo_32 is array (fifo_length-1 downto 0) of std_logic_vector (31 downto 0);
signal fifo : vect_fifo_32;
 
 
begin
fifo_wr_pr:process(clk, hresetn)
begin
if hresetn='0' then
wptr <= (others => '0');
elsif clk'event and clk='1' then
if fifo_reset='1' then
wptr <= (others => '0') after 1 ns;
elsif (fifo_write='1') then
fifo(conv_integer(wptr(wptr'length-2 downto 0))) <= fifo_datain after 1 ns;
wptr <= wptr+1 after 1 ns;
end if;
end if;
end process;
fifo_rd_pr:process(clk, hresetn)
begin
if hresetn='0' then
rptr <= (others => '0');
elsif clk'event and clk='1' then
if fifo_reset='1' then
rptr <= (others => '0') after 1 ns;
elsif (fifo_read='1') then
rptr <= rptr+1 after 1 ns;
end if;
end if;
end process;
fifo_dataout <= fifo(conv_integer(rptr(rptr'length-2 downto 0)));--data from fifo visible
 
fifo_count_s <= wptr(wptr'length-1 downto 0) - rptr(rptr'length-1 downto 0);
fifo_full_s <= '1' when (fifo_count_s=fifo_length) else '0';--same value,/=msb
fifo_empty_s <= '1' when (fifo_count_s=0) else '0';--same value,==msb
 
fifo_hfull <= '1' when (fifo_count_s>=fifohfull_level) else '0';
fifo_hempty <= '1' when (fifo_count_s<=fifohempty_level) else '0';
fifo_full <= fifo_full_s;
fifo_empty <= fifo_empty_s;
fifo_count <= fifo_count_s;
 
end rtl;
/trunk/src/ahb_master.vhd
0,0 → 1,687
 
--*******************************************************************
--** ****
--** AHB system generator ****
--** ****
--** Author: Federico Aglietti ****
--** federico.aglietti\@opencores.org ****
--** ****
--*******************************************************************
--** ****
--** Copyright (C) 2004 Federico Aglietti ****
--** federico.aglietti\@opencores.org ****
--** ****
--** This source file may be used and distributed without ****
--** restriction provided that this copyright statement is not ****
--** removed from the file and that any derivative work contains ****
--** the original copyright notice and the associated disclaimer.****
--** ****
--** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ****
--** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ****
--** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ****
--** FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ****
--** OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ****
--** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ****
--** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ****
--** GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ****
--** BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ****
--** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ****
--** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ****
--** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ****
--** POSSIBILITY OF SUCH DAMAGE. ****
--** ****
--*******************************************************************
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_misc.all;
use ieee.std_logic_arith.all;
 
use work.ahb_funct.all;
use work.ahb_package.all;
 
entity ahb_master is
generic (
fifohempty_level: in integer:= 2;
fifohfull_level: in integer:= 6;
fifo_length: in integer:= 8);
port (
--***********************************************
--master ahb amba signals
--***********************************************
hresetn: in std_logic;
hclk: in std_logic;
mst_in: in mst_in_t;
mst_out: out mst_out_t;
--***********************************************
--master<=>core interface: conf registers
--***********************************************
dma_start: in start_type_t;
--***********************************************
--master<=>core interface: program/data memories
--***********************************************
m_wrap_out: out wrap_out_t;
m_wrap_in: in wrap_in_t;
 
--***********************************************
--master/slave/core signals
--***********************************************
slv_running: in std_logic;
mst_running: out std_logic;
eot_int: out std_logic
);
end ahb_master;
 
architecture rtl of ahb_master is
 
--***************************************************************
--component declaration
--***************************************************************
component fifo
generic (
fifohempty_level: in integer:= 1;
fifohfull_level: in integer:= 7;
fifo_length: in integer:= 8);
port (
hresetn: in std_logic;
clk: in std_logic;
fifo_reset: in std_logic;
fifo_write: in std_logic;
fifo_read: in std_logic;
fifo_count: out std_logic_vector(nb_bits(fifo_length)-1 downto 0);
fifo_full: out std_logic;
fifo_hfull: out std_logic;
fifo_empty: out std_logic;
fifo_hempty: out std_logic;
fifo_datain: in std_logic_vector(31 downto 0);
fifo_dataout: out std_logic_vector(31 downto 0)
);
end component;
 
 
--***************************************************************
--configuration registers
--***************************************************************
signal start_hprot: std_logic_vector(3 downto 0);
signal start_hsize: std_logic_Vector(2 downto 0);
signal start_hburst: std_logic_Vector(2 downto 0);
signal start_hwrite: std_logic;
signal start_hlocked: std_logic;
signal start_prior: std_logic;
 
signal hbusreq_t, hlock_t: std_logic;
--***************************************************************
--***************************************************************
signal r_mst_in, s_mst_in: mst_in_t;
signal r_mst_out, s_mst_out: mst_out_t;
 
 
type master_fsm is (
idle_phase,
wait_phase,
req_phase,
addr, --A
addr_data,--A+D
data, --D
retry_phase,
error_phase,
be_phase);
signal mst_state, s_mst_state: master_fsm;
 
 
signal fifo_full, fifo_hfull, fifo_empty, fifo_hempty: std_logic;
signal fifo_count: std_logic_vector(nb_bits(fifo_length)-1 downto 0);
signal fifo_datain, fifo_dataout: std_logic_vector (31 downto 0);
signal fifo_hread, fifo_hwrite: std_logic;
signal fifo_read, fifo_write: std_logic;
signal fifo_reset: std_logic;
signal next_fifo_empty: std_logic;
 
signal dma_count: std_logic_vector (15 downto 0);
signal dma_count_s : std_logic_vector (15 downto 0);
signal right_count: std_logic_vector(15 downto 0);
signal data_trx: std_logic;
signal tmp_htrans: std_logic_vector(1 downto 0);
 
 
signal next_fifo_full: std_logic;
signal next_fifo_he: std_logic;
signal next_fifo_hf: std_logic;
 
signal mst_running_t:std_logic;
signal dma_restart: std_logic;
signal mst_req: std_logic;
signal granted: std_logic;
 
signal eot_int_reg:std_logic;
signal prior_reg, prior_s: std_logic;
 
signal int_addr, int_addr_s, int_addr_t : std_logic_vector (31 downto 0);
signal int_mod, int_mod_s : std_logic_vector (15 downto 0);
signal int_page_fault: std_logic;
signal int_addr_incr: std_logic;
 
signal page_attention: std_logic;
signal page_fault: std_logic;
signal pf_incr, pf_wrap4, pf_wrap8, pf_wrap16: std_logic;
 
signal haddr_t : std_logic_vector (31 downto 0);
signal haddr_incr: std_logic;
 
signal old_page_attention: std_logic;
signal old_addr_incr: std_logic;
signal old_addr, old_addr_s: std_logic_vector (31 downto 0);
signal old_hburst, old_hburst_s: std_logic_Vector(2 downto 0);
 
begin
 
--***************************************************************
--component instantiation
--***************************************************************
fifo_inst: fifo
generic map(
fifohempty_level => fifohempty_level,
fifohfull_level => fifohfull_level,
fifo_length => fifo_length)
port map(
hresetn => hresetn,
clk => hclk,
fifo_reset => fifo_reset,
fifo_write => fifo_write,
fifo_read => fifo_read,
fifo_count => fifo_count,
fifo_full => fifo_full,
fifo_hfull => fifo_hfull,
fifo_empty => fifo_empty,
fifo_hempty => fifo_hempty,
fifo_datain => fifo_datain,
fifo_dataout => fifo_dataout
);
--***************************
--****** master state *******
--***************************
master_pr:process(
mst_state,
mst_req,
slv_running,
prior_reg,
dma_count,
hbusreq_t,
fifo_empty,
page_fault,
r_mst_out,
mst_in
)
begin
s_mst_state <= mst_state;
case mst_state is
when idle_phase =>
if (dma_count>0 and (slv_running='0' or prior_reg=master)) then
s_mst_state <= wait_phase;
end if;
when wait_phase =>
if mst_req='1' then
s_mst_state <= req_phase;
end if;
when req_phase =>
if (hbusreq_t='1' and mst_in.hgrant='1' and mst_in.hready='1') then--master take bus ownership
s_mst_state <= addr;
end if;
when addr =>
if (mst_in.hready='1') then
if (page_fault='1' or mst_in.hgrant='0' or dma_count=1) then
s_mst_state <= data;
else
s_mst_state <= addr_data;
end if;
end if;
when addr_data =>
--end of transfer: ready+ok+no_busy_reg+count=1(idle/preidle or burstend)
--page fault:ready+ok+no_busy_reg+count>1 (page_fault)
--no_grant:ready+ok+busy+no_grant (page_fault)
--retry/split:no_ready+retry/split (retry)
--error:no_ready+error (error)
if (mst_in.hready='1') then
if (mst_in.hresp=ok_resp) then
if (r_mst_out.htrans/=busy) then
if (dma_count=1) then
if (r_mst_out.hwrite='1') then
s_mst_state <= data;
else --r_mst_out.hwrite='0', count>1
s_mst_state <= data;--be_phase;
end if;
elsif (page_fault='1' or mst_in.hgrant='0') then
s_mst_state <= data;
end if;
else -- r_mst_out.htrans=busy
if (mst_in.hgrant='0') then
assert false report "Protocol error: GRANT deasserted during BUSY!!!" severity error;
s_mst_state <= data;
end if;
end if;
end if;
else--hready='0'
case mst_in.hresp is
when retry_resp|split_resp =>
s_mst_state <= retry_phase;
when error_resp =>
s_mst_state <= error_phase;
when others =>
s_mst_state <= addr_data;
end case;
end if;
when data=>
if (mst_in.hready='1') then
if (mst_in.hresp=ok_resp and r_mst_out.htrans/=busy) then
if (dma_count=0) then
if (r_mst_out.hwrite='1') then
s_mst_state <= idle_phase;
else --r_mst_out.hwrite='0', count>1
s_mst_state <= be_phase;
end if;
else--collapse all this 'if-else'
if (r_mst_out.hwrite='1') then
s_mst_state <= idle_phase;
else
s_mst_state <= be_phase;
end if;
end if;
end if;
else
case mst_in.hresp is
when retry_resp|split_resp =>
s_mst_state <= retry_phase;--pay attention: grant removed and retry issued!!!!!!
when error_resp =>
s_mst_state <= error_phase;
when others =>
s_mst_state <= data;
end case;
end if;
when retry_phase =>
if (mst_in.hready='1') then
s_mst_state <= idle_phase;
end if;
when error_phase =>
if mst_in.hready='1' then
s_mst_state <= idle_phase;
end if;
when be_phase =>--one of more cycle to empty fifo, settling core internal state
if (fifo_empty ='1') then
s_mst_state <= idle_phase;
end if;
when others => null;
end case;
end process;
 
--synopsys translate_off
assert not (hclk'event and hclk='1' and (mst_state=addr_data or mst_state=data) and (mst_in.hready='1' and mst_in.hresp/=ok_resp))
report "####PROTOCOL ERROR: in addr_data error/retry/split&&ready!!!!!"
severity error;
--synopsys translate_on
 
process(hresetn, hclk)
begin
if hresetn='0' then
mst_state <= idle_phase;
elsif hclk'event and hclk='1' then
mst_state <= s_mst_state after 1 ns;
end if;
end process;
 
start_hlocked <= dma_start.hparams(0);
start_hwrite <= dma_start.hparams(1);
start_hprot <= dma_start.hparams(5 downto 2);
start_hburst <= dma_start.hparams(8 downto 6);
start_hsize <= dma_start.hparams(11 downto 9);
start_prior <= dma_start.hparams(12);
 
--***************************
--********** htrans *********
--***************************
--busy if:
--write:
--count>1 and fifo=1 and trans_reg/=busy and addr_data
--count=1 and fifo_empty and addr_data
--read:
--fifo_hfull and addr_data
s_mst_out.htrans <= tmp_htrans;
 
tmp_htrans <=
--busy when (mst_state=addr_data and granted='1' and page_fault='0' and dma_count>=2 and ((next_fifo_he='1' and r_mst_out.hwrite='1') or (next_fifo_hf='1' and r_mst_out.hwrite='0'))) else
busy when (mst_state=addr_data and (
(dma_count>=2 and ((fifo_count<=1 and r_mst_out.hwrite='1') or (fifo_count>=fifo_length-1 and r_mst_out.hwrite='0'))) or
(dma_count=1 and ((fifo_count<=1 and r_mst_out.hwrite='1') or (fifo_count=fifo_length and r_mst_out.hwrite='0'))))) else
nonseq when (mst_state=addr) else
seq when (mst_state=addr_data) else
idle;
 
--***************************
--******** granted bus ******
--***************************
process(hclk, hresetn)
begin
if hresetn='0' then
granted <= '0';
elsif hclk'event and hclk='1' then
granted <= '0' after 1 ns;
if (mst_in.hready='1' and mst_in.hgrant='1') then
granted <= '1' after 1 ns;
end if;
end if;
end process;
 
next_fifo_empty <= '1' when ((fifo_count=0 and (fifo_write='0' or (fifo_write=fifo_read))) or (fifo_count=1 and fifo_read='1' and fifo_write='0')) else '0';
next_fifo_full <= '1' when ((fifo_count=fifo_length and (fifo_read='0' or (fifo_write=fifo_read))) or (fifo_count=fifo_length-1 and fifo_read='0' and fifo_write='1')) else '0';
next_fifo_he <= '1' when ((fifo_count<=1 and (fifo_write='0' or (fifo_write=fifo_read))) or (fifo_count=2 and fifo_read='1' and fifo_write='0')) else '0';
next_fifo_hf <= '1' when ((fifo_count>=fifo_length-1 and (fifo_read='0' or (fifo_write=fifo_read))) or (fifo_count=fifo_length-2 and fifo_read='0' and fifo_write='1')) else '0';
--next_count_ge2 <= '1' when ((dma_count_ge2='1' and fifo_hwrite='0' and fifo_hread='0') or (dma_count_ge3='1' and (fifo_hwrite='1' or fifo_hread='1'))) else '0';
--***************************
--********* old_hburst ******
--***************************
process(hclk, hresetn)
begin
if hresetn='0' then
old_hburst <= incr;
prior_reg <= slave;
elsif hclk'event and hclk='1' then
old_hburst <= old_hburst_s after 1 ns;
prior_reg <= prior_s after 1 ns;
end if;
end process;
old_hburst_s <= start_hburst when (dma_start.start='1') else old_hburst;
prior_s <= start_prior when (dma_start.start='1') else prior_reg;
 
--***************************
--***************************
process(hclk,hresetn)
begin
if hresetn='0' then
r_mst_out.haddr <= (others => '0');
r_mst_out.htrans <= "00";
r_mst_out.hlock <= '0';
r_mst_out.hwrite <= '0';
r_mst_out.hsize <= bits32;
r_mst_out.hburst <= incr;
r_mst_out.hprot <= "0011";
elsif hclk'event and hclk='1' then
r_mst_out.haddr <= s_mst_out.haddr after 1 ns;
r_mst_out.htrans <= s_mst_out.htrans after 1 ns;
r_mst_out.hlock <= s_mst_out.hlock after 1 ns;
r_mst_out.hwrite <= s_mst_out.hwrite after 1 ns;
r_mst_out.hsize <= s_mst_out.hsize after 1 ns;
r_mst_out.hburst <= s_mst_out.hburst after 1 ns;
r_mst_out.hprot <= s_mst_out.hprot after 1 ns;
end if;
end process;
 
s_mst_out.hlock <= start_hlocked when (dma_start.start='1') else r_mst_out.hlock;
s_mst_out.hwrite <= start_hwrite when (dma_start.start='1') else r_mst_out.hwrite;
s_mst_out.hsize <= start_hsize when (dma_start.start='1') else r_mst_out.hsize;
s_mst_out.hburst <= start_hburst when (dma_start.start='1') else incr when (dma_restart='1') else r_mst_out.hburst;
s_mst_out.hprot <= start_hprot when (dma_start.start='1') else r_mst_out.hprot;
 
mst_out.hlock <= hlock_t;
mst_out.hwrite <= r_mst_out.hwrite;
mst_out.hsize <= r_mst_out.hsize;
mst_out.hburst <= r_mst_out.hburst;
mst_out.hprot <= r_mst_out.hprot;
 
mst_out.haddr <= r_mst_out.haddr;
mst_out.hwdata <= fifo_dataout;--not retimed!
mst_out.hbusreq <= hbusreq_t;
mst_out.htrans <= s_mst_out.htrans;
 
 
--***************************
--********** haddr **********
--***************************
old_addr_pr:process(hclk, hresetn)
begin
if hresetn='0' then
old_addr <= (others => '0');
elsif hclk'event and hclk='1' then
old_addr <= old_addr_s after 1 ns;
end if;
end process;
 
old_addr_move:process(mst_state, mst_in, tmp_htrans, r_mst_out)
begin
if ((mst_state=addr or mst_state=addr_data or mst_state=data) and mst_in.hready='1' and tmp_htrans/=busy and r_mst_out.htrans/=busy) then
old_addr_incr <= '1';
else
old_addr_incr <= '0';
end if;
end process;
 
old_addr_s <= r_mst_out.haddr when (old_addr_incr='1') else
dma_start.extaddr when (dma_start.start='1') else
old_addr;
 
page_fault <= '1' when (page_attention='1' and (pf_incr='1' or pf_wrap4='1' or pf_wrap8='1' or pf_wrap16='1')) else '0';
 
pf_incr <= '1' when (haddr_t(9 downto 2)=0) else '0';
pf_wrap4 <= '1' when (haddr_t(3 downto 2)=0 and old_hburst=wrap4) else '0';
pf_wrap8 <= '1' when (haddr_t(4 downto 2)=0 and old_hburst=wrap8) else '0';
pf_wrap16 <= '1' when (haddr_t(5 downto 2)=0 and old_hburst=wrap16) else '0';
with r_mst_out.hburst select
page_attention <=
'1' when incr|incr4|incr8|incr16,
'0' when others;
 
with old_hburst select
old_page_attention <=
'1' when incr|incr4|incr8|incr16,
'0' when others;
 
with r_mst_out.hburst select
haddr_t(9 downto 2) <=
r_mst_out.haddr(9 downto 2)+1 when incr|incr4|incr8|incr16,
r_mst_out.haddr(9 downto 4)&(r_mst_out.haddr(3 downto 2)+"01") when wrap4,
r_mst_out.haddr(9 downto 5)&(r_mst_out.haddr(4 downto 2)+"001") when wrap8,
r_mst_out.haddr(9 downto 6)&(r_mst_out.haddr(5 downto 2)+"0001") when wrap16,
r_mst_out.haddr(9 downto 2) when others;--"000",
 
--page increment if:
--page fault and incr/incr4/incr8/incr16 and old_burst incr/incr4/incr8/incr16
s_mst_out.haddr(31 downto 10) <=
dma_start.extaddr(31 downto 10) when (dma_start.start='1') else
old_addr(31 downto 10) when (mst_state=retry_phase or mst_state=idle_phase) else
(r_mst_out.haddr(31 downto 10)+1) when (page_attention='1' and old_page_attention='1' and pf_incr='1' and haddr_incr='1') else
r_mst_out.haddr(31 downto 10);
 
s_mst_out.haddr(1 downto 0) <= dma_start.extaddr(1 downto 0) when (dma_start.start='1') else r_mst_out.haddr(1 downto 0);
 
s_mst_out.haddr(9 downto 2) <=
dma_start.extaddr(9 downto 2) when (dma_start.start='1') else
old_addr(9 downto 2) when (mst_state=retry_phase or mst_state=idle_phase) else
r_mst_out.haddr(9 downto 4)&"00" when (page_fault='1' and pf_wrap4='1' and haddr_incr='1') else
r_mst_out.haddr(9 downto 5)&"000" when (page_fault='1' and pf_wrap8='1' and haddr_incr='1') else
r_mst_out.haddr(9 downto 6)&"0000" when (page_fault='1' and pf_wrap16='1' and haddr_incr='1') else
haddr_t(9 downto 2) when (haddr_incr='1') else
r_mst_out.haddr(9 downto 2);
--haddr_incr_pr:process(mst_state, mst_in, tmp_htrans, r_mst_out)
--begin
-- if ((mst_state=addr or mst_state=addr_data) and mst_in.hready='1' and tmp_htrans/=busy and r_mst_out.htrans/=busy) then-- or mst_state=data
-- haddr_incr <= '1';
-- else
-- haddr_incr <= '0';
-- end if;
--end process;
 
--haddr_incr <= '1' when
--(mst_in.hready='1' and
--(tmp_htrans=nonseq or
--((tmp_htrans=seq or tmp_htrans=busy) and r_mst_out.htrans/=busy))) else '0';
haddr_incr <= '1' when
(mst_in.hready='1' and (tmp_htrans=nonseq or tmp_htrans=seq or tmp_htrans=busy) and r_mst_out.htrans/=busy) else '0';
 
--***************************
--********* hbusreq *********
--***************************
 
hbusreq_t <= '1' when
(
(dma_count>0 and mst_state=req_phase) or
(dma_count>1 and (mst_state=addr or mst_state=addr_data))
) else '0';
 
mst_req <= '1' when (r_mst_out.hwrite='0' or fifo_empty='0') else '0';
--start new master if:
--read or
--write and fifo_count>=2 or
--write and fifo_count=1 and dma_count=1
--***************************
--********** hlock *********
--***************************
hlock_t <= hbusreq_t and r_mst_out.hlock;--for hlock behaviour different wrt hbusreq change ONLY here!!
 
 
--***************************
--********* eot_int *********
--***************************
int_gen:process(hclk, hresetn)
begin
if hresetn='0' then
eot_int_reg <= '0';
elsif hclk'event and hclk='1' then
if (mst_state=idle_phase) then
eot_int_reg <= '0' after 1 ns;
elsif
(s_mst_state=idle_phase and mst_running_t='1' and dma_count_s=0) then
eot_int_reg <= '1' after 1 ns;
end if;
end if;
end process;
 
eot_int <= eot_int_reg;
 
 
--***************************
--****** mst_running *****
--***************************
mst_running_t <= '0' when (mst_state=idle_phase or mst_state=wait_phase or mst_state=req_phase) else '1';
mst_running <= mst_running_t;
 
 
--***************************
--******** dma_count ********
--***************************
dma_count_pr:process(hclk, hresetn)
begin
if hresetn='0' then
dma_count <= (others => '0');
elsif hclk'event and hclk='1' then
dma_count <= dma_count_s after 1 ns;
end if;
end process;
process(dma_start, start_hburst)
begin
if dma_start.start='1' then
case start_hburst is
when single =>
right_count(15 downto 0) <= "0000000000000001";
when incr =>
right_count(15 downto 0) <= dma_start.count;
when wrap4|incr4 =>
right_count(15 downto 0) <= "0000000000000100";
when wrap8|incr8 =>
right_count(15 downto 0) <= "0000000000001000" ;
when others =>--wrap16|incr16
right_count(15 downto 0) <= "0000000000010000";
end case;
else
right_count(15 downto 0) <= (others => '-');
end if;
end process;
 
dma_count_s <=
(others=>'0') when fifo_reset='1' else
-- dma_count-1 when (r_mst_out.hwrite='1' and fifo_hread='1') or (r_mst_out.hwrite='0' and fifo_hwrite='1') else
dma_count-1 when ((mst_state=addr or mst_state=addr_data) and haddr_incr='1') else
dma_count+1 when (mst_state=retry_phase and mst_in.hready='1') else
right_count when (dma_start.start='1') else
dma_count;
 
dma_restart <= '1' when (mst_state=retry_phase or mst_state=data) else '0';
 
fifo_reset <= '1' when (
(mst_state=error_phase) or
(mst_in.hresp=ok_resp and r_mst_out.htrans/=busy and r_mst_out.hwrite='1' and mst_in.hready='1' and mst_state=data and dma_count=0)
) else '0';
--***************************
--***** fifo interface ******
--***************************
fifo_write <= fifo_hwrite or m_wrap_in.ask_ok;
fifo_read <= fifo_hread or m_wrap_in.take_ok;
 
fifo_datain <= mst_in.hrdata when (fifo_hwrite='1') else m_wrap_in.rdata;
m_wrap_out.wdata <= fifo_dataout;
 
--transfer master => fifo
fifo_hwrite <= '1' when (r_mst_out.hwrite='0' and data_trx='1' and fifo_full='0') else '0';
 
--transfer fifo => master
fifo_hread <= '1' when (r_mst_out.hwrite='1' and data_trx='1' and fifo_empty='0') else '0';
 
data_trx <= '1' when (mst_in.hready='1' and mst_in.hresp=ok_resp and r_mst_out.htrans/=busy and (mst_state=addr_data or mst_state=data)) else '0';
--***********************************************
--master<=>core interface: program/data memories
--***********************************************
 
--transfer fifo => core
m_wrap_out.take <= '1' when (r_mst_out.hwrite='0' and fifo_empty='0') else '0';
 
--transfer core => fifo
m_wrap_out.ask <= '1' when (r_mst_out.hwrite='1' and fifo_full='0' and (mst_running_t='1' or dma_count/=0)) else '0';
m_wrap_out.addr <= int_addr;
process(hclk, hresetn)
begin
if hresetn='0' then
int_addr <= (others => '0');
int_mod <= (others => '0');
elsif hclk'event and hclk='1' then
int_addr <= int_addr_s after 1 ns;
int_mod <= int_mod_s after 1 ns;
end if;
end process;
 
int_mod_s <= dma_start.intmod when (dma_start.start='1') else int_mod;
 
int_page_fault <= '1' when (int_addr_t(9 downto 2)=0 and page_attention='1') else '0';
with r_mst_out.hburst select
int_addr_t(9 downto 2) <=
int_addr(9 downto 2)+int_mod(9 downto 2) when incr|incr4|incr8|incr16,
int_addr(9 downto 4)&(int_addr(3 downto 2)+"01") when wrap4,
int_addr(9 downto 5)&(int_addr(4 downto 2)+"001") when wrap8,
int_addr(9 downto 6)&(int_addr(5 downto 2)+"0001") when wrap16,
int_addr(9 downto 2) when others;--"000",
 
int_addr_incr <= '1' when ((r_mst_out.hwrite='0' and m_wrap_in.take_ok='1') or (r_mst_out.hwrite='1' and m_wrap_in.ask_ok='1')) else '0';
 
int_addr_s(31 downto 16) <= (others => '0');
int_addr_s(15 downto 10) <= (int_addr(15 downto 10)+1) when (int_page_fault='1' and int_addr_incr='1') else dma_start.intaddr(15 downto 10) when (dma_start.start='1') else int_addr(15 downto 10);
int_addr_s(1 downto 0) <= dma_start.intaddr(1 downto 0) when (dma_start.start='1') else int_addr(1 downto 0);
int_addr_s(9 downto 2) <= int_addr_t(9 downto 2) when (int_addr_incr='1') else dma_start.intaddr(9 downto 2) when (dma_start.start='1') else int_addr(9 downto 2);
 
end rtl;
/trunk/src/ahb_package.vhd
0,0 → 1,320
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
 
package ahb_package is
 
-----------------------------------------------------------------------------
-- Generic contants
-----------------------------------------------------------------------------
--***************************************************************
constant dump_no: integer := 0;--no dump on memory write
constant dump_end: integer := 1;--memory dump at end of test
constant dump_all: integer := 2;--continuous memory dump
--***************************************************************
constant zeroes: std_logic_vector(31 downto 0):= (others => '0');
constant tie_zero: std_logic:= '0';
constant ones: std_logic_vector(31 downto 0):= (others => '1');
constant tie_one: std_logic:= '1';
--***************************************************************
 
-----------------------------------------------------------------------------
-- AHB system: for every slave define LOW and HIGH address
-----------------------------------------------------------------------------
type addr_t is
record
high: integer;
low: integer;
end record;
 
-----------------------------------------------------------------------------
-- AHB Master
-----------------------------------------------------------------------------
-- AHB master inputs
type mst_in_t is
record
hgrant: std_logic;
hready: std_logic;
hresp: std_logic_vector(1 downto 0);
hrdata: std_logic_vector(31 downto 0);
end record;
 
-- AHB master outputs
type mst_out_t is
record
hbusreq: std_logic;
hlock: std_logic;
htrans: std_logic_vector(1 downto 0);
haddr: std_logic_vector(31 downto 0);
hwrite: std_logic;
hsize: std_logic_vector(2 downto 0);
hburst: std_logic_vector(2 downto 0);
hprot: std_logic_vector(3 downto 0);
hwdata: std_logic_vector(31 downto 0);
end record;
 
-----------------------------------------------------------------------------
-- AHB Slave
-----------------------------------------------------------------------------
-- AHB slave inputs
type slv_in_t is
record
hsel: std_logic;
haddr: std_logic_vector(31 downto 0);
hwrite: std_logic;
htrans: std_logic_vector(1 downto 0);
hsize: std_logic_vector(2 downto 0);
hburst: std_logic_vector(2 downto 0);
hwdata: std_logic_vector(31 downto 0);
hprot: std_logic_vector(3 downto 0);
hready: std_logic;
hmaster: std_logic_vector(3 downto 0);
hmastlock: std_logic;
end record;
 
-- AHB slave outputs
type slv_out_t is
record
hready: std_logic;
hresp: std_logic_vector(1 downto 0);
hrdata: std_logic_vector(31 downto 0);
hsplit: std_logic_vector(15 downto 0);
end record;
 
-----------------------------------------------------------------------------
-- Definitions for AMBA APB Slaves constants and types
-----------------------------------------------------------------------------
constant apb_addr: integer range 8 to 32 := 32;-- address width
constant apb_data: integer range 8 to 32 := 32;-- data width
 
-- APB slave inputs
type apb_in_t is
record
psel: std_logic;
penable: std_logic;
paddr: std_logic_vector(apb_addr-1 downto 0);
pwrite: std_logic;
pwdata: std_logic_vector(apb_data-1 downto 0);
end record;
 
-- APB slave outputs
type apb_out_t is
record
prdata: std_logic_vector(apb_addr-1 downto 0);
end record;
-----------------------------------------------------------------------------
-- Definitions for AMBA AHB Arbiter/Decoder/Bridges
-----------------------------------------------------------------------------
-- supporting array types
 
type addr_in_v_t is array (15 downto 0) of addr_t;
type addr_matrix_t is array (natural range <> ) of addr_in_v_t;
type mst_in_v_t is array (natural Range <> ) of mst_in_t;
type mst_out_v_t is array (natural Range <> ) of mst_out_t;
 
type slv_in_v_t is array (natural Range <> ) of slv_in_t;
type slv_out_v_t is array (natural Range <> ) of slv_out_t;
 
type apb_in_v_t is array (natural range <> ) of apb_in_t;
type apb_out_v_t is array (natural range <> ) of apb_out_t;
 
 
--***************************************************************
-- definition of amba AHB protocol constants
--***************************************************************
 
--***************************************************************
--configuration register space addresses
--***************************************************************
constant dma_extadd_addr: std_logic_vector(3 downto 0):= "0000";
constant dma_intadd_addr: std_logic_vector(3 downto 0):= "0001";
constant dma_intmod_addr: std_logic_vector(3 downto 0):= "0010";
constant dma_type_addr: std_logic_vector(3 downto 0):= "0011";
constant dma_count_addr: std_logic_vector(3 downto 0):= "0100";
constant dma_go_addr: std_logic_vector(3 downto 0):= "0101";
 
--***************************************************************
-- hprot values
--***************************************************************
--constant opcode_fetch: std_logic_vector(3 downto 0):= "---0";
--constant data_access: std_logic_vector(3 downto 0):= "---1";
--constant user_access: std_logic_vector(3 downto 0):= "--0-";
--constant privileged_access: std_logic_vector(3 downto 0):= "--1-";
--constant not_bufferable: std_logic_vector(3 downto 0):= "-0--";
--constant bufferable: std_logic_vector(3 downto 0):= "-1--";
--constant not_cacheable: std_logic_vector(3 downto 0):= "0---";
--constant cacheable: std_logic_vector(3 downto 0):= "1---";
 
--***************************************************************
-- hburst values
--***************************************************************
constant single: std_logic_vector(2 downto 0):= "000";
constant incr: std_logic_vector(2 downto 0):= "001";
constant wrap4: std_logic_vector(2 downto 0):= "010";
constant incr4: std_logic_vector(2 downto 0):= "011";
constant wrap8: std_logic_vector(2 downto 0):= "100";
constant incr8: std_logic_vector(2 downto 0):= "101";
constant wrap16: std_logic_vector(2 downto 0):= "110";
constant incr16: std_logic_vector(2 downto 0):= "111";
 
--***************************************************************
-- hsize values
--***************************************************************
constant bits8: std_logic_vector(2 downto 0):= "000";
constant bits16: std_logic_vector(2 downto 0):= "001";
constant bits32: std_logic_vector(2 downto 0):= "010";
constant bits64: std_logic_vector(2 downto 0):= "011";
constant bits128: std_logic_vector(2 downto 0):= "100";
constant bits256: std_logic_vector(2 downto 0):= "101";
constant bits512: std_logic_vector(2 downto 0):= "110";
constant bits1024: std_logic_vector(2 downto 0):= "111";
 
--***************************************************************
-- htrans values
--***************************************************************
constant idle: std_logic_vector(1 downto 0):= "00";
constant busy: std_logic_vector(1 downto 0):= "01";
constant nonseq: std_logic_vector(1 downto 0):= "10";
constant seq: std_logic_vector(1 downto 0):= "11";
 
--***************************************************************
-- hresp values
--***************************************************************
constant ok_resp: std_logic_vector(1 downto 0):= "00";
constant error_resp: std_logic_vector(1 downto 0):= "01";
constant retry_resp: std_logic_vector(1 downto 0):= "10";
constant split_resp: std_logic_vector(1 downto 0):= "11";
 
-----------------------------------------------------------------------------
-- AHB system constants
-----------------------------------------------------------------------------
 
--***************************************************************
-- priority values
--***************************************************************
constant master: std_logic:= '1';
constant slave: std_logic:= '0';
 
--***************************************************************
-- split retry programmable slave response values
--***************************************************************
constant retry: std_logic:= '0';
constant split: std_logic:= '1';
 
--***************************************************************
-- locked/non locked ahb bus request programmable
--***************************************************************
constant nonlocked: std_logic:='0';
constant locked: std_logic:='1';
 
--***************************************************************
-- burst capability for masters and slaves
--***************************************************************
constant burst_support: integer:= 1;
constant no_burst_support: integer:= 0;
 
--***************************************************************
-- hprot values
--***************************************************************
constant hprot_posted: std_logic_vector(3 downto 0):= "1111";
constant hprot_nonposted: std_logic_vector(3 downto 0):= "0000";
 
-----------------------------------------------------------------------------
-- Definitions for test ports
-----------------------------------------------------------------------------
type conf_type_t is
record
write: std_logic;
addr: std_logic_vector(3 downto 0);
wdata: std_logic_vector(31 downto 0);
end record;
 
-----------------------------------------------------------------------------
-- Definitions for ahb master dma parameters passing
-----------------------------------------------------------------------------
type start_type_t is
record
start: std_logic;
extaddr: std_logic_vector(31 downto 0);
intaddr: std_logic_vector(15 downto 0);
intmod: std_logic_vector(15 downto 0);
count: std_logic_vector(15 downto 0);
hparams: std_logic_vector(15 downto 0);
end record;
 
-----------------------------------------------------------------------------
-- Handshake signals and data between master/slave and internal memories/registers
-----------------------------------------------------------------------------
type wrap_out_t is
record
addr: std_logic_vector(31 downto 0);
take: std_logic;
wdata: std_logic_vector(31 downto 0);
ask: std_logic;
end record;
type wrap_in_t is
record
take_ok: std_logic;
ask_ok: std_logic;
rdata: std_logic_vector(31 downto 0);
end record;
 
-----------------------------------------------------------------------------
-- Parameters for defining AHB STIMULATOR behaviour
-----------------------------------------------------------------------------
type uut_params_t is
record
hsize_tb: std_logic_vector(2 downto 0);
split_tb: std_logic;
prior_tb: std_logic;
hburst_cycle: std_logic;
hburst_tb: std_logic_vector(2 downto 0);
-- high_addr_tb:std_logic_vector(19 downto 0);
ext_addr_incr_tb: integer;
intmod_tb: integer;
hprot_tb: std_logic_vector(3 downto 0);
base_tb: integer;
int_addr_incr_tb: integer;
int_base_tb: integer;
locked_request: std_logic;
end record;
 
-----------------------------------------------------------------------------
-- Vector types (aggregates) of previous types
-----------------------------------------------------------------------------
type conf_type_v is array (Natural Range <> ) of conf_type_t;
 
type start_type_v is array (Natural Range <> ) of start_type_t;
 
type wrap_out_v is array (Natural Range <> ) of wrap_out_t;
type wrap_in_v is array (Natural Range <> ) of wrap_in_t;
 
type uut_params_v_t is array (Natural Range <> ) of uut_params_t;
 
--***************************************************************
 
--***************************************************************
--***************************************************************
--uut#0
--signal stim_0: uut_params_t:= (bits32,retry,master,'0',wrap4,"00000000000000000000",2,4,hprot_nonposted,2048,1,0,'1');
--uut#1
--signal stim_1: uut_params_t:= (bits32,retry,slave,'0',wrap4,"00000000000000000000",2,4,hprot_posted,2048+128,1,0,'1');
--uut#2
--signal stim_2: uut_params_t:= (bits32,retry,master,'0',wrap4,"00000000000000000000",2,4,hprot_posted,2048+256,1,0,'0');
--uut#3
--signal stim_3: uut_params_t:= (bits32,retry,master,'0',wrap4,"00010000001000000000",2,4,hprot_posted,2048,1,0,'0');
 
--signal stim_v: uut_params_v_t(3 downto 0) := (stim_3, stim_2, stim_1, stim_0);
--***************************************************************
--***************************************************************
end;
 
package body ahb_package is
end;
 
 
 
/trunk/src/ahb_slave_wait.vhd
0,0 → 1,301
 
--*******************************************************************
--** ****
--** AHB system generator ****
--** ****
--** Author: Federico Aglietti ****
--** federico.aglietti\@opencores.org ****
--** ****
--*******************************************************************
--** ****
--** Copyright (C) 2004 Federico Aglietti ****
--** federico.aglietti\@opencores.org ****
--** ****
--** This source file may be used and distributed without ****
--** restriction provided that this copyright statement is not ****
--** removed from the file and that any derivative work contains ****
--** the original copyright notice and the associated disclaimer.****
--** ****
--** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY ****
--** EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED ****
--** TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS ****
--** FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR ****
--** OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, ****
--** INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES ****
--** (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE ****
--** GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR ****
--** BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF ****
--** LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ****
--** (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT ****
--** OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE ****
--** POSSIBILITY OF SUCH DAMAGE. ****
--** ****
--*******************************************************************
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
use ieee.std_logic_unsigned.all;
 
use work.ahb_funct.all;
use work.ahb_package.all;
use work.ahb_configure.all;
 
entity ahb_slave_wait is
generic (
num_slv: in integer range 0 to 15:= 1;
fifohempty_level: in integer:= 2;
fifohfull_level: in integer:= 5;
fifo_length: in integer:= 8);
port(
hresetn: in std_logic;
hclk: in std_logic;
remap: in std_logic;
slv_in: in slv_in_t;
slv_out: out slv_out_t;
slv_err: out std_logic;
mst_running: in std_logic;
prior_in: in std_logic;
slv_running: out std_logic;
s_wrap_out: out wrap_out_t;
s_wrap_in: in wrap_in_t);
end ahb_slave_wait;
 
 
architecture rtl of ahb_slave_wait is
 
--parameters fixed for single-wait slave
constant num_slvs: integer:= 1;
constant num_ahb: integer:= 0;
constant def_slv: integer:= 0;
constant alg_number: integer range 0 to 2:= 0;
 
 
type slv_fsm is (data_cycle,error_cycle);
signal slv_state, s_slv_state: slv_fsm;
 
signal r_slv_in_v, s_slv_in_v: slv_in_v_t(num_slvs-1 downto 0);
 
signal hready_t, r_hready: std_logic;
signal hresp_t: std_logic_vector(1 downto 0);
signal dec_error: std_logic;
 
--***************************************************************
--arbitration signals
--***************************************************************
signal s_grant_slave, grant_slave: integer range 0 to num_slvs-1;
signal s_turn, turn: integer range 0 to num_slvs-1;
signal req_ored: std_logic;
 
signal slv_req: std_logic_vector(num_slvs-1 downto 0);
 
signal addr_slv_matrix: addr_matrix_t(0 downto 0);
 
begin
addr_slv_matrix(0)(num_slvs-1 downto 0) <= slv_matrix(0)(num_slv downto num_slv) when (remap='0') else slv_matrix(1)(num_slv downto num_slv);
 
--***************************
--******* slave state *******
--***************************
process(slv_state, dec_error)
begin
s_slv_state <= slv_state;
case slv_state is
when data_cycle =>
if (dec_error='1') then
s_slv_state <= error_cycle;
end if;
when error_cycle =>
s_slv_state <= data_cycle;
when others =>
end case;
end process;
 
process(hresetn, hclk)
begin
if hresetn='0' then
r_hready <= '1';
elsif hclk'event and hclk='1' then
r_hready <= hready_t after 1 ns;
end if;
end process;
 
process(hresetn, hclk)
begin
if hresetn='0' then
slv_state <= data_cycle;
elsif hclk'event and hclk='1' then
slv_state <= s_slv_state after 1 ns;
end if;
end process;
 
 
process(addr_slv_matrix, r_slv_in_v, grant_slave)
variable v_error: std_logic;
begin
v_error:= '0';
if (r_slv_in_v(grant_slave).hsel='1') then
if (r_slv_in_v(grant_slave).hsize/=bits32) then
v_error:= '1';
end if;
if (r_slv_in_v(grant_slave).haddr(1 downto 0)/="00") then
v_error:= '1';
end if;
if (r_slv_in_v(grant_slave).haddr(31 downto 10)<conv_std_logic_vector(addr_slv_matrix(num_ahb)(grant_slave).low, 32)(31 downto 10)) then
v_error:= '1';
end if;
if (r_slv_in_v(grant_slave).haddr(31 downto 10)>conv_std_logic_vector(addr_slv_matrix(num_ahb)(grant_slave).high, 32)(31 downto 10)) then
v_error:= '1';
end if;
end if;
dec_error <= v_error;
end process;
 
--***************************
--********** hready *********
--***************************
 
hready_t <= '1' when
(slv_state=error_cycle or
r_slv_in_v(grant_slave).htrans=idle or
r_slv_in_v(grant_slave).htrans=busy or
((r_slv_in_v(grant_slave).htrans=nonseq or r_slv_in_v(grant_slave).htrans=seq) and dec_error='0' and
((r_slv_in_v(grant_slave).hwrite='1' and s_wrap_in.take_ok='1') or (r_slv_in_v(grant_slave).hwrite='0' and s_wrap_in.ask_ok='1')))) else '0';
 
--***************************
--********** hresp **********
--***************************
 
hresp_t <= error_resp when (dec_error='1' or slv_state=error_cycle) else ok_resp;
slv_err <= '1' when (slv_state=error_cycle) else '0';
--***************************
--******* s_wrap_out ********
--***************************
process(r_slv_in_v, slv_in, slv_state, grant_slave, dec_error)
begin
s_wrap_out.addr <= r_slv_in_v(grant_slave).haddr;--to improve for LOW POWER!!
s_wrap_out.wdata <= slv_in.hwdata;--to improve for LOW POWER!!
s_wrap_out.take <= '0';
s_wrap_out.ask <= '0';
if (slv_state=data_cycle and dec_error='0' and slv_in.htrans/=busy and r_slv_in_v(grant_slave).hsel='1' and (r_slv_in_v(grant_slave).htrans=nonseq or r_slv_in_v(grant_slave).htrans=seq)) then
s_wrap_out.take <= r_slv_in_v(grant_slave).hwrite;
s_wrap_out.ask <= not r_slv_in_v(grant_slave).hwrite;
end if;
end process;
 
 
--***************************
--********** output *********
--***************************
process(s_wrap_in, hready_t, hresp_t, grant_slave, r_slv_in_v)
begin
for i in num_slvs-1 downto 0 loop
slv_out.hsplit <= (others => '0');
slv_out.hrdata <= s_wrap_in.rdata;
slv_out.hresp <= ok_resp;
slv_out.hready <= '1';
if (i=grant_slave) then
slv_out.hresp <= hresp_t;
slv_out.hready <= hready_t;
--easiest behaviour: wait for granting!!
elsif (r_slv_in_v(i).hsel='1' and r_slv_in_v(i).htrans/=idle and r_slv_in_v(i).htrans/=busy) then
slv_out.hready <= '0';
end if;
end loop;
end process;
 
--***************************
--********** input **********
--***************************
process(hresetn, hclk)
begin
if hresetn='0' then
for i in num_slvs-1 downto 0 loop
r_slv_in_v(i).hsel <= '0';
r_slv_in_v(i).hready <= '0';
r_slv_in_v(i).haddr <= (others=>'0');
r_slv_in_v(i).hwrite <= '0';
r_slv_in_v(i).htrans <= idle;
r_slv_in_v(i).hsize <= bits32;
r_slv_in_v(i).hburst <= incr;
r_slv_in_v(i).hprot <= "0011";
end loop;
elsif hclk'event and hclk='1' then
for i in num_slvs-1 downto 0 loop
r_slv_in_v(i).hready <= slv_in.hready after 1 ns;
if (slv_in.hready='1') then-- and slv_in.hsel='1'
r_slv_in_v(i).hsel <= slv_in.hsel after 1 ns;
r_slv_in_v(i).hburst <= slv_in.hburst after 1 ns;
r_slv_in_v(i).hprot <= slv_in.hprot after 1 ns;
r_slv_in_v(i).hsize <= slv_in.hsize after 1 ns;
r_slv_in_v(i).hwrite <= slv_in.hwrite after 1 ns;
end if;
if (slv_in.hready='1' and r_slv_in_v(i).htrans/=busy) then-- and slv_in.hsel='1'
r_slv_in_v(i).haddr <= slv_in.haddr after 1 ns;
end if;
if (slv_in.hready='1') then-- and slv_in.hsel='1'
r_slv_in_v(i).htrans <= slv_in.htrans after 1 ns;
end if;
end loop;
end if;
end process;
 
--------------------------------------------------------------------------
-- SLAVES RESPONSES AND ARBITRATION
--------------------------------------------------------------------------
 
process(r_slv_in_v)
begin
for i in num_slvs-1 downto 0 loop
slv_req(i) <= '0';
if (r_slv_in_v(i).hsel='1' and (r_slv_in_v(i).htrans=nonseq or r_slv_in_v(i).htrans=seq)) then
slv_req(i) <= '1';
end if;
end loop;
end process;
 
process(slv_req)
variable v_req_ored: std_logic;
begin
v_req_ored := '0';
for i in num_slvs-1 downto 0 loop
v_req_ored := v_req_ored or slv_req(i);
end loop;
req_ored <= v_req_ored;
end process;
 
update_pr:process(turn, grant_slave, r_hready, req_ored, slv_req, r_slv_in_v)
variable t_turn, t_grant_slave: integer;
begin
t_turn := turn;
t_grant_slave := grant_slave;
if (r_hready='1' and req_ored='1' and r_slv_in_v(grant_slave).htrans/=busy and not(slv_req(grant_slave) and r_slv_in_v(grant_slave).hmastlock)='1') then
case alg_number is
when 0 => --fixed
fixed_priority(t_turn, t_grant_slave, slv_req, turn);
-- when 1 => --round robin
-- round_robin(def_slv, t_turn, t_grant_slave, slv_req, turn);
when others => --NOT IMPLEMENTED
assert FALSE report "### NOT IMPLEMENTED!" severity FAILURE;
end case;
--else (no_ready) then SAME SLAVE
end if;
s_turn <= t_turn;
s_grant_slave <= t_grant_slave;
end process;
 
process(hresetn, hclk)
begin
if hresetn='0' then
grant_slave <= 0;
turn <= 0;
elsif hclk'event and hclk='1' then
grant_slave <= s_grant_slave after 1 ns;
turn <= s_turn after 1 ns;
end if;
end process;
 
end rtl;
/trunk/src/ahb_funct.vhd
0,0 → 1,147
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_arith.all;
 
package ahb_funct is
function nb_bits (A : std_logic_vector) return NATURAL;
function nb_bits (A : INTEGER) return NATURAL;
 
procedure fixed_priority(
t_turn: out integer;
t_grant: out integer;
req: in std_logic_vector;
turn: in integer);
procedure round_robin(
def_elem: in integer;
t_turn: out integer;
t_grant: out integer;
req: in std_logic_vector;
turn: in integer);
procedure random_priority(
def_elem: in integer;
t_turn: out integer;
t_grant: out integer;
random: in integer;
req: in std_logic_vector;
turn: in integer);
end ahb_funct;
 
package body ahb_funct is
 
function nb_bits (A : std_logic_vector) return NATURAL is
variable logres : NATURAL ;
begin
logres := 1;
for i in A'length-1 downto 0 loop
if A(i) = '1' then
logres := i;
exit;
end if;
end loop;
return logres;
end nb_bits;
function nb_bits (A : INTEGER) return NATURAL is
variable logres : NATURAL ;
begin
logres := 1;
for i in 0 to 30 loop
if 2**i <= A then
logres := i+1;
end if;
end loop;
return logres;
end nb_bits;
 
procedure fixed_priority(
t_turn: out integer;-- range 0 to num_elem-1;
t_grant: out integer;
req: in std_logic_vector;
turn: in integer-- range 0 to num_elem-1
) is
begin
t_grant := 0;
t_turn := 0;
req_for:for i in req'length-1 downto 0 loop
if req(i) = '1' then
t_grant := i;
end if;
end loop;
end fixed_priority;
 
procedure round_robin(
def_elem: in integer;
t_turn: out integer;-- range 0 to num_elem-1;
t_grant: out integer;-- range 0 to num_elem-1;
req: in std_logic_vector;
turn: in integer-- range 0 to num_elem-1
) is
constant req_size: integer:= req'length;
variable v_req: std_logic_vector(req_size*2-1 downto 0);
type turn_array is array (req_size-1 downto 0) of std_logic_vector(req_size-1 downto 0);
variable v_turn: turn_array;
begin
t_grant := def_elem;
t_turn := turn;
v_req := req&req;--concatenation
for i in 0 to req_size-1 loop
v_turn(i) := v_req(i+req_size-1 downto i);
end loop;
for j in 0 to req_size-1 loop
if j=turn then
for jj in 0 to req_size-1 loop
if v_turn(j)(jj)='1' then
if turn+jj >=req'length then
t_turn := turn+jj-req_size;
t_grant := turn+jj-req_size;
else
t_turn := turn+jj;
t_grant := turn+jj;
end if;
end if;
end loop; -- jj
end if;
end loop; -- j
end round_robin;
 
 
procedure random_priority(
def_elem: in integer;
t_turn: out integer;-- range 0 to num_elem-1;
t_grant: out integer;-- range 0 to num_elem-1;
random: in integer;-- range 0 to 2**(nb_bits(num_elem));
req: in std_logic_vector;
turn: in integer-- range 0 to num_elem-1
) is
constant req_size: integer:= req'length;
variable j, v_turn, upper_limit: integer;
begin
t_grant := def_elem;
upper_limit := 2**(nb_bits(req_size))-1;
v_turn := turn;
req_for:for i in upper_limit downto 0 loop
if ((i >= random) and (i <= random+upper_limit)) then
j := i mod req_size;
if req(j) = '1' then
t_grant := j;
if turn=req_size-1 then
v_turn := 0;
else
v_turn := turn+1;
end if;
end if;
t_turn := v_turn;
--synopsys translate_off
assert (v_turn>=0 and v_turn<req_size) report "####ERROR: WRONG ARBITRATION!!!" severity failure;
--synopsys translate_on
end if;
end loop;
end random_priority;
 
end ahb_funct;
 
 
 
/trunk/src/mst_wrap.vhd
0,0 → 1,227
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.std_logic_misc.all;
use ieee.std_logic_arith.all;
 
use std.textio.all;
 
use work.ahb_package.all;
 
entity mst_wrap is
generic (
--synopsys translate_off
dump_file: in string:= "mst_wrap.log";
dump_type: in integer:= dump_no;
--synopsys translate_on
ahb_max_addr: in integer:= 4;
--***************************************************************
--parameters for master access
--***************************************************************
m_const_lat_write: in integer:= 0;--0 latency states in write
m_const_lat_read: in integer:= 2;--2 cycles to get first data
m_write_burst: in integer := burst_support;--master accepts bursts in write!!!
m_read_burst: in integer := burst_support--master accepts bursts in read!!!
);
port (
hresetn: in std_logic;
clk: in std_logic;
conf: in conf_type_t;
dma_start: out start_type_t;
m_wrap_in: in wrap_out_t;
m_wrap_out: out wrap_in_t);
end mst_wrap;
 
architecture rtl of mst_wrap is
 
 
--synopsys translate_off
--***************************************************************
--**** DUMP OF MEMORY *******************************************
--***************************************************************
file file_descriptor : TEXT open WRITE_MODE is dump_file;
 
constant msg1: string(1 to 4):= "MEM ";
constant msg3: string(1 to 5):= "DATA ";
procedure Write_Message(msg1:string; addr:in integer; msg2:string; value:in integer) is
variable STR : line;
begin
write(STR,now);
write(STR,STRING'(" "));
write (STR, msg1);
write (STR, addr);
write(STR,STRING'(" "));
write (STR, msg2);
write (STR, value);
writeLine(file_descriptor, STR);
writeLine(OUTPUT, STR);
end Write_Message;
--***************************************************************
--***************************************************************
--synopsys translate_on
 
 
--***************************************************************
--configuration registers
--***************************************************************
signal hsize_reg: std_logic_Vector(2 downto 0);
signal priority_reg: std_logic;
signal hburst_reg: std_logic_Vector(2 downto 0);
signal hprot_reg: std_logic_Vector(3 downto 0);
signal trx_dir_reg: std_logic;
signal hlock_reg: std_logic;
signal extaddr: std_logic_Vector(31 downto 0);
signal intaddr: std_logic_Vector(15 downto 0);
signal intmod: std_logic_Vector(15 downto 0);
signal count_reg: std_logic_Vector(15 downto 0);
signal dma_go: std_logic;
--***************************************************************
--***************************************************************
 
type vect_32 is array (2**ahb_max_addr-1 downto 0) of std_logic_vector (31 downto 0);
signal mem : vect_32;
 
 
signal m_lat_write_ok, m_lat_read_ok: std_logic;
signal m_lat_write: integer range 0 to m_const_lat_write;
signal m_lat_read: integer range 0 to m_const_lat_read;
--***************************************************************
--***************************************************************
 
 
begin
--***************************************************************
--***************************************************************
--***************** master part *********************************
--***************************************************************
process(clk, hresetn)
begin
if hresetn='0' then
m_lat_write <= m_const_lat_write;
elsif clk'event and clk='1' then
if (m_wrap_in.take='1') then
if (m_lat_write_ok='0') then
m_lat_write <= m_lat_write-1 after 1 ns;
elsif (m_write_burst=1) then--accepts bursts .....
m_lat_write <= 0 after 1 ns;
else
m_lat_write <= m_const_lat_write after 1 ns;
end if;
else
m_lat_write <= m_const_lat_write after 1 ns;
end if;
end if;
end process;
 
m_lat_write_ok <= '1' when (m_lat_write=0) else '0';
m_wrap_out.take_ok <= '1' when (m_wrap_in.take='1' and m_lat_write_ok='1') else '0';
process(clk, hresetn)
begin
if hresetn='0' then
for i in 0 to 2**ahb_max_addr-1 loop
mem(i) <= conv_std_logic_vector(i, 32);
end loop;--i
elsif clk'event and clk='1' then
if (m_wrap_in.take='1' and m_lat_write_ok='1') then
mem(conv_integer(m_wrap_in.addr(2+ahb_max_addr-1 downto 2))) <= m_wrap_in.wdata after 1 ns;
--synopsys translate_off
if dump_type/=dump_no then Write_Message(msg1, conv_integer(m_wrap_in.addr(2+ahb_max_addr-1 downto 2)), msg3, conv_integer(m_wrap_in.wdata)); end if;
--synopsys translate_on
end if;
end if;
end process;
 
m_wrap_out.rdata <= mem(conv_integer(m_wrap_in.addr(2+ahb_max_addr-1 downto 2))) when (m_wrap_in.ask='1' and m_lat_read_ok='1') else (others => '-');
process(clk, hresetn)
begin
if hresetn='0' then
m_lat_read <= m_const_lat_read;
elsif clk'event and clk='1' then
if (m_wrap_in.ask='1') then
if (m_lat_read_ok='0') then
m_lat_read <= m_lat_read-1 after 1 ns;
elsif (m_read_burst=1) then--accepts bursts .....
m_lat_read <= 0 after 1 ns;
else
m_lat_read <= m_const_lat_read after 1 ns;
end if;
else
m_lat_read <= m_const_lat_read after 1 ns;
end if;
end if;
end process;
 
m_lat_read_ok <= '1' when (m_lat_read=0) else '0';
m_wrap_out.ask_ok <= '1' when (m_wrap_in.ask='1' and m_lat_read_ok='1') else '0';
 
 
 
 
--**************************************************************************
-- configuration registers write
--**************************************************************************
 
 
conf_reg_pr:process(hresetn, clk)
variable addr: std_logic_Vector(3 downto 0);
begin
if hresetn='0' then
hsize_reg <= bits32;
priority_reg <= slave;
hburst_reg <= incr;
hprot_reg <= "0011";
trx_dir_reg <= '0';
hlock_reg <= locked;
extaddr <= zeroes;
intaddr <= zeroes(15 downto 0);
intmod <= conv_std_logic_vector(4, intmod'length);--mod=+4(+1 word32)
count_reg <= zeroes(15 downto 0);
dma_go <= '0';
elsif clk'event and clk='1' then
if (conf.write='1') then
case conf.addr is
when dma_extadd_addr =>
extaddr <= conf.wdata;
when dma_intadd_addr =>
intaddr <= conf.wdata(15 downto 0);
when dma_intmod_addr =>
intmod <= conf.wdata(15 downto 0);
when dma_type_addr =>
priority_reg <= conf.wdata(12);
hsize_reg <= conf.wdata(11 downto 9);
hburst_reg <= conf.wdata(8 downto 6);
hprot_reg <= conf.wdata(5 downto 2);
trx_dir_reg <= conf.wdata(1);
hlock_reg <= conf.wdata(0);
when dma_count_addr =>
count_reg <= conf.wdata(15 downto 0);
when others => null;
end case;
end if;
if (conf.write='1' and conf.addr=dma_count_addr) then
dma_go <= '1';
else
dma_go <= '0';
end if;
end if;
end process;
--**************************************************************************
--**************************************************************************
 
 
--**************************************************************************
--**************************************************************************
dma_start.extaddr <= extaddr;
dma_start.intaddr <= intaddr;
dma_start.intmod <= intmod;
dma_start.hparams <= "000"&priority_reg&hsize_reg&hburst_reg&hprot_reg&trx_dir_reg&hlock_reg;
dma_start.count <= count_reg;
dma_start.start <= dma_go;
 
end rtl;
/trunk/docs/ahb_generator.pdf Cannot display: file marked as a binary type. svn:mime-type = application/octet-stream
trunk/docs/ahb_generator.pdf Property changes : Added: svn:mime-type ## -0,0 +1 ## +application/octet-stream \ No newline at end of property

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.