敏捷硬件開(kāi)發(fā)語(yǔ)言Chisel與數(shù)字系統(tǒng)設(shè)計(jì) 課件 第8章 函數(shù)的應(yīng)用_第1頁(yè)
敏捷硬件開(kāi)發(fā)語(yǔ)言Chisel與數(shù)字系統(tǒng)設(shè)計(jì) 課件 第8章 函數(shù)的應(yīng)用_第2頁(yè)
敏捷硬件開(kāi)發(fā)語(yǔ)言Chisel與數(shù)字系統(tǒng)設(shè)計(jì) 課件 第8章 函數(shù)的應(yīng)用_第3頁(yè)
敏捷硬件開(kāi)發(fā)語(yǔ)言Chisel與數(shù)字系統(tǒng)設(shè)計(jì) 課件 第8章 函數(shù)的應(yīng)用_第4頁(yè)
敏捷硬件開(kāi)發(fā)語(yǔ)言Chisel與數(shù)字系統(tǒng)設(shè)計(jì) 課件 第8章 函數(shù)的應(yīng)用_第5頁(yè)
已閱讀5頁(yè),還剩31頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(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ì)自己和他人造成任何形式的傷害或損失。

最新文檔

評(píng)論

0/150

提交評(píng)論