ASIC/FPGA Design and Verification Out Source Services
Simple PERL script, which checks SD data write to flash.
-
For an SD slave
project
I needed to check, that during SD write transaction, the data is written to a flash correctly. The VHDL
test-bench
generates valid SD traffic. When it writes data, I print it to the simulation log.
The DUT then writes to flash. The flash
FMF VHDL model
prints a message also to the log, when it is written.
-
The log print messages are of the following format:
k9f1208_ghdl.vhd:1869:44:@1234199903ps:(assertion warning): FL: mem write of location 0 Pg 32 Ad 0 Da 5
T:SD write data DA3 00001010...011111111 DA2 00001010...011111111 DA2 ...
-
The PERL script scans the log file. When it detects a SD write message,
it creates an array of expected data. Each time, that the PERL script
finds a flash write message, it checks that it was written as expected.
-
The PERL script main loop is simple, because of subroutine usage.
-
- #!/bin/perl
- $fi="ghdl.log";
- open(FPR, $fi) || die("open fail $fi\n");
- #typical line to work on
- $ix=0;
- @sd_a = (); #sd array
- while(eof(FPR) != 1) {
- $line=; chomp($line);
- #SD 4 bits
- if($line =~ /SD write data DA3 ([0-1]*) DA2 ([0-1]*) DA1 ([0-1]*) DA0 ([0-1]*)/) {
- $b3=$1;
- $b2=$2;
- $b1=$3;
- $b0=$4;
- &sd_4($b3, $b2, $b1, $b0);
- }
- #SD 1 bit
- elsif($line =~ /SD write data DA0 ([0-1]*)/) {
- $b0=$1;
- &sd_1($b0);
- }
- #read flash data and check
- elsif($line =~ /FL: mem write of location ([0-9]*) Pg ([0-9]*) Ad ([0-9]*) Da ([0-9]*)/) {
- $loc=$1; $page=$2; $addr=$3; $dat=$4;
- $data=sprintf("%02X", $dat);
- if($data != $sd_a[$ix]) {
- print("flash loc $loc page $page addr $addr data $data sd $sd_a[$ix] $ix ko\n");
- }
- else {
- print("flash loc $loc page $page addr $addr data $data sd $sd_a[$ix] $ix ok\n");
- }
- $ix++;
- }
- }#while
- close(FPR);
-
The subroutines use sprintf to convert from binary to hex.
The subroutines use substr to work on bits.
The subroutines are shown below:
-
- sub sd_1 {
- my $a="";
- my $l="";
- my $s="";
- my $is="";
- $a=$_[0];
- $l=length($a);
- for($i=0; $i < $l; $i+=8) {
- $s=substr($a, $i, 8);
- $is="";
- for($j=0; $j < 8; $j++) {$is=$is . substr($s, 7-$j, 1);}
- $s=substr($is, 4, 4) . substr($is, 0, 4);
- $hex = sprintf('%02X', oct("0b$s"));
- #print("dbg sd 1 bit $hex\n");
- push(@sd_a, $hex);
- }#for
- }#sub sd_1
- sub sd_4 {
- my $a3=$_[0];
- my $a2=$_[1];
- my $a1=$_[2];
- my $a0=$_[3];
- my $l3="";
- my $sd_byte="";
- my $sz=0;
- my $l8="";
- print("$a3\n");
- print("$a2\n");
- print("$a1\n");
- print("$a0\n");
- $l3=length($a3); print("Collected $l3 bits per channel\n");
- #build a byte and check it
- $sd_byte="";
- for($i = 0; $i < $l3; $i++) {
- $sd_byte=$sd_byte . substr($a3, $i, 1);
- $sd_byte=$sd_byte . substr($a2, $i, 1);
- $sd_byte=$sd_byte . substr($a1, $i, 1);
- $sd_byte=$sd_byte . substr($a0, $i, 1);
- $l8=length($sd_byte);
- if($l8 == 8) {
- $hex = sprintf('%02X', oct("0b$sd_byte"));
- #print("dbg sd 4 bits $sd_byte $hex $sz\n");
- push(@sd_a, $hex);
- $sz++;
- $sd_byte="";
- }
- }#for
- }#sd_4
|