2020年11月14日土曜日

raspberry pi : OS インストール(SSH, 無線LAN)

目的:

ラズベリーパイ に raspios  をインストールする。
ラズベリーパイ 用には モニタ、キーボード、マウス、有線LAN は接続せず、 Windows PC から無線LANで SSH接続して行う。

手順: 

Raspberry pi の モニタ、キーボード、マウス、有線LAN は 接続しない前提での インストール手順。
LAN は 無線LAN。
今回は、raspberry pi 3B に、Lite版 をインストール。

(1) OS ダウンロード

http://www.raspberrypi.org/downloads/
からダウンロードする。
但し、上記( 公式サイト) からのダウンロードが失敗が多い。
ミラーサイトは以下。
 (なぜか、ダウンロード先がネットワークドライブだと失敗する。 
  ローカルドライブだと成功する。)

・Raspberry Pi OS with desktop and recommended software
    http://ftp.jaist.ac.jp/pub/raspberrypi/raspios_full_armhf/images/
  デスクトップ環境 + 公式おすすめのソフトウェア
 
・Raspberry Pi OS with desktop
    http://ftp.jaist.ac.jp/pub/raspberrypi/raspios_armhf/images/
   デスクトップ環境
 
・Raspberry Pi OS Lite
    http://ftp.jaist.ac.jp/pub/raspberrypi/raspios_lite_armhf/images/
   デスクトップ環境 (X Window)  なし
 
今回は、"Raspberry Pi OS Lite" を使用。

(2) SDカードをフォーマット

SDカードを "SDFormatter" で 上書きフォーマット。

(3) OS を SDカードに書き込み

ダウンロードしたファイル を SD に書き込む。
書き込みには、balenaEtcher を使用した。
balenaEtcher は、.zip ファイルのまま書き込める。

(4) SSH ファイル を SDカードに書き込み

空のSSH ファイルを SDカードの boot ディレクトリに作成する。
Windows の エクスプローラで SDカードを開くと boot ディレクトリが表示される。
ここに、右クリックメニュー から 新規作成 > テキスト文書 を選択し、
ファイル名を SSH に変更する。 (拡張子は無し。中身は不要。ファイルサイズ 0 )

(5) wpa_supplicant.conf ファイルを SDカードに書き込み

以下の内容のファイルを SDカードの boot ディレクトリに作成する。
ctrl_interface=DIR=/var/run/wpa_supplicant GROUP=netdev
update_config=1
country=JP

network={
  ssid="[SSID]"
  psk="[パスフレーズ]"
  key_mgmt=WPA-PSK
  scan_ssid=1
}
[SSID], [パスフレーズ] は、各自の環境に合わせた値を設定。
"scan_ssid=1" は、SSID を非公開にしている場合に必要。

(6) Power ON

Raspberry Pi に SDカードを挿入して電源を接続し、電源onする。

(7) SSH でLOGIN

raspberry pi に SSH で LOGIN する。
IPアドレスは DHCP で割り当てられた IP アドレスで 立ち上がるため、IPアドレスは推定で指定する。
 NetEnum 等で ネットワーク上に存在する IPアドレス (ping の通ったアドレス)  を調べ、アタリをつける。
SSH 接続時の初期値は  ID : pi,  パスワード : raspberry。
SSH 接続は、Windows 上 の端末から、例えば 以下の様に 行う。

ssh pi@192.168.1.131

(7) 初期設定

raspi-config で ロケール等の 初期設定を行う。

sudo raspi-config

で、ラズベリーパイの設定を行う。
  • raspi-config の アップデート
     8 Update  を選択して Return
    で raspi-connfig 自体の アップデートを行う
  • ロケール設定
    5 Localisation Options を選択して Return。
    L1 Locale  を選択して Return。
    ja_JP.EUC-JP EUC-JP , ja_JP.UTF-8 UTF-8 で スペースキーを押下して '*' を付け、リターンキーを押下。
  • タイムゾーン設定
    5 Localisation Options を選択して Return。
    L2 Timezone  を選択して Return。
    アジア を選択してリターンキーを押下後、東京を選択してリターンキーを押下。
  • WLAN Country 設定
    5 Localisation Options を選択して Return。
    L4 WLAN Country  を選択して Return。
    JP Japan を選択してリターンキーを押下。

    Finish  を選択して Return で リブートする。

(8)ユーザ追加/パスワード設定

  1. root のパスワードを設定
    sudo passwd root
    で、root の パスワードを 設定する。
  2. 新規ユーザを設定
    通常使用するユーザを追加する。
    sudo adduser <新規ユーザ名>
    でユーザを追加する。
  3. 追加したユーザのグループを pi と同じグループにする
    pi と同じグループとする為、pi のグループを表示する。
    groups pi
    でグループが表示される。
    sudo usermod -G <pi の グループ> <新規ユーザ名>
    で、グループを追加する。
     (pi のグループは、',' 区切りで pi,adm,…… の様に 列挙する )
  4. pi ユーザのパスワードを変更する。
    piユーザのパスワードをデフォルトから変えておく。
    passwd
    で新しいパスワードを入力する。
  5. pi ユーザをリネームする。
    pi での接続を終了し、追加した新規ユーザで SSH 接続しなおす。
    ユーザ名 pi は、default のユーザ名の為、セキュリティ観点からリネームする。
    sudo usermod -l <新ユーザ名> pi

  

(9) パッケージ更新

sudo apt update
で、パッケージ管理ツールをアップデートする。
 (パッケージリストの更新)

sudo apt upgrade
で、アップグレードをする。(インストールされてるパッケージの更新)

(10) IPアドレス固定

/etc/dhcpcd.conf に以下を追記して IPアドレスを固定。
 ( /etc/dhcpcd.conf 内に 記述例があるので、それを参考に記述 )
sudo vi /etc/dhcpcd.conf
 
 

interface wlan0
static ip_address=***.***.***.***/24        // IPアドレスを指定する
static routers=***.***.***.***              // ルーターのIPアドレスを指定する
static domain_name_servers=***.***.***.***  // DNS の IPアドレスを指定する

設定後、
sudo reboot
でリブートし、設定した IPアドレスで接続できることを確認。 

(11) ホスト名変更

/etc/hostname と /etc/hosts に記載されている名前を変更し、リブートする。

sudo vi /etc/hostname
sudo vi /etc/hosts

で、それぞれ raspberrypi と書かれたところを 新しいホスト名に変更。
その後、

sudo reboot

でリブート。
この時、
sudo: ホスト raspberrypi の名前解決ができません: ホスト名にアドレスが割り当てられていません
のメッセージが発生するが、リブートする。

リブート後は、新しいホスト名となる。 

 

 

windows : Windows10 ネットワークドライブで接続できない

 現象:

 Windows10 のアップデートで 20H2 にアップデートしたところ、ネットワークドライブ (LAN DISK) にアクセスできなくなった。
( 20H2 にアップデートした 翌日にまたWindows が更新され、この時からアクセスができなくなった。(たぶん) )


原因:

なんらかのセキュリティアップデートにより、アクセス権のない共有フォルダにアクセスができなくなったと推定。


対処方法:

今回は、以下の手順で ゲストログオンを有効に設定することで、アクセス可能となった。
 ( Windows10 Home では できない らしい )

  1. スタートメニュー(画面左下) から [ファイル名を指定して実行]を押下。
  2. 名前に「gpedit.msc」と入力して[OK]を押下。
    → "ローカルグループポリシーエディター" が開く。
  3. [コンピューターの構成]→[管理用テンプレート]→[ネットワーク]→[Lanman ワークステーション]を押下。
  4. 右ペイン(設定) の[安全でないゲストログオンを有効にする]をダブルクリックする。
  5. 開いたウインドウの[有効]を選び、[OK]をクリックする。
  6. OSを再起動する。

 * 2021.5.5 追記
  本設定後も、PC 電源ON 直後 等 に アクセスできない場合が発生するようになった。
  Windows10 ネットワークドライブで接続できない_2 参照

2020年10月25日日曜日

blogger : 行の途中で文字の先頭を揃える

目的:

blogger で 文字の先頭位置を揃える。
 

内容:

項目1 : 内容1 は 1行分。
項目12 : 内容12 は
2行分

項目123 : 内容123 は 1行分

の様に、行の途中で文字の開始位置を揃える。

方法:

HTMLビュー で
 display: inline-block ;
 vertical-align: top;
 width: XXem;
を設定して整形する。
width の量は プレビュー で確認しながら調整。(作成ビューと表示が異なる可能性がある)
内容等、複数行になる場合を考慮して vertical-align で top を指定。

例:

 上の「内容:」の場合、項目, :, 内容 の 3部分に分けて以下の様に記述。
 ( 2020/10/29 : 3項目目の width 変更。スマホで 崩れる為 )

 <span style="display: inline-block; vertical-align: top; width: 5em;">
  項目1 </span>
<span style="display: inline-block; vertical-align: top; width: 1em;">
  : </span>
<span style="display: inline-block; vertical-align: top; width: calc( 100% - 7em);">
  内容1 は 1行分。&nbsp;</span><br/>
<span style="display: inline-block; vertical-align: top; width: 5em;">
  項目12</span>
<span style="display: inline-block; vertical-align: top; width: 1em;">
  : </span>
<span style="display: inline-block; vertical-align: top; width: calc( 100% - 7em);">
  内容12 は <br />2行分</span>
<span style="display: inline-block; vertical-align: top; width: 5em;">
  項目123 </span><br/>
<span style="display: inline-block; vertical-align: top; width: 1em;">
  : </span>
<span style="display: inline-block; vertical-align: top; width: calc( 100% - 7em);">
  内容123 は 1行分 </span><br/>


ESP32/arduino : WEBから制御可能なNゲージ用 PWM制御パワーパック_改4

目的:

Nゲージ用 PWM制御パワーパックの改良/機能追加として、以下を行う。
(1) フォトリフレクタ TPR-105 による車両検出

