Successfully reported this slideshow.
We use your LinkedIn profile and activity data to personalize ads and to show you more relevant ads. You can change your ad preferences anytime.

ハードウェア脳とソフトウェア脳

2,015 views

Published on

ハードウェアエンジニアとソフトウェアエンジニアの考え方の違いに関する体験談。

Published in: Engineering
  • Be the first to comment

ハードウェア脳とソフトウェア脳

  1. 1. ハードウェア脳とソフトウェア脳 ~考え方の違い~ にいやま
  2. 2. 自己紹介 • デジタル回路設計:5年 • 組み込みLinux:5年 • その他組み込みソフトウェア開発:3年 • Windowsアプリ開発:3年 • 全部ざっくりです • https://www.slideshare.net/dorniiyama 2017/08/12 FuraIT #33発表資料
  3. 3. 今日のお話 • ハードウェアエンジニアの思考とソフトウェアエンジニアの思考の違いについて お話します。 • 今までの組み込み機器開発経験の中で、「立場が違うと見え方、考え方が変わ る」と思ったことを中心にお話しします。 2017/08/12 FuraIT #33発表資料
  4. 4. 時間軸の表現方法 縦なのか横なのか 2017/08/12 FuraIT #33発表資料
  5. 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発表資料
  6. 6. ソフトウェアエンジニアの場合 • 縦軸で表現します • シーケンス図、アクティビティ図、フローチャート • 時間が下に伸びていくのでソースコードと同じように見られて便利 • 前後関係とイベントの発生タイミング(イベント通知や割り込み)が重要 • 厳密な時間の相関は表現不要 • ⾧い時間の感覚 • ミリ秒~秒 時間 2017/08/12 FuraIT #33発表資料
  7. 7. どのように協調設計するのか? • どのように協調設計するか • ハードウェアの処理時間など、厳密な時間を中心に考えるならタイミングチャート • システム全体の動作を表現したいならシーケンス図 • 適材適所の表現。どちらか一方に合わせるのではない。 現実的には... ソフトウェアエンジニアがハードウェアの仕様書を読めても、 ハードウェアエンジニアがソフトウェアの仕様書を読むことは 少ないかな 2017/08/12 FuraIT #33発表資料
  8. 8. 私のハードウェアエンジニア時代の失敗例 • 棒グラフのようなチャート • タイミングチャート風制御シーケンス図(?)。 • 無理のあるタイミング要求 • 「Xxクロック以内にyyの制御をしてください」みたいな。 • ソフトウェアにハードウェアの基準を要求してはいけない。 HW領域へ転送 HWによる処理 ソフトウェア処理A SW領域へ転送 ソフトウェア処理A HW領域へ転送 ソフトウェア ハードウェア 時間 それはハードウェアの 仕事です 2017/08/12 FuraIT #33発表資料
  9. 9. データサイズに関する考え方 Bit?Byte? 2017/08/12 FuraIT #33発表資料
  10. 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. 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発表資料
  12. 12. 失敗例 • ステータスビットをゼロクリアする仕様になってた • HWのうっかり仕様ミス ステータス1の要因が生じたのでBit1を1に Status 1がいつまでたっても 変わらないな…。 Address Bit 7 6 5 4 3 2 1 0 Status 1 Status 0 0x0000 0 0 0 0 0 0 0 1 0x0000 0 0 0 0 0 0 1 1 0x0000 0 0 0 0 0 0 0 0 ステータス0の要因が生じたのでBit0を1に 00000000を書く HW SW Status 0が1だから、 00000000を書いてクリアしよう 2017/08/12 FuraIT #33発表資料
  13. 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. 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発表資料
  15. 15. 私(と他人の)失敗例 • 自分が作ったHW • ちゃんと考えずにレジスタにたくさんの機能を詰め込んでしまった。 • 一緒に開発したHW • それじゃ制御しにくいよー • 「HW内部の実装を意識してデータを書いてね」って、なんじゃそれ? • HWにやってもらえば良かった • 最初に役割分担を決めちゃったので、設計した後で気づいた時には遅かった。 • 他の人も失敗するのね。 • 他社製のHW • どう見ても仕様検討漏れ。 • どう見てもバグ。 「仕様」ってことに なってるけど…。 2017/08/12 FuraIT #33発表資料
  16. 16. プログラミング言語の違い 一見、似ているように見えるでしょ? 2017/08/12 FuraIT #33発表資料
  17. 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発表資料
  18. 18. ソフトウェアエンジニア • 逐次処理 • みなさんご存知だと思うので省略 2017/08/12 FuraIT #33発表資料
  19. 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発表資料
  20. 20. デモ • Quartus Primeを使った簡単なデモ。 2017/08/12 FuraIT #33発表資料
  21. 21. プログラマブルロジックの原理 • 頭の体操 • どうやってハードウェアを変更するのか? LUT DFF ? FPGA 論路回路 スイッチ 2017/08/12 FuraIT #33発表資料
  22. 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発表資料
  23. 23. プログラマブルロジックの原理 • スイッチ ? 信号がHigh(1)でON Low(0)でOFF 1 0 0 0 0 0 0 0 0 0 0 1 100000 000100 メモリでスイッチの ON/OFFを記憶 2017/08/12 FuraIT #33発表資料
  24. 24. 設計時の見積もり 見積もりは「見積もり」でしか無い 2017/08/12 FuraIT #33発表資料
  25. 25. ハードウェアエンジニア • 性能見積もり • ハードウェアスペックを基にした理論値 • ハードウェアの制御を考慮した理論値 • ソフトウェアの動作も考慮した期待値はソフトウェアエンジニアにお任せ • ROM/RAMサイズ • 部品代を安くしたい • 拡張性を考慮すると回路設計がちょっとだけ面倒だから考慮したくない USB2.0 480Mbps, DDR4-1600 12.8GB/s, etc. 理論値のみで、 実際の性能までは 見積もれない 2017/08/12 FuraIT #33発表資料
  26. 26. ソフトウェアエンジニア • 性能見積もり • 同等のシステム(ハードウェア、ソフトウェアともに)があればベンチマーク • なければ何らかのデータを元に推測 • ROM/RAMサイズ • 性能見積もりと同じ 不確定要素が多い 2017/08/12 FuraIT #33発表資料
  27. 27. 失敗例 • 見積もりを大幅に超えてしまう • 思ったよりソフトウェアの処理が多くて性能が出ない。 • DRAM、Flashの容量が足りない。 • 何度か経験しました...。 • 原因 • 他のハードウェアがバスの帯域を使っていた。 • 自分の機能しかみてない。(理論値にとらわれて実動作を考えていない) • 思っていたよりプログラムサイズが大きかった。 • 度重なる仕様追加・変更。 • ものすごい手戻りコスト(設計、製造) • 製品仕様に影響。 • 部品発注、回路修正、上司への説明。 • これは解決策は思いつかないです • 念入りなベンチマーク、リスクの推定、経験などなど。 急がば回れ 慌てて進めても良いこと無い 2017/08/12 FuraIT #33発表資料
  28. 28. たまには成功例も • 事前に一緒に確認 • ハードウェアエンジニアもソフトウェアを作ってベンチマークしていた。 • でも、実際のソフトウェアを疑似的に作るところまではできなかった。 • 実環境に近いソフトウェアを作成し、一緒に仕様を事前検証した。 • ベンチマーク結果をもとに変更要求 • ハードウェアエンジニアは理論値を基に部品選定していた。 • 同等のシステムでベンチマークしていたので設計変更をお願い。 • CPUの処理不可が高いことが分かっていた。 • 理由が明確なため、すぐにハードウェアの仕様変更をしてもらえた。 2017/08/12 FuraIT #33発表資料
  29. 29. ソフトウェアが得意なこと、 ハードウェアが得意なこと 何事も適材適所 2017/08/12 FuraIT #33発表資料
  30. 30. ハードウェアの特徴 • 同じことの繰り返しは得意 • 条件分岐が少なく同じようなことを繰り返すことには最適 • 向かないことをさせると、速度が遅くなったり回路規模が大きくなったりする • CPUに比べると遅い • せいぜい数十MHz~百数十MHz程度。 • その代わりパイプラインでクロック単位で結果取得できる。 • 「ハードウェアの処理に必要な時間 < ソフトウェア処理時間」の場合のみ有効 HWへ転送 HWの処理 HWから転送 SW処理 ? HWの処理に必要な時間 2017/08/12 FuraIT #33発表資料
  31. 31. ソフトウェアの特徴 • いろんなことを処理するのは得意 • 略 2017/08/12 FuraIT #33発表資料
  32. 32. よくある誤解 • ソフトウェアで処理するよりハードウェアで処理した方が速い • 速度だけならソフトウェアでデータコピーした方が速いこともある • ハードウェアがメモリアクセスしていればCPUもメモリアクセスできない • 速度やCPU処理負荷も考えて選択する • 割り込みが大量に発生してソフトウェアが処理できないとか • ソフトウェアはなんでもできるけど... • ソフトウェアで実現することが正しいかは別問題 • ビットスタッフィングのソフトウェア実装をしていたことが... ビットスタッフィング概略 ・データの開始と終わりは”01111110” ・5個の1が続くデータ”11111”は、6bitの”111110”にする 01111110 01111111 01011111 01111101 01111110 01111110 10101111 01111110 10xxxxxx ビットスタッフィング前 ビットスタッフィング後 データ⾧可変& 全ビットチェック こんなのHWの仕事 2017/08/12 FuraIT #33発表資料
  33. 33. よくある誤解:続き • ハードウェアの機能が多い方がいい • ソフトウェア構造を無視して作られても使えない。 デバイスドライバ プロトコルレイヤ1 プロトコルレイヤ2 アプリケーション ハードウェア ハードウェアにプロトコルレイヤの機能を 入れてしまうと、ソフトウェアの階層が くずれるので使えない。デバイスドライバ プロトコルレイヤ1 プロトコルレイヤ2 アプリケーション ハードウェア 2017/08/12 FuraIT #33発表資料
  34. 34. 最後に 本日のお話を通じて伝えたいこと 2017/08/12 FuraIT #33発表資料
  35. 35. 言いたいこと • どうしたら最適な設計ができるかを考えましょう • 「自分が知っている」、「自分の設計に都合がいい」ではない。 • 使う人の立場で考えてみましょう。 • 他人の知恵、知識を吸収しましょう • ソフトウェアであればOSSのコード • ハードウェアであれば他社のデータシート • 通信ハードウェアであれば16550の各機能とその意味くらいは理解しておきましょう • 自分の専門分野を極めると同時に、他人の分野にも興味を持ってみましょう • 「どうして?」と思うようなことにも理由はある。 • 自分が興味を持てない仕事をにも、新たな発見があるかもしれません。 • たくさんのことに触れることで、より良いものを作れるようになると思います。 2017/08/12 FuraIT #33発表資料
  36. 36. おしまい 2017/08/12 FuraIT #33発表資料

×