chisel使用自定义/标准库中的函数简化设计(更新)

2023-11-08

主体内容摘自:https://blog.csdn.net/qq_34291505/article/details/87905379


函数是编程语言的常用语法,即使是Verilog这样的硬件描述语言,也会用函数来构建组合逻辑。对于Chisel这样的高级语言,函数的使用更加方便,还能节省不少代码量。不管是用户自己写的函数、Chisel语言库里的函数还是Scala标准库里的函数,都能帮助用户节省构建电路的时间


零、scala函数基础

1、普通函数
// No inputs or outputs (two versions).
def hello1(): Unit = print("Hello!")
def hello2 = print("Hello again!")

// Math operation: one input and one output.
def times2(x: Int): Int = 2 * x

// Inputs can have default values, and explicitly specifying the return type is optional.
// Note that we recommend specifying the return types to avoid surprises/bugs.
def timesN(x: Int, n: Int = 2) = n * x

// Call the functions listed above.
hello1()
hello2
times2(4)
timesN(4)         // no need to specify n to use the default value
timesN(4, 3)      // argument order is the same as the order where the function was defined
timesN(n=7, x=2)  // arguments may be reordered and assigned to explicitly

Hello!Hello again!
defined function hello1
defined function hello2
defined function times2
defined function timesN
res2_6: Int = 8
res2_7: Int = 8
res2_8: Int = 12
res2_9: Int = 14


2、函数字面量

Scala中的函数是一等对象。这意味着我们可以将一个函数分配给一个Val,并将它作为参数传递给类、对象或其他函数。

// These are normal functions.
def plus1funct(x: Int): Int = x + 1
def times2funct(x: Int): Int = x * 2

// These are functions as vals.
// The first one explicitly specifies the return type.
val plus1val: Int => Int = x => x + 1
val times2val = (x: Int) => x * 2

// Calling both looks the same.
plus1funct(4)
plus1val(4)
plus1funct(x=4)
//plus1val(x=4) // this doesn't work

defined function plus1funct
defined function times2funct
plus1val: Int => Int = ammonite. s e s s . c m d 3 sess.cmd3 sess.cmd3HelperKaTeX parse error: Can't use function '$' in math mode at position 7: Lambda$̲3224/925602942@…Lambda$3225/1395281840@1c22db5a
res3_4: Int = 5
res3_5: Int = 5
res3_6: Int = 5

为什么要创建一个Val而不是def?因为使用Val,可以将该函数传递给其他函数,如下所示。您甚至可以创建接受其他函数作为参数的自己的函数。形式上,接受或产生函数的函数称为高阶函数。

3、高阶函数
// create our function
val plus1 = (x: Int) => x + 1
val times2 = (x: Int) => x * 2

// pass it to map, a list function
val myList = List(1, 2, 5, 9)
val myListPlus = myList.map(plus1)
val myListTimes = myList.map(times2)

// create a custom function, which performs an operation on X N times using recursion
def opN(x: Int, n: Int, op: Int => Int): Int = {
  if (n <= 0) { x }
  else { opN(op(x), n-1, op) }
}

opN(7, 3, plus1)
opN(7, 3, times2)

plus1: Int => Int = ammonite. s e s s . c m d 4 sess.cmd4 sess.cmd4HelperKaTeX parse error: Can't use function '$' in math mode at position 7: Lambda$̲3249/997984377@…Lambda$3250/1596149926@bf801a7
myList: List[Int] = List(1, 2, 5, 9)
myListPlus: List[Int] = List(2, 3, 6, 10)
myListTimes: List[Int] = List(2, 4, 10, 18)
defined function opN
res4_6: Int = 10
res4_7: Int = 56

当使用没有参数的函数时,1/2两种情况可能会出现混淆的情况。如下所示:

import scala.util.Random

// both x and y call the nextInt function, but x is evaluated immediately and y is a function
val x = Random.nextInt
def y = Random.nextInt

// x was previously evaluated, so it is a constant
println(s"x = $x")
println(s"x = $x")

