2013年3月11日 星期一

fpga 0311 - 針對 test fixture 的再進化


針對 test fixture 的再進化

我們剛剛寫好的 test fixture 有什麼缺點 ?

缺點1. 我們所測試出來的波形,系統無法自行判斷是正確或是錯誤的波形,得要由人類的眼睛來判斷。

缺點2. 輸入波形無法自動產生


針對缺點1之解決方式

我們使用行為模式(behavior model)來撰寫 testfixture,其目的是讓 testfixture 能自動產生 x+y 的半加器輸出,程式碼如下:

reg sumY, coutY;        // test result


// self calculate coutY, sumY
always @ ( a or b)
  begin
    {coutY, sumY} = a+b;
  end


並以此輸出來與原始 ha_gate/ha_rtl/ha_cont.v 中電路所產生之輸出作比對。

reg testok;             // 0 == error, 1 == testok;

// compare
always @ ( coutX or sumX )
begin
  if ( coutX == coutY && sumX == sumY)
    testok=1;
  else
    testok=0;
end

我們可以觀察 testok 的波形,當 testok == 1 時,我們的電路輸出與自動產生之電路輸出是一致的,萬一 testok == 0 時,兩者不一致,運算有錯,必須進行除錯。

針對缺點2之解決方式
a. 定義一個 clock 訊號源
b. 利用 clock 訊號源來產生訊號

fpga 0311 講義


$display 語法 (課本 p2-10 - p2-12)

$display("Hello world")

可以在螢幕上顯示 Hello world 字串,在半加器的測試檔中作以下修改:

initial begin
$display("Half Adder test begin!!");    // 加入此行
$dumpvars;
$dumpfile("testha.dmp");

#0 a=0;
   b=0;
   $display($time, "=>a=%b,b=%b,sumX=%b,coutX=%b",a,b,sumX,coutX); // 加入此行

然後執行模擬,我們可以得到以下螢幕輸出:

Half Adder test begin!!
                   0=>a=0,b=0,sumX=x,coutX=x

從以上輸出我們可以得到當 a=0, b=0 的時候,sumX 跟 coutX 的值為 x (未知)。為什麼會有這個輸出結果 ?



原因:所有的電路都有延遲,當訊號在第 0 秒輸入時,不可能輸出就跟著改變。因此,
我們可以再修改程式碼如下:

#0      a=0;
        b=0;
        $display($time, "=>a=%b,b=%b,sumX=%b,coutX=%b",a,b,sumX,coutX);

#1
        $display($time, "=>a=%b,b=%b,sumX=%b,coutX=%b",a,b,sumX,coutX);

其輸出為:
Half Adder test begin!!
                   0=>a=0,b=0,sumX=x,coutX=x
                   1=>a=0,b=0,sumX=0,coutX=0

我們可以觀察上面的第二行,發現在第 1 個時間單位時,sumX=0, coutX=0。這表示經過一個時間單位的延遲之後,電路已完成運算並在輸出端看到結果。

現在有個問題,萬一我們每個訊號的改變都希望能從螢幕上看到數值,該如何作 ?

1. 每一個訊號改變都加上 $display ==> 累死人,我們最好不要作這種蠢事

2. 使用 $monitor ==> 比較聰明的作法

因此我們可以將測試檔改成:

initial begin
$display("Half Adder test begin!!");                            // 加入此行
$monitor($time, "=>a=%b,b=%b,sumX=%b,coutX=%b",a,b,sumX,coutX); // 加入此行
$dumpvars;
$dumpfile("testha.dmp");

#0      a=0;
        b=0;

其輸出為:

Half Adder test begin!!
                   0=>a=0,b=0,sumX=0,coutX=0
                  10=>a=0,b=1,sumX=1,coutX=0
                  20=>a=1,b=0,sumX=1,coutX=0
                  30=>a=1,b=1,sumX=0,coutX=1


我們可以看到只要加一行 $monitor 之後,系統即會根據輸出/入的變化而自動列印其數值,不必每一行都加 $display。

RTL level 的程式寫法

連接運算子 (p 5-19)

請將 half adder 以 rtl 方式撰寫出來


//RTL Level code                    | // Gate Level code
//ha_rtl.v                                 | // ha_gate.v
module half_adder(x, y, Sum, Cout); | module half_adder(x, y, Sum, Cout);
                                               |