追加機能:

レイアウトの主要地点に TPR-105 を設置し、車両検出を行う。
自動運転時、車両検出 (通過検出) により次の動作(設定)へ移行する。

 

車両検出ハードウェア:

 PWPK ハードウェア(回路) は こちら
 車両検出回路 は こちら

ESP32 に TPR-105 を接続できる端子が余っていない為、I2C接続の I/Oエキスパンダ(MCP23017) を使用して TPR-105 を接続している。
MCP23017 の使い方は こちら を参照。
TPR-105 の使い方は こちら を参照。
 

WEB画面:

車両検出対応の為、PWPK設定画面 ( 自動運行の設定画面 ) を下の様に変更。

 "設定更新契機" で、次の設定を開始するタイミングを
・時間経過
・地点通過
・スイッチ押下
から選択する。
地点通過で車両検出を行う。

その他の画面は WEBから制御可能なNゲージ用 PWM制御パワーパック_改3 と同じ。


スケッチ等:

スケッチ等は こちらのファイルを参照。(zipファイル)
スケッチ等の構成は、改3 と同様。
詳細はコメントを参照。
 

HTML     :   PWPK MAIN HTML (pwpk.html)

PWPK設定 HTML   (pwpk_conf.html)
PWPK XHR 応答 HTML (pwpk_resp.html)
WiFi設定 HTML (wifi_conf.html)
WiFi XHR 応答 HTML (wifi_resp.html)
スケッチ :    MAIN (pwpk_5.ino : 変数定義, setup, loop 関数)
WIFI設定 (wifi_config.ino : 主に WiFI 設定用 の関数)
PWPK処理 (pwpk.ino : 主に PWPK処理、PWPK 設定用 の関数)



車両位置検出概要:

車両位置検出は、以下の変数を使用する。

det_ariv : 到達フラグ。検出位置に到達したことを示す。定期割込み開始時にクリア。
pnt_extno : 車両位置。
最後に到達した位置を示す。初期値は 0xff

pnt_arrive[8] : 検出位置毎の到達フラグ。
検出位置に到達した事を示す。
検出位置 に 到達した時 '1', 処理終了か、別検出位置到達で '0'

pnt_mask[8] : 検出位置毎のマスクフラグ。
検出位置到達後、一定期間、到達の検出を行わない様にする
検出位置 に 到達した時 '1', 一定期間経過経過後に '0'

pnt_time[8] : 検出位置毎の到達時刻。
検出位置 に 到達した時の時刻を記憶する。


車両位置検出の処理の概要は以下の通り。
 (実際の処理は、スケッチ 参照)
  • 車両の位置情報取得
    1. 各検出位置毎に 到達後の経過時間をチェックし、一定時間経過していればマスクフラグを解除する。
    2. MC23017の割込み状態を取得 ( INTFA, INTCAPA をリードする )。
    3. 到達フラグをクリア。
    4. 割込み発生時、各変数更新。
      1. 到達位置を取得。
        マスクされていない位置に到達した時、到達フラグをセットして到達した位置を取得。
      2. 各変数更新。
        到達した位置の場合、到達フラグ(pnt_arrive[n]),マスクフラグ(pnt_mask[n]) をセットし、, 到達時刻(pnt_time[n])を更新。
        到達した位置ではない場合は、到達フラグ(pnt_arrine[n]) をクリア。

  • 自動運転制御中の 車両位置検出処理
    1. 自動運転開始時、全検出位置の変数を初期化する。
    2. 設定更新契機が地点通過の場合、待っている位置の到達フラグを確認。
      到達フラグが立っていた場合、自動運転設定の更新フラグをONし、全検出位置の到達フラグをクリア。

また、パワーパックの制御(定期割込み処理) の 概要は以下の通り。

  • 操作盤情報取得 : 操作盤の状態を取得し、状態により制御設定値を更新する。
    (Local(制御盤操作) 時)
    制御盤のスイッチ状態を取得する。
    (設定モード時)
    READYスイッチが押下ならWiFi再起動
    (通常モード時)
    出力用ボリューム値取得
    (制御盤操作許可時)
    (走行中ではない時)
    進行方向スイッチをチェックし、変化したらフラグをセット
    READYスイッチをチェックし、押下ならLED常時点灯設定を現在の反対にセット
    STARTスイッチをチェックし、押下ならスタートフラグをセット
    自動走行でない場合は、PWMduty値にボリューム値から計算した値を設定
    (制御盤操作不許可時)
    PWMduty値にOFF状態の値を設定
    ボリュームの値が'0'なら制御盤操作を許可にする。
    (Remote(WEB からの操作) 時)
    READYスイッチをチェックし、押下ならLocalにする。
  • 車両位置情報取得 : センサ()の状態を取得し、車両の位置情報を更新する。
    車両位置検出マスクフラグ更新
    MCP23017割込み状態取得(車両位置検出)
    車両位置検出用変数更新
  • 自動運転制御 : 自動運転設定により、制御盤設定値を自動で更新する。
    発車スイッチチェック
    (発車スイッチがONの時)
    (自動運行実行中ではない時)
    自動運行開始要求をON
    (自動運行実行中の時)
    (発車スイッチ待ちの時)
    設定更新要求をON
    (発車スイッチ待ちではない時)
    停車要求ON
    自動運転開始
    (自動運転開始要求がONの時)
    運転設定No.を1にし、各パラメータをセットする
    加減速要求ON
    通過位置情報をクリア
    ステータスLED値をNo.に設定して点灯ON
    自動運転中フラグをON
    開始時の時刻を取得
    自動運行中の処理
    (自動運転中フラグがONの時)
    (設定更新契機が時間経過の時)
    開始からの時間が運転設定時間以上なら設定更新要求ON
    (設定更新契機が地点通過の時)
    設定地点の到達フラグがONなら設定更新フラグをONし、全到達フラグをクリア
    (設定更新要求ONの時)
    次の有効な設定No.を探す。
    有効な設定No.が無い場合は停車要求をON
    (停車でない場合)
    設定を更新。
    ステータスLED値をNo.に設定して点灯ON
    (加速要求がONの時)
    (PWMduty値が目標値でない場合)
    PWMduty値に加速度設定値を加減算する
    (PWMduty値が目標値の場合)
    加速要求をOFFする
    (停車要求の時)
    (PWMduty値が停車時のdutyより大きい場合)
    PWMduty値から加速度設定値を減算する
    (PWMduty値が停車時のduty以下の場合)
    停車要求をOFFする
    自動運転中フラグをOFFする
    ステータスLED値を停車時の値に設定して点灯ON
    (自動運転中フラグがOFFの時)
    (停車時設定変化時)
    ステータスLED値を停車時の値に設定して点灯ON
    走行中フラグ更新
    PWMdutyの値から走行中の判定をしてフラグをON/OFF
    操作盤制御:更新された制御盤設定値により、走行設定を行う。
    進行方向設定
    ステータスLED制御
    PWMduty設定
    デバッグ用シリアル出力
    デバッグ用にシリアル画面に各種情報を出力する。



2020年9月21日月曜日

ESP32/arduino:WiFi接続時のスマホ画面とPC画面の切り替え

目的:

WiFi接続時、スマホからのアクセス画面をスマホ用にする。(スマホ対応)

背景:

WiFi接続時、スマホから接続した場合に ボタン間隔が狭い等、操作しにくい場合がある。
この為、PCからアクセスした場合とスマホからアクセスした場合で画面表示を変えて操作しやすくする。

方法:

HTML を レスポンシブデザインとして、ウィンドウ幅によりデザインを分ける。
  1. viewportを設定する。
    <head> ~ </head> 部分に、以下の様な metaタグ を記述する。
    <meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0">
    
  2. ウィンドウ幅に応じて styleタグ を分ける。
    以下の様に、styleタグを 分ける。
    <style media="screen and (min-width: 769px)">
     ....  (PC用 設定)
    </style>
    <style media="screen and (max-width:768px)">
     ....  (スマホ用 設定)
     </style>
  3. 必要に応じて、HTML を修正する。 
* ウィンドウ幅で切り替えているため、PC でも ブラウザの幅を狭めれば スマホ用表示になる。

 例:

ESP32/arduino:LED調光_WEBからと外付けのボリュームからを切り替えて調光
をスマホ対応にした 時の画面 と HTML を示す。(スケッチ、レスポンス用HTML は変更なし)
PC用 画面
スマホ用画面
*スマホ時は、全体に間隔を広げ、ラジオボタンの形状を変更している。

