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 //输出目标等于地址序号
}
生成的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]