input x, y;                                | input x, y;
output Sum, Cout;                   | output Sum, Cout;
reg Sum, Cout;                       |
                                              | // Circuit Description
// Circuit Description              |
                                             | xor xor0(Sum, x, y);
always @ (x or y)                  | and and0(Cout, x, y);
{Cout,Sum} = x+y;               |
                                            | endmodule
endmodule                           |

上面左邊的程式碼是告訴我們以 RTL 方式撰寫出來的 code,現在我們希望能將寫完的程式進行模擬,請執行:

cver ha_rtl.v test_ha.v

此時我們可以看到

1. $monitor 輸出與之前 ha_gate.v 相同
2. testha.dmp 亦相同


使用 continuous assignment 來撰寫 half adder:

module half_adder(x, y, Sum, Cout);

input x, y;
output Sum, Cout;

// Circuit Description

assign {Cout, Sum} = x + y;

endmodule

上面的例子是使用 assign 語法 (又稱為 continuous assignment,課本 p5-2) 來進行 half adder 的設計。

小結:在這三個半加器的例子中,我們使用了同一個 test fixture 來針對我們所寫的三個不同語法之半加器進行測試,而且測試後之結果均一模一樣。







2013年3月10日 星期日

Blender 0308 上課講義

第二種畫桌子的方法

1. 加入 Cube,將 Cube 左下角移至原點,並按 z 切換至骨架模式 (Wire frame)

a. 按 RMB 點選 Cube 以選擇 Cube,按 g 再押著 Ctrl 不放將左下角移至 0,0
   然後按 LMB。
b. 按 TAB 進入物件編輯模式,然後按 b 拉一個框框圈選最上面的端點。
c. 移動端點:按 g、按 y、按 3。
d. 取消端點選擇,然後選擇右側的面
e. 移動端點:按 g、按 x、按 8。到目前為止,我們會有一個方塊其大小為 5 x 10 x 2(高)
f. 移至視窗 3 (yz 平面),取消端點選擇,然後選擇最底下的面
g. 移動端點:按 g、按 z、按 1.7,此時我們即可得到一個 5 x 10 x 0.3 之方塊


練習 2

1. 回到初始狀態,刪除內建方塊
2. 切至視角 7,新增一個 Circle,其端點數為 32 (預設值),半徑 (Radius) 設為 1, fill type 設為 Triangle Fan,此時我們可以得到一片圓形。
3. 按 b 拉一個框框圈選左半圓的點,再按 x 然後將其刪除,刪完之後我們有半個圓。
4. 新增一個 plan,將此 plan 高度調為 1,並與半圓重疊
5. 刪半圓之某些端點,將圓切 plan 處加上一個新的端點,使用 k (knife) 工具。
6. 將切完之端點填面,可以選三個端點(按 Shift + RMB 點選) 再填面 (f)或是四個端點填面 (f)
7. 將 3D 遊標歸零 -> Shift +s -> Cursor to Grid / Cursor to Center
8. 全選所有端點,按 Ctrl + D 複製,將旋轉點  pivot 改為 3D 遊標,按 r 旋轉 180 度,即可完成一個重疊的圓。
9. 全選所有端點,按 Remove Double 按鍵,即可將重疊的端點「融合」
10. 移至視角 3,全選所有端點,按 e(extrude 延伸)、按 z、按 0.3

2013年3月3日 星期日

fpga 0304 上課講義


1. 如何證明我們所寫的半加器工作正確 ?

在 simulation command 的部份,我們需要針對半加器的動作來進行完整測試,請問什麼是半加器的完整測試 ? 要判別一個半加器是否完整動作,最簡單的方法是把真值表上的每一列都模擬一次,如果輸出/入之狀態完全符合真值表,則我們可以確認此電路工作正常。

x  y | Sum   Cout
-----+-----------
0  0 |   0      0
0  1 |   1      0
1  0 |   1      0
1  1 |   0      1

將全部可能的輸入訊號都跑一次模擬並檢查模擬結果是否正確,若全部正確的話,我們可以假設電路設計是對的。

2. 如何撰寫 test fixture (測試程式)

2.1 什麼是 test fixture ?

