FIFO是英文First In First Out 的缩写,是一种先进先出的数据缓存器,他与普通存储器的区别是没有外部读写地址线,这样使用起来非常简单,但缺点就是只能顺序写入数据,顺序的读出数据, 其数据地址由内部读写指针自动加1完成,不能像普通存储器那样可以由地址线决定读取或写入某个指定的地址。

FIFO般用于不同时钟域之间的数据传输,比如FIFO的一端是AD数据采集, 另一端是计算机的PCI总线,假设其AD采集的速率为16位 100K SPS,那么每秒的数据量为100K×16bit=1.6Mbps,而PCI总线的速度为33MHz,总线宽度32bit,其最大传输速率为 1056Mbps,在两个不同的时钟域间就可以采用FIFO来作为数据缓冲。另外对于不同宽度的数据接口也可以用FIFO,例如单片机位8位数据输出,而 DSP可能是16位数据输入,在单片机与DSP连接时就可以使用FIFO来达到数据匹配的目的。

FIFO的分类根均FIFO工作的时钟域,可以将FIFO分为同步FIFO和异步FIFO。同步FIFO是指读时钟和写时钟为同一个时钟。在时钟沿来临时同时发生读写操作。异步FIFO是指读写时钟不一致,读写时钟是互相独立的。

FIFO设计的难点 FIFO设计的难点在于怎样判断FIFO的空/满状态。为了保证数据正确的写入或读出,而不发生益处或读空的状态出现,必须保证FIFO在满的情况下,不 能进行写操作。在空的状态下不能进行读操作。怎样判断FIFO的满/空就成了FIFO设计的核心问题。

.........................................................................................................................................

同步FIFO的Verilog代码 之一

在modlesim中验证过。

/******************************************************
A fifo controller verilog description.
******************************************************/
module fifo(datain, rd, wr, rst, clk, dataout, full, empty);
input [7:0] datain;
input rd, wr, rst, clk;
output [7:0] dataout;
output full, empty;
wire [7:0] dataout;
reg full_in, empty_in;
reg [7:0] mem [15:0];
reg [3:0] rp, wp;
assign full = full_in;
assign empty = empty_in;
// memory read out
assign dataout = mem[rp];
// memory write in
always@(posedge clk) begin
    if(wr && ~full_in) mem[wp]<=datain;
end
// memory write pointer increment
always@(posedge clk or negedge rst) begin
    if(!rst) wp<=0;
    else begin
      if(wr && ~full_in) wp<= wp+1'b1;
    end
end
// memory read pointer increment
always@(posedge clk or negedge rst)begin
    if(!rst) rp <= 0;
    else begin
      if(rd && ~empty_in) rp <= rp + 1'b1;
    end
end
// Full signal generate
always@(posedge clk or negedge rst) begin
    if(!rst) full_in <= 1'b0;
    else begin
      if( (~rd && wr)&&((wp==rp-1)||(rp==4'h0&&wp==4'hf)))
          full_in <= 1'b1;
      else if(full_in && rd) full_in <= 1'b0;
    end
end
// Empty signal generate
always@(posedge clk or negedge rst) begin
    if(!rst) empty_in <= 1'b1;
    else begin
      if((rd&&~wr)&&(rp==wp-1 || (rp==4'hf&&wp==4'h0)))
        empty_in<=1'b1;
      else if(empty_in && wr) empty_in<=1'b0;
    end
end
endmodule

...........................................................................................................................

同步FIFO的Verilog代码 之二

这一种设计的FIFO,是基于触发器的。宽度,深度的扩展更加方便,结构化跟强。以下代码在modelsim中验证过。

