当前位置:   article > 正文

【HDLBits答案及思路(仅供参考,1 Getting Started与2 Verilog Language)】_hdl答案及思路

hdl答案及思路

目录(点击题目直达)

0 引言

  最近通过HDLBits学习verilog,写下此文记录下学习过程和一些心得,文中不对之处请各位批评指正。此文仅为1 Getting Started与2 Verilog Language两章题目,更多题目请见:
【HDLBits答案及思路(仅供参考,3 Circuits)(暂未更新)】
【HDLBits答案及思路(仅供参考,4 Verification: Reading Simulations与5 Verification: Writing Testbenches)(暂未更新)】
  所有代码都通过了HDLBits网站验证,但是可能在写文修改格式时出现一些问题,所以发现有不正确之处,请联系我修改。同时,我的方法不一定是最优解决方案,仅供参考,如果朋友有更好的解决思路,也希望能够不吝赐教。注:HDLBits中模块端口声明并没有指定数据类型,我也不打算修改。
  文中括号外标题对应于HDLBits首页中的标题,括号内的标题对应于具体题目左上角的标题,如● Getting Started (Step one),Getting Started是进入主页面后看到的标题,Step one是做题时左上角显示的标题。

1 Getting Started

● Getting Started (Step one)

module top_module( output one );
// Insert your code here

	assign one = 1'b1;
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5

注:verilog进行赋值时需要注意位宽问题,最好指定位宽,1'b1表示1位二进制数1

● Output Zero (Zero)

module top_module(
    output zero
);// Module body starts after semicolon

    assign zero = 1'b0;
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

2 Verilog Language

2.1 Basics

● Simple wire (Wire)

module top_module( 
	input in,
	output out );

    assign out = in;
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

● Four wires (Wire4)

module top_module( 
    input a,b,c,
    output w,x,y,z );
    
    assign w = a;
    assign x = b;
    assign y = b;
    assign z = c;
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

● Inverter (Notgate)

module top_module( input in, output out );

    assign out = !in;
endmodule
  • 1
  • 2
  • 3
  • 4

● AND gate (Andgate)

module top_module( 
    input a, 
    input b, 
    output out );
    
	assign out = a & b;
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

● NOR gate (Norgate)

module top_module( 
    input a, 
    input b, 
    output out );
    
    assign out = ~(a | b);
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

● XNOR gate (Xnorgate)

module top_module( 
    input a, 
    input b, 
    output out );
    
    assign out = ~(a^b);
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

● Declaring wires (Wire decl)

`default_nettype none
module top_module(
    input a,
    input b,
    input c,
    input d,
    output out,
    output out_n   ); 
    
	wire and_ab,and_cd,or1;
    assign and_ab = a & b;
    assign and_cd = c & d;
    assign or1 = and_ab | and_cd;
    assign out = or1;
    assign out_n = ~or1;
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

● 7458 chip (7458)

module top_module ( 
    input p1a, p1b, p1c, p1d, p1e, p1f,
    output p1y,
    input p2a, p2b, p2c, p2d,
    output p2y );
    
    assign p1y = (p1a & p1b & p1c) | (p1d & p1e & p1f);
    assign p2y = (p2a & p2b) | (p2c & p2d);
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

2.2 Vectors

● Vectors (Vector0)

module top_module ( 
    input wire [2:0] vec,
    output wire [2:0] outv,
    output wire o2,
    output wire o1,
    output wire o0  ); // Module body starts after module declaration
    
    assign outv = vec;
    assign o0 = vec[0];
    assign o1 = vec[1];
    assign o2 = vec[2];
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

● Vectors in more detail (Vector1)

`default_nettype none     // Disable implicit nets. Reduces some types of bugs.
module top_module( 
    input wire [15:0] in,
    output wire [7:0] out_hi,
    output wire [7:0] out_lo );
    
    assign out_hi[7:0] = in[15:8];
    assign out_lo[7:0] = in[7:0];
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

● Vector part select (Vector2)

module top_module( 
    input [31:0] in,
    output [31:0] out );

    assign out[31:24] = in[7:0];
    assign out[23:16] = in[15:8];
    assign out[15:8] = in[23:16];
    assign out[7:0] = in[31:24];
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

