From f07525840dd7aa46b11deabcba53ab3428a383aa Mon Sep 17 00:00:00 2001 From: Sebastian Date: Tue, 3 Sep 2013 21:46:47 +0200 Subject: [PATCH] hdf2arch.pl: initial commit (processor, memory) The utility hdf2arch.pl read the Hardware Description File from the Epiphany SDK and generates a DOL architecture specification in XML format. example: $ ./hdf2arch.pl zed_E16G3_512mb.hdf epiphany.xml This specifies the and elements for every eCore in the Epiphany (called "core_row_col" and "mem_row_col") as well as for the host cpu and the shared DRAM (called "arm_0" and "shm_0") and includes some basic sanity checking of the HDF. The generated file does not specify any , or tags and does not need any flattening. Since the HDF file does not contain any information about the amount of local SRAM or even the number of cores in the Epiphany, new chips will need to be added to this utility. The ARM (with 2 cores) is hard coded, though. --- hdf2arch/hdf2arch.pl | 189 +++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 189 insertions(+) create mode 100755 hdf2arch/hdf2arch.pl diff --git a/hdf2arch/hdf2arch.pl b/hdf2arch/hdf2arch.pl new file mode 100755 index 0000000..d1bc54d --- /dev/null +++ b/hdf2arch/hdf2arch.pl @@ -0,0 +1,189 @@ +#!/usr/bin/perl -w +use strict; +use v5.010; + +use XML::Simple qw(:strict); +use Data::Dumper; + +my $infile = shift; +my $outfile = shift; +my $data; + +# supported chips +my $chips = { + 'E16G301' => { + 'cores' => [4, 4], + 'sram' => '0x8000', + }, + 'E64G401' => { + 'cores' => [8, 8], + 'sram' => '0x8000', + }, +}; + +# parse arguments +if(!$infile || !$outfile) { + say "Usage: hdf2arch "; + say "\tinfile: Epiphany HDF file"; + say "\toutfile: DOL XML file"; + say "\tSpecify '-' to use standard input/output"; + exit 1; +} + +# parse HDF file +my $num_chips; # number of chips in system +my @chiplist; # information about current chip +my $chipnum = -1; # current chip +my $num_emems; # number of emems in system +my @ememlist; # information about current emem +my $ememnum = -1; # current emem +open (FH, "<$infile") or die("Can't open $infile."); +while() { + next if /\/\/.*/; # skip comment lines + + # globals - ignore them for now + #$data->{'version'} = $1 if(/^PLATFORM_VERSION\s+(\S+)\s*$/); + #$data->{'regbase'} = $1 if(/^ESYS_REGS_BASE\s+(\S+)\s*$/); + + + # number of chips + if(/^NUM_CHIPS\s+(\S+)\s*$/) { + if(!$num_chips) { + $num_chips = $1; + } else { + say STDERR "Warning: multiple 'NUM_CHIPS' entries!"; + } + } + + # per-chip information + if(/^CHIP\s+(\S+)\s*$/) { + my $id = $1; + if($chips->{$id}) { + $chipnum++; + $chiplist[$chipnum]->{'id'} = $id; + $chiplist[$chipnum]->{'rows'} = + $chips->{$id}->{'cores'}->[0]; + $chiplist[$chipnum]->{'cols'} = + $chips->{$id}->{'cores'}->[1]; + $chiplist[$chipnum]->{'sram'} = $chips->{$id}->{'sram'}; + } else { + say STDERR "Warning: unknown CHIP '$id' - ignoring!"; + next; + } + } + $chiplist[$chipnum]->{'row'} = $1 if(/^CHIP_ROW\s+(\S+)\s*$/); + $chiplist[$chipnum]->{'col'} = $1 if(/^CHIP_COL\s+(\S+)\s*$/); + + # number of emems + if(/^NUM_EXT_MEMS\s+(\S+)\s*$/) { + if(!$num_emems) { + $num_emems = $1; + } else { + say STDERR "Warning: multiple 'NUM_EXT_EMEM' entries!"; + } + } + + + # per-emem information + if(/^EMEM\s+(\S+)\s*$/) { + my $id = $1; + if($id eq 'ext-DRAM') { + $ememnum++; + $ememlist[$ememnum]->{'id'} = $id; + } else { + say STDERR "Warning: unknown EMEM '$id' - ignoring!"; + next; + } + } + $ememlist[$ememnum]->{'base'} = $1 if(/^EMEM_BASE_ADDRESS\s+(\S+)\s*$/); + $ememlist[$ememnum]->{'epi'} = $1 if(/^EMEM_EPI_BASE\s+(\S+)\s*$/); + $ememlist[$ememnum]->{'size'} = $1 if(/^EMEM_SIZE\s+(\S+)\s*$/); + $ememlist[$ememnum]->{'type'} = $1 if(/^EMEM_TYPE\s+(\S+)\s*$/); +} + +# some simple consistency checks +if($num_chips != scalar @chiplist) { + say STDERR "Warning: NUM_CHIPS does not match the number of CHIPs!"; +} +if($num_emems != scalar @ememlist) { + say STDERR "Warning: NUM_EXT_MEMS does not match the number of EMEMs!"; +} + +# generate output data +$data->{'processor'} = []; +$data->{'memory'} = []; + +# host processor, epiphany cores and their memories +push $data->{'processor'}, { + 'name' => 'arm_0', + 'type' => 'RISC', + 'configuration' => [ + { 'name' => 'cores', + 'value' => '2' }, + ], +}; + +for my $chip(@chiplist) { + for my $row (0..$chip->{'rows'}-1) { + for my $col (0..$chip->{'cols'}-1) { + my $r = $chip->{'row'} + $row; + my $c = $chip->{'col'} + $col; + push $data->{'processor'}, { + 'name' => "core_${r}_${c}", + 'type' => 'RISC', + 'configuration' => [ + { 'name' => 'type', + 'value' => $chip->{'id'}, }, + ], + }; + + push $data->{'memory'}, { + 'name' => "mem_${r}_${c}", + 'type' => 'RAM', + 'configuration' => [ + { 'name' => 'size', + 'value' => $chip->{'sram'}, }, + ], + }; + } + } +} + +# external memories +for my $idx(0..(scalar @ememlist-1)) { + push $data->{'memory'}, { + 'name' => "shm_$idx", + 'type' => "RAM", + 'configuration' => [ + { 'name' => 'size', + 'value' => $ememlist[$idx]->{'size'} }, + { 'name' => 'type', + 'value' => $ememlist[$idx]->{'type'} }, + { 'name' => 'base', + 'value' => $ememlist[$idx]->{'base'} }, + { 'name' => 'epibase', + 'value' => $ememlist[$idx]->{'epi'} }, + ], + }; +} + +#say Dumper $data; + +# write data in xml format +$data->{'name'} = 'Adapteva Parallella Architecture'; +$data->{'xmlns'} = 'http://www.tik.ee.ethz.ch/~shapes/schema/ARCHITECTURE'; +$data->{'xmlns:xsi'} = 'http://www.w3.org/2001/XMLSchema-instance'; +$data->{'xsi:schemaLocation'} = 'http://www.tik.ee.ethz.ch/~shapes/schema/ARCHITECTURE http://www.tik.ee.ethz.ch/~shapes/schema/architecture.xsd'; +my $outxml = "\n". + XMLout({'architecture' => $data}, + KeyAttr => [], + KeepRoot => 1); + +if($outfile eq '-') { + say $outxml; + exit 0; +} else { + open (FH, ">$outfile"); + say FH $outxml; + close (FH); +} -- 2.30.2