module fifo_cell (sys_clk, sys_rst_n, read_fifo, write_fifo, fifo_input_data,
                        next_cell_data, next_cell_full, last_cell_full, cell_data_out, cell_full);
                        parameter WIDTH =8;
                        parameter D = 2;
                        input sys_clk;
                        input sys_rst_n;
                        input read_fifo, write_fifo;
                        input [WIDTH-1:0] fifo_input_data;
                        input [WIDTH-1:0] next_cell_data;
                        input next_cell_full, last_cell_full;
                        output [WIDTH-1:0] cell_data_out;
                        output cell_full;
                        reg [WIDTH-1:0] cell_data_reg_array;
                        reg [WIDTH-1:0] cell_data_ld;
                        reg cell_data_ld_en;
                        reg cell_full;
                        reg cell_full_next;
                        assign cell_data_out=cell_data_reg_array;
                        always @(posedge sys_clk or negedge sys_rst_n)
                           if (!sys_rst_n)
                              cell_full <= #D 0;
                           else if (read_fifo || write_fifo)
                              cell_full <= #D cell_full_next;
                        always @(write_fifo or read_fifo or next_cell_full or last_cell_full or cell_full)
                           casex ({read_fifo, write_fifo})
                               2'b00: cell_full_next = cell_full;
                               2'b01: cell_full_next = next_cell_full;
                               2'b10: cell_full_next = last_cell_full;
                               2'b11: cell_full_next = cell_full;
                           endcase
                         always @(posedge sys_clk or negedge sys_rst_n)
                              if (!sys_rst_n)
                                 cell_data_reg_array [WIDTH-1:0] <= #D 0;
                              else if (cell_data_ld_en)
                                 cell_data_reg_array [WIDTH-1:0] <= #D cell_data_ld [WIDTH-1:0];
                         always @(write_fifo or read_fifo or cell_full or last_cell_full)   
                              casex ({write_fifo,read_fifo,cell_full,last_cell_full})
                                  4'bx1_xx: cell_data_ld_en = 1'b1;
                                  4'b10_01: cell_data_ld_en = 1'b1;
                                  default: cell_data_ld_en =1'b0;
                              endcase
                         always @(write_fifo or read_fifo or next_cell_full or cell_full or last_cell_full or fifo_input_data or next_cell_data)
                              casex ({write_fifo, read_fifo, next_cell_full, cell_full, last_cell_full})
                                 5'b10_x01: cell_data_ld[WIDTH-1:0] = fifo_input_data[WIDTH-1:0];
                                 5'b11_01x: cell_data_ld[WIDTH-1:0] = fifo_input_data[WIDTH-1:0];
                                 default: cell_data_ld[WIDTH-1:0] = next_cell_data[WIDTH-1:0];
                              endcase
endmodule

