
別シリーズにてゲートレベル回路図の論理シミュレーションをやってみたらば結構よかったです。MOSトランシスタ記述も可能。昔ながらのシミュレータとはちょっと違う感じもしますが使いでが良いです。ただ「回路図レベル」です。とうに開発停止状態。そのシミュレータ出力をGo言語で変換してVCD波形ビューワーに接続してみました。
※かえらざるMOS回路 投稿順 INDEX
別シリーズ記事は以下です。デジタル信号処理のお勉強をしていたらゲートレベルの回路図で動作説明されていたので、その回路を論理シミュレーションしてみた、という流れです。
やっつけな日常(18) いまさらゲートレベル回路図で論理シミュレーションでもあるまいが
そのとき使用した論理シミュレータのWebページは以下です。HDL設計、あるいは高級言語設計主流の昨今、今更ゲートレベルの回路図を描いて論理シミュレーションする需要は少ないと思います。その中で良さげなシミュレータです。MOSトランスミッションゲートに加え、単体のMOSトランジスタもモデリング可能なので、本シリーズ再開にあたって「使える」かと思いました。
ただし2014年10月で、開発は “suspended indefinitely” です。それでもと納得すれば上記からソフトウエアをダウンロードして動作させることが可能です。
VCD波形ビューワーに接続したい
Logisimの使いでは気にいったのですが、不満点がないわけではありません。今回テコ入れしたかったのは、波形ビューワーへの接続です。
Logisimは論理回路動作の画面上でのデモかデバッグに適するインタラクティブなシミュレータです。しかしシミュレーション結果をファイルに落とすことは出来ます。出力は以下のような「タブラー」フォーマットです。
CLK INI D0 D1 D2 D3 1 1 1 0 0 0 0 1 1 0 0 0 0 0 1 0 0 0 1 0 0 1 0 0 0 0 0 1 0 0
こういうテーブル形式で結果が出てくればまあ大抵のことはできますな。
一方波形ビューワーで標準的なファイルフォーマットは、Verilogなどで使われるVCDと呼ばれるフォーマットではないかと思います。VCDフォーマットに変換できればVerilog等向けの波形ビューワーでシミュレーション波形を確認できるようになる筈。
今回VCDビュワーとして使わせていただいたのは、以下のフリーの波形ビューワーです。
テーブル形式からVCD変換ソフト、試作その1
今回は、別件記事で生成したテーブル形式出力をGTKWaveで読み込んで表示する「だけ」を目的にして変換ソフトを試作してみました。このところ勉強中のGo言語を使用です。やっつけなので制限おおありです(今後拡張予定。)
-
- 論理の階層構造などサポート無し
- バイナリのワイヤのみのサポート、バンドル、バスなどの取扱いなし
- 信号線の本数等制限大有り。
- 他にもバグあるだろ~(テストしてないです。)
まあ、Go言語プログラミングの勉強にはなりました。ホントか?
package main
import (
"bufio"
"flag"
"fmt"
"os"
s "strings"
"time"
)
type vcdTable struct {
titleLine []string
dataLine [][]string
}
func check(e error) {
if e != nil {
panic(e)
}
}
func (v *vcdTable) tableReader(fname string) {
f, err := os.Open(fname)
check(err)
defer f.Close()
scanner := bufio.NewScanner(f)
header := true
for scanner.Scan() {
lin := scanner.Text()
linSlice := s.Split(lin, "\t")
if header {
v.titleLine = linSlice
header = false
} else {
v.dataLine = append(v.dataLine, linSlice)
}
}
}
func (v *vcdTable) vcdWriter(fname string, modname *string) {
f, err := os.Create(fname)
check(err)
defer f.Close()
w := bufio.NewWriter(f)
wN := []string{"!", "\"", "#", "$", "%", "&", "'", "(", ")"}
w.WriteString("$date\n")
now := time.Now()
w.WriteString("\t")
w.WriteString(fmt.Sprint(now.Weekday()))
w.WriteString(" ")
w.WriteString(fmt.Sprint(now.Month()))
w.WriteString(" ")
w.WriteString(fmt.Sprint(now.Day()))
w.WriteString(" ")
w.WriteString(fmt.Sprint(now.Hour()))
w.WriteString(":")
w.WriteString(fmt.Sprint(now.Minute()))
w.WriteString(":")
w.WriteString(fmt.Sprint(now.Second()))
w.WriteString(" ")
w.WriteString(fmt.Sprint(now.Year()))
w.WriteString("\n")
w.WriteString("$end\n")
w.WriteString("$version\n")
w.WriteString("\tLogisim\n")
w.WriteString("$end\n")
w.WriteString("$timescale\n")
w.WriteString("\t100ns\n")
w.WriteString("$end\n")
w.WriteString("$scope module ")
w.WriteString(*modname)
w.WriteString(" $end\n")
for idx, fil := range v.titleLine {
w.WriteString("$var wire 1 ")
w.WriteString(wN[idx])
w.WriteString(" ")
w.WriteString(fil)
w.WriteString(" $end\n")
}
w.WriteString("$upscope $end\n")
w.WriteString("$enddefinitions $end\n")
w.WriteString("#0\n")
w.WriteString("$dumpvars\n")
for linN, linBody := range v.dataLine {
w.WriteString("#")
w.WriteString(fmt.Sprint((linN + 1) * 100))
w.WriteString("\n")
for idx, fil := range linBody {
w.WriteString(fil)
w.WriteString(wN[idx])
w.WriteString("\n")
}
}
w.Flush()
}
func main() {
opt1 := flag.Bool("OPT", false, "a bool")
optFile := flag.String("FIELD", "", "a file name")
modName := flag.String("MOD", "DUT", "a module name")
flag.Parse()
fmt.Println("OPT: ", *opt1)
fmt.Println("FIELD: ", *optFile)
fmt.Println("MOD: ", *modName)
fnameSlice := flag.Args()
fmt.Println("fnameSlice: ", fnameSlice)
if len(fnameSlice) > 1 {
fmt.Println("Table filename: ", fnameSlice[0])
fmt.Println("VCD filename: ", fnameSlice[1])
var vt vcdTable
vt.tableReader(fnameSlice[0])
vt.vcdWriter(fnameSlice[1], modName)
fmt.Println(vt.titleLine)
fmt.Println(vt.dataLine[0])
} else {
fmt.Println("Two File names needed.")
}
}
動作確認
Go言語はビルドして実行可能なOBJに落とすこともできますが、今回はまだ「習作」なのでスクリプト形式のまま実行しています。こんな感じ。
$ go run table2VCD.go M4LFSR_SIM.LOG a.vcd
引数 M4LFSR_SIM.LOG が別シリーズ記事で作ってあったテーブル形式ファイル名で、a.vcd が生成するVCDファイル名です。
生成した a.vcd ファイルをGTKWaveで表示させてみたところが以下に。
とりあえず、シミュレーションした結果を波形ビューワーで観察することは「できそうだ」(これから変換プログラムの機能追加していけば)ということで。
いつもの泥縄だな、自分。
