IP核之FIFO实验

2023-10-31

        FIFO 的英文全称是 First In First Out ,即先进先出。 FPGA 使用的 FIFO 一般指的是对数据的存储具有先进先出特性的一个缓存器,常被用于数据的缓存, 或者高速异步数据的交互也即所谓的跨时钟域信号传递。它与 FPGA 内部的 RAM ROM 的区别是没有外部读写地址线,采取顺序写入数据,顺序读出数据的方式,使用起来简单方便,由此带来的缺点就是不能像 RAM ROM 那样可以由地址线决定读取或写入某个指定的地址。本章我们将对 Vivado 软件生成的 FIFO IP 核进行读写测试,来向大家介绍 Xilinx FIFO IP 核的使用方法。

FIFO IP 核简介

        根据 FIFO 工作的时钟域,可以将 FIFO 分为同步 FIFO 和异步 FIFO 。同步 FIFO 是指读时钟和写时钟为同一个时钟,在时钟沿来临时同时发生读写操作。异步 FIFO 是指读写时钟不一致,读写时钟是互相独立。Xilinx FIFO IP 核可以被配置为同步 FIFO 或异步 FIFO ,其信号框图如下图所示。从图中可以了解到,当被配置为同步 FIFO 时,只使用 wr_clk, 所有的输入输出信号都同步于 wr_clk 信号。而当被配置为异步 FIFO时,写端口和读端口分别有独立的时钟,所有与写相关的信号都是同步于写时钟 wr_clk ,所有与读相关的信号都是同步于读时钟 rd_clk

        对于 FIFO 需要了解一些常见参数:

        FIFO 的宽度: FIFO 一次读写操作的数据位 N
        FIFO的深度:FIFO 可以存储多少个宽度为 N 位的数据。
        将空标志:almost_empty FIFO 即将被读空。
        空标志:empty FIFO 已空时由 FIFO 的状态电路送出的一个信号,以阻止 FIFO 的读操作继续从 FIFO中读出数据而造成无效数据的读出。
        将满标志:almost_full FIFO 即将被写满。
        满标志:full FIFO 已满或将要写满时由 FIFO 的状态电路送出的一个信号,以阻止 FIFO 的写操作继续向 FIFO 中写数据而造成溢出。
        读时钟:读 FIFO 时所遵循的时钟,在每个时钟的上升沿触发。
        写时钟:写 FIFO 时所遵循的时钟,在每个时钟的上升沿触发。
        这里请注意,“almost_empty” “almost_full” 这两个信号分别被看作 “empty” “full” 的警告信号,他们相对于真正的空(empty )和满( full )都会提前一个时钟周期拉高。
        对于 FIFO 的基本知识先了解这些就足够了,可能有人会好奇为什么会有同步 FIFO 和异步 FIFO ,它们各自的用途是什么。之所以有同步 FIFO 和异步 FIFO 是因为各自的作用不同。同步 FIFO 常用于同步时钟的数据缓存,异步 FIFO 常用于跨时钟域的数据信号的传递,例如时钟域 A 下的数据 data1 传递给异步时钟域 B ,当 data1 为连续变化信号时,如果直接传递给时钟域 B 则可能会导致收非所送的情况,即在采集过程中会出现包括亚稳态问题在内的一系列问题,使用异步 FIFO 能够将不同时钟域中的数据同步到所需的时钟域中。

实验任务

        本节的实验任务是使用 Vivado 生成 FIFO IP 核,并实现以下功能:当 FIFO 为空时,向 FIFO 中写入数 ,写入的数据量和 FIFO 深度一致,即 FIFO 被写满;然后从 FIFO 中读出数据,直到 FIFO 被读空为止,以此向大家详细介绍一下 FIFO IP 核的使用方法。

硬件设计

        本章实验只用到了输入的时钟信号和按键复位信号,没有用到其它硬件外设。
        本实验中,各端口信号的管脚分配如下表所示。

        对应的 XDC 约束语句如下所示:

