k0b0's record.

Computer Engineering, Arts and Books

VerilogHDLでクロック分周器を記述してみる

クロック分周器

FPGAボードを使って、7セグメントLEDに結果を表示させたい時がある。
けれど、MHz〜GHzで動作されたんでは確認できない。
という事で、クロック分周器(50MHz -> 1Hz)を記述してみる。

クロック分周器(clk_divider.v)

/* clk_divider.v */
module clk_divider(input   clk, rst,
                   output  divid);

reg  [25:0] cnt;

/* 1Hzになるまでクロック(50MHz)の立ち上がりエッジをカウント */
always @( posedge clk or posedge rst) begin
    if ( rst )
        cnt <= 26'b0;
    else if ( divid )
        cnt <= 26'b0;
    else
        cnt <= cnt + 26'b1;
end

/* カウント値が1Hzになった時の処理(出力を'1'にする) */
assign divid = (cnt==26'd49_999_999);

endmodule

clk_divider.vを論理合成した結果(Quartus PrimeのRTL Viewerで確認)

f:id:k0b0:20190525172127p:plain

SystemVerilogでチャタリング除去回路を記述してみる。

チャタリング除去回路を記述してみる

FPGAボードを使っているとスイッチをよく使う。
スイッチを押すとノイズ(チャタリング)が起こる。
というわけで、色々と参考にしてチャタリング除去回路を書いたのでメモしておく。

チャタリング除去回路(chatter.sv)

/* chatter.sv */
module chatter (input  logic clk,     // クロック 
                input  logic reset,   // リセット
                input  logic sw,      // スイッチ入力(立ち下がり)
                output logic sw_out); // 出力(1パルス)

/* cntの値はクロック周波数をどのくらい分周するかによって調整する */
logic [20:0] cnt;
wire en_N_hz = (cnt == 1200000);

/* クロックをカウントして分周 */
always_ff @(posedge clk) 
begin
    if (reset)
        cnt <= 21'b0;
    else if ( en_N_hz )
        cnt <= 21'b0;
    else
        cnt <= cnt + 21'b1;
end

/* スイッチ入力をシフトレジスタ(2つのFF)に入力 */
logic ff_0, ff_1;
always_ff @( posedge clk ) 
begin
    if (reset) 
    begin
        ff_1 <= 1'b0;
        ff_0 <= 1'b0;
    end
    else if ( en_N_hz ) begin
        ff_1 <= ff_0;
        ff_0 <= sw;
    end
end

/* シフトレジスタの各出力とクロック(分周)のANDをとりノイズを消去 */
wire tmp = ~(ff_0) & ff_1 & en_N_hz;

always_ff @(posedge clk) 
begin
    if (reset)
        sw_out <= 1'b0;
    else
        sw_out <= tmp;
end

endmodule

SystemVrilogでレジスタファイルを記述してみる

SystemVerilogで2種類のレジスタファイル(アドレス長:2ビット、レジスタ数:4、データ長:32ビット)を記述してみる。

レジスタファイル(レジスタとMUXで構成)

個人的にはこちらの記述の方が読みやすいかなぁ。
(レジスタ数が増えると、コードの行数が長くなるけど。。。)

/* regfile.v */
module regfile #(parameter A_WIDTH = 2, D_WIDTH = 32)
                (input                clk,
		 input  [A_WIDTH-1:0] readaddr1,
		 input  [A_WIDTH-1:0] readaddr2,
		 input  [A_WIDTH-1:0] writeaddr,
		 input                we,
		 input  [D_WIDTH-1:0] writedata,
		 output [D_WIDTH-1:0] readdata1,
	         output [D_WIDTH-1:0] readdata2);


logic [D_WIDTH-1:0] r0 = 0;
logic [D_WIDTH-1:0] r1 = 0;
logic [D_WIDTH-1:0] r2 = 0;
logic [D_WIDTH-1:0] r3 = 0;

/* Reading Register 1 */
assign readdata1 = (readaddr1 == 0) ? r0 :
		   (readaddr1 == 1) ? r1 :
		   (readaddr1 == 2) ? r2 : r3;

/* Reading Register 2 */
assign readdata2 = (readaddr2 == 0) ? r0 :
		   (readaddr2 == 1) ? r1 :
		   (readaddr2 == 2) ? r2 : r3;

/* Writing data */
always_ff @(posedge clk) 
begin
    if(we) 
    begin
	case(writeaddr) 
	    0: r0  <= writedata;
	    1: r1  <= writedata;
	    2: r2  <= writedata;
	    3: r3  <= writedata;
	   default : r0 <= 32'd0;
	endcase
    end
end

endmodule

レジスタファイル(RAMで構成)

こちらの記述は↑の記述よりコード数が少ない。

/* regfile_ram.sv */
module regfile_ram #(parameter A_WIDTH = 2, D_WIDTH=32)
                    (input clk,
	             input [A_WIDTH-1:0] readaddr1, readaddr2,
	             input [A_WIDTH-1:0] writeaddr,
	             input               we,
		     input [D_WIDTH-1:0] writedata,
		     output [D_WIDTH-1:0] readdata1,
		     output [D_WIDTH-1:0] readdata2);
	             

logic [D_WIDTH-1:0] dmem [0:2**A_WIDTH-1] ;

always_ff @(posedge clk)
begin
    if(we) 
	dmem[writeaddr] <= writedata;
end

assign readdata1 = dmem[readaddr1];
assign readdata2 = dmem[readaddr2];

endmodule

我が青春のPentium D

 家を掃除していたら、懐かしい物が出てきた。Pentium Dである。
子供の頃に初めて自作PCを作った時に購入したマイクロプロセッサである。

第二世代のPentium D(65nmCMOS)で3.4GHzは出ていたと思う(当時は早い早いと感激していたっけなぁ)。

あれから、何年も経って今やチップの性能はこれとは比べ物にならないくらい速い。
(いやはや、ムーアの法則とそれを実現したエンジニアの技術力には本当に驚かされる。)

このチップを乗せたPCでよく友人たちとコードを書いたりして、遊んだことが懐かしい。

f:id:k0b0:20190504130152j:plain
f:id:k0b0:20190504130214j:plain

NVIDIAのシングルボードコンピュータ:Jetson Nano

ポケットサイズのGPU

 NvidiaのJetson Nanoが色々とすごい。

[仕様]

  • GPU:128 Core NVIDIA Maxwellアーキテクチャ
  • CPU:Quad Core ARM A57Cortex-A57 MPCore
  • グラフィックス:エンコード4K@30fps(H.264/H.265、デコード4K@60fps(H.264/H.265)
  • カメラ:MIPI CSI-2 DPHY 12レーン(モジュール)、MIPI CSI-2 DPHY 1レーン(開発者キット)
  • メモリ:4 GB 64 ビット LPDDR4(毎秒25.6GB)
  • ネットワーク:ギガビットイーサネット
  • OS:Linux for Tegra

この仕様で税別11,400円ってところが本当にすごい。
2019 年 6 月頃から世界各地の販売代理店で販売されるみたい。

www.nvidia.com
makezine.jp
pc.watch.impress.co.jp

ミンスキー博士の脳の探索

私たちはどのようにして考えて、学んでいくのか?そして、そのような思考するマシンを作ることはできるのか?

 人工知能の父として有名なMITのマービン・ミンスキー先生の著作。
 「思考素」と「思考路」という抽象的な概念を用いて、脳や常識、感情、自己について様々なアイディアを検証している。

 難解な内容でなかなか理解できないところも多いが、繰り返し読むことで様々な発見があるような一冊。
 

ミンスキー博士の脳の探検 ―常識・感情・自己とは―

ミンスキー博士の脳の探検 ―常識・感情・自己とは―

Virtualboxのエラー: VBoxClient (seamless): failed to start. Stage: Setting guest IRQ filter mas Error: VERR_INTERNAL_ERROR

VBoxClient (seamless): failed to start. Stage: Setting guest IRQ filter mas Error: VERR_INTERNAL_ERROR

 Virtualbox上のUbuntu16.04でこんなエラーに出くわした。それで、ホスト・ゲスト間でファイルの移動やコピペが出来なくなった。

 色々調べて見た結果、ゲスト側(Ubuntu)のカーネルをバージョンアップしたことが原因だったみたい。

解決方法

 Virtualboxをバージョンアップしたら正常に動作した。

参考サイト

qiita.com