ショッピングモール  CD/DVD搭載コンポ  CD+HDDコンポ  クラシック調オーディオ  CD/MDシステム


【掲示板ご利用上の注意】

 ※題名は具体的に!
 ※学校の課題の丸投げ禁止!
 ※ソースの添付は「HTML変換ツール」で字下げ!
 ※返信の引用は最小限に!
 ※環境(OSとコンパイラ)や症状は具体的に詳しく!
 ※マルチポスト(多重投稿)は謹んで!

 詳しくはこちら



 本当はこんなに大きく書きたくはないのですが、なかなか守っていただけなくて…。
 守ってくださいね。お願いします。(by管理人)

C言語ソース⇒HTML形式ツール   掲示板1こちら


管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    記事検索    ログ    タグ一覧

No.3289

Nクロック時間待ち
投稿者---chu-(2005/01/13 11:21:45)


マイコン(SH2(SH7044,SH7047))プログラムをしています。
ある出力ポート(マクロ名:CK_SDA)を100nsecだけハイにしようとしています。
例えば100nsecは4クロック時間に相当するとします。
アセンブラで組むときは単純にNOPを4つ並べています。
C言語では今は下記の用にしているのですが、もっと良い方法はないものでしょうか。

/* Nクロック時間待ちマクロ */
/* コンパイルしてアセンブラコードを出力させてみると */
/* while()の1ループが4クロックかかるコードになっていた */
/* だからnの4分の1回(nの右2シフト回)ループさせている */
#define NOP(n) do{volatile int t=(n)>>2;while(t--);}while(0)

/* 使用例 */
PADRL |= CK_SDA;
NOP(4);
PADRL &= ~CK_SDA;


この投稿にコメントする

削除パスワード

発言に関する情報 題名 投稿番号 投稿者名 投稿日時
<子記事> Re:Nクロック時間待ち 3290 るい 2005/01/13 12:11:57
<子記事> Re:Nクロック時間待ち 3291 tetrapod 2005/01/13 12:17:46
<子記事> Re:Nクロック時間待ち 3292 chu- 2005/01/13 13:33:29


No.3290

Re:Nクロック時間待ち
投稿者---るい(2005/01/13 12:11:57)


asm などのインラインアセンブラは使えませんか?



この投稿にコメントする

削除パスワード

No.3291

Re:Nクロック時間待ち
投稿者---tetrapod(2005/01/13 12:17:46)


# 7047 か、何もかも、みな、なつかしい...

たかだか nop 4回程度で済んでしまうのであればインラインアセンブラを使うのがいいでしょう。
Renesas の SH2 コンパイラなら nop(); 関数でインライン命令生成してくれます。
# RISC 系 CPU なのでパイプラインまで考慮しないと正しく待てませんよ、念のため。

もっと長い待ちが必要ならまた小細工する手もありますが...
どのみち特定コンパイラの特定バージョンの特定コンパイルオプション依存となります。



この投稿にコメントする

削除パスワード

No.3292

Re:Nクロック時間待ち
投稿者---chu-(2005/01/13 13:33:29)


返信ありがとうございます。

コンパイラの記述を忘れていました、申し訳ありません。
・Hitachi SH C Compiler Ver.4.1B

以前調べたことがあるのですが、SH-Cのバージョンが古いのでおそらく
インラインアセンブラはありません。

今テストしたのですが、
volatile unsigned char OP2;
int main(void)
{
    OP2;
    OP2;
    return 0;
}
とすると、
    00000000 D302                   MOV.L       L217,R3    ; _OP2
    00000002 6330                   MOV.B       @R3,R3
    00000004 D201                   MOV.L       L217,R2    ; _OP2
    00000006 6220                   MOV.B       @R2,R2
    00000008 000B                   RTS
    0000000A E000                   MOV         #0,R0
というコードが生成されるようでした。
これはどの最適化オプションでも同じでした。
これを利用して組もうかと考えています。
「OP2;」1つを2クロック時間と考えて問題ないでしょうか。

