コイルってなに?初心者向けに電流と磁場と起電力の関係をまとめてみた

「コンデンサは電荷がたまる素子だけど、コイルって結局どんな素子??」 そんな疑問をやさしく整理してみるよ~。

コイルは導線をぐるぐる筒状に巻いた形状のものだよ~。 コイルに電流を流すと筒を貫く向きに磁場が発生するよ~。 ある面積を貫く磁場の量を磁束っていうよ~。 コイルに電流を流し始めると、徐々に磁束が増えていくよ~。 磁束が変化すると、誘導起電力が生じるよ~。これをファラデーの法則というよ~。 誘導起電力は磁束の変化を打ち消すように生じるよ~。これをレンツの法則というよ~。 コイルが持つエネルギーは、コイルの特性であるインダクタンスLとコイルを流れる電流Iによって決まるよ~。 要するに、電流を流して磁場という形でエネルギーを蓄える素子だよ~。 そのエネルギーは1/2×L×I2で表されるよ~。 理想的なコイルは一本の導線だから抵抗なしとして考えるんだよ~。 でも、実際は導線が長いので、導線の抵抗を考慮して使うんだよ~。

やさしく解説してみたよ。 まとめると、コンデンサは電荷によって電場にエネルギーを蓄える素子だよ~。 コイルは電流によって磁場にエネルギーを蓄える素子だよ~。

カウンタ回路のベストプラクティス #VHDL

一生使えるHDLのコードを書くシリーズ第一弾。

VHDLverilog、SystemVerilogで、これまで同じような記述を何度も書いてきた。その度にまったく同じように書けなかったりミスしたり。。。

この経験から一生使えるコードをここに書き記す。

記念すべき第一弾の回路は、「カウンタ」です。

一生使えるカウンタはこれだ!!

※注意:
本記事に掲載している回路は、GHDLによるリントチェック(構文・型整合性チェック)を通過しています。ただし、実際のご使用にあたっては、目的や仕様に応じた十分な検証を行ってください。

本回路の使用によって生じたいかなる損害についても、当方は責任を負いかねます。自己責任でご利用ください。

counter.vhd

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.numeric_std.all;

entity counter is
    generic (CNT_WIDTH : integer := 8;
             MAX_VALUE  : unsigned(CNT_WIDTH-1 downto 0) := (others => '1');
             HOLD_ON_MAX : boolean := FALSE -- true: Hold at max value, false: Reset to 0
             );
    port (
        CLK     : in STD_LOGIC;
        RST     : in STD_LOGIC;
        CLR     : in STD_LOGIC;
        EN      : in STD_LOGIC;
        CNT   : out unsigned(CNT_WIDTH-1 downto 0)
    );
end counter;

architecture Behavioral of counter is
    signal count_reg : unsigned(CNT_WIDTH-1 downto 0) := (others => '0');
begin

    GEN_HOLD_ON_MAX : if HOLD_ON_MAX generate
            process(CLK, RST)
            begin
                if RST = '1' then
                    count_reg <= (others => '0');
                elsif rising_edge(CLK) then
                    if CLR = '1' then
                        count_reg <= (others => '0');
                    elsif EN = '1' then
                        if count_reg = MAX_VALUE then
                            count_reg <= count_reg; -- Hold at max value
                        else
                            count_reg <= count_reg + 1; -- Increment the counter
                        end if;
                    end if;
                end if;
            end process;
    end generate;

    GEN_AUTO_ROUTATE : if not HOLD_ON_MAX generate
        process(CLK, RST)
        begin
            if RST = '1' then
                count_reg <= (others => '0');
            elsif rising_edge(CLK) then
                if CLR = '1' then
                    count_reg <= (others => '0');
                elsif EN = '1' then
                    if count_reg = MAX_VALUE then
                        count_reg <= (others => '0'); -- Reset to 0
                    else
                        count_reg <= count_reg + 1; -- Increment the counter
                    end if;
                end if;
            end if;
        end process;
    end generate;

    
    CNT <= count_reg;

end Behavioral;

工夫したポイント

