https://mp.weixin.qq.com/s/SEcVjGRL1YloGlEPSoHr3A

 
位数为参数的加法器。通过FullAdder级联实现。
 
参考链接:
https://github.com/ucb-bar/chisel-tutorial/blob/release/src/main/scala/examples/Adder.scala
 
1. 引入Chisel3
 
 
2. 继承自Module类
 
这里的n是构造方法的参数,表示加法器的位数。
 
3. 定义输入输出接口
 
根据位数n,创建各项输入输出接口。
 
这些接口都是无符号整型数:val A = Input(UInt(n.W))
a. 使用n.W表示位宽为n位;
b. 使用UInt创建无符号整型数;
c. 使用Input/Output表示接口方向;
d. val 关键字表明定义的变量是所属匿名Bundle子类的数据成员;
 
4. 内部连接
 
 
创建n个全加器,并与输入和输出接口相连。
 
1) 创建多个全加器:val FAs = Array.fill(n)(Module(new FullAdder()).io)
 
a. 这个写法实际上是用了一点trick,以缩短后续代码。实际上FA是指FullAdder,但这里创建的却不是全加器,而是全加器的io。
 
如果是全加器,写法应该如下:
val FAs = Array.fill(n)(Module(new FullAdder()))
但这样写,后续使用时,需要加上io:
FAs(i).io.a := io.A(i)
 
因为后续使用时都是使用全加器的io,而不使用全加器。所以直接使用FAs指代FAs的io,也无可厚非。
 
b. 这里使用了Scala的call-by-name机制
Array.fill()方法的签名为:
def fill[T: ClassTag](n: Int)(elem: => T): Array[T]
包含两个参数列表,第一个为数组元素的个数;第二个参数使用“=> T”表明该参数为call-by-name参数,使用时如同这个参数是一个函数,这个函数返回类型为T的返回值。
 
所以Array.fill(n)(Module(new FullAdder()).io)的意思:
i. 创建一个数组;
i. 数组元素的个数为n;
i. 创建数组元素的方法为:Module(new FullAdder()).io。即每次创建数组元素时,都调用这段代码;
 
2) 创建进位线:val carry = Wire(Vec(n+1, UInt(1.W)))
 
a. 创建一个Vec[UInt]
 
 
b. 使用Wire()绑定Vec[UInt]
 
 
WireBinding不是只读绑定,可以作为“:=”的左值。
 
c. carry(i)返回元素UInt
 
carry(i)可以作为左值使用:
carry(0) := io.Cin
 
3) 创建和线:val sum = Wire(Vec(n, Bool()))
 
 
5. 生成Verilog
 
 
可以直接点运行符号运行。
 
也可以使用sbt shell执行:
 
生成Verilog如下:
 
6. 测试
 
 
 
7. 附录
 
Adder.scala:
 
  1. import chisel3._
  2.  
  3. //A n-bit adder with carry in and carry out
  4. class Adder(val n:Int) extends Module {
  5. val io = IO(new Bundle {
  6. val A = Input(UInt(n.W))
  7. val B = Input(UInt(n.W))
  8. val Cin = Input(UInt(1.W))
  9. val Sum = Output(UInt(n.W))
  10. val Cout = Output(UInt(1.W))
  11. })
  12. //create an Array of FullAdders
  13. // NOTE: Since we do all the wiring during elaboration and not at run-time,
  14. // i.e., we don't need to dynamically index into the data structure at run-time,
  15. // we use an Array instead of a Vec.
  16. val FAs = Array.fill(n)(Module(new FullAdder()).io)
  17. // val FAs = Array.fill(n)(Module(new FullAdder()))
  18. val carry = Wire(Vec(n+1, UInt(1.W)))
  19. val sum = Wire(Vec(n, Bool()))
  20.  
  21. //first carry is the top level carry in
  22. carry(0) := io.Cin
  23.  
  24. //wire up the ports of the full adders
  25. for (i <- 0 until n) {
  26. FAs(i).a := io.A(i)
  27. FAs(i).a := io.A(i)
  28. FAs(i).b := io.B(i)
  29. FAs(i).cin := carry(i)
  30. carry(i+1) := FAs(i).cout
  31. sum(i) := FAs(i).sum.toBool()
  32. }
  33.  
  34. // for (i <- 0 until n) {
  35. // FAs(i).io.a := io.A(i)
  36. // FAs(i).io.a := io.A(i)
  37. // FAs(i).io.b := io.B(i)
  38. // FAs(i).io.cin := carry(i)
  39. // carry(i+1) := FAs(i).io.cout
  40. // sum(i) := FAs(i).io.sum.toBool()
  41. // }
  42.  
  43. io.Sum := sum.asUInt
  44. io.Cout := carry(n)
  45. }
  46.  
  47. object AdderMain {
  48. def main(args: Array[String]): Unit = {
  49. chisel3.Driver.execute(Array("--target-dir", "generated/Adder"), () => new Adder(4))
  50. }
  51. }

