【Chisel】2.2 组合逻辑

本文介绍了如何使用Chisel语言来实现组合逻辑,包括无符号数 UInt、有符号数 SInt 和布尔数 Bool 的使用。通过示例代码解释了Chisel中的常见操作符,并展示了Chisel代码如何编译成Verilog。讨论了Chisel中的运算符如何映射到硬件操作,以及Mux和Cat操作的用法。
摘要由CSDN通过智能技术生成

前言

在这个部分我们将学习到如何用Chisel语言实现组合逻辑。这一节会介绍基础的Chisel数据类型:

  • UInt - 无符号数
  • SInt - 有符号数
  • Bool - 布尔数

注意: 所有的Chisel变量在Scala中都应声明为val,因为硬件一旦定义生成就不会再改变了。(想象电路图都画好了,逻辑不能再改,能改变的只有输入输出。)

常见的操作符

class MyModule extends Module {
  val io = IO(new Bundle {
    val in  = Input(UInt(4.W))
    val out = Output(UInt(4.W))
  })
}

声明一个类别 MyModule为Module类。这个声明表示这段代码会被编译为verilog代码。

MyModule模块内有一个4个bit无符号数的输入和输出。

示例代码

  • Example 1
class MyModule extends Module {
  val io = IO(new Bundle {
    val in  = Input(UInt(4.W))
    val out = Output(UInt(4.W))
  })

  val two  = 1 + 1
  println(two)
  val utwo = 1.U + 1.U
  println(utwo)
  
  io.out := io.in
}
println(getVerilog(new MyModule))

编译后的verilog代码:

module MyModule(
  input        clock,
  input        reset,
  input  [3:0] io_in,
  output [3:0] io_out
);
  assign io_out = io_in; // @[cmd2.sc 12:10]
endmodule

输出:

2
UInt<1>(OpResult in MyModule)

two 是Scala语言的两个为Int类别的数直接相加。因此输出也是Int类。

而utwo是num.U, .U代表Scala int 数字到 unit Chisel数字的映射,这样的相加会被直接识别为硬件

操作点(我理解的是寄存器),所以会直接输出函数类别和指针号。

  • Example 2
class MyOperators extends Module {
  val io = IO(new Bundle {
    val in      = Input(UInt(4.W))
    val out_add = Output(UInt(4.W))
    val out_sub = Output(UInt(4.W))
    val out_mul = Output(UInt(4.W))
  })

  io.out_add := 1.U + 4.U
  io.out_sub := 2.U - 1.U
  io.out_mul := 4.U * 2.U
}
println(getVerilog(new MyOperators))

编译后的verilog代码:

module MyOperators(
  input        clock,
  input        reset,
  input  [3:0] io_in,
  output [3:0] io_out_add,
  output [3:0] io_out_sub,
  output [3:0] io_out_mul
);
  wire [1:0] _T_3 = 2'h2 - 2'h1; // @[cmd3.sc 10:21]
  wire [4:0] _T_4 = 3'h4 * 2'h2; // @[cmd3.sc 11:21]
  assign io_out_add = 4'h5; // @[cmd3.sc 9:21]
  assign io_out_sub = {{2'd0}, _T_3}; // @[cmd3.sc 10:21]
  assign io_out_mul = _T_4[3:0]; // @[cmd3.sc 11:14]
endmodule

这里我觉得有个可以讨论的点,就是为什么Chisel翻译后的verilog操作这么复杂。

为什么不直接把计算后的结果assign给Verilog。

我的理解是:

这里可能需要理解到wire和assign在verilog中的区别:wire和operator有关,它会生成相应的逻辑阵列,也可以说是电路图。而assign是直接把值赋给寄存器。

因此当Chisel的源码中存在有运算符时,Scala的逻辑可能就对应着wire,我尝试着直接赋值,果然wire就消失了。

  • Example 3

认识MuxCat

class MyOperatorsTwo extends Module {
  val io = IO(new Bundle {
    val in      = Input(UInt(4.W))
    val out_mux = Output(UInt(4.W))
    val out_cat = Output(UInt(4.W))
  })

  val s = true.B
  io.out_mux := Mux(s, 3.U, 0.U) // should return 3.U, since s is true
  io.out_cat := Cat(2.U, 1.U)    // concatenates 2 (b10) with 1 (b1) to give 5 (101)
}

println(getVerilog(new MyOperatorsTwo))

test(new MyOperatorsTwo) { c =>
  c.io.out_mux.expect(3.U)
  c.io.out_cat.expect(5.U)
}
println("SUCCESS!!")

Mux 类似于C语言的 条件运算符 ? Mux(s, a, b), s.B 为Chisel布尔数, 当s为True时, 输出a, 否则输出b。

Cat 类似于verilog的合并 {a,b},比如上面的Cat(2.U, 1.U)就是把无符号数 2 和 1 串起来 {2‘b10 , 1’b1} = {3’b101} = 5

更多的内置函数可以在Chisel提供的Chisel cheatsheet上面看到,单击直接下裁。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值