fc2ブログ

[LM32]ビルドバッチ

内容は以下。

1.micosystem.exeでBuild allした時のコピー(sw.elfが生成される)
2.micosystem.exeでSoftware Deploymentlした時のコピー(命令RAMとデータRAMの.memが生成される)
3.srec生成
4.elfをobjdump
5.memからmifへ変換(自作rubyプログラム)
6.rubyだと16進数のアドレスの0埋めが出来ずに空白埋めになるので、0へ変換
7.mifをシミュレーションフォルダへコピー


#!/bin/bash

\rm sw.elf
\rm *.mif
\rm *.srec
\rm *.bin.*
\rm *.objdump.txt
\rm *.o
\rm *.d

src_name=LEDTest

#GCC_OPT="-D__RELOCATE_EXCEPTION_TABLE__"
GCC_OPT=""

LM32ELFBIN=/cygdrive/c/lscc/diamond/3.12/micosystem/gtools/lm32/lm32-elf/bin
LM32BIN=/cygdrive/c/lscc/diamond/3.12/micosystem/gtools/lm32/bin
PJ_DIR=/cygdrive/c/hoge/DE2-115/micosystem/mico32/soc
LATTICE_UTIL_DIR=/cygdrive/c/lscc/diamond/3.12/micosystem/utilities
RUBYBIN="/cygdrive/c/hoge/ruby"

echo "INFO : build ------------------------------------------------------------------------";
cd ../mico32/Debug

$LM32BIN/lm32-elf-gcc -c -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. ../DDInit.c -o ../../Debug/Debug/DDInit.o
$LM32BIN/lm32-elf-gcc -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. -MM -MG -P -w ../DDInit.c >> ../../Debug/Debug/DDInit.d
$LM32BIN/lm32-elf-gcc -c -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. ../DDStructs.c -o ../../Debug/Debug/DDStructs.o
$LM32BIN/lm32-elf-gcc -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. -MM -MG -P -w ../DDStructs.c >> ../../Debug/Debug/DDStructs.d
$LM32BIN/lm32-elf-gcc -c -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. ../LCD.c -o ../../Debug/Debug/LCD.o
$LM32BIN/lm32-elf-gcc -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. -MM -MG -P -w ../LCD.c >> ../../Debug/Debug/LCD.d
$LM32BIN/lm32-elf-gcc -c -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. ../LatticeMico32.c -o ../../Debug/Debug/LatticeMico32.o
$LM32BIN/lm32-elf-gcc -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. -MM -MG -P -w ../LatticeMico32.c >> ../../Debug/Debug/LatticeMico32.d
$LM32BIN/lm32-elf-gcc -c -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. ../LatticeMico32DbgModule.S -o ../../Debug/Debug/LatticeMico32DbgModule.o
$LM32BIN/lm32-elf-gcc -c -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. ../LatticeMico32Uart.c -o ../../Debug/Debug/LatticeMico32Uart.o
$LM32BIN/lm32-elf-gcc -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. -MM -MG -P -w ../LatticeMico32Uart.c >> ../../Debug/Debug/LatticeMico32Uart.d
$LM32BIN/lm32-elf-gcc -c -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. ../LatticeMicoUtils.S -o ../../Debug/Debug/LatticeMicoUtils.o
$LM32BIN/lm32-elf-gcc -c -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. ../LookupServices.c -o ../../Debug/Debug/LookupServices.o
$LM32BIN/lm32-elf-gcc -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. -MM -MG -P -w ../LookupServices.c >> ../../Debug/Debug/LookupServices.d
$LM32BIN/lm32-elf-gcc -c -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. ../MicoExit.S -o ../../Debug/Debug/MicoExit.o
$LM32BIN/lm32-elf-gcc -c -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. ../MicoFileClose.c -o ../../Debug/Debug/MicoFileClose.o
$LM32BIN/lm32-elf-gcc -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. -MM -MG -P -w ../MicoFileClose.c >> ../../Debug/Debug/MicoFileClose.d
$LM32BIN/lm32-elf-gcc -c -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. ../MicoFileDevices.c -o ../../Debug/Debug/MicoFileDevices.o
$LM32BIN/lm32-elf-gcc -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. -MM -MG -P -w ../MicoFileDevices.c >> ../../Debug/Debug/MicoFileDevices.d
$LM32BIN/lm32-elf-gcc -c -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. ../MicoFileIsAtty.c -o ../../Debug/Debug/MicoFileIsAtty.o
$LM32BIN/lm32-elf-gcc -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. -MM -MG -P -w ../MicoFileIsAtty.c >> ../../Debug/Debug/MicoFileIsAtty.d
$LM32BIN/lm32-elf-gcc -c -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. ../MicoFileOpen.c -o ../../Debug/Debug/MicoFileOpen.o
$LM32BIN/lm32-elf-gcc -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. -MM -MG -P -w ../MicoFileOpen.c >> ../../Debug/Debug/MicoFileOpen.d
$LM32BIN/lm32-elf-gcc -c -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. ../MicoFileRead.c -o ../../Debug/Debug/MicoFileRead.o
$LM32BIN/lm32-elf-gcc -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. -MM -MG -P -w ../MicoFileRead.c >> ../../Debug/Debug/MicoFileRead.d
$LM32BIN/lm32-elf-gcc -c -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. ../MicoFileSeek.c -o ../../Debug/Debug/MicoFileSeek.o
$LM32BIN/lm32-elf-gcc -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. -MM -MG -P -w ../MicoFileSeek.c >> ../../Debug/Debug/MicoFileSeek.d
$LM32BIN/lm32-elf-gcc -c -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. ../MicoFileStat.c -o ../../Debug/Debug/MicoFileStat.o
$LM32BIN/lm32-elf-gcc -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. -MM -MG -P -w ../MicoFileStat.c >> ../../Debug/Debug/MicoFileStat.d
$LM32BIN/lm32-elf-gcc -c -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. ../MicoFileWrite.c -o ../../Debug/Debug/MicoFileWrite.o
$LM32BIN/lm32-elf-gcc -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. -MM -MG -P -w ../MicoFileWrite.c >> ../../Debug/Debug/MicoFileWrite.d
$LM32BIN/lm32-elf-gcc -c -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. ../MicoGPIO.c -o ../../Debug/Debug/MicoGPIO.o
$LM32BIN/lm32-elf-gcc -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. -MM -MG -P -w ../MicoGPIO.c >> ../../Debug/Debug/MicoGPIO.d
$LM32BIN/lm32-elf-gcc -c -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. ../MicoGPIOService.c -o ../../Debug/Debug/MicoGPIOService.o
$LM32BIN/lm32-elf-gcc -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. -MM -MG -P -w ../MicoGPIOService.c >> ../../Debug/Debug/MicoGPIOService.d
$LM32BIN/lm32-elf-gcc -c -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. ../MicoInterrupts.c -o ../../Debug/Debug/MicoInterrupts.o
$LM32BIN/lm32-elf-gcc -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. -MM -MG -P -w ../MicoInterrupts.c >> ../../Debug/Debug/MicoInterrupts.d
$LM32BIN/lm32-elf-gcc -c -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. ../MicoSbrk.c -o ../../Debug/Debug/MicoSbrk.o
$LM32BIN/lm32-elf-gcc -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. -MM -MG -P -w ../MicoSbrk.c >> ../../Debug/Debug/MicoSbrk.d
$LM32BIN/lm32-elf-gcc -c -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. ../MicoSleepHelper.S -o ../../Debug/Debug/MicoSleepHelper.o
$LM32BIN/lm32-elf-gcc -c -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. ../MicoStdStreams.c -o ../../Debug/Debug/MicoStdStreams.o
$LM32BIN/lm32-elf-gcc -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. -MM -MG -P -w ../MicoStdStreams.c >> ../../Debug/Debug/MicoStdStreams.d
$LM32BIN/lm32-elf-gcc -c -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. ../MicoUart.c -o ../../Debug/Debug/MicoUart.o
$LM32BIN/lm32-elf-gcc -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. -MM -MG -P -w ../MicoUart.c >> ../../Debug/Debug/MicoUart.d
$LM32BIN/lm32-elf-gcc -c -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. ../MicoUartService.c -o ../../Debug/Debug/MicoUartService.o
$LM32BIN/lm32-elf-gcc -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. -MM -MG -P -w ../MicoUartService.c >> ../../Debug/Debug/MicoUartService.d
$LM32BIN/lm32-elf-gcc -c -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. ../MicoUtils.c -o ../../Debug/Debug/MicoUtils.o
$LM32BIN/lm32-elf-gcc -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. -MM -MG -P -w ../MicoUtils.c >> ../../Debug/Debug/MicoUtils.d
$LM32BIN/lm32-elf-gcc -c -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. ../printf_shrink.c -o ../../Debug/Debug/printf_shrink.o
$LM32BIN/lm32-elf-gcc -mbarrel-shift-enabled -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I. -MM -MG -P -w ../printf_shrink.c >> ../../Debug/Debug/printf_shrink.d

