版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
8.函數(shù)的應(yīng)用一、用函數(shù)抽象組合邏輯二、用工廠(chǎng)方法簡(jiǎn)化模塊的例化三、用Scala的函數(shù)簡(jiǎn)化代碼四、Chisel的打印函數(shù)五、Chisel的對(duì)數(shù)函數(shù)六、與硬件相關(guān)的函數(shù)七、隱式類(lèi)的應(yīng)用八、遞歸函數(shù)的應(yīng)用九、總結(jié)目錄1一、用函數(shù)抽象組合邏輯2一、用函數(shù)抽象組合邏輯在Verilog中,可以利用任務(wù)或函數(shù),將重復(fù)性的行為級(jí)設(shè)計(jì)進(jìn)行提取。與Verilog一樣,在Chisel中對(duì)于頻繁使用的組合邏輯電路,可以定義成Scala的函數(shù)形式,然后通過(guò)函數(shù)調(diào)用的方式來(lái)使用它。定義位置:?jiǎn)卫龑?duì)象內(nèi)供多個(gè)模塊使用頻繁使用任務(wù)(task)Scala函數(shù)
函數(shù)(function)VerilogChisel電路模塊內(nèi)3moduleUseFunc(
inputclock,
inputreset,
input[3:0]io_in,
outputio_out1,
outputio_out2
);
wire_io_out1_T_4=io_in[0]&io_in[1]
assignio_out1=io_in[0]&io_in[1]|~io_in[2]&io_in[3];assignio_out2=_io_out1_T_4&(io_in[2]&io_in[3]);
endmoduleclassUseFuncextendsModule{
valio=IO(newBundle{
valin=Input(UInt(4.W))
valout1=Output(Bool())
valout2=Output(Bool())
})
defclb(a:UInt,b:UInt,c:UInt,d:UInt):UInt=
(a&b)|(~c&d)
io.out1:=clb(io.in(0),io.in(1),io.in(2),io.in(3))
io.out2:=and(and(io.in(0),io.in(1)),and(io.in(2),io.in(3)))
}
objectand{
defapply(a:UInt,b:UInt):UInt=a&b}一、用函數(shù)抽象組合邏輯定義在單例對(duì)象中定義在電路模塊里直接表示函數(shù)內(nèi)容而沒(méi)有生成verilog的函數(shù)4二、用工廠(chǎng)方法簡(jiǎn)化模塊的例化5二、用工廠(chǎng)方法簡(jiǎn)化模塊的例化在Scala里,往往在類(lèi)的伴生對(duì)象里定義一個(gè)工廠(chǎng)方法,來(lái)簡(jiǎn)化類(lèi)的實(shí)例化。同樣,Chisel的模塊也是Scala的類(lèi),也可以在其伴生對(duì)象里定義工廠(chǎng)方法來(lái)簡(jiǎn)化例化、連線(xiàn)模塊。類(lèi)new例化定義工廠(chǎng)方法直接例化工廠(chǎng)方法方法調(diào)用對(duì)外隱藏了類(lèi)的實(shí)現(xiàn)細(xì)節(jié)6二、用工廠(chǎng)方法簡(jiǎn)化模塊的例化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)
}
objectMux2{
defapply(sel:UInt,in0:UInt,in1:UInt)={
valm=Module(newMux2)
m.io.in0:=in0
m.io.in1:=in1
m.io.sel:=sel
m.io.out
}
}classMux4extendsModule{
valio=IO(newBundle{
valsel=Input(UInt(2.W))
valin0=Input(UInt(1.W))
valin1=Input(UInt(1.W))
valin2=Input(UInt(1.W))
valin3=Input(UInt(1.W))
valout=Output(UInt(1.W))
})
io.out:=Mux2(io.sel(1),
Mux2(io.sel(0),io.in0,io.in1),
Mux2(io.sel(0),io.in2,io.in3))
}在伴生對(duì)象中定義工廠(chǎng)方法直接調(diào)用工廠(chǎng)方法例化模塊7三、用Scala的函數(shù)簡(jiǎn)化代碼8三、用Scala的函數(shù)簡(jiǎn)化代碼只要能通過(guò)Firrtl編譯器的檢查,Scala的函數(shù)就能在Chisel里使用,并生成Verilog代碼。因此我們可以使用Scala的函數(shù)來(lái)簡(jiǎn)化代碼。classDecoder(n:Int)extendsRawModule{
valio=IO(newBundle{
valsel=Input(UInt(n.W))
valout=Output(UInt((1<<n).W))
})
valx=for(i<-0until(1<<n))yieldio.sel===i.U
//Vector(io.sel===0.U,io.sel===1.U.......)
valy=for(i<-0until(1<<n))yield1.U<<i
//Vector(1,2,4......(1<<n))
io.out:=MuxCase(0.U,xzipy)
}Chisel寫(xiě)法classDecoder(n:Int)extendsRawModule{
valio=IO(newBundle{
valsel=Input(UInt(n.W))
valout=Output(UInt((1<<n).W))
})
valx=for(i<-0until(1<<n))yieldio.sel===i.U
//Vector(io.sel===0.U,io.sel===1.U.......)
valy=for(i<-0until(1<<n))yield1.U<<i
//Vector(1,2,4......(1<<n))
io.out:=MuxCase(0.U,xzipy)
}Verilog寫(xiě)法9always@(sel)begin
if(sel==3'b000)data_out=8'h1;
elseif(sel==3'b001)data_out=8'h2;
elseif(sel==3'b010)data_out=8'h4;
elseif(sel==3'b011)data_out=8'h8;
elseif(sel==3'b100)data_out=8'h10;
elseif(sel==3'b101)data_out=8'h20;
elseif(sel==3'b110)data_out=8'h40;
elseif(sel==3'b111)data_out=8'h80;
elsedata_out=8'h80;
end四、Chisel的打印函數(shù)10四、Chisel的打印函數(shù)Chisel提供了一個(gè)“printf”函數(shù)來(lái)打印信息,用于電路調(diào)試。它具有Scala和C兩種風(fēng)格。注意:printf函數(shù)只能用在Chisel定義的模塊中必須要有時(shí)鐘和復(fù)位信號(hào)printf轉(zhuǎn)換成Verilog的系統(tǒng)函數(shù)“$fwrite”Scala里的printf函數(shù)要寫(xiě)成“Predef.printf”的完整路徑11四、Chisel的打印函數(shù)Chisel自定義了一個(gè)p插值器,該插值器可以對(duì)字符串內(nèi)的一些自定義表達(dá)式進(jìn)行求值、Chisel類(lèi)型轉(zhuǎn)化成字符串類(lèi)型等。簡(jiǎn)單類(lèi)型聚合數(shù)據(jù)類(lèi)型自定義打印信息4.1Scala風(fēng)格12valmyUInt=33.U
//顯示Chisel自定義的類(lèi)型的數(shù)據(jù)
printf(p"myUInt=$myUInt")
//顯示成十六進(jìn)制
printf(p"myUInt=0x${Hexadecimal(myUInt)}")
//顯示成二進(jìn)制
printf(p"myUInt=${Binary(myUInt)}")
//顯示成字符(ASCII碼)
printf(p"myUInt=${Character(myUInt)}")四、Chisel的打印函數(shù)簡(jiǎn)單數(shù)據(jù)類(lèi)型//myUInt=33//myUInt=0x21//myUInt=100001//myUInt=!13valmyVec=Vec(5.U,10.U,13.U)
printf(p"myVec=$myVec")
valmyBundle=Wire(newBundle{
vala=UInt()
valb=UInt()
})
myBundle.a:=3.U
myBundle.b:=11.U
printf(p"myBundle=$myBundle")四、Chisel的打印函數(shù)聚合數(shù)據(jù)類(lèi)型//myVec=Vec(5,10,13)
//myBundle=Bundle(a->3,b->11)14四、Chisel的打印函數(shù)自定義打印信息classMessageextendsBundle{
valvalid=Bool()
valaddr=UInt(32.W)
vallength=UInt(4.W)
valdata=UInt(64.W)
overridedeftoPrintable:Printable={
valchar=Mux(valid,'v'.U,'-'.U)
p"Message:\n"+
p"valid:${Character(char)}\n"+
p"addr:0x${Hexadecimal(addr)}\n"+
p"length:$length\n"+
p"data:0x${Hexadecimal(data)}\n"
}}
valmyMessage=Wire(newMessage)
myMessage.valid:=true.B
myMessage.addr:="h1234".U
myMessage.length:=10.U
myMessage.data:="hdeadbeef".U
printf(p"$myMessage")Message:Message:
valid:vMessage:
valid:v
addr:0x00001234Message:
valid:v
addr:0x00001234
length:10Message:
valid:v
addr:0x00001234
length:10
data:0x00000000deadbeefclassMessageextendsBundle{
valvalid=Bool()
valaddr=UInt(32.W)
vallength=UInt(4.W)
valdata=UInt(64.W)
overridedeftoPrintable:Printable={
valchar=Mux(valid,'v'.U,'-'.U)
p"Message:\n"+
p"valid:${Character(char)}\n"+
p"addr:0x${Hexadecimal(addr)}\n"+
p"length:$length\n"+
p"data:0x${Hexadecimal(data)}\n"
}}
valmyMessage=Wire(newMessage)
myMessage.valid:=true.B
myMessage.addr:="h1234".U
myMessage.length:=10.U
myMessage.data:="hdeadbeef".U
printf(p"$myMessage")15valmyUInt=32.U
printf("myUInt=%x",myUInt)valmyUInt=33.U
printf(p"myUInt=0x${Hexadecimal(myUInt)}")四、Chisel的打印函數(shù)4.2C風(fēng)格格式控制符含義%d十進(jìn)制數(shù)%x十六進(jìn)制數(shù)%b二進(jìn)制數(shù)%c8位ASCⅡ字符%%百分號(hào)%n一個(gè)信號(hào)的名字%N聚合類(lèi)里一個(gè)葉子信號(hào)的名字轉(zhuǎn)義字符含義\n換行\(zhòng)t制表符\"雙引號(hào)\'單引號(hào)\\斜杠Scala風(fēng)格C風(fēng)格16格式控制符含義%d十進(jìn)制數(shù)%x十六進(jìn)制數(shù)%b二進(jìn)制數(shù)%c8位ASCⅡ字符%%百分號(hào)%n一個(gè)信號(hào)的名字%N聚合類(lèi)里一個(gè)葉子信號(hào)的名字轉(zhuǎn)義字符含義\n換行\(zhòng)t制表符\"雙引號(hào)\'單引號(hào)\\斜杠五、Chisel的對(duì)數(shù)函數(shù)17五、Chisel的對(duì)數(shù)函數(shù)在二進(jìn)制運(yùn)算里,求以2為底的對(duì)數(shù)也是常用的運(yùn)算,chisel3.util包里有一個(gè)單例對(duì)象Log2。作用:
計(jì)算并返回輸入值以2為底的冪次,返回結(jié)果向下截?cái)郺pply方法:defapply(x:Bits):UIntLog2(8.U)//等于3.U
Log2(13.U)//等于3.U(向下截?cái)?
Log2(myUIntWire)//動(dòng)態(tài)求值Log2(8.U)//等于3.U
Log2(13.U)//等于3.U(向下截?cái)?
Log2(myUIntWire)//動(dòng)態(tài)求值18println(log2Floor(3))
println(log2Ceil(3))
println(log2Up(3))
println(log2Down(1))五、Chisel的對(duì)數(shù)函數(shù)chisel3.util包里還有四個(gè)單例對(duì)象:log2Ceil、log2Floor、log2Up和log2Down,它們的apply方法的參數(shù)都是BigInt類(lèi)型,返回結(jié)果都是Int類(lèi)型。apply方法:defapply(in:BigInt):Int對(duì)象名log2Ceillog2Floorlog2Uplog2Down作用向上舍入向下舍入向上舍入且最小為1向下舍入且最小為1122119對(duì)象名log2Ceillog2Floorlog2Uplog2Down作用向上舍入向下舍入向上舍入且最小為1向下舍入且最小為1六、與硬件相關(guān)的函數(shù)20六、與硬件相關(guān)的函數(shù)chisel3.util包中的單例對(duì)象Reverse,可以把一個(gè)UInt類(lèi)型的對(duì)象進(jìn)行旋轉(zhuǎn),返回一個(gè)對(duì)應(yīng)的UInt值。apply方法:defapply(in:UInt):UInt6.1位旋轉(zhuǎn)Reverse("b1101".U)//等于"b1011".U
Reverse("b1101".U(8.W))//等于"b10110000".U
Reverse(myUIntWire)//動(dòng)態(tài)旋轉(zhuǎn)Reverse("b1101".U)//等于"b1011".U
Reverse("b1101".U(8.W))//等于"b10110000".U
Reverse(myUIntWire)//動(dòng)態(tài)旋轉(zhuǎn)21六、與硬件相關(guān)的函數(shù)單例對(duì)象Cat有兩個(gè)apply方法,分別接收一個(gè)Bits類(lèi)型的序列和Bits類(lèi)型的重復(fù)參數(shù),將它們拼接成一個(gè)UInt數(shù)。前面的參數(shù)在高位。apply方法:defapply[T<:Bits](a:T,r:T*):UIntdefapply[T<:Bits](r:Seq[T]):UInt6.2位拼接Cat("b101".U,"b11".U)//等于"b10111".U
Cat(Seq("b101".U,"b11".U))//等于"b10111".U
Cat(myUIntWire0,myUIntWire1)//動(dòng)態(tài)拼接Cat("b101".U,"b11".U)//等于"b10111".U
Cat(Seq("b101".U,"b11".U))//等于"b10111".U
Cat(myUIntWire0,myUIntWire1)//動(dòng)態(tài)拼接22六、與硬件相關(guān)的函數(shù)單例對(duì)象PopCount有兩個(gè)apply方法,分別接收一個(gè)Bits類(lèi)型的參數(shù)和Bool類(lèi)型的序列,計(jì)算參數(shù)里“1”或“true.B”的個(gè)數(shù),返回對(duì)應(yīng)的UInt值。apply方法:defapply(in:Iterable[Bool]):UInt
defapply(in:Bits):UInt6.31計(jì)數(shù)器PopCount(Seq(true.B,false.B,true.B,true.B))//等于3.U
PopCount(Seq(false.B,false.B,true.B,false.B))//等于1.U
PopCount("b1011".U)//等于3.U
PopCount("b0010".U)//等于1.UPopCount(Seq(true.B,false.B,true.B,true.B))//等于3.U
PopCount(Seq(false.B,false.B,true.B,false.B))//等于1.U
PopCount("b1011".U)//等于3.U
PopCount("b0010".U)//等于1.U23六、與硬件相關(guān)的函數(shù)單例對(duì)象OHToUInt可以接收一個(gè)Bits類(lèi)型或Bool序列類(lèi)型的獨(dú)熱碼參數(shù),計(jì)算獨(dú)熱碼里的“1”在第幾位(從0開(kāi)始),返回對(duì)應(yīng)的UInt值。apply方法:defapply(in:Seq[Bool]):UInt
defapply(in:Bits):UInt6.4獨(dú)熱碼轉(zhuǎn)換器OHToUInt("b1000".U)//等于3.U
OHToUInt(Seq(true.B,false.B))//等于1.UOHToUInt("b1000".U)//等于3.U
OHToUInt(Seq(true.B,false.B))//等于1.U24六、與硬件相關(guān)的函數(shù)Verilog里可以用問(wèn)號(hào)表示無(wú)關(guān)位,那么進(jìn)行比較時(shí)就不會(huì)關(guān)心這些位。Chisel里有對(duì)應(yīng)的BitPat類(lèi),可以指定無(wú)關(guān)位。apply方法:defapply(n:String):BitPat6.5無(wú)關(guān)位"b10101".U===BitPat("b101??")//等于true.B
"b10111".U===BitPat("b101??")//等于true.B
"b10001".U===BitPat("b101??")//等于false.B"b10101".U===BitPat("b101??")//等于true.B
"b10111".U===BitPat("b101??")//等于true.B
"b10001".U===BitPat("b101??")//等于false.B25六、與硬件相關(guān)的函數(shù)單例對(duì)象Fill可以對(duì)輸入的數(shù)據(jù)進(jìn)行重復(fù)apply方法:defapply(n:Int,x:UInt):UInt6.6數(shù)據(jù)重復(fù)Fill(2,"b1000".U)//等于"b10001000".U
Fill(2,"b1001".U)//等于"b10011001".UFill(2,"b1000".U)//等于"b10001000".U
Fill(2,"b1001".U)//等于"b10011001".U26六、與硬件相關(guān)的函數(shù)單例對(duì)象FillInterleaved,它可以對(duì)輸入數(shù)據(jù)的每一位進(jìn)行重復(fù)apply方法:defapply(n:Int,in:Seq[Bool]):UIntdefapply(n:Int,in:UInt]):UInt6.7位重復(fù)FillInterleaved(2,Seq(true.B,false.B,false.B,false.B))//等于"b11000000".U
FillInterleaved(2,"b1000".U)//等于"b11000000".UFillInterleaved(2,Seq(true.B,false.B,false.B,false.B))
//等于"b11000000".U
FillInterleaved(2,"b1000".U)
//等于"b11000000".U27七、隱式類(lèi)的應(yīng)用28七、隱式類(lèi)的應(yīng)用在Scala中我們可以通過(guò)在某個(gè)單例對(duì)象中,以關(guān)鍵字“implicit”開(kāi)頭創(chuàng)建一個(gè)隱式類(lèi),從而實(shí)現(xiàn)隱式轉(zhuǎn)換。在Chisel中我們也可以使用隱式類(lèi)來(lái)構(gòu)建電路。objectmyAbs{
implicitclassAbsBits[T<:Bits](in:T){
defAbs={
Mux(in.head(1).asBool,(~in).asUInt+1.U,in.asUInt())
}
}
}
classBitsAbs(n:Int)extendsModule{
valio=IO(newBundle{
valin=Input(SInt(n.W))
valout=Output(UInt(n.W))
valin2=Input(UInt(n.W))
valout2=Output(UInt(n.W))
})
importmyAbs._
io.out:=io.in.Abs
io.out2:=io.in2.Abs
printf(p"Chiselprintf:in=${io.in}out=${io.out}in2=${io.in2}out2=${io.out2}\n")
}objectmyAbs{
implicitclassAbsBits[T<:Bits](in:T){
defAbs={
Mux(in.head(1).asBool,(~in).asUInt+1.U,in.asUInt())
}
}
}
classBitsAbs(n:Int)extendsModule{
valio=IO(newBundle{
valin=Input(SInt(n.W))
valout=Output(UInt(n.W))
valin2=Input(UInt(n.W)
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 小學(xué)生手工制作集錦
- 平行進(jìn)口汽車(chē)合規(guī)整改服務(wù)合同
- 音樂(lè)培訓(xùn)班招生合同協(xié)議2025年
- 中小學(xué)生中秋節(jié)習(xí)俗介紹班會(huì) 138
- 安全課件及講義
- 黑龍江省2024上半年黑龍江省水利廳事業(yè)單位招聘78人筆試歷年參考題庫(kù)典型考點(diǎn)附帶答案詳解(3卷合一)試卷2套
- 藝術(shù)培訓(xùn)故事創(chuàng)作課件
- 控制性卵巢刺激對(duì)黃體功能的影響與黃體支持
- Excel在會(huì)計(jì)與財(cái)務(wù)中的應(yīng)用 第2版 課件 第1章 Excel的基礎(chǔ)知識(shí)
- 幼兒對(duì)繪本戲劇表演的社交技能發(fā)展實(shí)證研究課題報(bào)告教學(xué)研究課題報(bào)告
- 初中道德與法治課中提升學(xué)生政治認(rèn)同素養(yǎng)的策略研究
- 活著,余華,下載
- 糖尿病的急救和護(hù)理
- 中醫(yī)養(yǎng)生的吃野山參粉養(yǎng)生法
- 居民自建樁安裝告知書(shū)回執(zhí)
- 小學(xué)道德與法治-認(rèn)識(shí)居民身份證教學(xué)課件設(shè)計(jì)
- 采購(gòu)滅火器施工方案
- 小學(xué)生古詩(shī)詞大賽備考題庫(kù)(300題)
- 國(guó)家開(kāi)放大學(xué)最新《監(jiān)督學(xué)》形考任務(wù)(1-4)試題解析和答案
- GB/T 25085.3-2020道路車(chē)輛汽車(chē)電纜第3部分:交流30 V或直流60 V單芯銅導(dǎo)體電纜的尺寸和要求
- GB/T 242-2007金屬管擴(kuò)口試驗(yàn)方法
評(píng)論
0/150
提交評(píng)論