Atmel のサイトを見ていたら
Tiny20/
Tiny40 というのがあるのに気がついた。Tiny10 の仲間かと思ってデータシートをダウンロードしてみたら 全然違った。
TPI があるから 仲間ではあるが、Tiny20 は 14 pin で、Tiny44A とかと互換性があるピンアサイン。Tiny40 は 20 pin で 他とは互換性がない。
で、両方とも SPI と TWI が付いている。なにかスレーブ・コントローラに徹した感じがする。
そんなことより Tiny20/Tiny40 は命令が 54 しかない。Tiny10 ですら 112 命令 あるというのに。(普通 Tiny は 123 - 125 命令)
- いまさら命令を大幅に減らすとは、なかなか興味ぶかい。どの命令を減らしたのか? なぜそれで問題ないのか? について 分かったことがあったらここに追記していこうと想う。
- 一番興味があるのは なぜそうしたか。命令を減らせばチップ面積は減るだろうけど、大して変わらないような気もする。32 個の 特別な I/O レジスタとか 2レジスタ 転送命令 や ビット操作命令 をやめれば チップ面積を減らせてクロックを上げられそうな気がするが、どうなのだろう?
... とか思ったのだが、命令表を見たら 以下のように 普通だった。
算術命令 (20)
ADD , ADC, SUB , SUBI , SBC , SBCI, AND, ANDI, OR, ORI , EOR , COM ,
NEG , SBR, CBR , INC , DEC, TST , CLR , SER
ブランチ命令 (34)
RJMP, IJMP, RCALL, ICALL, RET, RETI,
CPSE, CP , CPC, CPI, SBRC, SBRS, SBIC, SBIS
BRBS, BRBC, BREQ, BENE, BRCS, BRCC, BRSH, BRLO, BRMI,
BRPL, BRGE, BRLT, BRHS, BRHC, BRTS, BRTC, BRVC, BRVS, BRIE, BRID
ビット・フラグ操作 (28)
SBI, CBI, LSL, LSR, ROL, ROR, ASR , SWAP, BSET, BCLR, BST, BLD, SEC,
CLC, SEN, CLN, SEZ, CLZ, SEI, CLI, SES, CLS, SEV, CLV, SET, CLT
SEH, CLH
ロード・セーブ (10)
MOV, LDI, LD(9), LDS, ST(9), STS, IN, OUT, PUSH, POP
MCU命令 (4)
BREAK, NOP, SLEEP, WDR
これだと 96命令。 LD/ST の アドレッシングモードを別にカウントして 112 命令。
Tiny2313 (123 命令) と比べてないのは以下のもの
算術命令 (2)
ADIW, SUBIW
ロード・セーブ (5)
MOVW, LDD, STD, LPM(3), SPM
ちょっと数が合わないが、要するに 2レジスタ転送命令系がなくなった先祖返りで Tiny10 と同じということか。ちなみに LPM, SPM は TPI ベースで仕組みが違う以上 なくなる方が自然。
なんだ。
ただ、54 って何? というのが次の疑問。
少なく見積もって 96 だ。大幅に減らすとしたら ブランチ命令 の条件と フラグ操作のフラグ名を モードの違いと定義づけるしかない。
BREQ, BENE, BRCS, BRCC, BRSH, BRLO, BRMI,
BRPL, BRGE, BRLT, BRHS, BRHC, BRTS, BRTC, BRVC, BRVS, BRIE, BRID
これを BRBS, BRBC の別名にすれば -16 。
SEC, CLC, SEN, CLN, SEZ, CLZ, SEI, CLI,
SES, CLS, SEV, CLV, SET, CLT, SEH, CLH
これを BSET, BCLRの別名にすれば さらに -16 。
こうすると 64 命令にはなる。しかし後 10 命令は?
LSL 0000:11dd:dddd:dddd # logical shift left (= ADD Rd,Rd)
ROL 0001:11dd:dddd:dddd # rotate left thru C (= ADC Rd,Rd)
TST 0010:00dd:dddd:dddd # TEST (= AND Rd,Rd)
CLR 0010:01dd:dddd:dddd # clear register (= XOR Rd,Rd)
SBR 0110:KKKK:dddd:KKKK # set bit register (= ORI)
SER 1110:1111:dddd:1111 # set register to 255 (= LDI) (追加)
どうも別名の命令がもともとあるらしい。これで -6 。
(追記: SER に後で気がついた。以下それに合わせて修正)
なんでもアリなら carry あり/なし を 1 命令に定義しなおすことは可能だ。
ADD 0000:11rd:dddd:rrrr # add without carry
ADC 0001:11rd:dddd:rrrr # add with carry
SBC 0000:10rd:dddd:rrrr # subtract with carry (borrow)
SUB 0001:10rd:dddd:rrrr # sub w/o carry
CP 0001:01rd:dddd:rrrr # compare withoout carry
CPC 0000:01rd:dddd:rrrr # compare with carry
SBCI 0100:KKKK:dddd:KKKK # subtract immediate with carry
SUBI 0101:KKKK:dddd:KKKK # subtract immediate w/o carry
こんな風な関係。普通ではないかも知れないが、これで数はあう。
あとは、SET/CLEAR だとか INC/DEC とか シフトの方向だとかで 2個イチにはできる。
BRBS 1111:00kk:kkkk:ksss # branch if bit set
BRBC 1111:01kk:kkkk:ksss # branch if bit cleared
BSET 1001:0100:0sss:1000 # bit set in FLAGS
BCLR 1001:0100:1sss:1000 # bit clear from FLAGS
CBI 1001:1000:AAAA:Abbb # clear bit in I/O register
SBI 1001:1010:AAAA:Abbb # set bit in I/O register
SBIC 1001:1001:AAAA:Abbb # skip if bit cleared in I/O register
SBIS 1001:1011:AAAA:Abbb # skip if bit set in I/O register
LSR 1001:010d:dddd:0110 # logical shift right
ROR 1001:010d:dddd:0111 # rotate right thru car
INC 1001:010d:dddd:0011 # increment register
DEC 1001:010d:dddd:1010 # decrement
極めつけは、演算つき レジスタ間移動命令
AND 0010:00rd:dddd:rrrr # logical AND
EOR 0010:01rd:dddd:rrrr # exclusive OR
OR 0010:10rd:dddd:rrrr # inclusive OR
MOV 0010:11rd:dddd:rrrr # copy register
遊びのようなものだが、減らす方法はいろいろありそうだ。
まぁいいや。しかし、命令数を 可能な限り少なく見積もるのに なにか意味があるのだろうか?
ちょっと驚いたが、普通だということが分かって安心した。
... と思ったが汎用レジスタが 32本→16本に減っているのに気がついた。これは面倒な話。
こんな AVR は存在したことがない。AT90S2313 や その前の世代の AT90S1200 ですら 32個ちゃんとある。レジスタ減らすと ABI の定義から初めて GCC までだいぶ改造しないといけないはず。
ちなみに 16 個のレジスタは、r16 - r31 。X/Y/Z レジスタがあるから当然か。
で、そこまでするメリットがあるわけか。
レジスタは単純なメモリではない。最低でも 1 clock (あたり) LOAD x 2 + STORE ができないといけない。2 レジスタ同時だと STORE x 2 。しかも、パイプラインプロセッサだから、演算結果を STORE する前に参照できないといけない。配線の規模がばかにならないということになる。
ちなみに、I/O レジスタも メモリではなくレジスタなのだ。分岐命令で BIT を見たり できるから 特別な配線が必要。これも規模が増える要因。だが、32 より上のアドレス(こちらはメモリに近い)に移動したりしていないようだ。削減の効果がレジスタほどではないということか。
追記: 頑張って GCCで サポートしたようだ。ググってみると、
The AVR 8-bit GNU Toolchain : Release 3.1.0.206
The AVR 8-bit GNU Toolchain adds support to the following devices: • ATxmega128B1. ATTiny10 Support.
それは良かった。FPGA なんかで 互換プロセッサを作る場合、規模を減らしても GCC が使えるというわけだ。(というより、こういうのは FPGA でこそ有用だろう。)
それはともかく、ATxmega128B1って何? USB とか付くと嬉しいのだが。
これは本当に USB 付きらしい。見つけたのはロシア語のページだったのでよく分からないが、どうも (開発版?) Flip に ATxmega128B1 が USB デバイスとして登録されているらしい。これに限らず開発ツールは発表前に対応するから 注意深く見ていると じきに入ってくるだろう。
結構嬉しい。入手できる頃にホンキを出そう。
追記: WinAVR は開発終了で AVR Toolchain に移行したのだそうだ。知らなかった。
とりあえず、レジストなしで入手するには、AVR Tools Beta Site に行って、AVR32 Studio 2.7 (Windows 版と Linux 版がある) の zip をダウンロードし、そこから抜き出すしかないかも。zip で 300MB 前後あるから 全部をインストールするのは、ちょっと 困る。gcc がある .../x86 ディレクトリだけ取り出して zip で固めると 84MB まで減る。ここから さらに avr32 関係と doc,info,man など抜いてしまえば 30MB まで減る。
とりあえず取ってきたものは、AVR32 Studio 2.7.0.851 (Toolchain 3.1.0.201012011657)。これをちょっと使ってみようかと思う。
ところで、ついでに次の文章を見付けた。
(Tiny10 について) But its use is limited by its silly programming scheme - it requires 5V power and 5V singles on 3 of the 4 IO pins.
TPI のデバイスを扱う場合は、電源周りをよくよく調べておかないと。
さて、ちょっとでも興味があるのは Tiny20 か。なにしろ Tiny44 系と似ている。
- ADC が シングルエンドしかない。AREF もない。
- USI がなくなり SPI/TWI が付いた。
- ISP がなきなり TPI になった。
- 水晶/セラロックは付かない。
- DIP がなくなり TSSOP が追加された。
命令以外の違いはこんなところか。TWI や SPI が付いたのは嬉しいし、TPI も歡迎。だが、ADC の機能は寂しくなった。
劣化した機能は、実際には役に立たない/あまり使われない... ということだろうか?
確かに USI での I2C スレーブは問題があった。2レジスタ転送命令系は性能が多少違うだけ。
ADC はどうなのだろう?
ちなみに、Touch sensing という 特別な項目があり、QTouch ライブラリに最適化したチップだという説明がある。どういうことだろう? 普通のADC のようにしか見えないのだが。
追記: まったく説明がないが QTCSR というレジスタがあった。なんだろう?