create_clock -period 20.000 -name clk [get_ports sys_clk]
set_property -dict {PACKAGE_PIN U18 IOSTANDARD LVCMOS33} [get_ports sys_clk]
set_property -dict {PACKAGE_PIN J15 IOSTANDARD LVCMOS33} [get_ports sys_rst_n]

程序设计

        根据实验任务要求和模块化设计的思想,我们需要如下 4 个模块:fifo IP 核、写 fifo 模块、读 fifo 模块以及顶层例化模块实现前三个模块的信号交互。由于 FIFO 多用于跨时钟域信号的处理,所以本实验我们使用异步 FIFO 来向大家详细介绍双时钟 FIFO IP 核的创建和使用。为了方便大家理解,这里我们将读/写时钟都用系统时钟来驱动。系统的功能框图如下图所示:

系统框图

        首先创建一个名为 ip_fifo 的工程,接下来我们创建 fifo IP 核。在 Vivado 软件的左侧“ Flow Navigator ” 栏中单击“IP Catalog ”,“ IP Catalog ”按钮以及单击后弹出的“ IP Catalog”窗口如下图所示。

“IP Catalog”窗口

         在“IP Catalog”窗口中,在搜索栏中输入“fifo”关键字,这时 Vivado 会自动查找出与关键字匹配的 IP 核名称,我们双击“FIFO Generator”,如下图所示。

搜索栏中输入关键字

         弹出“Customize IP”窗口,如下图所示。

“Customize IP”窗口

        下来就是配置 IP 核的时钟参数的过程。

        最上面的“Component Name ”一栏设置该 IP 元件的名称,这里保持默认即可。在第一个 “Basic” 选项卡中,“Interface Type” 选项用于选择 FIFO 接口的类型,这里我们选择默认的“ Native ”,即传统意义上的 FIFO 接口。“Fifo Implementation ”选项用于选择我们想要实现的是同步 FIFO 还是异步 FIFO 以及使用哪种资源实现 FIFO,这里我们选择“Independent Clocks Block RAM”,即使用块 RAM 来实现的异步 FIFO。如下图所示。

         接下来是“Native Ports”选项卡,用于设置 FIFO 端口的参数。“Read Mode”选项用于设置读 FIFO时的读模式,这里我们选择默认的“Standard FIFO”。“Data Port Parameters”一栏用于设置读写端口的数据总线的宽度以及 FIFO 的深度,写宽度“Write Width”我们设置为 8 位,写深度“Write Depth”我们设置为 256,注意此时 FIFO IP 核所能实现的实际深度却是 255;虽然读宽度“Read Width”能够设置成和写宽度不一样的位宽,且此时读深度“Read Depth”会根据上面三个参数被动地自动设置成相应的值;但是我们还是将读宽度“Read Width”设置成和写宽度“Write Width”一样的位宽,这也是在实际应用中最常用的情况。由于我们只是观察 FIFO 的读写,所以最下面的“Reset Pin”选项我们可以不使用,把它取消勾选。其他设置保持默认即可,如下图所示。

“Native Ports”选项卡

         “Status Flags”选项卡,用于设置用户自定义接口或者用于设定专用的输入口。这里我们使用“即将写满”和“即将读空”这两个信号,所以我们把它们勾选上,其他保持默认即可,如下图所示。

“Status Flags”选项卡

         “Data Counts”选项卡用于设置 FIFO 内数据计数的输出信号,此信号表示当前在 FIFO 内存在多少个有效数据。为了更加方便地观察读/写过程,这里我们把读/写端口的数据计数都打开,且计数值总线的位宽设置为满位宽,即 8 位,如下图所示。

“Data Counts”选项卡

         最后的“Summary”选项卡是对前面所有配置的一个总结,在这里我们直接点击“OK”按钮即可,如 下图所示。

“Summary”选项卡

         接着就弹出了“Genarate Output Products”窗口,我们直接点击“Generate”即可,如下图所示。

“Genarate Output Products”窗口

 之后我们就可以在“Design Run”窗口的“Out-of-Context Module Runs”一栏中出现了该 IP 核对应的run“fifo_generator_0_synth_1”,其综合过程独立于顶层设计的综合,所以在我们可以看到其正在综合,如下图所示。

