《敏捷硬件開發(fā)語言Chisel與數(shù)字系統(tǒng)設(shè)計(jì)》全套教學(xué)課件_第1頁
《敏捷硬件開發(fā)語言Chisel與數(shù)字系統(tǒng)設(shè)計(jì)》全套教學(xué)課件_第2頁
《敏捷硬件開發(fā)語言Chisel與數(shù)字系統(tǒng)設(shè)計(jì)》全套教學(xué)課件_第3頁
《敏捷硬件開發(fā)語言Chisel與數(shù)字系統(tǒng)設(shè)計(jì)》全套教學(xué)課件_第4頁
《敏捷硬件開發(fā)語言Chisel與數(shù)字系統(tǒng)設(shè)計(jì)》全套教學(xué)課件_第5頁
已閱讀5頁,還剩636頁未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

1.新型敏捷硬件開發(fā)語言——Chisel和Scala

全套可編輯PPT課件

一、什么是Scala二、什么是Chisel三、Scala安裝與運(yùn)行四、總結(jié)目

錄2一、什么是Scala3

什么是Scala1.1Scala與Java運(yùn)行環(huán)境:Scala是一門基于JVM運(yùn)行的語言。語法特性:

直接訪問java字段,調(diào)用java方法等。實(shí)用性:比java更簡(jiǎn)潔,語法功能也更強(qiáng)大。4什么是Scala1.2Scala特點(diǎn)面向?qū)ο?,函?shù)式編程:

函數(shù)式編程(functional):what,how。

命令式編程(Imperative):how,what。強(qiáng)大伸縮性:

自定義Scala類庫,快速開發(fā)出“新”語言。Chisel就是以Scala為宿主語言構(gòu)建的。5二、什么是Chisel6什么是Chisel2.1Verilog發(fā)展出現(xiàn):

1983年由GDA公司的PhilMoorby首創(chuàng)。突破:

PhilMoorby提出了用于快速門級(jí)仿真的XL算法。快速發(fā)展:

1989年,Cadence公司收購GDA公司,隨后對(duì)VerilogHDL進(jìn)行了公開。標(biāo)準(zhǔn)化:

1995年,

VerilogHDL的IEEE標(biāo)準(zhǔn)誕生。7什么是Chisel

Chisel全稱:

ConstructingHardwareinScalaEmbeddedLanguage開發(fā)團(tuán)隊(duì):

加州大學(xué)伯克利分校團(tuán)隊(duì)開發(fā)的新型硬件描述語言。特性:

操作符即方法,純粹的面向?qū)ο蟮取2话琕erilog的不可綜合語法。效果:

極大地提高硬件開發(fā)的效率。轉(zhuǎn)換形式:

2.2Chisel由來Chisel文件firrtl文件Verilog文件8三、Scala安裝9Scala安裝3.1ubuntu下安裝查看系統(tǒng)Java版本:下載對(duì)應(yīng)安裝包并安裝:Scala版本應(yīng)該與Java版本一致Linux系統(tǒng)應(yīng)選擇deb或者rpm文件10xjtu-chisel@ubuntu:~$java-version

openjdkversion"11.0.11"2021-04-20Scala安裝使用Scala解釋器:退出Scala解釋器:

3.1ubuntu下安裝11xjtu_chisel@ubuntu:~$scala

WelcometoScala2.11.12(OpenJDK64-BitServerVM,Java11.0.11).

Typeinexpressionsforevaluation.ortry:help.

scala>1+2

valres0:Int=3

scala>println("Hello,world!")

Hello,world!scala>:q

xjtu_chisel@ubuntu:~$鍵入:q或者:quit可退出Scala解釋器Scala安裝3.1ubuntu下安裝運(yùn)行腳本文件:編譯非腳本文件://hello.scala

