[DirectX12] Matrix の Row-major, Culumn-major

[DirectX12] Matrix の Row-major, Culumn-major

Row-major と Culumn-major は、行列のような多次元配列を、どのような順番でメモリーに格納しているかを表す概念である。例えば、下記のような 4×4 行列がある。

a11 a12 a13 a14
a21 a22 a23 a24
a31 a32 a33 a34
a41 a42 a43 a44

Row-major(行順)

メモリー上では a11 a12 a13 a14 a21 a22 … の順番で並んでいる。

C/C++ や Numpy では Row-major でメモリーに格納される。

DirectX などで、Row-major の変換行列(World, View, Projection)をベクトルに掛ける場合は下記のように右に置く。(逆行列も右側に置く)

mul(vector, matrix)

Column-major(列順)

メモリー上では a11 a21 a31 a41 a12 a22 … の順番で並んでいく。

Reference

https://pr0g.github.io/mathematics/matrix/2022/12/26/column-row-major.html

[Jenkins] Windows11 に Jenkins をインストールする

[Jenkins] Windows11 に Jenkins をインストールする

2023年1月現在。Jenkins を利用するためには Java 11 or 17 が必要。

Java 11

下記の jdk.java.net のページから Java11 をダウンロードする。「Windows/x64 Java Development Kit」と書かれたリンクを選択。
https://jdk.java.net/java-se-ri/11

ダウンロードした zip を解凍して、フォルダを C:\Program Files\Java\ 以下に配置する。

Jenkins

Jenkins のダウンロードサイトから、Windows の LTS 版をダウンロード。
https://www.jenkins.io/download/

msi 形式なのでセットアップを進めていくと、Java のホームディレクトリを指定する画面になる。上記でコピーした Java11 のディレクトリのパスを指定する。

C:\Program Files\Java\jdk-11.0.2

「Next」を進めていけば、インストールが完了する。
タスクマネージャーから「サービス」を確認すれば「Jenkins」が起動していはず。

セットアップ

インストールが完了すれば、サービスとして Jenkins が起動した状態になる。インストール時の Port を 8080 に設定していれば、下記でアクセスできるようになっているはず。

http://localhost:8080/

C:\ProgramData\Jenkins.jenkins\secrets\ 以下に initialAdminPassword というファイルがあるはずなので、そこに管理用の初期パスワードが書かれているのでログインする。

「Customize Jenkins」の設定では、とりあえず「Install suggested plugins」で初期プラグインを導入。

アンインストール

アンインストールする場合は、Windwos の「アプリと機能」から削除。

参考

https://www.jenkins.io/doc/book/installing/windows/
https://www.publickey1.jp/blog/22/jenkinsjava_8java_11java_17.html

[FPGA] ZedBoard で FPGA プログラミング大全をしたメモ

[FPGA] ZedBoard で FPGA プログラミング大全をしたメモ

ZedBoard で FPGA プログラミング大全を進めるための変更点。個人的なメモ用。間違っている可能性が大きいので注意。

Constrants (xdc)

set_property -dict { PACKAGE_PIN Y9   IOSTANDARD LVCMOS33 } [get_ports { CLK }];
create_clock -period 10.000 -name sys_clk_pin -waveform {0.000 5.000} -add [get_ports CLK]

set_property -dict { PACKAGE_PIN P16    IOSTANDARD LVCMOS18 } [get_ports { RST }];

set_property -dict { PACKAGE_PIN AA19   IOSTANDARD LVCMOS33 } [get_ports { VGA_HS }];
set_property -dict { PACKAGE_PIN Y19    IOSTANDARD LVCMOS33 } [get_ports { VGA_VS }];

set_property -dict { PACKAGE_PIN Y21    IOSTANDARD LVCMOS33 } [get_ports { VGA_B[0] }];
set_property -dict { PACKAGE_PIN Y20    IOSTANDARD LVCMOS33 } [get_ports { VGA_B[1] }];
set_property -dict { PACKAGE_PIN AB20   IOSTANDARD LVCMOS33 } [get_ports { VGA_B[2] }];
set_property -dict { PACKAGE_PIN AB19   IOSTANDARD LVCMOS33 } [get_ports { VGA_B[3] }];