cd ../../Debug

rm -f Debug/../LEDTest.o
rm -f Debug/../lm32_func.o
rm -f Debug/crt0ram.o

touch force_clean_archive_objs

$LM32BIN/lm32-elf-gcc -c -mbarrel-shift-enabled $GCC_OPT -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I./../mico32 ../LEDTest.c -o Debug/../LEDTest.o
$LM32BIN/lm32-elf-gcc -mbarrel-shift-enabled $GCC_OPT -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I./../mico32 -MM -MG -P -w ../LEDTest.c >> Debug/../LEDTest.d
$LM32BIN/lm32-elf-gcc -c -mbarrel-shift-enabled $GCC_OPT -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I./../mico32 ../lm32_func.c -o Debug/../lm32_func.o
$LM32BIN/lm32-elf-gcc -mbarrel-shift-enabled $GCC_OPT -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I./../mico32 -MM -MG -P -w ../lm32_func.c >> Debug/../lm32_func.d
$LM32BIN/lm32-elf-gcc -c -mbarrel-shift-enabled $GCC_OPT -ffunction-sections -O0 -g2 -Wall -D__lm32__ -I./../mico32 ./../mico32/crt0ram.S -o Debug/crt0ram.o
$LM32BIN/lm32-elf-gcc -mbarrel-shift-enabled -T ../mico32/Debug/linker.ld -osw.elf Debug/../LEDTest.o Debug/../lm32_func.o Debug/crt0ram.o ./Debug/libmico32.a -lm -lsmallc -lgcc ./Debug/libmico32.a -lnosys -Wl,--gc-sections
$LM32BIN/lm32-elf-size sw.elf



echo "INFO : objcopy elf to bin (boot, text) ----------------------------------"; $LM32BIN/lm32-elf-objcopy -j .boot -j .text -O binary $PJ_DIR/sw/Debug/sw.elf $PJ_DIR/sw/Debug/Application.bin.boot_text
echo "INFO : objcopy bin to mem (boot, text) ----------------------------------"; $LATTICE_UTIL_DIR/bin_to_verilog --h --EB --width 4 $PJ_DIR/sw/Debug/Application.bin.boot_text $PJ_DIR/sw/Debug/hoge_Instruction_IM.mem
echo "INFO : objcopy elf to bin (rodata, bss) ----------------------------------"; $LM32BIN/lm32-elf-objcopy -j .rodata -j .bss -O binary $PJ_DIR/sw/Debug/sw.elf $PJ_DIR/sw/Debug/Application.bin.rodata_bss
echo "INFO : objcopy bin to mem (rodata, bss) ----------------------------------"; $LATTICE_UTIL_DIR/bin_to_verilog --h --EB --width 4 $PJ_DIR/sw/Debug/Application.bin.rodata_bss $PJ_DIR/sw/Debug/hoge_Data_IM.mem


echo "INFO : convert Debug/sw.elf to $src_name.srec ----------------------------"; $LM32BIN/lm32-elf-objcopy -O srec sw.elf $src_name.srec
echo "INFO : objdump sw.elf -----------------------------------------"; $LM32ELFBIN/objdump.exe -d sw.elf > sw.elf.objdump.txt

\rm data_ram_data.mif
\rm inst_ram_data.mif

#echo "INFO : convert mem to mif (inst) --------------------"; ruby $RUBYBIN/mem2mif_v01.rb hoge_Instruction_IM.mem inst_ram_data.mif
echo "INFO : convert mem to mif (inst) --------------------"; ruby mem2mif_v01.rb hoge_Instruction_IM.mem inst_ram_data.mif
#echo "INFO : convert mem to mif (data) --------------------"; ruby $RUBYBIN/mem2mif_v01.rb hoge_Data_IM.mem data_ram_data.mif
echo "INFO : convert mem to mif (data) --------------------"; ruby mem2mif_v01.rb hoge_Data_IM.mem data_ram_data.mif

echo "INFO : padding 000 (inst) ---------------------------"; sed -i 's/ /000/g' inst_ram_data.mif
echo "INFO : padding 000 (data) ---------------------------"; sed -i 's/ /000/g' data_ram_data.mif

echo "INFO : padding 00 (inst) ---------------------------"; sed -i 's/ /00/g' inst_ram_data.mif
echo "INFO : padding 00 (data) ---------------------------"; sed -i 's/ /00/g' data_ram_data.mif

echo "INFO : padding 0 (inst) ---------------------------"; sed -i 's/00 /000/g' inst_ram_data.mif
echo "INFO : padding 0 (data) ---------------------------"; sed -i 's/00 /000/g' data_ram_data.mif

echo "INFO : cp inst_ram_data.mif ../../ ------------------"; \cp inst_ram_data.mif ../../
echo "INFO : cp data_ram_data.mif ../../ ------------------"; \cp data_ram_data.mif ../../


スポンサーサイト



[LM32](4).mem生成(Micosystem Builder)

久しぶりにやったら.elfから.hexが作れない。

host: x1 carbon
OS: Windows 10 Pro
Cygwin: 64bit

objcopy.exe -S -O $swname/Debug/$swname.elf $swname.srec

以前はこれをCygwinで実行すると.srecが生成出来たのに。効かない。
.srecが生成されたら、後はDesign Wave Magazine付属のプログラムで.mifと.hexへ変換していた。
以下どちらのobjcopyでも何も生成されず、エラーも出ず。

c/lscc/diamond/3.10_x64/micosystem/gtools/lm32/bin/lm32-elf-objcopy.exe
c/lscc/diamond/3.10_x64/micosystem/gtools/lm32/lm32-elf/bin/objcopy


Micosystem BuilderのSoftware Deploymentを使う
流れとしては、launchmicosystem.exeでEclipseのLattice Mico System(LMS) Builderを起動して、
メニューバー下の、LMS 1.0 D3.10画面で、HWプラットフォーム(ether.msb)を作り、
その隣の、C/C++画面で、ソフトウェアをビルドし.elfを作り、
その次に、SoftwareのDeploymentへ進む。