● Bitwise operators (Vectorgates)

module top_module( 
    input [2:0] a,
    input [2:0] b,
    output [2:0] out_or_bitwise,
    output out_or_logical,
    output [5:0] out_not
);
    
    assign out_or_bitwise = a|b;
    assign out_or_logical = a||b;
    assign out_not = {~b,~a};
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

● Four-input gates (Gates4)

module top_module( 
    input [3:0] in,
    output out_and,
    output out_or,
    output out_xor
);
    
    //写法一
    /*assign out_and = in[3] & in[2] & in[1] & in[0];
    assign out_or = in[3] | in[2] | in[1] | in[0];
    assign out_xor = in[3] ^ in[2] ^ in[1] ^ in[0];*/
    
	//写法二
    assign out_and = ∈
    assign out_or = |in;
    assign out_xor = ^in;
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

注:将运算符&、|、^放在vari[msb,lsb]左边表示从msb位开始按位与、或、异或到lsb位,即:&vari==vari[msb]&…&vari[lsb]

● Vector concatenation operator (Vector3)

module top_module (
    input [4:0] a, b, c, d, e, f,
    output [7:0] w, x, y, z );//

    assign w = {a,b[4:2]};
    assign x = {b[1:0],c[4:0],d[4]};
    assign y = {d[3:0],e[4:1]};
    assign z = {e[0],f,2'b11};
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9

注:verilog的拼接操作:{in1,in2}

● Vector reversal 1 (Vectorr)

module top_module( 
    input [7:0] in,
    output [7:0] out
);
    
    assign out = {in[0],in[1],in[2],in[3],in[4],in[5],in[6],in[7]};
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

● Replication operator (Vector4)

module top_module (
    input [7:0] in,
    output [31:0] out );

    assign out = { {24{in[7]}},in };
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

注:verilog的复制操作:{n{in}}

● More replication (Vector5)

module top_module (
    input a, b, c, d, e,
    output [24:0] out );

    assign out = ~{ {5{a}},{5{b}},{5{c}},{5{d}},{5{e}} } ^ {5{a,b,c,d,e}};
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

2.3 Modules: Hierarchy

● Modules (Module)

module top_module ( input a, input b, output out );
    
	mod_a inst1(.in1(a),
                .in2(b),
                .out(out));
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

注:通过端口名称进行模块实例化(推荐此种方式)。

● Connecting ports by position (Module pos)

module top_module ( 
    input a, 
    input b, 
    input c,
    input d,
    output out1,
    output out2
);
    
    mod_a inst2(out1,out2,a,b,c,d);
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

注:通过端口位置进行模块实例化(不推荐此种方式,因为被实例化模块端口顺序改变后,实例化的端口也得改)。

● Connecting ports by name (Module name)

module top_module ( 
    input a, 
    input b, 
    input c,
    input d,
    output out1,
    output out2
);
    
    mod_a inst1(.in1(a),
                .in2(b),
                .in3(c),
                .in4(d),
                .out1(out1),
                .out2(out2)
               );
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17

● Three modules (Module shift)

module top_module (
	input clk,
	input d,
	output q );

   wire wire1;
   wire wire2;
   my_dff mod_a(
       .clk(clk),
       .d(d),
       .q(wire1));
   my_dff mod_b(
       .clk(clk),
       .d(wire1),
       .q(wire2));
   my_dff mod_c(
       .clk(clk),
       .d(wire2),
       .q(q));
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

● Modules and vectors (Module shift8)

module top_module ( 
    input clk, 
    input [7:0] d, 
    input [1:0] sel, 
    output [7:0] q 
);

    wire [7:0]wire1;
    wire [7:0]wire2;
    wire [7:0]wire3;
    my_dff8 moda(
        .clk(clk),
        .d(d),
        .q(wire1));
    my_dff8 modb(
        .clk(clk),
        .d(wire1),
        .q(wire2));
    my_dff8 modc(
        .clk(clk),
        .d(wire2),
        .q(wire3));
    
    always@(*)
    begin
       case(sel)
          2'b00:q=d;
          2'b01:q=wire1;
          2'b10:q=wire2;
          2'b11:q=wire3;
       	  default:q=d;
       endcase
    end
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34

● Adder 1 (Module add)

module top_module(
    input [31:0] a,
    input [31:0] b,
    output [31:0] sum
);

    wire cin_1,cin_2;
    assign cin_1 = 1'b0;
    add16 u1_add16(
        .a(a[15:0]),
        .b(b[15:0]),
        .cin(cin_1),//可直接写.cin(1'b0)
        .cout(cin_2),
        .sum(sum[15:0]));
    add16 u2_add16(
        .a(a[31:16]),
        .b(b[31:16]),
        .cin(cin_2),
        .cout(),
        .sum(sum[31:16]));
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

● Adder 2 (Module fadd)

module top_module (
    input [31:0] a,
    input [31:0] b,
    output [31:0] sum
);

    wire cout_l;
    add16 ul_add16(
        .a(a[15:0]),
        .b(b[15:0]),
        .sum(sum[15:0]),
        .cin(1'b0),
        .cout(cout_l));
    add16 uh_add16(
        .a(a[31:16]),
        .b(b[31:16]),
        .sum(sum[31:16]),
        .cin(cout_l),
        .cout());
endmodule

module add1 (input a,b,cin,
             output sum,cout );
	assign {cout,sum}=a+b+cin;
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25

● Carry-select adder (Module cseladd)

module top_module(
    input [31:0] a,
    input [31:0] b,
    output [31:0] sum
);

    wire carry;
    wire [15:0]sum_uh1;
    wire [15:0]sum_uh2;
    add16 ul_add16(
        .a(a[15:0]),
        .b(b[15:0]),
        .cin(1'b0),
        .sum(sum[15:0]),
        .cout(carry));
    add16 uh1_add_16(
        .a(a[31:16]),
        .b(b[31:16]),
        .cin(1'b0),
        .sum(sum_uh1),
        .cout());
    add16 uh2_add_16(
        .a(a[31:16]),
        .b(b[31:16]),
        .cin(1'b1),
        .sum(sum_uh2),
        .cout());
    assign sum=carry?{sum_uh2,sum[15:0]}:{sum_uh1,sum[15:0]};
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29

注:进位选择加法器,用面积换速度,高位加法器有两个,一个carry_in=0,一个carry_in=1,当低位加法器计算出carry_out后,通过选择器“瞬间”可以得到整个输入的结果。三目运算符:?:

● Adder-subtractor (Module addsub)

module top_module(
    input [31:0] a,
    input [31:0] b,
    input sub,
    output [31:0] sum
);

    wire [31:0] bxor;
    wire carry;
    assign bxor=b^{32{sub}};
    add16 add16_u1(
        .a(a[15:0]),
        .b(bxor[15:0]),
        .cin(sub),
        .sum(sum[15:0]),
        .cout(carry));
    add16 add16_u2(
        .a(a[31:16]),
        .b(bxor[31:16]),
        .cin(carry),
        .sum(sum[31:16]),
        .cout());
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

2.4 Procedures

● Always blocks (combinational) (Alwaysblock1)

// synthesis verilog_input_version verilog_2001
module top_module(
    input a, 
    input b,
    output wire out_assign,
    output reg out_alwaysblock
);

    assign out_assign = a & b;
    always@(*)
    begin
        out_alwaysblock = a & b;
    end
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14

注:assign左侧必须为线网类型,如wirealways过程块中左侧必须为变量类型,如reg

● Always blocks (clocked) (Alwaysblock2)

// synthesis verilog_input_version verilog_2001
module top_module(
    input clk,
    input a,
    input b,
    output wire out_assign,
    output reg out_always_comb,
    output reg out_always_ff   );
    
    assign out_assign = a ^ b;
    always@(*)
    begin
        out_always_comb = a ^ b;
    end
    always@(posedge clk)
    begin
        out_always_ff = a ^ b;
    end
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

注:组合电路用always@(*),时序电路用always@(posedge clk)

● If statement (Always if)

// synthesis verilog_input_version verilog_2001
module top_module(
    input a,
    input b,
    input sel_b1,
    input sel_b2,
    output wire out_assign,
    output reg out_always   ); 
    
    assign out_assign = (sel_b1==1 && sel_b2==1) ? b : a;
    
    always@(*)
    begin
        if (sel_b1==1 && sel_b2==1)
        begin
            out_always = b;
        end
        else
        begin
            out_always = a;
        end
    end
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23

注:三目运算符等于最基础的if-else

● If statement latches (Always if2)

// synthesis verilog_input_version verilog_2001
module top_module (
    input      cpu_overheated,
    output reg shut_off_computer,
    input      arrived,
    input      gas_tank_empty,
    output reg keep_driving  ); 

    always @(*) begin
        if (cpu_overheated)
           shut_off_computer = 1;
        else
           shut_off_computer = 0;
    end

    always @(*) begin
        if (arrived)
           keep_driving = 0;
        else if(gas_tank_empty)
           keep_driving = 0;
        else
           keep_driving = 1;
    end
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

注:verilog中if语句必须有else,否则容易产生锁存latch。

● Case statement (Always case)

// synthesis verilog_input_version verilog_2001
module top_module ( 
    input [2:0] sel, 
    input [3:0] data0,
    input [3:0] data1,
    input [3:0] data2,
    input [3:0] data3,
    input [3:0] data4,
    input [3:0] data5,
    output reg [3:0] out   );

    always@(*) 
    begin
        case(sel)
            3'd0:out = data0;
            3'd1:out = data1;
            3'd2:out = data2;
            3'd3:out = data3;
            3'd4:out = data4;
            3'd5:out = data5;
            default:out = 3'd0;
        endcase
    end
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24

注:verilog中case语句必须有default,否则也容易产生锁存latch。

● Priority encoder (Always case2)

// synthesis verilog_input_version verilog_2001
module top_module (
    input [3:0] in,
    output reg [1:0] pos  );
    
    always@(*)begin
    if(in[0]==1)
        pos = 2'd0;
    else if(in[1]==1)
        pos = 2'd1;
    else if(in[2]==1)
        pos = 2'd2;
    else if(in[3]==1)
        pos = 2'd3;
    else
        pos = 2'd0;
    end
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

● Priority encoder with casez (Always casez)

// synthesis verilog_input_version verilog_2001
module top_module (
    input [7:0] in,
    output reg [2:0] pos );
    
    always@(*)begin
        casez(in)
            8'bzzzz_zzz1: pos= 3'd0;
            8'bzzzz_zz10: pos= 3'd1;
            8'bzzzz_z100: pos= 3'd2;
            8'bzzzz_1000: pos= 3'd3;
            8'bzzz1_0000: pos= 3'd4;
            8'bzz10_0000: pos= 3'd5;
            8'bz100_0000: pos= 3'd6;
            8'b1000_0000: pos= 3'd7;
            default: pos= 3'd0;
        endcase
    end
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19

注:case:完全匹配为1casez:某位的值为z则忽略,casex:某位的值为xz则忽略。一般经常用casez,慎用casex

● Avoiding latches (Always nolatches)

// synthesis verilog_input_version verilog_2001
module top_module (
    input [15:0] scancode,
    output reg left,
    output reg down,
    output reg right,
    output reg up  ); 
    
    always@(*)begin
        left = 0; down = 0;
        right = 0; up = 0;
        case(scancode)
            16'he06b:begin
                left = 1; down = 0;
                right = 0; up = 0;
                end
            16'he072:begin
                left = 0; down = 1;
                right = 0; up = 0;
                end
            16'he074:begin
                left = 0; down = 0;
                right = 1; up = 0;
                end
            16'he075:begin
                left = 0; down = 0;
                right = 0; up = 1;
                end
            default:begin
                left = 0; down = 0;
                right = 0; up = 0;
                end
        endcase
    end
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35

2.5 More Verilog Features

● Conditional ternary operator (Conditional)

module top_module (
    input [7:0] a, b, c, d,
    output [7:0] min);
    
    wire [7:0] compare_ab, compare_cd;
    always@(*)begin
        compare_ab = a<b?a:b;
        compare_cd = c<d?c:d;
        min = compare_ab<compare_cd?compare_ab:compare_cd;
    end
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

● Reduction operators (Reduction)

module top_module (
    input [7:0] in,
    output parity); 
    
    assign parity = ^in[7:0];
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6

注:奇偶校验,偶校验用异或:^,奇校验用同或:~^

● Reduction: Even wider gates (Gates100)

module top_module( 
    input [99:0] in,
    output out_and,
    output out_or,
    output out_xor 
);

    assign out_and = &in[99:0];
    assign out_or = |in[99:0];
    assign out_xor = ^in[99:0];
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

● Combinational for-loop: Vector reversal 2 (Vector100r)

module top_module( 
    input [99:0] in,
    output [99:0] out
);

    integer i;
    always@(*)begin
        out = 0;
        for(i=0;i<100;i=i+1)begin
            out[i] = in[99-i];
        end
    end
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13

注:verilog中for循环的循环变量定义为integer类型。

● Combinational for-loop: 255-bit population count (Popcount255)

module top_module( 
    input [254:0] in,
    output [7:0] out );
    
    integer i;
    always@(*)begin
        out = 0;
        for(i=0;i<255;i=i+1)begin
            if(in[i]==1'b1)begin
                out = out + 1'b1;
            end else begin
                out = out;
            end
        end
    end
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16

● Generate for-loop: 100-bit binary adder 2 (Adder100i)

//方法一:generate-for
/*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:RIPPLE_CARRY_ADDER
            if(i==0)begin
                full_adder_1 fadder1(
                    .a(a[i]),
                    .b(b[i]),
                    .cin(cin),
                    .sum(sum[i]),
                    .cout(cout[i]));
            end else begin
                full_adder_1 fadder1(
                    .a(a[i]),
                    .b(b[i]),
                    .cin(cout[i-1]),
                    .sum(sum[i]),
                    .cout(cout[i]));
            end
        end
    endgenerate
endmodule

module full_adder_1(
    input a,b,cin,
    output cout,sum);
    assign {cout,sum}=a+b+cin;
endmodule*/

//方法二:数组实例化
module top_module(
        input [99:0] a, b,
        input cin,
        output [99:0] cout,
        output [99:0] sum );
        
        full_adder_1 fadd1_inst[99:0](
            .a(a),
            .b(b),
            .cin({cout[98:0],cin}),
            .sum(sum),
            .cout(cout));
endmodule

module full_adder_1(
    input a,b,cin,
    output cout,sum);
    assign {cout,sum}=a+b+cin;
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55

注:同个模块多次实例化:使用generate-for循环结构或者使用数组实例化。generate-for循环结构中循环变量定义为genvar类型,且循环位于generate块内,for后的begin需接名字(标识)。数组实例化与常规实例化的区别在于实例名后需接循环数组长度,后续端口矢量长度需要与之匹配。

● Generate for-loop: 100-digit BCD adder (Bcdadd100)

module top_module( 
    input [399:0] a, b,
    input cin,
    output cout,
    output [399:0] sum );
    reg [99:0]cout_t;
    
    /*//方法一:利用generate-for
    genvar i;
    generate
        for(i=0;i<100;i=i+1)begin:BCDAdd100
            if(i==0)begin
                bcd_fadd bcdfadd_inst(
                    .a(a[3:0]),
                    .b(b[3:0]),
                    .cin(cin),
                    .sum(sum[3:0]),
                    .cout(cout_t[0]));
            end else begin
                bcd_fadd bcdfadd_inst(
                    .a(a[i*4+3:i*4]),
                    .b(b[i*4+3:i*4]),
                    .cin(cout_t[i-1]),
                    .sum(sum[i*4+3:i*4]),
                    .cout(cout_t[i]));
            end
        end
    endgenerate
    assign cout=cout_t[99];*/
    
    //方法二:利用数组实例化
    bcd_fadd bcdfadd_inst[99:0](
        .a(a[399:0]),
        .b(b[399:0]),
        .cin({cout_t[98:0],cin}),
        .sum(sum[399:0]),
        .cout(cout_t[99:0]));
    assign cout=cout_t[99];
endmodule
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39

注:for循环中的a[i*4+3:i*4]是允许的,因为对于每次循环而言,i为一个定值。也可以用a[i*4+3-:4]代替。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/我家自动化/article/detail/648870
推荐阅读
相关标签
  

闽ICP备14008679号