Chisel入门教程

来源:互联网 发布:linux 百度网盘 编辑:程序博客网 时间:2024/06/17 23:23
Chisel的基本概念
1、Chisel硬件表达
此版本的Chisel只支持二进制逻辑,不支持三态信号。

2、Chisel数据类型
数据类型用于指定状态元素中保存的值或wire上传输的值。 
类型有SInt,UInt,Bool,Bundle,Vcc。

Bundles&Vecs 
Bundle和Vec是可以允许用户使用其他数据类型来扩展Chisel数据类型集合的类。Bundle用class来定义,用户可以通过将一个类定义为Bundle的子类来定义自己的bundle。
原始类(SInt,UInt和Bool)加上聚合类(Bundles和Vecs)都继承自一个公共的超类Data。在电路中,每个最终继承自Data的对象都可以表示为一个位向量

3、组合电路
在Chisel中,电路会被表示为一张节点图。每个节点是具有零个或多个输入并驱动一个输出的硬件运算符。
Uint是一种退化类型的节点,它没有输入,并且在其输出上驱动一个恒定的值。创建和连接节点的一种方法是使用字面表达式。
eg. (a&b)|(c&d)
任何简单的表达式都可以直接转换成电路树,在叶子处使用命名的导线和操作符形成内部节点。表达式的电路输出取自树根处的运算符,在本示例中是按位或运算

3、函数
我们可以定义函数来分解一个重复的逻辑,这样可以在后续设计中重复使用。
eg. def clb(a: UInt, b: UInt, c: UInt, d: UInt): UInt = (a & b) | (~c & d)
其中clb是表示以a,b,c,d为参数的函数,并返回一个布尔电路的输出。def关键字是Scala的一部分,表示引入了一个函数定义,每个语句后面跟一个冒号,然后是它的类型,函数返回类型在参数列表之后的冒号之后。(=)符号将函数参数列表与函数定义分隔开。 
然后我们就可以在其他的电路中使用了:
val out = clb(a,b,c,d)

4、端口
端口用作硬件组件的接口。一个端口可以是任意的Data对象,但它是具有方向的。 Chisel提供端口构造函数,以允许在构建时给对象添加(输入或输出)。原始的端口构造函数需要将方向作为第一个参数(方向为INPUT或OUTPUT),将位数作为第二个参数(除了始终为1位的布尔值)。
eg. 端口声明如下所示
class Decoupled extends Bundle {
val ready = Bool(OUTPUT)
val data = UInt(INPUT, 32)
val valid = Bool(INPUT)
}

5、模块
我们现在可以构建电路层次,我们可以从较小的子模块开开始构建更大的模块。
Module用class来定义,继承Module。

6、状态元素
Chisel支持的状态元素的最简单形式是上升沿触发寄存器,可以实例化为:
val reg  = Reg(next = in)
该电路具有输出,该输出是前一个时钟周期的输入信号产生的值。在当前版本的Chisel中,时钟和复位是全局信号,在需要时可以隐式包含。

6.1、转发声明
纯组合电路在节点之间不存在周期,如果检测到这样的周期,则Chisel将报告错误。因为它们不具有周期,所以可以总是以前馈方式构建组合电路,通过添加一些输入从已经定义的节点导出的新节点。时序电路在节点之间具有反馈,因此有时需要在生成节点被定义之前输出。因为Scala顺序执行程序语句,所以我们允许数据节点作为wire来提供节点声明,这样可以立即被使用,但其输入将稍后设置。如下例所示,在简单的CPU中,我们需要定义pcPlus4和brTarget的线,以便在定义之前引用它们:
val pcPlus4 = UInt()
val brTarget = UInt()
val pcNext = Mux(io.ctrl.pcSel, brTarget, pcPlus4)
val pcReg = Reg(next = pcNext, init = UInt(0, 32))
pcPlus4 := pcReg + UInt(4)
...
brTarget := addOut
接线操作符:=用于在pcReg和addOut定义后连接。

6.2、条件更新
(1)在前面使用到寄存器的示例中,我们简单地将组合逻辑块连接到寄存器的输入。当描述状态元素的操作时,指定何时将发生寄存器更新并且用几个单独的语句指明这些更新。Chisel以when的形式提供条件更新规则,以支持这种顺序逻辑描述的风格。
val r = Reg(init = UInt(0, 16))
when (cond) {
r := r + UInt(1)
}
其中只有在cond为真时,才在当前时钟周期的结尾更新寄存器r。when的参数是返回Bool值。后面的更新块只能包含使用赋值运算符:=,简单表达式和用val定义的命名引线的更新语句
(2)在条件更新序列中,条件为真的最近条件更新优先。

6.3、有限状态机
class Parity extends Module {
val io = new Bundle {
val in = Bool(dir = INPUT)
val out = Bool(dir = OUTPUT)
}
val s_even :: s_odd :: Nil = Enum(UInt(), 2)
val state = Reg(init = s_even)
when (io.in) {
when (state === s_even) { state := s_odd }
when (state === s_odd) { state := s_even } 
}
io.out := (state === s_odd)
}
其中Enum(Uint(), 2)生成两个UInt数。当io.in为true时更新状态。需要注意的是,FSM的所有机制都建立在寄存器,线和条件更新的基础上。
0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 外痔疼的的历害怎么办 小肚子疼得历害怎么办 练瑜伽伤到颈椎怎么办 鼻子干口干胃烧怎么办 颈椎病压迫神经引起手麻怎么办 4个月婴儿睡觉少怎么办 晚上睡觉睡不好老是醒来怎么办 吃了没熟的香蕉怎么办 70岁父母老吵架怎么办 怀孕七个月晚上睡不着怎么办 九个月宝宝睡眠不好怎么办 一个月的宝宝放不下怎么办 宝宝被吓了发烧怎么办 体内火气重睡不着觉怎么办 宝宝睡觉一直翻身发出声音怎么办 严重失眠怎么办整夜睡不着觉 腿疼得睡不着觉怎么办 19岁晚上睡不着该怎么办 工作累的想哭怎么办 心累迷茫想哭怎么办 白天很累晚上又睡不着怎么办 发型睡觉压乱了怎么办 通宵一夜第二天怎么办 夏天了腿脚还凉怎么办 咖啡色三天了月经还是下不来怎么办 睡觉姿势不对腰疼怎么办 来月经吃了香瓜怎么办 减肥期间晚上有饭局怎么办 减肥期间遇到晚上聚餐怎么办 婴儿脸不向上睡怎么办 睡觉压奶了疼怎么办 堵奶了挤不下来怎么办 孕36周胎儿腿短怎么办 孕晚期胎儿腿短怎么办 孕晚期宝宝腿短怎么办 手劳累过度麻痛怎么办 大人发烧40不退怎么办? 颈椎扯的脑袋疼怎么办 孕妇颈椎痛导致失眠怎么办 做完运动脊椎中间痛怎么办? 阴虛阴虚火旺怎么办