具体的には、
LMSメニュー > Tools > Software Deployment
 > 左のメニューから「Mico32 Multi On Chip Memory Deployment」をダブルクリック
 > 新規の設定画面に対して以下を入力してから、Startで.memが生成された。

Name : ether_soft
Project: Browseで開くと、C/C++画面で作ってビルドしたプロジェクト名を選択
C/C++ Application: Debug/ether_soft.elf を選択
Save Memory Initialization Files to directory: 保存先DIRを指定
Memory Initialization Files Prefix: これを何か入力しないとエラーが出た。


尚、「Mico32 On Chip Memory Deployment」の方も試してみたが、Startボタンが押せなかった。
おそらく今回の回路では、Inst RAMとData RAMが別々になっているので、Multiの方を使うべきのようだ。

ここまでで.memが出来たが、このままではINTEL FPGAのMemoryで初期値として渡せない。

0000407c
0000407c
0000407c
 :

なので、対応するINTEL HEX形式へ変換する。

過去に作ったRobyプログラムで変換できる。記事の最後の方のソースを使う。

[LM32].mem to Intel-Hex変換Ruby
http://bobgosso.blog13.fc2.com/blog-entry-338.html

あとはCygwinから以下を実行して、.hexへ変換し、さらにそれをシミュレーション場所へコピーして読み込めるようにする。

ruby ../../../../common/ruby/mem2intel_hex_v01.rb ether_soft_Data_IM.mem ether_soft_Data_IM.hex
ruby ../../../../common/ruby/mem2intel_hex_v01.rb ether_soft_Instruction_IM.mem ether_soft_Instruction_IM.hex

\cp ether_soft_Data_IM.hex ../../../../board/de2-115/
\cp ether_soft_Instruction_IM.hex ../../../../board/de2-115/



デバッグ用にobjdumpも作っておく


以下で生成可能。しかし、Cygwin64bitでは動作せず。32bitで実行したら成功した。

lm32-elf-objdump.exe -D ether_soft.elf > ether_soft.elf.objdump

[LM32]仕様

汎用レジスタ

lm32_cpu.v
reg [`LM32_WORD_RNG] registers[0:(1<<`LM32_REG_IDX_WIDTH)-1]; // Register file



スタートアップルーチン

ether.elf:     file format elf32-lm32

Disassembly of section .boot:

00000000 <_reset_handler>:
0: 98 00 00 00 xor r0,r0,r0 > r0同士でXORすると必ず一致するから結果は0。これをr0へ格納するので0クリアになる。

<LatticeMico32 Processor Reference Manual>
After reset, the values in all of the above 32-bit registers are undefined. To
ensure that register 0 contains 0, the first instruction executed after reset
should be xor r0, r0, r0.


4: d0 00 00 00 wcsr IE,r0 > wcsr(Write Control or Status Register)でIE(Interrupt Enable)を0(Disable)にする。
8: d0 20 00 00 wcsr IM,r0 > IM(Interrupt Mask)を0(Disable)にする。
c: 78 01 00 00 mvhi r1,0x0 > mvhi(move high)で即値0x0を16bit左シフトした値をr1へ代入する。
10: 38 21 02 a8 ori r1,r1,0x2a8 > ori(bitwise logical OR)で、16bit即値0x2a8に上位16bitに0拡張(zero-extended)した32bit値とr1(32bit)のビット毎のORを取って、結果をr1へ格納。
14: d0 e1 00 00 wcsr EBA,r1 > EBA(Exception Base Address)へr1の値(つまり0x2a8)を代入。
18: f8 00 00 3a calli 100 <_crt0>
1c: 34 00 00 00 nop





汎用レジスタ

IEは1でEnable。IMより優先順位が高い。

<LatticeMico32 Processor Reference Manual>
IE – Interrupt Enable
1 – Interrupts enabled
IE, that determines whether interrupts are enabled. This flag has priority over the IM CSR.



IMはActive High。つまり、1でマスクされる。

<LatticeMico32 Processor Reference Manual>
The LatticeMico32 microprocessor supports up to 32 maskable, active-low,
level-sensitive interrupts. Each interrupt line has a corresponding mask bit in
the IM CSR. The mask enable is active high.








exitルーチンってなんだ?


  :
614: 34 02 00 06 mvi r2,6
618: 30 22 00 00 sb (r1+0),r2
61c: 78 01 80 00 mvhi r1,0x8000
620: 38 21 04 00 ori r1,r1,0x400
624: 34 02 00 07 mvi r2,7
628: 30 22 00 00 sb (r1+0),r2
62c: 78 01 80 00 mvhi r1,0x8000
630: 38 21 04 00 ori r1,r1,0x400
634: 34 02 00 44 mvi r2,68
638: 30 22 00 00 sb (r1+0),r2
63c: e3 ff ff fc bi 62c

00000640 <_exit>:
640: 34 08 00 01 mvi r8,1
644: ac 00 00 07 scall

00000648 :
648: 37 9c ff e8 addi sp,sp,-24
64c: 5b 9b 00 08 sw (sp+8),fp
  :

[LM32]トラブルシューティング

MSB = Mico System Builderでのエラー

[MSB] Couldn't compute FAST_CWD pointer.

micosystemのソフト(C/C++画面)のビルド時にこれが出たら、LMS画面の方に切り替えて、
何かしら変更して保存する。(例えば変更箇所なければ、一度変えて保存、戻して保存、という方法)
Generate AddressからRun Generatorまで実行し直す。それからビルドし直すとエラー無くビルド出来るようになった。
(Windows 10の場合)
しかし、Windows 8.1でも同様の方法で解決していたが、ある時から解決しなくなった。
8.1ではCygwinの問題だという指摘を掲示板で見つけた。

make all
0 [main] make 28276 find_fast_cwd: WARNING: Couldn't compute FAST_CWD pointer. Please report this problem to
the public mailing list cygwin@cygwin.com

make[1]: Entering directory `/cygdrive/c/user/work/quartus/DE2-115/micosystem/sw/ether/ether/Debug'
make[1]: Leaving directory `/cygdrive/c/user/work/quartus/DE2-115/micosystem/sw/ether/ether/Debug'





[Cygwin] objdumpが効かない

Windows 10上のCygwin64から以下いずれも実行しても何も返って来ないで終わる。
/cygdrive/c/lscc/diamond/3.10_x64/micosystem/gtools/lm32/bin/lm32-elf-objdump.exe -d ether.elf
/cygdrive/c/lscc/diamond/3.10_x64/micosystem/gtools/lm32/lm32-elf/bin/objdump.exe -d ether.elf

コマンドプロンプトから実行すると、以下を言われる。

cygwin1.dllが見つからないため、コードの実行を続行できません。プログラムを再インストール
すると、この問題が解決する可能性があります。


あ、でもこれは当たり前か。Cygwin用のプログラムobjdumpをコマンドプロンプトで実行しようとするのがダメか。

さらに試してみたら、
C:\cygwin64\Cygwin.bat
を使ってたために、この症状が起こったが、
C:\cygwin\Cygwin.bat
を使えば、正常に実行出来た。
Lattice DiamondインストールDIRのGNUツールは、Cygwin 32bit用実行ファイルという事だった。


[Cygwin] gcc: error trying to exec 'cc1': execvp: No such file or directory

memcvt.exeが効かなかったので、以前cygwin64bitのgccで生成したものだからと考え、
再度ビルドしてみたらこのエラー。
ごめんなさい、単にgccのパスを以下に間違えてただけでした。
/cygdrive/c/lscc/diamond/3.10_x64/micosystem/gtools/lm32/lm32-elf/bin/gcc
正しくは/bin/gccでした。これでエラー消えた。



