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