fc2ブログ

[veritak]トラブルシューティング(Lattice Mico32)

シミュレーションが1usから進まない
ログに以下が出てた。

Note : Cyclone IV E PLL self reset due to loss of lock
Time: 0.0 ns Instance: tb_ether_top.uut.ether1.pll_ddr.altpll_component.cycloneiii_pll.pll3
Note : Cyclone IV E PLL locked to incoming clock
Time: 90.0 ns Instance: tb_ether_top.uut.ether1.pll_ddr.altpll_component.cycloneiii_pll.pll3
Note : Cyclone IV E PLL was reset
Time: 990.0 ns Instance: tb_ether_top.uut.ether1.pll_ddr.altpll_component.cycloneiii_pll.pll3
Note : Cyclone IV E PLL self reset due to loss of lock
Time: 990.0 ns Instance: tb_ether_top.uut.ether1.pll_ddr.altpll_component.cycloneiii_pll.pll3

リセット期間を延ばしたらPLLからクロック出力出るようになったから、PLLリセット期間が短かったって事かな。



シミュレーションが0nsから進まない
ddr2c回路を追加するとこうなる。
試しにddr2c/phy_newをコメントアウトしたら0nsから進んだので、このモジュールが原因。
さらにddr2c/phy_new/outifをコメントアウトしたら0nsから進んだので、このモジュールが原因。
さらにddr2c/phy_new/outif/ALTPLL_ddr_readをコメントアウトしたら0nsから進んだので、このモジュールが原因。

NEEK用に使ってた回路を流用したので、おそらくALTPLL_ddr_readはCyclone III用のVerilogソースになっている事が問題みたい。
DE2-115用(Cyclone IV E)用に作ったPLLを使ったらシミュレーションは動いた。


シミュレーションが0nsから進まない(221023)
lm32_instruction_unit.v
lm32_load_store_unit.v
上記にあるpmi_ram_dp_trueがMico System Builder生成後そのままだと0nsから進まなかった(というか始まらなかった)。
これを自作したpmi_ram_dp_true_altera(アルテラ社のaltsyncramを使った同等回路)に変更したら進んだ。
原因は追えてないが、何か遅延の無い回路で無限ループしてる?


コンパイルが途中で止まる(1)

誤: `ifdef `HOGE
正: `ifdef HOGE

こんな間違いすると、途中で止まったような終わり方する。


コンパイルが途中で止まる(2)

C:\・・・\fpga\common\rtl\ddr2c_intel\sdramc_define.v(425):: Warning: Re-defined macro TPAT_W
C:\・・・\fpga\common\rtl\ddr2c_intel\sdramc_define.v(426):: Warning: Re-defined macro TPAT_VAL
C:\・・・\fpga\lattice\rtl\system_conf.v(2):: Warning: Re-defined macro LATTICE_FAMILY
C:\・・・\fpga\lattice\rtl\system_conf.v(3):: Warning: Re-defined macro LATTICE_FAMILY_EC
C:\・・・\fpga\lattice\rtl\system_conf.v(4):: Warning: Re-defined macro LATTICE_DEVICE
C:\・・・\fpga\common\rtl\i2c_master_defines.v(56):: Warning: Re-defined macro I2C_CMD_NOP
C:\・・・\fpga\common\rtl\i2c_master_defines.v(57):: Warning: Re-defined macro I2C_CMD_START
C:\・・・\fpga\common\rtl\i2c_master_defines.v(58):: Warning: Re-defined macro I2C_CMD_STOP
C:\・・・\fpga\common\rtl\i2c_master_defines.v(59):: Warning: Re-defined macro I2C_CMD_WRITE
C:\・・・\fpga\common\rtl\i2c_master_defines.v(60):: Warning: Re-defined macro I2C_CMD_READ

ここで止まる。

原因は不明だが、解決方法として、テストベンチにも
`include "sdramc_define.v"
を宣言すると先に進んだ。
今後は各RTLに以下を記述しておくと宣言重複する事もなくなり良いと思う。

