verilog当中使用预定义参数的注意事项

1define预定义参数的注意事项

如果要根据预定义的参数进行分类定义另一个参数的时候,不能直接用这种或方式对预定义参数进行判断。也就是说对于预定义的参数,如果是根据这个来进行判断,则需要用`ifdef来进行操作;如果是直接用这个参数的值进行计算,则`DIN_SIGNED直接使用。(但要特别注意,如果是将预定义的参数进行拼接时,要特别注意位宽,因为预定义的参数位宽是未知的,可以在预定义的时候就指定位宽,或者重新定义一个参数,规定他的位宽)


`define     DIN_SIGNED      1  

// 1  正确
`ifdef DIN_SIGNED
	localparam  DOUT_SIGNED  = 1'b1;
`elsif COEF_SIGNED
	localparam  DOUT_SIGNED  = 1'b1;
`else 
 	localparam  DOUT_SIGNED  = 1'b0; 
`endif




//2  错误
localparam  DOUT_SIGNED         =   (`DIN_SIGNED || `COEF_SIGNED) ? 1'b1 : 1'b0;


//-------------------------------------------------------

//1  
`define     DIN_SIGNED      1
assign data_out0 =  {{(2){`DIN_SIGNED}},data_in} ;  //错误
assign data_out1 =  data_in + `DIN_SIGNED ;   //true

//2  
`define     DIN_SIGNED      1'b1
assign data_out0 =  {{(2){`DIN_SIGNED}},data_in} ; //true
assign data_out1 =  data_in + `DIN_SIGNED ;   //true

2.根据预定义参数进行数据的打拍

预定义打拍数

//  define "DSP_OUT_REG_L0"    不打拍
//  define "DSP_OUT_REG_L1"    打一拍
//  define "DSP_OUT_REG_L2"    打两拍
//  define "DSP_OUT_REG_L3"    打三拍
`define DSP_OUT_REG_L2	


`ifdef DSP_OUT_REG_L0
	`define DOUT_REG_LEVEL  0
`elsif DSP_OUT_REG_L1
	`define DOUT_REG_LEVEL  1
`elsif DSP_OUT_REG_L2
	`define DOUT_REG_LEVEL  2
`elsif DSP_OUT_REG_L3
	`define DOUT_REG_LEVEL  3
`else
	`define DOUT_REG_LEVEL  0
`endif 

第一种方式:直接对每种打拍都实现,然后根据预定义参数进行选择输出

缺点:这种方式会产生资源的浪费,如果用户并不期望打拍,但还是使用到了三级的打拍电路

优点:代码美观

    reg		dout_vld_temp_dl1;
    reg		[DOUT_TOTAL_BITS-1:0]  dout_temp_dl1;
	reg		dout_vld_temp_dl2;
    reg		[DOUT_TOTAL_BITS-1:0]  dout_temp_dl2;
	reg		dout_vld_temp_dl3;
    reg		[DOUT_TOTAL_BITS-1:0]  dout_temp_dl3;

    always @(posedge clk) begin 
    	if (~intl_rstn)  begin
            dout_vld_temp_dl1 <= 1'b0;
			dout_vld_temp_dl2 <= 1'b0;
			dout_vld_temp_dl3 <= 1'b0;
            dout_temp_dl1     <= {DOUT_TOTAL_BITS{1'b0}};
			dout_temp_dl2     <= {DOUT_TOTAL_BITS{1'b0}};
			dout_temp_dl3     <= {DOUT_TOTAL_BITS{1'b0}};
        end
    	else  begin
    		dout_vld_temp_dl1 <= dout_vld_temp;
            dout_vld_temp_dl2 <= dout_vld_temp_dl1;
            dout_vld_temp_dl3 <= dout_vld_temp_dl2;
			dout_temp_dl1     <= dout_temp;
            dout_temp_dl2     <= dout_temp_dl1;
            dout_temp_dl3     <= dout_temp_dl2;
        end
    end
`ifdef DSP_OUT_REG_L0
	parameter DOUT_REG_LEVEL = 0;
	assign dout     = dout_temp;
	assign dout_vld = dout_vld_temp;
