chisel线网(wire)和寄存器(reg)详解(更新)

2023-10-30

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


在Verilog里,模块内部主要有“线网(wire)”和“四态变量(reg)”两种硬件类型,它们用于描述数字电路的组合逻辑和时序逻辑。在Chisel里,也按这个思路定义了一些硬件类型,包括基本的线网和寄存器。

在verilog中我们经常会对线网和寄存器赋值,以完成信号的传递或者电路的连接。在chisel中也是,线网和寄存器最常见的操作都是被赋值,因为只有这样我们才能实现各种我们想要的电路逻辑,所以,下面也会对在chisel中如何对线网和寄存器赋值做一下说明!!!


一、Chisel是如何赋值的

我们可以使用用赋值操作来进行信号的传递或者电路的连接。只有硬件赋值才有意义,单纯的数据类型的对象进行赋值并不会被编译器转换成实际的电路,因为在Verilog里也是对wire、reg类型的硬件进行赋值。那么,赋值操作需要什么样的操作符来完成呢?

在Chisel里,所有对象都应该由val类型的变量来引用,因为硬件电路的不可变性。因此,一个变量一旦初始化时绑定了一个对象,就不能再发生更改。但是,引用的对象很可能需要被重新赋值。例如,输出端口在定义时使用了“=”与端口变量名进行了绑定,那等到驱动该端口时,就需要通过变量名来进行赋值操作,更新数据。很显然,此时“=”已经不可用了,因为变量在声明的时候不是var类型。即使是var类型,这也只是让变量引用新的对象,而不是直接更新原来的可变对象。

为了解决这个问题,几乎所有的Chisel类都定义了方法“:=”,作为等号赋值的代替。所以首次创建变量时用等号初始化,如果变量引用的对象不能立即确定状态或本身就是可变对象,则在后续更新状态时应该用“:=”。从前面讲的操作符优先级来判断,该操作符以等号结尾,而且不是四种逻辑比较符号之一,所以优先级与等号一致,是最低的。例如:

val x = Wire(UInt(4.W))

val y = Wire(UInt(4.W))

x := "b1010".U  // 向4bit的线网x赋予了无符号数10

y := ~x  // 把x按位取反,传递给y

二、线网(类似于verilog中组合逻辑用的wire)

Chisel把线网作为电路的节点,通过工厂方法“Wire[T <: Data](t: T)”来定义。可以对线网进行赋值,也可以连接到其他电路节点,这是组成组合逻辑的基本硬件类型。例如:

  • 可以自动推断位宽:
val w0 = Wire(UInt()) // width is inferred
  • 也可以指定位宽:
val w1 = Wire(UInt(8.W)) // width is set to 8

注1:

  • 里面包裹Vec或者MixedVec也是可以的(注意,不能包裹Vecinit或者MixedVecinit,因为它们传入的是硬件类型,返回的也是硬件类型,而Wire必须传入数据类型):
val w2 = Wire(Vec(4, UInt())) // width is inferred
val w3 = Wire(Vec(4, UInt(8.W))) // width of each element is set to 8

但需要注意的是,一旦被Wire包裹,必须提供初始值,也即必须被驱动,至少要赋个DontCare,否则会报错。不过这个检查机制是可以关闭的!!!

注2: 赋值覆盖性理解

因为Scala作为软件语言是顺序执行的,定义具有覆盖性,所以如果对同一个线网多次赋值,则只有最后一次有效。例如下面的代码与上面的例子是等效的:

val myNode = Wire(UInt(8.W))

myNode := 10.U

myNode := 0.U

需要注意的是,如果存在多条赋值语句,那么要考虑覆盖性;如果只有一条赋值语句,那么该条语句一定是有效的,不能认为软件语言是顺序执行的就觉得该条语句执行过一次之后就没有了。因为对线网类型的赋值操作,在生成的verilog代码中一定会将其变成assign语句,那么该语句是一直有效的,你也可以认为一直在执行,只要右边的驱动源发生变化,左边的目标信号就一定会改变!!!下面举一个例子:
在这里插入图片描述
在这里插入图片描述
这是一个0-1上升沿检测的状态机,可以看到在switch里面,并没有对io.risingEdge进行false的赋值。这是因为,当需要进行true赋值的时候,它会覆盖一开始的false赋值语句;但是当条件不满足,不进行true赋值的时候,最上面的false赋值语句就会起作用,所以不在switch里面进行false赋值也是可以的。总之,总会有一个赋值语句起作用,否则就有可能出现未驱动的情况!!!