set_property -dict { PACKAGE_PIN AB22   IOSTANDARD LVCMOS33 } [get_ports { VGA_G[0] }];
set_property -dict { PACKAGE_PIN AA22   IOSTANDARD LVCMOS33 } [get_ports { VGA_G[1] }];
set_property -dict { PACKAGE_PIN AB21   IOSTANDARD LVCMOS33 } [get_ports { VGA_G[2] }];
set_property -dict { PACKAGE_PIN AA21   IOSTANDARD LVCMOS33 } [get_ports { VGA_G[3] }];

set_property -dict { PACKAGE_PIN V20    IOSTANDARD LVCMOS33 } [get_ports { VGA_R[0] }];
set_property -dict { PACKAGE_PIN U20    IOSTANDARD LVCMOS33 } [get_ports { VGA_R[1] }];
set_property -dict { PACKAGE_PIN V19    IOSTANDARD LVCMOS33 } [get_ports { VGA_R[2] }];
set_property -dict { PACKAGE_PIN V18    IOSTANDARD LVCMOS33 } [get_ports { VGA_R[3] }];

MMCME2_BASE

   MMCME2_BASE #(
      .BANDWIDTH("OPTIMIZED"),  // Jitter programming (OPTIMIZED, HIGH, LOW)
      .CLKFBOUT_MULT_F(18.0),   // 乗数M(2.000-64.000)
      .CLKFBOUT_PHASE(0.0),     // 位相(-360.000-360.000)
      .CLKIN1_PERIOD(5.0),      // CLKINの周期
      // CLKOUT0_DIVIDE - CLKOUT6_DIVIDE: Divide amount for each CLKOUT (1-128)
      .CLKOUT1_DIVIDE(1),
      .CLKOUT2_DIVIDE(1),
      .CLKOUT3_DIVIDE(1),
      .CLKOUT4_DIVIDE(1),
      .CLKOUT5_DIVIDE(1),
      .CLKOUT6_DIVIDE(1),
      .CLKOUT0_DIVIDE_F(35.75),  // 除数Q(1.000-128.000)
      // CLKOUT0_DUTY_CYCLE - CLKOUT6_DUTY_CYCLE: Duty cycle for each CLKOUT (0.01-0.99).
      .CLKOUT0_DUTY_CYCLE(0.5), // デューティ比
      .CLKOUT1_DUTY_CYCLE(0.5),
      .CLKOUT2_DUTY_CYCLE(0.5),
      .CLKOUT3_DUTY_CYCLE(0.5),
      .CLKOUT4_DUTY_CYCLE(0.5),
      .CLKOUT5_DUTY_CYCLE(0.5),
      .CLKOUT6_DUTY_CYCLE(0.5),
      // CLKOUT0_PHASE - CLKOUT6_PHASE: Phase offset for each CLKOUT (-360.000-360.000).
      .CLKOUT0_PHASE(0.0),
      .CLKOUT1_PHASE(0.0),
      .CLKOUT2_PHASE(0.0),
      .CLKOUT3_PHASE(0.0),
      .CLKOUT4_PHASE(0.0),
      .CLKOUT5_PHASE(0.0),
      .CLKOUT6_PHASE(0.0),
      .CLKOUT4_CASCADE("FALSE"), // Cascade CLKOUT4 counter with CLKOUT6 (FALSE, TRUE)
      .DIVCLK_DIVIDE(2),         // 除数D(1-106)
      .REF_JITTER1(0.0),         // Reference input jitter in UI (0.000-0.999).
      .STARTUP_WAIT("FALSE")     // Delays DONE until MMCM is locked (FALSE, TRUE)
   )

ZedBoard は 100MHz なので、書籍にのっていた数値をもとに、上のように変更した。

[FPGA] ZedBoard から VGA 出力

[FPGA] ZedBoard から VGA 出力

FPGA マガジンや、FPGA プログラミング大全に乗っていた、VGA 出力を ZedBoard で試してみる。

分周回路

reg [1:0] cnt;

always @( posedge clk, posedge reset ) begin
    if ( reset )
        cnt <= 2'h0;
    else
        cnt <= cnt + 2'h1;
end

assign pck = cnt[1];

Zedboard のクロックは 100MHz なので、これを4分周して 25MHz のクロックを作っている。cnt レジスタは 2bit で +1 でカウントアップをし続けることで、00 -> 01 -> 10 > 11 を繰り返す。この時、最上位 bit の cnt[1] が 1 になる立ち上がりを取得することで 1/4 のクロックが得られる?

