前几天想将一个大小端转换的模块转成chisel,感觉挺简单,但真写起来就各种bug。

module EndianCnvt #(parameter NUMLENGTH = 128)(
	input [NUMLENGTH-1:0]	NumIn,
	output [NUMLENGTH-1:0]	NumOut
	);
	localparam BYTENUM = NUMLENGTH/8;
	genvar i;
	for (i=0; i

一开始就是简单直译,但会保存,因为UInt类型不能切片赋值,在一点在官网cookbook其实已经说了,是我没认真看~

class EndianCnvt (NUMLENGTH :Int)extends Module{
  val io = IO(new Bundle {
    val NumIn = Input(UInt(NUMLENGTH.W))
    val NumOut= Output(UInt(NUMLENGTH.W))
  })
  val BYENUM = NUMLENGTH>>3
  val temp = Wire(Vec(BYENUM,UInt(8.W)))
  for (i <- 0 until BYENUM){
    io.NumOut[(i+1)*8-1:i*8] := io.NumIn((BYENUM-i)*8-1,(BYENUM-i-1)*8)//UInt不能切片赋值
  }
}

需要先转换类型才能赋值:

class EndianCnvt (NUMLENGTH :Int)extends Module{
  val io = IO(new Bundle {
    val NumIn = Input(UInt(NUMLENGTH.W))
    val NumOut= Output(UInt(NUMLENGTH.W))
  })
  val BYENUM = NUMLENGTH>>3
  val temp = Wire(Vec(BYENUM,UInt(8.W)))//转换成8bit的数组,分别赋值,再转回UInt
  for (i <- 0 until BYENUM){
    temp(i) := io.NumIn((BYENUM-i)*8-1,(BYENUM-i-1)*8)
  }
  io.NumOut := temp.asUInt
}

后来大神说可以用reverse的方法,还是很好用的,最后再添加例化模块的apply方法

class EndianCnvt (NUMLENGTH :Int)extends Module{
  val io = IO(new Bundle {
    val NumIn = Input(UInt(NUMLENGTH.W))
    val NumOut= Output(UInt(NUMLENGTH.W))
  })
  val BYENUM = NUMLENGTH>>3
  val temp =  io.NumIn.asTypeOf(Vec(BYENUM,UInt(8.W)))
  val temp2 = Wire(Vec(BYENUM,UInt(8.W)))
  temp2 := temp.reverse  //reverse方法,这里必须借助中间变量temp2,不然也会报错
  io.NumOut := temp2.asUInt()
}
object EndianCnvt{
  def apply(in1:UInt,NUMLENGTH:Int) :UInt={
  val inst = Module(new EndianCnvt(NUMLENGTH))
  inst.io.NumIn := in1
  inst.io.NumOut
}
}

生成的verilog如下:

module EndianCnvt(
  input          clock,
  input          reset,
  input  [127:0] io_NumIn,
  output [127:0] io_NumOut
);
  wire [7:0] temp_0 = io_NumIn[7:0]; // @[sub_module.scala 32:32]
  wire [7:0] temp_1 = io_NumIn[15:8]; // @[sub_module.scala 32:32]
  wire [7:0] temp_2 = io_NumIn[23:16]; // @[sub_module.scala 32:32]
  wire [7:0] temp_3 = io_NumIn[31:24]; // @[sub_module.scala 32:32]
  wire [7:0] temp_4 = io_NumIn[39:32]; // @[sub_module.scala 32:32]
  wire [7:0] temp_5 = io_NumIn[47:40]; // @[sub_module.scala 32:32]
  wire [7:0] temp_6 = io_NumIn[55:48]; // @[sub_module.scala 32:32]
  wire [7:0] temp_7 = io_NumIn[63:56]; // @[sub_module.scala 32:32]
  wire [7:0] temp_8 = io_NumIn[71:64]; // @[sub_module.scala 32:32]
  wire [7:0] temp_9 = io_NumIn[79:72]; // @[sub_module.scala 32:32]
  wire [7:0] temp_10 = io_NumIn[87:80]; // @[sub_module.scala 32:32]
  wire [7:0] temp_11 = io_NumIn[95:88]; // @[sub_module.scala 32:32]
  wire [7:0] temp_12 = io_NumIn[103:96]; // @[sub_module.scala 32:32]
  wire [7:0] temp_13 = io_NumIn[111:104]; // @[sub_module.scala 32:32]
  wire [7:0] temp_14 = io_NumIn[119:112]; // @[sub_module.scala 32:32]
  wire [7:0] temp_15 = io_NumIn[127:120]; // @[sub_module.scala 32:32]
  wire [63:0] lo = {temp_8,temp_9,temp_10,temp_11,temp_12,temp_13,temp_14,temp_15}; // @[sub_module.scala 35:28]
  wire [63:0] hi = {temp_0,temp_1,temp_2,temp_3,temp_4,temp_5,temp_6,temp_7}; // @[sub_module.scala 35:28]
  assign io_NumOut = {hi,lo}; // @[sub_module.scala 35:28]
endmodule

功能确实是对的,如何去除这些烦人的注释呢?写了一个脚本remove.py,还挺好用

# python3 remove.py -f yourfile.v
import argparse
parser = argparse.ArgumentParser()
parser.add_argument('-f','--file',dest='file',type=str,default='yourfile.v')

args = parser.parse_args()
file_data = ""
remove = 0
with open(args.file,"r",encoding="utf-8") as f:
    for line in f:
        if(line[1:3]=="if" or line[0:7]=="initial"):
            remove += 1
            temp = ""
        elif(line[1:4]=="end" or line[0:6]=="end //"):
            remove -= 1
            temp = ""
        else:
            if(remove!=0):
                temp=""
            else:
                temp = line.split('/')[0]
                if((len(temp)!=0) and (temp[-1]!='\n')) :
                	temp += '\n'
        file_data += temp
with open(args.file,"w",encoding= "utf-8") as f:
    f.write(file_data)

处理之后瞬间清爽了:

module EndianCnvt(
  input          clock,
  input          reset,
  input  [127:0] io_NumIn,
  output [127:0] io_NumOut
);
  wire [7:0] temp_0 = io_NumIn[7:0]; 
  wire [7:0] temp_1 = io_NumIn[15:8]; 
  wire [7:0] temp_2 = io_NumIn[23:16]; 
  wire [7:0] temp_3 = io_NumIn[31:24]; 
  wire [7:0] temp_4 = io_NumIn[39:32]; 
  wire [7:0] temp_5 = io_NumIn[47:40]; 
  wire [7:0] temp_6 = io_NumIn[55:48]; 
  wire [7:0] temp_7 = io_NumIn[63:56]; 
  wire [7:0] temp_8 = io_NumIn[71:64]; 
  wire [7:0] temp_9 = io_NumIn[79:72]; 
  wire [7:0] temp_10 = io_NumIn[87:80]; 
  wire [7:0] temp_11 = io_NumIn[95:88]; 
  wire [7:0] temp_12 = io_NumIn[103:96]; 
  wire [7:0] temp_13 = io_NumIn[111:104]; 
  wire [7:0] temp_14 = io_NumIn[119:112]; 
  wire [7:0] temp_15 = io_NumIn[127:120]; 
  wire [63:0] lo = {temp_8,temp_9,temp_10,temp_11,temp_12,temp_13,temp_14,temp_15}; 
  wire [63:0] hi = {temp_0,temp_1,temp_2,temp_3,temp_4,temp_5,temp_6,temp_7}; 
  assign io_NumOut = {hi,lo}; 
endmodule

附上寄存器、向量初始化的语句备忘

val regs = RegInit(VecInit(Seq.fill(32)(0.U(32.W))))//寄存器向量初始化
val reg  = RegNext(updateData,resetData,enable)
val reg2 = ShiftRegister(in , n , en )
val reg3 = ShiftRegister(in ,n ,resetData,en)
val reg4 = Reg(Vec(32,SInt(64.W)))
val array = Wire(Vec(4,SInt(8.W)))
val array1 = array.asTypeOf(Vec(2,UInt(16.W)))
val array2 = VecInit(Seq.fill(4)(false.B))
val array3 = VecInit(Seq.fill(4)(0.S))
//rom
val mem = VecInit("h11".U,"hff".U,"h15".U,"h31".U)

标签: chisel

添加新评论