// y is a function and gets reevaluated at each call, thus these produce different results
println(s"y = $y")
println(s"y = $y")

x = 1775160696
x = 1775160696
y = 804455125
y = 958584765

可以看到,x其实就是一个常量,是调用Random.nextInt返回的一个常量;而y是你定义的一个函数,该函数的函数体就是执行Random.nextInt这个函数,所以每次调用y都会执行Random.nextInt,也就会出现不一样的结果。

4、匿名函数

顾名思义,匿名函数是匿名的。如果我们只使用它一次,就没有必要为函数创建Val。

val myList = List(5, 6, 7, 8)

// add one to every item in the list using an anonymous function
// arguments get passed to the underscore variable
// these all do the same thing
myList.map( (x:Int) => x + 1 )
myList.map(_ + 1)

// a common situation is to use case statements within an anonymous function
val myAnyList = List(1, 2, "3", 4L, myList)
myAnyList.map {
  case (_:Int|_:Long) => "Number"
  case _:String => "String"
  case _ => "error"
}

myList: List[Int] = List(5, 6, 7, 8)
res6_1: List[Int] = List(6, 7, 8, 9)
res6_2: List[Int] = List(6, 7, 8, 9)
myAnyList: List[Any] = List(1, 2, “3”, 4L, List(5, 6, 7, 8))
res6_4: List[String] = List(“Number”, “Number”, “String”, “Number”, “error”)


一、用自定义函数抽象组合逻辑

与Verilog一样,对于频繁使用的组合逻辑电路,可以定义成Scala的函数形式,然后通过函数调用的方式来使用它。这些函数既可以定义在某个单例对象里,供多个模块重复使用,也可以直接定义在电路模块里。例如:

// function.scala
import chisel3._
class UseFunc extends Module {
  val io = IO(new Bundle {
    val in = Input(UInt(4.W))
    val out1 = Output(Bool())
    val out2 = Output(Bool())
  })
  def clb(a: UInt, b: UInt, c: UInt, d: UInt): UInt =
    (a & b) | (~c & d)
  io.out1 := clb(io.in(0), io.in(1), io.in(2), io.in(3))
  io.out2 := clb(io.in(0), io.in(2), io.in(3), io.in(1))
}

二、用工厂方法简化模块的例化

在Scala里,往往在类的伴生对象里定义一个工厂方法,来简化类的实例化。同样,Chisel的模块也是Scala的类,也可以在其伴生对象里定义工厂方法来简化例化、连线模块。例如用双输入多路选择器构建四输入多路选择器:

// mux4.scala
import chisel3._
class Mux2 extends Module {
  val io = IO(new Bundle {
    val sel = Input(UInt(1.W))
    val in0 = Input(UInt(1.W))
    val in1 = Input(UInt(1.W))
    val out = Output(UInt(1.W))
  })
  io.out := (io.sel & io.in1) | (~io.sel & io.in0)
}
object Mux2 {
  def apply(sel: UInt, in0: UInt, in1: UInt) = {
    val m = Module(new Mux2)
    m.io.in0 := in0
    m.io.in1 := in1
    m.io.sel := sel
    m.io.out
  }
}
class Mux4 extends Module {
  val io = IO(new Bundle {
    val sel = Input(UInt(2.W))
    val in0 = Input(UInt(1.W))
    val in1 = Input(UInt(1.W))
    val in2 = Input(UInt(1.W))
    val in3 = Input(UInt(1.W))
    val out = Output(UInt(1.W))
  })
  io.out := Mux2(io.sel(1),
                 Mux2(io.sel(0), io.in0, io.in1),
                 Mux2(io.sel(0), io.in2, io.in3))
}

注:

其实就是把例化模块和端口连接的代码放入了伴生对象的apply方法里,这样可以被重复使用。当然也可以只定义一个普通函数,不使用伴生对象。函数的输入输出其实就是待使用的模块的输入输出。

三、用Scala的函数简化代码