println("Hello,world!")classHello{

valhw="Hello,world!"

defdisplay()=println(hw)

}使用scala命令使用scalac或者fsc命令12Scala安裝3.2IDEA工具開發(fā)下載安裝軟件并配置好開發(fā)環(huán)境:JDK版本選擇1.813Scala安裝3.2IDEA工具開發(fā)運(yùn)行調(diào)試:objecttest{

defmain(args:Array[String]):Unit={

vara=0;

for(a<-1until6){

println("Valueofa:"+a);

}

}

}Valueofa:1Valueofa:2Valueofa:3Valueofa:4Valueofa:5控制臺(tái)輸出14四、總結(jié)15總結(jié)16

本章主要介紹了Scala與Chisel的背景以及開發(fā)環(huán)境安裝。

在開發(fā)環(huán)境安裝這一塊,可以使用命令行的形式直接運(yùn)行Scala腳本文件和編譯非腳本文件,也可以使用集成開發(fā)環(huán)境IDEA,本書推薦使用IDEA進(jìn)行Scala開發(fā)。參考資料基礎(chǔ)知識(shí)

在學(xué)習(xí)Chisel前,初學(xué)者應(yīng)該掌握一定的面向?qū)ο蟮乃枷?。建議初學(xué)者先學(xué)習(xí)第二篇的Scala部分。參考資料1Chisel3官網(wǎng)/2Chisel3開源github網(wǎng)址/chipsalliance/chisel33伯克利Chisel開源項(xiàng)目chisel-tutorial、chiseltest、chipyard等/ucb-bar4課題組維護(hù)的博客/qq_34291505/article/details/86744581?utm_source=app5chisel-template網(wǎng)址/freechipsproject/chisel-template6Chisel官方bootcamp/v2/gh/freechipsproject/chisel-bootcamp/master7RocketChip網(wǎng)址/chipsalliance/rocket-chip8chipyard文檔https://chipyard.readthedocs.io/17謝謝大家2.Chisel入門及數(shù)據(jù)類型

一、Chisel開發(fā)環(huán)境安裝二、Chisel的常見問題三、Chisel的變量與數(shù)據(jù)類型四、總結(jié)目

錄20一、Chisel開發(fā)環(huán)境安裝21Chisel開發(fā)環(huán)境安裝1.1安裝步驟安裝SBT:安裝Git:

Scala的構(gòu)建工具方便后續(xù)項(xiàng)目開發(fā)xjtu-chisel@ubuntu:~$sbtsbtVersion

[info]welcometosbt1.4.6(PrivateBuildJava1.8.0_275)

[info]loadingprojectdefinitionfrom/home/xjtu-chisel/project

[info]setcurrentprojecttoxjtu-chisel(inbuildfile:/home/xjtu-chisel/)

[info]1.4.6xjtu-chisel@ubuntu:~$sudoapt-getinstallgit

xjtu-chisel@ubuntu:~$git–version

gitversion2.25.122Chisel開發(fā)環(huán)境安裝1.1安裝步驟安裝Verilator:安裝g++:

開源高性能VerilogHDL仿真器C++編譯器,Verilator會(huì)用到xjtu-chisel@ubuntu:~$sudoapt-getinstallverilator

xjtu-chisel@ubuntu:~$verilator-version

Verilator4.0282020-02-06revv4.026-92-g890cecc1xjtu-chisel@ubuntu:~$sudoapt-getinstallg++

xjtu-chisel@ubuntu:~$g++-v

gccversion7.5.0(Ubuntu7.5.0-3ubuntu1~18.04)23Chisel開發(fā)環(huán)境安裝1.1安裝步驟安裝GTKWave:安裝Chisel:

波形查看器從github上克隆chisel-template,其自帶了Chisel3.4.3,后續(xù)項(xiàng)目都是基于這個(gè)工程開發(fā)xjtu-chisel@ubuntu:~$sudoapt-getinstallgtkwavexjtu-chisel@ubuntu:~$gitclonehttps:///freechipsproject/chisel-template24Chisel開發(fā)環(huán)境安裝1.2工程文件目錄Chisel的設(shè)計(jì)部分文件測(cè)試文件和生成電路的主函數(shù)自定義工程文件與Chisel互動(dòng)的外部文件25Chisel開發(fā)環(huán)境安裝1.2環(huán)境測(cè)試主工程文件:

