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. B. Modulo Sum dp

    https://codeforces.com/contest/577/problem/B 先读懂题意,substring 这个是子串说明不可以跳 subsequence这个是子序列可以跳 这个题目是一 ...

  2. mac下xampp访问php显示403错误

    错误描述 New xampp security concept: Access Forbidden Error 403 错误分析和解决 403就是我们访问的时候,被安全策略拒绝了,解决方法 找到文件 ...

  3. 【Spark】快来学习RDD的创建以及操作方式吧!

    目录 RDD的创建 三种方式 从一个集合中创建 从文件中创建 从其他的RDD转化而来 RDD编程常用API 算子分类 Transformation 概述 帮助文档 常用Transformation表 ...

  4. 【matlab 基础篇 02】基础知识一键扫盲,看完即可无障碍编程(超详细+图文并茂)

    博主快速入门matlab,系统地整理一遍,如何你和我一样是一个新手,那么此文很适合你: 本人能力有限,文中难免有错误和纰漏之处,请大佬们不吝赐教 创作不易,如果本文帮到了您: 请帮忙点个赞

  5. STM32 标准库V3.5启动文件startup_stm32f10xxx.s分析

    layout: post tags: [STM32] comments: true 文章目录 layout: post tags: [STM32] comments: true 前言 分析startu ...

  6. c++11 符号修饰与函数签名、函数指针、匿名函数、仿函数、std::function与std::bind

    一.符号修饰与函数签名 1.符号修饰 编译器将c++源代码编译成目标文件时,用函数签名的信息对函数名进行改编,形成修饰名.GCC的C++符号修饰方法如下: 1)所有符号都以_z开头 2)名字空间的名字 ...

  7. 学习ASP.NET Core(05)-使用Swagger与Jwt授权

    上一篇我们使用IOC容器解决了依赖问题,同时简单配置了WebApi环境,本章我们使用一下Swagger,并通过Jwt完成授权 一.Swagger的使用 1.什么是Swagger 前后端分离项目中,后端 ...

  8. js判断数组(数组对象)中是否存在指定的值,如果存在就删除

    数组中是否存在指定值,存在就删除 var str = ["a", "b", "c"]; var index = str.indexOf(&q ...

  9. httpd+tomcat 均衡负载

    接前面的文章http://www.cnblogs.com/gqdw/p/3785812.html workers.properties worker.list=controller#worker1 w ...

  10. ambari添加新的服务出错

    错误信息 : raise ExecutionFailed(err_msg, code, out, err) resource_management.core.exceptions.ExecutionF ...