Scala的函数也能在Chisel里使用,只要能通过Firrtl编译器的检查。比如在生成长的序列上,利用Scala的函数就能减少大量的代码。

假设要构建一个译码器:

  • 在Verilog里需要写多条case语句,当n很大时就会使代码显得冗长而枯燥。
  • 利用Scala的for、yield组合可以产生相应的判断条件与输出结果的序列,再用zip函数将两个序列组成一个对偶序列,再把对偶序列作为MuxCase的参数,就能用几行代码构造出任意位数的译码器。例如:
// decoder.scala
package decoder
 
import chisel3._
import chisel3.util._
import chisel3.experimental._
 
class Decoder(n: Int) extends RawModule {
  val io = IO(new Bundle {
    val sel = Input(UInt(n.W))
    val out = Output(UInt((1 << n).W))  
  })
 
  val x = for(i <- 0 until (1 << n)) yield io.sel === i.U
  val y = for(i <- 0 until (1 << n)) yield 1.U << i
  io.out := MuxCase(0.U, x zip y)
}
 
object DecoderGen extends App {
  chisel3.Driver.execute(args, () => new Decoder(args(0).toInt))
}

只需要输入参数n,就能立即生成对应的n位译码器。

四、Chisel的对数函数

在二进制运算里,求以2为底的对数也是常用的运算。

chisel3.util包里有一个单例对象Log2,它的一个apply方法接收一个Bits类型的参数,计算并返回该参数值以2为底的幂次。返回类型是UInt类型,并且是向下截断的。另一个apply的重载版本可以接受第二个Int类型的参数,用于指定返回结果的位宽。例如:

Log2(8.U)  // 等于3.U

Log2(13.U)  // 等于3.U(向下截断)

Log2(myUIntWire)  // 动态求值 

chisel3.util包里还有四个单例对象:log2Ceil、log2Floor、log2Up和log2Down,它们的apply方法的参数都是Int和BigInt类型,返回结果都是Int类型。log2Ceil是把结果向上舍入,log2Floor则向下舍入。log2Up和log2Down不仅分别把结果向上、向下舍入,而且结果最小为1。

单例对象isPow2的apply方法接收Int和BigInt类型的参数,判断该整数是不是2的n次幂,返回Boolean类型的结果。

五、chisel获取数据位宽

chisel3.util包里还有两个用来获取数据位宽的函数,分别是signedBitLengthunsignedBitLength,使用方法如下例所示。需要注意的是入参类型是scala的BigInt,返回值是Int,因此如果用在chisel构建电路的过程中,不要忘了根据需要转换成chisel的数据类型。

    val a = -12
    val b = 15
    println(signedBitLength(a))//5
    println(unsignedBitLength(b))//4

六、与硬件相关的函数

chisel3.util包里还有一些常用的操作硬件的函数:

Ⅰ、位旋转

单例对象Reverse的apply方法可以把一个UInt类型的对象进行旋转,返回一个对应的UInt值。在转换成Verilog时,都是通过拼接完成的组合逻辑。例如:

Reverse("b1101".U)  // 等于"b1011".U

Reverse("b1101".U(8.W))  // 等于"b10110000".U

Reverse(myUIntWire)  // 动态旋转
Ⅱ、位拼接

单例对象Cat有两个apply方法,分别接收一个Bits类型的序列和Bits类型的重复参数,将它们拼接成一个UInt数。前面的参数在高位。例如:

Cat("b101".U, "b11".U)  // 等于"b10111".U

Cat(myUIntWire0, myUIntWire1)  // 动态拼接

Cat(Seq("b101".U, "b11".U))  // 等于"b10111".U

Cat(mySeqOfBits)  // 动态拼接 
Ⅲ、1计数器

单例对象PopCount有两个apply方法,分别接收一个Bits类型的参数和Bool类型的序列,计算参数里“1”或“true.B”的个数,返回对应的UInt值。例如:

PopCount(Seq(true.B, false.B, true.B, true.B))  // 等于3.U

