10.ポストレイアウト遅延シミュレーション
論理合成した最大周波数で駆動してみましょう。
ところで、最初のTRYでは、Stratix、CYCLONEは通ったもののStratixUは走りませんでした。StratixUが走らなかったのは、H8プロジェクトに続いて2回目です。H8プロジェクトで行ったStratixU用の記述は既に実施済みだったので別なエラーです。
解析したところ(全ての信号が動いていなかったのですぐ分かりました)、sync_resetが次の記述で、StratixUでは HIGHになったままになってしまいました。(CYCLONEや、Stratixでは、問題なく遅延シミュレーションが通っています)
//sync_reset always @(posedge clock , negedge Async_Reset) begin if (!Async_Reset) sync_reset <=1'b1; else sync_reset <=!Async_Reset; end |
上記でも、問題ない記述の筈ですが、StratixUが通るように次のように書き換えました。
//Jul.29.2004 always @(posedge clock ) begin // if (!Async_Reset) sync_reset <=1'b1; /* else*/ sync_reset <=!Async_Reset; end |
この記述でStratixUで合成してみました。RAMは4KB です。156.1MHz(6.406ns)です。
ゲートシミュレーションのプロジェクトを作成します。
stratixii_atoms.vは、Quartusインストール環境にあります。同じドライブにないときは、COPYして持ってきます。
とりあえず、最大駆動周波数で駆動するために、テストベンチのクロック駆動部を次のように書き換えます。
`define CYCLE (6.406/2) //6.406 always #(`CYCLE) clock=~clock; |
シミュレーションを行います。
下がそのログ(一回目のRUN)ですが、文字化けしています。Simulation自体は、進んでいるようなので、出力遅延が疑わしいです。
出力の遅延パスは、
テストベンチCLOCK=>内部REGISTER=>内部REGISTER Q=>テストベンチ観測点
になります。時間がかかるIO遅延を往復することになりますから、156MHz駆動では、間に合っていない可能性が大です。
実際、遅延シミュレーション波形を見ると、下のようにやはり間に合っていません。
ステータスバーに 6.406ns(=T2-T1)が見えます。確かに、設定周波数になっています。このクロックPosedgeの前後で、波形ばバタついているのがわかります。つまり、Posedge読み込みに間に合っていないことが確認できました。
そこで、ゲートシミュレーションでは、下のソースのようにPosedge clockに読み込み遅延を3nsつけて読むことにします。
`timescale 1ns/1ps `define ECHO_BACK `define CYCLE (6.406/2) //6.406 `define DELAY_SIM module yacc_test; reg clock=0; reg Reset=0; wire TXD; `ifdef ECHO_BACK wire RXD=TXD; `else reg RXD=1; `endif wire [31:0] mem_data_w; wire mem_write; wire [15:0] mem_address; wire [11:0] PC; wire [31:0] IRD1; wire sync_reset; always #(`CYCLE) clock=~clock; initial begin Reset=0; #800 Reset=1; end yacc cpu(.clock(clock),.Async_Reset(Reset),.MemoryWData(mem_data_w), .MWriteFF(mem_write), .data_port_address(mem_address),.RXD(RXD),.TXD(TXD),.IRD1(IRD1), .sync_reset(sync_reset),.PC(PC)); `define Print_Port_Address 12'hff0 //ATMEL Big Endian `define Print_CAHR_Port_Address 12'hff1 `define Print_INT_Port_Address 12'hff2 //First ADDRESS `define Print_LONG_Port_Address 12'hff4 //First ADDRESS task Cprint;// String OUT until the byte 00 or xx detected with least Byte first and justified. integer i; begin :Block i=0; while (1) begin if (char_buffer[i*8 +:8] ===8'h00 || char_buffer[i*8 +:8]===8'hxx) begin disable Block; end $write("%c",char_buffer[i*8 +:8]); i=i+1; end end endtask reg [0:639] char_buffer; integer counter=0; always @ (posedge clock ) begin `ifdef DELAY_SIM #3;// `endif if ((mem_write === 1'b1)) begin if (mem_address==`Print_Port_Address) begin if (mem_data_w[7:0]===8'h00) begin char_buffer[counter*8 +:8]=mem_data_w[7:0]; if (char_buffer[0 +:8*7]==="$finish") begin $stop; end else if (char_buffer[0 +:8*5]==="$time") begin $display("Current Time on Simulation=%d",$time); end else Cprint;//$write("%s",char_buffer); for (counter=0; counter< 80; counter=counter+1) begin char_buffer[counter*8 +:8]=8'h00; end counter=0; end else begin char_buffer[counter*8 +:8]=mem_data_w[7:0]; counter=counter+1; end end else if (mem_address==`Print_CAHR_Port_Address) begin $write("%h ",mem_data_w[7:0]); end else if (mem_address==`Print_INT_Port_Address) begin $write("%h ",mem_data_w[15:0]);//Little Endian end else if (mem_address==`Print_LONG_Port_Address) begin $write("%h ",mem_data_w[31:0]);//Big Endian end end //if end //always endmodule |
こうすると2回目のRUNのとおり、SETUP/HOLD TIMEが十分あるので、文字化けはなくなりました。
筆者のマシン(Athron1.2GHz)で6時間程、走らせるとやっとTEST終了です。7月30日2004現在、StartixUボードは、未だないですが、合成後のポストレイアウトゲートシミュレーションでも、156MHzで動くことが、検証できました。
なお、Stratix、CYCLONE共、同様の手順で動作確認を行いました。
Xilinx Gate Simulation
Dual Portのメモリ衝突エラーメッセージが頻発してしまい、コンソール出力を確認することが困難です。
実際上は、同期クロックエッジしか使用していないため、YACCでは無害ですが、CoregenでWarningをDisableにしても変わりません。駆動周波数は、25MHzです。
そこで、やむを得ず、RAMのPRIMITIVE記述を以下のように変更しました。
parameter SIM_COLLISION_CHECK = "NONE";//All ORIG TAK Apr.12.2005
これで、次のようにコンソール出力を確認することができます。(なお、最初のSDFメッセージは、電源On時のシミュレータ過渡状態によるものですので無視します。)
StratixU16KB 版では、駆動周波数を最大駆動周波数の165MHzにして走らせました。
Cycloneでは、104MHzです。