packagetest

importchisel3._

classANDextendsRawModule{

valio=IO(newBundle{

vala=Input(UInt(1.W))

valb=Input(UInt(1.W))

valc=Output(UInt(1.W))

})

io.c:=io.a&io.b}端口定義二輸入與門邏輯26Chisel開發(fā)環(huán)境安裝1.2環(huán)境測(cè)試生成電路的主函數(shù):

//ANDtest.scala

packagetest

importchisel3.stage.ChiselGeneratorAnnotation

objecttestMainextendsApp{

(newchisel3.stage.ChiselStage).execute(Array("--target-dir","generated/and"),Seq(ChiselGeneratorAnnotation(()=>newAND)))

}27Chisel實(shí)現(xiàn)簡(jiǎn)單電路1.2環(huán)境測(cè)試moduleAND(

inputio_a,

inputio_b,

outputio_c

);

assignio_c=io_a&io_b;//@[and.scala11:16]

endmodule生成Verilog文件:對(duì)于大規(guī)模電路,用生成的Verilog文件在專業(yè)EDA工具里仿真。28二、Chisel常見問題29Chisel常見問題2.1常見問題寄宿在Scala里面。轉(zhuǎn)變成Verilog時(shí)不會(huì)采用不可綜合語法。只支持0,1邏輯。自動(dòng)檢測(cè)未被驅(qū)動(dòng)的輸出型線網(wǎng)或端口。代碼包不會(huì)被隱式導(dǎo)入。Chisel仍在更新中。30三、Chisel的變量與數(shù)據(jù)類型31Chisel的變量與數(shù)據(jù)類型3.1數(shù)據(jù)類型長(zhǎng)方形是trait,三角形是object,橢圓形是class。32Chisel的變量與數(shù)據(jù)類型3.2數(shù)據(jù)字面量構(gòu)造UInt對(duì)象:1.U//字面值為“1”的UInt對(duì)象0xd.U//字面值為“14”的UInt對(duì)象構(gòu)造SInt對(duì)象:-8.S//字面值為“-8”的SInt對(duì)象構(gòu)造Bool對(duì)象:true.B//字面值為“true”的Bool對(duì)象構(gòu)造UInt,SInt對(duì)象,其實(shí)調(diào)用了fromtIntToLiteral(1).U的方法,Bool則是fromBooleanToLiteral33Chisel的變量與數(shù)據(jù)類型3.3數(shù)據(jù)寬度默認(rèn)情況,數(shù)據(jù)寬度按字面值取最小:1.U字面值為“1”、寬度為1bit的UInt對(duì)象構(gòu)造指定寬度的對(duì)象:1.U(32.W)字面值為“1”、寬度為32bit的UInt對(duì)象-8.S(32.W)字面值為“-8”、寬度為32bit的SInt對(duì)象取數(shù)據(jù)的某一位:1.U(31)字面值為“0”、寬度為1bit的UInt對(duì)象1.U(0)字面值為“1”、寬度為1bit的UInt對(duì)象34Chisel的變量與數(shù)據(jù)類型3.4類型轉(zhuǎn)換類型轉(zhuǎn)換包括asUInt、asSInt、asBool和asBools:"ha".asUInt(8.W)-1.S(3.W).asUInt、輔助完成子字賦值:

classTestModuleextendsModule{

valio=IO(newBundle{

valin=Input(UInt(10.W))

valbit=Output(Bool())

valout=Output(UInt(10.W))

})

valbools=VecInit(io.in.asBools)

bools(0):=io.bit

io.out:=bools.asUInt}35Chisel的變量與數(shù)據(jù)類型3.5向量定義:參數(shù):

第一個(gè)參數(shù):元素的個(gè)數(shù)

第二個(gè)參數(shù):元素的類型與位寬提取向量中某個(gè)元素:

valmyVec=Wire(Vec(3,UInt(32.W)))valmyReg_0=myVec(0)