この回路は、genericのHOLD_ON_MAXのTRUE/FALSEを切り替えることで、最大値に達したときの動作を変更できるところ。

最大値も、ビット幅以内であれば好きな値を指定できるのもポイント。

ブロック図

Diagram


タイムチャート 「最大値に達したらキープ」Ver.


タイムチャート 「最大値に達したら0へ戻る」Ver.


インスタンス化の記述例

    component counter is
        generic (CNT_WIDTH   : integer := 8;
                 MAX_VALUE   : unsigned(CNT_WIDTH-1 downto 0) := (others => '1');
                 HOLD_ON_MAX : boolean := FALSE -- true: Hold at max value, false: Reset to 0
        );
        port (
            CLK : in STD_LOGIC;
            RST : in STD_LOGIC;
            CLR : in STD_LOGIC;
            EN  : in STD_LOGIC;
            CNT : out unsigned(CNT_WIDTH-1 downto 0)
        );
    end component;
    xxx_counter : counter
    generic map(
        CNT_WIDTH   => 4,
        MAX_VALUE   => (others => '1'),
        HOLD_ON_MAX => FALSE
    ) port map(
        CLK    => user_signal,
        RST    => user_signal,
        CLR    => user_signal,
        EN     => user_signal,
        CNT  => user_signal
    );

まとめ

これで一生、カウンタはコピペで済むようになった。

AN 647: Single-Port Triple Speed Ethernet and On-Board PHY Chip Reference Designを開いてみた

これからTriple Speed Ethernet IPを使おうとしている人には参考になる。

https://www.altera.com/en_US/pdfs/literature/an/an647.pdf

module top (
//Clock and Reset

CLKIN,
GTX_CLK,
RX_CLK,
RESET_N,            // USER_PB0
PHY_RESET_N,

// Reset Status
LED_RESET_N,        // USR_LED0
LED_CORE_RESET_N,   // USR_LED1

//MDIO
MDC,
MDIO,

//RGMII 
RGMII_IN,
RGMII_OUT,
RX_CONTROL,
TX_CONTROL,

//MAC Status Signals
SET_1000,           // USER_DIPSW1
SET_10,             // USER_DIPSW0
ENA_10_N,           // USR_LED2
ETH_MODE_N          // USR_LED3
);

input              CLKIN;
output          GTX_CLK;
input           RX_CLK;
input           RESET_N;
output          PHY_RESET_N;

output          LED_RESET_N;
output          LED_CORE_RESET_N;

output          MDC;
inout           MDIO;

input   [3:0]   RGMII_IN;
output  [3:0]   RGMII_OUT;
input           RX_CONTROL;
output          TX_CONTROL;

input           SET_1000;
input           SET_10;
output          ENA_10_N;
output          ETH_MODE_N;

wire            clk_25M;
wire            clk_2_5M;
wire            clk_125M;

wire            tx_clk;

//wire          RESET_N;
wire            core_reset_n;

wire            mdio_in;
wire            mdio_oen;
wire            mdio_out;

wire            ena_10;
wire            eth_mode;
wire [1:0] select;
// Clock and Reset connection
assign PHY_RESET_N = core_reset_n;
assign LED_RESET_N = RESET_N;
assign LED_CORE_RESET_N = ~core_reset_n;

// MDIO ports connection
assign MDIO = mdio_oen ? 1'bz : mdio_out;
assign mdio_in = MDIO;

assign ENA_10_N = ~ena_10;
assign ETH_MODE_N = ~eth_mode;


pll pll_0 (
    
    .rst    (~RESET_N),
    .refclk         (CLKIN),
    .outclk_0       (clk_125M),
    .outclk_1       (clk_25M),
    .outclk_2       (clk_2_5M),

    .locked (core_reset_n)
);

