• Chisel3


    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))
    }
    }
  • 相关阅读:
    使用Apache的ab工具进行压力测试
    Effective Java开篇
    mysql删除同一表中重复字段记录
    正则表达式的元字符匹配
    几个学习git的地方
    创建和销毁对象
    遇到多个构造器参数时要考虑用构建器
    Java的类和接口
    转:流言粉碎机:每天对着电脑46小时的人必看
    页面选中文字弹出层,点击层中文字或者图片触发事件
  • 原文地址:https://www.cnblogs.com/wjcdx/p/10093492.html
Copyright © 2020-2023  润新知