valmyReg_1=myVec(1.U)36Chisel的變量與數(shù)據(jù)類型3.5向量高級(jí)用法一

37Chisel的變量與數(shù)據(jù)類型3.5向量38Chisel的變量與數(shù)據(jù)類型3.5向量高級(jí)用法二

39Chisel的變量與數(shù)據(jù)類型3.5向量40Chisel的變量與數(shù)據(jù)類型3.5包裹構(gòu)建端口列表可以包含向量classMyModuleextendsModule{

valio=IO(newBundle{

valin=Input(UInt(32.W))

valout=Output(UInt(32.W))

})classMyBundleextendsBundle{

valfoo=UInt(4.W)

valbar=Vec(2,UInt(4.W))

}41Chisel的變量與數(shù)據(jù)類型3.5包裹字段拼接classMyBundleextendsBundle{

valfoo=UInt(4.W)//高位

valbar=UInt(4.W)//低位

}

valbundle=Wire(newMyBundle)

bundle.foo:=0xc.U

bundle.bar:=0x3.U

valuint=bundle.asUInt//12*16+3=195wire[7:0]uint;

reg[3:0]foo=4’hc;reg

[3:0]bar=4’h3;

assignuint={

foo,

bar};//把foo和bar拼接成uint。42Chisel的變量與數(shù)據(jù)類型3.5包裹完成拼接變量的賦值wire[1:0]a;

wire[3:0]b;

wire[2:0]c;

wire[8:0]z=[...];

assign{a,b,c}=z;classMyBundleextendsBundle{

vala=UInt(2.W)

valb=UInt(4.W)

valc=UInt(3.W)

}

valz=Wire(UInt(9.W))

z:=...

valunpacked=z.asTypeOf(newMyBundle)

unpacked.a

unpacked.b

unpacked.c43Chisel的變量與數(shù)據(jù)類型3.5內(nèi)建操作符Chisel的內(nèi)建操作符操作符釋義位操作符作用類型:

SInt,UInt,BoolvalinvertedX=~x位取反valhiBits=x&"h_ffff_0000".U位與valflagsOut=flagsIn|overflow位或valflagsOut=flagsIn^toggle位異或縮減位操作符作用類型:

SInt,UInt

返回類型:BoolvalallSet=x.andR縮減與valanySet=x.orR縮減或44Chisel的變量與數(shù)據(jù)類型3.6位寬推斷Chisel的位寬推斷操作符位寬z=x+y

or

z=x+%yw(z)=max(w(x),w(y))z=x+&yw(z)=max(w(x),w(y))+1z=x-y

or

z=x-%yw(z)=max(w(x),w(y))z=x-&yw(z)=max(w(x),w(y))+1z=x&yw(z)=min(w(x),w(y))z=Mux(c,x,y)w(z)=max(w(x),w(y))z=w*yw(z)=w(x)+w(y)z=x<<nw(z)=w(x)+maxNum(n)45四、總結(jié)46總結(jié)

本章主要是Chisel開發(fā)環(huán)境的安裝以及Chisel的變量和數(shù)據(jù)類型的介紹。

對(duì)于Chisel開發(fā)環(huán)境安裝部分,要能夠搭建起開發(fā)環(huán)境并實(shí)現(xiàn)由Chisel生成Verilog的流程。此外本章還應(yīng)掌握數(shù)據(jù)字面量,數(shù)據(jù)位寬定義,包裹,向量等基本數(shù)據(jù)類型及其常見用法。47謝謝大家

3.模塊與硬件類型一、硬件類型二、賦值三、端口四、模塊五、線網(wǎng)六、寄存器(組)七、補(bǔ)充與總結(jié)50目

錄一、硬件類型51

硬件類型

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))52二、賦值53賦值首次創(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í)與“=”一致,是最低的54三、端口55端口3.1定義端口列表端口列表是由方法“IO[T<:Data](iodef:T)”定義參數(shù)通常是一個(gè)Bundle類型的對(duì)象而且引用的字段名稱必須是“io”(繼承自Module的模塊)56端口通過“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è)端口表明具體方向57端口3.3翻轉(zhuǎn)端口列表的方向使用情況:

對(duì)于兩個(gè)相連的模塊,可能存在大量同名但方向相反的端口方法:Flipped[T<:Data](source:T)實(shí)現(xiàn)細(xì)節(jié)

其把參數(shù)里所有的輸入端口轉(zhuǎn)為輸出端口,輸出端口轉(zhuǎn)為輸入端口

58端口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是輸入

......

}59MyModule_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

}60四、模塊614.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ù)位624.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è)二選一多路選擇器:63模塊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)建四輸入多路選擇器:64模塊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))

})65模塊生成序列的方法:

調(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

}66五、線網(wǎng)67線網(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.1Wire68Wire不提供位寬參數(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.knownissetto869WireDefault例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.2WireDefault70WireDefault例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.knownissetto871WireDefault帶有兩個(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};72六、寄存器(組)73寄存器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ì)象74寄存器和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.knownissetto875寄存器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)。76寄存器例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)//widthwillbeinferred77寄存器例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.knownissetto878寄存器帶有兩個(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)連接。79第一個(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ù)位初始化。例:80寄存器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)81寄存器使用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異步寄存器82寄存器如果把子類型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寄存器組83寄存器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

}84七、補(bǔ)充與總結(jié)85補(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}86補(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è)二選一多路選擇器:87unlessimportchisel3.util._

unless(condition){definition}除了when結(jié)構(gòu),util包里還有一個(gè)與之對(duì)偶的結(jié)構(gòu)“unless”,如果unless的判定條件為false.B,則一直執(zhí)行,否則不執(zhí)行7.2unless88總結(jié)數(shù)據(jù)類型必須配合硬件類型才能使用,它不能獨(dú)立存在,因?yàn)榫幾g器只會(huì)把硬件類型生成對(duì)應(yīng)的Verilog代碼。這是因?yàn)榉椒╒ec期望第二個(gè)參數(shù)是數(shù)據(jù)類型,這樣它才能推斷出返回的Vec[T]是數(shù)據(jù)類型。但實(shí)際的“io.a”是經(jīng)過Input封裝過的硬件類型,導(dǎo)致Vec[T]變成了硬件類型,所以發(fā)生了類型匹配錯(cuò)誤。valreg0=RegNext(VecInit(io.a,io.a))//正確

valreg0=RegNext(Vec(2,io.a))//錯(cuò)誤,報(bào)錯(cuò)如下

//[error]chisel3.core.Binding$ExpectedChiselTypeException:vectype'chisel3.core.UInt@6147b2fd'mustbeaChiseltype,nothardware

89總結(jié)Chisel提供了一個(gè)用戶API——chiselTypeOf[T<:Data](target:T):T,其作用就是把硬件類型的“封皮”去掉,變成純粹的數(shù)據(jù)類型。這次是RegNext出錯(cuò)了。RegNext需要根據(jù)入?yún)硗茢喾祷亟Y(jié)果的類型,所以傳入一個(gè)數(shù)據(jù)類型Vec[T]就引發(fā)了錯(cuò)誤。VecInit專門接收硬件類型的參數(shù)來構(gòu)造硬件向量,給VecInit傳入數(shù)據(jù)類型反而會(huì)報(bào)錯(cuò),盡管它的返回類型也是Vec[T]。

valreg0=RegNext(Vec(2,chiselTypeOf(io.a)))//依然錯(cuò)誤,錯(cuò)誤信息如下

//[error]chisel3.core.Binding$ExpectedHardwareException:regnext'Vec(chisel3.core.UInt@65b0972a,chisel3.core.UInt@25155aa4)'mustbehardware,notabareChiseltype.PerhapsyouforgottowrapitinWire(_)orIO(_)?90總結(jié)

寄存器組部分例子: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)))

valreg5=RegEnable(VecInit(io.a+1.U,io.a+1.U),VecInit(0.U(8.W),0.U(8.W)),io.en)