“fifo_generator _0_synth_1”run

         在其 Out-of-Context 综合的过程中,我们就可以进行 RTL 编码了。首先打开 IP 核的例化模板,在“Source” 窗口中的“IP Sources”选项卡中,依次用鼠标单击展开“IP-“fifo_generator _0”-Instantitation Template”,我们可以看到“fifo_generator_0.veo”文件,它是由 IP 核自动生成的只读的 verilog 例化模板文件,双击就可以打开它,如下图所示。

“fifo_generator_0.veo”文件

         我们创建一个 verilog 源文件,其名称为 ip_fifo.v,作为顶层模块,其代码如下:、

module ip_fifo(
    input    sys_clk ,  // 时钟信号
    input    sys_rst_n  // 复位信号
);

//wire define
wire         fifo_wr_en         ;  // FIFO写使能信号
wire         fifo_rd_en         ;  // FIFO读使能信号
wire  [7:0]  fifo_din           ;  // 写入到FIFO的数据
wire  [7:0]  fifo_dout          ;  // 从FIFO读出的数据
wire         almost_full        ;  // FIFO将满信号
wire         almost_empty       ;  // FIFO将空信号
wire         fifo_full          ;  // FIFO满信号
wire         fifo_empty         ;  // FIFO空信号
wire  [7:0]  fifo_wr_data_count ;  // FIFO写时钟域的数据计数
wire  [7:0]  fifo_rd_data_count ;  // FIFO读时钟域的数据计数

//*****************************************************
//**                    main code
//*****************************************************

//例化FIFO IP核
fifo_generator_0  fifo_generator_0 (
    .wr_clk        ( sys_clk            ),  // input wire wr_clk
    .rd_clk        ( sys_clk            ),  // input wire rd_clk

    .wr_en         ( fifo_wr_en         ),  // input wire wr_en
    .rd_en         ( fifo_rd_en         ),  // input wire rd_en

    .din           ( fifo_din           ),  // input wire [7 : 0] din
    .dout          ( fifo_dout          ),  // output wire [7 : 0] dout
    
    .almost_full   (almost_full         ),  // output wire almost_full
    .almost_empty  (almost_empty        ),  // output wire almost_empty
    .full          ( fifo_full          ),  // output wire full
    .empty         ( fifo_empty         ),  // output wire empty

	.wr_data_count ( fifo_wr_data_count ),  // output wire [7 : 0] wr_data_count	
	.rd_data_count ( fifo_rd_data_count )   // output wire [7 : 0] rd_data_count
);

//例化写FIFO模块
fifo_wr  u_fifo_wr(
    .clk            ( sys_clk    ),   // 写时钟
    .rst_n          ( sys_rst_n  ),   // 复位信号

    .fifo_wr_en     ( fifo_wr_en )  , // fifo写请求
    .fifo_wr_data   ( fifo_din    ) , // 写入FIFO的数据
    .almost_empty   ( almost_empty ), // fifo空信号
    .almost_full    ( almost_full  )  // fifo满信号
);

//例化读FIFO模块
fifo_rd  u_fifo_rd(
    .clk          ( sys_clk    ),      // 读时钟
    .rst_n        ( sys_rst_n  ),      // 复位信号

    .fifo_rd_en   ( fifo_rd_en ),      // fifo读请求
    .fifo_dout    ( fifo_dout  ),      // 从FIFO输出的数据
    .almost_empty ( almost_empty ),    // fifo空信号
    .almost_full  ( almost_full  )     // fifo满信号
);

