joe 发表于 2021-9-16 15:55:14

chisel在内存中写数据并搜索目标数据

import chisel3._
import chisel3.util.log2Ceil
class DynamicMemorySearch(val n:Int,val w:Int) extends Module{ //动态搜索目标数据
val io = IO(new Bundle {
    val isWr = Input(Bool()) //isWr和wrAddr表示写data到模块内部存储器中
    val wrAddr = Input(UInt(log2Ceil(n).W)) //集合大小即内存大小是n,需要log2Ceil(n)个bit位宽作为地址位宽即0~(n-1)
    val data = Input(UInt(w.W)) //w表示数据的位宽
    val en = Input(Bool()) //启动搜索
    val target =Output(UInt(log2Ceil(n).W)) //搜索到数据之后的地址
    val done = Output(Bool()) //搜索到数据之后为1否则为0
})
val index = RegInit(0.U(log2Ceil(n).W)) //地址序号
val list = Mem(n,UInt(w.W)) //内存,异步读同步写,上升沿写数据,读是组合逻辑
val memVal = list(index) //Mem的def apply(Uint):UInt形式,产生动态地址的内存访问,如果是list(Int)则是产生静态地址的内存访问
val done = !io.en && ((memVal === io.data) || (index === (n-1).asUInt()))
//!io.en没有启动探索
//memVal === io.data 当前地址序号index所对应的内存中的数据与输入模块来的数据是否相等
//index === (n-1).asUInt() 当前地址序号是否是达到序号的最大值了
when(io.isWr) { //是写
    list(io.wrAddr) := io.data
}.elsewhen(io.en) { //启动搜索就恢复地址序号,表示从0地址开始搜索
    index := 0.U   
}.elsewhen(done === false.B) { //没有搜索到目标
    index := index + 1.U //每个时钟上升沿地址序号寄存器就会+1
}
io.done := done
io.target := index //输出目标等于地址序号
}


joe 发表于 2021-9-16 17:01:31

生成的verilog文件内容如下:
module DynamicMemorySearch(
input      clock,
input      reset,
input      io_isWr,
input io_wrAddr,
input io_data,
input      io_en,
output io_target,
output       io_done
);
reg list ; // @
reg _RAND_0;
wire list_memVal_data; // @
wire list_memVal_addr; // @
wire list__T_4_data; // @
wire list__T_4_addr; // @
wirelist__T_4_mask; // @
wirelist__T_4_en; // @
reg index; // @
reg _RAND_1;
wire_T = ~io_en; // @
wire_T_1 = list_memVal_data == io_data; // @
wire_T_2 = index == 4'hf; // @
wire_T_3 = _T_1 | _T_2; // @
wiredone = _T & _T_3; // @
wire_T_5 = ~done; // @
wire _T_7 = index + 4'h1; // @
assign list_memVal_addr = index;
assign list_memVal_data = list; // @
assign list__T_4_data = io_data;
assign list__T_4_addr = io_wrAddr;
assign list__T_4_mask = 1'h1;
assign list__T_4_en = io_isWr;
assign io_target = index; // @
assign io_done = _T & _T_3; // @
`ifdef RANDOMIZE_GARBAGE_ASSIGN
`define RANDOMIZE
`endif
`ifdef RANDOMIZE_INVALID_ASSIGN
`define RANDOMIZE
`endif
`ifdef RANDOMIZE_REG_INIT
`define RANDOMIZE
`endif
`ifdef RANDOMIZE_MEM_INIT
`define RANDOMIZE
`endif
`ifndef RANDOM
`define RANDOM $random
`endif
`ifdef RANDOMIZE_MEM_INIT
integer initvar;
`endif
`ifndef SYNTHESIS
initial begin
`ifdef RANDOMIZE
    `ifdef INIT_RANDOM
      `INIT_RANDOM
    `endif
    `ifndef VERILATOR
      `ifdef RANDOMIZE_DELAY
      #`RANDOMIZE_DELAY begin end
      `else
      #0.002 begin end
      `endif
    `endif
_RAND_0 = {1{`RANDOM}};
`ifdef RANDOMIZE_MEM_INIT
for (initvar = 0; initvar < 16; initvar = initvar+1)
    list = _RAND_0;
`endif // RANDOMIZE_MEM_INIT
`ifdef RANDOMIZE_REG_INIT
_RAND_1 = {1{`RANDOM}};
index = _RAND_1;
`endif // RANDOMIZE_REG_INIT
`endif // RANDOMIZE
end // initial
`endif // SYNTHESIS
always @(posedge clock) begin
    if(list__T_4_en & list__T_4_mask) begin
      list <= list__T_4_data; // @
    end
    if (reset) begin
      index <= 4'h0;
    end else if (!(io_isWr)) begin
      if (io_en) begin
      index <= 4'h0;
      end else if (_T_5) begin
      index <= _T_7;
      end
    end
end
endmodule
页: [1]
查看完整版本: chisel在内存中写数据并搜索目标数据