1. 程式人生 > >Chisel3 - bind - Op, ReadOnly, 左值

Chisel3 - bind - Op, ReadOnly, 左值

ble b2c 進行 size inf push ext data- tty

https://mp.weixin.qq.com/s/F_08jKFMoX9Gf_J_YpsDpg 兩個數據變量進行某個操作(op),產生一個輸出,這個輸出存在一個匿名變量中。這個匿名變量就是以OpBinding的形式綁定到hardware graph中的。 0. 這裏先簡單對 "=" 和 ":="做一個討論。 假設 a & b 的結果輸出到一個匿名變量,記為anonymousVariable。 a & b的用法有兩種: 1) c := a & b ":="的意思為連接。變量c作為下遊,連接到anonymousVariable,接收其值。即anonymousVariable的值的變化會傳播到下遊c中。
2) c = a & b "="的意思是賦予。之所以不說賦值,是因為更多情況下賦予的不是值,而是引用。 這裏就是把anonymousVariable賦給c。就相當於給a & b的輸出這個匿名變量取了一個名字,叫做c。 因為anonymousVariable是匿名的,所以這裏使用c來簡化引用也是有意義的。 總結下來: 1) 兩者的區別在於,一個是匿名變量本身,一個是匿名變量的下一級連接。 2) ":="是連接到的意思(connect to); 3) "="也不是賦值,而是賦引用,取名字或者起別名的意思; 1. OpBinding 1) 兩個操作數:a op b
以a & b為例,方法&定義在UInt中: ?技術分享圖片? 這裏a是this,b是that。&的結果為UInt(this.width max that.width),這是一個匿名變量。 binop定義在Bits中: ?技術分享圖片? 其中a是this, b是other,dest為匿名變量。 這裏要求this, other亦即a, b都是已經綁定了的(設想一下,輸入輸出端口已經綁定了,內部變量使用Wire/Reg綁定了)。dest是新創建的變量,還沒有綁定。 DefPrim定義了一個Definition,無關綁定。其id為dest。 case class DefPrim[T <: Data](sourceInfo: SourceInfo, id: T, op: PrimOp, args: Arg*) extends Definition
pushOp定義於Builder中: ?技術分享圖片? 這裏cmd.id即為dest,調用其bind進行綁定。綁定類型為OpBinding。 2) 一個操作數:取反 與1)類似。 ?技術分享圖片? ?技術分享圖片? ?技術分享圖片? 3) 一個操作數:截取部分位 如ByteSelector中: ?技術分享圖片? io.in(7, 0)這個截取定義於Bits類中: ?技術分享圖片? 其中,UInt(Width(w))為匿名變量。 ?技術分享圖片? pushOp與之前定義一致。 可見位截取生成的臨時變量也是使用OpBinding綁定到hardware graph中的。 2. ReadOnlyBinding OpBinding為只讀綁定,即ReadOnlyBinding。 只讀綁定的變量,只能被讀取,而不能被賦值。換一種說法:在硬件模型(hardware graph)中,只讀綁定的變量,只能作為上遊輸出值(傳播值),而不能作為下遊,接收值(被傳播)。 3. 連接的左值 只讀綁定的變量只能作為右值,而不能作為左值。這裏的左右是針對連接符號“:=”而言的。也是在連接方法中進行限制的。 連接符號定義於Data類中, ?技術分享圖片? 單個連接和批量連接,這裏不做進一步區分解析。 ?技術分享圖片? 這裏如果this.topBinding為ReadOnlyBinding,則跑出異常。 所以this可以是WireBinding/RegBinding/PortBinding/MemPortBinding等的變量,而不能是OpBinding的變量。亦即,可以是模塊的輸出端口,內部定義的Wire()/Reg()臨時變量,而不能是op的結果,也不能是比特截取的結果。

Chisel3 - bind - Op, ReadOnly, 左值