FC2ブログ

端子情報(端子表)からVerilogのRTLテンプレートを作成


#!/usr/bin/perl

use strict;
use warnings;
use Getopt::Std;
use File::Basename;

my $outdir = "./";
my $signal_max = 20;

my $modname;
my @signal;
my @msb;
my @lsb;
my @inout;
my $linenum;

my %opt = ();
getopts("hg", \%opt);
if ($opt{h}) { &help(); }
if ($opt{g}) {
foreach (@ARGV) {
my $infilename = $_;
&parse_txt($infilename);

my $outfilename;
my @extlist;
my $dir;
my $ext;
@extlist = qw /.txt/;
($modname, $dir, $ext) = fileparse($infilename, @extlist);
$outfilename = $outdir . $modname . ".v";
open (OUTFILE, ">$outfilename") || die "$outfilename: $!";
&gen_module();
&gen_interface();
&gen_connect();
close (OUTFILE);
}
}

sub help()
{
print << "ENDLINE";
Usage: ${0} [Optin]
Option:
-h :help
-g modulename.txt ... :making template
txt fomat is:
hoge \t input
hoge[MSB:LSB] \t input
hoge \t output
hoge[MSB:LSB] \t output
ENDLINE
}

sub parse_txt {
my $ifn = $_[0];

@signal = ();
@msb = ();
@lsb = ();
@inout = ();
$linenum = 0;

open (INFILE, "<$ifn") || die "$ifn: $!";
while (<INFILE>) {
chomp;

s/ //g;

my @line = split(/\t/, $_);

push(@inout, $line[1]);
@line = split(/[\[:\]]/, $line[0]);
push(@signal, $line[0]);
if (defined($line[1])) { push(@msb, $line[1]); }
else { push(@msb, ""); }
if (defined($line[2])) { push(@lsb, $line[2]); }
else { push(@lsb, ""); }

$linenum++;
}
close (INFILE);
}

sub gen_module {
my $i;

print OUTFILE "module $modname\n";
print OUTFILE "(\n";

for ($i = 0; $i < $linenum; $i++) {
print OUTFILE " " x 4 . $signal[$i];
if ($i != ($linenum - 1)) { print OUTFILE " " x ($signal_max - length($signal[$i])) . ","; }
print OUTFILE "\n";
}

print OUTFILE ");\n\n";
}

sub gen_interface {
my $i;
my $max = 0;
my $str;
my $size;

for ($i = 0; $i < $linenum; $i++) {
$str = " " x 4;
if ($inout[$i] eq "in") { $inout[$i] = "input"; }
if ($inout[$i] eq "out") { $inout[$i] = "output"; }
$str = $str . $inout[$i];
if ($inout[$i] eq "input") { $str = $str . " " x 3; }
elsif ($inout[$i] eq "output") { $str = $str . " " x 2; }
if ($msb[$i] ne "" && $lsb[$i] ne "") { $str = $str . "[" . $msb[$i] . ":" . $lsb[$i] . "]" }
$str = $str . " ";
$size = length($str);
if ($max < $size) { $max = $size; }
}

for ($i = 0; $i < $linenum; $i++) {
$str = " " x 4;
$str = $str . $inout[$i];
if ($inout[$i] eq "input") { $str = $str . " " x 3; }
elsif ($inout[$i] eq "output") { $str = $str . " " x 2; }
if ($msb[$i] ne "" && $lsb[$i] ne "") { $str = $str . "[" . $msb[$i] . ":" . $lsb[$i] . "]" }
$size = length($str);
$str = $str . " " x ($max - $size) . $signal[$i] . " " x ($signal_max - length($signal[$i])) . ";";
print OUTFILE $str;
if ($inout[$i] eq "input") { print OUTFILE " // I :\n"; }
elsif ($inout[$i] eq "output") { print OUTFILE " // O :\n"; }
}

print OUTFILE "endmodule\n\n";
}

sub gen_connect {
my $i;
my $max = 0;
my $str;
my $size;

print OUTFILE $modname . " " . $modname . "\n";
print OUTFILE "(\n";

for ($i = 0; $i < $linenum; $i++) {
$str = " " x 4;
$str = $str . "." . $signal[$i];
$str = $str . " ";
$size = length($str);
if ($max < $size) { $max = $size; }
}

for ($i = 0; $i < $linenum; $i++) {
$str = " " x 4;
$str = $str . "." . $signal[$i];
$size = length($str);
$str = $str . " " x ($max - $size);
$str = $str . "(" . $signal[$i] . " " x ($signal_max - length($signal[$i]));
print OUTFILE $str;
if ($i != ($linenum - 1)) { print OUTFILE "),"; }
else { print OUTFILE ") "; }
if ($inout[$i] eq "input") { print OUTFILE " // I :\n"; }
elsif ($inout[$i] eq "output") { print OUTFILE " // O :\n"; }
}

print OUTFILE ");\n\n";
}

2018-10-30 : Work-Linux-Perl : コメント : 0 : トラックバック : 0
Pagetop
コメントの投稿
非公開コメント

Pagetop
« next  ホーム  prev »

プロフィール

zive

Author:zive
大阪在住、男

ブログ検索

月別アーカイブ

FC2カウンター