[Cygwin] /tmp/ccmUUqJZ.s:2: Fatal error: unrecognized .section attribute: want a,w,x,M,S,G,T

/bin/gcc memcvt_171125.c -o memcvt_171125.exe


上に続き、/bin/gccでビルドしようとしたらこのエラー。

/tmp/ccmUUqJZ.s: Assembler messages:
/tmp/ccmUUqJZ.s:2: Fatal error: unrecognized .section attribute: want a,w,x,M,S,G,T



原因は$PATHの前に、
/cygdrive/c/lscc/diamond/3.10_x64/micosystem/gtools/lm32/lm32-elf/bin
を追加した事が原因だった。

export PATH=/cygdrive/c/lscc/diamond/3.10_x64/micosystem/gtools/lm32/lm32-elf/bin:$PATH:/cygdrive/c/user/onedrive/user/app/vim74-kaoriya-win64:/cygdrive/c/user/tool/lattice/memcvt:/cygdrive/c/lscc/diamond/3.10_x64/micosystem/gtools/lm32/bin



memcvt_171125.cをビルドする時は以下に戻す事で成功した。

export PATH=$PATH:/cygdrive/c/user/onedrive/user/app/vim74-kaoriya-win64:/cygdrive/c/user/tool/lattice/memcvt:/cygdrive/c/lscc/diamond/3.10_x64/micosystem/gtools/lm32/bin





inst_ram_data.ver Access Error accessing address=1000 min_address=fff max_address=0
In module:tb_DE2_115.uut.ether1.LM32.cpu.instruction_unit.ram.ram.m_default.altsyncram_inst;



[Cygwin] C:/lscc/diamond/3.10_x64/micosystem/gtools/lm32/libexec/gcc/lm32-elf/4.3.0/cc1.exe: error while loading shared libraries: cyggmp-3.dll: cannot open shared object file: No such file or directory

Cygwin32bit環境で以下を実行した際に出たエラー。

lm32-elf-gcc -c $src_name.c






[Quartus] object "GSR_INST" is not declared.

Error (10161): Verilog HDL error at DP16KD.v(157): object "GSR_INST" is not declared. Verify the object name is correct. If the name is correct, declare the object.
Error (10161): Verilog HDL error at DP16KD.v(158): object "PUR_INST" is not declared. Verify the object name is correct. If the name is correct, declare the object.