module fifo_4cell(sys_clk, sys_rst_n, fifo_input_data, write_fifo, fifo_out_data,
                  read_fifo, full_cell0, full_cell1, full_cell2, full_cell3);
                  parameter WIDTH = 8;
                  parameter D = 2;
                  input sys_clk;
                  input sys_rst_n;
                  input [WIDTH-1:0] fifo_input_data;
                  output [WIDTH-1:0] fifo_out_data;
                  input read_fifo, write_fifo;
                  output full_cell0, full_cell1, full_cell2, full_cell3;
                  wire [WIDTH-1:0] dara_out_cell0, data_out_cell1, data_out_cell2,
                                   data_out_cell3, data_out_cell4;
                  wire full_cell4;
                  fifo_cell #(WIDTH,D) cell0
                  ( .sys_clk (sys_clk),
                    .sys_rst_n (sys_rst_n),
                    .fifo_input_data (fifo_input_data[WIDTH-1:0]),
                    .write_fifo (write_fifo),
                    .next_cell_data (data_out_cell1[WIDTH-1:0]),
                    .next_cell_full (full_cell1),
                    .last_cell_full (1'b1),
                    .cell_data_out (fifo_out_data [WIDTH-1:0]),
                    .read_fifo (read_fifo),
                    .cell_full (full_cell0)
                   );

fifo_cell #(WIDTH,D) cell1
                  ( .sys_clk (sys_clk),
                    .sys_rst_n (sys_rst_n),
                    .fifo_input_data (fifo_input_data[WIDTH-1:0]),
                    .write_fifo (write_fifo),
                    .next_cell_data (data_out_cell2[WIDTH-1:0]),
                    .next_cell_full (full_cell2),
                    .last_cell_full (full_cell0),
                    .cell_data_out (data_out_cell1[WIDTH-1:0]),
                    .read_fifo (read_fifo),
                    .cell_full (full_cell1)
                   );                  
                  fifo_cell #(WIDTH,D) cell2
                  ( .sys_clk (sys_clk),
                    .sys_rst_n (sys_rst_n),
                    .fifo_input_data (fifo_input_data[WIDTH-1:0]),
                    .write_fifo (write_fifo),
                    .next_cell_data (data_out_cell3[WIDTH-1:0]),
                    .next_cell_full (full_cell3),
                    .last_cell_full (full_cell1),
                    .cell_data_out (data_out_cell2[WIDTH-1:0]),
                    .read_fifo (read_fifo),
                    .cell_full (full_cell2)
                   );

fifo_cell #(WIDTH,D) cell3
                  ( .sys_clk (sys_clk),
                    .sys_rst_n (sys_rst_n),
                    .fifo_input_data (fifo_input_data[WIDTH-1:0]),
                    .write_fifo (write_fifo),
                    .next_cell_data (data_out_cell4[WIDTH-1:0]),
                    .next_cell_full (full_cell4),
                    .last_cell_full (full_cell2),
                    .cell_data_out (data_out_cell3[WIDTH-1:0]),
                    .read_fifo (read_fifo),
                    .cell_full (full_cell3)
                   );     
                   assign data_out_cell4[WIDTH-1:0] = {WIDTH{1'B0}};
                   assign full_cell4 = 1'b0;
endmodule

..........................................................................................................................

异步FIFO的Verilog代码 之一

这个是基于RAM的异步FIFO代码,个人认为代码结构简单易懂,非常适合于考试中填写。记得10月份参加威盛的笔试的时候,就考过异步FIFO的实现。想当初要是早点复习,可能就可以通过威盛的笔试了。

与之前的用RAM实现的同步FIFO的程序相比,异步更为复杂。增加了读写控制信号的跨时钟域的同步。此外,判空与判满的也稍有不同。

module fifo1(rdata, wfull, rempty, wdata, winc, wclk, wrst_n,rinc, rclk, rrst_n);
parameter DSIZE = 8; parameter ASIZE = 4;
output [DSIZE-1:0] rdata;
output wfull;
output rempty;
input [DSIZE-1:0] wdata;
input winc, wclk, wrst_n;
input rinc, rclk, rrst_n;
reg wfull,rempty;
reg [ASIZE:0] wptr, rptr, wq2_rptr, rq2_wptr, wq1_rptr,rq1_wptr;
reg [ASIZE:0] rbin, wbin;
reg [DSIZE-1:0] mem[0:(1<<ASIZE)-1];
wire [ASIZE-1:0] waddr, raddr;
wire [ASIZE:0] rgraynext, rbinnext,wgraynext,wbinnext;
wire rempty_val,wfull_val;
//-----------------双口RAM存储器--------------------
assign rdata=mem[raddr];
always@(posedge wclk)
if (winc && !wfull) mem[waddr] <= wdata;
//-------------同步rptr 指针-------------------------
always @(posedge wclk or negedge wrst_n)
if (!wrst_n) {wq2_rptr,wq1_rptr} <= 0;
else {wq2_rptr,wq1_rptr} <= {wq1_rptr,rptr};
//-------------同步wptr指针---------------------------
always @(posedge rclk or negedge rrst_n)
if (!rrst_n) {rq2_wptr,rq1_wptr} <= 0;
else {rq2_wptr,rq1_wptr} <= {rq1_wptr,wptr};
//-------------rempty产生与raddr产生-------------------
always @(posedge rclk or negedge rrst_n) // GRAYSTYLE2 pointer
begin
if (!rrst_n) {rbin, rptr} <= 0;
else {rbin, rptr} <= {rbinnext, rgraynext};
end
// Memory read-address pointer (okay to use binary to address memory)
assign raddr = rbin[ASIZE-1:0];
assign rbinnext = rbin + (rinc & ~rempty);
assign rgraynext = (rbinnext>>1) ^ rbinnext;
// FIFO empty when the next rptr == synchronized wptr or on reset
assign rempty_val = (rgraynext == rq2_wptr);
always @(posedge rclk or negedge rrst_n)
begin
if (!rrst_n) rempty <= 1'b1;
else rempty <= rempty_val;
end
//---------------wfull产生与waddr产生------------------------------
always @(posedge wclk or negedge wrst_n) // GRAYSTYLE2 pointer
if (!wrst_n) {wbin, wptr} <= 0;
else {wbin, wptr} <= {wbinnext, wgraynext};
// Memory write-address pointer (okay to use binary to address memory)
assign waddr = wbin[ASIZE-1:0];
assign wbinnext = wbin + (winc & ~wfull);
assign wgraynext = (wbinnext>>1) ^ wbinnext;
assign wfull_val = (wgraynext=={~wq2_rptr[ASIZE:ASIZE-1], wq2_rptr[ASIZE-2:0]}); //:ASIZE-1]
always @(posedge wclk or negedge wrst_n)
if (!wrst_n) wfull <= 1'b0;
else wfull <= wfull_val;
endmodule

..........................................................................................................................

异步FIFO的Verilog代码 之二

与前一段异步FIFO代码的主要区别在于,空/满状态标志的不同算法。

第一个算法:Clifford E. Cummings的文章中提到的STYLE #1,构造一个指针宽度为N+1,深度为2^N字节的FIFO(为便方比较将格雷码指针转换为二进制指针)。当指针的二进制码中最高位不一致而其它N位都 相等时,FIFO为满(在Clifford E. Cummings的文章中以格雷码表示是前两位均不相同,而后两位LSB相同为满,这与换成二进制表示的MSB不同其他相同为满是一样的)。当指针完全相 等时,FIFO为空。

这种方法思路非常明了,为了比较不同时钟产生的指针,需要把不同时钟域的信号同步到本时钟域中来,而使用Gray码的目的就是使这个异步同步化的过 程发生亚稳态的机率最小,而为什么要构造一个N+1的指针,Clifford E. Cummings也阐述的很明白,有兴趣的读者可以看下作者原文是怎么论述的,Clifford E. Cummings的这篇文章有Rev1.1 \ Rev1.2两个版本,两者在比较Gray码指针时的方法略有不同,个Rev1.2版更为精简。

第二种算法:Clifford E. Cummings的文章中提到的STYLE #2。它将FIFO地址分成了4部分,每部分分别用高两位的MSB 00 、01、 11、 10决定FIFO是否为going full 或going empty (即将满或空)。如果写指针的高两位MSB小于读指针的高两位MSB则FIFO为“几乎满”,若写指针的高两位MSB大于读指针的高两位MSB则FIFO 为“几乎空”。

它是利用将地址空间分成4个象限(也就是四个等大小的区域),然后观察两个指针的相对位置,如果写指针落后读指针一个象限(25%的距离,呵呵), 则证明很可能要写满,反之则很可能要读空,这个时候分别设置两个标志位dirset和dirrst,然后在地址完全相等的情况下,如果dirset有效就 是写满,如果dirrst有效就是读空。

这种方法对深度为2^N字节的FIFO只需N位的指针即可,处理的速度也较第一种方法快。

这段是说明的原话,算法一,还好理解。算法二,似乎没有说清楚,不太明白。有兴趣的可以查查论文,详细研究下。

总之,第二种写法是推荐的写法。因为异步的多时钟设计应按以下几个原则进行设计:
1,尽可能的将多时钟的逻辑电路(非同步器)分割为多个单时钟的模块,这样有利于静态时序分析工具来进行时序验证。
2,同步器的实现应使得所有输入来自同一个时钟域,而使用另一个时钟域的异步时钟信号采样数据。
3,面向时钟信号的命名方式可以帮助我们确定那些在不同异步时钟域间需要处理的信号。
4,当存在多个跨时钟域的控制信号时,我们必须特别注意这些信号,保证这些控制信号到达新的时钟域仍然能够保持正确的顺序。

module fifo2 (rdata, wfull, rempty, wdata,
winc, wclk, wrst_n, rinc, rclk, rrst_n);
parameter DSIZE = 8;
parameter ASIZE = 4;
output [DSIZE-1:0] rdata;
output wfull;
output rempty;
input [DSIZE-1:0] wdata;
input winc, wclk, wrst_n;
input rinc, rclk, rrst_n;
wire [ASIZE-1:0] wptr, rptr;
wire [ASIZE-1:0] waddr, raddr;
async_cmp #(ASIZE) async_cmp(.aempty_n(aempty_n),
.afull_n(afull_n),
.wptr(wptr), .rptr(rptr),
.wrst_n(wrst_n));
fifomem2 #(DSIZE, ASIZE) fifomem2(.rdata(rdata),
.wdata(wdata),
.waddr(wptr),
.raddr(rptr),
.wclken(winc),
.wclk(wclk));
rptr_empty2 #(ASIZE) rptr_empty2(.rempty(rempty),
.rptr(rptr),
.aempty_n(aempty_n),
.rinc(rinc),
.rclk(rclk),
.rrst_n(rrst_n));
wptr_full2 #(ASIZE) wptr_full2(.wfull(wfull),
.wptr(wptr),
.afull_n(afull_n),
.winc(winc),
.wclk(wclk),
.wrst_n(wrst_n));
endmodule
module fifomem2 (rdata, wdata, waddr, raddr, wclken, wclk);
parameter DATASIZE = 8; // Memory data word width
parameter ADDRSIZE = 4; // Number of memory address bits
parameter DEPTH = 1<<ADDRSIZE; // DEPTH = 2**ADDRSIZE
output [DATASIZE-1:0] rdata;
input [DATASIZE-1:0] wdata;
input [ADDRSIZE-1:0] waddr, raddr;
input wclken, wclk;
`ifdef VENDORRAM
// instantiation of a vendor's dual-port RAM
VENDOR_RAM MEM (.dout(rdata), .din(wdata),
.waddr(waddr), .raddr(raddr),
.wclken(wclken), .clk(wclk));
`else
reg [DATASIZE-1:0] MEM [0:DEPTH-1];
assign rdata = MEM[raddr];
always @(posedge wclk)
if (wclken) MEM[waddr] <= wdata;
`endif
endmodule
module async_cmp (aempty_n, afull_n, wptr, rptr, wrst_n);
parameter ADDRSIZE = 4;
parameter N = ADDRSIZE-1;
output aempty_n, afull_n;
input [N:0] wptr, rptr;
input wrst_n;
reg direction;
wire high = 1'b1;
wire dirset_n = ~( (wptr[N]^rptr[N-1]) & ~(wptr[N-1]^rptr[N]));
wire dirclr_n = ~((~(wptr[N]^rptr[N-1]) & (wptr[N-1]^rptr[N])) |
~wrst_n);
always @(posedge high or negedge dirset_n or negedge dirclr_n)
if (!dirclr_n) direction <= 1'b0;
else if (!dirset_n) direction <= 1'b1;
else direction <= high;
//always @(negedge dirset_n or negedge dirclr_n)
//if (!dirclr_n) direction <= 1'b0;
//else direction <= 1'b1;
assign aempty_n = ~((wptr == rptr) && !direction);
assign afull_n = ~((wptr == rptr) && direction);
endmodule
module rptr_empty2 (rempty, rptr, aempty_n, rinc, rclk, rrst_n);
parameter ADDRSIZE = 4;
output rempty;
output [ADDRSIZE-1:0] rptr;
input aempty_n;
input rinc, rclk, rrst_n;
reg [ADDRSIZE-1:0] rptr, rbin;
reg rempty, rempty2;
wire [ADDRSIZE-1:0] rgnext, rbnext;
//---------------------------------------------------------------
// GRAYSTYLE2 pointer
//---------------------------------------------------------------
always @(posedge rclk or negedge rrst_n)
if (!rrst_n) begin
rbin <= 0;
rptr <= 0;
end
else begin
rbin <= rbnext;
rptr <= rgnext;
end
//---------------------------------------------------------------
// increment the binary count if not empty
//---------------------------------------------------------------
assign rbnext = !rempty ? rbin + rinc : rbin;
assign rgnext = (rbnext>>1) ^ rbnext; // binary-to-gray conversion
always @(posedge rclk or negedge aempty_n)
if (!aempty_n) {rempty,rempty2} <= 2'b11;
else {rempty,rempty2} <= {rempty2,~aempty_n};
endmodule
module wptr_full2 (wfull, wptr, afull_n, winc, wclk, wrst_n);
parameter ADDRSIZE = 4;
output wfull;
output [ADDRSIZE-1:0] wptr;
input afull_n;
input winc, wclk, wrst_n;
reg [ADDRSIZE-1:0] wptr, wbin;
reg wfull, wfull2;
wire [ADDRSIZE-1:0] wgnext, wbnext;
//---------------------------------------------------------------
// GRAYSTYLE2 pointer
//---------------------------------------------------------------
always @(posedge wclk or negedge wrst_n)
if (!wrst_n) begin
wbin <= 0;
wptr <= 0;
end
else begin
wbin <= wbnext;
wptr <= wgnext;
end
//---------------------------------------------------------------
// increment the binary count if not full
//---------------------------------------------------------------
assign wbnext = !wfull ? wbin + winc : wbin;
assign wgnext = (wbnext>>1) ^ wbnext; // binary-to-gray conversion
always @(posedge wclk or negedge wrst_n or negedge afull_n)
if (!wrst_n ) {wfull,wfull2} <= 2'b00;
else if (!afull_n) {wfull,wfull2} <= 2'b11;
else {wfull,wfull2} <= {wfull2,~afull_n};
endmodule

再分享一下我老师大神的人工智能教程吧。零基础!通俗易懂!风趣幽默!还带黄段子!希望你也加入到我们人工智能的队伍中来!https://blog.csdn.net/jiangjunshow

同步FIFO和异步FIFO的Verilog实现相关推荐

  1. 【FPGA——基础篇】同步FIFO与异步FIFO——Verilog实现

    FIFO是英文First In First Out 的缩写,是一种先进先出的数据缓存器,他与普通存储器的区别是没有外部读写地址线,这样使用起来非常简单,但缺点就是只能顺序写入数据,顺序的读出数据, 其 ...

  2. 7 centos 时钟跟物理机同步_同步FIFO和异步FIFO

    1.定义 FIFO是英文First In First Out 的缩写,是一种先进先出的数据缓存器,他与普通存储器的区别是没有外部读写地址线,这样使用起来非常简单,但缺点就是只能顺序写入数据,顺序的读出 ...

  3. 同步fifo与异步fifo

    参考以下帖子: https://blog.csdn.net/hengzo/article/details/49683707 https://blog.csdn.net/Times_poem/artic ...

  4. 同步FIFO和异步FIFO

    1.定义 FIFO是英文First In First Out 的缩写,是一种先进先出的数据缓存器,他与普通存储器的区别是没有外部读写地址线,这样使用起来非常简单,但缺点就是只能顺序写入数据,顺序的读出 ...

  5. IC设计 — 同步FIFO和异步FIFO设计实现(一)

    文章目录 1. FIFO介绍 1.1 FIFO参数 1.2 full/empty 检测 1.3 同步FIFO和异步FIFO 2. FIFO设计 2.1 二进制和格雷码 2.2 同步FIFO 2.3 异 ...

  6. 数字IC设计系列----单端口RAM、双端口RAM、同步FIFO、异步FIFO

    目录​​​​​​​ 一.单端口RAM原理及实现 1.1.原理 1.2.Verilog实现 1.3.优缺点分析 2.双端口RAM原理及实现 2.1.原理 2.2.Verilog实现 2.3.优缺点分析 ...

  7. (87)FPGA面试题-同步FIFO与异步FIFO区别?异步FIFO代码设计

    1.1 FPGA面试题-同步FIFO与异步FIFO区别?异步FIFO代码设计 1.1.1 本节目录 1)本节目录: 2)本节引言: 3)FPGA简介: 4)FPGA面试题-同步FIFO与异步FIFO区 ...

  8. 同步FIFO和异步FIFO总结

    文章目录 1. FIFO简介 2. 使用场景 3. 分类 4. FIFO的常见参数 5. FIFO设计 5.1 空满标志生成 5.2 异步FIFO的设计还要注意跨时钟域问题 5.3 gray码如何判断 ...

  9. 【FIFO】异步 FIFO 设计

    目录 写在前面 简介 传递多个异步信号 同步 FIFO 指针 异步FIFO指针 二进制 FIFO 指针注意事项 FIFO测试问题 格雷码计数器 ‑ 样式 #1 格雷码模式 格雷码计数器基础 额外的格雷 ...

最新文章

  1. 批量替换_批量替换图框
  2. ASP.NET Core Web Razor Pages系列教程一:使用ASP.NET Core 创建一个Razor Pages网络应用程序
  3. 不断提升自己创造溢价的能力
  4. iOS开发 Block的用法
  5. 关于ElasticSearch性能调优几件必须知道的事
  6. android linux截图库,Android中截图(surfaceView)源码
  7. python连接opencv库_利用Python和OpenCV库将URL转换为OpenCV格式的方法
  8. 苹果全面开放漏洞奖励计划:最高100万美元等你拿
  9. uva 1637 Double Patience
  10. 杭电oj-----Nightmare(BFS)
  11. Java之while循环基本使用
  12. 如何建立个人网站?先分享一下
  13. 2022-2028年全球与中国智能咖啡机行业市场前瞻与投资战略规划分析
  14. Android扫描系统文件,安卓文档扫描仪
  15. android简单手电筒,android 简单的手电筒制作
  16. 现代战争的制胜法宝?-黑科技原子无线电技术应用前景及最新研究进展
  17. git 提交 全部文件
  18. 通过身体跳跃和蹲伏玩chromes dino游戏
  19. 发明专利申请的一些内容
  20. Centos 7搭建Raid5案例

热门文章

  1. 初识ElasticSearch(2) -文档查询之match查询 | 分词器
  2. 2021-11-03如何删除文件夹名中间有【空格】及后边带有“..”的文件夹
  3. Android学习必经之路--apk反编译
  4. 解决go语言热部署组件fresh安装问题
  5. 【ELT.ZIP】OpenHarmony啃论文俱乐部——一文穿透多媒体过往前沿
  6. 微积分中几个重要的不等式:Jensen不等式、平均值不等式、Holder不等式、Schwarz不等式、Minkovski不等式 及其证明
  7. mysql怎么对月份进行统计_MySQL如何按月份统计数据详解(转)
  8. android动态贴纸实现原理,人脸动态贴纸sdk算法详解,人脸动态贴纸功能如何实现...
  9. 机器学习中的归纳偏置
  10. 建设一个SaaS平台需要知道什么,做什么