當我們寫完 verilog 電路後,我們必須證明它是對的,因此我們要寫 test fixture 來針對我們所寫的 verilog 程式進行測試。

2.2 test fixture 的內容

一個 test fixture 就是一個 verilog module,以半加器 test fixture 為例,其語法大致如下:

module test_ha;
reg   definition  -> 暫存器定義
wire  definition  -> 線定義
other definition  -> 其它定義

half_adder ha0 () -> 呼叫我們要進行測試的電路

initial begin                   -> 開始進行波形輸入
$dumpvars;                      -> 產生 gtkwave 語法
$dumpfile("testha.dmp");        -> 將波形以 VCD 格式存在 testha.dmp 檔中,
                                   testha.dmp 可照自己的需求改名字

simulation command   模擬指令,以下特別說明!!

$dumpall;                       -> 紀錄所有訊號
$dumpflush;                     -> 必要
#10 $finish;                    -> 在 10 個時間單位後結束模擬
end                             -> 結束 initial begin
endmodule

因此一個完整的半加器 test fixture 如下,我們將其存為 test_ha.v

module test_ha;
reg a, b;
wire sumX, coutX;

half_adder ha0(a, b, sumX, coutX);

initial begin
$dumpvars;
$dumpfile("testha.dmp");

#0      a=0;
        b=0;

#10     a=0;
        b=1;

#10     a=1;
        b=0;

#10     a=1;
        b=1;


$dumpall;
$dumpflush;
#10 $finish;
end
endmodule


2.3 進行 verilog 測試模擬

請執行

cver ha_gate.v test_ha.v \Enter

理論上應該輸出如下:

GPLCVER_2.12a of 05/16/07 (Linux-elf).
Copyright (c) 1991-2007 Pragmatic C Software Corp.
  All Rights reserved.  Licensed under the GNU General Public License (GPL).
  See the 'COPYING' file for details.  NO WARRANTY provided.
Today is Mon Mar  7 11:25:30 2011.
Compiling source file "ha_gate.v"
Compiling source file "test_ha.v"
Highest level modules:
test_ha

Halted at location **test_ha.v(25) time 40 from call to $finish.

我們會發現沒有 error、沒有 warning,而且會有個檔案叫 testha.dmp,接下來就可以用 GTKwave 觀察波形了。




3. 使用 GTKwave

請執行

gtkwave testha.dmp

來載入模擬波形檔,並觀察我們所寫的變數 (reg, wire .. 之類) 的輸出,若想將目前觀察狀態留待下次載入,請選擇

File -> Write Save File

存檔為 testha.sav,下次載入 gtkwave 時請執行:

gtkwave testha.dmp testha.sav

即可載入前一次觀察狀態。




作業 1. 畫 Full Adder 的電路圖
        以 Gate Level 寫 Verilog 程式
        撰寫 test fixture,並跑模擬,可存檔檔名為 testfa.dmp
        列印波形

2013年3月1日 星期五

blender 0301 上課講義


安裝執行 Blender

1. 請至 blender 網頁下載 Blender 檔案:

http://www.blender.org/download/get-blender/

下載

blender-2.63a-linux-glibc27-i686.tar.bz2

2. 將此檔案解壓縮至 /usr/local

/usr/local# tar jxfv 目錄/blender-2.63a-linux-glibc27-i686.tar.bz2

此時會解開一個 blender-2.63a-linux-glibc27-i686 目錄,其完整路徑為

/usr/local/blender-2.63a-linux-glibc27-i686

3. 在 /usr/local/bin 建一個 blender 之連結

/usr/local/bin# ln -s /usr/local/blender-2.63a-linux-glibc27-i686/blender .

4. 呼叫 Blender

在選單中啟動 Blender 或是直接輸入 blender,看是不是最新的 2.63a 版


Blender 基本操作:

視角切換(以鍵盤右側數字鍵盤來操作)

  • 7 -> yx 平面
  • 3 -> zy 平面
  • 1 -> xz 平面
  • 0 -> Camera 視角
  • 5 -> 切換透視投影 / 平行投影

