HDLBits刷题Day1,2.5.6 Generate for-loop:100-bit binary adder 2

文章详细介绍了如何通过实例化100个全加器构建一个100位波纹进位加法器,使用generate语句在Verilog中动态生成代码,以解决等波纹进位加法器中位间的依赖问题。作者还给出了generate语句的不同用法,如for循环、if条件和case选择,以及如何在测试bencht中应用这些技术。
摘要由CSDN通过智能技术生成

问题描述

练习:通过实例化100个全加器来创建一个 100 位二进制波纹进位加法器。加法器将两个 100 位数字和一个进位相加,产生一个 100 位和并执行。为了鼓励您实际实例化全加器,还要输出纹波进位加法器中每个全加器的进位。cout[99] 是最后一个全加器的最终进位,也是您通常看到的进位。

提示:有许多全加器要实例化。实例数组或生成语句将在这里有所帮助

相关知识:

等波纹进位加法器:最低的比特位先进行简单的全加器计算(A0+B0),生产的和作为最终sum的最低位sum0,然后其进位cout0参与下一位的全加器计算(A1+B1+cout0),其和为sum1,进位为cout1。依次推列,后面是(A2+B2+cout1)、(A3+B3+cout2)……这样的加法器有个很明显的缺陷,即每位的计算都要等低位计算完后才能开始计算(每次全加器计算都要等低一位的进位),会严重的浪费时间。

代码:

module top_module( 
    input [99:0] a, b,
    input cin,
    output [99:0] cout,
    output [99:0] sum );
    
    genvar i;
    generate 
        for(i=0;i<100;i=i+1) begin:adder
            if(i==0)
                assign{cout[0],sum[0]} = a[0]+b[0]+cin;
            else
                assign{cout[i],sum[i]} = a[i]+b[i]+cout[i-1];
        end
    endgenerate

endmodule

generate语句介绍

generate语句可以动态地生成verilog代码

1、多个模块需要进行重复例化,或者多条赋值语句需要重复执行时(generate-for)

2、多个模块需要进行选择例化,或者多条赋值语句需要选择执行时(generate-if   generate-case)

有些抽象,没关系,我们来看例子

1.generate-for

注意事项

①必须使用genvar定义循环索引变量,用作for循环判断

②需要复制的语句必须写到begin_end语句中,即使只有一句话

③begin后面需要有一个类似模块名的名字代码

//以任意位宽数据高位到低位倒序
genvar  i;	//生成循环索引变量
generate 
        for(i=0;i<data_width;i=i+1) begin:datashift
				assign out_data[data_width-1-i] = in_data[i];
		end
endgenerate

再举一个重复例化的例子

// 四个一位半加法器构成一个四位半加法器

// 半加法器module
module half_addr(
    input   a   ,
    input   b   ,
    output  cout ,
    output  sum
);
    assign sum = a^b;
    assign cout = a&b; 
endmodule
// 四位半加法器module
module half_adder4(
    input   [3:0]   add_a,
    input   [3:0]   add_b,
    output  [3:0]   cout,
    output  [3:0]   sum
);
    genvar i;
    generate
        // 重复例化
        for(i=0;i<4;i=i+1) begin:half_addr_f
             half_addr u_half_addr(
                    .a      (add_a[i]   ),
                    .b      (add_b[i]   ),
                    .cout   (cout[i]    ),
                    .sum    (sum[i]     )             
                    );
        end
    endgenerate  
endmodule


// testbench
module half_adder4_tb;
    reg     [3:0]   add_a   ;
    reg     [3:0]   add_b   ;
    wire    [3:0]   cout     ;
    wire    [3:0]   sum     ;
    initial begin
        add_a = 4'b0010;
        add_b = 4'b1001;
        #100;
        add_a = 4'b1011;
        add_b = 4'b0010;
    end

    half_adder4 u_half_adder4(
        .add_a  (add_a  ),
        .add_b  (add_b  ),
        .cout   (cout   ),
        .sum    (sum    )
    );
endmodule

2.generate-if

注意事项:

①模块的参数(必须是常量parameter型或lacalparam型)作为条件判断,来产生满足条件的电路

②每一个条件分支,在begin后最好命一个名字,如果不写这个名字,有的编译器会报警告

③当begin-end中只需要一句话时,begin-end可以省略(如下面的例子)

语法:

generate 
	if(condition1)begin:name_one
		分支1代码;
	end
    else if(condition2)begin:name_two
    	分支2代码;
    end
    ...
	else begin:name_n
		其他分支代码;
	end
endgenerate

 例子:

generate
    if(a<b)
        assign d = a&b;
    else
        assign d = a|b;
endgenerate

3.generate-case

注意事项:

①模块的参数(必须是常量parameter型或lacalparam型)作为条件判断,来产生满足条件的电路

②每一个条件分支,在begin后最好命一个名字,如果不写这个名字,有的编译器会报警告

③当begin-end中只需要一句话时,begin-end可以省略(如下面的例子)

语法:

generate 
	case(condition)
		case1条件:begin : name_one
			分支1代码;
		end      
		case2条件:begin : name_two
			分支2代码;
		end     
		case3条件:begin:name_three
			分支3代码;
		end
		default:begin:name_n
			分支n代码;
		end
     endcase
endgenerate

例子: 

generate
    case(condition)
        1'b0: assign d = a&b;
        1'b1: assign d = a|b;
        default: assign d = 1'b0;
    endcase
endgenerate

  • 3
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值