PopCount(Seq(false.B, false.B, true.B, false.B))  // 等于1.U

PopCount("b1011".U)  // 等于3.U

PopCount("b0010".U)  // 等于1.U

PopCount(myUIntWire)  // 动态计数
Ⅳ、独热码转换器
  • 单例对象OHToUInt的apply方法可以接收一个Bits类型或Bool序列类型的独热码参数,计算独热码里的“1”在第几位(从0开始),返回对应的UInt值。如果不是独热码,则行为不确定。例如:
OHToUInt("b1000".U)  // 等于3.U

OHToUInt("b1000_0000".U)  // 等于7.U 
  • 还有一个行为相反的单例对象UIntToOH,它的apply方法是根据输入的UInt类型参数,返回对应位置的独热码,独热码也是UInt类型。例如:
UIntToOH(3.U)  // 等于"b1000".U

UIntToOH(7.U)  // 等于"b1000_0000".U
Ⅴ、无关位

Verilog里可以用问号表示无关位,那么用case语句进行比较时就不会关心这些位。Chisel里有对应的BitPat类,可以指定无关位。在其伴生对象里:

  • 一个apply方法可以接收一个字符串来构造BitPat对象,字符串里用问号表示无关位。例如:
"b10101".U === BitPat("b101??") // 等于true.B

"b10111".U === BitPat("b101??") // 等于true.B

"b10001".U === BitPat("b101??") // 等于false.B 
  • 另一个apply方法则用UInt类型的参数来构造BitPat对象,UInt参数必须是字面量。这允许把UInt类型用在期望BitPat的地方,当用BitPat定义接口又并非所有情况要用到无关位时,该方法就很有用。

另外,bitPatToUInt方法可以把一个BitPat对象转换成UInt对象,但是BitPat对象不能包含无关位。

dontCare方法接收一个Int类型的参数,构造等值位宽的全部无关位。例如:

val myDontCare = BitPat.dontCare(4)  // 等于BitPat("b????") 
Ⅵ、查找表

BitPat通常配合两种查找表使用。

  • 一种是单例对象Lookup,其apply方法定义为:
def apply[T <: Bits](addr: UInt, default: T, mapping: Seq[(BitPat, T)]): T 

参数addr会与每个BitPat进行比较,如果相等,就返回对应的值,否则就返回default。

Lookup(2.U,  // address for comparison
  *                          10.U,   // default "row" if none of the following cases match
  *     Array(BitPat(2.U) -> 20.U,  // this "row" hardware-selected based off address 2.U
  *           BitPat(3.U) -> 30.U)
  * ) // hardware-evaluates to 20.U
  • 第二种是单例对象ListLookup,它的apply方法与上面的类似,区别在于返回结果是一个T类型的列表:
defapply[T <: Data](addr: UInt, default: List[T], mapping: Array[(BitPat, List[T])]): List[T] 
ListLookup(2.U,  // address for comparison
  *                          List(10.U, 11.U, 12.U),   // default "row" if none of the following cases match
  *     Array(BitPat(2.U) -> List(20.U, 21.U, 22.U),  // this "row" hardware-selected based off address 2.U
  *           BitPat(3.U) -> List(30.U, 31.U, 32.U))
  * ) // hardware-evaluates to List(20.U, 21.U, 22.U)

这两种查找表的常用场景是构造CPU的控制器,因为CPU指令里有很多无关位,所以根据输入的指令(即addr)与预先定义好的带无关位的指令进行匹配,就能得到相应的控制信号。

Ⅶ、数据重复和位重复

单例对象Fill是对输入的数据进行重复,它的apply方法是:
def apply(n: Int, x: UInt): UInt,第一个参数是重复次数,第二个是被重复的数据,返回的是UInt类型的数据,如下例所示:

Fill(2, "b1000".U)  // 等于 "b1000 1000".U
Fill(2, "b1001".U)  // 等于 "b1001 1001".U
Fill(2, myUIntWire)  // 动态重复

