版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
7.多时钟域设计一、没有隐式端口的模块二、定义一个时钟域和复位域三、使用时钟负沿和低有效复位四、示例:异步FIFO五、总结目录1一、没有隐式端口的模块2一、没有隐式端口的模块1.1RawModule继承自Module的模块类会获得隐式的全局时钟与同步复位信号,当我们不需要这两个隐式端口时,则可以选择继承自RawModule,这样在转换成Verilog时就没有隐式端口。3ModuleRawModule时钟隐式时钟无复位信号隐式同步复位无没有隐式端口的模块例子:含隐式端口importchisel3._
importchisel3.experimental._
importchisel3.stage.ChiselGeneratorAnnotation
classMyModuleextendsModule{
valio=IO(newBundle{
vala=Input(UInt(4.W))
valb=Input(UInt(4.W))
valc=Output(UInt(4.W))
})
io.c:=io.a&io.b
}moduleMyModule(
inputclock,
inputreset,
input[3:0]io_a,
input[3:0]io_b,
output[3:0]io_c
);
assignio_c=io_a&io_b;//@[MyRawModule.scala14:16]
endmodule一、没有隐式端口的模块4没有隐式端口的模块例子:无隐式端口importchisel3._
importchisel3.experimental._
importchisel3.stage.ChiselGeneratorAnnotation
classMyRawModuleextendsRawModule{
valio=IO(newBundle{
vala=Input(UInt(4.W))
valb=Input(UInt(4.W))
valc=Output(UInt(4.W))
})
io.c:=io.a&io.b
}moduleMyRawModule(
input[3:0]io_a,
input[3:0]io_b,
output[3:0]io_c
);
assignio_c=io_a&io_b;//@[MyRawModule.scala14:16]
endmodule一、没有隐式端口的模块5一、没有隐式端口的模块1.1RawModule这样的模块一般用于纯组合逻辑。由于其不再有隐式的时钟和复位信号,因此在其类内顶层不能出现使用时钟的相关操作。RawModule子类纯组合逻辑多时钟域语法时序逻辑6二、定义一个时钟域和复位域72.1withClockAndReset作用:创建一个新的时钟和复位域,作用范围仅限于它的传名参数的内部apply方法:defapply[T](clock:Clock,reset:Reset)(block:⇒T):T二、定义一个时钟域和复位域withClockAndReset是chisel3包里的一个单例对象8在Verilog中:定义时钟和复位信号的端口在always语句块中进行相应选择modulea(
inputclk,
inputrst_n
);
always(posedgeclkornegedgerst_n)
begin新的时钟和复位信号2.1withClockAndReset二、定义一个时钟域和复位域classMultiClockModuleextendsModule{
valio=IO(newBundle{
valclockB=Input(Clock())
valresetB=Input(Bool())
valstuff=Input(Bool())
})
valregClock1=RegNext(io.stuff)
withClockAndReset(io.clockB,io.resetB){
valregClockB=RegNext(io.stuff)
valm=Module(newChildModule)
}
valregClock2=RegNext(io.stuff)
}这个寄存器跟随当前模块的隐式全局时钟clock在该花括号内,所有时序元件都跟随时钟io.clockB和复位信号io.resetB这个寄存器跟随当前模块的隐式全局时钟clock92.1withClockAndReset二、定义一个时钟域和复位域classMultiClockModuleextendsModule{
valio=IO(newBundle{
valclockB=Input(Clock())
valresetB=Input(Bool())
valstuff=Input(Bool())
})
valclockB_child=withClockAndReset(io.clockB,io.resetB){
Module(newChildModule)
}
clockB_child.io.in:=io.stuff
}工厂方法:defapply[T](clock:Clock,reset:Reset)(block:⇒T):T例化其它模块在时钟域外对其赋值102.2withClock和withReset二、定义一个时钟域和复位域作用:分别用于构建只有独立时钟和只有独立复位信号的作用域apply方法:defapply[T](clock:Clock)(block:⇒T):Tdefapply[T](reset:Reset)(block:⇒T):TwithClock和withReset也是chisel3包里有单例对象11withClockAndResetwithClockwithReset独立时钟
独立复位信号
二、定义一个时钟域和复位域classChildModuleextendsModule{
valio=IO(newBundle{
valin=Input(Bool())
valclockChild=Input(Clock())
valout=Output(Bool())
})
withClock(io.clockChild){
//该寄存器跟随时钟io.clockChild,隐式复位信号reset
valregclock=RegNext(io.in,0.U)
io.out:=regclock
}
}classMultiClockTesterextendsModule{
valio=IO(newBundle{
valclockA=Input(Clock())
valresetA=Input(Bool())
valclockChild=Input(Clock())
valresetB=Input(Bool())
valstuff_in=Input(Bool())
valstuff_out=Output(Bool())
valoutregClock=Output(Bool())
valoutregClockA=Output(Bool())
valoutregClockB=Output(Bool())
})
//这个寄存器跟随当前模块的隐式全局时钟clock
valregClock=RegNext(io.stuff_in,0.U)
valclockA_child=withClockAndReset(io.clockA,io.resetA.asAsyncReset()){
//在该花括号内,所有时序元件都跟随时钟io.clockA
//所有寄存器的复位信号都是io.resetA
valregClockA=RegNext(io.stuff_in,0.U)
//这个寄存器跟随当前模块的隐式全局时钟clock
regClock:=regClockA
io.outregClockA:=regClockA
Module(newChildModule)
}clockA_child.io.clockChild:=io.clockChild
clockA_child.io.in:=io.stuff_in
io.stuff_out:=clockA_child.io.out
withReset(io.resetB){
//在该花括号内,所有时序元件都跟随时钟隐式时钟clock,复位信号都是io.resetB
valregClockB=RegNext(io.stuff_in,0.U)
io.outregClock:=regClock
io.outregClockB:=regClockB
}
}123122.2withClock和withReset二、定义一个时钟域和复位域一个寄存器只和它定义时所处的时钟域有关,即使在其他时钟域被赋值,那么它还是跟随自己被定义时的时钟。时钟域是可以嵌套的,当前的时钟域会覆盖掉上一层的时钟域。132.3复位信号的三种类型二、定义一个时钟域和复位域Reset是抽象类型,具体是同步复位还是异步复位需要根据上下文推断,也即既可以是同步,也可以异步。14复位信号BoolAsyncResetReset复位类型同步复位异步复位同步/异步当我们不希望其自动推断抽象类型的时候,可以在定义模块时通过混入以下特质,将reset的类型设置成我们想要的类型。混入RequireSyncReset特质可以将模块的隐式reset设置成同步复位信号。混入RequireAsyncReset
特质可以将模块的隐式reset设置成异步复位信号。二、定义一个时钟域和复位域classSyncResetModuleextendsMultiIOModulewithRequireSyncReset{
valSyncResetReg=RegInit(false.B)
}classAsyncResetModuleextendsMultiIOModulewithRequireAsyncReset{
valAsyncResetReg=RegInit(false.B)
}classSyncResetModuleextendsMultiIOModulewithRequireSyncReset{
valSyncResetReg=RegInit(false.B)//resetisoftypeBool
}classAsyncResetModuleextendsMultiIOModulewithRequireAsyncReset{
valAsyncResetReg=RegInit(false.B)//resetisoftypeAsyncReset
}15为了方便的修改任何复位信号的类型,我们还可以进行强制类型转换。使用reset.asBool()可以将复位信号从其他两种类型转换成Bool类型使用reset.asAsyncReset()可以将复位信号从其他两种类型转换成AsyncReset类型。二、定义一个时钟域和复位域16三、使用时钟负沿和低有效的复位信号17三、使用时钟负沿和低有效的复位信号Chisel:默认情况下,声明的时序元件都是以时钟的正沿和高有效的复位信号作为敏感变量。复位信号:只需要加上取反符号或逻辑非符号。时钟信号:需要先用asUInt方法把Clock类型转换成UInt类型,再用asBool转换成Bool类型,此时可以加上取反符号或逻辑非符号,最后再用asClock变回Clock类型。18Verilog:复位信号:使用取反符号或逻辑非符号。时钟信号:使用posedge或negedge。modulea(
inputclk,
inputrst_n
);
always(negedgeclk)
begin
if(!ret_n)classNegativeClkRstextendsRawModule{
valio=IO(newBundle{
valin=Input(UInt(4.W))
valmyClk=Input(Clock())
valmyRst=Input(Bool())
valout=Output(UInt(4.W))
})
withClockAndReset((~io.myClk.asUInt.asBool).asClock,~io.myRst){
valtemp=RegInit(0.U(4.W))
temp:=io.in
io.out:=temp
}
}三、使用时钟负沿和低有效的复位信号需要进行多次类型转换直接加上取反符号或逻辑非符号19四、示例:异步FIFO四、示例:异步FIFO下面是一个异步FIFO例子:数据位宽和深度都是参数化的,读、写地址指针的交互采用格雷码和两级寄存器采样,以便改善亚稳态。通过在Vivado2018.3里综合后,可以得到以BRAM为存储器的FIFO。21四、示例:异步FIFOclassFIFO(width:Int,depth:Int)extendsRawModule{
valio=IO(newBundle{
//write-domain
valdataIn=Input(UInt(width.W))
valwriteEn=Input(Bool())
valwriteClk=Input(Clock())
valfull=Output(Bool())
//read-domain
valdataOut=Output(UInt(width.W))
valreadEn=Input(Bool())
valreadClk=Input(Clock())
valempty=Output(Bool())
//reset
valsystemRst=Input(Bool())
})22四、示例:异步FIFOvalram=SyncReadMem(1<<depth,UInt(width.W))//2^depth
valwriteToReadPtr=Wire(UInt((depth+1).W))//toreadclockdomain
valreadToWritePtr=Wire(UInt((depth+1).W))//towriteclockdomain
//writeclockdomain
withClockAndReset(io.writeClk,io.systemRst){
valbinaryWritePtr=RegInit(0.U((depth+1).W))
valbinaryWritePtrNext=Wire(UInt((depth+1).W))
valgrayWritePtr=RegInit(0.U((depth+1).W))
valgrayWritePtrNext=Wire(UInt((depth+1).W))
valisFull=RegInit(false.B)
valfullValue=Wire(Bool())
valgrayReadPtrDelay0=RegNext(readToWritePtr)
valgrayReadPtrDelay1=RegNext(grayReadPtrDelay0)
binaryWritePtrNext:=binaryWritePtr+(io.writeEn&&!isFull).asUInt
binaryWritePtr:=binaryWritePtrNext
grayWritePtrNext:=(binaryWritePtrNext>>1).asUInt()^binaryWritePtrNext
grayWritePtr:=grayWritePtrNext
writeToReadPtr:=grayWritePtr
fullValue:=(grayWritePtrNext===Cat(~grayReadPtrDelay1(depth,depth-1),grayReadPtrDelay1(depth-2,0)))
isFull:=fullValue
when(io.writeEn&&!isFull){
ram.write(binaryWritePtr(depth-1,0),io.dataIn)
}
io.full:=isFull
}23四、示例:异步FIFO//readclockdomain
withClockAndReset(io.readClk,io.systemRst){
valbinaryReadPtr=RegInit(0.U((depth+1).W))
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年中职轻化工(日用化妆品生产)试题及答案
- 2025年大学大二(戏剧影视文学)戏剧理论基础测试题及答案
- 2025年大学(化学生物学)化学生物学概论试题及答案
- 2025年大学本科一年级(机械工程)机械原理基础测试题及答案
- 2025年大学机械基础应用技术(机械应用)试题及答案
- 2025年中职助产(助产实操)试题及答案
- 2025年大学工业机器人应用技术(机器人应用)试题及答案
- 2025年大学大三(生态学)海洋生态学综合测试题及答案
- 2026年广东机电职业技术学院高职单招职业适应性测试模拟试题有答案解析
- 2026年河南科技职业大学单招综合素质笔试模拟试题带答案解析
- 220kV升压站调试施工方案
- 新人教版数学六年级下册全册课本练习题可编辑可打印
- 教育管理社会调查分析报告
- 小学生心理健康咨询个案辅导记录
- YYT 0771.2-2009 动物源医疗器械 第2部分 来源、收集与处置的控制
- QCT265-2023汽车零部件编号规则
- 快电子期末50题参考答案
- (高清版)TDT 1071-2022 园地分等定级规程
- 江陵亚东建材水泥有限公司 年产150万吨水泥研磨及年产50万吨矿渣粉-复合掺合料生产线项目环评报告
- 市政工程安全文明施工组织设计样本
- 桩基中的钢筋笼工程量EXCLE表计算
评论
0/150
提交评论