Chisel3 - Tutorial - Adder的更多相关文章

  1. Chisel3 - Tutorial - Adder4

    https://mp.weixin.qq.com/s/X5EStKor2DU0-vS_wIO-fg   四位加法器.通过FullAdder级联实现.   参考链接: https://github.co ...

  2. Chisel3 - Tutorial - VendingMachine

    https://mp.weixin.qq.com/s/tDpUe9yhwC-2c1VqisFzMw   演示如何使用状态机.   参考链接: https://github.com/ucb-bar/ch ...

  3. Chisel3 - Tutorial - VendingMachineSwitch

    https://mp.weixin.qq.com/s/5lcMkenM2zTy-pYOXfRjyA   演示如何使用switch/is来实现状态机.   参考链接: https://github.co ...

  4. Chisel3 - Tutorial - Tbl

    https://mp.weixin.qq.com/s/e8vJ8claauBtiuedxYYaJw   实现可以动态索引的表.   参考链接: https://github.com/ucb-bar/c ...

  5. Chisel3 - Tutorial - Stack

    https://mp.weixin.qq.com/s/-AVJD1IfvNIJhmZM40DemA   实现后入先出(last in, first out)的栈.   参考链接: https://gi ...

  6. Chisel3 - Tutorial - Functionality

    https://mp.weixin.qq.com/s/3hDzpJiANdwp07hO03psyA   演示使用函数进行代码复用的方法.   参考链接: https://github.com/ucb- ...

  7. Chisel3 - Tutorial - Parity

    https://mp.weixin.qq.com/s/OtiQnE52PwdCpvmzJ6VFnA   奇偶发生器.统计输入中1的个数,如果为偶数则输出0,奇数则输出1.   参考链接: https: ...

  8. Chisel3 - Tutorial - ByteSelector

    https://mp.weixin.qq.com/s/RQg2ca1rwfVHx_QG-IOV-w   字节选择器.   参考链接: https://github.com/ucb-bar/chisel ...

  9. Chisel3 - Tutorial - ShiftRegister

    https://mp.weixin.qq.com/s/LKiXUgSnt3DzgFLa9zLCmQ   简单的寄存器在时钟的驱动下,逐个往下传值.   参考链接: https://github.com ...

随机推荐

  1. Matlab矩阵总结

  2. Spring Cloud feign GET请求无法用实体传参的解决方法

    代码如下: @FeignClient(name = "eureka-client", fallbackFactory = FallBack.class, decode404 = t ...

  3. MySQL连接不上

    access denied for user root @localhost 解决办法: create user 'root'@'localhost' identified by '你的密码'; gr ...

  4. 004_Python的列表切片,增删改查,常用操作方法,元组,range,join

    列表 列表是Python中的基础数据类型之一,它是以[]括起来,每个元素以逗号隔开,而且他里面可以存放各种数据类型比如: li = ['kevin',123,True,(1,2,3,'wusir'), ...

  5. Polar码快速入门

    Polar码快速入门 本科生在学习极化码时,并不是件简单的事情.网上极化码的资料很少,而且基本上都是较难的论文.这篇文章是用来帮你快速入门极化码. Poalr码背景 2015 年,国际电信联盟无线通信 ...

  6. 一文教你如何在ubuntu上快速搭建STM32 CubeIDE环境(图文超详细+文末有附件)

    在快速ubuntu上安装cubeide你值得拥有:适合对linux系统还不是很熟悉的同学: 文章目录 1 下载 cubeide 2 找到软件 3 安装 4 附件 5 总结 1 下载 cubeide 登 ...

  7. 学习python的第一天,python的简单知识

    python 是现如今比较火的一种编程语言.在抱着试试的态度我来进行学习下python.要学习python 要先进行环境的安装. 下面是下载链接:https://pan.baidu.com/s/1PW ...

  8. 小心了!Kubernetes自动化操作工具将让你失去工作

    运行Kubernetes的人已经花费太多时间在操作上,企业正在考虑为Kubernetes编写自动化工具. 尽管IT部门的大部分职位都会增加,但职业顾问说,计算机操作员预计会减少.这个角色涉及运行She ...

  9. 一、线程 & 线程池

    一.线程的介绍 1.1.概念 进程: 你的硬盘上有一个简单的程序,这个程序叫QQ.exe,这是一个程序,这个程序是一个静态的概念,它被扔在硬盘上也没人理他,但是当你双击它,弹出一个界面输入账号密码登录 ...

  10. mybatis中 #{} 和 ${}

    在mybatis中#{}表示一个占位符: 1.#将传入的数据都当成一个字符串,会对自动传入的数据加一个双引号 2.#在很大程度上可以防止sql注入 3.例如#{id}:#{}中的id表示输入的参数名称 ...