chisel语言(一)数据类型 | 您所在的位置:网站首页 › uint和sint › chisel语言(一)数据类型 |
一、基本数据类型1. 字面量(常量) 能够表示具体值的数据类型为UInt、SInt和Bool 1.U // 字面值为“1”的UInt对象 -8.S // 字面值为“-8”的SInt对象 "b0101".U // 字面值为“5”的UInt对象 "h1234_5678".U // 字面量为16进制表示的UInt对象 true.B // 字面值为“true”的Bool对象2. 数据宽度在没有声明数据位宽时,字面值为“8”的UInt对象默认是4位宽,SInt就是默认5位宽 1.U // 字面值为“1”、宽度为1bit的UInt对象 1.U(32.W) // 字面值为“1”、宽度为32bit的UInt对象3. 类型转换UInt、SInt和Bool三个类包含四个方法:asUInt、asSInt、toBool和toBools toUInt:将有符号数转换无符号数 toSInt:3bit的UInt值“b111”,其字面量是“7”,转换成SInt后字面量就变成了“-1” toBool:会把1bit的“1”转换成Bool类型的true,“0”转换成false toBools:如果位宽超过1bit,则用toBools转换成Bool类型的序列Seq[Bool]。 op1 := "b1110".U //此时的值为e op1.asSInt //转换之后的值为-24. 向量Vec相当于verilog中的二维数据,它属于可索引的序列,下标从0开始 val myVec = Wire(Vec(3, UInt(32.W))) val myReg = myVec(0)混合向量MixedVec[T]与普通的向量Vec[T]类似,只不过包含的元素可以不全都一样 val mixVec = Wire(MixedVec((1 to 10) map { i => UInt(i.W) }))5. 包裹抽象类Bundle很像C语言的结构体(struct),用户可以编写一个自定义类来继承自它,然后在自定义的类里包含其它各种Data类型的字段 class MyModule extends Module { val io = IO(new Bundle { val in = Input(UInt(32.W)) val out = Output(UInt(32.W)) })Bundle可以和UInt进行相互转换。Bundle类有一个方法asUInt,可以把所含的字段拼接成一个UInt数据,并且前面的字段在高位。例如: class MyBundle extends Bundle { val foo = UInt(4.W) // 高位 val bar = UInt(4.W) // 低位 } val bundle = Wire(new MyBundle) bundle.foo := 0xc.U bundle.bar := 0x3.U val uint = bundle.asUInt // 12*16 + 3 = 195二、操作符1. 位操作符位运算2. 单目位运算单目位运算3. 相等运算符比较运算符4. 移位运算符移位运算符5. 部分位运算符部分位运算符6. 逻辑运算符逻辑运算符7. 算术运算符算术运算符8. 算术比较运算符算术比较运算符9. 位宽推断Chisel位宽推断三、硬件类型1. 端口列表(1) 端口定义的基本模型 class MyIO extends Bundle { val in = Input(Vec(5, UInt(32.W))) val out = Output(UInt(32.W)) } ...... val io = IO(new MyIO) // 模块的端口列表(2) 翻转接口方向Flipped class MyIO extends Bundle { val in = Input(Vec(5, UInt(32.W))) val out = Output(UInt(32.W)) } ...... val io = IO(new MyIO) // in是输入,out是输出 ...... val io = IO(Flipped(new MyIO)) // out是输入,in是输出(3)整体连接 class MyIO extends Bundle { val in = Input(Vec(5, UInt(32.W))) val out = Output(UInt(32.W)) } ...... val io = IO(new Bundle { val x = new MyIO val y = Flipped(new MyIO) }) io.x io.y // 相当于 io.y.in := io.x.in; io.x.out := io.y.out 2. 模块(1)模块定义 在Chisel里面是用一个自定义的类来定义模块的,这个类有以下三个特点:①继承自Module类。②有一个抽象字段“io”需要实现,该字段必须引用前面所说的端口对象。③在类的主构造器里进行内部电路连线。 package test import chisel3._ class Mux2 extends Module { val io = IO(new Bundle{ val sel = Input(UInt(1.W)) val in0 = Input(UInt(1.W)) val in1 = Input(UInt(1.W)) val out = Output(UInt(1.W)) }) io.out := (io.sel & io.in1) | (~io.sel & io.in0)(2)模块例化 双输入多路选择器构建四输入多路选择器 // mux4.scala class Mux4 extends Module { val io = IO(new Bundle { val in0 = Input(UInt(1.W)) val in1 = Input(UInt(1.W)) val in2 = Input(UInt(1.W)) val in3 = Input(UInt(1.W)) val sel = Input(UInt(2.W)) val out = Output(UInt(1.W)) }) val m0 = Module(new Mux2) m0.io.sel := io.sel(0) m0.io.in0 := io.in0 m0.io.in1 := io.in1 val m1 = Module(new Mux2) m1.io.sel := io.sel(0) m1.io.in0 := io.in2 m1.io.in1 := io.in3 val m2 = Module(new Mux2) m2.io.sel := io.sel(1) m2.io.in0 := m0.io.out m2.io.in1 := m1.io.out io.out := m2.io.out(3)同时例化多组模块 因为Vec是一种可索引的序列,所以这种方式例化的多个模块类似于“模块数组”,用下标索引第n个模块。另外,因为Vec的元素已经是模块的端口字段io,所以要引用例化模块的某个具体端口时,路径里不用再出现“io” class Mux4_2 extends Module { val io = IO(new Bundle { val in0 = Input(UInt(1.W)) val in1 = Input(UInt(1.W)) val in2 = Input(UInt(1.W)) val in3 = Input(UInt(1.W)) val sel = Input(UInt(2.W)) val out = Output(UInt(1.W)) }) val m = VecInit(Seq.fill(3)(Module(new Mux2).io)) // 例化了三个Mux2,并且参数是端口字段io m(0).sel := io.sel(0) // 模块的端口通过下标索引,并且路径里没有“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 }3. 线网Chisel把线网作为电路的节点,通过工厂方法“Wire[T |
CopyRight 2018-2019 实验室设备网 版权所有 |