草庐IT

FPGA纯verilog代码实现4路视频缩放拼接 提供工程源码和技术支持

9527华安 2023-04-14 原文

目录

1、前言

本文详细描述了FPGA纯verilog代码实现4路视频缩放拼接的实现设计方案,工程代码编译通过后上板调试验证,文章末尾有演示视频,可直接项目移植,适用于在校学生、研究生,也适用于在职工程师做项目开发,可应用于医疗、军工等行业的数字成像和图像传输领域;
提供完整的、跑通的工程源码和技术支持;
工程源码和技术支持的获取方式放在了文章末尾,请耐心看到最后。

2、目前主流的FPGA图像缩放方案

目前市面上主流的FPGA图像缩放方案如下:
1:Xilinx的HLS方案,该方案简单,易于实现,但只能用于Xilinx自家的FPGA;关于HLS实现图像缩放请,参考我之前写的文章HLS实现图像缩放点击查看:HLS图像缩放
2:非纯Verilog方案,大部分代码使用Verilog实现,但中间的fifo或ram等使用了IP,导致移植性变差,难以在Xilinx、Altera和国产FPGA之间自由移植;
3:纯Verilog方案,也就是本方案,一个字:牛逼!!!

3、目前主流的FPGA视频拼接方案

FPGA实现视频拼接是FPGA在图像处理领域的基本应用,如果你的视频是AXIS流,且你的开发板是K7或者zynq之类的高端处理器,可以使用Xilinx官方的video mixer实现视频拼接,关于video mixer实现视频拼接,可以参考我之前写的文章点击查看:video mixer实现视频拼接
但是,对于使用A7或者Spartan6之类的低端FPGA开发者来说,video mixer就不适用了,再者,video mixer必须是AXIS接口,对于vga时序或者摄像头rgb时序而言也不适用,必须用Xilinx的ip转为AXIS流,如此不仅麻烦且加大了逻辑资源消耗,这时,本文的纯verilog视频拼接方案就有用了。

4、本设计方案的优越性

一个字:牛逼,表现如下:
1:纯Verilog代码实现,学习性和阅读性达到天花板;
2:移植性达到天花板,Xilinx、Altera和国产FPGA之间自由移植;
3:算法达到天花板,融合了邻近插值和双线性插值两种算法;
4:实用性达到天花板,将图像缩放和图像拼接融合一体,符合实际的工程项目,做类似项目的兄弟可直接拿去用,一个月工资直接拿到手。。。

5、详细设计方案解读

详细设计方案框图如下:

HDMI输入

视频输入采用HDMI,分辨率为1920x1080,HDMI采用silicon9011芯片解码,silicon9011需要i2c配置才能使用,关于silicon9011芯片的配置和使用,请参考我之前写的文章点击查看:silicon9011
输入只有1路HDMI,为了模拟4路视频输入,直接将解码后的视频数据给到4路图像缩放模块。

图像缩放

本图像缩放模块将常用的双线性插值和邻域插值算法融合为一个代码中,通过输入参数选择某一种算法;代码使用纯verilog实现,没有任何ip,可在Xilinx、Intel、国产FPGA间任意移植;代码以ram和fifo为核心进行数据缓存和插值实现;
网上也有其他图像缩放例程代码,但大多使用了IP,导致在其他FPGA器件上移植变得困难,通用性不好;相比之下,本设计代码就具有通用性;
这里例化了4个图像缩放模块,将4路输入视频缩小至960x540;
关于图像缩放的详细设计说明,请参考我之前写的文章点击查看:图像缩放

图像缓存

使用FDMA方案实现图像三帧缓存,关于FDMA方案实现图像三帧缓存,请参考我之前写的文章点击查看:FDMA图像缓存

VGA时序

这部分很简单,不必多讲,就是生成一个1080P的VGA时序;

HDMI输出

视频输出采用HDMI,分辨率为1920x1080,HDMI采用silicon9134芯片编码,silicon9134需要i2c配置才能使用,关于silicon9134芯片的配置和使用,请参考我之前写的文章点击查看:silicon9134