qsys_top qsys_top_0 (
    .triple_speed_ethernet_0_mac_status_connection_eth_mode (eth_mode),     // triple_speed_ethernet_0_conduit_connection.eth_mode
    .triple_speed_ethernet_0_mac_status_connection_ena_10       (ena_10),       //                                           .ena_10
    .triple_speed_ethernet_0_mac_rgmii_connection_rgmii_in    (RGMII_IN),       //                                           .rgmii_in
    .triple_speed_ethernet_0_mac_mdio_connection_mdc        (MDC),          //                                           .mdc
    .triple_speed_ethernet_0_mac_rgmii_connection_tx_control    (TX_CONTROL),   //                                           .tx_control
    .triple_speed_ethernet_0_mac_status_connection_set_1000    (SET_1000),      //                                           .set_1000
    .triple_speed_ethernet_0_mac_mdio_connection_mdio_out   (mdio_out),     //                                           .mdio_out
    .triple_speed_ethernet_0_mac_rgmii_connection_rgmii_out     (RGMII_OUT),    //                                           .rgmii_out
    .triple_speed_ethernet_0_mac_mdio_connection_mdio_oen   (mdio_oen),     //                                           .mdio_oen
    .triple_speed_ethernet_0_mac_status_connection_set_10      (SET_10),        //                                           .set_10
    .triple_speed_ethernet_0_mac_mdio_connection_mdio_in        (mdio_in),      //                                           .mdio_in
    .triple_speed_ethernet_0_mac_rgmii_connection_rx_control  (RX_CONTROL),     //                                           .rx_control
    .triple_speed_ethernet_0_mac_misc_connection_xon_gen (1'b0),     
    .triple_speed_ethernet_0_mac_misc_connection_xoff_gen (1'b0),    
    .triple_speed_ethernet_0_mac_misc_connection_ff_tx_crc_fwd (1'b0),
    .triple_speed_ethernet_0_mac_misc_connection_ff_tx_septy    (), 
    .triple_speed_ethernet_0_mac_misc_connection_tx_ff_uflow    (), 
    .triple_speed_ethernet_0_mac_misc_connection_ff_tx_a_full   (),
    .triple_speed_ethernet_0_mac_misc_connection_ff_tx_a_empty  (),
    .triple_speed_ethernet_0_mac_misc_connection_rx_err_stat    (), 
    .triple_speed_ethernet_0_mac_misc_connection_rx_frm_type    (), 
    .triple_speed_ethernet_0_mac_misc_connection_ff_rx_dsav     (),  
    .triple_speed_ethernet_0_mac_misc_connection_ff_rx_a_full   (),
    .triple_speed_ethernet_0_mac_misc_connection_ff_rx_a_empty  (),
    .reset_reset_n                                          (core_reset_n), //                                      reset.reset_n
    .clk_clk                                                    (clk_125M),      //                                        clk.clk
    .triple_speed_ethernet_0_pcs_mac_tx_clock_connection_clk    (tx_clk),
    .triple_speed_ethernet_0_pcs_mac_rx_clock_connection_clk    (RX_CLK)
    );

ddio_out ddio_out_0 (
    .outclock (tx_clk),
    .dataout ( GTX_CLK ),
    .aclr (!core_reset_n),
    .datain_h (1'b1),
    .datain_l (1'b0),
    .outclocken (1'b1),
    .oe (1'b1)
);


assign tx_clk =   ( eth_mode ) ? ( clk_125M ) :  // GbE Mode = 125MHz clock
                  ( ena_10 ) ? ( clk_2_5M ) :    // 10Mb Mode = 2.5MHz clock
                  ( clk_25M );                  // 100Mb Mode = 25MHz clock
                        



endmodule 

Intelの新CPU「Nios V」とライセンス取得手順のまとめ【Quartus 24対応】

IntelがQuartus 21から新しく「Nios V」というFPGA向けCPUを発表しました。 これまでのNios Ⅱとは開発手順が大きく異なるようですが、詳しく解説しているサイトが少ないため、マニュアルを参照しながら自分なりに整理してみました。

■ Nios Vとは?

Nios Vは、Intelが提供するRISC-VベースのソフトウェアCPU(IPコア)です。

RISC-V」とは、命令セットアーキテクチャ(ISA)がオープンソース化されているCPUで、ライセンス料が無料。また命令セットがモジュラー式のため、不要な命令を削って回路を小さく最適化できます。FPGAのようにカスタマイズが可能なハードウェアには、この柔軟性が非常に相性が良いです。

■Nios Vを使うために必要なもの

Nios Vを利用するには、次の2つが必須です。 (※Nios Vを使用しない場合でも必要な構成です)

1. JTAGインターフェース

2. コンフィギュレーションができる(例:外部フラッシュから読み出し、JTAG経由での書き込みなど)

■Nios V用IPライセンスの取得方法

Nios Vを使うには、無償ライセンス「Nios V Processor Intel FPGA IP licenses」の取得が必要です。今回は、このライセンス取得手順に絞って説明します。

Step1:My Intelにログイン

まず、Intel FPGA Self-Service Licensing Centerにアクセスして、サインインする。

Intel FPGA Self-Service Lincensing Centerにサインインした画面

Step 2:Enroll(登録)

画面右にある「Enroll」ボタンをクリックし、自分の情報を入力します。完了すると、"Welcome to PSG Licensing"という件名のメールが届きます。

登録(Enroll)で情報提出後の画面

Step 3:SSLCへサインイン

Licensing Centerに戻り、左側の「Already enrolled ? - Sign In here」をクリックしてサインインします。ここでは2段階認証などの手続きが少し面倒ですが、完了後は以下のような画面になります。

Licensing Centerにサインイン後の画面

Step 4:ライセンスの選択

Sign up for Evaluation or No-Cost Lisence」タブをクリックし、 Nios® V/m Microcontroller FPGA IP (License: IP-NIOSVM)を選択して「Next」をクリックする。

Nios V/mのライセンスを選択

Step 5:NIC IDの入力とライセンス取得

次に、ライセンスを紐づけるPCのNIC ID(MACアドレス)を入力します。Linuxの場合、以下のコマンドで取得します。複数出力された場合、ip aコマンドだけ実行して、現在使用しているNIC IDを選択してください。

ip a | grep 'link/ether' | awk '{print $2}'

入力後、メールでライセンスファイルが届きます。 今回は、FIXED_LICENSEとして取得しました。

Step 6:ライセンスファイルの設定

最後に、Intel公式マニュアルのFixed-licenseの取得方法を参考にして、ライセンスファイルを設定します。 この手順通りに設定できれば、ライセンスの準備は完了です。

今回はここまで

最後までお読みいただきありがとうございました。 次回は、実際にNios Vを使ったプロジェクト作成の手順について解説予定です。

参照したマニュアル
A. Nios® V Processor Software Developer Handbook Archives
https://cdrdv2-public.intel.com/793065/ug-726952-793065.pdf

pythonバイナリデータを扱う①

pythonでバイナリデータを2進数にした後、いろいろ操作する方法をまとめてみた。 いろいろ操作した後にバイナリデータや整数に変換する方針にしている。正しいのかな?

import sys

def main():
    binary_data = b'\x08'
    # binary_data = b'\x48\x65\x6c\x6c\x6f'
    data = int.from_bytes(binary_data, sys.byteorder)
    binary_num = to_binary_number(data,10)
    binary_num = bit_slice(binary_num,4,2)
    print (binary_num)
    binary_num += create_0(5)
    print (binary_num)

def to_binary_number(data,bit_width):
    binary_number = format(data,"0"+str(bit_width)+"b")
    return binary_number

def create_0(num):
    return str("0"*int(num))

def bit_slice(binary_num,msb,lsb):
    data_len = len(binary_num)
    if data_len < msb+1:
        print ("[    ERROR    ] msb is bigger than binary_num width")
        return -1
    if msb < lsb:
        print ("[    ERROR    ] msb is less than lsb")
        return -1
    first_pos = data_len - msb - 1
    last_pos = data_len - lsb - 1
    return binary_num[first_pos:last_pos+1]

if __name__ == "__main__":
    main()

openpyxlを使ってみた②

こちらは本体。入力データと出力データそれぞれ、選ばれた時用と選ばれてない時用の2種類、計4種類(2×2)を準備する。

その後、1つのテストの設定にする。

#test.py

import openpyxl
from common_function import get_position_from_ws
from common_function import get_port_data_list
from common_function import peer_to_peer

hsize = 320 
vsize = 240 

base_port_row    =0  
base_port_column =0

in_select_list     = []
in_no_select_list  = []
in_color_list      = []
out_select_list    = []
out_no_select_list = []
out_color_list     = []

wb = openpyxl.load_workbook(filename = 'sample_1.xlsx',data_only=True)
ws = wb.active

base_port_row,base_port_column     = get_position_from_ws(ws,target_chr="port")

#                     [port name,sel_number,color,file name,  bit width,reserve,hsize,vsize]
# in_select_list    : [port_name,sel_number,1,    file_name,  bit_width,1,      hsize,vsize]
# in_no_select_list : [port_name,sel_number,0,    "empty.bin",bit_width,1,      0,    0    ]
in_select_list, in_no_select_list  = get_port_data_list("in", ws,base_port_row,base_port_column,hsize,vsize)

#                      [port name,reg name,color,file name,bit width,reserve,hsize,vsize]
# out_select_list    : [port_name,reg_name,1,    file_name,bit_width,1,      hsize,vsize]
# out_no_select_list : [port_name,reg_name,0,    file_name,bit_width,1,      0,    0    ]
out_select_list, out_no_select_list = get_port_data_list("out",ws,base_port_row,base_port_column,hsize,vsize)

#peer to peer
data_testlist,color_testlist = peer_to_peer(ws,base_port_row,base_port_column,in_no_select_list,in_select_list,out_no_select_list,out_select_list)
print (data_testlist)
print (color_testlist)
#common_function.py

def to_bit_width(char_bit_width_raw):
    data = char_bit_width_raw.replace('[','').replace(']','')
    f_pos = data.find(':')
    return int(data[:f_pos])+1

def get_position_from_ws(ws,target_chr):
    for test in ws: 
        for data in test:
            if data.value == str(target_chr) :
               return data.row, data.column

def get_port_data_list(port_is,ws,base_port_row,base_port_column,hsize,vsize):
    select_list    = []
    no_select_list = []
    if (port_is == "in"):
        for i in range(base_port_row+1,ws.max_row+1):
            sel_number =              ws.cell(i,base_port_column-2).value
            bit_width  = to_bit_width(ws.cell(i,base_port_column-1).value)
            port_name  =              ws.cell(i,base_port_column-0).value
            file_name  = port_name + ".bin"
                         #port name,sel_number,color,file name,  bit width,reserve,hsize,vsize
            select     = [port_name,sel_number,1,    file_name,  bit_width,1,      hsize,vsize]
            no_select  = [port_name,sel_number,0,    "empty.bin",bit_width,1,      0,    0    ]   
            select_list.append    (select)
            no_select_list.append (no_select)

    if (port_is == "out"):
        for i in range(base_port_column+1,ws.max_column+1):
            reg_name  =              ws.cell(base_port_row-2,i).value
            bit_width = to_bit_width(ws.cell(base_port_row-1,i).value)
            port_name =              ws.cell(base_port_row-0,i).value
            file_name = port_name + ".bin"
                        #port name,reg name,color,file name,bit width,reserve,hsize,vsize
            select    = [port_name,reg_name,1,    file_name,bit_width,1,      hsize,vsize]
            no_select = [port_name,reg_name,0,    file_name,bit_width,1,      0,    0    ]   
            select_list.append    (select)
            no_select_list.append (no_select)
    return select_list, no_select_list
def peer_to_peer(ws,base_port_row, base_port_column, in_no_select_list, in_select_list, out_no_select_list, out_select_list):
    data_testlist  = []
    color_testlist = []
    test_num = 0
    in_num = 0
    for i in range(base_port_row+1,ws.max_row):
        out_num = 0
        temp_in_list          = in_no_select_list.copy()
        temp_in_list[in_num]  = in_select_list[in_num]
        in_color_list         = len(temp_in_list) * [len(temp_in_list[0])* [0]]
        in_color_list[in_num] = [0,0,0,1,1]
        sel_number            = temp_in_list[in_num][1]

        for j in range(base_port_column+1,ws.max_column):
            if ws.cell(i,j).value is not None:
                temp_out_list           = out_no_select_list.copy()
                temp_out_list[out_num]  = out_select_list[out_num]
                out_color_list          = len(temp_out_list) * [len(temp_out_list[0])* [0]]
                out_color_list[out_num] = [0,0,0,1,1]
                temp_reg_list           = len(temp_out_list) * [0]
                temp_reg_list[out_num]  = sel_number
                reg_color_list          = len(temp_reg_list) * [0]
                reg_color_list[out_num] = 1

                in_name_for_testlist  = [data[0] for data in temp_in_list ]
                out_name_for_testlist = [data[0] for data in temp_out_list]
                reg_name_for_testlist = [data[1] for data in temp_out_list]
                in_data_for_testlist  = [data for test in temp_in_list  for data in test[3:8]]
                out_data_for_testlist = [data for test in temp_out_list for data in test[3:8]]
                reg_data_for_testlist = temp_reg_list
                data_testlist.append(in_data_for_testlist + out_data_for_testlist + [""] + reg_data_for_testlist)

                in_color_for_testlist  = [x for color in in_color_list  for x in color]
                out_color_for_testlist = [x for color in out_color_list for x in color]
                reg_color_for_testlist = reg_color_list
                color_testlist.append(in_color_for_testlist + out_color_for_testlist + [""] + reg_color_for_testlist)
                test_num += 1
            out_num += 1 
    return data_testlist, color_testlist

openpyxlを使ってみた①

openpyxlを使ってみた。整理できていないけど、参考として記載。

import openpyxl

base_port_row    =0
base_port_column =0
wb = openpyxl.load_workbook(filename = 'sample_1.xlsx')
ws = wb.active

#test_list = [[input_1,infile,bpp,epp,hsize,vsize],[...],]
for test in ws:
    for data in test:
        if data.value == "port" :
           base_port_row    = data.row
           base_port_column = data.column
           break

inport_no_select_list = []
inport_select_list    = []
outport_no_select_list = []
outport_select_list    = []
regport_no_select_list = []
for i in range(base_port_row+1,ws.max_row+1):
    sel_num     = ws.cell(i,base_port_column-2).value
    bit_wid     = ws.cell(i,base_port_column-1).value
    port_name   = ws.cell(i,base_port_column-0).value
    file_name   = str(ws.cell(i,base_port_column-0).value) + ".bin"
    inport_select_list.append   ([port_name,file_name,  bit_wid,1,320,240,sel_num])
    inport_no_select_list.append([port_name,"empty.bin",bit_wid,1,320,240,sel_num])

for i in range(base_port_column+1,ws.max_column+1):
    reg_name    = ws.cell(base_port_row-2,i).value
    bit_wid     = ws.cell(base_port_row-1,i).value
    port_name   = ws.cell(base_port_row-0,i).value
    file_name   = str(ws.cell(base_port_row-0,i).value) + ".bin"
    outport_no_select_list.append([port_name,file_name,bit_wid,1,320,240,reg_name])
    outport_select_list.append   ([port_name,file_name,bit_wid,1,320,240,reg_name])
    regport_no_select_list.append([reg_name,0])

#peer to peer
test_list = []
input_num = 0
for i in range(base_port_row+1,ws.max_row):
    temp_in_list            = inport_no_select_list.copy()
    temp_in_list[input_num] = inport_select_list[input_num]

    output_num = 0
    for j in range(base_port_column+1,ws.max_column):
        if ws.cell(i,j).value is not None:
            temp_out_list                = outport_no_select_list.copy()
            temp_out_list[output_num]    = outport_select_list[output_num]

            temp_reg_list                = regport_no_select_list.copy()
            temp_reg_list[output_num][1] = temp_in_list[input_num][6]

            test_list.append(temp_in_list + temp_out_list + temp_reg_list)
        output_num += 1
    input_num += 1
print (test_list[0])