注3: 未驱动的线网

Chisel的Invalidate API支持检测未驱动的输出型IO以及定义不完整的Wire定义,在编译成firrtl时会产生“not fully initialized”错误。换句话说,就是组合逻辑的真值表不完整,不能综合出完整的电路。如果确实需要不被驱动的线网,则可以赋给一个DontCare对象,这会告诉Firrtl编译器,该线网故意不被驱动。转换成的Verilog会赋予该信号全0值,甚至把逻辑全部优化掉,所以谨慎使用。例如:

val io = IO(new Bundle {
    val outs = Output(Vec(10, Bool()))
})
io.outs <> DontCare 

检查机制是由CompileOptions.explicitInvalidate控制的,如果把它设置成true就是严格模式(执行检查),设置成false就是不严格模式(不执行检查)。

  • 开关方法有两种,第一种是定义一个抽象的模块类,由抽象类设置,其余模块都继承自这个抽象类。例如:
// 严格
abstract class ExplicitInvalidateModule extends Module()(chisel3.core.ExplicitCompileOptions.NotStrict.copy(explicitInvalidate = true))

// 不严格
abstract class ImplicitInvalidateModule extends Module()(chisel3.core.ExplicitCompileOptions.Strict.copy(explicitInvalidate = false)) 
  • 第二种方法是在每个模块里重写compileOptions字段,由该字段设置编译选项。例如:
// 严格
class MyModule extends Module {
  override val compileOptions = chisel3.core.ExplicitCompileOptions.NotStrict.copy(explicitInvalidate = true)
  ...
} 

// 不严格
class MyModule extends Module {
  override val compileOptions = chisel3.core.ExplicitCompileOptions.Strict.copy(explicitInvalidate = false)
  ...
}

三、寄存器(类似于verilog中时序逻辑中用的reg)

寄存器是时序逻辑的基本硬件类型,它们都是由当前时钟域的时钟上升沿触发的如果模块里没有多时钟域的语句块,那么寄存器都是由隐式的全局时钟来控制。对于有复位信号的寄存器,如果不在多时钟域语句块里,则由隐式的全局复位来控制,并且高有效。目前Chisel所有的复位都是同步复位,异步复位功能还在开发中。如果需要异步复位寄存器,则需要通过黑盒引入

有五种内建的寄存器:

  • 第一种是跟随寄存器“RegNext[T <: Data](next: T)”,在每个时钟上升沿,它都会采样一次传入的参数(跟随),并且没有复位信号;它的另一个版本的apply工厂方法是“RegNext[T <: Data](next: T, init: T)”,也就是由复位信号控制,当复位信号有效时,复位到指定值,否则就跟随。

注4:

注意,在定义时传入next,后面可以无需再显式的对寄存器赋值,它会自动跟随next;但也可以在后面再对其进行无条件或者有条件赋值,这样会覆盖掉之前的定义或者赋值,然后开始跟随新的变量。这里的覆盖,比如RegNext[T <: Data](next: T, init: T),一开始如果给了init参数,那么是会有复位信号的, 但如果被后面的无条件或者有条件赋值给覆盖,那么复位信号的有无就要取决了后面的赋值逻辑!!!

  • 第二种是复位到指定值的寄存器“RegInit[T <: Data](init: T)”或者“RegInit[T <: Data](t: T, init: T)”,可以进行条件赋值,也可以无条件赋值;默认有复位信号;参数t的意思是提供一个数据类型模板,也即指定数据的类型,不用给确切的值。

定义之后可以不显式赋值,但是会被当做一个常量,常量的值取决于你定义时给的init参数的值。

  • 第三种是普通的寄存器“Reg[T <: Data](t: T)”,可以进行条件赋值,也可以进行无条件赋值,默认没有复位信号;参数t的意思是提供一个数据类型模板,也即指定数据的类型,不用给确切的值。

注5:

定义之后必须显式赋值,否则报错!!!

  • 第四种是util包里的带一个使能端的寄存器“RegEnable[T <: Data](next: T, init: T, enable: Bool)”,如果不需要复位信号,则第二个参数需要省略给出;有使能信号。

注6:

注意,在定义时传入next,后面可以无需再显式的对寄存器赋值,它会自动跟随next;但也可以在后面再对其进行无条件或者有条件赋值,这样会覆盖掉之前的定义或者赋值,然后开始跟随新的变量。一开始如果给了init参数,那么是会有复位信号的,也有使能信号; 但如果被后面的无条件或者有条件赋值给覆盖,那么复位信号和使能信号的有无就都要取决了后面的赋值逻辑了!!!

  • 第五种是util包里的移位寄存器“ShiftRegister[T <: Data](in: T, n: Int, resetData: T, en: Bool)”,其中第一个参数in是待移位的数据;第二个参数n是需要延迟的周期数;第三个参数resetData是指定的复位值,可以省略,省略之后无复位信号;第四个参数en是使能移位的信号,默认为true.B。

从以上内容可以总结出:

  • 如果寄存器有next参数,那么就可以无任何显式赋值操作,寄存器会跟随next参数,如RegNext、RegEnable;如果无next参数,而是t参数,那么就必须显式的赋值,如RegInit、Reg;ShiftRegister因为有in参数,也可以不用显式赋值。
  • 如果有init或者resetData参数,那么就不需要显式的将reset信号作为when的条件进行赋值,这样也会有复位信号,当然也可以通过省略init参数使得生成的verilog代码中没有复位信号(RegInit除外);如果没有init参数,就只有通过将reset信号作为when的条件进行赋值才会有复位信号。
  • 无条件赋值就是直接赋值,有条件就是使用when语句。
  • 如果寄存器被赋值为常量,那么在生成的verilog中就不会出现该寄存器变量;如果被赋值为变量,那么才会在跟随该变量,跟随就是每个时钟上升沿时对变量进行采样。
  • 除了Reg,其余寄存器传入的参数都必须是硬件类型,而Reg传入的参数是数据类型。
  • 关于t参数的理解:提供一个参数模板的意思就是指定该寄存器的数据类型,不能指定为确切值,并且在以后赋值的时候所提供的值必须是该类型,如下所示:
class MyBundle extends Bundle {
  val unknown = UInt()
  val known   = UInt(8.W)
}

val myreg = Reg(new MyBundle)
val myReg = RegInit(UInt(12.W), 0.U)//对应RegInit[T <: Data](t: T, init: T)
val myReg = RegInit(0.U(12.W))//对应RegInit[T <: Data](init: T)

假如有如下代码:

// reg.scala
package test
 
import chisel3._
import chisel3.util._
class REG extends Module {
  val io = IO(new Bundle {
    val a = Input(UInt(8.W))
    val en = Input(Bool())
    val c = Output(UInt(1.W))
  })
  val reg0 = RegNext(io.a)
  val reg1 = RegNext(io.a, 0.U)
  val reg2 = RegInit(0.U(8.W))
  val reg3 = Reg(UInt(8.W))
  val reg4 = Reg(UInt(8.W))
  val reg5 = RegEnable(io.a + 1.U, 0.U, io.en)
  val reg6 = RegEnable(io.a - 1.U, io.en)
  val reg7 = ShiftRegister(io.a, 3, 0.U, io.en)
  val reg8 = ShiftRegister(io.a, 3, io.en)
  
  reg2 := io.a.andR
  reg3 := io.a.orR
  when(reset.asBool) {
    reg4 := 0.U
  } .otherwise {
    reg4 := 1.U
  }
  io.c := reg0(0) & reg1(0) & reg2(0) & reg3(0) & reg4(0) & reg5(0) & reg6(0) & reg7(0) & reg8(0)
} 

对应生成的主要Verilog代码为:

// REG.v
module REG(
  input        clock,
  input        reset,
  input  [7:0] io_a,
  input        io_en,
  output       io_c
);
  reg [7:0] reg0; 
  reg [7:0] reg1; 
  reg [7:0] reg2; 
  reg [7:0] reg3; 
  reg [7:0] reg4; 
  wire [7:0] _T_1; 
  reg [7:0] reg5; 
  wire [8:0] _T_2; 
  wire [8:0] _T_3; 
  wire [7:0] _T_4; 
  reg [7:0] reg6; 
  reg [7:0] _T_5; 
  reg [7:0] _T_6; 
  reg [7:0] reg7; 
  reg [7:0] _T_7; 
  reg [7:0] _T_8; 
  reg [7:0] reg8; 
  wire [7:0] _T_9; 
  wire  _T_10; 
  wire  _T_11; 
  wire  _GEN_8; 
  wire  _T_13; 
  wire  _T_14; 
  wire  _T_15; 
  wire  _T_16; 
  wire  _T_17; 
  wire  _T_18; 
  wire  _T_19; 
  wire  _T_20; 
  wire  _T_21; 
  wire  _T_22; 
  wire  _T_23; 
  wire  _T_24; 
  wire  _T_25; 
  wire  _T_26; 
  wire  _T_27; 
  wire  _T_28; 
  assign _T_1 = io_a + 8'h1; 
  assign _T_2 = io_a - 8'h1; 
  assign _T_3 = $unsigned(_T_2); 
  assign _T_4 = _T_3[7:0]; 
  assign _T_9 = ~ io_a; 
  assign _T_10 = _T_9 == 8'h0; 
  assign _T_11 = io_a != 8'h0; 
  assign _GEN_8 = reset ? 1'h0 : 1'h1; 
  assign _T_13 = reg0[0]; 
  assign _T_14 = reg1[0]; 
  assign _T_15 = _T_13 & _T_14; 
  assign _T_16 = reg2[0]; 
  assign _T_17 = _T_15 & _T_16; 
  assign _T_18 = reg3[0]; 
  assign _T_19 = _T_17 & _T_18; 
  assign _T_20 = reg4[0]; 
  assign _T_21 = _T_19 & _T_20; 
  assign _T_22 = reg5[0]; 
  assign _T_23 = _T_21 & _T_22; 
  assign _T_24 = reg6[0]; 
  assign _T_25 = _T_23 & _T_24; 
  assign _T_26 = reg7[0]; 
  assign _T_27 = _T_25 & _T_26; 
  assign _T_28 = reg8[0]; 
  assign io_c = _T_27 & _T_28; 
 
  always @(posedge clock) begin
    reg0 <= io_a;
    if (reset) begin
      reg1 <= 8'h0;
    end else begin
      reg1 <= io_a;
    end
    if (reset) begin
      reg2 <= 8'h0;
    end else begin
      reg2 <= {{7'd0}, _T_10};
    end
    reg3 <= {{7'd0}, _T_11};
    reg4 <= {{7'd0}, _GEN_8};
    if (reset) begin
      reg5 <= 8'h0;
    end else begin
      if (io_en) begin
        reg5 <= _T_1;
      end
    end
    if (io_en) begin
      reg6 <= _T_4;
    end
    if (reset) begin
      _T_5 <= 8'h0;
    end else begin
      if (io_en) begin
        _T_5 <= io_a;
      end
    end
    if (reset) begin
      _T_6 <= 8'h0;
    end else begin
      if (io_en) begin
        _T_6 <= _T_5;
      end
    end
    if (reset) begin
      reg7 <= 8'h0;
    end else begin
      if (io_en) begin
        reg7 <= _T_6;
      end
    end
    if (io_en) begin
      _T_7 <= io_a;
    end
    if (io_en) begin
      _T_8 <= _T_7;
    end
    if (io_en) begin
      reg8 <= _T_8;
    end
  end
endmodule

四、寄存器组(可以一次性生成多个reg)

上述构造寄存器的工厂方法,它们的参数可以是任何Data的子类型。如果把子类型Vec[T]作为参数传递进去,就会生成多个位宽相同、行为相同、名字前缀相同的寄存器当然如果Vec[T]或者Vecinit[T]中的参数不一样,那么生成的多个reg也不一样,其实它们本质上是没啥必然联系的,具体咋用取决于你想怎么操作它们!!!。同样,寄存器组在Chisel代码里可以通过下标索引。例如:

// reg2.scala
package test
 
import chisel3._
import chisel3.util._
class REG2 extends Module {
  val io = IO(new Bundle {
    val a = Input(UInt(8.W))
    val en = Input(Bool())
    val c = Output(UInt(1.W))
  })
  val reg0 = RegNext(VecInit(io.a, io.a))
  val reg1 = RegNext(VecInit(io.a, io.a), VecInit(0.U, 0.U))
  val reg2 = RegInit(VecInit(0.U(8.W), 0.U(8.W)))
  val reg3 = Reg(Vec(2, UInt(8.W)))
  val reg4 = Reg(Vec(2, UInt(8.W)))
  val reg5 = RegEnable(VecInit(io.a + 1.U, io.a + 1.U), VecInit(0.U(8.W), 0.U(8.W)), io.en)
  val reg6 = RegEnable(VecInit(io.a - 1.U, io.a - 1.U), io.en)
  val reg7 = ShiftRegister(VecInit(io.a, io.a), 3, VecInit(0.U(8.W), 0.U(8.W)), io.en)
  val reg8 = ShiftRegister(VecInit(io.a, io.a), 3, io.en)
  
  reg2(0) := io.a.andR
  reg2(1) := io.a.andR
  reg3(0) := io.a.orR
  reg3(1) := io.a.orR
  when(reset.asBool) {
    reg4(0) := 0.U
    reg4(1) := 0.U
  } .otherwise {
    reg4(0) := 1.U
    reg4(1) := 1.U
  }
  io.c := reg0(0)(0) & reg1(0)(0) & reg2(0)(0) & reg3(0)(0) & reg4(0)(0) & reg5(0)(0) & reg6(0)(0) & reg7(0)(0) & reg8(0)(0) &
          reg0(1)(0) & reg1(1)(0) & reg2(1)(0) & reg3(1)(0) & reg4(1)(0) & reg5(1)(0) & reg6(1)(0) & reg7(1)(0) & reg8(1)(0)
}

五、用when给线网或者寄存器进行条件赋值

在Verilog里,可以使用“if…else if…else”这样的条件选择语句来方便地构建电路的逻辑。由于Scala已经占用了“if…else if…else”语法,所以相应的Chisel控制结构改成了when语句,其语法如下:

when (condition 1) { definition 1 }
.elsewhen (condition 2) { definition 2 }
...
.elsewhen (condition N) { definition N }
.otherwise { default behavior }

注意,“.elsewhen”和“.otherwise”的开头有两个句点。所有的判断条件都是返回Bool类型的传名参数,不要和Scala的Boolean类型混淆,也不存在Boolean和Bool之间的相互转换。对于UInt、SInt,甚至是Clock和Reset类型,可以用方法asBool转换成Bool类型来作为判断条件


when语句不仅可以给线网赋值,还可以给寄存器赋值,但是要注意构建组合逻辑时不能缺失“.otherwise”分支。 下面是一个简单的寻找三个数中的最大值的模块:

class Max3 extends Module {
  val io = IO(new Bundle {
    val in1 = Input(UInt(16.W))
    val in2 = Input(UInt(16.W))
    val in3 = Input(UInt(16.W))
    val out = Output(UInt(16.W))
  })
    
  when(io.in1 >= io.in2 && io.in1 >= io.in3) {
    io.out := io.in1  
  }.elsewhen(io.in2 >= io.in3) {
    io.out := io.in2 
  }.otherwise {
    io.out := io.in3
  }
}

when有很多场合可以使用:

  • 比如使用when给带使能信号的寄存器更新数据;
  • 还可用于状态机的状态转换;

除了when结构,util包里还有一个与之对偶的结构“unless”,如果unless的判定条件为false.B则一直执行,否则不执行:

import chisel3.util._

unless (condition) { definition }
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

chisel线网(wire)和寄存器(reg)详解(更新) 的相关文章

  • 组合逻辑电路——编码器

    组合逻辑电路 编码器 概念 编码的概念 在数字系统中 常需要将有特定意义的信息编成二进制代码 这一过程称为编码 编码器 实现编码的数字电路被称为编码器 二进制编码器 这里我们采用与非门来设计二进制编码器 二进制编码器输出端数量不定 可以根据
  • STM32学习——什么是寄存器(存储器映射和寄存器映射)

    目录 STM32芯片里面有什么 一 驱动单元 1 ICode总线 2 DCode总线 3 系统总线 4 DMA总线 二 被动单元 1 内部的闪存存储器 2 内部的SRAM 3 FSMC 4 AHB到APB的桥 三 STM32的外设基地址映射
  • Chisel Tutorial(五)——Bundles与Vecs

    以下内容依据2015 7 10版的Chisel 2 2 Tutorial整理 此处的Bundles Vecs就不翻译了 免得因为翻译不准引起一些误解 童鞋们有没有好的建议 lt
  • Timing Borrow的理解

    在集成电路设计中 静态时序分析 Static Timing Analysis STA 是一种常用的验证方法 用于确保芯片在运行时的时序约束得到满足 在STA分析过程中 Timing Borrow是一种时序收敛技术 即在某些情况下 可以借用下
  • 7种PCB走线方式

    01电源布局布线相关 数字电路很多时候需要的电流是不连续的 所以对一些高速器件就会产生浪涌电流 如果电源走线很长 则由于浪涌电流的存在进而会导致高频噪声 而此高频噪声会引入到其他信号中去 而在高速电路中必然会存在寄生电感和寄生电阻以及寄生电
  • 超详细!基于Proteus的简易测频计实现(数字电路课程设计)

    本文阐述基于Proteus 7 8的简易测频计电路的实现 附具体电路的工程文件下载 工程文件下载链接 设计要求 闸门时间1S 10S可选 读数保持时间10秒 可选 四位数字显示 范围000 1 9999 Hz 能够自动进行下一次测量 设计方
  • Chisel 教程翻译 之 第三章 构建过程和测试 of 《Digital Design with Chisel》

    3 Build Process and Testing 21 3 1 Building your Project with sbt 21 3 1 1 Source Organization 21 3 1 2 Running sbt 23 3
  • 吃透Chisel语言.10.Chisel项目构建、运行和测试(二)——Chisel中生成Verilog代码&Chisel开发流程

    Chisel项目构建 运行和测试 二 Chisel中生成Verilog代码 Chisel开发流程 上一篇文章我们提到了怎么用sbt构建Chisel项目并运行Chisel代码 但是毕竟还是在电脑上运行的 而在实践中 我们写的Chisel代码最
  • Chisel入门(三)------Chisel的基本语法2

    概述 继续介绍Chisel的基本语法 3 组件 3 1 Chisel中的组件是模块 Chisel中的每个模块都拓展了class 并包含了接口的io字段 接口是由封装为IO 的Bundle所定义的 Bundle包含的字段表示模块的输入输出端口
  • chisel可选值/模式匹配实例

    一 scala可选值语法 可选值就是类型为Option T 的一个值 其中 Option是标准库里的一个密封抽象类 T可以是任意的类型 例如标准类型或自定义的类 并且T是协变的 简单来说 就是如果类型T是类型U的超类 那么Option T
  • chisel黑盒(调用verilog书写的模块)

    因为Chisel的功能相对Verilog来说还不完善 所以设计人员在当前版本下无法实现的功能 就需要用Verilog来实现 在这种情况下 可以使用Chisel的BlackBox功能 它的作用就是向Chisel代码提供了用Verilog设计的
  • 电子技术基础(三)__第7章 时序逻辑电路_D触发器

    在触发器的分类中有 同步触发器 同步触发器有3种 其中就有一种是 D触发器 称为同步D触发器 另外 还有一种触发器是 维持阻塞型 D触发器 这里 D 指Delay 延时 一 概念 1 1 概念 我们再次看到时钟上 有o 与 无o的区别 这在
  • chisel相比verilog优势之一:复用特性

    0 绪论 世界由于人这个最大的无厘头变量 还是比技术本身复杂难懂很多 各种技术的兴起与发展总是有其背后的理由的 这篇文章是这个系列的第三篇文章 主要来说明Chisel比Verilog在某些方面具有优势的理由 换句话说 为什么要用Chisel
  • chisel使用自定义/标准库中的函数简化设计(更新)

    主体内容摘自 https blog csdn net qq 34291505 article details 87905379 函数是编程语言的常用语法 即使是Verilog这样的硬件描述语言 也会用函数来构建组合逻辑 对于Chisel这样
  • MOS管应用---电源开关、电平转换、防反接、全桥变换器

    MOS管应用 电源开关 电平转换 防反接 全桥变换器 1 PMOS作电源开关 Q2也可以用光耦替代 电容C1 电阻R2延长MOS管导通 截止时间 实现软开启 soft start 功能 充电时间3到4个R2 C2 2 NMOS作双向电平转换
  • 详细介绍如何在linux中配置chisel环境

    一 安装java和scala 1 安装java 安装java sudo apt install openjdk 11 jre headless 安装javac sudo apt install openjdk 11 jdk headless
  • 握手信号valid/ready的打拍技巧

    一 前言 valid和ready信号 尤其是ready信号的时序一般很差 因为它通常是接收端通过组合逻辑输出的 当流水线的级数较多时 ready反压信号一级一级往前传递 时序将会变得更差 为了优化时序 通常需要对valid和ready信号进
  • asm:常用语法

    常用语法 1 循环 1 1 使用条件跳转指令实现循环 1 2 使用LOOP指令实现循环 2 字符串 2 1 指定字符串的长度 2 2 字符串指令 2 3 重复前缀 3 数组 4 递归 5 宏 6 文件操作 7 内存管理 1 循环 1 1 使
  • Chisel实验笔记(一)

    最近在学习Risc v 其中伯克利大学开源了一款兼容Risc v指令集的处理器Rocket 而Rocket处理器是采用Chisel编写的 所以要学习Chisel Chisel的简单介绍如下 Chisel Constructing Hardw
  • W801

    目录 文档来源 芯片概述及MCU 特性可参考 安全特性 Wi Fi 特性 蓝牙特性 低功耗模式 芯片结构 与前述介绍的外设相对应 总线结构 说明 1 AHB 1 总线 主设备列表 编辑 从设备列表 2 AHB 2总线 时钟结构 CDK中对运

随机推荐

  • React直接渲染从后台传过来的标签

    在工作中使用react 遇到需要渲染从后台获取到的标签语言 发现直接放在react中是不能解析标签语言的 解决办法如下 var content strong content strong 假设content是从接口获取到的数据 react
  • 大数据shell基础

    一 常用shell命令 1 管道命令 命令1 命令2 命令1的输入作为命令2的输入 2 抓取命令 grep命令 可以使用正则表达式来过滤 3 查找命令 find命令 选项参数 type name size perm 如果上面这个不行可以在
  • 蓝桥杯 java a组_2019年第十届蓝桥杯国赛总结(JavaA组)

    JavaA组国二 可以报销了 JA死亡之组可不是盖的 rank12的排名还是拿不到国一啊 只有五个 出成绩的一刻波澜不惊 毕竟去年有国一了不慌哈哈哈 不过对我来说这个结果还算意料之外吧 毕竟大三考研狗 这次再也不敢说蓝桥杯水了 十周年十道题
  • EMC的RS和CS和RI,CI一样吗是属于EMS 吗

    EMC Electromagnetic Compatibility 是指电子设备在电磁环境中能够正常工作 同时不对周围的其他设备和系统产生不可接受的电磁干扰的能力 在EMC设计中 RS Radiated Susceptibility 和CS
  • stm32电机驱动调试平台pid调试开发ros底盘里程计脉冲速度监测MPR

    MPRO 用于调试ros小车底盘 pid开发学学 电机驱动板反馈脉冲等数据的上位机工具 欢迎下载试用 MPRO搭载stm32单片机驱动GA370编码电机 实现PID速度调节 转向控制 实体图如下 采用杜邦线加模块设计 简单易用 可实现插拔
  • JLINK在ADS中的调试心得

    JLINK在ADS中的调试心得 分类 ARM 2010 01 03 19 39 138人阅读 评论 0 收藏 举报 分享 JLINK在ADS下调试心得 前两天一个客户用jlink在ADS来调试LPC2148总报错 这个错误我之前在调试LPC
  • 【论文精读】HumanNeRF

    目录 Abstract 1 Introduction 2 Related work Human specific rendering Neural radiance fields Human specific neural renderin
  • Java:抽象类和接口

    文章目录 抽象类 什么是抽象类 抽象类的特性 为什么会有抽象类这种东西 接口 什么是接口 接口的特性 匿名内部类 拓展 实现多个接口 接口间的继承 三个重要的接口 Comparable接口 Comparator接口 Clonable接口 浅
  • 关于 Cannot read property 'length' of null 报错的解决办法

    最近在搞前端的时候突然报了Cannot read property length of null的错 一开始都是在前端调试错 发现解决不了问题 后来发现如果你所查找的数据条数为0的时候 后端返回给前端是null 此时必然报错Cannot r
  • CityEngine三维建模几个常见问题解决方法(1)

    CityEngine被Esri收购以后 大踏步进入GIS三维建模领域 由于CityEngine独有的基于规则建模 使得GIS三维建模效率大增 不过不是规则就可以一刀切 解决所有问题的 有时我们还是要做这样或那样的一些处理才能顺利的使用规则达
  • Mysql8.0开启远程访问权限

    use mysql 登录后选择mysql数据库 select host user password from user 查看当前root对应host是否为 update user set host where user root 更新 se
  • 基于YOLOv5+Hough变换的目标检测和车道线检测

    这学期做的一个大作业 实现了对行驶过程中车辆 行人以及车道线的检测 1 B站视频演示 2 Github仓库链接 文章目录 一 实现效果 二 环境配置 三 基于YOLOv5的目标检测 四 基于Hough变换的车道线检测 4 1 前置工作 Ca
  • 鸿蒙3部曲先看哪部,“隋唐三部曲”“鸿蒙三部曲”“斗罗四部曲”谁才是网文巅峰之作...

    原标题 隋唐三部曲 鸿蒙三部曲 斗罗四部曲 谁才是网文巅峰之作 从网络小说诞生的那一刻起 续集就是一个绕不过去的话题 如同电视剧一样 一部网络小说红了之后 它的原作者很多时候会忍不住开发它的续集 形成一个系列 然后再现网文界 小编今天就给大
  • java开发转测试开发经历

    1 背景 我从毕业一直做java开发已经两年半了 到目前为止也挺喜欢开发的 2 为什么想转行 想转行是由多方面考虑的 一 我的开发技能没达标 只能找到外包里的开发工作 二 开发前景对女生不够友好 难以获得认可 个人感受 至于第一点其实也可以
  • 减少数据打拍翻转的低功耗设计方法

    在流水设计中 时常会遇到对某一路数据打多拍从而对齐另一路数据的场景 而除了最后一拍是真正需要的 中间的打拍从功耗上来看是有点浪费的 举个例子 对8bit in data打4拍 总共需要用到4个8bit寄存器 常规打拍方法传输4个数据 D0
  • android 屏幕适配--------解决方案

    以下是Demo首页的预览图 demo下载 http www eoeandroid com forum php mod attachment aid NjE0Njh8ZTIyZDA2M2N8MTMzODgyOTQxN3w1NzAwOTV8MT
  • Spring Boot实现QQ邮件发送,用户注册功能——前后端分离版

    1 准备工作 我们需要前往我们的QQ邮箱开启相关功能 登录QQ邮箱后 点击进入 设置 在账户在一栏中 我们可以找到这个界面 然后点击开启 POP3 SMTP服务 他们会让我们用QQ的密保手机发送一条短信 我们照着即可 验证成功之后 会获得一
  • ISP记1

    目录 0 参考 1 噪声分类 1 1 空间区域 1 1 1 高斯噪声 1 1 2 瑞利噪声 1 1 3 伽马噪声 1 1 4 均匀分布噪声 1 1 5 泊松噪声 1 1 6 加性噪声 乘性噪声 0 参考 数字图像滤波算法的研究及应用 倪层敏
  • anaconda+pytorch安装说明

    第一步 anconda的安装 大家可以参考以下博文 写的比较简约 看起来比较清爽 https blog csdn net ITLearnHall article details 81708148 Anacond的介绍 Anaconda指的是
  • chisel线网(wire)和寄存器(reg)详解(更新)

    主体内容摘自 https blog csdn net qq 34291505 article details 87714172 在Verilog里 模块内部主要有 线网 wire 和 四态变量 reg 两种硬件类型 它们用于描述数字电路的组