valreg7=ShiftRegister(VecInit(io.a,io.a),3,VecInit(0.U(8.W),0.U(8.W)),io.en)甚至是帶有字面量的數(shù)據(jù)類型,比如“0.U(8.W)”這樣的對(duì)象,也被當(dāng)作是硬件類型。另外,Reg(_)的參數(shù)是數(shù)據(jù)類型,不是硬件類型,所以示例代碼中它的參數(shù)是Vec,而別的參數(shù)都是VecInit。91謝謝大家

4.Chisel常用的硬件原語一、多路選擇器二、優(yōu)先編碼器三、仲裁器四、隊(duì)列五、ROM六、RAM七、計(jì)數(shù)器八、線性反饋移位寄存器九、狀態(tài)機(jī)94目

錄一、多路選擇器95多路選擇器二輸入多路選擇器”Mux(sel,in1,in2)”sel是Bool類型;in1和in2的類型相同,都是Data的任意子類型。當(dāng)sel為true.B時(shí),返回in1,否則返回in2可內(nèi)嵌Mux,構(gòu)成n輸入,例:

“Mux(c1,a,Mux(c2,b,Mux(...,default)))”1.1Mux96多路選擇器1.2MuxCasen輸入多路選擇器”MuxCase(default,Array(c1->a,c2->b,...))”第一個(gè)參數(shù)是默認(rèn)情況下返回的結(jié)果;第二個(gè)參數(shù)是一個(gè)數(shù)組,數(shù)組的元素是對(duì)偶“(成立條件,被選擇的輸入)”。97多路選擇器MuxCase的變體,類似查找表“MuxLookup(idx,default,Array(0.U->a,1.U->b,...))”相當(dāng)于把MuxCase的成立條件依次換成從0開始的索引值它的展開相當(dāng)于:“MuxCase(default,Array((idx===0.U)->a,(idx===1.U)->b,...))”1.3MuxLookup98多路選擇器1.4Mux1H獨(dú)熱碼多路選擇器如果零個(gè)或多個(gè)選擇信號(hào)有效,則行為變?yōu)槎鄠€(gè)被選擇數(shù)字之和Mux1H三種常用的定義形式(等價(jià)):valhotValue=Mux1H(io.selector,Seq(2.U,4.U,8.U,11.U))

valhotValue=Mux1H(Seq(io.selector(0),io.selector(1),

io.selector(2),io.selector(3)),Seq(2.U,4.U,8.U,11.U))

valhotValue=Mux1H(Seq(

io.selector(0)->2.U,

io.selector(1)->4.U,

io.selector(2)->8.U,

io.selector(3)->11.U

))io.selectorSeq(2.U,4.U,8.U,11.U)00012.U00104.U01008.U100011.U99多路選擇器1.5PriorityMux當(dāng)多個(gè)選擇信號(hào)有效時(shí),按照定義時(shí)的順序,返回更靠前的被選數(shù)據(jù)。有以下三種定義形式(等價(jià)):valpriorityValue=PriorityMux(io.selector,Seq(2.U,4.U,8.U,11.U))

valpriorityValue=PriorityMux(Seq(io.selector(0),io.selector(1),

io.selector(2),io.selector(3)),

Seq(2.U,4.U,8.U,11.U))

valpriorityValue=PriorityMux(Seq(

io.selector(0)->2.U,

io.selector(1)->4.U,

io.selector(2)->8.U,

io.selector(3)->11.U,

))io.selectorSeq(2.U,4.U,8.U,11.U)xxx12.Uxx104.Ux1008.U100011.U100二、優(yōu)先編碼器101優(yōu)先編碼器2.1PriorityEncoderPriorityEncoder("b1010".U)

PriorityEncoder(Seq(false.B,true.B,false.B,true.B))作用是對(duì)多個(gè)輸入信號(hào)中優(yōu)先級(jí)最高的一個(gè)信號(hào)進(jìn)行編碼。有以下兩種定義形式:以上兩種形式是等價(jià)的,返回值類型都是UInt,值為1.U。入?yún)ⅲ築its返回值:UIntxxx10.Uxx101.Ux1002.U10003.U102優(yōu)先編碼器2.2PriorityEncoderOH有以下兩種定義形式:PriorityEncoderOH("b1010".U)

