日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 综合教程 >内容正文

综合教程

Chisel 手册(中文part2)

發布時間:2023/12/1 综合教程 32 生活家
生活随笔 收集整理的這篇文章主要介紹了 Chisel 手册(中文part2) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Chisel 手冊(中文part2)

作者:Jonathan Bachrach, Huy Vo, Krste Asanovi?;? EECS Department, UC Berkeley?

譯者:智能物聯(CSDN)?

?

6?Updateables

當描述wire和state節點的運作時,我們通常為輸出端口指定一系列的條件更新,然后用若干獨立語句把這些更新散播出去。舉例來說,Data節點的輸出可以立刻引用,但是輸入可以延后設置。Updateable表示一個條件更新節點,它累積針對節點的路徑,然后生成mux并對這些電路的路徑進行組合邏輯運算。

?
abstract?class?Updateable?extends?Node?{?//?conditional?reads?def?reads:?Queue[(Bool,?UInt)]?//?conditional?writes?def?writes:?Queue[(Bool,?UInt,?Node)]?//?gen?mux?integrating?all?conditional?writes?def?genMuxes(default:?Node)?override?def?:=?(x:?Node):?this.type?
}

Chisel提供條件更新規則,用when語句支持這類時序邏輯描述:

?
object?when?{?def?apply(cond:?Bool)(block:?=>?Unit):?when?
}?class?when?(prevCond:?Bool)?{?def?elsewhen?(cond:?Bool)(block:?=>?Unit):?when?def?otherwise?(block:?=>?Unit):?Unit?
}

when語句使用動態作用域scope來操縱全局條件棧,因此,when語句生成新的條件,將在函數調用路徑內一直起作用。舉個例子:

?
def?updateWhen?(c:?Bool,?d:?Data)?=?when?(c)?{?r?:=?d?}?
when?(a)?{?updateWhen(b,?x)?
}

與下列相同:

?
when?(a)?{?when?(b)?{?r?:=?x?}?
}

Chisel為其他常用類型的條件更新提供一些語法糖:

?
def?unless(c:?Bool)(block:?=>?Unit)?=?when?(!c)?{?block?)

還有

?
def?otherwise(block:?=>?Unit)?=?when?(Bool(true))?{?block?}

我們介紹了switch語句,用于根據一系列普通key的比較結果進行條件更新:

?
def?switch(c:?UInt)(block:?=>?Unit):?Unit?def?is(v:?Bool)(block:?=>?Unit)

?

7?Forward Declarations

純組合電路不允許出現節點的閉環。如果發現閉環,Chisel會報錯。因為不存在閉環,所以可以生成單方向的合法的組合邏輯電路,通過添加新的節點,輸入取自那些已定義的節點。時序電路具有節點之間的反饋,所以有時候必須在定義生成某個節點之前聲明這個輸出。因為Scala順序執行程序語句,我們一般讓數據節點作為wire立即引用,但是它們的輸入延后設置。舉例來說,在一個簡單的CPU中,我們需要預先聲明pcPlus4和brTarget這兩個wires,以便后續引用:

?
val?pcPlus4??=?UInt()?
val?brTarget?=?UInt()?
val?pcNext???=?Mux(pcSel,?brTarget,?pcPlus4)?
val?pcReg????=?RegUpdate(pcNext)?
pcPlus4?????:=?pcReg?+?UInt(4)?
...?
brTarget????:=?addOut

連線運算符 := 用于連接pcReg與addOut。所有的賦值完成,所有的電路都計算以后,如果還有前向聲明還沒有被賦值的話,系統將會報告錯誤。

?

8?Regs

Chisel支持的最簡單的狀態單元是正沿觸發的寄存器,如下所示:

?
object?Reg?{?def?apply[T?<:?Data]?(data:?T,?next:?T?=?null,?init:?T?=?null):?T?
}?object?RegNext?{?def?apply[T?<:?Data]?(next:?T,?init:?T?=?null):?T?
}?object?RegInit?{?def?apply[T?<:?Data]?(init:?T):?T?
}?class?Reg?extends?Updateable

創建方法如下所示:

?
val?r1?=?RegUpdate(io.in)?
val?r2?=?RegReset(UInt(1,?8))?
val?r3?=?RegUpdate(io.in,?UInt(1))?
val?r4?=?Reg(UInt(width?=?8))