ボードからの出力

FPGA からの出力はデジタル情報なので「ラダー抵抗」と呼ばれる仕組みを使って D-A 変換を行い、目的の電圧 (0.7V?) に変換してから VGA 端子で出力している。当たり前だが VGA はアナログなので、アナログに変換しないといけない。

参考

  • FPGA マガジン No.7
  • FPGA プログラミング大全 Xilinx編

Video Graphics Array
https://ja.wikipedia.org/wiki/Video_Graphics_Array
VGA端子
https://ja.wikipedia.org/wiki/VGA%E7%AB%AF%E5%AD%90
VGA Signal Timing
http://www.tinyvga.com/vga-timing
11 VGA Port
https://digilent.com/reference/programmable-logic/zybo/reference-manual
ちょっとTea Time!? VGAを調べてみる
http://www.easyaudiokit.com/bekkan2020/TeaTime8/vga.html
VGAモジュールの作成
http://www.arch.cs.kumamoto-u.ac.jp/~kuga/cad/exp/sys/2009/vga.html
分周器・CPUトップモジュール
https://sagara-works.jp/research-and-development/code-prescaler/

[DirectX12] World, View, Projection マトリックス

[DirectX12] World, View, Projection マトリックス

World 行列

View 行列

XMVECTOR Eye = XMVectorSet( 0.0f, 0.0f, -5.0f, 0.0f );
XMVECTOR At = XMVectorSet( 0.0f, 0.0f, 0.0f, 0.0f );
XMVECTOR Up = XMVectorSet( 0.0f, 1.0f, 0.0f, 0.0f );
g_View = XMMatrixLookAtLH( Eye, At, Up );

カメラ位置(座標)と、カメラの見ている場所(注視点)、そしてカメラの上方向のベクトルをXMMatrixLookAtLH に指定することで View 行列が作られる。この行列によって、World 座標から定義した View 座標への変換が行える。

上記の Eye, At, Up から作られる View 行列はこちら。

{1.00, 0.00, 0.00, 0.00}
{0.00, 1.00, 0.00, 0.00}
{0.00, 0.00, 1.00, 0.00}
{0.00, 0.00, 5.00, 1.00} 

計算式は以下。

zaxis = normal(At - Eye)
xaxis = normal(cross(Up, zaxis))
yaxis = cross(zaxis, xaxis)

 xaxis.x           yaxis.x           zaxis.x          0
 xaxis.y           yaxis.y           zaxis.y          0
 xaxis.z           yaxis.z           zaxis.z          0
-dot(xaxis, eye)  -dot(yaxis, eye)  -dot(zaxis, eye)  1
https://learn.microsoft.com/ja-jp/windows/win32/direct3d9/d3dxmatrixlookatlh

計算式を見れば分かるが up ベクトルが必要なのは、カメラからの視線のベクトルと up 方向のベクトルの外積を取って、横方向(xaxis)のベクトルを計算するために使用している。つまり、カメラの3次元での軸を決定するために、上方向がどちらかという情報が必要になる。

Projection 行列

g_Projection = XMMatrixPerspectiveFovLH( XM_PIDIV4, width / (FLOAT)height, 0.01f, 100.0f );
  • XM_PIDIV4 は 0.785398163f(3.14/4)
  • 2つ目はビュースペースのアスペクト比。(640/480=1.333333)
  • 3つ目と、4つ目は NearPlane と FarPlane。(0.01~100.0)

これによって、下記の Projection 行列が得られる。

{1.81066, 0.00, 0.00, 0.00}
{0.00, 2.41421, 0.00, 0.00}
{0.00, 0.00, 1.0001, 1.00}
{0.00, 0.00, -0.01, 0.00}

計算式としては下記。

xScale     0          0               0
0        yScale       0               0
0          0       zf/(zf-zn)         1
0          0       -zn*zf/(zf-zn)     0
where:
yScale = cot(fovY/2)

xScale = yScale / aspect ratio

https://learn.microsoft.com/ja-jp/windows/win32/direct3d9/d3dxmatrixperspectivefovlh

Viewport 行列

640×480 のレンダーターゲットに描画する場合は、Viewport も Width 640, Height 480 に設定する。他は通常はデフォルト値の X, Y 0で、Min 0.0, Max 1.0 になるのが普通。

    dwWidth/2,              0,             0, 0,
            0,    -dwHeight/2,             0, 0,
            0,              0, dwMaxZ-dwMinZ, 0,