`ifndef SDRAM_DEFINE
`include "sdramc_define.v"
`endif


コンパイルが途中で止まる(3)

テストベンチでこんな書き方すると、途中でシミュレーションが止まる。

initial begin
rstn = 1'b0;
@(negedge clk) ;
@(negedge clk) ;
rstn = 1'b1;

while(1) begin
validi = 1'b1 ; > whileループの中に時間を進めるものがないのが原因!
end
end


原因はwhileの無限ループの中に時間を進める記述がないから。
なので、このwhileループの中で永遠に処理が行われてしまう。
例えば以下のように書けば@(negedge clk)が時間を進めてくれるから正常に動く。

initial begin
while(1) begin
validi = 1'b1 ;
@(negedge clk) ; > これで時間が進むようになった
end
end




シミュレーションが途中で止まる(300ns)

fpga\common\tb\tb_ddr2c_new.v(545)::Info: シミュレーション時間更新により一時停止しました。time=300,000ps ,インスタンス名:tb_ddr2c

これ原因分かってみれば単純なミスだった。

Veritak > シミュレーション > Run Length
ここで、300ns設定にして、Enableにチェックが入っていたため。
チェックを外せば、300nsで止まらず、シミュレーションが先に進んだ。




ファイル出力できない

こう書くとファイル出力がうまくいく。

integer W_OVEC1 ;
initial begin
W_OVEC1 = $fopen("tb_ddr2c.ppm");

$fdisplay(W_OVEC1, "P3" );
$fdisplay(W_OVEC1, "# Created by tb_ddr2c Simulation output file" );
$fdisplay(W_OVEC1, "640 700" );
$fdisplay(W_OVEC1, "255" );

while(1) begin
@(posedge uut.clk );
$fdisplay(W_OVEC1, "%d" , uut.r1_datho);
end

$fclose(W_OVEC1);
end


でも、if文の制御を追加すると、ファイルに何も出力されなくなる。原因なんだ?

integer W_OVEC1 ;
initial begin
W_OVEC1 = $fopen("tb_ddr2c.ppm");

$fdisplay(W_OVEC1, "P3" );
$fdisplay(W_OVEC1, "# Created by tb_ddr2c Simulation output file" );
$fdisplay(W_OVEC1, "640 700" );
$fdisplay(W_OVEC1, "255" );

while(1) begin
if (uut.r1_rei) begin
@(posedge uut.clk );
$fdisplay(W_OVEC1, "%d" , uut.r1_datho);
end
else begin
@(posedge uut.clk );
end
end

$fclose(W_OVEC1);
end



テストベンチコンパイルエラー
全角スペースが入っていたからだった。


メモリ初期値ファイル読み込み失敗(221023)
LatticeMicoSystemBuilderで生成したソースのうちsystem_conf.vに以下書いても初期値ファイルが読み込まれない。
原因は、自作したpmi_ram_dp_true_altera.vだと思ってるが。

system_conf.v
`define CFG_IROM_INIT_FILE_FORMAT "hex"
`define CFG_IROM_INIT_FILE "inst_ram_data.hex"
`define CFG_DRAM_INIT_FILE_FORMAT "hex"
`define CFG_DRAM_INIT_FILE "data_ram_data.hex"



なので、RAMモジュールに近い所で指定する事にした。

lm32_instruction_unit.v
pmi_ram_dp_true_altera
:
.pmi_init_file ("inst_ram_data.hex"),
.pmi_init_file_format ("hex"),


lm32_data_store_unit.v
pmi_ram_dp_true_altera
:
.pmi_init_file ("data_ram_data.hex"),
.pmi_init_file_format ("hex"),


ダブルクオーテーションを付けないとエラーになり、""で囲ったらエラー消えたので、値としては渡せたようだ。
しかしVeritekでコンパイル後にシミュレーションをスタートすると以下エラーが消えない。

can not open the file. Path-root is folder where Veritak project file exists.
can not open the file. Path-root is folder where Veritak project file exists.



原因はaltera_mf.vの中で、エラー対策のため(?)にコメントアウトしてたため。
なんでか忘れたが、convert_to_ver_file関数が無いとか言われてコメントアウトしたんだった。
結果的にはここを自分がいじったために、初期値ファイルが読み込めないというVeritakエラーが出たという結論。

mem.convert_to_ver_file(init_file, width_a, ram_initf);




Instruction bus error(221023)>解決したが原因特定出来ず。memcvt.c設定ミス? .mifを使わなかったから?
上記の初期値ファイル読み込めない問題は解決したが、以下エラーが出る。

Instruction bus error. Address: 0000cd14
Instruction bus error. Address: 0000cd18
Instruction bus error. Address: 0000cd1c


原因はinst_ramの方も、両方とも、data_ram_data.mifを読み込んでいたため。
(初期値ファイルが読み込めない問題デバッグのために、一時的にソース変更したのだった。)

上記は解決したが、今度は以下が発生。

Instruction bus error. Address: 00004000
Instruction bus error. Address: 00004004
Instruction bus error. Address: 00004008


ちなみにベースアドレスは以下。

inst_ram BASE_ADDRESS: 0x0
data_ram BASE_ADDRESS: 0x4000


 ↓
原因は以下アドレスが、最初は0x0だったが、83.0us時点で0x4000にアクセスした事。
tb_DE2_115_lm32_test.uut.lm32_test1.LM32.cpu.instruction_unit.i_adr_o
 ↓
自作のpmi_ram_dp_true_altera.vから、Lattice社ライブラリのpmi_ram_dp.vとpmi_ram_dp_true.vへ置き換えてシミュレーションしたらInstruction bus errorが消えた。
 ↓
問題はpmi_ram_dp_true_altera.v論理か?と思ったが、サイクルベースで命令RAM信号をdumpして比較したら、Latticeライブラリを使ったシミュレーションは単に多くの信号がXで、このSIM結果が正しいとは言えないので、まだ何が原因か不明。
 ↓
inst_ram_data.mifを見ると、最後までびっしりコードが。
メモリ容量が足りてないっぽい。
Lattice Mico System Builderで、命令RAMとデータRAMの容量を0x8000にした。
さらにmemcvt.cを以下の通り、1024から4096に変えた。

#define INST_BASE_ADDR 0x00000000
//#define INST_SIZE_LIMIT (1024*8)
#define INST_SIZE_LIMIT (4096*8)
#define RWDATA_BASE_ADDR 0x00004000
//#define RWDATA_SIZE_LIMIT (1024*8)
#define RWDATA_SIZE_LIMIT (4096*8)

#define INST_FILE_NAME "inst_ram_data.v"
#define RWDATA_FILE_NAME "data_ram_data.v"

// For Spartan3E device(in byte)
#define TARGET_MEM_WIDTH (256/8)
#define NUM_INTERLEAVE 4
#define INSTANCE_BASE_NAME "RAMB16_S9_"

#define INST_FILE_NAME_MIF "inst_ram_data.mif"
#define RWDATA_FILE_NAME_MIF "data_ram_data.mif"
#define TARGET_MEM_WIDTH_MIF 4
//#define TARGET_MEM_DEPTH_MIF 1024
#define TARGET_MEM_DEPTH_MIF 4096


この後ビルドした後のelfをmif、hexへ変換してから、シミュレーションすると以下結果。
Lattice社pmi_dp_ram.v、pmi_dp_ram_true.v使用: シミュレーションがスタートしない問題
アルテラ用の自作pmi_dp_ram_true.v使用: シミュレーションがスタート。しかし今度は以下Instruction bus errorが出た。

Instruction bus error. Address: 00008000
Instruction bus error. Address: 00008004
Instruction bus error. Address: 00008008


波形を見ると、プログラムカウンタがどんどん進み、237us頃に命令RAMの上限0x8000をこえて、上記エラーが出てた。
 ↓
何したか忘れたが、Instruction bus errorは消えた。
命令RAMのベースアドレスを0x0に変えたとか?
シンプルな回路構成にしたから?(icacheとかdcacheとかTimerとかDebug回路とかを削除したから?)
 ↓
objdumpしたのは以下。mifもhexもそうなってる。

00000000 <_reset_handler>:
0: 98 00 00 00 xor r0,r0,r0
4: d0 00 00 00 wcsr IE,r0
8: d0 20 00 00 wcsr IM,r0


<hex>
:1000000098000000d0000000d0200000780100001f
:1000040038210000d0e10000f800003a340000007c
:1000080090e0380034e70020c0e000003400000031


<mif>
DEPTH=4096;
WIDTH=32;
ADDRESS_RADIX = HEX;
DATA_RADIX = HEX;
CONTENT
BEGIN
00000000:98000000;
00000001:d0000000;
00000002:d0200000;
00000003:78010000;



しかし、シミュレーションでRAM初期値を確認したら、以下になってる。なぜ?

tb_DE2_115_lm32_test.uut.lm32_test1.LM32.cpu.instruction_unit.ram.ram.m_default.altsyncram_inst.mem_data
mem_data[0]: 98000000 > これはOK
mem_data[1]: 34000000 > なぜNOPになってる?
mem_data[2]: 34000000 > 同上


 ↓
altera_mf.vがhexを読み込んでverファイルに変換した後の内容は以下で正しいように見える。
なぜシミュレーション時のmem_data信号がおかしくなった?

@0
98000000
@1
d0000000
@2
d0200000
@3
78010000


 ↓
よくよく見ると、初期値ファイルが4アドレス毎?とか飛び飛びに読み込まれているように見える。
 ↓
memcvt.cのmifとhexの設定にミスがあるのでは?と思い、system_conf.vで初期値をmifに変えてみる。
 ※ 詳しく調べてないが、FORMATの方はhexのままでも良かったはず。

`define CFG_IROM_INIT_FILE_FORMAT "hex"
`define CFG_IROM_INIT_FILE "inst_ram_data.mif"
`define CFG_DRAM_INIT_FILE_FORMAT "hex"
`define CFG_DRAM_INIT_FILE "data_ram_data.mif"


 ↓

tb_DE2_115_lm32_test.uut.lm32_test1.LM32.cpu.instruction_unit.ram.ram.m_default.altsyncram_inst.mem_data
mem_data[0]: 98000000 > OK
mem_data[1]: d0000000 > OK
mem_data[2]: d0200000 > OK


正常に戻った感じ?
 ↓
シミュレーションしてみるとmain関数には飛ぶようになった。
2.985msシミュレーションしても、UART送信はされてない。Cテンプレートをきっと勘違いしてるみたい。
 ↓
UART_ECHOテンプレートをやめて、元々やってたCソースに変更。
UARTのボーレートレジスタ(divisor)への書き込みはシミュレーションでは成功してる。
GPIOへの書き込みは成功して、LEDは実機で点滅。
しかし、Teratermで何かキー入力すると、実機LED点滅が終わり、フリーズ。
つまり、UART割り込みハンドラで何か問題があって、正常に終了しない問題あるようだ。
 ↓
Cソース編集。

MicoRegisterISR(0, (void *)&iTotalInterrupts, interrupt_handler); // uart
//MicoRegisterISR(1, (void *)&iTotalInterrupts, interrupt_handler1); // spi master > 2022.10.24コメントアウト
//MicoRegisterISR(2, (void *)&iTotalInterrupts, interrupt_handler2); // i2c master > 2022.10.24コメントアウト
//writeIM(0x1); // uart
writeIM(0x0); // uart 2022.10.24
//writeIE(0x1); // uart
writeIE(0x0); // uart 2022.10.24


 ↓
Cソース最後のLED点滅ループは実機動作しており、Teratermでキー入力しても、LED点滅が止まらなくなった。
しかし、UART出力は失敗。何も表示されない。
 ↓
その後UART受信時にuart_handlerには飛んでいる事を確認済。
しかし、テストベンチからのUART受信タスク有無に関係なく、UART送信は以下WriteString関数によって出るはずだが、出ない。

WriteString("B");
*((volatile unsigned char*)(GPIO_BASE)) = 0x09;
WriteString("AC");
*((volatile unsigned char*)(GPIO_BASE)) = 0x0a;
WriteString("123");
*((volatile unsigned char*)(GPIO_BASE)) = 0x0b;


 ↓
WriteString関数の動作を確認。


WriteString("DEF");

void Write_Byte(char chr) //1バイト送信関数
{
UART_RBR_THR = chr; // 送信バッファーに1バイト書込み・送信
while ( !(UART_LSR & (1< }

void WriteString(const char *str) { //文字列送信関数
while(*str) {
Write_Byte(*str); //データ送信
str++;
}
}


上記のように書いたら、なぜかWriteString内のwhile(*str)ループに入ってくれない。
この場合"DEF"値を格納したメモリの番地が*strとして渡されるはずなのに。
シミュレーションで値を見てみたら、なぜか0x0。
尚、他の人のヘルプを借りて、見てもらったら、Windows上のVisual Studioではwhileループ内に入ったとの事。
Mico32のコンパイラではおかしくなるって事?
 ↓
以下のように明示的に文字列を宣言する事で、0x0番地でなく、ちゃんと?格納されたアドレスが渡されて、while(*str)に入る事が出来た。

const char *hoge = "ABC";
WriteString(*hoge);


 ※ 2022.10.29 これは後で間違いだった事に気付きました。
 ↓
UART文字列送信の2文字目の挙動が不可解なので、なんとなくFIFOを追加。
 ↓
uart/rxcver/rbrが最初からずっと不定になってしまう。
 ↓
FIFO(1)に設定すると、generate文でrbr記述が無くなるので、不定なのは当たり前だった。
無視して進む。
 ↓
WriteString関数に文字列を渡す時、いろいろ苦戦した。
1. WriteString("ABC"); > こう書くと、渡された値は0x0になってた。何かおかしい?
2. const char *msg = "ABC";
WriteString(*msg); > こう渡すと、0x0でなく、*msgのポインタ(メモリ番地)が渡ったようだが、ABCのASCIIコードを渡せなかった。何か間違ってるかな。。?
3.結局以下で成功した。

unsigned char msg[] = "helloUART\n";
WriteString(msg);


スポンサーサイト



[Veritak]define記述を考慮して関係RTL部のみ出力 > こんな機能無かったかな?

Mico32ソース追ってると、defineによる記述分岐が多いので追うのが疲れる。
ifdefとかで無関係な記述を除外したソースを再生成する機能あったような気がしたが・・・見つからない。

[veritak]アルテラCycloneIII Gateシミュレーション

RTLシミュレーションではLattice Mico32のLEDチカチカ出来てるのに、
アルテラNEEKにダウンロードすると動作しない。なぜ?
VeritakとQuartusIIで扱ってるRTLに何か違いがあった??

QuartusII生成のネットリストでGATEシミュレーションしてみる事に。
以下ファイルを読んだ上で、Veritak設定でcompile modeをRTL(default)からAltera SDFに変更して実行。
1us/秒くらいでシミュレーション出来た。

QuartusIIプロジェクタフォルダのsimulation/modelsim/*.vo
C/altera/13.1/quartus/eda/sim_lib/altera_primitives.v
C/altera/13.1/quartus/eda/sim_lib/altera_mf.v
C/altera/13.1/quartus/eda/sim_lib/cycloneiii_atoms.v

[veritak]EC:2884 MapViewOfFile . Can not allocate memory.

DDRコントローラを自作し、1画面分のシミュレーションをしてる。

Save All sim dataのチェックを外して実行。
  ↓
すっごい高速。これは良い!
fdisplayタスクで出力したppmは生成されるので、結果見ると、何十ライン目かで動作不備。
  ↓
Save All sim dataのチェックをつけて波形データを保存。
  ↓
OSディスクのSSD 256GBでは容量足りず。
外付けHDDにデータを置いて、Veritakプロジェクト設定でMax Archive Disk=Max Disp Disk=100GBに。
PCはx230でメモリは8GB搭載。
  ↓
シミュレーションしたら以下エラーで止まった。400us付近だったかな。

EC:2884 MapViewOfFile . Can not allocate memory.
Please try USE DISK option on the project.
6
size=92183632low_address=1303707648high_address=7hdiskpmap=000000
00



(2014.11.2追記)
マシンを変えてz77(メモリ16GB)でやったら、Time=685us(ArchiveDisk=51GB)まで出来た。
物理メモリの問題か?

[veritak]Simデータ保存せず高速化

RTLシミュレーションでppmを作成してLCD表示の各フレーム確認すると時間かかる。
そんな時は、Veritakのプロジェクト設定で「Save All Sim Dataのチェックを外す」。

そうすると、シミュレーションデータは保存しないが、taskで走らせているppm作成はちゃんと行われる。
シミュレーション波形は見れないが、表示画像はppmで確認出来る。

時間経過見てるとSave All Sim Dataしてる時の3倍以上(もっとかな?)くらいにはなってそう。
計ってみるとこんなスピード。

x230: 961.2us @ 1分間 (Save All Sim Dataチェック無し)

60fpsとすると、16.66ms/1frameだから、18分くらいでシミュレーション出来ると。
デスクトップPCでOCすればもっと速くなるだろうし、なかなか良い感じだ。

z77デスクトップで計ってみた。

z77: 1119.4us @ 1分間 (Save All Sim Dataチェック無し)
カレンダー
02 | 2024/03 | 04
- - - - - 1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
31 - - - - - -
累積訪問者
現在の訪問者
現在の閲覧者数:
最新記事
最新トラックバック
最新コメント
月別アーカイブ
カテゴリ
プロフィール

bobgosso

Author:bobgosso
FPGAのブログへようこそ!

検索フォーム
RSSリンクの表示
リンク
ブロとも申請フォーム

この人とブロともになる

QRコード
QRコード