ログイン
ユーザ名:

パスワード:


パスワード紛失

新規登録
Main Menu
Tweet
Facebook
Line
:-?
« 1 (2) 3 4 »
スレッド表示 | 新しいものから 前のトピック | 次のトピック | 下へ
投稿者 スレッド
webadm
投稿日時: 2008-2-8 12:47
Webmaster
登録日: 2004-11-7
居住地:
投稿: 3093
検証開始
一応論理合成とPlace & Routeが出来たので、動かすことは出来るがいきなり実機でやることは普通しない。

一発で動けば良いが、ここまで来るまでの間にもいろいろ仕様検討時のミスが発見されているので、他にも潜んでいる可能性は大である。実機でやって意図した通り動かなければやはり時間の無駄である。

普通は次ぎの段階としてシミュレーションテストを行うためにテストベンチモジュールを作成することになる。

テストベンチモジュールは今回出来たシグネチャアナライザモジュールを下位モジュールとして入力信号を与えて出力信号を検査するシミュレーション用のトップモジュールである。

以前に1万年カレンダー時計をやった時はこれが面倒でテスト波形を入力してやっていた。

実はQuartusにはtest bench template writerという機能があることに今更ながら知って、それを使わない手はないと思った。

ProcessingのStartメニューでTest Bench Template Writerというのを選択すると自動的に現在のデザインのトップモジュールを駆動するためのテストベンチモジュールのひな形を生成してくれる。

あとはテストケースに応じた信号を駆動するための肉付けをすれば良いということになる。

いやはや至れり尽くせりである。

ソフトウェア開発ツールにもこういうのがないものかのう。

satop.vt:テストベンチトップモジュール(自動生成)

// Copyright (C) 1991-2007 Altera Corporation
// Your use of Altera Corporation's design tools, logic functions
// and other software and tools, and its AMPP partner logic
// functions, and any output files from any of the foregoing
// (including device programming or simulation files), and any
// associated documentation or information are expressly subject
// to the terms and conditions of the Altera Program License
// Subscription Agreement, Altera MegaCore Function License
// Agreement, or other applicable license agreement, including,
// without limitation, that your use is for the sole purpose of
// programming logic devices manufactured by Altera and sold by
// Altera or its authorized distributors. Please refer to the
// applicable agreement for further details.

// *****************************************************************************
// This file contains a Verilog test bench template that is freely editable to
// suit user's needs .Comments are provided in each section to help the user
// fill out necessary details.
// *****************************************************************************
// Generated on "02/08/2008 03:41:48"

// Verilog Test Bench template for design : satop
//
// Simulation tool : ModelSim-Altera (Verilog)
//