dwX+DwWidth/2, dwHeight/2+dwY,        dwMinZ, 1,

https://learn.microsoft.com/ja-jp/windows/win32/direct3d9/viewports-and-clipping

実際は width, height ぐらいしかパラメータは設定しないので、

w = width / 2
h = height / 2

w  0 0 0
0 -h 0 0
0  0 1 0
w  h 0 1

ぐらいの単純な行列になる。

SV_Position の値

頂点シェーダーを使用して、上記のような View, Projection 行列で、ローカル座標 [ -1.0f, 1.0f, -1.0f] を変換した場合はこのような結果になる。

 [-1.81066, 2.41421, 3.9904, 4.00]

頂点シェーダーから SV_Position へ渡している値はこれ。
ラスタライザを通り、ピクセルシェーダーの入力として渡ってくる SV_Position は下記のようになる。

[175.50, 95.50, 0.9976, 4.00]

X, Y はピクセルのスクリーン座標。
Z は Depth Buffer に書かれる値と一致する。頂点シェーダーからの出力 3.9904 / 4.0 = 0.9976 になる。
W は頂点シェーダーでの World, View, Projection の計算結果がそのまま来る。

Reference

https://shikihuiku.github.io/post/projection_matrix/
Windows Sysinternals

Windows Sysinternals

Windows Sysinternals は、主に Windows マシンの管理者や開発者向けに提供される、ユーティリティーのアプリケーション。

ここから、個別にダウンロード可能
https://learn.microsoft.com/en-us/sysinternals/downloads/

ProcessExplorer

タスクマネージャーよりも詳細にプロセスの情報を見ることが出来る。プロセスごとの詳細な RAM 使用率など。また、 System.exe を選択すると、ここからロードされている .sys ファイルの詳細なども見ることが出来る。
https://learn.microsoft.com/en-us/sysinternals/downloads/process-explorer

DebugView

アプリケーションから標準出力に書き出されるメッセージを表示することが出来る。
https://learn.microsoft.com/en-us/sysinternals/downloads/debugview

Windowsのドライバー開発

Windowsのドライバー開発

ソフトウェアのインストール

ドライバー開発には、下記の3つが必要。

  • Visual Studio
  • Windows SDK
  • WDK (Windows Driver Kit)

使用する Windows のバージョンや、インストールする Visual Studio、Windows SDK/WDK は環境によって一致させておかないといけない。そうしないと WDK インストール時に、対応する SDK が見つからない旨の Warning が表示される。

私は Windows 10 22H2 に、Visual Studio 2019 をインストールして、Windows SDK 2004 と WDK for Windows10 2004 を導入した。正しくインストールされれば、Visual Studio を立ち上げたときの「新しいプロジェクト作成」で Driver 制作のプロジェクトが使用できる。

ドライバファイル

Windows ドライバーの構成ファイルは下記。

  • ドライバー情報ファイル (.inf)
  • カーネルモードドライバー (.sys)
  • ユーザーモードドライバー (.dll)

必ずしもこの3つがある訳では無いが、概ねこれらのファイルでドライバーは動いている。

Reference

Windows ハードウェア開発者向けドキュメント
https://learn.microsoft.com/ja-jp/windows-hardware/drivers/

Windows でドライバーの使用を開始する
https://learn.microsoft.com/ja-jp/windows-hardware/drivers/gettingstarted/

ドライバーの開発、テスト、および展開
https://learn.microsoft.com/ja-jp/windows-hardware/drivers/develop/

[FPGA] 個人的な勉強用のリンク (Zynq)

[FPGA] 個人的な勉強用のリンク (Zynq)

ZedBoard

ZedBoard Hardware User’s Guide
https://digilent.com/reference/_media/zedboard:zedboard_ug.pdf

ZedBoard
https://marsee101.web.fc2.com/zedboard.html
貴重な情報に感謝。(FPGAの部屋のまとめ サイト)

Zybo

Zybo Z7 Reference Manual
https://digilent.com/reference/programmable-logic/zybo-z7/reference-manual

Vitis HLSL

ユーザーガイド
https://www.xilinx.com/content/dam/xilinx/support/documents/sw_manuals_j/xilinx2021_1/ug1399-vitis-hls.pdf

