Contenu connexe Similaire à ハードウェア脳とソフトウェア脳 (20) ハードウェア脳とソフトウェア脳5. ハードウェアエンジニアの場合
• 横軸で表現します
• タイミングチャート
• クロックに対して厳密なタイミング設計が必要になるため
• 私がA4方眼ノートを愛用しているのはこのころの名残り
• ⾧い時間の感覚
• 数十~百マイクロ秒以上
• 例えば、1サイクル100MHzで10クロックかかる処理=100ns=0.1μs
• シミュレーションデータの作成が大変
• そこそこ時間がかかる
10ns
20ns
5ns
CLK
nCS
nW/R
ADDR[15..0]
DATA[15..0]
nACK
時間2017/08/12 FuraIT #33発表資料
10. ハードウェアエンジニアの場合
• 自由
• 1bit単位でも値を変更可能
• 飛び飛びのbitでも同時に変更可能
• 1byte/word中の特定のbitのみ変更することも可能
• wordサイズは自由
• 8bit/word、16bit/word、24bit/word、etc.
Address Bit 7 6 5 4 3 2 1 0
0x0000 0 0 0 0 0 0 0 0
Bit 3と5だけ1を書き換え
“01001000”を書くのとは異なる
Address Bit 7 6 5 4 3 2 1 0
0x0000 0 1 0 0 1 0 0 0
どうにでもできる
2017/08/12 FuraIT #33発表資料
11. ソフトウェアエンジニア
• CPU依存
• 一般的には1byte、2byte、4byte、8byteのいずれか。
• bit単位の制御はできない
• どこかのbitを変更するには、1byte読みだして、対象ビットとそれ以外のビットをマスクして、変
更したい値とそれ以外の元の値をORして書き戻すとか。
00000010を書く
Status 0が0になる
Address
Bit 7 6 5 4 3 2 1 0
Status 1 Status 0
0x0000 0 0 0 0 0 0 1 1
Bit 0のStatus 0だけをクリアしよう
0x0000 0 0 0 0 0 0 1 0
2017/08/12 FuraIT #33発表資料
13. メモリの配置と構造体
• 経験の浅いハードウェアエンジニア(当時の私)が考えるとこうなったりする
#define INTR_MASK 0x0F; // 00000111
#define SEND_BUF_MASK 0x04; // 00000100
#define RECV_BUF_MASK 0x02; // 00000010
#define DETECT_MASK 0x01; // 00000001
uint8_t status = *(status_reg);
uint8_t send_buf_status = status & SEND_BUF_MASK;
uint8_t recv_buf_status = status & RECV_BUF_MASK;
uint8_t detect_status = status & DETECT_MASK;
if (detect_status) {
....
}
#define INTR_MASK 0x0F; // 00000111
#define SEND_BUF_MASK 0x04; // 00000100
#define RECV_BUF_MASK 0x02; // 00000010
#define DETECT_MASK 0x01; // 00000001
uint8_t status = *(status_reg);
uint8_t send_buf_status = status & SEND_BUF_MASK;
uint8_t recv_buf_status = status & RECV_BUF_MASK;
uint8_t detect_status = status & DETECT_MASK;
if (detect_status) {
....
}
読みだして、所望のビットを取り出すので面倒
一つのアドレスに
複数機能を詰め込む
Address Bit [7..3] Bit 2 Bit 1 Bit 0
0x0000 0 送信ステータス 受信ステータス デバイス検出
空きビットあるの
もったいないから
詰め込もう
2017/08/12 FuraIT #33発表資料
14. メモリの配置と構造体
• ソフトウェア思考があると、こうするので便利(アドレスに余裕があれば)
struct status {
uint8_t detect;
uint8_t send_buf;
uint8_t recv_buf;
};
Struct status intr = *(status_reg);
If (intr.send_buf) {
} else if (intr.detect) {
struct status {
uint8_t detect;
uint8_t send_buf;
uint8_t recv_buf;
};
Struct status intr = *(status_reg);
If (intr.send_buf) {
} else if (intr.detect) {
Bit [7..2] Bit 1 Bit 0
0x0000 - 割り込み1 割り込み0
0x0001 - - 送信完了
0x0002 - - 受信完了 機能ごとにレジスタ(アドレス)を分ける
ソフトウェアが
扱いやすいデータ
構造にしておこう
2017/08/12 FuraIT #33発表資料
17. ハードウェアの場合
• VerilogHDL、VHDL
• 全部が同時に起きる
• でも微妙な伝播時間も暗黙の了解で頭に入ってる
• ↓上から順ではなく全部同時に発生する
always @(posedge clk or posedge reset) begin
if (reset) begin
mem[addr] <= 0;
q <= 0;
end
else begin
mem[addr] <= d;
q <= mem[addr];
end
end
簡単なメモリデバイスの例
2017/08/12 FuraIT #33発表資料
19. 新人時代に悩んだこと(ハードウェア)
• どうがんばっても上から処理するように読んでしまう
• プログラミングの経験が頭から離れない
• 入門書が存在しない(当時は)
• 趣味でFPGAのロジック設計するなんてまずない
• 資料も基本的にプロ向けに書かれている
• 先輩たちが不親切だったとかは別な話としてある…
always @(posedge clk or posedge reset) begin
if (reset) begin
mem[addr] <= 0;
q <= 0;
end
else begin
mem[addr] <= d;
q <= mem[addr];
end
end
always @(posedge clk or posedge reset) begin
if (reset) begin
result[addr] <= 0;
end
else begin
result[addr] <= q + data;
end
end
全部同時に発生する
んだけど、上から順に
考えてしまう。
2017/08/12 FuraIT #33発表資料
22. プログラマブルロジックの原理
• LUT
入力1 入力2 出力
0 0 0
0 1 0
1 0 0
1 1 1
LUT DFF
AND回路
入力1 入力2 出力
0 0 0
0 1 1
1 0 1
1 1 1
OR回路
ADDRESS 出力
00 0
01 0
10 0
11 1
メモリ
ADDRESS 出力
00 0
01 1
10 1
11 1
メモリ
メモリで実現した
真理値表
2017/08/12 FuraIT #33発表資料
25. ハードウェアエンジニア
• 性能見積もり
• ハードウェアスペックを基にした理論値
• ハードウェアの制御を考慮した理論値
• ソフトウェアの動作も考慮した期待値はソフトウェアエンジニアにお任せ
• ROM/RAMサイズ
• 部品代を安くしたい
• 拡張性を考慮すると回路設計がちょっとだけ面倒だから考慮したくない
USB2.0 480Mbps,
DDR4-1600 12.8GB/s, etc.
理論値のみで、
実際の性能までは
見積もれない
2017/08/12 FuraIT #33発表資料
27. 失敗例
• 見積もりを大幅に超えてしまう
• 思ったよりソフトウェアの処理が多くて性能が出ない。
• DRAM、Flashの容量が足りない。
• 何度か経験しました...。
• 原因
• 他のハードウェアがバスの帯域を使っていた。
• 自分の機能しかみてない。(理論値にとらわれて実動作を考えていない)
• 思っていたよりプログラムサイズが大きかった。
• 度重なる仕様追加・変更。
• ものすごい手戻りコスト(設計、製造)
• 製品仕様に影響。
• 部品発注、回路修正、上司への説明。
• これは解決策は思いつかないです
• 念入りなベンチマーク、リスクの推定、経験などなど。
急がば回れ
慌てて進めても良いこと無い
2017/08/12 FuraIT #33発表資料
28. たまには成功例も
• 事前に一緒に確認
• ハードウェアエンジニアもソフトウェアを作ってベンチマークしていた。
• でも、実際のソフトウェアを疑似的に作るところまではできなかった。
• 実環境に近いソフトウェアを作成し、一緒に仕様を事前検証した。
• ベンチマーク結果をもとに変更要求
• ハードウェアエンジニアは理論値を基に部品選定していた。
• 同等のシステムでベンチマークしていたので設計変更をお願い。
• CPUの処理不可が高いことが分かっていた。
• 理由が明確なため、すぐにハードウェアの仕様変更をしてもらえた。
2017/08/12 FuraIT #33発表資料
32. よくある誤解
• ソフトウェアで処理するよりハードウェアで処理した方が速い
• 速度だけならソフトウェアでデータコピーした方が速いこともある
• ハードウェアがメモリアクセスしていればCPUもメモリアクセスできない
• 速度やCPU処理負荷も考えて選択する
• 割り込みが大量に発生してソフトウェアが処理できないとか
• ソフトウェアはなんでもできるけど...
• ソフトウェアで実現することが正しいかは別問題
• ビットスタッフィングのソフトウェア実装をしていたことが...
ビットスタッフィング概略
・データの開始と終わりは”01111110”
・5個の1が続くデータ”11111”は、6bitの”111110”にする
01111110 01111111 01011111
01111101
01111110
01111110 10101111 01111110 10xxxxxx
ビットスタッフィング前
ビットスタッフィング後
データ⾧可変&
全ビットチェック
こんなのHWの仕事
2017/08/12 FuraIT #33発表資料
35. 言いたいこと
• どうしたら最適な設計ができるかを考えましょう
• 「自分が知っている」、「自分の設計に都合がいい」ではない。
• 使う人の立場で考えてみましょう。
• 他人の知恵、知識を吸収しましょう
• ソフトウェアであればOSSのコード
• ハードウェアであれば他社のデータシート
• 通信ハードウェアであれば16550の各機能とその意味くらいは理解しておきましょう
• 自分の専門分野を極めると同時に、他人の分野にも興味を持ってみましょう
• 「どうして?」と思うようなことにも理由はある。
• 自分が興味を持てない仕事をにも、新たな発見があるかもしれません。
• たくさんのことに触れることで、より良いものを作れるようになると思います。
2017/08/12 FuraIT #33発表資料