//例化ILA IP核
ila_0  ila_0 (
	.clk    ( sys_clk            ), // input wire clk

	.probe0 ( fifo_wr_en         ), // input wire [0:0]  probe0  
	.probe1 ( fifo_rd_en         ), // input wire [0:0]  probe1 
	.probe2 ( fifo_din           ), // input wire [7:0]  probe2 
	.probe3 ( fifo_dout          ), // input wire [7:0]  probe3 
	.probe4 ( fifo_empty         ), // input wire [0:0]  probe4 
	.probe5 ( almost_empty       ), // input wire [0:0]  probe5 
	.probe6 ( fifo_full          ), // input wire [0:0]  probe6
	.probe7 ( almost_full        ), // input wire [0:0]  probe7 
	.probe8 ( fifo_wr_data_count ), // input wire [7:0]  probe8 
	.probe9( fifo_rd_data_count  )  // input wire [7:0]  probe9
);
endmodule 
        顶层模块主要是对 FIFO IP 核、写 FIFO 模块、读 FIFO 模块进行例化,除此之外本实验还生成并例化了一个 ILA IP 核,用于对顶层模块信号的进行在线捕获观察。
        写 FIFO 模块 fifo_wr.v 源文件的代码如下:
module fifo_wr(
    //mudule clock
    input                  clk    ,           // 时钟信号
    input                  rst_n  ,           // 复位信号
    //FIFO interface       
    input                  almost_empty,      // FIFO将空信号
    input                  almost_full ,      // FIFO将满信号
	output    reg          fifo_wr_en ,       // FIFO写使能
    output    reg  [7:0]   fifo_wr_data       // 写入FIFO的数据
);

//reg define
reg  [1:0]  state            ; //动作状态
reg  		almost_empty_d0  ;  //almost_empty 延迟一拍
reg  		almost_empty_syn ;  //almost_empty 延迟两拍
reg  [3:0]  dly_cnt          ; //延迟计数器
//*****************************************************
//**                    main code
//*****************************************************

//因为 almost_empty 信号是属于FIFO读时钟域的
//所以要将其同步到写时钟域中
always@( posedge clk ) begin
	if( !rst_n ) begin
		almost_empty_d0  <= 1'b0 ;
		almost_empty_syn <= 1'b0 ;
	end
	else begin
		almost_empty_d0  <= almost_empty ;
		almost_empty_syn <= almost_empty_d0 ;
	end
end