<!DOCTYPE html><html lang='ja'>
<head> 
  <meta charset='UTF-8'>
  <meta name="viewport" content="width=device-width,initial-scale=1.0,minimum-scale=1.0">
  <style media="screen and (min-width: 769px)">
       #base          {font-size:16pt;text-align:center;width:300px;border:solid 4px #93ff93; }
       #radio_box     {font-size:12pt;float:left ;text-align:left; width:45%; }
       #disp_box      {font-size:12pt;float:right;text-align:left; width:50%; }
       #brightness    {font-size:12pt;text-align:right; }
       #val_box       {font-size:10pt;text-align:center; clear:both ;}
       #ctl_box       {text-align:center; }
       input.radio    {margin-left:8px; width:30px;}
       input.value    {margin-left:8px; width:30px;}
       input.setbutton{margin-left:8px; width:40px;}
       input.slider   {margin-left:8px; width:250px;}
       input.button   {margin:0px 15px; width:100px;}
  </style>
  <style media="screen and (max-width:768px)">
       #base             {font-size:20pt;text-align:center; width:97%; border:solid 4px #008000; }
       #radio_box        {font-size:18pt;float:left ;text-align:left; width:45%; }
       #disp_box         {font-size:18pt;float:right;text-align:left; width:50%; line-height:30pt; }
       #brightness       {font-size:18pt;text-align:right; }
       #val_box          {font-size:16pt;text-align:center; clear:both ; width:100% ; }
       #ctl_box          {text-align:center; height: 100px }
       input.radio       {margin-left:8px; width:30px; vertical-align:middle ; display:none; }
       input.radio:checked + label.lbl { background: #00FF00 ; color: #FF0080 ; }
       label.lbl         {display:block ; margin: 0px calc(90% - 120px) 10px 10% ; text-align:center ; height:50px; line-height:50px; border: 1px solid #006DD9; border-radius:8px;}
       output.brightness {margin-right:50px }
       input.value       {margin-left:8px; margin-top:30px; width:50px; height:30px ; font-size:16pt; }
       input.setbutton   {margin-left:8px; width:50px; height:30px ; font-size:16pt; }
       input.slider      {margin-top:20px; margin-bottom:20px; width:95%; height:80px }
       input.button      {margin:0px 5% ; width:30%; height:50px ; font-size:18pt; background: #008000 ; color:#ffffff ; }
  </style>
  <title>Color LED Controller</title>
</head>

<body>
<div id="base">
  <p>LED ON/OFF</p>
  <div id="radio_box">
    <form method="get"> 
      <input class='radio' type='radio' name='remote' id="rad_lo" value='local' $checked_lo onclick='disp_ctrl(this.value); submit(this.value)'>
      <label for="rad_lo" class="lbl">Local<br></label>
      <input class='radio' type='radio' name='remote' id="rad_rm" value='remote' $checked_rm onclick='disp_ctrl(this.value); submit(this.value)'>
      <label for="rad_rm" class="lbl">Remote<br></label>
    </form>
  </div>
  <div id="disp_box">
      <span> brightness value</span><br>
      <div id="brightness"><output class='brightness' id="o1">$led_brightness</output></div>
  </div>
  <div id="val_box">
    <form method="get">
      <span > LED brightness (0-255)</span> 
      <input class='value'  type='text' name='led_v' value=$led_brightness id='led_v' disabled>
      <input class='setbutton' type='submit' name='set' id='set' value='SET' disabled>
    </form> 
    <form method='get'> 
      <input class="slider" type="range" name='led_s' id='led_s' value=$led_brightness min="0" max="255" step="1" disabled
        onchange="setval(this.value);" oninput="setval(this.value)"; onmouseup="submit(this.form)": ontouchend="submit(this.form)">
    </form> 
  </div>
  <div id="ctl_box">
    <form method='get'>
      <input class='button' type='submit' name='on' id="on" value='ON' disabled >
      <input class='button' type='submit' name='off' id="off" value='OFF' disabled><br>
    </form>
  </div>
</div>


<script>
var polling = null ;

function setval(ledval){
 var xhr = new XMLHttpRequest();
        xhr.open("get", "?slid="+ledval );
        xhr.setRequestHeader('Cache-Control', 'no-cache');
        xhr.setRequestHeader('If-Modified-Since', 'Thu, 01 Jun 1970 00:00:00 GMT');
        xhr.responseType = 'document' ;

        xhr.onreadystatechange = function() {
          if( (xhr.readyState == 4) && (xhr.status == 200) ) {
            document.getElementById('led_v').value = xhr.response.getElementById("output1").innerHTML;
            document.getElementById('o1').value = xhr.response.getElementById("output1").innerHTML;
          }
        }

        ntimeout = function(e) {
          xhr.abort() ;
        }
        xhr.send();
}


function getval(){
 var xhrget = new XMLHttpRequest();
        xhrget.open("get", "?pol" );
        xhrget.setRequestHeader('Cache-Control', 'no-cache');
        xhrget.setRequestHeader('If-Modified-Since', 'Thu, 01 Jun 1970 00:00:00 GMT');
        xhrget.responseType = 'document' ;

        xhrget.onreadystatechange = function() {
          if( (xhrget.readyState == 4) && (xhrget.status == 200) ) {
            document.getElementById('o1').value = xhrget.response.getElementById("output1").innerHTML;
          }
        }

        ntimeout = function(e) {
          xhrget.abort() ;
        }
        xhrget.send();
}

function disp_ctrl( radioid ) {
   if(radioid == 'remote') {
      document.getElementById('led_v').disabled = false;
      document.getElementById('set').disabled = false;
      document.getElementById('led_s').disabled = false;
      document.getElementById('on').disabled = false;
      document.getElementById('off').disabled = false;
      clearInterval(polling);
   } else {
      document.getElementById('led_v').disabled = true;
      document.getElementById('set').disabled = true;
      document.getElementById('led_s').disabled = true;
      document.getElementById('on').disabled = true;
      document.getElementById('off').disabled = true;
      polling = setInterval(getval,100) ;
   }

}

window.onload = function() {
    if(document.getElementById("rad_rm").checked) {
      document.getElementById('led_v').disabled = false;
      document.getElementById('set').disabled = false;
      document.getElementById('led_s').disabled = false;
      document.getElementById('on').disabled = false;
      document.getElementById('off').disabled = false;
      clearInterval(polling);
    } else if(document.getElementById("rad_lo").checked) {
      document.getElementById('led_v').disabled = true;
      document.getElementById('set').disabled = true;
      document.getElementById('led_s').disabled = true;
      document.getElementById('on').disabled = true;
      document.getElementById('off').disabled = true;
      polling = setInterval(getval,100) ;
    }
}

</script>

</body>
</html>

以下、覚書など。
  ( 行# 4 )
viewportの設定。

  ( 行# 5 ~ 17 )
styleタグに メディア属性を設定。769px 以上の幅の場合は PC画面とし、従来の設定のままとする。但し、行#10 は html 内で font-size を変更していた為、style の設定を変更。

  ( 行# 18 ~ 33 )
スマホ用の styleタグ。
styleタグに メディア属性を設定。768px 以下の幅の場合は スマホ画面とし、スマホ用の設定を記述。
全体に 間隔が広がるように margin、font-size 等の設定を変更。
ラジオボタンの形状変更の為、通常のラジオボタンの表示を消し ( display:none; )、
Label タグ を設定して、"input.radio:checked + label.lbl" (行#26) で、chkeck 時の動作 (Label の 色を変更)

  ( 行# 42 ~ 45 )
スマホ用に ラジオボタンの形状を変更する為、labelタグを追加し、表示文字列は Label で設定。

  ( 行# 50 )
表示位置をずらすため、class の設定を追加。(PC画面には影響なし)

  ( 行# 50 )
font-size を style で設定する為に削除。


2020年9月5日土曜日

verilog : Vivado で SVA(アサーション) を試す 2

目的:

Vivado で SVA を使用した時の 波形表示 や 発火回数 表示 ができるようにする。

概要:

一案として、アサーション記述に Pass/Fail 時の処理を記述し、波形表示を行った。
また、シミュレーション終了時に 発火回数 と FAIL 回数の表示を行った。
Vivado で SVA(アサーション) を試す」のサンプルを修正して確認を行った。

波形表示:

少し面倒ではあるが、アサーション記述に以下の様な処理を記述することで波形に表示できることを確認した。(「Vivado で SVA(アサーション) を試す」の sva_1.sv を修正)
// -----------------------------------------------------
//   Sample module
//
//   Module Name : sva_1
//   Version     : 0.00
// -----------------------------------------------------

module sva_1 ( clk, clr, start, en, outpls) ;
  input clk ;
  input clr ;
  input start ;
  input en ;
  input outpls ;

  // internal signal declaration ---------
  logic [15:0] a_test1_fire ;
  logic [15:0] a_test1_pass = 0 ;
  logic [15:0] a_test1_fail = 0 ;

  assign a_test1_fire = a_test1_pass + a_test1_fail ;

  // sequence description ----------------
  sequence S1 ;
    outpls[*4] ##1 !outpls[*5] ;
  endsequence

  // property description ---------------
  property p_test1 ;
    @(posedge clk ) disable iff(clr)
      $rose(start) |-> ##1 S1[*6] ;
  endproperty

  // assertion description
//  a_test1 : assert property ( p_test1 ) $display("a_test1 : OK") ;
  a_test1 : assert property ( p_test1 ) begin
              a_test1_pass = a_test1_pass + 1 ;
              $display("a_test1 : OK") ;
            end
            else begin
              a_test1_fail = a_test1_fail + 1 ;
              $display("a_test1 : FALE") ;
            end
  endmodule
発火回数、PASS回数、FAIL回数 の変数(信号)を定義し、アサーション記述で PASS回数、FAIL回数をカウントし、「OK」,「FAIL」の画面表示を行う。
発火回数は、PASS回数 + FAIL 回数 とする。
シミュレーション実行後、各回数の変数(信号) が波形で表示でき、値の変化点が PASS, FAIL の ポイント となる。
sva_2.sv も同様に修正する。

終了時の発火等回数の表示:

テストパターンの終了時、各アサーションの発火等の回数を $display で表示する。
// +-------------------------------------------------------------------------+
// | test pattern                                                            |
// |                                                                         |
// |   test name : test_1                                                    |
// +-------------------------------------------------------------------------+
//

initial begin
  #200
  // H:4clk,L:5clk  x 5cycle -----
  @(posedge clk) #1
      pls_start    = 1'b1  ;
      h_width      = 8'd4  ;
      l_width      = 8'd5  ;
      pls_num      = 8'h5  ;
  @(posedge clk) #1
      pls_start    = 1'b0  ;
  @(negedge i_plsgen.plsen)
  #100
  // H:4clk,L:5clk  x 6cycle -----
  @(posedge clk) #1
      pls_start    = 1'b1  ;
      h_width      = 8'd4  ;
      l_width      = 8'd5  ;
      pls_num      = 8'h6  ;
  @(posedge clk) #1
      pls_start    = 1'b0  ;
  @(negedge i_plsgen.plsen)
  #100
  // H:4clk,L:5clk  x 7cycle -----
  @(posedge clk) #1
      pls_start    = 1'b1  ;
      h_width      = 8'd4  ;
      l_width      = 8'd5  ;
      pls_num      = 8'h7  ;
  @(posedge clk) #1
      pls_start    = 1'b0  ;

  @(negedge i_plsgen.plsen)
  #100

  // test end -------------------
  $display ("") ;
  $display ("---- assertion result ------") ;
  $display ("[SVA] a_test1 : fire = %d , FAIL = %d",
                testbench.i_plsgen.i_sva_1.a_test1_fire,
                testbench.i_plsgen.i_sva_1.a_test1_fail ) ;
  $display ("[SVA] a_test2 : fire = %d , FAIL = %d",
                testbench.i_plsgen.i_sva_2.a_test2_fire,
                testbench.i_plsgen.i_sva_2.a_test2_fail ) ;

  $finish ;
  end
終了時に $display で表示する為、最後までシミュレーションが実行されないと回数表示はされない。

出力結果:

 実行結果の波形を以下に示す。
 発火 (PASS, FAIL) したタイミングが波形で判る。

実行結果の LOG を以下に示す。
****** xsim v2020.1 (64-bit)
  **** SW Build 2902540 on Wed May 27 19:54:35 MDT 2020
  **** IP Build 2902112 on Wed May 27 22:43:36 MDT 2020
    ** Copyright 1986-2020 Xilinx, Inc. All Rights Reserved.

source xsim.dir/test_1/xsim_script.tcl
# xsim {test_1} -autoloadwcfg -runall
Vivado Simulator 2020.1
Time resolution is 1 ps
run -all

Time: 1140 ns Started: 220 ns Scope: /testbench/i_plsgen/i_sva_1 File: /mnt/d/UserData/hobby/logic/study/test3/assertion/sva_1.sv Line:36
a_test1 : FALE

Time: 2340 ns Started: 1260 ns Scope: /testbench/i_plsgen/i_sva_1 File: /mnt/d/UserData/hobby/logic/study/test3/assertion/sva_1.sv Line:36
a_test1 : OK

Time: 2360 ns Started: 1260 ns Scope: /testbench/i_plsgen/i_sva_2 File: /mnt/d/UserData/hobby/logic/study/test3/assertion/sva_2.sv Line:36
a_test2 : OK

Time: 3560 ns Started: 2480 ns Scope: /testbench/i_plsgen/i_sva_1 File: /mnt/d/UserData/hobby/logic/study/test3/assertion/sva_1.sv Line:36
a_test1 : OK

Time: 3580 ns Started: 2480 ns Scope: /testbench/i_plsgen/i_sva_2 File: /mnt/d/UserData/hobby/logic/study/test3/assertion/sva_2.sv Line:36
a_test2 : FALE

---- assertion result ------
[SVA] a_test1 : fire =     3 , FAIL =     1
[SVA] a_test2 : fire =     2 , FAIL =     1
$finish called at time : 3841 ns : File "/mnt/d/UserData/hobby/logic/study/test3/testbench/tp.sv" Line 52
exit
INFO: [Common 17-206] Exiting xsim at Fri Sep  4 01:02:27 2020...
~
~

最後に発火回数 と FAIL 回数 が表示されている。

2020年8月28日金曜日

WSL : WSL2 を使用する

目的:

WSL2 を使用できるようにする

概要:

Windows10 バージョン 1909 でも WSL2 が使用できるようになった為、WSL2 に更新にする。
 更新は以下を実施し、WSL2 が使用できることを確認した。
  1. 累積的更新プログラム「KB4566116 」を適用
  2. "仮想マシン プラットフォーム" のオプション コンポーネントを有効にする
  3. WSL2の有効化
  4. ディストリビューションの更新 (Debian を更新)
  5. wsltty を最新版に更新 
  6. GUI 設定 (DISPLAY 変更, VcXsrv 設定変更)

更新手順:

  1. 累積的更新プログラム「KB4566116 」を適用
    「設定」-「更新とセキュリティ」から アップデートを行う。
     
  2. "仮想マシン プラットフォーム" のオプション コンポーネントを有効にする
    1. powershellを管理者権限で起動
      スタートメニューから 「Windows powershell」-「Windows powershell」を右クリックし、「管理者として実行する」を左クリック
    2. "仮想マシン プラットフォーム" のオプション コンポーネントを有効にする
      powershell で次のコマンドを実行
      dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
    3. PS C:\WINDOWS\system32> dism.exe /online /enable-feature /featurename:VirtualMachinePlatform /all /norestart
      
      展開イメージのサービスと管理ツール
      バージョン: 10.0.18362.900
      
      イメージのバージョン: 10.0.18363.1049
      
      機能を有効にしています
      [==========================100.0%==========================]
      操作は正常に完了しました。
      
    4. PC を再起動
      再起動すると、Windows の機能の更新が行われる
       
  3. WSL2の有効化
    WSL2をデフォルトへ設定
    powershell で次のコマンドを実行
    wsl --set-default-version 2
    PS C:\WINDOWS\system32> wsl --set-default-version 2
    WSL 2 との主な違いについては、https://aka.ms/wsl2 を参照してください
      
  4. ディストリビューションの更新
    1. 現在のディストリビューションのバージョンを確認
      powershell で次のコマンドを実行
      wsl --list --verbose
      (更新プログラム適用前は、 --verbose は 使用できない。)
      PS C:\WINDOWS\system32> wsl --list --verbose
        NAME      STATE           VERSION
      * Debian    Stopped         1
        Ubuntu    Stopped         1
      
      debian と ubuntu が あり、共に VERSION 1
    2. ディストリビューションの更新
      ここでは Debian を更新してみる。 powershell で次のコマンドを実行
      wsl --set-version Debian 2
      PS C:\WINDOWS\system32> wsl --set-version Debian 2
      変換中です。この処理には数分かかることがあります...
      WSL 2 との主な違いについては、https://aka.ms/wsl2 を参照してください
      変換が完了しました。
      
    3. 再度バージョンを確認
      wsl --list --verbose
      PS C:\WINDOWS\system32> wsl --list --verbose
        NAME      STATE           VERSION
      * Debian    Stopped         2
        Ubuntu    Stopped         1
      
      debian の VERSION が 2 に変わる。
       
  5. wsltty を最新版に更新
    wsltty を使用している場合、最新版( 現時点で 3.3.0 ) にしないと動作しない。
     
  6. GUI 設定 (DISPLAY , VcXsrv 設定) の変更
    WSL2 では ネットワーク構成が変更されている為、DISPLAY 設定が
    DISPLAY=:0.0
    では エラーが発生する。
    以下の設定に変更する必要がある。
    export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}'):0
    また、VcXsrv設定で,
    「Additional parameters for VcXsrv」(設定画面 3画面目) に -ac を入力する。
以上で、Debian が WSL2 が使用できるようになった。

尚、Ubuntu は 更新していないため、従来の WSL で起動した。

その他:

(2020/08/30 追記)

ネットワークドライブアクセス不可

現象:
 ネットワークドライブ 2つの内、1つへのアクセスができなくなった。
 アクセスできなくなったのは NAS( SMB1.0)。
 Raspbery pi のディスク ( SMB 2 ?) は アクセスできている。
対応:
  1.  WSL2 に cifs-utils をインストール
    sudo apt install cifs-utils
  2.  /etc/fstab を修正
    NAS の マウントの設定を以下の様にして  drvfs から cifs に 変更
    //サーバー名/共有名 /mnt/<マウント先ディレクトリ名> cifs vers=1.0,username=<ユーザ名>,password=<パスワード>,iocharset=utf8,rw,uid=1000,gid=1000,defaults 0 0
  3. ディストリビューションの再起動
    パワーシェル から WSL 終了コマンドを入力 後、起動し、起動時にマウントされることを確認する。
    wsl -t <ディストリビューション名>
これで、Debian は アクセス可能になった。
但し、WSL1 にすると、cifs での アクセスはできなくなる。
Ubuntu も同様にしたが、起動時に マウントができていない。
sudo mount -a
ではマウントできる。対応調査中

2020年8月16日日曜日

verilog : Vivado で SVA(アサーション) を試す

目的:

Vivado で SVA を使用してみる。

結果:

Vivado で SVA 並列アサーション を記述し、アサーションができることを確認した。
  • 2021/11/4 追記
    とくに問題なくアサーションできている。
  • 2020/10/16 追記
    前回から30日以上経過しているが、アサーション結果表示できている。
  • 2020/09/04 追記
    再実行で アサーションの表示が また 出力されるようになった。
    先日、Windows版の vivado を Update したが、この影響か ?
  • 2020/08/29 追記
    再実行したところ、アサーションの表示が 出力されない。
    WEB PACK ではサポートされず、30日間無償評価で使用できていたと思われる。
但し、
  1.  property に 引数 を付けるとエラー が発生する。
  2. アサーションの結果は 波形には表示されない。
  3. アサーションの結果は Fail 時 のみ ログ, ディスプレイ に表示される。
    ( 特に処理の記述を行わない場合 )
となる。
以下のパターンで試しただけなので、他にも注意点があるかもしれないし、上の点も 設定, 記述方法等があるかもしれないが、SVA は使用可能。
(尚、波形への表示については「Vivado で SVA(アサーション) を試す 2」を参照。)

SVA 適用手順:

Vivado の コマンドラインでのシミュレーション環境 をベースに SVA を適用した。
( SVA 適用後の サンプルは こちら を参照。)
  1. ディレクトリ構成
    アサーション格納用として assertion ディレクトリを作成
  2. アサーション用ファイルの作成
    アサーション用ファイルとして
    1. SVA ファイル ( アサーション記述のモジュール )
    2. bind ファイル ( SVA のモジュールを rtl に接続する記述 )
    3. bind リスト ( bind ファイルを インクルードする為の リスト )
    を作成する。
  3. bind ファイルのインクルード
    テストベンチに 上 の bind リスト を インクルードする。
  4. プロジェクトファイル (vlog.prj) 修正
    vlog.prj に SVA ファイル を追加する。
以上で、SVA が適用される。

SVA 適用例:

SVA 適用例を以下に示す。
  1. テストベンチ ( Vivado の コマンドラインでのシミュレーション環境からの差分 )
      end
    
    // include test patteern  ------------
    `include "tp.sv"
    
    // include assertion bind list -------
    `include "./assertion/bind.list"
    
    
    endmodule
    

  2. bind リスト
    `include "./assertion/bind_sva.sv"
    
    bind ファイルのインクルード文を記述する。
     
  3. bind ファイル
    bind testbench.i_plsgen sva_1 i_sva_1(
      .clk    (clk),
      .clr    (clr),
      .start  (pls_start),
      .en     (plsen),
      .outpls (output_pls)
    ) ;
    
    bind testbench.i_plsgen sva_2 i_sva_2(
      .clk    (clk),
      .clr    (clr),
      .start  (pls_start),
      .en     (plsen),
      .outpls (output_pls)
    ) ;
    
    ここでは、 2つのアサーションファイルをバインドしている。
    それぞれ RTL (i_plsgen) にバインド
    testbench には バインドできない ?
     
  4. SVA ファイル
    アサーションファイルを以下に示す。
    尚、アサーションの適不適は不問とする。
    ( RTL は パルス生成回路 )
    // -----------------------------------------------------
    //   Sample module
    //
    //   Module Name : sva_1
    //   Version     : 0.00
    // -----------------------------------------------------
    
    module sva_1 ( clk, clr, start, en, outpls) ;
      input clk ;
      input clr ;
      input start ;
      input en ;
      input outpls ;
    
      // sequence description ----------------
      sequence S1 ;
        outpls[*4] ##1 !outpls[*5] ;
      endsequence
    
      // property description ---------------
      property p_test1 ;
        @(posedge clk ) disable iff(clr)
          $rose(start) |-> ##1 S1[*6] ;
      endproperty
    
      // assertion description
      a_test1 : assert property ( p_test1 ) ;
    
      endmodule
    
    sva_1 は、 start 信号の立ち上がりの次クロックから、"H 4サイクル, L 5サイクル"のシーケンスを 6回繰り返すことをチェックする。
     
    // -----------------------------------------------------
    //   Sample module
    //
    //   Module Name : sva_2
    //   Version     : 0.00
    // -----------------------------------------------------
    
    module sva_2 ( clk, clr, start, en, outpls) ;
      input clk ;
      input clr ;
      input start ;
      input en ;
      input outpls ;
    
      // sequence description ----------------
      sequence S1 ;
        outpls[*4] ##1 !outpls[*5] ;
      endsequence
    
      // property description ---------------
      property p_test2 ;
        @(posedge clk ) disable iff(clr)
          $rose(start) |-> ##1 S1[*6] |-> ##1 $fell(en) ;
      endproperty
    
      // assertion description ---------------
      a_test2 : assert property ( p_test2 ) ;
    
      endmodule
    
    sva_2 は、 start 信号の立ち上がりの次クロックから、"H 4サイクル, L 5サイクル"のシーケンスを 6回繰り返した後、次サイクルで en が 立ち下がることをチェックする。
    尚、sva_1, sva_2 の 2ファイルに分ける必要は無いが (通常は 1つのファイル(モジュール) に a_test1 と a_test2 の 両方を記述する) 、サンプルの為 2つのファイルに分けている。
      
  5. プロジェクトファイル (vlog.prj)
    verilog xil_defaultlib  \
    "./rtl/plsgen.v" \
    "./rtl/D_CNT.v" \
    
    sv xil_defaultlib  \
    "./testbench/testbench.sv" \
    "./testbench/param.sv" \
    "./assertion/sva_1.sv" \
    "./assertion/sva_2.sv" \
    
    verilog xil_defaultlib "/tools/Xilinx/Vivado/2020.1/data/verilog/src/glbl.v"
    
    プロジェクトファイルに sva_1.sv, sva_2.sv を追加する。
     

SVA 適用結果:

SVA 適用後の シミュレーション実行結果を以下に示す。
****** xsim v2020.1 (64-bit)
  **** SW Build 2902540 on Wed May 27 19:54:35 MDT 2020
  **** IP Build 2902112 on Wed May 27 22:43:36 MDT 2020
    ** Copyright 1986-2020 Xilinx, Inc. All Rights Reserved.

source xsim.dir/test_1/xsim_script.tcl
# xsim {test_1} -autoloadwcfg -runall
Vivado Simulator 2020.1
Time resolution is 1 ps
run -all
ERROR: Assertion failed.
Time: 1140 ns Started: 220 ns Scope: /testbench/i_plsgen/i_sva_1 File: /mnt/d/UserData/hobby/logic/study/test3/assertion/sva_1.sv Line:28
ERROR: Assertion failed.
Time: 3580 ns Started: 2480 ns Scope: /testbench/i_plsgen/i_sva_2 File: /mnt/d/UserData/hobby/logic/study/test3/assertion/sva_2.sv Line:28
$finish called at time : 3841 ns : File "/mnt/d/UserData/hobby/logic/study/test3/testbench/tp.sv" Line 42
exit
INFO: [Common 17-206] Exiting xsim at Sun Aug 16 15:08:32 2020...
この時の波形

テストパターンは、3回 パルスを生成。
1回目は "H" 4 クロック, "L" 5クロック を 5回繰り返し
 6回目の"H" が無い為、a_test1 が Fail
 a_test2 は 6回目 の "H" が無く 前提部が不成立の為、発火しない。(Fail しない)
2回目は H4 クロック, L5クロック を 6回繰り返し
 a_test1, a_test2 共に 発火し、Pass。

3回目は H4 クロック, L5クロック を 7回繰り返し
 6回目の "H" がある為、a_test1 は発火し、Pass
 6回目の "H"→"L" の後 7回目が開始し、en (plsen) が 立ち下がらない為、Fail
期待通り、1回目, 3回目 のパルス生成で Fail し、エラー出力されている。

発火確認:

上の結果では、Fail した場合は ERROR 表示されるが、Fail しない場合は 何も表示されない。
この為、Pass したのか 発火しなかったのかの区別がつかない。
発火した場合に表示する様に SVA ファイルを修正してみる。
  // assertion description
  a_test1 : assert property ( p_test1 ) $display("a_test1 : OK") ;

  endmodule
  // assertion description ---------------
  a_test2 : assert property ( p_test2 ) $display("a_test2 : OK") ;

  endmodule
assert文 に 処理 ($display 等) を追加する。
処理追加後の結果は下の通り。

****** xsim v2020.1 (64-bit)
  **** SW Build 2902540 on Wed May 27 19:54:35 MDT 2020
  **** IP Build 2902112 on Wed May 27 22:43:36 MDT 2020
    ** Copyright 1986-2020 Xilinx, Inc. All Rights Reserved.

source xsim.dir/test_1/xsim_script.tcl
# xsim {test_1} -autoloadwcfg -runall
Vivado Simulator 2020.1
Time resolution is 1 ps
run -all
ERROR: Assertion failed.
Time: 1140 ns Started: 220 ns Scope: /testbench/i_plsgen/i_sva_1 File: /mnt/d/UserData/hobby/logic/study/test3/assertion/sva_1.sv Line:28

Time: 2340 ns Started: 1260 ns Scope: /testbench/i_plsgen/i_sva_1 File: /mnt/d/UserData/hobby/logic/study/test3/assertion/sva_1.sv Line:28
a_test1 : OK

Time: 2360 ns Started: 1260 ns Scope: /testbench/i_plsgen/i_sva_2 File: /mnt/d/UserData/hobby/logic/study/test3/assertion/sva_2.sv Line:28
a_test2 : OK

Time: 3560 ns Started: 2480 ns Scope: /testbench/i_plsgen/i_sva_1 File: /mnt/d/UserData/hobby/logic/study/test3/assertion/sva_1.sv Line:28
a_test1 : OK
ERROR: Assertion failed.
Time: 3580 ns Started: 2480 ns Scope: /testbench/i_plsgen/i_sva_2 File: /mnt/d/UserData/hobby/logic/study/test3/assertion/sva_2.sv Line:28
$finish called at time : 3841 ns : File "/mnt/d/UserData/hobby/logic/study/test3/testbench/tp.sv" Line 42
exit
INFO: [Common 17-206] Exiting xsim at Sun Aug 16 16:19:29 2020...

実行結果は、
1回目 (started: 220nS) は a_test1 Fail し、a_test2 は発火なし。
2回目 (started: 1260nS) は a_test1, a_test2 共に発火し、Fail なし。
3回目 (Started: 2480nS) は a_test1 は発火して Failなし, a_test2 は Fail。
となり、発火したことを確認できる。

できれば、波形に 表示されるといいのだが、、、
 → 表示案 : Vivado で SVA(アサーション) を試す 2 

2020年8月14日金曜日

verilog : Vivado の コマンドラインでのシミュレーション環境

目的:

Vivado のシミュレーション をコマンドラインで 実行する環境を作る 。
 ( Icarus Verilog と同様な環境でシミュレーションできるようにする )


概要:

Ivarus Verilog 用に作成した環境と同様の環境とする。

ディレクトリ構成

以下の様にディレクトリを分ける。
rtl         : 論理合成可能な RTL を格納する
testbench   : テストベンチ を格納する
testpattern : テストパターン を格納する。
log         : コンパイル,シミュレーション時の LOG を格納する。
xsim_dir    : コンパイル時に生成される作業ディレクトリ。
wave        : シミュレーション結果の波形ファイルを格納する。

コンパイル, シミュレーション実行

カレントディレクトリに Makefile、vlog.prj を作成し、
make TESTNAME=test_1
の様に テストパターンを指定してコンパイル、シミュレーションを実行できる様にする。
コンパイル、シミュレーション時に実行 LOG を log ディレクトリ下に生成/移動する。
シミュレーション結果の波形は、wave ディレクトリに 移動した <TESTNAME>.vcd を gtkwave 等で確認する。

vlog.prj は、verilog のファイル構成を記したファイル。
コンパイル、シミュレーションは vivado のプロジェクトは作成せず、コマンド実行のみで行う。

詳細:

ディレクトリ構成は、概要の通り。
サンプルの環境は こちら を参照。(rtl, testbench の内容についての説明は省略)
サンプルは パルス生成回路。
テストパターンは test_1. sv と test_2.sv
make TESTNAME=test_1
make TESTNAME=test_2
でそれぞれ異なるパルス出力 (output_pls) が発生。

尚、vivado のインストールは、
Windows : WSL に Vivado をインストールする
を参照。

テストベンチ構成

テストパターン(項目) に依存しない共通部分を testbench.sv に記述。
テストパターン(項目)毎の記述は、パターンごとにファイルを作成し、testpattern ディレクトリに格納する。
make 実行時に、実行するテストパターン(項目)のファイルを testbench ディレクトリにtp.sv のファイル名でコピーし、testbench.sv から include で 呼び出す。

vlog.prj 例

vlog.prj は、以下を記述する。
verilog <work_library> <file_names>...
sv <work_library> <file_names> ...
verilog xil_defaultlib  \
"./rtl/plsgen.v" \
"./rtl/D_CNT.v" \

sv xil_defaultlib  \
"./testbench/testbench.sv" \
"./testbench/param.sv" \

verilog xil_defaultlib "/tools/Xilinx/Vivado/2020.1/data/verilog/src/glbl.v"
* /tools/Xilinx/ は、Vivado をインストールしたディレクトリ
vlog.prj にvhdl のソースを記述する。
verilog のファイルは verilog に、SystemVerilog のファイルは sv に記述する。
また、glbl.v を記述する必要がある。


Makefile 例

# ==============================================

TESTNAME = default

# -- SHELL setting -------------------------
SHELL=/bin/bash -o pipefail

# -- dir setting ---------------------------
TBDIR  = ./testbench
TPDIR  = ./testpattern
WAVE   = ./wave
LOG    = ./log

# -- compile option ------------------------
VLOGOPT  = -log $(LOG)/xvlog.log
VLOGOPT += -prj vlog.prj

ELABOPT  = -timescale 1ns/100ps
ELABOPT += -log $(LOG)/xelab.log
ELABOPT += -debug typical
ELABOPT += -L xil_defaultlib

# -- simulation option ---------------------
SIMOPT   = -log $(LOG)/simulate.log
SIMOPT  += -R

# -- wave file name ------------------------
VCD_NAME = wave.vcd

# -- Description ---------------------------
all : clean comp  sim

comp :
 # --- testpattern copy to tp.sv ----------------------------
ifeq ($(TESTNAME),default)
 echo >| $(TBDIR)/tp.sv
else
 cp $(TPDIR)/$(TESTNAME).sv $(TBDIR)/tp.sv
endif
 # --- analysis ---------------------------------------------
 xvlog $(VLOGOPT) 2>&1 | tee $(LOG)/comp.log
 # --- elaborate --------------------------------------------
 xelab $(ELABOPT) xil_defaultlib xil_defaultlib.testbench  -s $(TESTNAME) 
 # --- move log file ----------------------------------------
 mv *.pb $(LOG)/. 2> /dev/null ; true
 mv webtalk.* $(LOG)/. 2> /dev/null ; true

sim :
 # --- simulation -------------------------------------------
 xsim $(SIMOPT) $(TESTNAME)
 # --- move log file ----------------------------------------
 mv *.log $(LOG)/. 2> /dev/null ; true
 mv *.jou $(LOG)/. 2> /dev/null ; true
 # --- move wave file ----------------------------------------
 mv *.wdb $(WAVE)/. 2> /dev/null ; true
 mv $(VCD_NAME ) $(WAVE)/$(TESTNAME).vcd

clean :
 rm $(LOG)/* 2> /dev/null ; true

Make file 内容
TESTNAME : テストパターンファイル名の拡張子を除いた部分。初期値として "default" を設定。
SHELL setting :Shell 設定。パイプ中でのエラーコードを返す様にする。
dir setting : 各ディレクトリ名を設定。
compile option : コンパイルオプション (xvlog, xelab のオプション )を指定する。simulation option : シミュレーションオプション (xsim のオプション)を指定する。
wave file name : 波形ファイル名。(テストベンチに記述しているファイル名)Description : make での 実行内容。

実行方法
make TESTNAME=<テストパターンファイル名(拡張子を除く)
で、テストパターンファイルに記述したテスト内容で コンパイル、シミュレーションし、gtkwave を起動する。
実行は、
  1. log ファイル を消去する。
  2. コンパイルを以下の順に行う。
    1. テストパターン ファイルを tp.sv のファイル名で testbench ディレクトリにコピーする。
      TESTNAME を指定しない場合( make のみで実行 ) は、空の tp.sv を作成する。
    2. コンパイル (xvlog) を実行する。
    3. エラボレーション (xelab) を実行する。
    4. ログファイルを LOGディレクトリに移動する。
  3. シミュレーション (xsim) を実行する。
    実行後、ログファイルを ログディレクディレクトリに移動する。
    また、結果 (波形ファイル wave.vcd) を wave ディレクトリ下に <テストパターン名>.vcd として移動する。
の順に行う。
波形の確認は gtkwave で行う。wave ディレクトリで、
gtkwave <テストパターン名>.vcd



2020年8月11日火曜日

WSL : WSL に Vivado をインストールする

目的:

WSL (Debian) に Vivado をインストールする。
 

結果:

CUI でインストールすることで、Vivado をインストールすることができた。
但し、
  1. コンパイル時など、スタックサイズを変更できない旨の Warning が発生。
    ( WSL では スタックサイズの変更はできないらしい )
    ( WSL2 では Warning は発生しない ) * 2020/08/28 追記
  2. Debian は 公式サポートされていない。 できれば、Ubuntu 等の方が良いかも。
  3. 作業ディレクトリを NAS上にすると、ファイルがコピーできない、ファイルが無い等のエラーでコンパイルできない。Dドライブ等の内臓ディスク上は OK。

    (マウントの仕方が悪い ?  vi 等では普通に編集かのうだが、、)

インストール手順:

  1. インストーラをダウンロードする。(Windows)
    ダウンロードする為には、アカウントを作成する必要が有る。

GUIインストールの場合

  1. Xサーバを起動する。(Windows)
  2. ダウンロードしたインストーラを起動する。(WSL)
    (Windows で d:\download\xilinx に ダウンロードした場合の例)
    cd /mnt/d/download/xilinx
    ./Xilinx_Unified_2020.1_0602_1208_Lin64.bin

    自環境(Debian) では インストーラのGUI は開かず、下の様なメッセージが発生。
    Exception in thread "SPLASH_LOAD_MESSAGE" java.lang.IllegalStateException: no splash screen available
            at java.desktop/java.awt.SplashScreen.checkVisible(Unknown Source)
            at java.desktop/java.awt.SplashScreen.getBounds(Unknown Source)
            at java.desktop/java.awt.SplashScreen.getSize(Unknown Source)
            at com.xilinx.installer.gui.H.run(Unknown Source)
    Exception in thread "main" java.lang.IllegalStateException: no splash screen available
            at java.desktop/java.awt.SplashScreen.checkVisible(Unknown Source)
            at java.desktop/java.awt.SplashScreen.close(Unknown Source)
            at com.xilinx.installer.gui.G.b(Unknown Source)
            at com.xilinx.installer.gui.InstallerGUI.G(Unknown Source)
            at com.xilinx.installer.gui.InstallerGUI.e(Unknown Source)
            at com.xilinx.installer.api.InstallerLauncher.main(Unknown Source)
    
    この為、CUI でインストールを行った。
    また、Debianでのインストールの為、以下のメッセージ(ダイアログボックス)が表示された。
    尚、Ubuntu の WSL で試したところ、GUI のインストーラが起動した。
    ( インストーラが起動するまで 数分 かかった。)
    Ubuntu でのインストールは行わなかったが、インストーラに従えばGUIで インストールできると思われる。

CUIインストールの場合


  1. インストーラの抽出
    --noexec  --target <抽出ディレクトリ> のオプションを付けてインストーラを起動する。
    [Windows で d:\download\xilinx に ダウンロードした場合の例:]
    cd /mnt/d/download/xilinx
    ./Xilinx_Unified_2020.1_0602_1208_Lin64.bin --noexec --target ~/xilinx-installer
    これで、~/xilinx-installer ディレクトにインストール用ファイルが抽出される。
  2. ユーザ名、パスワードの入力
    抽出されたディレクトリに移動し、 ./xsetup -b AuthTokenGen を実行する。
    cd ~/xilinx-installer
    ./xsetup -b AuthTokenGen
    で、User ID, Password ( Xilinx のアカウント登録した ID(メールアドレス) と パスワード) を入力する。
    ( ./xsetup コマンド 実行してから UserID, Password 入力まで 数分 かかった。
     以降、コマンド入力後、気長に待つ必要あり。(環境に依存するかも) )
  3. 設定ファイルの作成
    ./xsetup -b ConfigGen
    で、インストール用の設定ファイルを作成する。
    実行すると以下の様な選択項目が表示されるため、選択する。
    Select a Product from the list: に Vivado (2) を選択
    Select an Edition from the list: に WebPACK (1) を選択
    選択後、設定ファイルのパス,ファイル名 が表示される。
  4. 設定ファイルの編集
    3. で生成された設定ファイル (テキストファイル) を編集する。
    ( 今回は、インストール先を  /tools/Xilinx  に修正した。 )
  5. インストールの実行
    sudo ./xsetup --agree XilinxEULA,3rdPartyEULA,WebTalkTerms --batch Install --config <設定ファイルのパス/ファイル名>
    で、Vivado のダウンロートとインストールを開始する。
    2020.1 での ダウンロードサイズ は 16.12GB だった。

    インストール終了後、Xilinx Information Center が起動したため、
     [File] → [Exit]  で、これを閉じた。

Vivado 実行:

以下の様に、インストールディレクトリの settings64.sh を ソースし、vivado を実行する。( インストール先 : /tools/Xilinx, Ver 2020.1 の場合 )
source /tools/Xilinx/Vivado/2020.1/settings64.sh
vivado

vivado の実行で、GUI で Vivado が起動する。

2020年8月4日火曜日

raspberry pi : NFSサーバーのインストール

目的:

NFSサーバーをインストールし 接続した USB HDD を NFS で共有できるようにする。

手順:

以下の手順で nfs-kernel-server をインストールし、共有ディレクトリの設定を行う。
  1. パッケージリストの更新、パッケージのアップデートを行う。
    sudo apt update
    sudo apt upgrade
     
    この時、カーネルの更新が行われた場合は、再起動する。
    sudo reboot
     
  2. nsf-kernel-server のインストールを行う。
    sudo apt install nfs-kernel-server
     
  3. /etc/export を編集し、共有ディレクトリを設定する。
    sudo vi /etc/exports

    以下の書式でディレクトリを追記する。
    <共有ディレクトリ> <ホスト1>(オプション) <ホスト2>(オプション) …

    例:
    /mnt/hdd1 192.168.1.0/255.255.255.0(rw,sync)

  4. 設定を反映する
    exportfs -ra

以上で、NFSサーバーのインストール、設定は終了。

クライアント側の設定については、
  Windows10の場合 はこちら
  WSL では NFS クライアント は使用できなさそう。


/etc/export 書式 :

<共有ディレクトリ> <ホスト1>(オプション) <ホスト2>(オプション) …

<共有ディレクトリ>
共有させたいディレクトリを記載
<ホスト>
共有ディレクトリにアクセスするクライアントを記載
ホスト名, IPアドレス, IPネットワーク  等を記載
IPネットワークは、
192.168.1.0/24
192.168.1.0/255.255.255.0
の様な形式。
(オプション)
主なオプションを以下に示す。
rw             : 読み出し、書き込み 可能
ro             : 読み出し専用 (default)
sync           : 同期書き込みを有効にする (default)
async          : 非同期書き込み(遅延書き込み)を有効にする
root_squash    : root としての書き込みを行わない様にする。(default)
                 (rootのuidとgidをanonymousのuidとgidに割り当てる。)
no_root_squash : root_squashを無効にする。
all_squash     : すべてのuidとgidをanonymousのuidとgidに割り当てる。
anonuid=uid    : anonymousに割り当てるuidを指定する。
anongid=gid    : anonymousに割り当てるgidを指定する。
secure         : 1023番以前のポートの接続のみ許可する。 (default)
insecure       : 1024番以降のポートの接続も許可する。


Windows10 : NFSクライアントのインストール

目的:

Windows10 に NFSクライアント をインストールし、Linux に接続した USB HDD を NFS で共有できるようにする。

手順:

以下の手順で NFSクライアント を有効化し、NFS アクセスの設定を行う。
  1. NFS クライアントの有効化
    1. スタート(画面左下) を右クリックし、「アプリと機能」を押下
    2. 右上 関連設定 の 「プログラムと機能」を押下
    3. 左側にある 「Windowsの機能の有効化または無効化」を押下
    4. 「NFS用サービス」の 「NFSクライアント」にチェックをして、「OK」を押下
       
  2. マウント
    1. スタート(画面左下) を右クリックし、「コマンドプロンプト」を押下
      (管理者権限ではない方)
    2. mount <NFSサーバ>:<exportディレクトリ> <マウントドライブ>
      で、NFSサーバーのディレクトリをマウントする。
      例:
      mount 192.168.1.91:/mnt/hdd1 w:¥

  3. アンマウント
    1. umount <マウントドライブ>
      例:
      umount w:¥

アクセス時の uid, gid:

マウント時の uid, gid を指定するには、¥Windows¥System32¥drivers¥etc ディレクトリに passwd ファイル, group ファイルを 作成する必要がある。
作成しない場合の uid, gid は 適当な値(?) になっている。
uid, gid の指定は、以下の様な ファイルを作成して行う。

uid :

¥Windows¥System32¥drivers¥etc¥passwd
に、
<Windows ユーザ名>:x:<uid>:<gid>:<コメント>::
の形式で記入する。
例: (Windows ユーザ名=hoge, uid=1001, gid=1001 の場合)
hoge:x:1001:100:hoge::

gid :

¥Windows¥System32¥drivers¥etc¥group
に、
<Windows 所属グループ名>:x:<gid>:
の形式で記入する。
例: (Windows ユーザ名=Administrators, gid=1001 の場合)
BUILTIN¥Administrators:x:1001:
( Administrators の場合は、前に BUILTIN¥ を付ける )

passwd, group ファイルを作成/保存したら、内容を反映させる為に 一度 アンマウント して、再度 マウント を行う。

以上

2020年7月28日火曜日

WSL : WSL の停止、起動 の 方法

目的:
WSL の停止, 起動 の方法を記す。

手順:
管理者権限で PowerShell  を 起動し、以下のコマンドを実行する。
WSL 停止 : net stop LxssManager
WSL 起動 : net start LxssManager

管理者権限の PowerShell は、「Start」メニュー の
「Windows PowerShell」- 「Windows PowerShell」
を右クリックし、「管理者として実行する」を選択して 起動する。

2020年7月26日日曜日

verilog : Icarus Verilog でのシミュレーション環境

目的:

Icarus Verilog でのシミュレーション環境を構築する。


背景:

  1. rtl, テストベンチ,コンパイル結果,波形ファイル等を同じディレクトリに混在させたくない。
  2. 異なる テストパターン でのシミュレーションを手軽に実行したい。
  3. シミュレーション時のコマンド入力を簡単にしたい。
これらの為、シミュレーション環境の整備を行う。尚、以下は、現時点での自環境の例を示す。

概要:

ディレクトリ構成


以下の様にディレクトリを分ける。
rtl         : 論理合成可能な RTL を格納する
testbench   : テストベンチ を格納する
testpattern : テストパターン を格納する。
log         : コンパイル,シミュレーション時の LOG を格納する。
sim_work    : コンパイル結果等の 中間ファイルを格納する。
wave        : シミュレーション結果の波形ファイルを格納する。

コンパイル, シミュレーション実行

Makefile を作成し、
make TESTNAME=test_1
の様に テストパターンを指定してコンパイル、シミュレーションを実行できる様にする。
コンパイル、シミュレーション時に実行 LOG を log ディレクトリ下に生成/移動する。

詳細:

ディレクトリ構成は、概要の通り。
サンプルの環境は こちら を参照。(rtl, testbench の内容についての説明は省略)
サンプルは パルス生成回路。
テストパターンは test_1. sv と test_2.sv
make TESTNAME=test_1
make TESTNAME=test_2
でそれぞれ異なるパルス出力 (output_pls) が発生。

尚、icarus verilog,  gtkwave のインストールは、
コンパイル/シミュレーション環境のインストール (WSL)
を参照。

テストベンチ構成

テストパターン(項目) に依存しない共通部分を testbench.sv に記述。
テストパターン(項目)毎の記述は、パターンごとにファイルを作成し、testpattern ディレクトリに格納する。
make 実行時に、実行するテストパターン(項目)のファイルを testbench ディレクトリにtp.sv のファイル名でコピーし、testbench.sv から include で 呼び出す。

Makefile 例

# ==============================================

TESTNAME = default

# -- SHELL setting -------------------------
SHELL=/bin/bash -o pipefail

# -- dir -----------------------------------
RTLDIR = ./rtl
TBDIR  = ./testbench
TPDIR  = ./testpattern
OUTDIR = ./sim_work
WAVE   = ./wave
LOG    = ./log

# -- rtl source ----------------------------
RTL  = $(RTLDIR)/plsgen.v
RTL += $(RTLDIR)/D_CNT.v

# -- testbench source ----------------------
TESTBENCH  = $(TBDIR)/testbench.sv

# -- compile option ------------------------
CMPOPT  = -g 2012
# CMPOPT += -v

# -- simulation option ---------------------
SIMOPT   = -l $(LOG)/simlog.log

# -- compile file name ---------------------
CMP_NAME = work

# -- wave file name ------------------------
VCD_NAME = wave.vcd

# -- Description ---------------------------
all : pre comp sim wav

pre :
ifeq ($(TESTNAME),default)
 echo >| $(TBDIR)/tp.sv
else
 cp $(TPDIR)/$(TESTNAME).sv $(TBDIR)/tp.sv
endif

comp :
 iverilog $(CMPOPT) -o $(OUTDIR)/$(CMP_NAME) $(TESTBENCH) $(RTL) 2>&1 | tee $(LOG)/comp.log

sim :
 vvp $(SIMOPT) $(OUTDIR)/$(CMP_NAME)
 mv $(VCD_NAME)  $(WAVE)/$(TESTNAME).vcd

wav :
 gtkwave $(WAVE)/$(TESTNAME).vcd

clean :
 rm -f $(LOG)/*
 rm -f $(OUTDIR)/*

Make file 内容
TESTNAME : テストパターンファイル名の拡張子と除いた部分。初期値として "defaule"を設定。
SHELL setting :Shell 設定。パイプ中でのエラーコードを返す様にする。
dir : 各ディレクトリ名を設定。
rtl source : ここに コンパイルする RTL を列挙する。
testbench source : ここに テストベンチ の RTL を列挙する。
compile option : コンパイルオプション (iverilog のオプション )を指定する。
simulation option : シミュレーションオプション (vvp のオプション)を指定する。
compile file name : コンパイル結果のファイル名。
wave file name : 波形ファイル名。(テストベンチに記述しているファイル名)
Description : make での 実行内容。

実行方法
make TESTNAME=<テストパターンファイル名(拡張子を除く)
で、テストパターンファイルに記述したテスト内容で コンパイル、シミュレーションし、gtkwave を起動する。
実行は、
  1. テストパターン ファイルを tp.sv のファイル名で testbench ディレクトリにコピーする。
    TESTNAME を指定しない場合( make のみで実行 ) は、空の tp.sv を作成する。
    (pre)
  2.  コンパイル (iverilog) を実行する。
    この時、出力を log 下にも ファイル(comp.log) として出力する。
  3. シミュレーション (vvp) を実行する。
    実行時の log を log 下に sim.log として出力する。
    結果 (波形ファイル wave.vcd) を wave ディレクトリ下に <テストパターン名>.vcd として移動する。
  4. gtkwave で <テストパターン名>.vcd を開く。
の順に行う。

2020年7月24日金曜日

Windows : キーボード入力が切り替わる

目的:

キーボード入力が英語キーボードに切り替わる原因と対策を記す

背景:

キーボードがいつの間にか英語キーボード 変わっていて、記号等が期待通りに入力できなくなった。

原因:

EXCEL で図形の編集を行った際に SHIFT, ALT の同時押しを行った事で キーボード入力が切り替わったと思われる。

Windows10 では Default で "左Alt + shift" が キーボード入力切り替えのホットキー に割り当てられている。

Excel では、 図形の移動時に
 shift キー : 水平/垂直 移動時に使用
 alt キー   : 図形を セルに合わせる時に使用
し、shift と alt を 同時に使用することも可能。

この為、"左Alt + shift" を押下した時にキーボード入力が切り替わった。
(図形を選択してから "左Alt + shift" 押下なら切り替わらない ? )


対策:

キーボード入力切り替えのホットキー割り当てを解除する。

手順

  1. タスクバー左下の 「スタート」を右クリックし、「設定」押下
  2. 「デバイス」-「入力」-「キーボードの詳細設定」-「入力言語のホットキー」で「テキストサービスと入力言語」のウィンドウを表示
  3. 「入力言語を切り替える」を選択し、「キーシーケンスの変更(C)...」を押下
  4. 「入力言語の切り替え」を「割り当てなし」にして 「OK」を押下


2020年7月22日水曜日

WSL : WSL で Network ドライブをマウントする

目的:
WSL で ネットワークドライブをマウントする

手順:
  1. マウントポイントを作成する
    cd /mnt
    sudo mkdir <マウントディレクトリ>

    例 : nwdrv1 という名前のマウントポイント(ディレクトリ) を作成。
    sudo mkdir nwdrv1
     
  2. ネットワークドライブをマウントする。
    sudo mount -t drvfs <デバイス名> <マウントポイント>

    例 : \\hogehoge\hoge を /mnt/nwdrv1 にマウントする
    sudo mount -t drvfs '\\hogehoge\hoge' /mnt/nwdrv1
     ( \ が含まれる場合、 ’ で括る )

    -t drvfs は マウントするデバイスのタイプで、WSL での Windows のドライブタイプ
     
  3. マウントポイントのシンボリックリンクを 適当な場所に作成する。
    ln -s <マウントポイント下 の任意のディレクトリ>

    例 : ホームディレクトリ (~/.) で
    ln -s /mnt/nwdrv1/abc
    で、ホームディレクトリに abc ディレクトリ(シンボリックリンク) ができる。
     (abc は ネットワークドライブに存在するディレクトリ)

    シンボリックリンクを作成しなくても良いが、ホームディレクトリの下 などに作成しておくと、アクセスが楽。
     
  4. /etc/fstab に設定して自動マウントする様にする。
    sudo /etc/fstab
    で、
    <デバイス名> <マウントポイント> drvfs defaults 0 0
    を記述する。
    例:
    \\hogehoge\hoge /mnt/nwdrv1 drvfs defaults 0 0

    debian の場合、/etc/fstab が無い為、新規作成する。

    上記記述の場合、所有権は root になる。
    所有権を設定する場合は、
    <デバイス名> <マウントポイント> drvfs defaults,metadata,uid=<ユーザID>,gid=<グループID>  0 0
    の様に記述する。
    例:
    \\hogehoge\hoge /mnt/nwdrv1 drvfs defaults,metadata,uid=1000,gid=1000   0 0

2020年7月18日土曜日

verilog : SVA の演算子

目的:

SVAの演算子等について記す。

各演算子:

(SVA の記述については、こちらを参照。
 下記 動作は、全てを確認した訳では無い為、使用時は注意して下さい。 )

主なシーケンス演算子:

  ( s, s1, s2 : シーケンス 、b : ブーリアン 、 x, y 等 : 信号名 )
演算子 説明
s1 ##n s2 s1 が成立してから nサイクル後に s2 が成立する時
 
s1 ##[n:m] s2 s1 が成立してから n~mサイクル後に s2 が成立する時
 
s [*n] s がnサイクル連続して繰り返された時
 
   
s [*n:m] s がn~mサイクル連続して繰り返された時
 
 
b[->n] b がnサイクル連続 又は 非連続 で繰り返された時
 
* ブーリアンのみ 
s1 intersect s2 s1, s2 の開始と終了が同じである時
 
b throughout s  s の継続中、 b が 真の時
 
s1 within s2  s2 の継続中 に s1 が 真になった場合の s2 終了時
 

主なプロパティ演算子:

演算子 説明
p1 and p2 p1, 2が共に成立するとき評価
   
p1 or p2 p1, 2どちらかが成立するとき評価
   
not p pが成立しないときに評価
   
if(b) p1 else p2 bが真ならp1を評価、偽ならp2を評価
   
disable iff(b) bが真の時は評価しない(Fail しない)
   
s |-> p s が成立した サイクルで p を評価
   
s |=> p s が成立した 次のサイクルで p を評価 ( s |-> ##1 p と同じ )
   


主な関数:

$rose( 信号 )  信号の最下位ビットが '1' に変化した時に 真
   
$fell( 信号 )  信号の最下位ビットが '0' に変化した時に 真
   
$stable( 信号 )  信号が 1サイクル前から変化しなければ 真
   
$past( 信号 , n )  信号のnサイクル前の値,  nが省略された場合は n=1
   
$onehot( 信号 )  信号の'H' のビット数が 1 の時に 真
   
$onehot0( 信号 )  信号の'H' のビット数が 1 又は 0 の時に 真
   
$isunknown(信号)  信号に 'x' や 'z' が含まれる場合に 真
   
$countones(信号)  信号の'H' のビット数
   



2020年6月22日月曜日

blogger : 画像の枠を消す/変更する

目的:

画像を挿入した時の画像についた枠を消す。

概要:

画像を挿入した時、画像の周りに枠が表示される。
テーマの編集でカステムCSSを追加するか、テーマのHTMLを編集する事で枠を表示しない様になるが、全ての画像で枠が消える。
個々の画像で枠を消したり、枠を変更したりできるようにする。

方法: 

画像を挿入した後、HTML表示に切り替え、挿入した画像のボーダー指定部分をスタイルの指定に変更し、枠とパディングのサイズを"0" に する。
変更前 :  <img border="0" data-original-height=...
変更後: <img style="border: 0px ;  padding: 0px ;" data-original-height=...
 ( 変更後、"作成"に戻り、再度 HTML表示すると style の記述位置は自動で変更されている... )

例:

変更前 (画像を挿入)
変更後 (style="border: 0px ;  padding: 0px ;")
枠の色を変更 (style="border: solid 2px #00FF00 ;  padding: 0px ;")

2020年6月21日日曜日

verilog : SVA の property 記述概要

目的:

SVA の property 記述について 理解した内容を 記す

property 記述 :

検証の動作を定義する。
property 記述のみでは アサーションを生成できず、 assertion 記述が必用。

記述方法:




プロパティ表現:

プロパティ表現で 検証の動作内容を定義する。

インプリケーション演算子を使用する場合。


前提条件が 成立した後、 1 クロック後に 帰結部 を 評価する。
上の例では、 X が 立ち上がった後、1クロック後に Y が 立ち下がる事 を確認する。
シーケンスについては、下記参照。
インプリケーション演算子 には次の 2種類がある。
  • オーバーラップ・インプリケーション演算子  ( |-> )
      前提部終了と帰結部開始が同じクロック
  • ノン・オーバーラップ・インプリケーション演算子 ( |=> )
      前提部終了の 1クロック後に帰結部開始。 |-> ##1  と同じになる。

プロパティ否定演算子を使用する場合。






クロック毎に x と y が 等しくない事を確認する。

演算子を使用しない場合。





クロック毎に x と y が 同じであることを確認する。

その他、プロパティ演算子 として and, or, if else を使用して複数のプロパティ表現を組み合わせる事が可能。

シーケンス:

シーケンスは、信号の一連の動作を表す。
例えは、 信号 A, B, C が 1クロック毎に 立ち上がる場合は、
  a ##1 b ##1 c
の様に記述する。
1つの信号が立ち上がるだけでも シーケンス である。
  a
シーケンスは、シーケンス記述で 名前を付けて プロパティ記述の中で使用することができる。

シーケンス演算子 の 詳細は こちら を参照。

システム関数:

システム関数として、以下の関数があり、シーケンス記述等で使用できる。
$rose( 信号 )
 信号の最下位ビットが '1' に変化した時に 真
$fell( 信号 )
 信号の最下位ビットが '0' に変化した時に 真
$stable( 信号 )
 信号が 1サイクル前から変化しなければ 真
$past( 信号 , n )
 信号のnサイクル前の値,  nが省略された場合は n=1
$onehot( 信号 )
 信号の'H' のビット数が 1 の時に 真
$onehot0( 信号 )
 信号の'H' のビット数が 1 又は 0 の時に 真
$isunknown(信号)
 信号に 'x' や 'z' が含まれる場合に 真
$countones(信号)
 信号の'H' のビット数