`timescale 1 ps/ 1 ps
module satop_vlg_tst();
// constants
// general purpose registers
reg eachvec;
// test vector input registers
reg clk;
reg clock_pol;
reg hold;
reg reset;
reg sa_clock;
reg sa_data;
reg sa_start;
reg sa_stop;
reg start_pol;
reg stop_pol;
// wires
wire [3:0] led_com;
wire led_data;
wire led_gate;
wire [6:0] led_seg;
wire led_unstable;
wire test_clock;
wire test_data;
wire test_start;
wire test_stop;

// assign statements (if any)
satop i1 (
// port map - connection between master ports and signals/registers
.clk(clk),
.clock_pol(clock_pol),
.hold(hold),
.led_com(led_com),
.led_data(led_data),
.led_gate(led_gate),
.led_seg(led_seg),
.led_unstable(led_unstable),
.reset(reset),
.sa_clock(sa_clock),
.sa_data(sa_data),
.sa_start(sa_start),
.sa_stop(sa_stop),
.start_pol(start_pol),
.stop_pol(stop_pol),
.test_clock(test_clock),
.test_data(test_data),
.test_start(test_start),
.test_stop(test_stop)
);
initial
begin
// code that executes only once
// insert code here --> begin

// --> end
$display("Running testbench");
end
always
// optional sensitivity list
// @(event1 or event2 or .... eventn)
begin
// code executes for every event on sensitivity list
// insert code here --> begin

@eachvec;
// --> end
end
endmodule

webadm
投稿日時: 2008-2-8 22:13
Webmaster
登録日: 2004-11-7
居住地:
投稿: 3093
波形入力(Quartus Simulator)でやってみた
もしかして一発でOKかもしれないという思いから手っ取り早くその答えを知るために波形入力でシミュレーションをやってみた。

後で同じ波形を与えるテストベンチテンプレートを自動作成できるので慣れているこの方法がやりやすい。

とりあえず4桁のLEDが全部表示し終わる程度の時間をシミュレーションすることにし、SA_CLOCK入力はHP5004Aの仕様上限と同じ25MHzを与え、RESET入力のアサートとデアサート、それにSA_START/STOPのパルスを65536クロック周期で与える。その間はSA_DATAは1のまま。

おそらくLED表示コントローラー部分は何の問題も無く動作するだろう、以前に1万年カレンダー時計で培った回路なので。他は動く事は動くだろうけど疑問符がつくことは否めない。

やってみたら、回路が小さいので意外とシミュレーションが短時間で終わった。

そして結果をみたら、やはり表示コントローラーはまじめに動作しているくさい。しかし次ぎの瞬間、驚愕の事実が発覚。



まずステートマシンがしょっぱな誤動作している...orz

いきなりS00,S01どちらも1になっている。よく考えたらRESETがアサートされたらS00に戻るようにしていたのにそこからして意図した動きになっていない。

S00がONになりっぱなしのままS11がON次いでS11がOFFになって代わりにS10がONになるのはまあいいとして、S10がONになったとたんにCLEARが繰り返しトグルし始めた。なんだこれは。結局このために以降シフトレジスタが意図していた通り動かなくなってしまっている。

ステートマシンに問題有りだな。シミュレーション以前の問題かもしれないので見直すことにしよう。

自分で書いたコードは動くと信じたいよね、しかしそうはいかないのが世の常。

webadm
投稿日時: 2008-2-8 22:51
Webmaster
登録日: 2004-11-7
居住地:
投稿: 3093
ステートマシンの問題(その1)
ステートマシンからのCLEAR出力が繰り返しトグルする原因が判明した。

仕様段階では正論理で考えていたCLEAR信号を実装時に負論理にしたのだが、その時に頭で考えたドモルガンの定理による論理式の書き換えが間違っていた...orz

仕様では正論理で

CLEAR = (STOP & !CLOCK) | RESET

だったのをCLEARとRESETを負論理に書き換えた際に

clear = (!stop & clock) & reset

としていたのだが、本来は

clear = (!stop | clock) & reset

であった。

このように修正すると異常なトグル動作は無くなったが別の問題が発覚。



計測終了時のCLEARパルス幅が予想より短くて、直後にSHIFTパルスがヒゲのように余分に出てしまっている。このためせっかくリセットされたシフトレジスタが誤動作してしまい、初期値が0でなくなってしまっている。

仕様上でCLEARパルスが半クロックサイクルしか出ないようにしたのが良くないので、初期状態ではCLEARはアサートしたままに変更したほうが良いかもしれない。

それにして計測終了時に状態値レジスタが全部OFFになってしまうのは何故だろう? もしかしてそのままバイナリなのか?

しかし何故4ビットある?
webadm
投稿日時: 2008-2-9 5:23
Webmaster
登録日: 2004-11-7
居住地:
投稿: 3093
Re: ステートマシンの問題(その1)
このプロジェクトはもとはと言えば、おジャンクなHP3456Aの故障原因を突き止めるためにサービスマニュアルにあるシグネチャアナライザを使った故障診断を行うのが目的だった。

で以前から気になっていたのだが、HP3456AのサービスマニュアルのROMシグネチャの測定のところでプローブを+5Vに接続して測定した場合にシグネチャ値は0003になる、と書いてある。

HP3456AのROMシグネチャの測定ではROMアドレス空間である上位32KBの時にアサートされるA15をSA START/STOP信号として使用する。SA CLOCKはシステムクロックで6MHzを4分周した1.5MHzである。ROMシグネチャアナリシス中はCPUはフリーランするのでSA START/STOPのパルス周期は65KB分、すなわち65536サイクルということになる。

実は疑似乱数生成回路があっているか確かめるためにC言語で等価なプログラムを書いて65536サイクル分data=1固定でシグネチャ値を生成したらいくつになるか調べてみたら、64KB目には初期値0に戻ってしまうことがわかった。これだと違う。本当は0003になって欲しいのだが。

今回の回路はHP5004Aの回路図を苦労して読み取って等価な回路にしたつもりだったのだが、何か違うのだろうか悩んだ。しかしやはり同じだという結論しか出てこない。

ふと今回のシミュレーション結果で計測終了時にシフトレジスタが0にクリアされた直後にヒゲでシフトレジスタが一回動作してしまい初期値が0000ではなく0001になってしまうことが発覚してふと気づいた。

初期値が0000ではなく0001なら65536サイクル後にシグネチャ値はいくつになるのだろうか?

やってみたら見事に0003になった。

つまりこれはHP5004Aの仕様そのままであるということだ。

オリジナルの回路を見てもやはりヒゲは出てしまう。ヒゲも仕様のうちに含まれていたのだったのだ。

なのでこれはこのままで良いことにする。

他に気づいた点がいくつもあるのでそちらをなんとかしよう。
webadm
投稿日時: 2008-2-9 11:25
Webmaster
登録日: 2004-11-7
居住地:
投稿: 3093
Re: ステートマシンの問題(その1)
例の状態値レジスタが4つ生成されている件は、コンパイル結果のState Machinesを見ることによって、One Hotステートマシンが生成されているのに間違いないことが判明。



S00の時はすべて0で、他はどれか2つが1で残りは0という組み合わせらしい。

いずれの状態に遷移しても同時に変化するビットは2ビットだけということになるのでOne Hotに間違いない。

これはこれでクローズ。
webadm
投稿日時: 2008-2-9 11:34
Webmaster
登録日: 2004-11-7
居住地:
投稿: 3093
だいたい動くことを確認
一カ所ステートマシンの出力信号の式が間違っていた点を除けばほぼ大きな問題は無いとみた。

もうこれで意図した通り動くと思われるで厳密にテストベンチでいろんなケースを試すよりは実際に装置を組んで実機で試してみたほうが良いかもしれない。

シミュレーションで確認していないのはテスト信号出力だけど、これは当面使う予定は無い。

とりあえずHP3456AのROMシグネチャの確認をしたい。新しく作ったROM基板が間違いないか確認したいのである。そうすれば故障原因は他にあるということで切り分けができる。

当初実機は1万年カレンダーを流用と考えていたが、あれは結構がさばるので実際に測定しようと思うと置き場所に困る。

この際、専用の基板をユニバーサルボードでこしらえて、LEDや入力信号コネクタやスイッチをつけて、そこにトラ技付録のMAX II基板をのせるとしよう。LEDは余っているし。

回路図を描いて部品を買って半田付けするだけである。
webadm
投稿日時: 2008-2-10 13:05
Webmaster
登録日: 2004-11-7
居住地:
投稿: 3093
タイミングアナライザーがひどいことに
普通はシミュレーションの前にタイミングアナライザーのチェック結果を見る。

見てみたら真っ赤だった...orz

クロック系信号の条件を設定していなかったのもあるが、ちゃんと設定してもどうしても疑似乱数生成器のシフトレジスタに前段のデータラッチの出力をサンプル際にホールドタイムを満たさないというもの。



なんでhold timeバイオレーションがこんなにでるんだ?


そんなはずはと、オリジナルのHP5004Aの回路図を改めてみたら、データのラッチはDFFではなくJKFFであるが、これはプローブ入力を2つのコンパレータ(HレベルとLレベル)の出力をJ,Kに接続しているだけなので、出力の変化タイミングはクロックエッジに同期している点ではDFFと変わらない。



今時のロジックICはhold timeは0なのでsetupが満たせば良いと思うのだが、何故かhold違反が出る。

よく考えれば当たり前だった。プローブデータ(sa_data)はsa_clockをclock_polとxorしたclock信号でサンプルするので疑似乱数生成器にその出力が変化するのはclock立ち上がりの後になる。一方疑似乱数生成器のシフトレジスタをシフトするのはclock信号を状態値でandしたshift信号でサンプルするので、立ち上がりがclockの立ち上がりから更に遅れる。このあたりのタイミングはPlace & Routeの結果によって配線遅延でレースが発生してしまう。一番良くない設計パターンだ。

というかやはりFPGA内部で非同期信号を扱うともう大変過ぎ。

あっち直せば今度はこっちにしわ寄せが出るとかいうイタチごっこになってくる。

根本的にだめくさい...orz
webadm
投稿日時: 2008-2-10 14:22
Webmaster
登録日: 2004-11-7
居住地:
投稿: 3093
タイミングアナライザの問題はクリア
諸悪の根元は疑似乱数生成器のシフトレジスタをシフトするクロックとしてゲーテドクロック(shift)を生成しているのがいただけなかった。

オリジナルのHP5004Aでは実際そうしているのだけれどもFPGAで同じことをやってもPlace & Routeの結果配線遅延が変わってくると同じ動きをする保証は無くなる。

まずゲーテドクロックを使うのをやめて、イネーブル付きのシフトレジスタを構成するように仕様を改める。

今度からステートマシンが出力するshift信号はゲーテドクロックではなく、単なる疑似乱数生成イネーブル信号ということにする。これは従来のled_gate信号と同じなのでled_gate信号は廃止してshift信号でled_gate信号ピンをドライブするように変更。

最後に疑似乱数生成器にclock信号を入力し、shift信号がアサートされている時のみclock信号の立ち上がりでシフトレジスタをシフトするように変更。

変更したソースは以下の通り。

satop.v:シグネチャアナライザトップ

引用:
module satop(sa_clock, sa_start, sa_stop, sa_data,
clock_pol, start_pol, stop_pol,
clk, reset, hold,
test_clock, test_start, test_stop, test_data,
led_seg, led_com,
led_gate, led_unstable, led_data);

// Input Port(s)
input sa_clock, sa_start, sa_stop, sa_data;
input clock_pol, start_pol, stop_pol;
input clk, reset, hold;

// Output Port(s)
output test_clock, test_start, test_stop, test_data;
output [6:0] led_seg;
output [3:0] led_com;
output led_gate, led_unstable, led_data;

wire clock, start, stop, data, clear, shift, dclock;
wire [15:0] prn;
wire [3:0] dcount;

// Parameter Declaration(s)

// Additional Module Item(s)
assign led_gate = shift;

edgesel edgesel(sa_clock, sa_start, sa_stop,
clock_pol, start_pol, stop_pol,
reset, clock, start, stop);
sm sm(clock, start, stop, hold, reset, clear, shift);
prg prg(clear, clock, shift, data, reset, prn);
dc dc(prn, dcount, led_seg, led_com, led_unstable);
dl dl(sa_data, clock, reset, dclock, data, led_data);
stosc stosc(clk, dcount, dclock, test_clock, test_start, test_stop, test_data);

endmodule


sm.v:ステートマシン

引用:
module sm(clock, start, stop, hold, reset, clear, shift);

input clock, start, stop, hold, reset;

output reg clear, shift;

// Declare state register
reg [1:0]state;

// Declare states
parameter S00 = 0, S01 = 1, S10 = 2, S11 = 3;

// Determine the next state synchronously, based on the
// current state and the input
always @ (posedge clock) begin
if (!reset)
state <= S00;
else
case (state)
S00:
if (!start)
begin
state <= S01;
end
else
begin
state <= S00;
end
S01:
if (start)
begin
if (!stop)
begin
state <= S10;
end
else
begin
state <= S11;
end
end
else
begin
state <= S01;
end
S10:
if (stop && !hold)
begin
state <= S00;
end
else
begin
state <= S10;
end
S11:
if (!stop)
begin
state <= S10;
end
else
begin
state <= S11;
end
endcase
end

// Determine the output based only on the current state
// and the input (do not wait for a clock edge).
always @ (state or stop or clock or reset)
begin
case (state)
S00:
begin
clear = reset;
shift = 0;
end
S01:
begin
clear = reset;
shift = 0;
end
S10:
begin
clear = (!stop | clock) & reset;
shift = 1;
end
S11:
begin
clear = reset;
shift = 1;
end
endcase
end

endmodule


prg.v:疑似乱数生成モジュール

引用:
module prg(clear, clock, shift, data, reset, prn);

input clear, clock, shift, data, reset;

output reg [15:0] prn;

// Declare the shift register
reg [15:0] sr;

// Shift everything over, load the incoming bit
always @ (posedge clock or negedge clear or negedge reset)
begin
if (!clear | !reset)
begin
sr <= 0;
end
else if(shift)
begin
sr[15:1] <= sr[14:0];
sr[0] <= data ^ sr[6] ^ sr[11] ^ sr[12] ^ sr[15];
end
end

always @ (negedge clear or negedge reset)
begin
if (!reset)
begin
prn <= 0;
end
else
begin
prn <= sr;
end
end

endmodule


タイミングアナライザの結果は以下の通り



RTL Viewerで全体を見るとled_gateがshiftとつながっているのとprgにclock信号につながっている点を除いて従来と変わらない。



今回貢献したのはイネーブル付きのシフトレジスタにしたこと。



良いことずくめのようだが副作用もある。



自慢のヒゲが無くなってしまった。

まあこれは後日実際に動作させてみて必要であればシフトレジスタをリセットする際の初期値にdataを取り込むようにすれば良い。



webadm
投稿日時: 2008-2-11 2:57
Webmaster
登録日: 2004-11-7
居住地:
投稿: 3093
周辺回路の設計
MAX II CPLDでシグネチャアナライザの基本回路が実装できたので、シグネチャアナライザ装置として必要な周辺回路基板を設計しないと実用にならない。

すぐさま信号をつなげてみたい気持ちははやるが、罠がある。

MAX II CPLDは古いCPLDやFPGAと違って新しいので5V動作ではないという点。

電源電圧が3.3Vなのでそれより高い入力電圧を加えると破壊されてしまう。

従って外部の入力信号からCPLDを保護するための回路が必要となる。

トラ技付録のMAX II基板にもJTAG関連の信号接続で同様の対策が施されている。東芝の74VHCシリーズの標準ICを使ってレベル変換及び入力保護を行っている。

特にやばいのがCPLDに電源が供給されていない状態でうっかり動作中の測定対象機器から信号をつなぎ込んでしまうケース。相手は古いTTLレベルでドライブ能力もCMOSに比べたら大きいので一瞬にして大電流がCPLDのI/Oブロックに流れ込んで破壊してしまうことが予想される。

出力はLVTTLなのでLEDを点す程度なら問題無い。あまりCPLDから電流を取ると誤動作と故障の原因になるので、外付けトランジスタをドライブする形とする。

実際に回路を実装するときには74VHCシリーズがフラットパッケージなので変換基板とかを必要とするかもしれない。ちょっと直付けは自信が無い。

LEDのCOMMONとSEGMENTの駆動用のトランジスタもバカにならない数となる。COMMON側は複数のSEGMENTに流れる電流の総和となるのでON抵抗を下げるために電流増幅率の大きなダーリントン接続回路を使用する。

単体LEDは直接CPLDからドライブできるがそれでもかなり電流を流すことになるので駆動用トランジスタを外付けする形とする。

まあそこまでやる必要はないのかもしれないけど、虎の子のMAX II基板なので壊れると痛い。
webadm
投稿日時: 2008-2-11 4:12
Webmaster
登録日: 2004-11-7
居住地:
投稿: 3093
表示用の基準クロック
シグネチャアナライザーはLEDのダイナミック点灯用に低速な基準クロックを必要とする。

MAX IIの場合にはこうした厳密な精度を求めないクロック発生源であれば内部のオシレーターを使うという手がある。

QuartusのToolメニューからMegawizard Plug-In Managerを起動してCreate custum Megafunctionを選択するとI/O Megafunctionの中にMAX II oscillatorというのがある。



これを選択してオシレーターを利用するためのモジュールを作成してくれる。これを使うにはトップモジュールでインスタンス化して出力信号をクロック源が必要な他のモジュールの入力につなげてやればよい。

これを使うとトップモジュールはAltera MaxII専用になってしまうが、下位は影響を受けないのでこれも有りである。

どうしてもベンダー固有の機能は使いたくない場合は、物理的に外付けのクロック源を用意する必要がある。トラ技付録CPLD基板にはそれもあるので任意の周波数のXOSCを差し込んでクロック源として使うことができる。
« 1 (2) 3 4 »
スレッド表示 | 新しいものから 前のトピック | 次のトピック | トップ

投稿するにはまず登録を
 
ページ変換(Google Translation)
サイト内検索