> # RISC 系 CPU なのでパイプラインまで考慮しないと正しく待てませんよ、念のため。
これはどういうことなのでしょうか。
また、どう対処すればいいのでしょうか。



この投稿にコメントする

削除パスワード

No.3293

Re:Nクロック時間待ち
投稿者---tetrapod(2005/01/13 14:05:22)


>> # RISC 系 CPU なのでパイプラインまで考慮しないと正しく待てませんよ、念のため。
>これはどういうことなのでしょうか。
以下のとおり。

00000000 D302 MOV.L L217,R3 ; _OP2
00000002 6330 MOV.B @R3,R3
>「OP2;」1つを2クロック時間と考えて問題ないでしょうか。
いいえ。この場合パイプラインストールが発生し、もっと時間がかかります。
今この場で答えを言っちゃってもいいんですが、ご自分で調べてみてください。

私が使っているインライン時間待ち関数は以下のとおり。
static inline Inline_Wait_Loop(ureg32 w) { for(;w;) --w; }
MOV #nn, R2
DT R2
BF -2
となって1カウントあたり4クロックを消費します(最初のロードを除く)
数百nsec から 数msec の時間待ちなら最初のロード部分の誤差が無視できるので、これでいけます。
1クロック2クロックしか待つ必要が無いなら #include <umachine.h> してnop(); 関数を使うのがもっとも適切です。
# Version4 でも使えたと思うが...



この投稿にコメントする

削除パスワード

No.3294

Re:Nクロック時間待ち
投稿者---REE(2005/01/13 14:06:09)


>これはどの最適化オプションでも同じでした。
>これを利用して組もうかと考えています。
>「OP2;」1つを2クロック時間と考えて問題ないでしょうか。

OP2一つに付き、レジスタを一つ使っているようなので、
OP2の数が多かったり、他のコードがあったりすると、変わる可能性が高そうです。


余談ですが、待ち無しでも最低1クロック幅にはなるでしょうから、
4クロック分の幅にしたいなら、待ち時間は3クロックになるはずです。
# PADRL &= ~CK_SDA; が1クロックで処理可能と仮定しての話です



この投稿にコメントする

削除パスワード

No.3295

Re:Nクロック時間待ち
投稿者---chu-(2005/01/13 19:08:12)


返信ありがとうございます。

> 00000000 D302 MOV.L L217,R3 ; _OP2
> 00000002 6330 MOV.B @R3,R3
> いいえ。この場合パイプラインストールが発生し、もっと時間がかかります。
分岐も無く、転送するだけのこのコードでストールが発生するのですか。
せっかくいただいたヒントなので考えてみます。

> # Version4 でも使えたと思うが...
残念ながらありません。
[umachine.h]
set_gbr(base), get_gbr(), gbr_read_byte(offset), gbr_read_word(offset),
gbr_read_long(offset), gbr_write_byte(offset,data), gbr_write_word(offset,data),
gbr_write_long(offset,data), gbr_and_byte(offset,mask), gbr_or_byte(offset,mask),
gbr_xor_byte(offset,mask), gbr_tst_byte(offset,mask), tas(addr), trapa(trap_no),
macw(ptr1, ptr2, count), macwl(ptr1, ptr2, count, mask), macl(ptr1, ptr2, count),
macll(ptr1, ptr2, count, mask), trapa_svc, prefetch
[smachine.h]
set_imask(mask), get_imask(), set_cr(cr), get_cr(), set_vbr(base), get_vbr(), sleep()

> OP2の数が多かったり、他のコードがあったりすると、変わる可能性が高そうです。
OP2の数を増やしてみると下記の用に循環していたので大丈夫のようです。
しかし、あまりだらだら並べるのも醜いのでループでの実装と併用しようと思います。
MOV.L L217,R3 ; _OP2
MOV.B @R3,R3
MOV.L L217,R2 ; _OP2
MOV.B @R2,R2
MOV.L L217,R3 ; _OP2
MOV.B @R3,R3
MOV.L L217,R2 ; _OP2
MOV.B @R2,R2

