版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
3.模塊與硬件類型一、硬件類型二、賦值三、端口四、模塊五、線網(wǎng)六、寄存器(組)七、補(bǔ)充與總結(jié)2目
錄一、硬件類型3
硬件類型
Chisel的數(shù)據(jù)類型是無法獨(dú)立工作的,實(shí)際的電路應(yīng)該是由硬件類型的對(duì)象構(gòu)成的硬件類型完成:信號(hào)的聲明、用賦值進(jìn)行信號(hào)傳遞valx=Wire(UInt(4.W))數(shù)據(jù)類型對(duì)象作為參數(shù)定義:位寬是多少、按無符號(hào)數(shù)還是有符號(hào)數(shù)解釋、是不是向量valx=Wire(UInt(4.W))4二、賦值5賦值首次創(chuàng)建變量時(shí)用賦值運(yùn)算符“=”初始化valx=Wire(UInt(4.W))
valy=Wire(UInt(4.W))
x:="b1010".U
//向4bit的線網(wǎng)x賦予了無符號(hào)數(shù)10
y:=~x
//把x按位取反,傳遞給y
驅(qū)動(dòng)該端口時(shí),就需要通過變量名來進(jìn)行賦值操作,使用方法“:=”作為賦值運(yùn)算符“=”的代替“:=”優(yōu)先級(jí)與“=”一致,是最低的6三、端口7端口3.1定義端口列表端口列表是由方法“IO[T<:Data](iodef:T)”定義參數(shù)通常是一個(gè)Bundle類型的對(duì)象而且引用的字段名稱必須是“io”(繼承自Module的模塊)8端口通過“io.xxx”來使用端口從性質(zhì)上來說它仍然屬于組合邏輯的線網(wǎng)3.2端口方向classMyIOextendsBundle{
valin=Input(Vec(5,UInt(32.W)))
valout=Output(UInt(32.W))
}
classMyModuleextendsModule{
valio=IO(newMyIO)
//模塊的端口列表
......
}端口存在方向,需要方法“Input[T<:Data](source:T)”和“Output[T<:Data](source:T)”來為每個(gè)端口表明具體方向9端口3.3翻轉(zhuǎn)端口列表的方向使用情況:
對(duì)于兩個(gè)相連的模塊,可能存在大量同名但方向相反的端口方法:Flipped[T<:Data](source:T)實(shí)現(xiàn)細(xì)節(jié)
其把參數(shù)里所有的輸入端口轉(zhuǎn)為輸出端口,輸出端口轉(zhuǎn)為輸入端口
10端口classMyIOextendsBundle{
valin=Input(Vec(5,UInt(32.W)))
valout=Output(UInt(32.W))
}
classMyModule_1extendsModule{
valio=IO(newMyIO)
//in是輸入,out是輸出
......
}
classMyModule_2extendsModule{
valio=IO(Flipped(newMyIO))
//in是輸出,out是輸入
......
}11MyModule_1inoutMyModule_2inout端口3.4端口整體連接使用整體連接符號(hào)“<>”該操作符會(huì)把符號(hào)左右兩邊的端口列表里所有同名的端口進(jìn)行連接
同一級(jí)的模塊的端口方向必須是輸入連輸出、輸出連輸入;父級(jí)模塊和子級(jí)模塊的端口方向則是輸入連輸入、輸出連輸出不能存在端口名字、數(shù)量、類型不同的情況classMyIOextendsBundle{
valin=Input(Vec(5,UInt(32.W)))
valout=Output(UInt(32.W))
}
classMyModuleextendsModule{
valio=IO(newBundle{
valx=newMyIO
valy=Flipped(newMyIO)
})
io.x<>io.y
//相當(dāng)于io.y.in:=io.x.in;
//io.x.out:=io.y.out
}12四、模塊134.1模塊的分類Module/LegacyModuleChisel的模塊分為三類,繼承關(guān)系如下(箭頭指向父類)MultiIOModuleRawModule必須實(shí)現(xiàn)抽象成員io有隱式時(shí)鐘(稱為clock)和隱式復(fù)位(稱為reset)123模塊根據(jù)需要定義IO無抽象成員io不提供隱式時(shí)鐘和復(fù)位根據(jù)需要定義IO無抽象成員io有隱式時(shí)鐘和復(fù)位144.2定義模塊模塊繼承自Module類包含一個(gè)用于接口的抽象字段“io”在類的主構(gòu)造器里進(jìn)行內(nèi)部電路連線//mux2.scala
packagetest
importchisel3._
classMux2extendsModule{
valio=IO(newBundle{
valsel=Input(UInt(1.W))
valin0=Input(UInt(1.W))
valin1=Input(UInt(1.W))
valout=Output(UInt(1.W))
})
io.out:=(io.sel&io.in1)|(~io.sel&io.in0)
}“newBundle{...}”是聲明一個(gè)繼承自Bundle的匿名類,然后實(shí)例化該匿名類。定義一個(gè)二選一多路選擇器:15模塊4.3例化模塊//mux4.scala
packagetest
importchisel3._
classMux4extendsModule{
valio=IO(newBundle{
valin0=Input(UInt(1.W))
valin1=Input(UInt(1.W))
valin2=Input(UInt(1.W))
valin3=Input(UInt(1.W))
valsel=Input(UInt(2.W))
valout=Output(UInt(1.W))
})
valm0=Module(newMux2)
m0.io.sel:=io.sel(0)
m0.io.in0:=io.in0
m0.io.in1:=io.in1
valm1=Module(newMux2)
m1.io.sel:=io.sel(0)
m1.io.in0:=io.in2
m1.io.in1:=io.in3
valm2=Module(newMux2)
m2.io.sel:=io.sel(1)
m2.io.in0:=m0.io.out
m2.io.in1:=m1.io.out
io.out:=m2.io.out
}例化一個(gè)模塊,要把實(shí)例對(duì)象傳遞給單例對(duì)象Module的apply方法通過例化剛才的雙輸入多路選擇器構(gòu)建四輸入多路選擇器:16模塊4.4例化多個(gè)模塊對(duì)于要多次例化的重復(fù)模塊,可以利用向量的工廠方法VecInit[T<:Data]通常使用待例化模塊的io字段組成的序列作為參數(shù)://mux4_2.scala
packagetest
importchisel3._
classMux4_2extendsModule{
valio=IO(newBundle{
valin0=Input(UInt(1.W))
valin1=Input(UInt(1.W))
valin2=Input(UInt(1.W))
valin3=Input(UInt(1.W))
valsel=Input(UInt(2.W))
valout=Output(UInt(1.W))
})17模塊生成序列的方法:
調(diào)用單例對(duì)象Seq里的方法fill,該方法的一個(gè)重載版本有兩個(gè)單參數(shù)列表,第一個(gè)參數(shù)接收Int類型的對(duì)象,表示序列的元素個(gè)數(shù),第二個(gè)是傳名參數(shù),接收序列的元素。
valm=VecInit(Seq.fill(3)(Module(newMux2).io))
//例化了三個(gè)Mux2,并且參數(shù)是端口字段io
m(0).sel:=io.sel(0)//模塊的端口通過下標(biāo)索引,并且路徑里沒有“io”
m(0).in0:=io.in0
m(0).in1:=io.in1
m(1).sel:=io.sel(0)
m(1).in0:=io.in2
m(1).in1:=io.in3
m(2).sel:=io.sel(1)
m(2).in0:=m(0).out
m(2).in1:=m(1).out
io.out:=m(2).out
}18五、線網(wǎng)19線網(wǎng)classMyModuleextendsModule{
valio=IO(newBundle{
valin=Input(UInt(8.W))
})
valmyNode=Wire(UInt(8.W))
myNode:=0.U;//無效
myNode:=io.in+1.U;
}通過工廠方法“Wire[T<:Data](t:T)”來定義線網(wǎng)可以對(duì)線網(wǎng)進(jìn)行賦值,也可以把線網(wǎng)連接到其他電路節(jié)點(diǎn),線網(wǎng)是組成組合邏輯的基本硬件類型。定義具有覆蓋性,對(duì)同一個(gè)線網(wǎng)多次賦值,則只有最后一次賦值是有效的5.1Wire20Wire不提供位寬參數(shù)將啟用自動(dòng)推斷。官方源代碼注釋:valw0=Wire(UInt())//widthisinferred
valw1=Wire(UInt(8.W))//widthissetto8
valw2=Wire(Vec(4,UInt()))//widthisinferred
valw3=Wire(Vec(4,UInt(8.W)))//widthofeachelementissetto8
classMyBundle{
valunknown=UInt()
valknown=UInt(8.W)
}
valw4=Wire(newMyBundle)
//Widthofw4.unknownisinferred
//Widthofw4.knownissetto821WireDefault例1:Non-LiteralElementinitializer-widthwillbeinferred對(duì)于non-literalchisel3.Bits,導(dǎo)線的寬度將被推斷。WireDefault用于構(gòu)建具有默認(rèn)連接的硬件線路有單參數(shù)和多參數(shù)兩種形式。
單參數(shù)使用參數(shù)來指定類型和默認(rèn)連接:valx=Wire(UInt())
valy=Wire(UInt(8.W))
valw1=WireDefault(x)//widthwillbeinferred
valw2=WireDefault(y)//widthwillbeinferred5.2WireDefault22WireDefault例3:Aggregateinitializer:widthwillbesettomatchtheaggregate例2:Literalchisel3.Bitsinitializer:widthwillbesettomatch對(duì)于literalchisel3.Bits和所有非Bits參數(shù),類型將從參數(shù)復(fù)制。valw1=WireDefault(1.U)//widthwillbeinferredtobe1
valw2=WireDefault(1.U(8.W))//widthissetto8classMyBundle{
valunknown=UInt()
valknown=UInt(8.W)
}
valw1=Wire(newMyBundle)
valw2=WireDefault(w1)
//Widthofw2.unknownisinferred
//Widthofw2.knownissetto823WireDefault帶有兩個(gè)參數(shù)的WireDefault的寬度推斷語義與Wire的相匹配。WireDefault的第一個(gè)參數(shù)是類型模板,它定義了Wire的寬度,其方式與Wire的參數(shù)完全相同。其定義類似于:
雙參數(shù)形式允許獨(dú)立指定Wire的類型和默認(rèn)連接。defWireDefault[T<:Data](t:T,init:T):T={
valx=Wire(t)
x:=init
x
}vala=Wire(UInt(8.W))
valb=WireDefault(UInt(10.W),a)wire[7:0]a;
wire[9:0]b={{2'd0},a};24六、寄存器(組)25寄存器6.1RegChisel有五種內(nèi)建的寄存器,Reg、RegNext、RegInit、util包里的RegEnable和ShiftRegister普通的寄存器“Reg[T<:Data](t:T):T”可以在when語句里用全局reset信號(hào)進(jìn)行同步復(fù)位(asBool),也可以進(jìn)行條件賦值或無條件跟隨入?yún)⒈仨毷菙?shù)據(jù)類型的對(duì)象26寄存器和Wire的構(gòu)造方式非常類似valr0=Reg(UInt())//widthisinferred
valr1=Reg(UInt(8.W))
//widthissetto8
valr2=Reg(Vec(4,UInt()))
//widthisinferred
valr3=Reg(Vec(4,UInt(8.W)))
//widthofeachelementissetto8
classMyBundle{
valunknown=UInt()
valknown=UInt(8.W)
}
valr4=Reg(newMyBundle)
//Widthofr4.unknownisinferred
//Widthofr4.knownissetto827寄存器6.2RegNextvalfoo=Reg(UInt(4.W))//widthis4
valbar=RegNext(foo)//widthisunset
valfoo=Reg(UInt(4.W))//widthis4
valbar=Reg(chiselTypeOf(foo))
//widthis4
bar:=foo
classMyBundleextendsBundle{
valx=UInt(4.W)
}
valfoo=Wire(newMyBundle)
//thewidthoffoo.xis4
valbar=RegNext(foo)
//thewidthofbar.xis4“RegNext[T<:Data](next:T)”,沒有復(fù)位信號(hào)另一個(gè)版本的apply工廠方法是“RegNext[T<:Data](next:T,init:T)”,是由復(fù)位信號(hào)控制RegNext經(jīng)常用于構(gòu)造延遲一個(gè)周期的信號(hào)。28寄存器例1:Non-LiteralElementinitializer-widthwillbeinferred對(duì)于non-literalchisel3.Bits、Reg的寬度將被推斷6.3RegInit
復(fù)位到指定值的寄存器RegInit,也有兩種構(gòu)造方式:“RegInit[T<:Data](init:T)”“RegInit[T<:Data](t:T,init:T)”
單參數(shù)形式使用參數(shù)來指定類型和重置值valx=Wire(UInt())
valy=Wire(UInt(8.W))
valr1=RegInit(x)//widthwillbeinferred
valr2=RegInit(y)//widthwillbeinferred29寄存器例3:Aggregateinitializer:widthwillbesettomatchtheaggregate例2:Literalchisel3.Bitsinitializer:widthwillbesettomatch對(duì)于literalchisel3.Bits和所有非Bits參數(shù),類型將從參數(shù)復(fù)制。valr1=RegInit(1.U)//widthwillbeinferredtobe1
valr2=RegInit(1.U(8.W))//widthissetto8classMyBundleextendsBundle{
valunknown=UInt()
valknown=UInt(8.W)
}
valw1=Reg(newMyBundle)
valw2=RegInit(w1)
//Widthofw2.unknownisinferred
//Widthofw2.knownissetto830寄存器帶有兩個(gè)參數(shù)的RegInit的寬度推斷語義與Reg的寬度推斷語義相匹配。RegInit的第一個(gè)參數(shù)是類型模板,它定義Reg的寬度的方式與Wire的完全相同。其定義類似于:defRegInit[T<:Data](t:T,init:T):T={
valx=Reg(t)
x:=init
x
}
雙參數(shù)形式允許獨(dú)立指定Reg的類型和默認(rèn)連接。31第一個(gè)apply方法,不進(jìn)行復(fù)位初始化。例:寄存器6.4RegEnableobjectRegEnable{
defapply[T<:Data]
(next:T,enable:Bool):T=
{
valr=Reg(chiselTypeOf(next))
when(enable){r:=next}
r
}
defapply[T<:Data]
(next:T,init:T,enable:Bool):T=
{
valr=RegInit(init)
when(enable){r:=next}
r
}
}valregWithEnableAndReset=RegEnable(nextVal,ena)valregWithEnableAndReset=RegEnable(nextVal,0.U,ena)第二個(gè)apply方法,進(jìn)行復(fù)位初始化。例:32寄存器6.5ShiftRegister“ShiftRegister[T<:Data](in:T,n:Int,resetData:T,en:Bool)”第一個(gè)參數(shù)in是待移位的數(shù)據(jù),第二個(gè)參數(shù)n是需要延遲的周期數(shù),第三個(gè)參數(shù)resetData是指定的復(fù)位值,可以省略,第四個(gè)參數(shù)en是移位的使能信號(hào),默認(rèn)為true.B,也是通過兩個(gè)apply方法實(shí)現(xiàn)的valregDelayTwo=ShiftRegister(nextVal,2,ena)valregDelayTwoReset=ShiftRegister(nextVal,2,0.U,ena)33寄存器使用withClockAndReset來構(gòu)造異步時(shí)鐘和異步復(fù)位信號(hào),也可以用withClock和withReset單獨(dú)控制異步時(shí)鐘或異步復(fù)位信號(hào)classasyncRegextendsModule{
valio=IO(newBundle{
valasyncClk=Input(UInt(1.W))
valasyncRst=Input(UInt(1.W))
valout=Output(UInt(8.W))
})
valasyncRegInit=withClockAndReset(io.asyncClk.asBool().asClock(),
io.asyncRst.asBool().asAsyncReset())(RegInit(0.U(8.W)))
asyncRegInit:=asyncRegInit+1.U
io.out:=asyncRegInit
}6.6異步寄存器34寄存器如果把子類型Vec[T]作為參數(shù)傳遞進(jìn)去,就會(huì)生成多個(gè)位寬相同、行為相同、名字前綴相同的寄存器。同樣,寄存器組在Chisel代碼里可以通過下標(biāo)索引。
valreg0=RegNext(VecInit(io.a,io.a))
valreg1=RegNext(VecInit(io.a,io.a),VecInit(0.U,0.U))
valreg2=RegInit(VecInit(0.U(8.W),0.U(8.W)))
valreg3=Reg(Vec(2,UInt(8.W)))
valreg4=Reg(Vec(2,UInt(8.W)))
valreg5=RegEnable(VecInit(io.a+1.U,io.a+1.U),VecInit(0.U(8.W),0.U(8.W)),io.en)
valreg6=RegEnable(VecInit(io.a-1.U,io.a-1.U),io.en)6.7寄存器組35寄存器valreg7=ShiftRegister(VecInit(io.a,io.a),3,VecInit(0.U(8.W),0.U(8.W)),io.en)
valreg8=ShiftRegister(VecInit(io.a,io.a),3,io.en)
reg2(0):=io.a.andR
reg2(1):=io.a.andR
reg3(0):=io.a.orR
reg3(1):=io.a.orR
when(reset.asBool){
reg4(0):=0.U
reg4(1):=0.U
}.otherwise{
reg4(0):=1.U
reg4(1):=1.U
}36七、補(bǔ)充與總結(jié)37補(bǔ)充與總結(jié)7.1when條件賦值由于Scala已經(jīng)占用了“if…elseif…else”語法,所以相應(yīng)的Chisel控制結(jié)構(gòu)改成了when語句,其語法如下:所有的判斷條件都是返回Bool類型的傳名參數(shù),不要和Scala的Boolean類型混淆,也不存在Boolean和Bool之間的相互轉(zhuǎn)換。對(duì)于UInt、SInt和Reset類型,可以用方法asBool轉(zhuǎn)換成Bool類型來作為判斷條件。when(condition1){definition1}
.elsewhen(condition2){definition2}
...
.elsewhen(conditionN){definitionN}
.otherwise{defaultbehavior}38補(bǔ)充與總結(jié)//mux2_when.scala
packagetest
importchisel3._
classMux2extendsModule{
valio=IO(newBundle{
valsel=Input(UInt(1.W))
valin0=Input(UInt(1.W))
valin1=Input(UInt(1.W))
valout=Output(UInt(1.W))
})
when(io.sel===1.U){
io.out:=io.in1
}.otherwise{
io.out:=io.in0
}
}通常,when用于給帶使能信號(hào)的寄存器更新數(shù)據(jù),組合邏輯不常用。對(duì)于有復(fù)位信號(hào)的寄存器,推薦使用RegInit來聲明用when實(shí)現(xiàn)一個(gè)二選一多路選擇器:39unlessimportchisel3.util._
unless(condition){definition}除了when結(jié)構(gòu),util包里還有一個(gè)與之對(duì)偶的結(jié)構(gòu)“unless”,如果unless的判定條件為false.B,則一直執(zhí)行,否則不執(zhí)行7.2unless40總結(jié)數(shù)據(jù)類型必須配合硬件類型才能使用,它不能獨(dú)立存在,因?yàn)榫幾g器只會(huì)把硬件類型生成對(duì)應(yīng)的Verilog代碼。這是因?yàn)榉椒╒ec期望第二個(gè)參數(shù)是數(shù)據(jù)類型,這樣它才
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 外貿(mào)出口代理協(xié)議(2025年退稅服務(wù))
- 土地租賃合同(長期租賃2025年)?
- 2026年安徽警官職業(yè)學(xué)院單招綜合素質(zhì)考試備考試題帶答案解析
- 2026年廣東機(jī)電職業(yè)技術(shù)學(xué)院高職單招職業(yè)適應(yīng)性測試參考題庫有答案解析
- 投資合同協(xié)議2025年
- 2026年福建衛(wèi)生職業(yè)技術(shù)學(xué)院單招綜合素質(zhì)筆試備考題庫帶答案解析
- 2026年甘肅鋼鐵職業(yè)技術(shù)學(xué)院高職單招職業(yè)適應(yīng)性測試備考題庫有答案解析
- 2026年福建幼兒師范高等??茖W(xué)校單招職業(yè)技能筆試備考題庫帶答案解析
- 2026年包頭輕工職業(yè)技術(shù)學(xué)院高職單招職業(yè)適應(yīng)性測試備考試題有答案解析
- 2026年撫州職業(yè)技術(shù)學(xué)院高職單招職業(yè)適應(yīng)性考試參考題庫帶答案解析
- 《種子里孕育著新生命》課件
- 公司文件存儲(chǔ)管理辦法
- 即食鮮切果蔬制作服務(wù)規(guī)范(食品經(jīng)營者)
- 船閘環(huán)保監(jiān)理工作報(bào)告
- 工傷醫(yī)療墊付協(xié)議書
- 原發(fā)性肺癌診療指南2022版
- 《磁控濺射鍍膜》課件
- 機(jī)械制造技術(shù)基礎(chǔ)試題大全試題庫歷年考題帶答案
- 天車維修協(xié)議書范本
- 甘蔗砍伐合同協(xié)議
- 車輛機(jī)械系統(tǒng)檢修120型控制閥結(jié)構(gòu)64課件
評(píng)論
0/150
提交評(píng)論