LRM読解(Chap.2 字句定義/語彙規約)

2008/08/31Verilog::文法import

字句定義/語彙規約 ~ Lexical conventions (LRM-Chap.2)

LRMから,少し抜粋.

数値表現

| binary  | [size]*'[s|S]*(b|B)[01]+
| octal   | [size]*'[s|S]*(o|O)[0-7]+
| hexa    | [size]*'[s|S]*(h|H)[0-9a-fA-F]+
| decimal | ([size]*'[s|S]*(d|D)[0-9]+)|([0-9]+)

LRM 2.5.1 Integer constants

Example 3 Using sign with constant numbers

8'd-6   // 構文違反.
-8'd6   // 6の2の補数を示します.8bitサイズを保持します.
4'shf   // これはbinaryで 4bitの'1111'と書き直せます.
        // 2の補数表現では-1になります.
        // 即ち,これは -4'h1と等価です.
-4'sd15 // 同様にして,これは 4'd1と等価です.(-(-4'd1))

LRM 2.6 Strings

一行内で,double quotes("")で閉じられた部分を文字列とみなします.unsigned int定数として 8bit ASCII文字を取り扱うことができます.

文字列変数?の定義と使い方

stringvarというレジスタ変数を用意し,"Hello world!"を代入してみましょう.

 reg [8*12:1] stringvar;
 initial begin
   stringvar = "Hello world!";
 end

8bit widthの[12:1]配列,と見ればいいんですかねぇ.[8*(欲しい文字数):1]とすればよいようです.C言語と違い,NULL挿入はされない模様です.


LRM 2.6.2 の NOTE

意訳で敵どうだけれど,まぁ,こんなもんで.

When a variable is larger than required to hold a value being assigned,
the contents on the left are padded with zeros after the assignment.
This is consistent with the padding that occurs during assignment of nonstring values.

変数のほうが,文字列よりも大きい場合には,左側がゼロパディングされます.これは,定数のパディングと矛盾しないようになっているからである.(意訳)

If a string is larger than the destination string variable,
the string is truncated to the left, and the leftmost characters will be lost.
文字列のほうが長い場合には,文字列の左側が失われます.
LRM 2.6.3 特殊文字

C言語と同様に,下記の特殊文字が定義されます.エスケープ記号とか..

Escape Stringescape stringで示される文字
\n改行文字
\tタブ文字
\\\(バックスラッシュ, \x5C)
\"double quote(",\x22)
\dddキャラクタコード指定. dは0~7の数値を示す. ただし, 1~3個で構成する(3個必要なわけではない).

LRM 2.7 Identifiers, keywords, and system names

識別子は、それに参照をつけることができるようにユニークな名前をオブジェクトに与えるのに使用されます。識別子は、簡単な識別子かエスケープされた識別子(LRM 2.7.1参照)のどちらかです。簡単な識別子は 文字、数字、ドル記号($)、およびアンダースコア(_)の組み合わせである。簡単な識別氏の一文字目は,数値やドル記号にすべきではないです.英字か,アンダースコアなら可能です.識別子は大文字と小文字を区別するでしょう.

原文

An identifier is used to give an object a unique name so it can be referenced.
An identifier is either a simple identifier or an escaped identifier (see 2.7.1).
A simple identifier shall be any sequence of letters, digits, dollar signs ($), and underscore characters (_).
The first character of a simple identifier shall not be a digit or $;
it can be a letter or an underscore. Identifiers shall be case sensitive.

naming rule?
  • System task/functionの名前は,'$'で始まる.[LRM2.7.4]

2.8 Attribute[LRM 2.8]

syntax

attribute_instance ::= (From Annex A - A.9.1)
  (* attr_spec { , attr_spec } *)

attr_spec ::=
  attr_name = constant_expression
  | attr_name

attr_name ::=
  identifier

2008/08/22(金)[ISE] Verilog Simulation(ISim)

概要とか問題とか

今回,試行錯誤して遊んだメモなので,ワークフローではありません.いじくっているうちに慣れたり覚えたりしますよねぇ?.基礎知識が不足しているからこうして下積みを・・・(^^;

Post Route Simulationにて,配置配線で問題が生じたかを確認する.
Timing Constraintsの設定はClockしかしていない.設定不足か?
また,behavior simulationで得られた期待どおりの波形が見えない(出力信号).

ざっとまわして,いくつか出てきた.どれもこれもsetup time/hold time違反の模様.コレを見て,配置配線前にエラーが出ていなかったので,おかしいなぁと思いつつ,Warningのとり方を調べていた.

WARNING:Simulator:29 - at 6.000350773 ms: Warning:  Timing violation in
   /TST_BSC/uut/\TPU_1/TADD_buf_14 /  $setuphold<setup>( I:6.000350768 ms,
   CLK:6.000350773 ms,132.000 ps,48.000 ps)
WARNING:Simulator:29 - at 6.000350773 ms: Warning:  Timing violation in
   /TST_BSC/uut/\TPU_1/TADD_buf_15 /  $setuphold<setup>( I:6.000350736 ms,
   CLK:6.000350773 ms,132.000 ps,48.000 ps)
WARNING:Simulator:29 - at 6.000380773 ms: Warning:  Timing violation in
   /TST_BSC/uut/\RAM1K_1/RAMB16_S18_inst /  $setuphold<setup>( ADDR:6.000380571
   ms, CLK:6.000380773 ms,377.000 ps,131.000 ps)
WARNING:Simulator:29 - at 6.000380839 ms: Warning:  Timing violation in
   /TST_BSC/uut/\RAM1K_1/RAMB16_S18_inst /  $setuphold<hold>( CLK:6.000380773
   ms, ADDR:6.000380839 ms,377.000 ps,131.000 ps)

半日以上うろうろしていたけれども,最終的には問題ないという見解に落ち着く.おそらくskewにより,使用しない信号を拾うタイミングで発生していると思われる.ポートから受けたデータをDFFでラッチし,その次のサイクルで内部の所望のレジスタへと転送するように実装してある.ところが,今回の箇所は,ポートからラッチするタイミングでviolation警告が出る.DFFにラッチするタイミングがわずかに早くなり,その後段にあるDFFへと信号が先行してしまって,posedge CLKが入ったのではないだろうか.
裏づけを取るにはシミュレーション時に該当信号をモニタする必要があるわけだが,その手段についてもわからなかった(現在進行形).

とりあえず,検証モジュール(タスク)で,インスタンス名をドットでつないで内部信号をassignして観測しようとしています.が,なんだか調子悪いような・・・.DCMを使っているせいもあり,5mSec強の待ち時間を作りこんでしまった.当該回路を取り去ると挙動が変わる恐れもあり,実行していない.*1

Warningの意味

合成/シミュレーションデザイン ガイド

WARNING:Simulator:29 - at 6.000350773 ms: Warning:  Timing violation in
   /TST_BSC/uut/\TPU_1/TADD_buf_15 /  $setuphold<setup>( I:6.000350736 ms,
   CLK:6.000350773 ms,132.000 ps,48.000 ps)

clock skewによるwarningと判断する.SHからのWRアサート→ネゲートを検出して,データをラッチして,次のCLKでTPU moduleに書き込み要求を出す.(module向けのWRはネゲートされたまま.DFFの貫通が起きればその限りではない?が,次のCLKで書きにいくのでおk.bufferにしてあるから1clk間化けても大丈夫)



*1 : シミュレーション時間がかかりすぎるので,削るようにもしたほうがいいナ.

少し解決

シミュレーションに時間を要していた件,DCM出力が出てこないのは時間のせいと思い込んでいましたが,リセットがかかっていなかった模様.
リセット信号がnegedgeなのにt=0から0で100nSecおいて1にしてました.そりゃ非同期リセットかからない罠('A`.

次に,timing violation.下位モジュールで別クロックを作ってしまっていました.同じクロックと期待して表示させたのに0.7nSecもずれている.10nSec周期なので,7%誤差ですね.コレを削ればviolationも消えるかもしれませんし,そもそも非同期になっていては設計想定が崩れます.

DCMにするか,クロックバッファを通してやるのが無難でしょうかねぇ.DCMもったいないかな・・・?分周して同窓にあわせようとすれば,これしかないか.出力にDFFかましても位相ずれるには変わりないしねぇ.


ISE 10.1のmanual類

日本語版は,ここらへんに落ちてます.

http://japan.xilinx.com/support/software_manuals.htm

module

2008/08/20Verilog::文法import

module文(synthesizable/TestBench)

概要

階層化設計の一塊.入出力信号・パラメータを引数として、実体化する.
順序回路・組み合わせ回路の0個以上の組み合わせの回路ブロックを記述する.

書式

ANSI式*1を以下に示す.

module <module-name> (
   input foo,
   output bar,
   inout bus
  );
  // local signal/variable...
  begin
   // 式
  end
endmodule

それ以前の書式は以下のように記述する.

module <module-name> ;
   input foo,
   output bar,
   inout bus
// (略)
endmodule


*1 : ANSI-Cの関数記述相当.K&R時代は変数だけを並べて,型+変数名は後に記述した.Verilogでも、module名だけでセミコロンを打ち,信号名を並べてからbegin文を置く記述も可能.

moduleのパラメタ変更方法

パラメタの使い方を理解しておらず,つい最近に例を見かけて知ったので記載しておく.
defineとは違い、インスタンス化する際に値を変化させて利用することができる,と推測する.

  • defparam文
  • instance化する際に, 渡す.
     module-name #(
    		.paramete-name(value),
    		...
    	) instance-name (
    		.signal-name(symbol),
    		....
    	) ;
    

※インデントはxilinx webpack 10.1sp2の自動生成ツールの出力を真似た.

wait

2008/08/20Verilog::文法import

待ち処理(TestBench)

Test記述時に有効. 式の評価結果が TRUEになるまで待つ.
initial文でクロックに同期して処理をさせたい場合に使うとよさそう. @(posedge CLK)で十分です.

  always #20 CLK <= ~CLK;

  initial begin
   ...
   wait( CLK==0 );
   wait( CLK==1 );
→ @(posedge CLK);
  # 2  // CLK's posedge + 2 [nSec]
   hoge <= 1;
   ...
  end

wait(式?)

前述のとおり.


@ (式?)

式の状態を待つ?立ち上がり:posedge
立ち下り:negedge
などなど...と思う.調べてないけれども使ったものだけ記述.サイトではなく仕様書を見て転記してこないと、ですね.

task

2008/08/20Verilog::文法import

書式

task <name>;
	// input ; 値渡し. 呼び出しもとのreg等に影響を与えない.
	// output

	// process...
endtask

syntax

task_declaration ::= (From Annex A - A.2.7)
   task [ automatic ] task_identifier ;
     { task_item_declaration }
     statement
   endtask
 | task [ automatic ] task_identifier ( task_port_list ) ;
     { block_item_declaration }
     statement
   endtask

task_item_declaration ::=
  block_item_declaration
  | { attribute_instance } tf_input_declaration ;
  | { attribute_instance } tf_output_declaration ;
  | { attribute_instance } tf_inout_declaration ;

task_port_list ::=
  task_port_item { , task_port_item }

task_port_item ::=
  { attribute_instance } tf_input_declaration
  | { attribute_instance } tf_output_declaration
  | { attribute_instance } tf_inout_declaration

tf_input_declaration ::=
  input [ reg ] [ signed ] [ range ] list_of_port_identifiers
  | input [ task_port_type ] list_of_port_identifiers

tf_output_declaration ::=
  output [ reg ] [ signed ] [ range ] list_of_port_identifiers
  | output [ task_port_type ] list_of_port_identifiers

tf_inout_declaration ::=
  inout [ reg ] [ signed ] [ range ] list_of_port_identifiers
  | inout [ task_port_type ] list_of_port_identifiers

task_port_type ::=
  time | real | realtime | integer

block_item_declaration ::= (From Annex A - A.2.8)
  { attribute_instance } block_reg_declaration
  | { attribute_instance } event_declaration
  | { attribute_instance } integer_declaration
  | { attribute_instance } local_parameter_declaration
  | { attribute_instance } parameter_declaration
  | { attribute_instance } real_declaration
  | { attribute_instance } realtime_declaration
  | { attribute_instance } time_declaration

block_reg_declaration ::=
  reg [ signed ] [ range ]
  list_of_block_variable_identifiers ;

list_of_block_variable_identifiers ::=
  block_variable_type { , block_variable_type }

block_variable_type ::=
  variable_identifier
  | variable_identifier dimension { dimension }


概要

  • 記述はmoduleとほぼ同じ. 許容される型/process文が増える程度.
  • 引数は宣言した順に渡される.名前渡しも可能.(ドット+名前(信号))
  • input引数は値渡しになる.呼び出し元に影響はでない.
  • inout/outputは代入すると呼び元に値を返すことができる.[LRM 10.1]
  • 実回路としてsynthesize不可. simulation modelでのみ使用可能
  • "#値"による待ち処理を入れることができる. task呼び出し元は, task内で消費した時間の後に返ってくる.

その他メモ

if文を用いて、条件によって待ち時間を変化させることもできる.ex.

  if (t_AD > t_CS)  begin
    # (t_CS)
    CS_n <= 0;
    # (t_AD - t_CS)
    ADR <= ADR_buf;
  end
  else begin
    # (t_AD)
    ADR <= ADR_buf;
    # (t_CS - t_AD)
    CS_n <= 0;
  end

※CS_nとADRの変化時間が、パラメタt_ADとt_CSの大小関係により前後するため、分岐させた.後日,CPUバスの試験パターンを振るための例を示す.waveformを外部プログラムで吐いて,取り込んだほうが早かった気がするけれど。。。