PriorityEncoderOH(Seq(false.B,true.B,true.B,false.B))它和第一種編碼器的區(qū)別在于該編碼器會(huì)把編碼結(jié)果轉(zhuǎn)換成獨(dú)熱碼。第一種形式返回一個(gè)UInt的數(shù)據(jù)2.U,第二種形式返回一個(gè)Seq:Seq(false.B,true.B,false.B,false.B)。入?yún)ⅲ築its返回值:Uintxxx10001xx100010x100010010001000103三、仲裁器104仲裁器3.1ready-valid接口Arbiter使用的是標(biāo)準(zhǔn)的ready-valid接口,該類型的端口在單一數(shù)據(jù)信號(hào)的基礎(chǔ)上又添加了ready和valid信號(hào)以使用ready-valid握手協(xié)議。它包含3個(gè)信號(hào):ready:高有效時(shí)表示數(shù)據(jù)接收者consumer已經(jīng)準(zhǔn)備好接收信號(hào),由consumer驅(qū)動(dòng)。valid:高有效時(shí)表示數(shù)據(jù)生產(chǎn)者producer已經(jīng)準(zhǔn)備好待發(fā)送的數(shù)據(jù)了,由producer驅(qū)動(dòng)。bits:是要在producer與consumer之間傳輸?shù)臄?shù)據(jù)。105仲裁器使用單例對(duì)象Decoupled可創(chuàng)建ready-valid接口,有以下兩種形式:

Decoupled(...):可以傳入任意的數(shù)據(jù)類型,然后返回一個(gè)ready-valid接口,此時(shí)ready是input信號(hào),valid和bits都是output信號(hào)。因此它是屬于數(shù)據(jù)生產(chǎn)者producer的端口。

Flipped(Decoupled(...)):Flipped()會(huì)將ready-valid接口的信號(hào)方向進(jìn)行取反,因此此時(shí)ready是output信號(hào),valid和bits都是input信號(hào)。因此它是屬于數(shù)據(jù)接收者consumer的端口。106仲裁器producerDecoupled(...)readyvalidbitsconsumerFlipped(Decoupled(...))readyvalidbits107仲裁器3.2優(yōu)先仲裁器優(yōu)先仲裁器的輸入通道的優(yōu)先級(jí)是固定的,每次都是選擇多個(gè)有效通道中優(yōu)先級(jí)最高的。創(chuàng)建Arbiter對(duì)象的方式為newArbiter(gen:T,n:Int)gen是傳輸?shù)臄?shù)據(jù)的類型,n是待仲裁對(duì)象的個(gè)數(shù),也即數(shù)據(jù)發(fā)送者producer的個(gè)數(shù)。數(shù)據(jù)接收者consumer的個(gè)數(shù)為默認(rèn)為1。108仲裁器Arbiter內(nèi)部使用ArbiterIO定義端口,而ArbiterIO內(nèi)部又使用Decoupled()創(chuàng)建最終所需的ready-valid接口,定義如下:classArbiterIO[T<:Data](privatevalgen:T,valn:Int)extendsBundle{

valin=Flipped(Vec(n,Decoupled(gen)))

valout=Decoupled(gen)

valchosen=Output(UInt(log2Ceil(n).W))

}”log2Ceil(n)”是實(shí)現(xiàn)的是以2為底的對(duì)數(shù)函數(shù)的計(jì)算,把結(jié)果向上取整返回109仲裁器producer0readyvalidbitsconsumerreadyvalidbitsArbiterin(0).validin(0).bitsin(0).readyin(1).validin(1).bitsin(1).readyout.bitsout.readyout.validchosenproducer1readyvalidbitschosen110仲裁器例:

溫馨提示

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

評(píng)論

0/150

提交評(píng)論