100nsec未満になってしまう可能性が心配だったのですが、返信を読んでいる限り大丈夫そうです。
以下のマクロで組むことにします。
volatile unsigned char OP2_;
#define WAIT2() do{OP2_;}while(0)
#define WAIT4(n) do{int t=(n)-1;while(t--);}while(0)
int main(void)
{
    /* 4x3+2=14クロック時間待ち */
    WAIT4(3);
    WAIT2();
    return 0;
}
P   00000000              _main:                           ; function: main
                                                           ; frame size=0
    00000000 E402                   MOV         #2,R4
    00000002              L219:                             
    00000002 2448                   TST         R4,R4
    00000004 8FFD                   BF/S        L219
    00000006 74FF                   ADD         #-1,R4
    00000008 D101                   MOV.L       L222,R1    ; _OP2_
    0000000A 6110                   MOV.B       @R1,R1
    0000000C 000B                   RTS
    0000000E E000                   MOV         #0,R0
    00000010              L222:                             
    00000010 <00000000>             .DATA.L     _OP2_
B   00000000              _OP2_:                           ; static: OP2_
    00000000 00000001               .RES.B      1



この投稿にコメントする

削除パスワード

No.3299

Re:Nクロック時間待ち
投稿者---tetrapod(2005/01/14 08:49:22)


>分岐も無く、転送するだけのこのコードでストールが発生するのですか。
そのとおり。日立の資料を読んでください。

>#define WAIT4(n) do{int t=(n)-1;while(t--);}while(0)
ループ内が1命令多くて 2BYTE 余計にかかるので、提示コードのほうがいいと思う。
待ち時間は結果同じになるけど... 4CLOCK

Version4 は inline 関数展開しないのでしたっけ?
#define より inline 関数のほうが使いやすいと思います。



この投稿にコメントする

削除パスワード

No.3300

Re:Nクロック時間待ち
投稿者---chu-(2005/01/14 18:58:29)


返信ありがとうございます。

> ループ内が1命令多くて 2BYTE 余計にかかるので、提示コードのほうがいいと思う。
これには自分なりの理由があります。
#define WAIT4(n) do{int t=(n)-1;while(t--);}while(0)

#define WAIT4(n) do{int t=(n);while(--t);}while(0)
とすればtetrapodさんと同じような2バイト少ないコードが出力されるのですが、
それだと、たとえばWAIT4(1);としたときに3クロックになってしまいます。
WAIT4(1);として4クロックとなるように試行錯誤した結果がこのコードです。
それと、RAM容量にはいつも悩まされますが、ROM容量は比較的余裕があります。
そういう理由からこのコードに落ち着きました。

> Version4 は inline 関数展開しないのでしたっけ?
> #define より inline 関数のほうが使いやすいと思います。
C++で趣味プロをするときはconstとinlineでマクロを排除して組む人間ではあるのですが、
残念ながらこの機能もVer.4にはありません。

# 返信を読んでいると、新しいVer.はずいぶん機能アップして便利になってそうですね。
# うらやましい…



この投稿にコメントする

削除パスワード

No.3302

Re:Nクロック時間待ち
投稿者---chu-(2005/01/15 17:12:06)


最終的に以下の用にしました。
#include <machine.h>    /* get_cr */

#define WAIT1()  (void)get_cr()
#define WAIT4(n) do{long t=(n)-1;while(t--);}while(0)

int main(void)
{
    /* 4x2+1=9クロック時間待ち */
    WAIT4(2);
    WAIT1();

    return 0;
}

P   00000000              _main:                           ; function: main
                                                           ; frame size=0
    00000000 E401                   MOV         #1,R4
    00000002              L217:                             
    00000002 2448                   TST         R4,R4
    00000004 8FFD                   BF/S        L217
    00000006 74FF                   ADD         #-1,R4
    00000008 0102                   STC         SR,R1
    0000000A 000B                   RTS
    0000000C E000                   MOV         #0,R0



この投稿にコメントする

削除パスワード

管理者用メニュー    ツリーに戻る    携帯用URL    ホームページ    記事検索    ログ    タグ一覧




掲示板提供:Real Integrity