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:
 
import chisel3._

//A n-bit adder with carry in and carry out
class Adder(val n:Int) extends Module {
val io = IO(new Bundle {
val A = Input(UInt(n.W))
val B = Input(UInt(n.W))
val Cin = Input(UInt(1.W))
val Sum = Output(UInt(n.W))
val Cout = Output(UInt(1.W))
})
//create an Array of FullAdders
// NOTE: Since we do all the wiring during elaboration and not at run-time,
// i.e., we don't need to dynamically index into the data structure at run-time,
// we use an Array instead of a Vec.
val FAs = Array.fill(n)(Module(new FullAdder()).io)
// val FAs = Array.fill(n)(Module(new FullAdder()))
val carry = Wire(Vec(n+1, UInt(1.W)))
val sum = Wire(Vec(n, Bool())) //first carry is the top level carry in
carry(0) := io.Cin //wire up the ports of the full adders
for (i <- 0 until n) {
FAs(i).a := io.A(i)
FAs(i).a := io.A(i)
FAs(i).b := io.B(i)
FAs(i).cin := carry(i)
carry(i+1) := FAs(i).cout
sum(i) := FAs(i).sum.toBool()
} // for (i <- 0 until n) {
// FAs(i).io.a := io.A(i)
// FAs(i).io.a := io.A(i)
// FAs(i).io.b := io.B(i)
// FAs(i).io.cin := carry(i)
// carry(i+1) := FAs(i).io.cout
// sum(i) := FAs(i).io.sum.toBool()
// } io.Sum := sum.asUInt
io.Cout := carry(n)
} object AdderMain {
def main(args: Array[String]): Unit = {
chisel3.Driver.execute(Array("--target-dir", "generated/Adder"), () => new Adder(4))
}
}

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. E - Tunnel Warfare HDU - 1540 F - Hotel G - 约会安排 HDU - 4553 区间合并

    E - Tunnel Warfare HDU - 1540 对这个题目的思考:首先我们已经意识到这个是一个线段树,要利用线段树来解决问题,但是怎么解决呢,这个摧毁和重建的操作都很简单,但是这个查询怎么 ...

  2. CC2530入门

    一.简介 单片机(MCU)就是一个将微型计算机系统制作到里面的集成电路芯片. 微控制器的基本结构:内核+外设.内核通过寄存器控制外设:外设通过中断系统通知内核:内核与外设之间通过总线传输数据.地址及控 ...

  3. Python 为什么抛弃累赘的花括号,使用缩进来划分代码块?

    大家好,这是"Python为什么"系列节目的文字稿(文末有观看地址). 本期话题:Python 为什么使用缩进来划分代码块,而不像其它语言使用花括号 {} 或者 "end ...

  4. 【Hadoop离线基础总结】oozie定时任务设置

    目录 简介 概述 oozie定时任务设置 1.拷贝定时任务的调度模板 拷贝hello.sh脚本 3.修改配置文件 4.上传到hdfs对应路径 5.运行定时任务 简介 概述 在oozie当中,主要是通过 ...

  5. 目前校园百晓生APP与CSDN软件的对比

    不忘初心.注入灵魂 设计之初 在做校园百晓生该APP时,初心是为校园的同学提供便捷的查询校园信息的服务,确实目前的软件已经实现了该功能,但是总感觉缺少一些灵魂,感觉大部分人渴望的重点在于信息而不是自己 ...

  6. [hdu2112]最短路

    相当于模板题了,用trie来完成字符串到数字的映射比map<string, int>要快不少,令外可以考虑hash. 运行时间对比: (1)(2)600ms左右 (3)3000ms左右(4 ...

  7. [csu1605]数独(精确覆盖问题)

    题意 :给定数独的某些初始值,规定每个格子的得分,求得分最大的数独的解. 思路:这是某年的noip的原题,高中时就写过,位运算也就是那个时候学会的--.这题明显是暴搜,但是需要注意两点,一是需要加一些 ...

  8. 在微服务框架Demo.MicroServer中添加SkyWalking+SkyApm-dotnet分布式链路追踪系统

    1.APM工具的选取 Apm监测工具很多,这里选用网上比较火的一款Skywalking. Skywalking是一个应用性能监控(APM)系统,Skywalking分为服务端Oap.管理界面UI.以及 ...

  9. angular foreach的使用

    var myAppModule = angular.module('myApp', []); var values = { name : 'misko', gender : 'male', " ...

  10. git命令之切换分支

    Git一般有很多分支,我们clone到本地的一般都是master分支,如何进行分支的切换呢?那么下面带大家简单的看看如何通过命令来切换: 1.查看远程仓库及本地的所有分支 命令:git branch ...