6、vivado工程详解

工程BD如下:

综合后的代码架构如下:

FPGA资源消耗以及功耗预估如下:

顶层代码源码如下:

`timescale 1ns / 1ps
module top(  
//ddr3  
  output [14:0]DDR3_0_addr,
  output [2:0]DDR3_0_ba   ,
  output DDR3_0_cas_n     ,
  output [0:0]DDR3_0_ck_n ,
  output [0:0]DDR3_0_ck_p ,
  output [0:0]DDR3_0_cke  ,
  output [0:0]DDR3_0_cs_n ,
  output [3:0]DDR3_0_dm   ,
  inout [31:0]DDR3_0_dq   ,
  inout [3:0]DDR3_0_dqs_n ,
  inout [3:0]DDR3_0_dqs_p ,
  output [0:0]DDR3_0_odt  ,
  output DDR3_0_ras_n     ,
  output DDR3_0_reset_n   ,
  output DDR3_0_we_n      , 
  
  input        CLK_IN1_D_0_clk_n,
  input        CLK_IN1_D_0_clk_p,
  output       ddr3_ok          ,  
//hdmi_in
  output       hdmi_in_nreset   ,     //9011/9013 reset
  input        vin_clk          ,            //clock for 9111/9013
  input        vin_hs           ,             //horizontal synchronization for 9011/9013
  input        vin_vs           ,             //vertical synchronization for 9011/9013
  input        vin_de           ,             //data valid for 9011/9013
  input[23:0]  vin_data         ,           //data for 9011/9013   
  inout        hdmi_scl         ,           //HDMI I2C clock
  inout        hdmi_sda         ,           //HDMI I2C data
  output       hdmi_nreset      ,        //9134 reset
//hdmi_out  
  output       vout_hs          ,            //horizontal synchronization for 9134
  output       vout_vs          ,            //vertical synchronization for 9134
  output       vout_de          ,            //data valid for 9134
  output       vout_clk         ,           //clock for 9134
  output[23:0] vout_data                   //data for 9134
);

wire	    clk_200m  ;
wire        clk_hdmi  ;
wire        pll_resetn;
wire [0:0]  resetn;
wire        ud_r_0_ud_rclk;
wire [31:0] ud_r_0_ud_rdata;
wire        ud_r_0_ud_rde;
wire        ud_r_0_ud_rvs;
wire        ud_w_0_ud_wclk;
wire [31:0] ud_w_0_ud_wdata;
wire        ud_w_0_ud_wde;
wire        ud_w_0_ud_wvs;
wire [31:0] ud_w_1_ud_wdata;
wire        ud_w_1_ud_wde;
wire        ud_w_1_ud_wvs;
wire [31:0] ud_w_2_ud_wdata;
wire        ud_w_2_ud_wde;
wire        ud_w_2_ud_wvs;
wire [31:0] ud_w_3_ud_wdata;
wire        ud_w_3_ud_wde;
wire        ud_w_3_ud_wvs;
wire        ui_clk_100m;

wire [9:0]   lut_index;
wire [31:0]  lut_data; 

wire [23:0] i_rgb;  
wire 	    o_hs ;  
wire 	    o_vs ;  
wire 	    o_de ;  
wire [23:0] o_rgb;  
wire hdmi_clk_rstn;
wire o_data_req;

wire [23:0] resize0_rgb;    
wire 	    resize0_vs ;  
wire 	    resize0_de ;
wire [23:0] resize1_rgb;    
wire 	    resize1_vs ;  
wire 	    resize1_de ;
wire [23:0] resize2_rgb;    
wire 	    resize2_vs ;  
wire 	    resize2_de ;
wire [23:0] resize3_rgb;    
wire 	    resize3_vs ;  
wire 	    resize3_de ;

assign hdmi_nreset   =pll_resetn;  
assign hdmi_in_nreset=pll_resetn;
assign ud_w_0_ud_wclk =vin_clk ;
assign ud_w_0_ud_wvs  =resize0_vs  ;
assign ud_w_0_ud_wde  =resize0_de  ;
assign ud_w_0_ud_wdata=resize0_rgb;
assign ud_w_1_ud_wclk =vin_clk ;
assign ud_w_1_ud_wvs  =resize1_vs  ;
assign ud_w_1_ud_wde  =resize1_de  ;
assign ud_w_1_ud_wdata=resize1_rgb;
assign ud_w_2_ud_wclk =vin_clk ;
assign ud_w_2_ud_wvs  =resize2_vs  ;
assign ud_w_2_ud_wde  =resize2_de  ;
assign ud_w_2_ud_wdata=resize2_rgb;
assign ud_w_3_ud_wclk =vin_clk ;
assign ud_w_3_ud_wvs  =resize3_vs  ;
assign ud_w_3_ud_wde  =resize3_de  ;
assign ud_w_3_ud_wdata=resize3_rgb;
assign ud_r_0_ud_rclk=clk_hdmi;
assign ud_r_0_ud_rvs=o_vs;
assign ud_r_0_ud_rde=o_data_req;
assign i_rgb=ud_r_0_ud_rdata[23:0];
assign vout_clk=clk_hdmi;
assign vout_hs=o_hs;
assign vout_vs=o_vs;
assign vout_de=o_de;
assign vout_data=o_rgb;

i2c_config i2c_config_m0(
.rst            (~pll_resetn    ),
.clk            (clk_200m       ),
.clk_div_cnt    (16'd500        ),
.i2c_addr_2byte (1'b0           ),
.lut_index      (lut_index      ),
.lut_dev_addr   (lut_data[31:24]),
.lut_reg_addr   (lut_data[23:8] ),
.lut_reg_data   (lut_data[7:0]  ),
.error          (               ),
.done           (               ),
.i2c_scl        (hdmi_scl       ),
.i2c_sda        (hdmi_sda       )
);

lut_hdmi lut_hdmi_m0
(
.lut_index (lut_index),
.lut_data  (lut_data )
);

helai_video_scale #(
	.DATA_WIDTH         (8 ),		//Width of input/output data
	.CHANNELS           (3 ),		//Number of channels of DATA_WIDTH, for color images
	.DISCARD_CNT_WIDTH  (8 ),		//Width of inputDiscardCnt
	.INPUT_X_RES_WIDTH  (11),		//Widths of input/output resolution control signals
	.INPUT_Y_RES_WIDTH  (11),
	.OUTPUT_X_RES_WIDTH (11),
	.OUTPUT_Y_RES_WIDTH (11),
	.FRACTION_BITS      (8 ),		//Number of bits for fractional component of coefficients.
	.SCALE_INT_BITS     (8 ),		//Width of integer component of scaling factor. The maximum input data width to
	.SCALE_FRAC_BITS    (14),		//Width of fractional component of scaling factor
	.BUFFER_SIZE        (4 )		//Depth of RFIFO	
)video_scale0(
	.clk             (vin_clk    ),
	.rst             (~pll_resetn),
	.i_vid_data      (vin_data   ), 
	.i_vid_de        (vin_de     ),
	.o_vid_fifo_read (),
	.i_vid_vs        (vin_vs     ),
	.o_vout_data     (resize0_rgb),
	.o_vout_de       (resize0_de ),			//latency of 4 clock cycles after nextDout is asserted
	.o_vout_vs       (resize0_vs ),
	.i_vout_read     (1),
	.i_discard_cnt   (0),	//Number of input pixels to discard before processing data. Used for clipping
	.i_src_image_x   (1920-1),			//Resolution of input data minus 1
	.i_src_image_y   (1080-1),
	.i_des_image_x   (960-1),			//Resolution of output data minus 1
	.i_des_image_y   (540-1),
	.i_scaler_x_ratio(32'h4000 * (1920-1) / (960-1)-1),				//Scaling factors. Input resolution scaled up by 1/xScale. Format Q SCALE_INT_BITS.SCALE_FRAC_BITS
	.i_scaler_y_ratio(32'h4000 * (1080-1) / (540-1)-1),				//Scaling factors. Input resolution scaled up by 1/yScale. Format Q SCALE_INT_BITS.SCALE_FRAC_BITS
	.i_left_offset   (0),			//Integer/fraction of input pixel to offset output data horizontally right. Format Q OUTPUT_X_RES_WIDTH.SCALE_FRAC_BITS
	.i_top_offset    (0),		//Fraction of input pixel to offset data vertically down. Format Q0.SCALE_FRAC_BITS
	.i_scaler_type   (0)		//Use nearest neighbor resize instead of bilinear
);

helai_video_scale #(
	.DATA_WIDTH         (8 ),		//Width of input/output data
	.CHANNELS           (3 ),		//Number of channels of DATA_WIDTH, for color images
	.DISCARD_CNT_WIDTH  (8 ),		//Width of inputDiscardCnt
	.INPUT_X_RES_WIDTH  (11),		//Widths of input/output resolution control signals
	.INPUT_Y_RES_WIDTH  (11),
	.OUTPUT_X_RES_WIDTH (11),
	.OUTPUT_Y_RES_WIDTH (11),
	.FRACTION_BITS      (8 ),		//Number of bits for fractional component of coefficients.
	.SCALE_INT_BITS     (8 ),		//Width of integer component of scaling factor. The maximum input data width to
	.SCALE_FRAC_BITS    (14),		//Width of fractional component of scaling factor
	.BUFFER_SIZE        (4 )		//Depth of RFIFO	
)video_scale1(
	.clk             (vin_clk    ),
	.rst             (~pll_resetn),
	.i_vid_data      (vin_data   ), 
	.i_vid_de        (vin_de     ),
	.o_vid_fifo_read (),
	.i_vid_vs        (vin_vs     ),
	.o_vout_data     (resize1_rgb),
	.o_vout_de       (resize1_de ),			//latency of 4 clock cycles after nextDout is asserted
	.o_vout_vs       (resize1_vs ),
	.i_vout_read     (1),
	.i_discard_cnt   (0),	//Number of input pixels to discard before processing data. Used for clipping
	.i_src_image_x   (1920-1),			//Resolution of input data minus 1
	.i_src_image_y   (1080-1),
	.i_des_image_x   (960-1),			//Resolution of output data minus 1
	.i_des_image_y   (540-1),
	.i_scaler_x_ratio(32'h4000 * (1920-1) / (960-1)-1),				//Scaling factors. Input resolution scaled up by 1/xScale. Format Q SCALE_INT_BITS.SCALE_FRAC_BITS
	.i_scaler_y_ratio(32'h4000 * (1080-1) / (540-1)-1),				//Scaling factors. Input resolution scaled up by 1/yScale. Format Q SCALE_INT_BITS.SCALE_FRAC_BITS
	.i_left_offset   (0),			//Integer/fraction of input pixel to offset output data horizontally right. Format Q OUTPUT_X_RES_WIDTH.SCALE_FRAC_BITS
	.i_top_offset    (0),		//Fraction of input pixel to offset data vertically down. Format Q0.SCALE_FRAC_BITS
	.i_scaler_type   (0)		//Use nearest neighbor resize instead of bilinear
);

helai_video_scale #(
	.DATA_WIDTH         (8 ),		//Width of input/output data
	.CHANNELS           (3 ),		//Number of channels of DATA_WIDTH, for color images
	.DISCARD_CNT_WIDTH  (8 ),		//Width of inputDiscardCnt
	.INPUT_X_RES_WIDTH  (11),		//Widths of input/output resolution control signals
	.INPUT_Y_RES_WIDTH  (11),
	.OUTPUT_X_RES_WIDTH (11),
	.OUTPUT_Y_RES_WIDTH (11),
	.FRACTION_BITS      (8 ),		//Number of bits for fractional component of coefficients.
	.SCALE_INT_BITS     (8 ),		//Width of integer component of scaling factor. The maximum input data width to
	.SCALE_FRAC_BITS    (14),		//Width of fractional component of scaling factor
	.BUFFER_SIZE        (4 )		//Depth of RFIFO	
)video_scale2(
	.clk             (vin_clk    ),
	.rst             (~pll_resetn),
	.i_vid_data      (vin_data   ), 
	.i_vid_de        (vin_de     ),
	.o_vid_fifo_read (),
	.i_vid_vs        (vin_vs     ),
	.o_vout_data     (resize2_rgb),
	.o_vout_de       (resize2_de ),			//latency of 4 clock cycles after nextDout is asserted
	.o_vout_vs       (resize2_vs ),
	.i_vout_read     (1),
	.i_discard_cnt   (0),	//Number of input pixels to discard before processing data. Used for clipping
	.i_src_image_x   (1920-1),			//Resolution of input data minus 1
	.i_src_image_y   (1080-1),
	.i_des_image_x   (960-1),			//Resolution of output data minus 1
	.i_des_image_y   (540-1),
	.i_scaler_x_ratio(32'h4000 * (1920-1) / (960-1)-1),				//Scaling factors. Input resolution scaled up by 1/xScale. Format Q SCALE_INT_BITS.SCALE_FRAC_BITS
	.i_scaler_y_ratio(32'h4000 * (1080-1) / (540-1)-1),				//Scaling factors. Input resolution scaled up by 1/yScale. Format Q SCALE_INT_BITS.SCALE_FRAC_BITS
	.i_left_offset   (0),			//Integer/fraction of input pixel to offset output data horizontally right. Format Q OUTPUT_X_RES_WIDTH.SCALE_FRAC_BITS
	.i_top_offset    (0),		//Fraction of input pixel to offset data vertically down. Format Q0.SCALE_FRAC_BITS
	.i_scaler_type   (0)		//Use nearest neighbor resize instead of bilinear
);

helai_video_scale #(
	.DATA_WIDTH         (8 ),		//Width of input/output data
	.CHANNELS           (3 ),		//Number of channels of DATA_WIDTH, for color images
	.DISCARD_CNT_WIDTH  (8 ),		//Width of inputDiscardCnt
	.INPUT_X_RES_WIDTH  (11),		//Widths of input/output resolution control signals
	.INPUT_Y_RES_WIDTH  (11),
	.OUTPUT_X_RES_WIDTH (11),
	.OUTPUT_Y_RES_WIDTH (11),
	.FRACTION_BITS      (8 ),		//Number of bits for fractional component of coefficients.
	.SCALE_INT_BITS     (8 ),		//Width of integer component of scaling factor. The maximum input data width to
	.SCALE_FRAC_BITS    (14),		//Width of fractional component of scaling factor
	.BUFFER_SIZE        (4 )		//Depth of RFIFO	
)video_scale3(
	.clk             (vin_clk    ),
	.rst             (~pll_resetn),
	.i_vid_data      (vin_data   ), 
	.i_vid_de        (vin_de     ),
	.o_vid_fifo_read (),
	.i_vid_vs        (vin_vs     ),
	.o_vout_data     (resize3_rgb),
	.o_vout_de       (resize3_de ),			//latency of 4 clock cycles after nextDout is asserted
	.o_vout_vs       (resize3_vs ),
	.i_vout_read     (1),
	.i_discard_cnt   (0),	//Number of input pixels to discard before processing data. Used for clipping
	.i_src_image_x   (1920-1),			//Resolution of input data minus 1
	.i_src_image_y   (1080-1),
	.i_des_image_x   (960-1),			//Resolution of output data minus 1
	.i_des_image_y   (540-1),
	.i_scaler_x_ratio(32'h4000 * (1920-1) / (960-1)-1),				//Scaling factors. Input resolution scaled up by 1/xScale. Format Q SCALE_INT_BITS.SCALE_FRAC_BITS
	.i_scaler_y_ratio(32'h4000 * (1080-1) / (540-1)-1),				//Scaling factors. Input resolution scaled up by 1/yScale. Format Q SCALE_INT_BITS.SCALE_FRAC_BITS
	.i_left_offset   (0),			//Integer/fraction of input pixel to offset output data horizontally right. Format Q OUTPUT_X_RES_WIDTH.SCALE_FRAC_BITS
	.i_top_offset    (0),		//Fraction of input pixel to offset data vertically down. Format Q0.SCALE_FRAC_BITS
	.i_scaler_type   (0)		//Use nearest neighbor resize instead of bilinear
);

design_1_wrapper u_design_1_wrapper
   (
    .CLK_IN1_D_0_clk_n(CLK_IN1_D_0_clk_n),
    .CLK_IN1_D_0_clk_p(CLK_IN1_D_0_clk_p),
    .DDR3_0_addr      (DDR3_0_addr      ),
    .DDR3_0_ba        (DDR3_0_ba        ),
    .DDR3_0_cas_n     (DDR3_0_cas_n     ),
    .DDR3_0_ck_n      (DDR3_0_ck_n      ),
    .DDR3_0_ck_p      (DDR3_0_ck_p      ),
    .DDR3_0_cke       (DDR3_0_cke       ),
    .DDR3_0_cs_n      (DDR3_0_cs_n      ),
    .DDR3_0_dm        (DDR3_0_dm        ),
    .DDR3_0_dq        (DDR3_0_dq        ),
    .DDR3_0_dqs_n     (DDR3_0_dqs_n     ),
    .DDR3_0_dqs_p     (DDR3_0_dqs_p     ),
    .DDR3_0_odt       (DDR3_0_odt       ),
    .DDR3_0_ras_n     (DDR3_0_ras_n     ),
    .DDR3_0_reset_n   (DDR3_0_reset_n   ),
    .DDR3_0_we_n      (DDR3_0_we_n      ),
    .clk_200m         (clk_200m         ),
	.clk_hdmi         (clk_hdmi         ),
    .ddr3_ok          (ddr3_ok          ),
    .pll_resetn       (pll_resetn       ),
    .resetn           (resetn           ),
    .ud_r_0_ud_rclk   (ud_r_0_ud_rclk   ),
    .ud_r_0_ud_rdata  (ud_r_0_ud_rdata  ),
    .ud_r_0_ud_rde    (ud_r_0_ud_rde    ),
    .ud_r_0_ud_rempty (ud_r_0_ud_rempty ),
    .ud_r_0_ud_rvs    (ud_r_0_ud_rvs    ),
    .ud_w_0_ud_wclk   (ud_w_0_ud_wclk   ),
    .ud_w_0_ud_wdata  (ud_w_0_ud_wdata  ),
    .ud_w_0_ud_wde    (ud_w_0_ud_wde    ),
    .ud_w_0_ud_wfull  (ud_w_0_ud_wfull  ),
    .ud_w_0_ud_wvs    (ud_w_0_ud_wvs    ),	
    .ud_w_1_ud_wclk   (ud_w_1_ud_wclk   ),
    .ud_w_1_ud_wdata  (ud_w_1_ud_wdata  ),
    .ud_w_1_ud_wde    (ud_w_1_ud_wde    ),
    .ud_w_1_ud_wvs    (ud_w_1_ud_wvs    ),		
    .ud_w_2_ud_wclk   (ud_w_1_ud_wclk   ),
    .ud_w_2_ud_wdata  (ud_w_1_ud_wdata  ),
    .ud_w_2_ud_wde    (ud_w_1_ud_wde    ),
    .ud_w_2_ud_wvs    (ud_w_1_ud_wvs    ),		
    .ud_w_3_ud_wclk   (ud_w_1_ud_wclk   ),
    .ud_w_3_ud_wdata  (ud_w_1_ud_wdata  ),
    .ud_w_3_ud_wde    (ud_w_1_ud_wde    ),
    .ud_w_3_ud_wvs    (ud_w_1_ud_wvs    ),		
    .ui_clk_100m      (ui_clk_100m      )
	);	

video_timing_control vga(
  .i_clk     (clk_hdmi   ), 
  .i_rst_n   (pll_resetn ), 
  .i_start_x (0),
  .i_start_y (0),
  .i_disp_h  (1920),
  .i_disp_v  (1080), 
  .i_rgb     (i_rgb      ),
  .o_hs      (o_hs       ),
  .o_vs      (o_vs       ),
  .o_de      (o_de       ),
  .o_rgb     (o_rgb      ),
  .o_data_req(o_data_req )
);	
endmodule

7、上板调试验证

开发板:Xilinx Artix7-35T开发板;
开发环境:vivado2019.1;
输入:HDMI,1080P,silicon9011解码;
输出:HDMI,1080P,silicon9134编码;
静态演示如下:
由于采用了懂王的视频,所以审核不过,只能截取点图片了。。。

8、福利:工程源码获取

福利:工程代码的获取
代码太大,无法邮箱发送,以某度网盘链接方式发送;
资料如下:获取方式:私,或者文章结尾的V名片;

有关FPGA纯verilog代码实现4路视频缩放拼接 提供工程源码和技术支持的更多相关文章

  1. ruby - 如何在 buildr 项目中使用 Ruby 代码? - 2

    如何在buildr项目中使用Ruby?我在很多不同的项目中使用过Ruby、JRuby、Java和Clojure。我目前正在使用我的标准Ruby开发一个模拟应用程序,我想尝试使用Clojure后端(我确实喜欢功能代码)以及JRubygui和测试套件。我还可以看到在未来的不同项目中使用Scala作为后端。我想我要为我的项目尝试一下buildr(http://buildr.apache.org/),但我注意到buildr似乎没有设置为在项目中使用JRuby代码本身!这看起来有点傻,因为该工具旨在统一通用的JVM语言并且是在ruby中构建的。除了将输出的jar包含在一个独特的、仅限ruby​​

  2. ruby-on-rails - Rails 源代码 : initialize hash in a weird way? - 2

    在rails源中:https://github.com/rails/rails/blob/master/activesupport/lib/active_support/lazy_load_hooks.rb可以看到以下内容@load_hooks=Hash.new{|h,k|h[k]=[]}在IRB中,它只是初始化一个空哈希。和做有什么区别@load_hooks=Hash.new 最佳答案 查看rubydocumentationforHashnew→new_hashclicktotogglesourcenew(obj)→new_has

  3. ruby - 如何根据特征实现 FactoryGirl 的条件行为 - 2

    我有一个用户工厂。我希望默认情况下确认用户。但是鉴于unconfirmed特征,我不希望它们被确认。虽然我有一个基于实现细节而不是抽象的工作实现,但我想知道如何正确地做到这一点。factory:userdoafter(:create)do|user,evaluator|#unwantedimplementationdetailshereunlessFactoryGirl.factories[:user].defined_traits.map(&:name).include?(:unconfirmed)user.confirm!endendtrait:unconfirmeddoenden

  4. ruby-on-rails - 浏览 Ruby 源代码 - 2

    我的主要目标是能够完全理解我正在使用的库/gem。我尝试在Github上从头到尾阅读源代码,但这真的很难。我认为更有趣、更温和的踏脚石就是在使用时阅读每个库/gem方法的源代码。例如,我想知道RubyonRails中的redirect_to方法是如何工作的:如何查找redirect_to方法的源代码?我知道在pry中我可以执行类似show-methodmethod的操作,但我如何才能对Rails框架中的方法执行此操作?您对我如何更好地理解Gem及其API有什么建议吗?仅仅阅读源代码似乎真的很难,尤其是对于框架。谢谢! 最佳答案 Ru

  5. ruby - 模块嵌套代码风格偏好 - 2

    我的假设是moduleAmoduleBendend和moduleA::Bend是一样的。我能够从thisblog找到解决方案,thisSOthread和andthisSOthread.为什么以及什么时候应该更喜欢紧凑语法A::B而不是另一个,因为它显然有一个缺点?我有一种直觉,它可能与性能有关,因为在更多命名空间中查找常量需要更多计算。但是我无法通过对普通类进行基准测试来验证这一点。 最佳答案 这两种写作方法经常被混淆。首先要说的是,据我所知,没有可衡量的性能差异。(在下面的书面示例中不断查找)最明显的区别,可能也是最著名的,是你的

  6. ruby - 寻找通过阅读代码确定编程语言的ruby gem? - 2

    几个月前,我读了一篇关于ruby​​gem的博客文章,它可以通过阅读代码本身来确定编程语言。对于我的生活,我不记得博客或gem的名称。谷歌搜索“ruby编程语言猜测”及其变体也无济于事。有人碰巧知道相关gem的名称吗? 最佳答案 是这个吗:http://github.com/chrislo/sourceclassifier/tree/master 关于ruby-寻找通过阅读代码确定编程语言的rubygem?,我们在StackOverflow上找到一个类似的问题:

  7. ruby - Net::HTTP 获取源代码和状态 - 2

    我目前正在使用以下方法获取页面的源代码:Net::HTTP.get(URI.parse(page.url))我还想获取HTTP状态,而无需发出第二个请求。有没有办法用另一种方法做到这一点?我一直在查看文档,但似乎找不到我要找的东西。 最佳答案 在我看来,除非您需要一些真正的低级访问或控制,否则最好使用Ruby的内置Open::URI模块:require'open-uri'io=open('http://www.example.org/')#=>#body=io.read[0,50]#=>"["200","OK"]io.base_ur

  8. 程序员如何提高代码能力? - 2

    前言作为一名程序员,自己的本质工作就是做程序开发,那么程序开发的时候最直接的体现就是代码,检验一个程序员技术水平的一个核心环节就是开发时候的代码能力。众所周知,程序开发的水平提升是一个循序渐进的过程,每一位程序员都是从“菜鸟”变成“大神”的,所以程序员在程序开发过程中的代码能力也是根据平时开发中的业务实践来积累和提升的。提高代码能力核心要素程序员要想提高自身代码能力,尤其是新晋程序员的代码能力有很大的提升空间的时候,需要针对性的去提高自己的代码能力。提高代码能力其实有几个比较关键的点,只要把握住这些方面,就能很好的、快速的提高自己的一部分代码能力。1、多去阅读开源项目,如有机会可以亲自参与开源

  9. 华为OD机试用Python实现 -【明明的随机数】 2023Q1A - 2

    华为OD机试题本篇题目:明明的随机数题目输入描述输出描述:示例1输入输出说明代码编写思路最近更新的博客华为od2023|什么是华为od,od薪资待遇,od机试题清单华为OD机试真题大全,用Python解华为机试题|机试宝典【华为OD机试】全流程解析+经验分享,题型分享,防作弊指南华为o

  10. UE4 源码阅读:从引擎启动到Receive Begin Play - 2

    一、引擎主循环UE版本:4.27一、引擎主循环的位置:Launch.cpp:GuardedMain函数二、、GuardedMain函数执行逻辑:1、EnginePreInit:加载大多数模块int32ErrorLevel=EnginePreInit(CmdLine);PreInit模块加载顺序:模块加载过程:(1)注册模块中定义的UObject,同时为每个类构造一个类默认对象(CDO,记录类的默认状态,作为模板用于子类实例创建)(2)调用模块的StartUpModule方法2、FEngineLoop::Init()1、检查Engine的配置文件找出使用了哪一个GameEngine类(UGame

随机推荐