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

■ 実行方法
./実行ファイル モジュール名.txt ...(複数指定可能) <- 端子情報

■ 端子情報のフォーマット
各行は以下の4種類で空白行禁止。

hoge \t input
hoge[MSB:LSB] \t input
hoge \t input
hoge[MSB:LSB] \t output


#!/usr/bin/perl

# 実行方法
# ./実行ファイル モジュール名.txt ...(複数指定可能) <- 端子情報

# 端子情報のフォーマットは以下の4種類
# hoge \t input
# hoge[MSB:LSB] \t input
# hoge \t input
# hoge[MSB:LSB] \t output

use strict;
use warnings;
use File::Basename;

sub bus_gen;
sub port_gen;
sub portmap_gen;
sub entity_gen;
sub arch_gen;

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

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

foreach (@ARGV) {
my $infilename;
my $outfilename;
my @extlist;
my $dir;
my $ext;

# 入出力ファイル名決定
$infilename = $_;
@extlist = qw /.txt/;
($modname, $dir, $ext) = fileparse($infilename, @extlist);
$outfilename = $outdir . $modname . ".vhd";

# 入出力ファイルハンドル確保
open (INFILE, "<$infilename") || die "$infilename: $!";
open (OUTFILE, ">$outfilename") || die "$outfilename: $!";

# 入力ファイル内を走査
@signal = ();
@msb = ();
@lsb = ();
@inout = ();
$linenum = 0;
while (<INFILE>) {
chomp;

s/ //g; # スペース削除

my @line = split(/\t/, $_); # 各要素を展開

push(@inout, $line[1]); # INOUT格納
@line = split(/[\[:\]]/, $line[0]); # 信号名、MSB、LSBに分解
push(@signal, $line[0]); # 信号名格納
# MSB格納
if (defined($line[1])) { push(@msb, $line[1]); }
else { push(@msb, ""); }
# LSB格納
if (defined($line[2])) { push(@lsb, $line[2]); }
else { push(@lsb, ""); }

$linenum++;
}

# エンティティー宣言生成
entity_gen();

# アーキテクチャー宣言生成
arch_gen();

# 入出力ファイルハンドル開放
close (INFILE);
close (OUTFILE);

}

# バス幅記述生成
sub bus_gen {
my $idx = $_[0];
my $str;

# std_logic
if ($msb[$idx] eq "") { $str = "std_logic"; }
# std_logic_vector
else { $str = "std_logic_vector(" . $msb[$idx] . " downto " . $lsb[$idx] . ")"; }

return $str;
}

# ポート記述生成
sub port_gen {
my $sps = $_[0];
my $i;

print OUTFILE " " x $sps;
print OUTFILE "port (\n";

for ($i = 0; $i < $linenum; $i++) {
print OUTFILE " " x ($sps+$tab);
print OUTFILE $signal[$i];
print OUTFILE " " x ($signal_max - length($signal[$i]));
print OUTFILE ": $inout[$i] ";
print OUTFILE " " x (6 - length($inout[$i]));
print OUTFILE bus_gen($i);
print OUTFILE " " x (30 - length(bus_gen($i)));
if ($i != $linenum-1) { print OUTFILE "; --"; }
else { print OUTFILE " --"; }
print OUTFILE "\n";
}

print OUTFILE " " x $sps;
print OUTFILE ");\n";
}

# ポートマップ記述生成
sub portmap_gen {
my $sps = $_[0];
my $i;

print OUTFILE " " x $sps;
print OUTFILE "port map (\n";

for ($i = 0; $i < $linenum; $i++) {
print OUTFILE " " x ($sps+$tab);
print OUTFILE $signal[$i];
print OUTFILE " " x ($signal_max - length($signal[$i]));
print OUTFILE " => ";
print OUTFILE $signal[$i];
print OUTFILE " " x ($signal_max - length($signal[$i]));
if ($i != $linenum-1) { print OUTFILE ","; }
else { print OUTFILE " "; }
print OUTFILE " -- $inout[$i]";
print OUTFILE " " x (6 - length($inout[$i]));
print OUTFILE ");\n";
}

print OUTFILE " " x $sps;
print OUTFILE ");\n";
}

# エンティティー宣言生成
sub entity_gen {
print OUTFILE "library ieee;\n";
print OUTFILE "use ieee.std_logic_1164.all;\n";
print OUTFILE "use ieee.std_logic_unsigned.all;\n";
print OUTFILE "\n";

print OUTFILE "entity $modname is\n";
port_gen($tab);
print OUTFILE "end;\n";
print OUTFILE "\n";
}

# アーキテクチャー宣言生成
sub arch_gen {
print OUTFILE "architecture rtl of $modname is\n";
print OUTFILE " " x $tab;
print OUTFILE "-- constant description\n";
print OUTFILE " " x $tab;
print OUTFILE "-- signal description\n";
print OUTFILE " " x $tab;
print OUTFILE "-- component description\n";
print OUTFILE " " x $tab;
print OUTFILE "compnent $modname\n";
port_gen($tab);
print OUTFILE " " x $tab;
print OUTFILE "end compnent\n";
print OUTFILE "\n";
print OUTFILE "begin\n";
print OUTFILE "\n";

print OUTFILE " " x $tab;
print OUTFILE "-- \n";
print OUTFILE " " x $tab;
print OUTFILE "process (clk, rst) begin\n";
print OUTFILE " " x ($tab*2);
print OUTFILE "if (rst = '0') then\n";
print OUTFILE " " x ($tab*2);
print OUTFILE "elsif (clk'event and clk = '1') then\n";
print OUTFILE " " x ($tab*2);
print OUTFILE "end if;\n";
print OUTFILE " " x $tab;
print OUTFILE "end process;\n";
print OUTFILE "\n";

print OUTFILE " " x $tab;
print OUTFILE "$modname: $modname\n";
portmap_gen($tab);
print OUTFILE "\n";
print OUTFILE "end;\n";
}


テーマ : プログラミング
ジャンル : コンピュータ

2009-09-11 : Work-Linux-Perl : コメント : 0 : トラックバック : 0
Pagetop
コメントの投稿
非公開コメント

Pagetop
« next  ホーム  prev »

プロフィール

zive

Author:zive
大阪在住、男

ブログ検索

月別アーカイブ

FC2カウンター