2014年12月29日 星期一

J1 Forth CPU 研究之五:算術邏輯單元(ALU)

這是一系列文章中的第五篇,這系列的文章是要解讀 J1 CPU 的設計以及在其上的 Forth 語言的使用法。

這篇談的是 j1 CPU 的 Verilog 程式中的算術邏輯單元(ALU),請見以下檔案:

src/hardware/verilog/j1.v


為了方便說明,以下程式的次序不一定和 j1.v 中一致。

  wire [15:0] insn;
  wire [15:0] immediate = { 1'b0, insn[14:0] };
  wire is_alu = (insn[15:13] == 3'b011);
  wire is_lit = (insn[15]);


  reg [3:0] st0sel;
  always @*
  begin
    case (insn[14:13])
      2'b00: st0sel = 0;          // ubranch
      2'b01: st0sel = 1;          // 0branch
      2'b10: st0sel = 0;          // call
      2'b11: st0sel = insn[11:8]; // ALU
      default: st0sel = 4'bxxxx;
    endcase
  end



  always @*
  begin
    if (insn[15])
      _st0 = immediate;
    else
      case (st0sel)
        4'b0000: _st0 = st0;
        4'b0001: _st0 = st1;
        4'b0010: _st0 = st0 + st1;
        4'b0011: _st0 = st0 & st1;
        4'b0100: _st0 = st0 | st1;
        4'b0101: _st0 = st0 ^ st1;
        4'b0110: _st0 = ~st0;
        4'b0111: _st0 = {16{(st1 == st0)}};
        4'b1000: _st0 = {16{($signed(st1) < $signed(st0))}};
        4'b1001: _st0 = st1 >> st0[3:0];
        4'b1010: _st0 = st0 - 1;
        4'b1011: _st0 = rst0;
        4'b1100: _st0 = |st0[15:14] ? io_din : ramrd;
        4'b1101: _st0 = st1 << st0[3:0];
        4'b1110: _st0 = {rsp, 3'b000, dsp};
        4'b1111: _st0 = {16{(st1 < st0)}};
        default: _st0 = 16'hxxxx;
      endcase
  end

以上總共 40 行,加上之前的 90 行,我們已經看懂了 j1.v 的 130/200。接下來的兩篇處理RAM 及 memory mapped I/O,我們對 j1.v 的探索就算完成。

2014年4月1日 星期二

Mapabone 硬體設計之一

目前正在設計一款針對創客社群,類似 Raspberry Pi 和 Beaglebone,但是更強調 realtime 性能以及運動控制的軟硬體平台。這個軟硬體平台暫時命名為 Mapabone。目前的硬體設計原則如下:

  1. 參考 Beaglebone 的設計,但針對其複雜不便之處加以簡化。
  2. 擁抱 Raspberry Pi 的 pin definition 以擁抱 Raspberry Pi 社群。
  3. 擴充更多的 I/O 腳位以方便設計週邊。
  4. 內建 FPGA 以實現 MPU 無法達到的性能。
此外還進行其他的修正,以附合我心中好用的運動控制硬體平台的形象。

I'm designing for makers a software/hardware platform, which likes Raspberry Pi or Beaglebone, but emphasize realtime performance and motion control. I named this software/hardware platform Mapabone temporarily. My design guidelines are:

  1. Adapt the design of Beaglebone, but simplify its complexity.
  2. Embrace the P1 pin definition of Raspberry Pi, to embrace the Raspberry Pi community.
  3. Add more connectors to facilitate the development of peripherials.
  4. Embed an FPGA to provide performance which can not be achieved with MPU.
Many other improvements are underway in order to realize the ideal motion control platform in my mind.

進行這設計已有一段時間。已完成腳位的分析,開始進行線路的修改。但因為我從未使用過 OrCAD,在此一系列「Mapabone 硬體設計筆記」中記錄我在修改線路時的各種經驗,以及對這硬體平台的想法。

第零課:New project 和 New design

首先學習建立一個新的 Project 和 Schematics。選擇 File->New->Project...
輸入 project 名稱及位置,並選擇要進行的設計是 Schematic。
這樣就可以開始了!

第一課:Place Part

就是把零件放在設計圖面上,再用線連起來。我學會了置放以下的零件:電阻(R)、電容(C)、電感(L)、電源(V)。作法很簡單,選擇 Place->Part,再選擇零件。比較難的是要知道如何找到這些零件。最快的方法是輸入零件的第一個字母再在清單中尋找。以下是我們用的元件。

  • R/ANALOG
  • C/ANALOG
  • L/ANALOG
  • VPULSE/SOURCE

再來是接線和地線,分別選擇 Place->Wire 和 Place->Ground。

以下是我的完成圖:



2013年10月12日 星期六

學習筆記:Debian on Beaglebone

首先參考 Compile Linux Kernel 3.2 for Arm and Emulate with QEMU
這篇文章中不討論 u-boot, 因此編譯的核心是 zImage 而非 uImage。只利用 initramfs 執行一個很小的 init 程式。

安裝 Emdebian Toolchain

再來參考 How to Cross Compile Arm Kernel under Ubuntu-10-10
這篇講如何編譯 Ubuntu,但是同樣的作法用在 Debian 不成功。末尾說明了如何編從 kernel.org 拿到的核心,到是可以用的。只是沒說明編了 uImage 後要如何和 u-boot 結合。

之後參考 Installing Debian On TI BeagleBone
這篇使用 linaro-image-tools 和 live-build,以及 qemubuilder 。
依照文中的方法建造 Debian binary rootfs 不成功。
之後再試建造 u-boot,但之前使用 qemubuilder 失敗過,得到以下訊息,
   FATAL: kernel too old
據說是因 c 函式庫的新舊問題造成,我沒時間思考如何解決,因此先放棄。
建造 kernel 也使用 qemubuilder,因此放棄。
再來是 hwpack。這部份不熟,先擱置。

再參考 BeagleBone Debian Wheezy snapshot armhf based RootFileSystem
先取得 cross-compilers:
   $ wget -c https://launchpad.net/linaro-toolchain-binaries/trunk/2013.07/+download/gcc-linaro-arm-linux-gnueabihf-4.8-2013.07-1_linux.tar.xz
   $ tar xJf gcc-linaro-arm-linux-gnueabihf-4.8-2013.07-1_linux.tar.xz
   $ export CC=`pwd`/gcc-linaro-arm-linux-gnueabihf-4.8-2013.07-1_linux/bin/arm-linux-gnueabihf-
確定是 32bit 版本:
   $ {CC}gcc --version
取得最新版的 u-boot:
   $ git clone git://git.denx.de/u-boot.git
   $ cd u-boot/
   $ git checkout v2013.07 -b tmp
patch 後進行編譯:
   $ wget -c https://raw.github.com/eewiki/u-boot-patches/master/v2013.07/0001-am335x_evm-uEnv.txt-bootz-n-fixes.patch
   $ patch -p1 < 0001-am335x_evm-uEnv.txt-bootz-n-fixes.patch
   $ make ARCH=arm CROSS_COMPILE=${CC} distclean
   $ make ARCH=arm CROSS_COMPILE=${CC} am335x_evm_config
   $ make ARCH=arm CROSS_COMPILE=${CC}
接下來編譯 kernel,在此不使用作者提供的 git.sh, 因曾無法 git clone 或 fetch from kernel.org 而出問題。而且未來將針對特定的 branch 進行 patch。作法如下:

。不使用文中所用的 git.sh,因此先 clone 之後,修改 system.sh 中的 LINUX_GIT,並且將 scripts/git.sh 中所有從 kernel.org 取得 repository 的程式片段都放在註解中。之後就可以成功編譯。
可惜的是我在成功產生一個  3.2 的 MicroSD 後,以此 MicroSD boot linux,在 boot kernel  階段失敗。當掉的原因是因為我實際上產生的是 3.12 的 kernel 而非 3.2 的 kernel。
在 linux-dev 中執行
   git checkout origin/am33x-v3.2 -b tmp
並在 linux-src 中執行
    git checkout v3.2
後,成功。

再參考 Flashing Ubuntu 13-04 or debian wheezy to the beaglebone black emmc

2013年9月4日 星期三

YUI 的 Promise

YUI 的 Promise 用法如下:

var promise = new Y.Promise(function (resolve, reject) {
   // 非同步的呼叫, 當非同步的呼叫完成後,
   // 依結果執行 resolve 或是 reject。
}

在內部的實作中,我們可見 Y.Promise 定義了一個 Y.Promise.Resolver,再使用這個 resolver
來執行以上傳給 Y.Promise 的 function。

fn.call (this, function(value) {
      resolver.fulfill(value);
   }, function (value) {
      resolver.reject(value);
   }
}):

因此可知 resolve(value) 就是執行 resolver.fulfill(value), reject(value) 就是執行 resolver.reject(value)。

所以可把對 Y.Promise 的說明改成如下:

var promise = new Y.Promise(function (resolve, reject) {
   // 非同步的呼叫, 當非同步的呼叫完成後,
   // 依結果執行 resolver.fulfill 或是 resolver.reject。
}

由於看 YUI promise 以上程式時有點吃力,因此將理解記錄於此。

2013年2月2日 星期六

Firefox 18 vs. Chrome 24

我們的產品以網頁為人機界面。這些日子我最關心的事情之一就是 Firefox 在 javascript performance 上的性能提升。雖然 Chrome 的性能已經滿足產品的需求,我仍希望 Chrome 不是唯一的選擇。畢竟,Firefox 在客製化的能力上略勝一籌。

Firefox 18 採用 IonMonkey 為引擎,首次使得我們的產品能在 Firefox 上使用。雖然切換畫面時,仍有延遲,已是很大的進步。

Google 在去年八月提出新的 javascript 速度評估的基準 octane。經瞭解,他的基準包括了以下幾項新的測試:
  • Box2DWeb
  • Mandreel
  • Pdf.js
  • GB emulator
  • CodeLoad
其中的 Box2DWeb 測試 2D 繪圖能力。Mandreel 測試 3D 繪圖能力。這兩項對我未來的產品都很重要。

Octane 的連結位於:
http://octane-benchmark.googlecode.com/svn/latest/index.html
只要點選以上連結,就可以進行測試。

以下是使用我的筆電針對 octane v1 測試的結果:
測試測試內容Chrome 24Firefox 18
RichardsCore language features104748991
DeltablueCore language features1381211333
CryptoBit and math operations114859111
RaytraceCore language features146826701
EarlyBoyerMemory and GC2367912388
RegexpStrings and Arrays3061922
SplayMemory and GC435510431
NavierStokesStrings and Arrays1501715418
pdf.jsStrings and Arrays102373913
MandreelVirtual machine101546803
GB emulatorVirtual machine111116212
CodeLoadLoading and Parsing104448634
Box2DWebBit and math operations116677325

可以看出 Firefox 18 和 Chrome 24 仍有很大差距。

不過,Mozilla 的團隊每日比較 Firefox 和 Chrome 的性能(http://arewefastyet.com/), 從 2012 年十二月到 2013 年二月初,可以見到 Firefox 一路迫進 Chrome 的性能。該說唉呀已經達到  Chrome 的 90% 的速度了。想來,我的產品上切換畫面的延遲可能已得到解決,只是還得等到 Firefox 19,20。但是,是不是有可能更好,進而和 Chrome 平手?

似乎是可能的。Firefox 的 Generational GC 尚未完成。它的完成將帶來 Firefox 性能的再次提升。

2013年1月11日 星期五

WebM 初探

最近研究 WebM,尤其是其 encoder 的部份。以下說明我研究的結果:

Firefox 和 Google Chrome 都使用 WebM project 的 libvpx 函式庫來處理 WebM。WebM 包括了 video 和 audio 兩個部份,video 部份使用 VP8 video codec,audio 部份使用 Vorbis audio codec。這兩個部份被放在 container 內。Container 的設計參考了 Matroska container。

libvpx 內的 simple encoder 範例讀取了 YV12 檔案,編碼成 IVF 檔案。

YV12 是 YUV 的一種。YUV 是編譯 true color 顏色空間的種類。YUV 發明於黑白電視和彩色電視的過渡期,為了訊號能和黑白電視相容,不採用 RGB 的編碼,而採用 YUV,Y 代表明亮度,也就是給黑白電視的訊號。UV 則是色度、濃度。

IVF (Indeo Video Format) 是 Intel 開發的格式,在 1990 年代很流行,後被 MPEG 標準打敗。IVF  在 WebM 計劃中被用來傳送 raw VP8 data。

2011年11月30日 星期三

C 語言上的 Forth

三十年以上功力,我也算是 Forth 的老手了。開發了一套自己的 Forth,雖然不用 C,但它的確是建立高階語言上的。

很多人反對 C 語言上的 Forth。我想依據我的經驗,說明一下 C 語言上的 Forth 的好處,讓大家思考一下:

  1. 當您的大型專案是以 C 語言寫成,當這專案編譯成執行檔後您要如何測試這個專案的各個小零件?

反對 C 語言上的 Forth 的人會選擇 ruby, python, javascript, lua, scheme 或其他能和 C 語言連結的 scripting languages 來和這專案連結,以 scripting language 和執行檔內的副程式互動,進行測試。

贊成 C 語言上的 Forth 的人會自建 Forth,或是用別人建好的 C 語言上的 Forth,作為這專案的互動式測試工具。

 2. 如果您有兩個執行檔,他們必須溝通並且呼叫對方的某些函式。一個執行檔以 Java 寫成,另一個是以 C 寫成。請問您要如何處理這樣的問題?

反對 C 語言上的 Forth 的人可能會在 C 語言的專案中內建 lua,因為聽說 lua 是最適合內建在 C 程式中的 scripting language 了。但是 Lua 不能內建在 Java 中,所以只好在 Java 的專案內選擇 JRuby。

贊成 C 語言上的 Forth 的人會在 Java 上建一套 Forth,畢竟那是很容易的事。更偷懶的會使用別人在 Java 上建好的 Forth,配合他在 C 語言那端的 Forth。然後,用同一種語言來解決問題。

有句話,一招半式闖江湖,會上 Forth 的一招半式,可以闖闖 C 語言的江湖、Java 語言的江湖,還有 MCU 江湖。

我希望用我的經驗讓反對 C 語言上的 Forth 的 Forth 愛好者,能瞭解為什麼會有 C 語言上的 Forth。C 語言上的 Forth 不會因為別人反對而消失,因為它們以簡單的方法解決了現實中程式開發的問題,只有真正面對過這些問題的人才瞭解到它的價值。