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です。
