跳转至

Combinational Building Blocks

val 不可重新赋值

val 无法用=, :=重新赋值

要表达Mux, 需使用Wire

When

when生成 Mux:

val w = Wire(UInt())
w := 0.U

// val w = WireDefault(0.U)  //  assign default value for complex circuit

when (cond) {
    w := 1.U
}
image.png
val w = Wire(UInt())
when(cond) {
    w := 1.U
} .elsewhen(cond2) {
    w := 2.U
} .otherwise {
    w := 3.U
}

elsewhen

elsewhen可接无数个 当所有条件与某个变量相关时,最好使用switch

Switch

switch生成 decoder:

result := 0.U  // always need to assign default value

switch(sel) {
    is (0.U) { result := 1.U }
    is (1.U) { result := 2.U }
    is (2.U) { result := 4.U }
    is (3.U) { result := 8.U }
}

switch(sel) {
    is ("b00".U) { result := "b0001".U }
    is ("b01".U) { result := "b0010".U }
    is ("b10".U) { result := "b0100".U }
    is ("b11".U) { result := "b1000".U }
}

result := 1.U << sel

Encoder

小Encode

b := "b00".U  // assign default value
switch (a) {
    is ("b0001".U) { b:= "b00".U }
    is ("b0010".U) { b:= "b01".U }
    is ("b0100".U) { b:= "b10".U }
    is ("b1000".U) { b:= "b11".U }
}

循环

for (i <- 0 until 10) {  // [0, 9]
    // ...
}

硬件生成器

val v = Wire(Vec(16, UInt(4.W)))
v(0) := 0.U
for (i <- 1 until 16) {
    v(i) := Mux(hotIn(i), i.U, 0.U) | v(i - 1)
}
val encOnt = v(15)
  • 向量v的每个元素在对应的整数值和0中选择,选择信号为输入hotIn的对应位
  • 对向量v做约化,求或相当于求前缀或,约化结果为v(15)

生成结果

module Encoder(
  input         clock,
                reset,
  input  [15:0] io_hotIn,
  output [3:0]  io_encOut
);

  wire [2:0] _v_5_T_1 = io_hotIn[5] ? 3'h5 : 3'h0;
  wire [2:0] _v_6_T_1 = io_hotIn[6] ? 3'h6 : 3'h0;
  assign io_encOut =
    {4{io_hotIn[15]}} | (io_hotIn[14] ? 4'hE : 4'h0) | (io_hotIn[13] ? 4'hD : 4'h0)
    | (io_hotIn[12] ? 4'hC : 4'h0) | (io_hotIn[11] ? 4'hB : 4'h0)
    | (io_hotIn[10] ? 4'hA : 4'h0) | (io_hotIn[9] ? 4'h9 : 4'h0)
    | {io_hotIn[8],
       io_hotIn[7] | _v_6_T_1[2] | _v_5_T_1[2] | io_hotIn[4],
       {2{io_hotIn[7]}} | _v_6_T_1[1:0] | _v_5_T_1[1:0] | {2{io_hotIn[3]}}
         | io_hotIn[2:1]};
endmodule

优先仲裁器

  • 优先放行低位信号
  • 每次只放行一个信号

小仲裁器

val grant = VecInit(false.B, false.B, false.B)
val notGranted = VecInit(false.B, false.B)

grant(0) := request(0)
notGranted(0) := !grant(0)
grant(1) := request(1) && notGranted(0)
notGranted(1) := !grant(1) && notGranted(0)
grant(2) := request(2) && notGranted(1)
val grant = WireDefault("b000".U(3.W))
switch (request) {
    is ("b000".U) { grant := "b000".U }
    is ("b001".U) { grant := "b001".U }
    is ("b010".U) { grant := "b010".U }
    is ("b011".U) { grant := "b001".U }
    is ("b100".U) { grant := "b100".U }
    is ("b101".U) { grant := "b001".U }
    is ("b110".U) { grant := "b010".U }
    is ("b111".U) { grant := "b001".U }
}

硬件生成器

val grant = VecInit.fill(n)(false.B)
val notGranted = VecInit.fill(n)(false.B)

grant(0) := request(0)
notGranted(0) := !grant(0)

for (i <- 1 until n) {
    grant(i) := request(i) && notGranted(i - 1)
    notGranted(i) := !grant(i) && notGranted(i - 1)
}
生成结果
module Arbiter(
  input        clock,
               reset,
  input  [2:0] io_request,
  output [2:0] io_grant
);

  wire grant_1 = io_request[1] & ~(io_request[0]);
  assign io_grant = {io_request[2] & ~grant_1 & ~(io_request[0]), grant_1, io_request[0]};
endmodule

优先编码器

优先编码器 = 仲裁器 + 编码器 image.png

比较器

val equ = a === b
val gt = a > b