//向FIFO中写入数据
always @(posedge clk ) begin
    if(!rst_n) begin
        fifo_wr_en   <= 1'b0;
        fifo_wr_data <= 8'd0;
        state        <= 2'd0;
		dly_cnt      <= 4'd0;
    end
    else begin
        case(state)
            2'd0: begin 
                if(almost_empty_syn) begin  //如果检测到FIFO将被读空
                    state <= 2'd1;        //就进入延时状态
                end 
                else
                    state <= state;
            end 
			2'd1: begin
                if(dly_cnt == 4'd10) begin  //延时10拍
											//原因是FIFO IP核内部状态信号的更新存在延时
											//延迟10拍以等待状态信号更新完毕                   
                    dly_cnt    <= 4'd0;
					state      <= 2'd2;     //开始写操作
					fifo_wr_en <= 1'b1;     //打开写使能
				end
				else
					dly_cnt <= dly_cnt + 4'd1;
            end             
			2'd2: begin
                if(almost_full) begin        //等待FIFO将被写满
                    fifo_wr_en   <= 1'b0;  //关闭写使能
                    fifo_wr_data <= 8'd0;
                    state        <= 2'd0;  //回到第一个状态
                end
                else begin                 //如果FIFO没有被写满
                    fifo_wr_en   <= 1'b1;  //则持续打开写使能
                    fifo_wr_data <= fifo_wr_data + 1'd1;  //且写数据值持续累加
                end
            end 
			default : state <= 2'd0;
        endcase
    end
end

endmodule
        fifo_wr 模块的核心部分是一个不断进行状态循环的小状态机,如果检测到 FIFO 为空,则先延时 10 拍,这里注意,由于 FIFO 的内部信号的更新比实际的数据读 / 写操作有所延时,所以延时 10 拍的目的是等待 FIFO 的空 / 满状态信号、数据计数信号等信号的更新完毕之后再进行 FIFO 写操作,如果写满,则回到状态 0 ,即等待 FIFO 被读空,以进行下一轮的写操作。
        读 FIFO 模块 fifo_rd.v 源文件的代码如下:
module fifo_rd(
    //system clock
    input               clk ,        // 时钟信号
    input               rst_n ,      // 复位信号
    //FIFO interface
    input        [7:0]  fifo_dout ,  // 从FIFO读出的数据
    input               almost_full ,// FIFO将满信号
    input               almost_empty,// FIFO将空信号
    output  reg         fifo_rd_en   // FIFO读使能
);

//reg define
reg  [1:0]  state           ;  // 动作状态
reg         almost_full_d0  ;  // fifo_full 延迟一拍
reg  		almost_full_syn ;  // fifo_full 延迟两拍
reg  [3:0]  dly_cnt         ;  //延迟计数器

//*****************************************************
//**                    main code
//*****************************************************

//因为 fifo_full 信号是属于FIFO写时钟域的
//所以要将其同步到读时钟域中
always@( posedge clk ) begin
	if( !rst_n ) begin
		almost_full_d0  <= 1'b0 ;
		almost_full_syn <= 1'b0 ;
	end
	else begin
		almost_full_d0  <= almost_full ;
		almost_full_syn <= almost_full_d0 ;
	end
end

//读出FIFO的数据
always @(posedge clk ) begin
    if(!rst_n) begin
        fifo_rd_en <= 1'b0;
		state      <= 2'd0;
		dly_cnt    <= 4'd0;
    end
    else begin
        case(state)
            2'd0: begin
                if(almost_full_syn)      //如果检测到FIFO将被写满
                    state <= 2'd1;       //就进入延时状态
                else
                    state <= state;
            end 
			2'd1: begin
                if(dly_cnt == 4'd10) begin  //延时10拍
											//原因是FIFO IP核内部状态信号的更新存在延时
											//延迟10拍以等待状态信号更新完毕
                    dly_cnt <= 4'd0;
					state   <= 2'd2;        //开始读操作
				end
				else
					dly_cnt <= dly_cnt + 4'd1;
            end
		    2'd2: begin
                if(almost_empty) begin     //等待FIFO将被读空
                    fifo_rd_en <= 1'b0;    //关闭读使能
                    state      <= 2'd0;    //回到第一个状态
                end
                else                       //如果FIFO没有被读空
                    fifo_rd_en <= 1'b1;    //则持续打开读使能
            end 
			default : state <= 2'd0;
        endcase
    end
end

endmodule
        读模块的代码结构与写模块几乎一样,也是使用一个不断进行状态循环的小的状态机来控制操作过程,读者参考着代码应该很容易能够理解,这里就不再赘述。
        我们对代码进行仿真,TestBench 中只要送出时钟的复位信号即可。 TB 文件如下:
module tb_ip_fifo( );
    // Inputs
    reg sys_clk;
    reg sys_rst_n;
    
    // Instantiate the Unit Under Test (UUT)
    ip_fifo  u_ip_fifo (
        .sys_clk         (sys_clk), 
        .sys_rst_n       (sys_rst_n)
    );
    
    //Genarate the clk
    parameter PERIOD = 20;
    always begin
        sys_clk = 1'b0;
        #(PERIOD/2) sys_clk = 1'b1;
        #(PERIOD/2);
    end   
   
    initial begin
        // Initialize Inputs
        sys_rst_n = 0;
        // Wait 100 ns for global reset to finish
        #100  ;
        sys_rst_n = 1;
        // Add stimulus here
        
    end

endmodule
        写满后转为读的仿真波形图如下图所示:

        由波形图可知,当写满 255 个数据后,fifo_full 满信号就会拉高。经过延时之后,fifo_rd_en 写使能信号拉高,经过一拍之后就开始将 fifo 中的数据送到 fifo_dout 端口上。写满后转为读的仿真波形图如下图所示:

        由波形图可知,当读完 255 个数据后,fifo_empty 空信号就会拉高。经过延时之后,fifo_wr_en 写使能信号拉高,经过一拍之后就开始向 fifo 中继续写入数据。

下载验证

        编译工程并生成比特流.bit 文件,将比特流 .bit 文件下载到 Zynq 中。
        下载完成后,接下来在 Vivado 中会自动出现“ hw_ila_1 Dashboard 窗口。如下图所示:

将探针信号添加到波形窗口中

        将有关探针信号添加到波形窗口中,这里我们已经完成信号的添加,方法是点击“hw_ila_1”Dashboard窗口左上角的“+”。同时我们在窗口右下角将“fifo_rd_en”信号添加到触发窗口中且设置为上升沿触发,单击左上角的触发按钮,如下图所示:

触发按钮

         最后就看到了 ILA 捕获得到的数据,展开波形图如下图所示:

捕获得到的波形图

         从捕获得到的波形图中可以看出,其逻辑行为与仿真波形图中的一致,证明我们的代码正确地实现了预期的功能。

演示视频

ip_fifo

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

IP核之FIFO实验 的相关文章

  • 记一次kafka Consumer线程停止消费过程分析

    前言 kafka消息队列在项目开发中经常被使用 尤其是在大数据领域经常见到它的身影 spring集成了kafka方便我们使用 只要引入spring kafka即可 问题描述 有一天我们后台版本发布 虽然改动很大 但是大家还是自信满满 因为经
  • Spring Boot中使用WebSocket [第三部分]

    使用消息队列实现分布式WebSocket 在上一篇文章 https www zifangsky cn 1359 html 中我介绍了服务端如何给指定用户的客户端发送消息 并如何处理对方不在线的情况 在这篇文章中我们继续思考另外一个重要的问题
  • PTA自测-1 打印沙漏 python实现

    本题要求你写个程序把给定的符号打印成沙漏的形状 例如给定17个 要求按下列格式打印 所谓 沙漏形状 是指每行输出奇数个符号 各行符号中心对齐 相邻两行符号数差2 符号数先从大到小顺序递减到1 再从小到大顺序递增 首尾符号数相等 给定任意N个
  • 前端接收后端返回换行符 /n 不生效

    问题 前端接收后端返回换行符 n 不换行 不生效 解决方案 一 设置css的white space属性 div class text container text div export default data return text 这是

随机推荐

  • StackOverflow 第四周周报及19年就业情况分析

    这是 Stack Overflow 第四周周报 两篇 Java 两篇 Python 公众号 渡码 为日更 欢迎关注 另外 我搜集了今年的就业数据 对招聘情况和岗位情况做了简单总结 想了解的朋友点这里 DAY1 枚举对象 和 equals 区
  • TypeError: can only concatenate str (not “int“) to str

    看见报的错误我们可以发现大致的错误 首先要做的是先梳理一下代码整体的思路 确保思路没有问题 然后再断点调试 每个步骤的打印也可以 这样可以很好的得到每个阶段所获得的值 定位错误 然后就是针对错误进行解决 简而言之就是报错解决的范围太泛了 太
  • 【自然语言处理】Transformer 讲解

    有任何的书写错误 排版错误 概念错误等 希望大家包含指正 在阅读本篇之前建议先学习 自然语言处理 Seq2Seq 讲解 自然语言处理 Attention 讲解 Transformer 为了讲解更加清晰 约定 预测阶段 被称为 推断阶段 in
  • cubemx hal stm32 舵机 可减速 任意位置停止 驱动代码

    CubeMX配置 对于 STM32 F407VE 这里的84是来自APB1那路2倍频得到 代码部分 两个舵机都是180度的 servo c include servo h include tim h include stdio h IO u
  • css补充2:flex布局,居中方案等

    一 flex 布局 1 1 flex布局原理 flex是flexible Box的缩写 意为 弹性布局 用来为盒状模型提供最大的灵活性 任何一个容器都可以指定为flex布局 当我们为父盒子设为flex布局以后 子元素的float clear
  • 相似度计算

    在推荐系统中 最基础的一个概念就是计算相似度 很多的相似度都是基于距离计算出来的 计算距离的方法有很多种 包括 Euclidian Distance Pearson Correlation Cosine Similarity interse
  • 【华为OD机试真题2023B卷 JAVA&JS】模拟消息队列

    华为OD2023 B卷 机试题库全覆盖 刷题指南点这里 模拟消息队列 知识点排序 时间限制 1s 空间限制 256MB 限定语言 不限 题目描述 让我们来模拟一个消息队列的运作 有一个发布者和若干消费者 发布者会在给定的时刻向消息队列发送消
  • JQuery美化下拉框插件

  • 简单卸载硬盘安装的ubuntu

    我们多数要卸载ubuntu的都是双系统 简简单单 两步搞定ubuntu的卸载前提拥有一张windows的光盘 上面带有PE系统即可 用优盘启动盘估计也可以第一步 先去除grub 进入PE 多数PE里面有一个分区表医生或者类似的软件 我用的F
  • ubuntu解压zip文件命令_Ubuntu压缩及解压文件简介

    使用Ubuntu的过程中 无论用来干什么 都会有文件上的交流 必不可免的就是压缩文件 Ubuntu系统中自带了部分格式的压缩软件 但是win系统习惯的rar格式文件解压需要下载相关软件 现整理如下 1 文件格式及解压工具 tar 用 tar
  • ARM中MMU之地址转换

    第一次发帖略微有点激动 有不足的地方还请各位大神指教 最近看了看mmu 找了好多资料 看了好多博文终于稍微清楚了一点 现在我把自己理解的内容总结一下 首先我来说一下MMU的作用 MMU就是负责虚拟地址 virtual address 转化成
  • response.getWriter().write()和 response.getWriter().print()的区别 以及 PrintWriter对象 和 out对象 的区别

    一 response getWriter write 和 response getWriter print 的区别 response getWriter 返回的是PrintWriter 这是一个打印输出流 response getWrite
  • Pytorch之经典神经网络Generative Model(三) —— GAN (MNIST)

    2014年由GAN之父Ian Goodfellow提出 加拿大蒙特利尔大学 GAN 生成式对抗网络 前面我们讲了自动编码器和变分自动编码器 不管是哪一个 都是通过计算生成图像和输入图像在每个像素点的误差来生成 loss 这一点是特别不好的
  • 一篇文章,让你彻底搞懂单例设计模式

    今天在一群小哥哥的带领下 本程序媛终于学会了所有单例模式 非常感谢大哥哥 小哥哥 下文是我总结的单例模式的八种实现方式 如下所示 单例模式的简介 我们将一个类在当前进程中只有一个实例的这种模式 称之为 单例模式 那么Java代码如何实现一个
  • Postman —— 配置环境变量

    PostMan是一套比较方便的接口测试工具 但我们在使用过程中 可能会出现创建了API请求 但API的URL会随着服务器IP地址的变化而改变 这样的情况下 如果每一个API都重新修改URL的话那将是非常的麻烦 所以PostMan中也提供环境
  • 【ViT 微调时关于position embedding如何插值(interpolate)的详解】

    目录 1 问题描述 2 positional embedding如何interpolate 3 输入的sequence length改变了ViT还能正常前向推断 本文适合对Vision Transformer有一定了解 知道内部结构和一些实
  • 项目6—利用中断实现单位数码管0~9显示

    项目5中有介绍中断问题 中断函数命名格式 函数值类型 函数名 形式参数列表 interrupt x interrupt为中断函数关键字 表中第二行T0中断 使能T0中断 就要将ET0置1 当它的中断标志位TF0变为1时 就会触发T0中断 这
  • UVA1613 K-GraphOddity

    UVA1613 K GraphOddity 题目传送门 刚看第一眼一点思路都没有 后面看了大佬的题解发现这道题其实是一道水题 用到的方法就是DFS遍历图 我是废物 题目意思很简单 就不分析了 下面直接说方法 首先求出k 然后dfs遍历一遍图
  • 出现这个问题 -bash: /etc/profile.d/env.sh: Permission denied

    记录一下搞了一个上午都没有解决的问题 如下图 出现的问题很奇怪 从root用户切换到普通用户是出现了 bash etc profile d env sh Permission denied 然后用root 把这个env sh文件 内容是PS
  • IP核之FIFO实验

    FIFO 的英文全称是 First In First Out 即先进先出 FPGA 使用的 FIFO 一般指的是对数据的存储具有先进先出特性的一个缓存器 常被用于数据的缓存 或者高速异步数据的交互也即所谓的跨时钟域信号传递 它与 FPGA