基本操作
  • 旋轉視角 -> MMB 按著移動滑鼠可以旋轉視角
  • 拉近/拉遠與物件的距離 -> MMB 滾輪
  • 平移視角 -> 左手先按 Shift + 右手按 MMB 再移動
  • 選取物件 -> 以 RMB 點選不同的物件,這裡面的物件泛指 3D 物件、Camera、燈源皆是物件。
  • 刪除物件 -> 先選取物件,再按 x,此時會出現一個 Delete 視窗,請點 OK 即可刪除物件。
  • 還原上一步 -> Ctrl + z,可以還原上一步,例如將剛剛刪除的物件還原回來
  • z -> 切換著色模式/網格模式
  • 新增物件 -> 選單 Add -> Mesh 可以新增基本物件,其快捷鍵為 Shift + a
  • 旋轉物件 -> r 移動滑鼠
    • 若臨時不想執行旋轉操作,可以按 Esc 退出,
    • 若要固定角度旋轉,請按 r 之後,將左手按 Ctrl,右手移動滑鼠,如此一來可以以 5 度角為單位旋轉物件。
    • 若想針對某軸進行特定角度旋轉,請在左下角 rotation 小表格中直接填入該軸的旋轉角度。
  • 縮放物件 -> s 移動滑鼠
    •         a. 若臨時不想執行縮放操作,可以按 Esc 退出,
    •         b. 若要固定單位縮放,請按 s 之後,將左手按 Ctrl,右手移動滑鼠,如此一來
    •            可以以 0.1 為單位旋轉物件。
    •         c 若想針對某軸進行縮放,請按 s 之後,再按該軸 (x or y or z),右手移動
    •           滑鼠,如此一來可以沿該軸縮放。
  • 移動物件 -> g 移動滑鼠
    • 若臨時不想執行移動操作,可以按 Esc 退出,
    • 若要固定單位移動,請按 s 之後,將左手按 Ctrl,右手移動滑鼠,如此一來可以以 0.1 為單位移動物件。
    • 若想針對某軸進行移動,請按 s 之後,再按該軸 (x or y or z),右手移動滑鼠,如此一來可以沿該軸移動。
  • 取消/全選物件 -> a
  • 複製物件 -> Shift + d

2013年2月20日 星期三

自序

算一算,自民國 83 年起至現在,筆者玩 Linux 已經超過 17 年了,當初玩 Linux 曾經有裝過五十幾片磁碟片的,後來出了雲觀光碟可以一次搞定安裝 Slackware,再後來出了 Redhat Linux,一直到現在玩的 Debian 作業系統。我還記得當初為了要在 Linux 上看中文字得從倚天中文字形轉成 Linux 可用的格式,而 chdrv 更是當初不可或缺的工具。一開始玩 Linux 作業系統時,Linux 被眾多作業系統大廠笑稱之為「高級玩具作業系統」。的確,那時候的 Linux 比上 (Solaris、HP Unix、IBM AIX ..) 不足,比下 (Dos、 Minix ) 有餘。然而物換星移到了今天,當初許多的作業系統大廠已經消失了,而這個當年的「玩具作業系統」卻登堂入室,成為高科技產業不可或缺的一部份,從伺服器架設,Android 手機/平板、嵌入式系統乃至於機器人控制 .. 等在在可看見 Linux 的身影。

這本書是筆者累積這幾年教學經驗所整理的教學內容,其主要目的是以 Debian Linux 為基礎教導讀者一步步從文字介面安裝、設定乃至於完整的中文桌面環境,再至程式設計環境架設等。筆者希望本書可以讓一般學生在一個學期內完成本書的內容,以此書學習到的內容為基礎,讀者可以在進入 Linux 伺服器管理甚至是嵌入式 Linux/Android 系統開發等領域都會變得比較容易。

由於這本書主要是寫給 Linux 入門的初學者看的,因此筆者盡可能把安裝過程螢幕上的資訊一一截取下來,讓初學者能按圖索驥以利學習,希望藉此降低初學者安裝、學習過程中遇到問題卻無法解決的困境。

本書「不保證」你能順利安裝 Linux,亦「不保證」你的主機不會因此受到損壞(包括硬體損壞及軟體損壞或資料毀損)。從另一方面來說,由於筆者學識不足能力有限,書裡錯誤疏漏之處在所難免,望請各位多多海涵。

李博明 謹誌 於南台科技大學 電子系

推薦序