復位值resetVal是隱含的reset信號為真時候所取的reg值。

?

9?Mems

Chisel通過Mem語句支持RAM。寫入Mem是正沿觸發,讀取是組合邏輯或者正沿觸發。

?
object?Mem?{?def?apply[T?<:?Data](depth:?Int,?gen:?=>?T,?seqRead:?Boolean?=?false):?Mem?
}?class?Mem[T?<:?Data](gen:?()?=>?T,?depth:?Int,?seqRead:?Boolean?=?false)?extends?Updateable?{?def?apply(idx:?UInt):?T?
}

Mems內部的Ports被賦值UInt的索引 。一個具有一個寫端口和兩個組合邏輯讀端口的32-entry的寄存器組描述如下:

?
val?rf?=?Mem(32,?UInt(width?=?64))?
when?(wen)?{?rf(waddr)?:=?wdata?}?
val?dout1?=?rf(waddr1)?
val?dout2?=?rf(waddr2)

如果設置可選參數seqRead,當Reg被賦予Mem的輸出,Chisel會生成時序讀取端口。一個單口讀,單口寫的SRAM可以描述如下:

?
val?ram1r1w?=?Mem(1024,?UInt(width?=?32),?seqRead?=?true)?
val?dout?=?Reg(UInt())?
when?(wen)?{?ram1r1w(waddr)?:=?wdata?}?
when?(ren)?{?dout?:=?ram1r1w(raddr)?}

在when語句鏈條中,如果讀和寫的條件互斥,將生成單端口的SRAM。

?
val?ram1p?=?Mem(1024,?UInt(width?=?32),?seqRead?=?true)?
val?dout?=?Reg(UInt())?
when?(wen)?{?ram1p(waddr)?:=?wdata?}?
.elsewhen?(ren)?{?dout?:=?ram1p(raddr)?}

如果同一個Mem地址在同一個clock邊沿同步讀寫,或者如果sequential read使能被清除,讀數據是用戶自定義的?

Mem 也支持寫入mask,以便部分字節寫入。?

?
val?ram?=?Mem(256,?UInt(width?=?32))?
when?(wen)?{?ram.write(waddr,?wdata,?wmask)?}

?

10?Ports

端口繼承自Data節點,用于硬件模塊的接口。端口是原始Data對象的有方向版本。端口方向定義如下:

?
trait?PortDir?
object?INPUT??extends?PortDir?
object?OUTPUT?extends?PortDir

復合端口可以遞歸創建,使用vec或者bundle組合簡單的子端口。

?

11?Modules

在Chisel中,模塊Module與Verilog中的模塊非常相似,模塊定義了一個被生成電路的層次結構。模塊的命名空間可以被下游的工具來訪問,用于調試和物理布局。一個用戶自定義模塊被定義成一個class:

  • 繼承自Module,
  • 包含一個接口Bundle,保存于一個io,
  • 在構造器中用連線連接子電路。

用戶通過module的子類來寫自己的模塊:

?
abstract?class?Module?{?val?io:?Bundle?var?name:?String?=?""?def?compileV:?Unit?def?compileC:?Unit?
}

定義它們自己的io。下例定義了一個雙輸入Mux的模塊:

?
class?Mux2?extends?Module?{?val?io?=?new?Bundle{?val?sel?=?Bool(INPUT)?val?in0?=?Bool(INPUT)?val?in1?=?Bool(INPUT)?val?out?=?Bool(OUTPUT)?}?io.out?:=?(io.sel?&?io.in1)?|?(~io.sel?&?io.in0)?
}

:= 賦值運算符,用于module內部,是Chisel的一個特殊運算符,連接左側的輸入到右側的輸出。典型地用于連接輸出端口和它們的定義。

<> 運算符成捆連接兄弟模塊之間的相反的接口,或者父子模塊之間的相同的接口。成捆連接使用路徑名匹配方式連接葉端口。連接只在port非無效的時候進行,允許用戶重復成捆連接那些只有部分使用的接口。所有的連接完成以后電路將被優化,Chisel 如果發現端口不止一個連接,將會發出警告。

模塊內部的節點和子模塊的命名,由C++或者Verilog后端負責,取自模塊的域名,使用Scala內審機制。使用函數setName()也可以設置節點和子模塊的名字。

總結

以上是生活随笔為你收集整理的Chisel 手册(中文part2)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。