Basic examples for Vitis HLS
https://github.com/Xilinx/Vitis-HLS-Introductory-Examples
Xilinx から Example が提供されていた。

HDMI 出力

ZYBO (Zynq) でHDMI出力をする
https://qiita.com/iwatake2222/items/b323e129f96426031f9f

ZyboのHDMI入出力デモをVitisから実行してみた
https://phys-higashi.com/1267/

ADV7511 HDMI トランスミッタ
https://www.analog.com/media/en/technical-documentation/user-guides/ADV7511_Hardware_Users_Guide.pdf

FPGAでHDMIから画像出力!フリーのIPを使ってみた
https://misoji-engineer.com/archives/fpga-hdmi.html

TMDS(Transition Minimized Differential Signaling)
http://www.hdmi-navi.com/tmds/

HDMI
https://www.fpga4fun.com/HDMI.html

ADV7511 Xilinx Evaluation Boards Reference Design
https://wiki.analog.com/resources/fpga/xilinx/kc705/adv7511

その他

FPGA オリジナルボード設計 ~Xilinx FPGA の I/O ピンの使い方~
https://www.acri.c.titech.ac.jp/wordpress/archives/1244

Chiselでビットコインマイナーを設計してみる
https://msyksphinz.hatenablog.com/entry/2019/03/22/040000

AXI Basics Xilinx
https://support.xilinx.com/s/article/1137753?language=ja

Vitis HLS と Vivado で作った回路を PYNQ を使って FPGA 上で動かすまで
https://blog.n-hassy.info/2021/05/vitis-hls-to-fpga-1/

[FPGA] Vivado で ZedBoard 用のプロジェクトを作成

[FPGA] Vivado で ZedBoard 用のプロジェクトを作成

準備

電源と電源の隣に PROG と書かれた USB があるので、そこに接続する。FPGA にコンフィグ(書き込む)場合は、PROG への接続が必要。また、FPGA から出力をする場合は、UART と書かれた USB にも接続が必要。USB ケーブルは2本使う。

プロジェクト作成

Vivado 起動後の画面で、Create Project からプロジェクトを作成。

Project name に任意のプロジェクト名を指定し、次の画面では「RTL Project」を選択して、この時「Do not specity sources at this time」にチェックをいれておく。

ターゲットとなるボードを選択できるので、Search に ZedBoard と入力して、表示された「ZedBoard Zynq Evaluation and Development Kit」を選択。もし、表示されなければ「Refresh」を押せば更新されるかも。

この後に「Finish」を押せばプロジェクトが作られる。

ファイルの追加

Flow Navigator の Add Sources を選択すると追加用のダイアログが開くので、「constraints」と「design sources」をそれぞれ選択して追加していく。

「Add Files」から、それぞれ .xdc (constraints) や .v (design sources) などを追加していく。この時「Copy Sources into project」のチェックは off。「Scan and add RTL include files into project」のチェックは on にしておく。

Bitstream の生成

Design Sources と Constraints を追加したら Bitstream を生成する。左側のパネルの「PROGRAM AND DEBUG」から「Generate Bitstrea」を押す。

FPGA に書き込む

FPGA を PC に接続して電源を入れる。「PROGRAM AND DEBUG」の Open Hardware Manager -> Auto Connect を選択する。上部に「Program Device」が出てくるので、選択すると書き込める。

Reference

FPGA プログラミング大全 Xilinx 編

[Linux] Ubuntu22.04 が起動しない

[Linux] Ubuntu22.04 が起動しない

gave up waiting for root file system device. common problmes:

というメッセージが表示されて、新規インストールした Ubuntu が起動出来ないことがあった。この場合、一度 HDD をフォーマットして、再度インストールし直したら上手く行った。以下、自己責任で行ってください。

HDD をフォーマット

HDD に問題がありそうだったのでフォーマットする。もちろん HDD が初期化されるので、実行する場合は要注意。該当の HDD を接続している状態で、PC を Windows から起動するように変更する。まずは diskpart.exe から clean した。

list disk
select disk 1 ※1部分は、list disk の結果をもとに、ディスク番号を指定
clean

その後、スタートボタンを右クリックして「ディスクの管理」を立ち上げる。該当のボリュームを選択して、右クリックから「新しいシンプルボリューム」でフォーマットを実行した。

再度インストール

HDD を初期化した後に、再度 Ubuntu をインストールしたら、今度は正常に起動できた。