还有一个单例对象FillInterleaved,它是对输入数据的每一位进行重复,它有两个apply方法:

第一个是def apply(n: Int, in: Seq[Bool]): UInt,n表示位重复的次数,in是被重复的数据,它是由Bool类型元素组成的序列,返回的是UInt类型的数据,如下例所示:

FillInterleaved(2, Seq(true.B, false.B, false.B, false.B))  // 等于 "b11 00 00 00".U
FillInterleaved(2, Seq(true.B, false.B, false.B, true.B))  // 等于 "b11 00 00 11".U

第二个是def apply(n: Int, in: Seq[Bool]): UInt,n表示位重复的次数,in是被重复的UInt类型的数据,返回的是UInt类型的数据,如下例所示:

FillInterleaved(2, "b1 0 0 0".U)  // 等于 "b11 00 00 00".U
FillInterleaved(2, "b1 0 0 1".U)  // 等于 "b11 00 00 11".U
FillInterleaved(2, myUIntWire)  // 动态位重复
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

chisel使用自定义/标准库中的函数简化设计(更新) 的相关文章

  • 如何从命令行运行scala文件?

    scala是否支持scala run xxx scala go语言支持这样运行 go my go 并且Python支持 python my py 但看来 scala xxx scala 仅进行语法检查 未观察到任何输出或运行行为 那么有没有
  • 案例类和案例对象之间的区别?

    我正在学习 Scala 和 Akka 并且在最近的查找中solution https stackoverflow com questions 22770927 waiting for multiple results in akka 我发现
  • 使用 slick 3.0.0-RC1 无法在 TableQuery 上找到方法结果

    我正在尝试 Slick3 0 0 RC1我遇到了一个奇怪的问题 这是我的代码 import slick driver SQLiteDriver api import scala concurrent ExecutionContext Imp
  • 选项包装值是一个好的模式吗?

    我最近写了以下 Scala 代码 val f File pretend this file came from somewhere val foo toFoo io Source fromFile f mkString 我真的不喜欢这种方式
  • Spark Scala:按小时或分钟计算两列的 DateDiff

    我在数据框中有两个时间戳列 我想获取它们的分钟差异 或者小时差异 目前我可以通过四舍五入获得日差 val df2 df1 withColumn time datediff df1 ts1 df1 ts2 但是 当我查看文档页面时https
  • .java 和 .scala 类之间是否可能存在循环依赖?

    假设我在 java 文件中定义了类 A 在 scala 文件中定义了类 B A 类使用 B 类 B 类使用 A 类 如果我使用 java 编译器 则会出现编译错误 因为 B 类尚未编译 如果我使用scala编译器A类将找不到 有没有可以同时
  • Scala repl 抛出错误

    当我打字时scala在终端上启动 repl 它会抛出此错误 scala gt init error error while loading AnnotatedElement class file usr lib jvm java 8 ora
  • 映射存在类型列表

    我有一个要映射的存在类型对象的列表 像这样的东西 sealed abstract class IntBox val v Int case object IB1 extends IntBox 1 case object IB2 extends
  • 如何在 Scala 中编写 Pig UDF

    我正在尝试在 Scala 中编写 Pig UDF 使用 Eclipse 我已将 pig jar 添加为 java 构建路径中的库 这似乎解决了以下 2 个导入问题 导入 org apache pig EvalFunc 导入 org apac
  • Joda Time 类没有任何构造函数...为什么?我做错了什么?

    显然 Eclipse 上的 Scala 试图让我相信DateTime Period DateMidnightJoda Time 中的许多其他类没有任何构造函数 考虑到它们的文档显示了构造函数和许多方法 这很奇怪 我唯一可以访问的是静态方法
  • 如何设计具有相互依赖的测试的 Specs2 数据库测试?

    有没有一些首选的方法来设计Specs2 http etorreborre github com specs2 测试 有很多测试取决于之前测试的结果 下面 您将找到我当前的测试套件 我不喜欢var位于测试片段之间 不过 它们是 需要的 因为某
  • 在scala / play框架中构建Json文件

    我正在使用 Play 框架和 Scala 我需要提供一个如下所示的输入 id node37 name 3 7 data children 如何使用 json 获取该格式 以下是 Play 框架网站上的示例 val JsonObject Js
  • 如何以最佳方式传递元组参数?

    如何以最佳方式传递元组参数 Example def foo Int Int def bar a Int b Int 现在我想传递的输出foo to bar 这可以通过以下方式实现 val fooResult foo bar fooResul
  • 为什么 Scala 中的隐式类必须驻留在另一个特征/类/对象中?

    基于scala文档 http docs scala lang org overviews core implicit classes html http docs scala lang org overviews core implicit
  • 具有两个通用参数的上下文边界

    在 Scala 中 我可以使用上下文边界 def sort T Ordered t Seq T 与以下意思相同 def sort T t Seq T implicit def Ordered T 如果我有一个带有两个泛型参数的类怎么办 IE
  • HashPartitioner 是如何工作的?

    我阅读了文档HashPartitioner http spark apache org docs 1 3 1 api java index html org apache spark HashPartitioner html 不幸的是 除了
  • 模拟 BlazeClientBuilder[IO] 以返回模拟客户端[IO]

    我正在使用BlazeClientBuilder IO resource方法得到Client IO 现在 我想模拟客户端进行单元测试 但不知道该怎么做 有没有一个好的方法来嘲笑这个 我会怎么做 class ExternalCall val r
  • 高效序列化案例类

    对于我正在工作的图书馆 我需要提供一个高效 便捷 typesafe序列化 scala 类的方法 理想的情况是用户可以创建一个案例类 并且只要所有成员都是可序列化的 它似乎也应该如此 我准确地知道序列化和反序列化阶段的类型 因此不需要 也不能
  • 对两种类型之间的二元关系进行建模

    有企业 也有人 用户可以对某个企业点赞或发表评论 但效果是一样的can not发生在一个人身上 当用户发布有关某个企业的内容或对其点赞时 该企业就被称为target喜欢或帖子 trait TargetingRelation Targetin
  • 如何使用 Spark 2 屏蔽列?

    我有一些表 我需要屏蔽其中的一些列 要屏蔽的列因表而异 我正在读取这些列application conf file 例如 对于员工表如下所示 id name age address 1 abcd 21 India 2 qazx 42 Ger