`elsif DSP_OUT_REG_L1
	assign dout     = dout_temp_dl1;
	assign dout_vld = dout_vld_temp_dl1; 
`elsif DSP_OUT_REG_L2
	assign dout     = dout_temp_dl2;
	assign dout_vld = dout_vld_temp_dl2;
`elsif DSP_OUT_REG_L3
	assign dout     = dout_temp_dl3;
	assign dout_vld = dout_vld_temp_dl3; 
`endif 

第二种方式:根据预定义参数,产生不同的打拍次数,并输出

缺点:代码很多

优点:这种方式不会产生资源的浪费,


generate
	if (DOUT_REG_LEVEL == 0 ) begin: L0
		assign dout     = dout_temp;
		assign dout_vld = dout_vld_temp;
	end
endgenerate

generate
	if (DOUT_REG_LEVEL == 1 ) begin: L1
		reg		dout_vld_temp_dl1;
    	reg		[DOUT_TOTAL_BITS-1:0]  dout_temp_dl1;
		always @(posedge clk) begin 
    		if (~intl_rstn)  begin
        	    dout_temp_dl1     <= {DOUT_TOTAL_BITS{1'b0}};
				dout_vld_temp_dl1 <= 1'b0;
        	end
    		else  begin
				dout_temp_dl1     <= dout_temp;
				dout_vld_temp_dl1 <= dout_vld_temp;
        	end
    	end
		assign dout     = dout_temp_dl1;
		assign dout_vld = dout_vld_temp_dl1; 
	end
endgenerate

generate
	if (DOUT_REG_LEVEL == 2 ) begin: L2
		reg		dout_vld_temp_dl1;
		reg		dout_vld_temp_dl2;
    	reg		[DOUT_TOTAL_BITS-1:0]  dout_temp_dl1;
    	reg		[DOUT_TOTAL_BITS-1:0]  dout_temp_dl2;
		always @(posedge clk) begin 
    		if (~intl_rstn)  begin
        	    dout_vld_temp_dl1 <= 1'b0;
				dout_vld_temp_dl2 <= 1'b0;
        	    dout_temp_dl1     <= {DOUT_TOTAL_BITS{1'b0}};
        	    dout_temp_dl2     <= {DOUT_TOTAL_BITS{1'b0}};
        	end
    		else  begin
    			dout_vld_temp_dl1 <= dout_vld_temp;
				dout_vld_temp_dl2 <= dout_vld_temp_dl1;
				dout_temp_dl1     <= dout_temp;
				dout_temp_dl2     <= dout_temp_dl1;
        	end
    	end
		assign dout     = dout_temp_dl2;
		assign dout_vld = dout_vld_temp_dl2; 
	end
endgenerate

generate
	if (DOUT_REG_LEVEL == 3 ) begin: L3
		reg		dout_vld_temp_dl1;
    	reg		[DOUT_TOTAL_BITS-1:0]  dout_temp_dl1;
		reg		dout_vld_temp_dl2;
    	reg		[DOUT_TOTAL_BITS-1:0]  dout_temp_dl2;
		reg		dout_vld_temp_dl3;
    	reg		[DOUT_TOTAL_BITS-1:0]  dout_temp_dl3;

    	always @(posedge clk) begin 
    		if (~intl_rstn)  begin
    	        dout_vld_temp_dl1 <= 1'b0;
				dout_vld_temp_dl2 <= 1'b0;
				dout_vld_temp_dl3 <= 1'b0;
    	        dout_temp_dl1     <= {DOUT_TOTAL_BITS{1'b0}};
				dout_temp_dl2     <= {DOUT_TOTAL_BITS{1'b0}};
				dout_temp_dl3     <= {DOUT_TOTAL_BITS{1'b0}};
    	    end
    		else  begin
    			dout_vld_temp_dl1 <= dout_vld_temp;
    	        dout_vld_temp_dl2 <= dout_vld_temp_dl1;
    	        dout_vld_temp_dl3 <= dout_vld_temp_dl2;
				dout_temp_dl1     <= dout_temp;
    	        dout_temp_dl2     <= dout_temp_dl1;
    	        dout_temp_dl3     <= dout_temp_dl2;
    	    end
    	end
			assign dout     = dout_temp_dl2;
			assign dout_vld = dout_vld_temp_dl2; 
	end
endgenerate

第三种方式:定义二维数组,始终生成一次打拍,其他根据预定义参数进行打拍

优点:这种方式只会最多产生一级的资源浪费



localparam DOUT_REG_LEVEL_REAL  = (`DOUT_REG_LEVEL == 0) ? 0 : `DOUT_REG_LEVEL-1;

reg dout_vld_temp_dl[DOUT_REG_LEVEL_REAL:0]; 
reg [DOUT_TOTAL_BITS-1:0] dout_temp_dl[DOUT_REG_LEVEL_REAL:0]; 

always @(posedge clk) begin
    if (~intl_rstn) begin
        dout_vld_temp_dl[0] <= 1'b0;
        dout_temp_dl[0]     <= {DOUT_TOTAL_BITS{1'b0}};
    end else  begin
        dout_vld_temp_dl[0] <= dout_vld_temp; 
        dout_temp_dl[0]     <= dout_temp;
    end 
end

generate
    if (DOUT_REG_LEVEL_REAL > 0) begin
        genvar n;
        for (n = 1; n <= `DOUT_REG_LEVEL; n = n + 1) begin : dout_buf_dl_gen
            always @(posedge clk) begin
                if (~intl_rstn) begin
                    dout_vld_temp_dl[n] <= 1'b0;
                    dout_temp_dl[n]     <= {DOUT_TOTAL_BITS{1'b0}};
                end else begin
                    dout_vld_temp_dl[n] <= dout_vld_temp_dl[n-1]; 
                    dout_temp_dl[n]     <= dout_temp_dl[n-1]; 
                end
            end
        end
    end
endgenerate

//------------------------------------------1
//assign dout_vld = (`DOUT_REG_LEVEL == 0) ? dout_vld_temp : dout_vld_temp_dl[DOUT_REG_LEVEL_REAL]; 
//assign dout     = (`DOUT_REG_LEVEL == 0) ? dout_temp     : dout_temp_dl[DOUT_REG_LEVEL_REAL]; 



//------------------------------------------2
`ifdef DSP_OUT_REG_L0 
		assign dout_vld = dout_vld_temp;
		assign dout     = dout_temp;
`else
		assign dout_vld = dout_vld_temp_dl[DOUT_REG_LEVEL_REAL];
		assign dout     = dout_temp_dl[DOUT_REG_LEVEL_REAL];
`endif


//------------------------------------------3
/*
generate
    if (`DOUT_REG_LEVEL == 0) begin :dout_gen
		assign dout_vld = dout_vld_temp;
		assign dout     = dout_temp;
	end
	else  begin :dout_dl_gen
		assign dout_vld = dout_vld_temp_dl[DOUT_REG_LEVEL_REAL];
		assign dout     = dout_temp_dl[DOUT_REG_LEVEL_REAL];
	end
endgenerate*/

第一段是产生一级打拍时的电路,后面的for是为了产生二级和三级的打拍。后面的输出一共有三种方式,如果用assign会产生一个多余的输出选择电路。使用define或者generate则只会产生相应的电路。

  • 1
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。1、资源项目源码均已通过严格测试验证,保证能够正常运行; 2、项目问题、技术讨论,可以给博主私信或留言,博主看到后会第一时间与您进行沟通; 3、本项目比较适合计算机领域相关的毕业设计课题、课程作业等使用,尤其对于人工智能、计算机科学与技术等相关专业,更为适合; 4、下载使用后,可先查看README.md文件(如有),本项目仅用作交流学习参考,请切勿用于商业用途。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值