onedriveの自動バックアップを切るお話
onedriveの自動バックアップを切るお話
自動バックアップをオフにしても、再起動後、ONに戻る
最近、winodows11へアップデートしたのですが、デスクトップとドキュメントフォルダがonedriveの自動バックアップ対象になってしまいました。
もしかしたら直近のwinodwsアップデート(2024/1/12)が原因かも。win11へアップデート直後は大丈夫だった気がします。
そのせいで、OneDrive上のドキュメントフォルダとCドライブにあったドキュメントフォルダがマージされて、くちゃくちゃになってしまいました。。。(ひどいよマイクロソフトさん)
検索すると、windows11はデフォルトでそのような動作になってしまうとの事。
自動バックアップ対象になると何が困るかというと、
CドライブはSSDにしていて、"デスクトップ"とか"ドキュメント"フォルダはCドライブにあります。onedriveはサブスクリプション契約で1TBで契約しているため、低容量のSSDではなくっ大容量のHDDのフォルダへ移動させています。該当フォルダがonedriveの自動バックアップ対象になってしまうと、OneDriveのフォルダ配下に"デスクトップ"とか"ドキュメント"フォルダが移動してしまいます。
そのため、"デスクトップ"とか"ドキュメント"が低速なHDDになってしまうことが問題です。
既存アプリがデータの格納場所として、元々の場所を見ている場合、動作しないこともありそうです(適当書いちゃいましたが、こちらは不明。ハードリンクで解決している感じがします)
また、これらのフォルダは、さして重要でないファイルを気軽に置いてきたため、サイズも肥大化してきており、かつイマイチ整理する気力が今更ないという事もあり、そのようなくだらないデータでOneDriveの様な高コストなストレージを使うのがもったいない
あと、僕の場合は、1TBと割と余裕があるのでいいですが、無料の場合には5GBしかないので、そもそもこれらのフォルダがOneDriveへ収容できない(容量不足でアップロードできないので同期エラーが起きる)という問題もありそうです。
という事で、 同期を止めたいと思いました。
onedriveの設定→"同期とバックアップ"→"バックアップを管理"
で自動バックアップをオフにしました。
以下の様な画面で警告が出ているうちはスイッチをスライドできません。おそらく、ドキュメントフォルダのデータをOneDriveへ移動の最中は本警告は消えないようです。サイズが大きいと時間がかかりますので気長に待ちます。
オフに出来たら、OneDrive配下に移動してしまったドキュメント配下のファイルを、元の場所へ移動します。(c:\ユーザー\xxxx\ドキュメント)
この際に、"ドキュメント へのショートカット (OneDrive - 個人用)"というショートカットが生成されていますが、削除します。(ショートカット先は意図せず出来たOneDriveのドキュメントになります)
これで作業は終了だと思ったのは、間違いで、再起動すると、またもドキュメントがOneDrive配下へ移動するという事態が発生。ひどいよマイクロソフトさん。
そして、自動バックアップ対象のスイッチもONに戻ってしまっています。
検索しても、そのような事例は見つからず。バグなのか、仕様なのか、分かりません。事例がないので、前者だと信じたい。
しかし、この状態は好ましくない。。。
色々調査すると、PCの再起動さえ行わなければ、自動バックアップはオフのままです。
OneDriveアプリを再起動しても自動バックアップの設定はキープされています。
PicoRV32のプログラムをSDRAM上で動かす(TangNano20K)
- はじめに
- 課題
- フラッシュからITCMへ命令実行を遷移する方法の解析
- ITCM実行部分をSDRAM領域へ差し替えを行う(ソフト面)
- スタックポインタの設定を行う(ソフト面)
- ITCM実行部分をSDRAM領域へ差し替えを行う(ハード面)
- 合成済みPicoRV32の再利用方法
- SDRAMで命令を実行するためのその他のハード情報
- 回路の公開
- SDRAMの動作速度について
- SDRAMコントローラインスタンス部のサンプル
- 動作速度について
- Gowin_PicoRV32合成でリセットパスのセットアップエラーの修正
- まとめ
- 参考資料
- 次回予定
はじめに
Gowin_PicoRV32の命令の実行方法は下記の3択になっております。
実行速度は3.が最も早く、1.が最も大きなプログラムが動かせます。
TangNano20KのITCMのデフォルトサイズは32KBで(実際にサイズの大きなプログラムを作る機会があるか?というのは置いておいて)、ちょっと込み入ったものを作るとすぐに枯渇してしまいます。
TangNano20KのBSRAMは32KB使った状態でもまだ余っているので、サイズを大きくできる余地があるとはいえ、そんなに大きくできるわけではありません。
じゃーフラッシュメモリを使えばよいのではないか?という話になるのですが、読み出し速度がとてつもなく遅く、実行速度がガタ落ちになってしまいます。
というわけで、SDRAM上に命令コードを置いて、かつキャッシュメモリを挟めば、そこそこの速度を出しつつ大容量(8MB)の命令空間を確保できるのはないか?というのが発想です。 ただ今にして思えば、フラッシュメモリにキャッシュメモリを挟むだけでよかったのでは?とも思います。
課題
フラッシュメモリからSDRAMへ命令コードを転送して、かつSDRAMへPC(プログラムカウンタ)を移動させる必要があります。メモリ配置でリンカをうまく使う必要がありそうで、その知識がないため難しそうです。
という慣れた人には、なんら課題でもない気がしますが、自分には大きな課題でした。
今回、IP版のPicoRV32には"フラッシュメモリ→ITCM"へ命令を移すという事が簡単に出来てしまうので、ITCM部分をSDRAMへ変更すれば実現できるのはないか?と思ったからです。
ソースコードの解析とか色々やってますが、SDRAM上で動かすための方法だけを知りたい方は、
ITCM実行部分をSDRAM領域へ差し替えを行う(ソフト面) へ飛んでください。
フラッシュからITCMへ命令実行を遷移する方法の解析
どのように実現しているかを前回使ったリファレンスデザインのソフトを解析してみました。
ブート方法をFLASH→ITCMとした場合には、loader.cのboot() から実行されます。
(config.hで BUILD_MODE == BUILD_BURN としている場合)
なぜboot()
だと特定したかは後ほど記載します。
_lma_ldsec_startなどの変数はexternで参照されています。
本変数はリンカファイルsections.lds にて定義されています。
本変数がアドレスであることは、想像がつくかと思いますが、実アドレスの特定は難しいので一旦置いておいて、boot()で何を行っているかを見てみます。
おそらく_lma_ldsec_startから配置されているコードを_vsloaderの示すアドレスへコピーしていることは分かります。またそのコピーサイズは(&lma_ldsec_end - &lma_ldsec_start)byteです。
また、
src_ptr += 0x4100000; src_ptr_end += 0x4100000;
コピー元アドレスの算出のため、lma_ldsec_startに対し0x4100000を加算しています。
この値は4byte単位である(unsigned intでsrc_ptr変数を作っている)ので、0x4100000をbyte単位に変換すると、0x1040_0000になります。このアドレスはFLASHメモリのアドレスになります。
リンカファイルで定義されたアドレス情報を命令コードが置かれているFLASHメモリのアドレスへ変換しているのだと思います。
つまり、FLASHメモリに書き込まれた命令コードを、リンカファイルで定義されたアドレス**vsloader**へコピーしているのだろうと思います。
おそらく、リンカファイルで定義されたアドレスとはITCMのアドレスを示しているのだろうと大方予想が付きます。
読み進めると
__asm__ __volatile__("la t3, _vsloader"); __asm__ __volatile__("jr t3");
という記述が現れるので、_vsloaderのアドレスへbranchしていることが分かります。
つまりここでコピーしたコードの先へbranchしています。
ここでリンカファイルの方へ戻って、_lma_ldsec_end の定義を見てみます。
_lma_ldsec_end = _lma_ldsec_start + SIZEOF(.ldsec);
と書いてあります。コピーサイズは.ldsecのサイズ分だという事が分かります。
.ldsecのサイズはリンカファイルから
.ldsec : AT (_lma_ldsec_start) { _vsloader = .; ~ } >SMEM
の部分であることが想像は付きますが、具体的にどこのコード部分かが分かりません。
また、本sectionに_vsloaderと記載があるので、先ほどのコピー先がこの位置であることが想像できます。
このセクションの最後のSMEM
というキーワードですが、リンカファイルの先頭で
SMEM (rxai!w) : ORIGIN = 0x02000000, LENGTH = 32K /* LENGTH based on hardware configuration of ITCM size */
と記載があります。 SMEMとはITCMの領域で先頭アドレスが0x02000000だったのですね。
とはいえ、セクション.ldsecのスタートがITCMの先頭ではなく、SMEM領域の定義はこの部分より前に.textのセクションが存在しています。この.textセクションがITCMの先頭に配置されます。
そしてITCMが0x0200_0000から配置されています。
(本来はハード情報から、このmakefileを作る流れになりますが、私はmakefileが分からないので本来とは逆の順序で見ています)
_vsloader のアドレスの特定
make時に、ディスアセンブルリストが生成されます。生成場所は以下になります。
Gowin_PicoRV32_V1.3\ref_design\MCU_RefDesign\picorv32_demo\Debug\picorv32_demo.lst
このリストで、_vsloader のアドレスを特定することにします。
本ファイル中のvsloaderを検索すると私のディスアセンブルリストでは以下の様になっていました。
02001c34 g .ldsec 00000000 _vsloader
アドレス0x02001c34
がvsloderの先頭なので、disアセンブルリストから02001c34
を検索します。
void loader(void) { 2001c34: 1101 addi sp,sp,-32 2001c36: ce22 sw s0,28(sp) 2001c38: 1000 addi s0,sp,32 …
上記のところにヒットします。関数loaderの先頭だという事が分かります。
関数loaderもコピー処理になります。きちんとは見ていないですが、おそらくFLASHの内容を同様にITCMへコピーして、ITCMのアドレスへブランチしているものと思われます。
リセット解除後、最初に実行される関数は?
最初に実行される関数は何でしょうか?
リンカのファイルにはそれらしい記述は、なかったです。正しいアドレスへプログラムが配置されればよいだけなので、もしかするとリンカは理解していないかもしれません。
ソフト面から追うのではなく、ハード面から追うことにしました。とにかくpicorv32のリセットベクタさえ分かればよいので、IDEがインストールされているIPが格納されているフォルダをなんとなく見てみました。
C:\Gowin\Gowin_V1.9.8.11_Education\IDE\ipcore\GowinPicoRV32\Gowin_PicoRV32\picosoc.v
がGOWIN_PicoRV32のTOPモジュールのようで、ここを見てみると
localparam [31:0] PROGADDR_RESET = `PROGADDR_RESET_DEF;
という記述があります。PROGADDR_RESET_DEF
が定義されているところを探すと
同フォルダのpico_config.vh
なるファイルにて定義されていました。
`define PROGADDR_RESET_DEF 32'h1040_0000
とあるのでリセットベクタはアドレス0x1040_0000
らしい事が分かりました。
このあたりのハード情報が記載されているドキュメントを見つけることが出来ませんでした。
分かりやすいところに記載があると良いのですが。。。
ここで逆アセンブルリストでアドレス10400000
を探すと、以下を見つけることが出来ました。
void boot(void) { 10400000: 1101 addi sp,sp,-32 10400002: ce22 sw s0,28(sp) 10400004: 1000 addi s0,sp,32 …
つまりリセット解除後、最初に実行される関数はboot()
関数のようです。
リンカファイルsections.lds
でも
FLASH (rxw) : ORIGIN = 0x10400000, LENGTH = 1M
となっていてアドレスが同じですね。
リンカはどうやってアドレスを決めているか?
大体Cのソースコードの流れは把握しました。
リンカはどのようにしてアドレスを決めているのでしょうか?
改めて、 リンカファイルsections.lds
へ目を向けると
ENTRY(start)
の後に
SECTIONS { _lma_btsec_start = 0; .btsec : AT (_lma_btsec_start) { _vsbtsec = .; KEEP(*.o(.btsec)) . = ALIGN(4); } >FLASH _lma_btsec_end = _lma_btsec_start + SIZEOF(.btsec);
大きなSECTIONS
の中に.btsec
というセクションが切られています。
そして、アドレスは_lma_btsec_start
であると記載され、_lma_btsec_start=0
と書かれています。
また本セクションはFLASHに割り付けらています。
つまり0x10400000
をベースとするアドレス0番地が.btsec
でありFLASHメモリであると分かります。
そして.btsec
はCソースコードのどこを指すかというとloader.c
に以下の様な記述があります。
void boot(void) __attribute__((section(".btsec")));
void loader(void) __attribute__((section(".ldsec")));
ここでboot(void)
は.btsec
セクションであると定義されています。
また。loader(void)
は、.ldsec
セクションであると定義されています。
リンカファイルsections.lds
へ戻って続きを読むと 、.ldsecセクションは.text
の後ろに定義されています。
また.ldesc, .text
両セクションともSMEM領域であるとも記載されています。
.text
セクションがSMEM領域の先頭と定義されているので、つまりココが、ITCMの先頭アドレスになります。
.text
セクションはどのソースかというと、逆アセンブルリストによるとstart.S
になります。
02000000 <_vstext>: reset_vec(): <ソース配置フォルダ>\Gowin_PicoRV32_V1.3\ref_design\MCU_RefDesign\picorv32_demo\Debug/../src/start.S:26 .section .text .global irq
きちんとアドレスと関数の関係及び、実行するアドレス順序をまとめたい気がしますが、目的はプログラムをSDRAMで実行させることで、ここまでの理解で十分だと思うので、細かく追うのはここまでにします。
ITCM実行部分をSDRAM領域へ差し替えを行う(ソフト面)
boot()が実行されるアドレス(0x200_0000番地でした)をSDRAMのアドレスへ書き換えればよいと分かります。
より簡単に実現するために、単にITCM空間をSDRAM空間へ差し替えます。
よってリンカファイルsections.lds
を以下の様に書き換えます。
SMEM (rxai!w) : ORIGIN = 0x30000000, LENGTH = 1M /* LENGTH based on hardware configuration of ITCM size */
SDRAM領域は0x3000_0000から1Mbyte分用意することにしました。(後ほど、ハード情報を記載します)
ITCMは使わない設定にします。
但し、GOWIN_PicoRV32をインスタンスする際に気が付くと思いますが、ITCMのサイズは0に出来なくて、最小8KB作る必要があるようです。(今回はこの8KBは全く使わない、もったいないRAMになってしまいました)
スタックポインタの設定を行う(ソフト面)
サンプルデモではスタックを使わないのかスタックポインタの設定がされていませんでした。
loader.c
のloader(void)関数
でスタックポインタを設定します。
__asm__ __volatile__("la t3, _vstext");
の行の手前に以下を追記します。
extern int _stack_start; __asm__ __volatile__("la sp, _stack_start-4"); __asm__ __volatile__("la t3, _vstext");
_stack_start
変数はリンカファイルsections.lds
で設定します。
.eh_frame
セクションの下に以下のような.stack
セクションを記述します。
.stack ORIGIN(RAM) + LENGTH(RAM) - _stack_size : { . = ALIGN(16); PROVIDE(_stack_end = .); . = _stack_size; . = ALIGN(16); PROVIDE(_stack_start = .); } >RAM
ソフト面はリンカファイルの書き換え、追記とスタックポインタの設定を行うのみです。
逆アセンブルリストを追ったりしましたが、正直なところ不要でした。キーワード検索で本ブログを参考にした方々にも無駄な時間を使わせた気がします。
ITCM実行部分をSDRAM領域へ差し替えを行う(ハード面)
picorv32のリセットベクタは変わらずFLASHの0x1040_0000のままでよいです。
しかし、先ほどのpicorv32のリセットベクタを記述しているファイルpico_config.h
には、もう一行defineがありました。
`elsif BUILD_BURN
`define PROGADDR_RESET_DEF 32'h1040_0000
`define PROGADDR_IRQ_DEF 32'h0200_0010 ←この行がITCMのアドレス
PROGADDR_IRQ_DEF
というdefineです。ITCMのアドレス+0x0010
が定義されています。
割込みベクタの定義でしょうか?このあたりの説明のドキュメントが見つけられなくて、勘になります。
SDRAM領域は0x3000_0000以降1Mbyteと決めているので、以下の様に書き換えてしまいます。
ただ、本ファイルはIDEインストールフォルダのIPが格納されているフォルダにあるファイルですので、書き換えてしまうと、オリジナルのGOWIN_picoRV32とは異なるものになってしまいます。オリジナルは取っておくなどして、十分注意して作業を行いましょう。
`elsif BUILD_BURN `define PROGADDR_RESET_DEF 32'h1040_0000 //`define PROGADDR_IRQ_DEF 32'h0200_0010 `define PROGADDR_IRQ_DEF 32'h3000_0010
書き換えた後、GOWIN_IDEでpicorv32を再度IP呼び出しを行ってください。
ITCMの設定はMCU boot from External flash and run in ITCM
へチェックを入れます。またITCMのサイズは0が設定できないので最小の8KBに設定します。
また、この際に生成フォルダ(Create In:のところ)をデフォルトから書き換えてgowin_picorv32_run_sdram
と後から見て分かりやすい場所にしておくというのも良いかと思います。見やすい以外にも理由があって後述します。
OKボタンを押すとPicoRV32の合成が始まります。
PicoRV32の合成が終わってしまえば、pico_config.h
はオリジナルに戻してしまってもよいです。全体の合成時に、PicoRV32単体の合成が再度かかる事はありません。
以上、ハード面は1行を書き換えればよいです。
合成済みPicoRV32の再利用方法
少し話は逸れまずが、オリジナルPicoRV32と今回修正したPicoRV32をデバッグなどの目的でちょくちょく切り替えることが想定されるような場合に時短できる小技を紹介します。
GOWIN_IDEのDesignタブでRTLファイルを指定しますが、IPの場合にはIPを呼び出すとココに自動的に追加されます。ソースファイルを右クリックすると下のスクショの様にEnable,Disableが切り替えられます。
この機能を使って、Designペインのところにあらかじめ、合成済みのSDRAM実行版とITCM実行版の両方のpicorv32を用意しておきます(よってpicorv32の合成時は生成フォルダを別にしておかないといけません)。
このDesignペインで使う側のpicorv32をEnable,使わない側をDisableとして全体合成を行うと、disableと指定した側は合成対象外になるので、都度picoRV32を作成しなくても、あらかじめ合成済みのものを呼び出して使うという事が可能になります。
つまりは、構成の異なるPicoRV32(今回はSDRAMで動く版とITCMで動く版)をあらかじめ合成してDesignペインに追加しておけば、マウス右クリックで簡単に切り替えが出来ます。
SDRAMで命令を実行するためのその他のハード情報
アドレスマップ
全体ブロック図
簡単ですが、今回作成した回路のブロックを示します。PicoRV32から発行されたアクセス(アドレス0x3000_0000から1MB分の領域のみ)をキャッシュコントローラ経由でSDRAMメモリへアクセスします。
キャッシュメモリの構成は、(こんなショボい容量ではありますが)4wayセットアソシアティブです。容量は4KBです。BSRAMの構成上、おそらく容量は4倍まで増やしても利用BSRAM数は変わらないんじゃないかと思われます。
(BSRAMは1個あたり1Kx16bitの容量を持つので、今回32bit幅のRAMとして使っているので1wayあたり2個のBSRAMを消費してしまいます。つまり4wayで8個、容量にしてトータル16KBにもなります)。詳しくは過去記事参照↓
spend-carefree.hatenablog.com
キャッシュメモリコントローラの性能
PicoRV32のwishboneバスにぶら下げていて、以下のような性能になります。あまり速くありません。
Read Hit時 : 4cycle
Write Hit時: 2cycle
Readの時は、TAGメモリからアドレスを引き出してHit/Miss判定を行うため、時間がかかってしまいます。
Write動作は、キャッシュの判定を待たないで、一旦書き込む動作を行っているので早いです。
また、SDRAMへのアクセスは、命令の読み出し動作がほとんどになるので、write動作がread動作より早いというのは全体の実行時間に対する割合は非常に小さいです。
それでも4cycleは外部FLASHメモリで動作するよりずっと高速です。
回路の公開
SDRAMコントローラは前回の記事でgitで公開していますが、そこからバグ取りなど行い再度アップロードしています。以下になります。
■SDRAMコントローラ
tangnano20k/sdramc at main · kazuokada/tangnano20k · GitHub
■キャッシュコントローラ(新規)
tangnano20k/picorv32_cachec/rtl at main · kazuokada/tangnano20k · GitHub
公開はしていますが、デバッグ中(後述)という事もあり、動作は不安定です。ひたすらにコードは汚いです。
SDRAMの動作速度について
GOWINのドキュメントによると166MHzまで動作するはずですが、安定動作が確認できたのは95MHzでした。133MHzへ上げると、動いたり動かなかったりで不安定でした。
キャッシュコントローラに不具合があるのか、SDRAMへのアクセスがうまくいかないのか。どちらに原因があるのか突き止められませんでした。
SDRAMから出力されるリードデータをキャプチャするタイミングはSDRAMコントローラとは独立したクロック(clk_capdq)で行っていて、何通りか振ってみたのですが、調整の結果、アクセスが可能になったはずなのに、次の日に試したら何も変更していないのに時折データが化けたりと安定しません。リードタイミングを振りましたが、ライトで失敗している可能性もあります(低速では動作しているのでライトはOKだと思いますが)。
とりあえず95MHzでは安定動作しているので、95MHzで動かす事にします。(なのでキャッシュコントローラはうまく動けていると信じたい)
なんとか、133MHzでも安定動作を目指したいですけど、安定化作業だけで既に3week程度使っているので、一旦原因突き止めは休憩です。
SDRAMコントローラインスタンス部のサンプル
リードタイミングに係わる部分でパラメータを変更するようにしているので、そのサンプルという事で、インスタンス部を置いておきます。
`define SDRAM95M
のdefine定義がインスタンス前に行われているという前提です。(ifdef SDRAM95M
が存在していないのですが、という指摘は合ってます。現状、何もセットしなくても意図通りのパラメータが引き渡されます)
sdramc #( `ifdef SDRAM166M .FREQ(166*1000000), // 166MHz .PHASE_SHIFT_CLKIN(0) // when clk_capdq != sdramclk `else `ifdef SDRAM150M .FREQ(150*1000000), // 150MHz .PHASE_SHIFT_CLKIN(1) // when clk_capdq != sdramclk `else `ifdef SDRAM132M .FREQ(132*1000000), // 132MHz .PHASE_SHIFT_CLKIN(1) // when clk_capdq != sdramclk `else .FREQ(95*1000000), // 94.5MHz .PHASE_SHIFT_CLKIN(1) // when clk_capdq != sdramclk `endif `endif `endif ) inst_sdramc ( // SDRAM side interface .SDRAM_DQ(IO_sdram_dq), // inout [31:0] .SDRAM_A(O_sdram_addr), // out [10:0] .SDRAM_BA(O_sdram_ba), // out [1:0] .SDRAM_nCS(O_sdram_cs_n), // out / not strictly necessary(), always 0 .SDRAM_nWE(O_sdram_wen_n), // out .SDRAM_nRAS(O_sdram_ras_n), // out .SDRAM_nCAS(O_sdram_cas_n), // out .SDRAM_CLK(O_sdram_clk), // out .SDRAM_CKE(O_sdram_cke), // out / not strictly necessary(), always 1 .SDRAM_DQM(O_sdram_dqm), // out [3:0] // Logic side interface .clk(sdramclk), // input .clk_sdram(sdramclk), // input / phase shifted from clk (normally 180-degrees) //.clk_sdram(~sdramclk), // input / phase shifted from clk (normally 180-degrees) `ifdef SDRAM166M .clk_capdq(sdramclk), // DQ capture clock //.clk_capdq(sdramclk_90d), // DQ capture clock `else `ifdef SDRAM150M //.clk_capdq(sdramclk), // DQ capture clock .clk_capdq(~sdramclk), // DQ capture clock `else `ifdef SDRAM132M .clk_capdq(~sdramclk), // DQ capture clock //.clk_capdq(sdramclk_90d), // DQ capture clock //.clk_capdq(sdramclk), // DQ capture clock `else .clk_capdq(sdramclk_90d), // DQ capture clock //.clk_capdq(~sdramclk), // DQ capture clock `endif `endif `endif .resetn(sys_resetn_sdramc), // input .addr(cmd_addr_sdram), // input [22:0] byte address(), buffered at cmd_en time. 8MB .busy(), // output / 0: ready for next command .cmd(cmd_sdram), // input 0:read(), 1:write .cmd_en(cmd_en_sdram), // input .cmd_ack(cmd_ack_sdram), // output .cmd_len(cmd_len_sdram), // input [3:0] 0-15 .rd_data(cmd_rdata_sdram), // output [31:0] .rd_data_valid(cmd_rvalid_sdram), // output .wr_data(cmd_wdata_sdram), // input [31:0] .wr_mask(cmd_wmask_sdram) // input [3:0] );
動作速度について
以前に、以下の記事でbmp画像をHDMI表示させる挑戦しましたが、この時の動作速度との比較をします。
spend-carefree.hatenablog.com
前回(FLASH上で命令実行) | 今回(キャッシュを介してSDRAM上で実行 |
---|---|
80秒 | 6.9秒 |
10倍以上高速化が出来ました。
Gowin_PicoRV32合成でリセットパスのセットアップエラーの修正
本記事とは関係ないのですが、、、
PicoRV32を37.125MHzで利用しています。
Place&Route工程でリセットの同期化と思われる部分でセットアップエラーが発生しました。
パスを確認すると、リセットをクロックの逆相で同期化していました。そのため、PicoRV32コアへのリセットパスが半サイクル分のセットアップ時間しかなくエラーになりました。
以下のファイルを修正すると直りますが、これまたIP部を触ることになりますので、重々承知の上、作業を行う必要があります。
IDEのverは1.9.8.11
<GOWIN IDEインストールdir>\IDE\ipcore\GowinPicoRV32\Gowin_PicoRV32\picosoc.v
316行目のalways文のnegedgeをposedgeへ変更
まとめ
- ソフト開発環境はすごく便利(MCU designer)。
- SDRAMを高速動作させるのは難しい。phy部のタイミングが未考慮で済むようにSDRAMデータが必ず取得できるクロックとかあるとありがたいのだが。(私の設計のロジックのバグの可能性がありますが)
- SDRAMのACタイミングが公開されていないのがつらい。(ドキュメント見つけられないだけかも)
2、3部分で時間の大半を使ってるので。。 - IPになっているGOWIN_PicoRV32 取り扱いが簡単でよい。
ただ、SIMが出来ないのは我慢するとして、ロジックアナライザ―で内蔵RAMとの接続部分が観測出来たらなぁとデバッグ時に思う事がありました。
参考資料
- Gowin PicoRV32のドキュメント群
https://www.gowinsemi.com/ja/support/ip_detail/46/ - Gowin MCU Designerのマニュアル
https://www.gowinsemi.com/ja/support/download_eda/
次回予定
TangPrimer20Kを触りたいと思います。ただネタはなし。実は一度破壊しました。再注文しました。