随机推荐

  • Python 基础知识8 循环

    循环语句关键知识 while flag True num 0 while flag and num lt 9 print meng num 1 死循环 while True print ling range 函数 for i in rang
  • R语言填坑

    最近在做一个数据挖掘的算法 用到了R语言 对遇到的一些坑 基础知识 做一个简单记录 文件编码问题 脚本写完之后保存可以选择UTF 8或者GB2313 可以解决中文乱码问题 同样 读文件的时候如果出现读不出来的情况 记得加一个 encodin
  • linux查看剩余信息保护,linux系统日常管理----监控系统的状态(一)

    监控系统的状态 1 w查看当前系统的负载 相信所有的linux管理员最常用的命令就是这个 w 了 该命令显示的信息还是蛮丰富的 第一行从左面开始显示的信息依次为 时间 系统运行时间 登录用户数 平均负载 第二行开始以及下面所有的行 告诉我们
  • 西门子S7-1200控制伺服/步进电机方法与接线(全)

    西门子S7 1200控制伺服 步进电机方法与接线 全 伺服 步进电机在非标自动化控制中十分常用 但作者发现在各类开源网站上很少有人做西门子1200PLC控制伺服 步进电机的教程 于是今天想着跟大家分享一下 本文共分为一下几个四个内容 文章目
  • IDEA 如何搭建python环境

    首先打开idea 首先是file gt setting 然后点击Plugins 然后在Marketplace里面搜索python 然后点击Installed 最后再重启一下IDEA
  • 最优化六:牛顿法(牛顿法、拟牛顿法、阻尼牛顿法)

    牛顿法将目标函数近似为二阶函数 沿着牛顿方向进行优化 包含了Hession矩阵与负梯度信息 阻尼牛顿法在更新参数之前进行了一维搜索确定步长 确保沿着下降的方向优化 拟牛顿法用常数矩阵近似替代Hession矩阵或Hession矩阵的逆矩阵 不
  • GprMax的建模in文件编写详细解释

    一 in建模文件示例 gprMax http www gprmax com 是一款模拟电磁波传播的开源软件 它采用时域有限差分 FDTD 方法求解三维麦克斯韦方程组 gprMax是为模拟探地雷达 GPR 而设计的 但也可以用于模拟电磁波传播
  • 设计模式之组合模式

    组合模式 将对象组合成树形结构以表示 部分 整体 的层次结构 组合模式使得用户对单个对象和组合对象的使用具有一致性 class Program static void Main string args Composite root new
  • python 文件读取

    def read file 读取文件 file name test txt 打开文件 f open file name encoding utf 8 with open file name encoding utf 8 as f 读取文件内
  • 将Ubuntu 的文件映射到windows 中

    可以通过Samba服务器将VM 下安装的Ubuntu 的文件映射到windows系统下 从而实现在windows下对虚拟机中的文件进行编辑 1 sudo apt get install samba 安装samba服务器 2 vim etc
  • Scala中的集合(容器)元素

    1 列表List https blog csdn net hzp666 article details 115004788 2 vector 向量 https blog csdn net hzp666 article details 115
  • Java多线程(面试)

    一 程序 进程与线程 程序 Program 程序是一段静态代码 进程 Process 进程是指一种正在运行的程序 有自己的地址空间 特点 动态性 并发性 独立性 并发和并行的区别 并发 多个cpu同时执行多个任务 并行 一个cpu同时执行多
  • TCP/IP网络编程之四书五经

    TCP IP网络编程之四书五经 http blog chinaunix net u 24935 showart 330099 html http book csdn net bookfiles 69 100691972 shtml http
  • python笔记8--命令行解析Argparse

    python笔记8 命令行解析Argparse 1 功能 2 源码案例 2 1 默认功能 2 3 添加说明 2 4 设置参数类型 2 5 设置参数可省略 2 6 同时存在可省略和必须参数 2 7 设置参数的范围 2 8 结束案例 3 说明
  • SpringBoot,或springcloud微服务项目前端Vue和后端java实现国际化

    外包公司接到了一个新加坡绿联国际银行的项目 有一个需求是要求实现国际化 像谷歌浏览器自带翻译那样 点按钮可以切换英文 繁体 中文来回切换这种效果 琢磨过之后找的资料最多的就是说用i18n 用i18n这个思路没问题 也很简单 下载一下i18n
  • Emqx的简单使用

    Emqx 是一个mqtt 的服务器产品 之前activemq可以作为mqtt协议的服务器 但是功能相对来说比较单一 Emqx作为跟Mqtt协议相关的新一代产品 功能实际上更为强大 它的功能也主要体现在可视化 认证 规则 httpApi 上面
  • MongoDB和Redis

    mongoDB基础语法 封装之后的查询 测试脚本 using System using YouYouServer Common using YouYouServer Common DBData using YouYouServer Core
  • javaweb (三)——javabean

    文章目录 1 1 javabean简介 1 2 javabean应用 1 2 1 javabean与表单 1 2 2 设置属性
  • 文献

    Hello 大家好 这里是壹脑云科研圈 我是墨心 你快乐吗 你想获得快乐吗 如果你不快乐 可能是因为你太想快乐了 这是一个 追求快乐 的悖论 Zerwas和Ford 2021 在Current Opinion in Behavioral S
  • chisel使用自定义/标准库中的函数简化设计(更新)

    主体内容摘自 https blog csdn net qq 34291505 article details 87905379 函数是编程语言的常用语法 即使是Verilog这样的硬件描述语言 也会用函数来构建组合逻辑 对于Chisel这样