PUR PUR_INST (.PUR(1'b1)); > 追加
GSR GSR_INST (.GSR(1'b1)); > 追加


tri1 GSR_sig = GSR_INST.GSRNET;
tri1 PUR_sig = PUR_INST.PURNET;





[Quartus] Error (10200): Verilog HDL Conditional Statement error at wb_spi.v(338): cannot match operand(s) ...

Error (10200): Verilog HDL Conditional Statement error at wb_spi.v(338): cannot match operand(s) in the condition to the corresponding edges in the enclosing event control of the always construct




always @(posedge CLK_I or posedge RST_I)
if (RST_I || (c_status == ST_IDLE))  > ここがエラー箇所
clock_cnt <= 0;
else if (clock_cnt == CLOCK_SEL)
clock_cnt <= 0;
else
clock_cnt <= clock_cnt + 1;



always @(posedge CLK_I or posedge RST_I)
if (RST_I)
clock_cnt <= 0;
else if (c_status == ST_IDLE)  > RST_Iとは別にif文追加した。
clock_cnt <= 0;
else if (clock_cnt == CLOCK_SEL)
clock_cnt <= 0;
else
clock_cnt <= clock_cnt + 1;





[Veritak] ether_top.vo::Error: CLOCK2_50~input.bus_holdパラメータが見つかりません

Quartus生成ネットリストをVeritakでコンパイルするとこのエラー。

C:\user\work\quartus\DE2-115\ether\soc\simulation\custom\ether_top.vo(113291)::Error: CLOCK2_50~input.bus_holdパラメータが見つかりません



C/intelFPGA_lite/17.0/quartus/eda/sim_lib/altera_primitives.v
C/intelFPGA_lite/17.0/quartus/eda/sim_lib/altera_mf.v
C/intelFPGA_lite/17.0/quartus/eda/sim_lib/cycloneiv_atoms.v > 後述するが、ivではなく、iveが正解だった。


220_model.vじゃなく、altera_primitives.vを追加したらエラーが消えて、今度は以下が出た。


../../../../../../intelFPGA_lite/17.1/quartus/eda/sim_lib/altera_primitives.v(34):: Error: Macro name=begin_keywords is not defined.
../../../../../../intelFPGA_lite/17.1/quartus/eda/sim_lib/altera_primitives.v(44):: Error: Macro name=end_keywords is not defined.
../../../../../../intelFPGA_lite/17.1/quartus/eda/sim_lib/altera_primitives.v(84):: Error: Macro name=begin_keywords is not defined.
../../../../../../intelFPGA_lite/17.1/quartus/eda/sim_lib/altera_primitives.v(93):: Error: Macro name=end_keywords is not defined.



エラーの箇所は以下。

//if simulator dees not support begin_keywords/end_keywords pragmas then define macro SKIP_KEYWORDS_PRAGMA to skip them.
//pragmas are required to prevent "global" from being treated as a systemverilog 1800-2009 keyword
`ifndef SKIP_KEYWORDS_PRAGMA
`begin_keywords "1364-1995"
`endif



altera_primitives.vのコメント通り、以下を宣言してみる。

tb_ether_top.v内に追加
// 2017.12.29 to prevent error of altera_primitives.v for veritak
`define SKIP_KEYWORDS_PRAGMA



しかし、テストベンチに追記しても、下位モジュールに適用されないのでエラーは出た。
なので、Veritakで以下設定を行う。

Veritak > Verilogプロジェクト > プロジェクト設定 > Define Propagationの設定を変える。
  > 現状=Per File → 変更後=Throughout Project



すると、SKIP_KEYWORDS_PRAGMA関連エラーが消えた代わりに、元のエラーが出た。
つまり、altera_primitives.vが対策ではなかったようだ。

Loading vpi
スコープを生成中です。
C:\user\work\quartus\DE2-115\ether\soc\simulation\custom\ether_top.vo(113291)::Error: CLOCK2_50~input.bus_holdパラメータが見つかりません

C:\user\work\quartus\DE2-115\ether\soc\simulation\custom\ether_top.vo(113292)::Error: CLOCK2_50~input.simulate_z_asパラメータが見つかりません
  :



ネットリストでエラー箇所を見てみる。
// Location: LCCOMB_X112_Y36_N24
cycloneive_lcell_comb \led_cnt[9]~41 ( > cycloneivじゃなくて、cycloneiveだった。
  :
// synopsys translate_off
defparam \led_cnt[9]~41 .lut_mask = 16'hC30C; > このdefparamはcycloneive_lcell_comb宣言があればエラーにならない。
defparam \led_cnt[9]~41 .sum_lutc_input = "cin";
// synopsys translate_on



結論
以下条件でネットリストでゲート(GATE)シミュレーションが出来た。

<読み込むファイル>

GSR.v
PUR.v
tb_ether_top.v
simulation/custom/ether_top.vo > simulation/custom/ether_top.sdo
C/intelFPGA_lite/17.0/quartus/eda/sim_lib/altera_primitives.v
C/intelFPGA_lite/17.0/quartus/eda/sim_lib/altera_mf.v
C/intelFPGA_lite/17.0/quartus/eda/sim_lib/cycloneive_atoms.v



<設定>
Veritak > Verilogプロジェクト > プロジェクト設定 > Compile Mode = Altera SDF

<準備>
simulation/custom/*.sdo をVeritakのプロジェクトファイル(=実行場所)に保存する。

<結果>
SDFを実行場所に保存する前はこれ。

ERROR: can not open $sdf_annotate



ちゃんとSDF保存したらエラーが消えて、以下が出た。

------------- シミュレーションを開始します。--------------------
SDF: timing check[0] HOLD[Spec.186ps] FAILS at simtime 87ps <- 87ps: posedge tb_ether_top.uut.ether1|LM32|cpu|load_store_unit|irom_select_m.clk ==> tb_ether_top.uut.ether1|LM32|cpu|load_store_unit|irom_select_m.d
SDF: timing check[0] HOLD[Spec.186ps] FAILS at simtime 87ps <- 87ps: posedge tb_ether_top.uut.ether1|LM32|cpu|load_store_unit|d_we_o.clk ==> tb_ether_top.uut.ether1|LM32|cpu|load_store_unit|d_we_o.d
SDF: timing check[0] HOLD[Spec.186ps] FAILS at simtime 87ps <- 87ps: posedge tb_ether_top.uut.ether1|spi|wait_one_tick_done.clk ==> tb_ether_top.uut.ether1|spi|wait_one_tick_done.d






[Quartus] Mico32のゲート(GATE)シミュレーションが動かない

動く、の定義は、ソフトでLEDがチカチカすること。HWで組んだカウンタではチカチカしてる。

実験1

以前2014/11に動かなかったブログの後に、以下を自分でやってた。
[Quartus]グローバルクロック設定と確認方法
http://bobgosso.blog13.fc2.com/blog-entry-370.html
でも今回はこれだけでは動かず。



[Quartus] Mico32のデータ用SRAMがマッピングされない?


Quartus > Analysis & Synthesis > View Report > LPM Parameter Settings > RAMs
 > asyncram Parameter Settings by Entity instance
 > これで見ると、以下2つのRAMが表示されている。

ether:ether1|lm32_top:LM32|lm32_cpu:cpu|lm32_instruction_unit:instruction_unit|pmi_ram_dp_true_altera:ram|altsyncram:ram
ether:ether1|lm32_top:LM32|lm32_cpu:cpu|lm32_load_store_unit:load_store_unit|pmi_ram_dp_true_altera:ram|altsyncram:ram

 > load_store_unit内のデータ用RAMも認識されている。



Quartus > Fitter > View Report > Resource Section > RAM Summary
ether:ether1|lm32_top:LM32|lm32_cpu:cpu|lm32_instruction_unit:instruction_unit|pmi_ram_dp_true_altera:ram|altsyncram:ram|altsyncram_bni1:auto_generated|ALTSYNCRAM

 > ここでは、instruction_unit内の命令用RAMしか認識されてない。



Fitterレポート(*.fit.rpt)には以下のようにinstruction_unitのみRAMになってる。
; Fitter RAM Summary                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         

; Name ; Type ; Mode ; Clock Mode ; Port A Depth ; Port A Width ; Port B Depth ; Port B Width ; Port A Input Registers ; Port A Output Registers ; Port B Input Registers ; Port B Output Registers ; Size ; Implementation Port A Depth ; Implementation Port A Width ; Implementation Port B Depth ; Implementation Port B Width ; Implementation Bits ; M9Ks ; MIF ; Location ; Mixed Width RDW Mode ; Port A RDW Mode ; Port B RDW Mode ; ECC Mode ; ECC Pipeline Registers ; Fits in MLABs ;

; ether:ether1|lm32_top:LM32|lm32_cpu:cpu|lm32_instruction_unit:instruction_unit|pmi_ram_dp_true_altera:ram|altsyncram:ram|altsyncram_hni1:auto_generated|ALTSYNCRAM ; AUTO ; True Dual Port ; Single Clock ; 2048 ; 32 ; 2048 ; 32 ; yes ; no ; yes ; no ; 65536 ; 2048 ; 32 ; 2048 ; 32 ; 65536 ; 8 ; inst_ram_data.mif ; M9K_X51_Y35_N0, M9K_X64_Y35_N0, M9K_X64_Y32_N0, M9K_X51_Y36_N0, M9K_X64_Y33_N0, M9K_X51_Y33_N0, M9K_X51_Y37_N0, M9K_X51_Y34_N0 ; Don't care ; New data with NBE Read ; New data with NBE Read ; Off ; No ; No - Unknown ;

Note: Fitter may spread logical memories into multiple blocks to improve timing. The actual required RAM blocks can be found in the Fitter Resource Usage section.



Mapレポート(*.map.rpt)を見ると、lm32_load_store_unitのRAMの扱われ方がinstruction_unitのRAMとは違うようだ。
Warning (14284): Synthesized away the following node(s):
Warning (14285): Synthesized away the following RAM node(s):
Warning (14320): Synthesized away node "ether:ether1|lm32_top:LM32|lm32_cpu:cpu|lm32_load_store_unit:load_store_unit|pmi_ram_dp_true_altera:ram|altsyncram:ram|altsyncram_dmi1:auto_generated|q_a[0]" File: C:/user/work/quartus/DE2-115/ether/soc/db/altsyncram_dmi1.tdf Line: 43
Warning (14320): Synthesized away node "ether:ether1|lm32_top:LM32|lm32_cpu:cpu|lm32_load_store_unit:load_store_unit|pmi_ram_dp_true_altera:ram|altsyncram:ram|altsyncram_dmi1:auto_generated|q_a[1]" File: C:/user/work/quartus/DE2-115/ether/soc/db/altsyncram_dmi1.tdf Line: 79
  :
Warning (14320): Synthesized away node "ether:ether1|lm32_top:LM32|lm32_cpu:cpu|lm32_load_store_unit:load_store_unit|pmi_ram_dp_true_altera:ram|altsyncram:ram|altsyncram_dmi1:auto_generated|q_a[31]" File: C:/user/work/quartus/DE2-115/ether/soc/db/altsyncram_dmi1.tdf Line: 1159



実機でLM32が動かない原因(これが動かない原因か不明だが、データ用RAMがマッピングされない事)は、
`define SIMULATION を宣言してるのが問題か?
以前どんな判断したか忘れたが、SIMULATIONをdefineしてた。
FPGAにインプリするためには、これdefineしてはダメなのでは?



[Quartus] Warning (xx): Synthesized away the following RAM node(s)

上に書いた流れでデバッグしてみた。
QuartusのAdvanced Settings(Synthesis)やAdvanced Settings(Fitter)のオプションを見直したが、これでは直らず。

以下のコメントをヒントに、load_store_unitのRAM出力をFPGAトップまで引き上げて信号出してみた。
結果、Synthesized awayのWarningは消えた!

https://www.alteraforum.com/forum/showthread.php?t=21882
A signal is synthesized away, if it's not used in the design, more exactly, if no FPGA output signal depends on it.





pmi_ram_dp_true_altera > Lattice用RAMからAltera用RAMへ個人的に変えてる
#(
// ----- Parameters -------
.pmi_family (`LATTICE_FAMILY),
.pmi_addr_depth_a (`CFG_DRAM_LIMIT/4-`CFG_DRAM_BASE_ADDRESS/4+1),
.pmi_addr_width_a (clogb2_v1(`CFG_DRAM_LIMIT/4-`CFG_DRAM_BASE_ADDRESS/4+1)),
.pmi_data_width_a (`LM32_WORD_WIDTH),
.pmi_addr_depth_b (`CFG_DRAM_LIMIT/4-`CFG_DRAM_BASE_ADDRESS/4+1),
.pmi_addr_width_b (clogb2_v1(`CFG_DRAM_LIMIT/4-`CFG_DRAM_BASE_ADDRESS/4+1)),
.pmi_data_width_b (`LM32_WORD_WIDTH),

.pmi_regmode_a ("noreg"),
.pmi_regmode_b ("noreg"),
.pmi_gsr ("enable"),
.pmi_resetmode ("sync"),
.pmi_init_file (`CFG_DRAM_INIT_FILE),
.pmi_init_file_format (`CFG_DRAM_INIT_FILE_FORMAT),
.module_type ("pmi_ram_dp_true")
)
ram (
.ClockA (clk_i),
   :
.QA (dram_data_out),
.QB (load_store_unit_ram_out) > 元は接続無しだったが、この信号に接続して上の階層へ引き出す。
);


lm32_load_store_unit.v > 上の階層へ引き出す
lm32_cpu.v        > 上の階層へ引き出す
ether.v          > 上の階層へ引き出す(これがMico System Builderで生成するRTLトップ)
ether_top.v       > ここがFPGAトップ。以下のように、てきとーに信号をLEDR[1](FPGA出力)へ出してる。

assign LEDR[1] = !load_store_unit_ram_out ;





[MSB] 割り込みハンドラに飛ばない

しょーもない話だけど、MSBで構成変更したりして、
 A = Generate Base Address
 I  = Generate IRQ
 D = Run DRC
 G = Run Generator
とやった時、Generatorでファイルが生成されない時は、
コンソールにばらばらと表示されずに、1行とかで終わる時がある。
これはたぶんファイルを生成しようと思ったら上書き出来ずに失敗した時とかだと思う。

対策として、既存のcomponentを改名して、一からcomponentフォルダを作らせるとちゃんとGeneratorが走る。
これをさぼってて、RTLが更新されなかった事が原因で、割り込みハンドラにジャンプしない原因になったらしい。



[Quartus] lpm_mltもSynthesized away nodeになった


Warning (14284): Synthesized away the following node(s):
Warning (14285): Synthesized away the following DSP element node(s):
Warning (14320): Synthesized away node "ether:ether1|lm32_top:LM32|lm32_cpu:cpu|lm32_multiplier:multiplier|lpm_mult:Mult0|mult_7dt:auto_generated|mac_mult7" File: C:/user/work/quartus/DE2-115/ether/soc/db/mult_7dt.tdf Line: 66
Warning (14320): Synthesized away node "ether:ether1|lm32_top:LM32|lm32_cpu:cpu|lm32_multiplier:multiplier|lpm_mult:Mult0|mult_7dt:auto_generated|mac_out8" File: C:/user/work/quartus/DE2-115/ether/soc/db/mult_7dt.tdf Line: 90





[Quartus] sysresetが内部FF駆動でGlobal Signalになってない?

<ether.vの中身>

reg [2:0] counter;
wire sys_reset = !counter[2];


Mico System Builderで生成されたRTLトップ見ると、リセット信号は内部カウンタから生成されてる。
これがあると、Global Signalとして扱われるのか?

Quartus > Fitter > View Report > Resource Section > Global & Other Fast Signals
ここでGlobal Signalを調べられる。

CLOCK_50  Location=PIN_Y2  Fan-Out=2107
KEY[0]    Location=PIN_M23  Fan-Out=2092

Fan-Outが2000以上あるから、counterというFF(FlipFlop)を超えてGlobal Signalが適用されてるみたい。




[Quartus] LM32動かない箇所シミュレーション

instruntion_unit/ramはRTLと同じ動きしてるように見えるが、load_store_unit/ramは同じでない。
しかもPOATB/WEは信号が消えてる。

ネットリストでの信号名

◆ether1|LM32|cpu|load_store_unit{ramの信号
// Location: M9K_X51_Y25_N0
cycloneive_ram_block \ether1|LM32|cpu|load_store_unit|ram|ram|auto_generated|ram_block1a28 (
.portawe(gnd),
.portare(vcc),
.portaaddrstall(gnd),
.portbwe(gnd),  > PORTBのWEはなぜGNDになってる?
.portbre(vcc),
.portbaddrstall(gnd),
.clk0(\CLOCK_50~inputclkctrl_outclk ),
.clk1(\CLOCK_50~inputclkctrl_outclk ),
.ena0(\ether1|LM32|cpu|stall_x~3_combout ),
.ena1(\ether1|LM32|cpu|stall_m~combout ),
.ena2(vcc),
.ena3(vcc),
.clr0(gnd),
.clr1(gnd),
.portadatain({\~GND~combout ,\~GND~combout ,\~GND~combout ,\~GND~combout }),
.portaaddr({\~GND~combout ,\~GND~combout ,\~GND~combout ,\~GND~combout ,\~GND~combout ,\~GND~combout ,\~GND~combout ,\~GND~combout ,\~GND~combout ,\~GND~combout ,\~GND~combout }),
.portabyteenamasks(1'b1),
.portbdatain({ \ether1|LM32|cpu|load_store_unit|dram_store_data_m[31]~63_combout , \ether1|LM32|cpu|load_store_unit|dram_store_data_m[30]~61_combout , \ether1|LM32|cpu|load_store_unit|dram_store_data_m[29]~59_combout , \ether1|LM32|cpu|load_store_unit|dram_store_data_m[28]~57_combout }),
.portbaddr({\ether1|LM32|cpu|operand_m [12],\ether1|LM32|cpu|operand_m [11],\ether1|LM32|cpu|operand_m [10],\ether1|LM32|cpu|operand_m [9],\ether1|LM32|cpu|operand_m [8],\ether1|LM32|cpu|operand_m [7],\ether1|LM32|cpu|operand_m [6],\ether1|LM32|cpu|operand_m [5],\ether1|LM32|cpu|operand_m [4],
\ether1|LM32|cpu|operand_m [3],\ether1|LM32|cpu|operand_m [2]}),
.portbbyteenamasks(1'b1),
.devclrn(devclrn),
.devpor(devpor),
.portadataout(\ether1|LM32|cpu|load_store_unit|ram|ram|auto_generated|ram_block1a28_PORTADATAOUT_bus ),
.portbdataout(\ether1|LM32|cpu|load_store_unit|ram|ram|auto_generated|ram_block1a28_PORTBDATAOUT_bus ));


portbweがGND固定になってる。RTLでは信号入れてるのに。動いてない、と判断されたのか?

.WrA (`FALSE),
.WrB (store_q_m & dram_select_m),




; Registers Removed During Synthesis

; Register name ; Reason for Removal

; ether:ether1|lm32_top:LM32|lm32_cpu:cpu|lm32_load_store_unit:load_store_unit|d_stb_o ; Merged with ether:ether1|lm32_top:LM32|lm32_cpu:cpu|lm32_load_store_unit:load_store_unit|d_cyc_o ;
; ether:ether1|lm32_top:LM32|lm32_cpu:cpu|lm32_load_store_unit:load_store_unit|dram_select_m ; Stuck at GND due to stuck port data_in ;
; ether:ether1|lm32_top:LM32|lm32_cpu:cpu|lm32_load_store_unit:load_store_unit|wb_select_m ; Stuck at GND due to stuck port data_in ;
; ether:ether1|lm32_top:LM32|lm32_cpu:cpu|lm32_load_store_unit:load_store_unit|wb_load_complete ; Lost fanout ;
; ether:ether1|lm32_top:LM32|lm32_cpu:cpu|lm32_load_store_unit:load_store_unit|byte_enable_m[1] ; Merged with ether:ether1|lm32_top:LM32|lm32_cpu:cpu|lm32_load_store_unit:load_store_unit|byte_enable_m[0] ;
; ether:ether1|lm32_top:LM32|lm32_cpu:cpu|lm32_load_store_unit:load_store_unit|size_m[1] ; Merged with ether:ether1|lm32_top:LM32|lm32_cpu:cpu|lm32_load_store_unit:load_store_unit|byte_enable_m[2] ;



; Removed Registers Triggering Further Register Optimizations

; Register name ; Reason for Removal ; Registers Removed due to This Register ;

; ether:ether1|lm32_top:LM32|lm32_cpu:cpu|lm32_load_store_unit:load_store_unit|dram_select_m ; Stuck at GND ; ether:ether1|lm32_top:LM32|lm32_cpu:cpu|lm32_load_store_unit:load_store_unit|wb_load_complete ;
; due to stuck port data_in ;


load_store_unitのRAM/portbweがGNDにスタックされているので、論理が動いてないからかと思い、
FPGA出力まで引き出して見たが変わらず。

load_store_unit|dram_select_m ; Stuck at GND due to stuck port data_in

よくよく見ると、RAM/WrBに入力されているstore_q_m & dram_select_mの方ではなくて、
「due to stuck port data_in」って、WrBがDisable?

load_store_unit.ramのパラメータを調べると、

defparam ram.width_byteena_a= 1;
defparam ram.width_byteenb_a= 1;

が抜けてた。これが原因か?
bit幅はてきとーに1bitにした。
 :
試すが、これでもLM32ソフトによるLEDチカチカは動作せず。
シミュレーションだと意図した動きになってるのに、なぜかQuartusでDE2-115にインプリすると、Mico32のプログラムが動作しない。




[LM32] system_conf.v LATTICE_FAMILYは"EC"でなく"SC"を使え。

ソース追ってないので理由は不明だが、system_conf.vで
`define LATTICE_FAMILY "EC"
から
`define LATTICE_FAMILY "SC"
にしたら、Mico32のプログラムによるLEDチカチカした!

ちなみにsystem.confの最初の数行は以下設定。

//`define LATTICE_FAMILY "EC"
// 2018.1.4
`define LATTICE_FAMILY "SC"
`define LATTICE_FAMILY_EC
`define LATTICE_DEVICE "All"
`ifndef SYSTEM_CONF
`define SYSTEM_CONF
  :



変更した箇所として、厳密にはLATTICE_FAMILYをSCにしたら、
components/uart_core/rtl/verilog/rxcver_fifo.v
components/uart_core/rtl/verilog/txcver_fifo.v
で使ってるpmi_fifo_dcが無いと言われ、同等回路をQuartusのIP CatalogでFIFO作った(中身はdcfifo)。




1.85us付近からLM32のINST RAMアドレス0x1a4から0xb4のループになる


問題?が起こる前にやった事
ソースの置き場所をgitへまとめた後、DE2-115でMico32の動作を確認しようとしたら、
IROM=BASE 0x0, Size 0x2000、 DRAM=BASE 0x2000, Size 0x2000
ではelfがオーバーした。なので、
IROM=BASE 0x0, Size 0x4000、 DRAM=BASE 0x4000, Size 0x4000
に変えた。


症状

ループとなるアドレスは、
tb_ether_top.uut.ether1.LM32.cpu.instruction_unit.ram.ram.address_a
の信号でいうと、0x69から0x6dの間。
1アドレス32bit(4バイト)のため、4倍すると、0x1a4から0xb4になる。
elfからobjdumpした中身で見ると、このアドレスの期間は以下になる。


1a0: 38 63 44 7c ori r3,r3,0x447c

000001a4 <.ClearBSS>:
1a4: 44 23 00 04 be r1,r3,1b4 <.CallConstructor>
1a8: 58 20 00 00 sw (r1+0),r0
1ac: 34 21 00 04 addi r1,r1,4
1b0: e3 ff ff fd bi 1a4 <.ClearBSS>

000001b4 <.CallConstructor>:
1b4: 78 04 00 00 mvhi r4,0x0


何やらmain関数に行く前にループしてるような感じ。


解決するまでにやった事

・system_conf.vを古い方を読んでいた。不要なsystem_conf.vを削除して1つだけにした。さらに以下。
  > LATTICE_FAMILYは"SC"になってるので問題なし。
  > `define CFG_IROM_LIMIT 32'h1fff から 32'h3fff へ変更した。
  > `define CFG_DRAM_BASE_ADDRESS 32'h2000 から 32'h4000 へ変更した。
  > `define CFG_DRAM_LIMIT 32'h3fff から 32'h7fff へ変更した。

・IROMとDRAMのアドレスを12ビット(4096バイト)にしたので、Verilogソースもアドレス12ビットになっているか確認した。

・memory.def を修正。
  > .rdata 0x00002000: { のアドレスを 0x00004000 に変更した。
  > スタックポインタの . = 0x00004000 + (1024*8) - 4; の加える値を (2048*8) に変更した。

・シミュレーションを175usまで進めたら、main関数の先頭コードまで進んだ。


IROM/DRAMサイズを変えた事で、上記の変更は必要になったが、加えて、シミュレーション時間を175usまで
待たずに、途中の動きを見て、勝手に問題視したようだ。
main関数まで進めた設定で、1.85us付近を見ると、やはり.address_a信号は、
1.8us付近から、0x69から0x6dの間のループが始まり、17.17us付近まで続いていた。
なのでこの動きは全く問題無いみたい。


2022.6.7 命令メモリ(lm32_instruction_unit.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"




ベースアドレスは、ビルドした際のstartup.sやmemory.def、さらにはmemcvtプログラム設定と一致してるか?


`define CFG_IROM_BASE_ADDRESS 32'h0
`define CFG_DRAM_BASE_ADDRESS 32'h2000




micosystem.exeで生成されるcomponent/lm32_top/rtl/verilog/lm32_include_all.v内でpmi_def.vが読まれてないか?


`ifndef SIMULATION
`include "pmi_def.v" → SIMULATION宣言が無いとpmi_def.vが読まれるが、これは中身の論理が無い箱なのでveritakコンパイル通ってしまうが、中身の動作が無く、信号がzになったりする問題発生。
`endif




instruction_unitとload_store_unitの中で、pmi_ram_dp_trueを使ってないか?


これを使うとなぜかveritakシミュレーションがスタートしない(止まるというより最初から進まない)。
過去対策したようで、代わりに自作したpmi_ram_dp_true_altera.vを使うとシミュレーションが進むようになった。




テストベンチ内のtimescale設定が無くて、例えば生成したクロックがps単位の高速なパルスになってないか?


そうするとおそらくPLLとか一部の回路は動作しないはず。





2022.6.13 UART入力割込でinterrupt_handlerに飛ばない

RTLシミュレーションでLattice Mico32のinterrupt_nはアサートされている事は確認してる。
一度Cソースビルド前にclean projectしてみたら、生成されたsw.elfの各セクション容量に違いが出たので、これはこれで原因の1つと思う。
  → clean project(クリーンプロジェクト)する前は、.dataセクションなどデータメモリの値がALLゼロだった。これは明らかにおかしい。
それでもまだ割込入ると、crt0からmainへ飛んでしまう。なぜ?


[Veritak]エラー箇所が分からない(2022.11.26)

Veritakでコンパイルすると、いつからかLattice Mico System Builder(MSB)で生成したトップVerilogの48行目でエラーが出る。

module arbiter2


でもMSBで生成した直後なので、文法ミスしてるとは考えにくい。
どうも原因が見つからない。
そんな時は、他のシミュレータもしくは合成ツールでデバッグしよう。
今回はQuartusでコンパイルしてみた。
すると、Veritakで指摘されたモジュールの上の階層で、指摘された。

Error (10171): Verilog HDL syntax error at HOGE_lm32_test.v(831) near end of file ; expecting ")"
 > これは上位階層の最後の行ね。

どうやらMBS生成のトップではなく、その上の回路記述で何か文法ミスっているようだ。

[LM32](3)interrupt_handlerにjumpしない原因解析

ether.elfをobjdumpで逆アセンブルした。
シミュレーション波形と見比べてみると、
INSTメモリは0x0番地から実行される。


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
c: 78 01 00 00 mvhi r1,0x0
10: 38 21 02 a8 ori r1,r1,0x2a8
14: d0 e1 00 00 wcsr EBA,r1
18: f8 00 00 3a calli 100 <_crt0> > ここで_crt0(0x100)へjump
1c: 34 00 00 00 nop > 0x18 calliで実際にjumpする前にフェッチされた。

00000020 <_breakpoint_handler>:
20: 90 e0 38 00 rcsr r7,EBA > 0x18 calliで実際にjumpする前にフェッチされた。
   :
fc: 34 00 00 00 nop > ここ0xfcへjumpした。なぜ0x100に直接jumpしないか不明。

00000100 <_crt0>:
100: 98 00 00 00 xor r0,r0,r0
104: 78 1c 20 00 mvhi sp,0x2000
108: 3b 9c 1f fc ori sp,sp,0x1ffc
10c: 78 1a 20 00 mvhi gp,0x2000
110: 3b 5a 80 00 ori gp,gp,0x8000
114: 78 01 00 00 mvhi r1,0x0
118: 38 21 02 a4 ori r1,r1,0x2a4
11c: 78 02 00 00 mvhi r2,0x0
120: 38 42 02 a4 ori r2,r2,0x2a4
124: 44 22 00 04 be r1,r2,134 <_crt0+0x34>
128: 78 03 00 00 mvhi r3,0x0
12c: 38 63 08 f8 ori r3,r3,0x8f8
130: f8 00 00 30 calli 1f0 <_relocate_text>
134: 78 01 20 00 mvhi r1,0x2000
138: 38 21 00 00 ori r1,r1,0x0
13c: 78 02 00 00 mvhi r2,0x0
140: 38 42 08 f8 ori r2,r2,0x8f8
144: 44 22 00 08 be r1,r2,164 <_crt0+0x64>
148: 78 03 20 00 mvhi r3,0x2000
14c: 38 63 00 04 ori r3,r3,0x4
150: 44 23 00 05 be r1,r3,164 <_crt0+0x64>
154: c8 61 18 00 sub r3,r3,r1
158: 78 04 00 00 mvhi r4,0x0
15c: 38 84 06 88 ori r4,r4,0x688
160: d8 80 00 00 call r4 > ここで0x688へjump。
164: 78 01 20 00 mvhi r1,0x2000 > jumpする前にフェッチされた。
168: 38 21 00 04 ori r1,r1,0x4 > jumpする前にフェッチされた。
16c: 78 02 00 00 mvhi r2,0x0
   :
684: c3 a0 00 00 ret

00000688 :
688: b8 20 38 00 mv r7,r1 > 今度のjumpは0x688に直接jumpした。
68c: b8 40 28 00 mv r5,r2
690: b8 20 20 00 mv r4,r1
694: 34 06 00 0f mvi r6,15
698: 50 c3 00 19 bgeu r6,r3,6fc
69c: b8 41 08 00 or r1,r2,r1
6a0: 20 21 00 03 andi r1,r1,0x3
6a4: 5c 20 00 16 bne r1,r0,6fc
6a8: b8 c0 28 00 mv r5,r6
6ac: 28 41 00 00 lw r1,(r2+0)
6b0: 34 63 ff f0 addi r3,r3,-16
6b4: 58 81 00 00 sw (r4+0),r1
6b8: 34 42 00 04 addi r2,r2,4
6bc: 28 41 00 00 lw r1,(r2+0)
6c0: 34 84 00 04 addi r4,r4,4
6c4: 58 81 00 00 sw (r4+0),r1
6c8: 34 42 00 04 addi r2,r2,4
6cc: 28 41 00 00 lw r1,(r2+0)
6d0: 34 84 00 04 addi r4,r4,4
6d4: 58 81 00 00 sw (r4+0),r1
6d8: 34 42 00 04 addi r2,r2,4
6dc: 28 41 00 00 lw r1,(r2+0)
6e0: 34 84 00 04 addi r4,r4,4
6e4: 58 81 00 00 sw (r4+0),r1
6e8: 34 42 00 04 addi r2,r2,4
6ec: 34 84 00 04 addi r4,r4,4
6f0: 50 a3 00 0f bgeu r5,r3,72c
6f4: e3 ff ff ee bi 6ac
6f8: b8 40 28 00 mv r5,r2
6fc: 34 63 ff ff addi r3,r3,-1
700: 64 61 ff ff cmpei r1,r3,-1
704: 5c 20 00 08 bne r1,r0,724
708: 40 a1 00 00 lbu r1,(r5+0)
70c: 34 63 ff ff addi r3,r3,-1
710: 64 62 ff ff cmpei r2,r3,-1
714: 30 81 00 00 sb (r4+0),r1
718: 34 a5 00 01 addi r5,r5,1
71c: 34 84 00 01 addi r4,r4,1
720: 44 40 ff fa be r2,r0,708
724: b8 e0 08 00 mv r1,r7
728: c3 a0 00 00 ret
72c: 34 01 00 03 mvi r1,3
730: 50 23 ff f2 bgeu r1,r3,6f8  > ここで何かが起こり、0x0番地へ戻った。simulation時間62us地点。

その後、IROMのアドレスを見ると。0x0から順次実行
  > 0x168まで行った後、0x688へjump
  > そのまま0x730まで実行した後、0x0へ戻る。2回目のこの地点でsim時間118us地点。
これがずっと繰り返されるようだ。



0x730での命令bgeuが原因のようだ。何が起こったのか。

LatticeMico32 Processor Reference Manual で調べると、
r1がr3以上であれば、PC + へ分岐する。
という事らしい。

bgeu r1,r3,6f8
Syntax = bge rX, rY, imm16
Semantics = if (gpr[rX] >= gpr[rY]) PC = PC + sign_extend(imm16 << 2)




■memcvt.c設定を疑う

#define INST_BASE_ADDR 0x00000000
#define INST_SIZE_LIMIT (1024*16)
#define RWDATA_BASE_ADDR 0x20000000
#define RWDATA_SIZE_LIMIT (1024*8)
#define TARGET_MEM_WIDTH (256/8) > これは.mifではなく.v用かな?
#define TARGET_MEM_WIDTH_MIF 4

system_conf.v内の設定 `define CFG_IROM_LIMIT 32'h3fff
system_conf.v内の設定 `define CFG_DRAM_LIMIT 32'h20003fff


上の設定で、
#define TARGET_MEM_DEPTH_MIF 2048
こうすると、data_ram_data.mifは全て0x00データになる。これは以前正常動作してた時と同じ。
しかし今はリセット番地0x0へのループが発生。

#define TARGET_MEM_DEPTH_MIF 4096
ちなみにこうすると、data_ram_data.mifは0x801辺りから最後0xfffまで初期値が存在するようになった。
こちらもリセット番地0x0へのループが発生。
カレンダー
11 | 2023/12 | 01
- - - - - 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コード