Verilog案例


1、用verilog HDL设计一个4位加法器树乘法器

`timescale 1ns/10ps
module mul_addtree(mul_a,mul_b,mul_out);
    input [3:0] mul_a,mul_b;          //IO端口声明
    output [7:0] mul_out;
    
    wire [7:0] mul_out;               //连线类型声明
    wire [7:0] store0,store1,store2,store3;
    wire [7:0] add01,add23;
    
    assign store0 = mul_b[0]?{4'b0000,mul_a}:8'b0000_0000;
    assign store1 = mul_b[1]?{3'b000,mul_a,1'b0}:8'b0000_0000;
    assign store2 = mul_b[2]?{2'b00,mul_a,2'b00}:8'b0000_0000;
    assign store3 = mul_b[3]?{1'b0,mul_a,3'b000}:8'b0000_0000;
    assign add01 = store0+store1;
    assign add23 = store2+store3;
    assign mul_out = add01+add23;
endmodule

//*****************testbench of mul_addtree******************
module mul_addtree_tb;
    wire [7:0] mul_out;               //输出是wire
    reg [3:0] mul_a;                  //输入是reg 
    reg [3:0] mul_b;
    
    //模块例化
    mul_addtree U(.mul_a(mul_a),.mul_b(mul_b),.mul_out(mul_out));
    
    //测试信号
    initial
        begin
            mul_a=4'b0;mul_b=4'b0;
            repeat(9)
                begin
                    #20 mul_a = mul_a+1'b1;mul_b = mul_b+1'b1;
                end
        end
endmodule

 2、用verilog HDL设计一个两级流水线4位加法器树乘法器

`timescale 1ns/10ps
module mul_addtree2(clk,clr,mul_a,mul_b,mul_out);

    input clk,clr;
    input [3:0] mul_a,mul_b;                    //IO端口声明
    output [7:0] mul_out;
    
    reg [7:0] add_tmp1,add_tmp2,mul_out;        //连线类型声明
    wire [7:0] store0,store1,store2,store3;
    
    assign store0 = mul_b[0]?{4'b0000,mul_a}:8'b0000_0000;   //逻辑设计
    assign store1 = mul_b[1]?{3'b000,mul_a,1'b0}:8'b0000_0000;
    assign store2 = mul_b[2]?{2'b00,mul_a,2'b00}:8'b0000_0000;
    assign store3 = mul_b[3]?{1'b0,mul_a,3'b000}:8'b0000_0000;
    
    always@(posedge clk or negedge clr)
    begin
        if(!clr) begin             //注意使用非阻塞语句
            add_tmp1 <= 8'b0;
            add_tmp2 <= 8'b0;
            mul_out <= 8'b0;
        end
        else begin
           add_tmp1 <= store2+store3;
            add_tmp2 <= store1+store0;
            mul_out <= add_tmp1+add_tmp2;
        end
    end
endmodule

//*****************testbench of mul_addtree******************
module mul_addtree2_tb;
    wire [7:0] mul_out;               //输出是wire
    reg [3:0] mul_a;                  //输入是reg 
    reg [3:0] mul_b;
    reg clk,clr;
    
    //模块例化
    mul_addtree2 U(.mul_a(mul_a),.mul_b(mul_b),.mul_out(mul_out),.clk(clk),.clr(clr));
    
    //测试信号
    initial
        begin
            clk=0;clr=0;mul_a=1;mul_b=1;
            #5 clr=1;
        end
        
    always #10 clk=~clk;
    
    initial
        begin
            repeat(5)
            begin
                #20 mul_a = mul_a+1;mul_b = mul_b+1;
            end 
        end
endmodule

 3、用verilog HDL 设计4位wallace树乘法器

1)从数据最多的那一列开始,用半加器将数据最多的那一列中的两个数相加,得到和a0以及向高列的进位b0;

这时得到进位的那一列也有四个数据,我们也用半加器相加得到积a1和进位b0

2)用半加器和全加器反复压缩覆盖所有数据超过三个的列,得到下表所示的数据

3)最后采用简单的2输入加法器,就可以得到相乘结果了

module wallace(x,y,out);
    input [3:0] x,y;        //IO端口声明
    output [7:0] out;
    
    wire [7:0] out;       //连线类型声明
    wire [15:0] a;        
    wire [1:0] out1,out2,out3,out4,out5,out6;
    wire [6:0] add1,add2;
    
    assign a = {x[0],x[1],x[2],x[3],x[0],x[1],x[2],x[3],x[0],x[1],x[2],x[3],x[0],x[1],x[2],x[3]}
              &{y[0],y[0],y[0],y[0],y[1],y[1],y[1],y[1],y[2],y[2],y[2],y[2],y[3],y[3],y[3],y[3]};
                 
    //第一级 2个半加器
    Hadd U1(.x(a[3]),.y(a[6]),.out(out1));
    Hadd U2(.x(a[2]),.y(a[5]),.out(out2));
    
    //第二级 3个全加器+1个半加器
    Hadd U3(.x(a[7]),.y(a[10]),.out(out3));
    Fadd U4(.x(a[12]),.y(a[9]),.c(out1[0]),.out(out4));
    Fadd U5(.x(a[8]),.y(out2[0]),.c(out1[1]),.out(out5));
    Fadd U6(.x(a[4]),.y(a[1]),.c(out2[1]),.out(out6));
    
    assign add1 = {a[0],out6[0],out5[0],out4[0],a[13],a[14],a[15]};
    assign add2 = {out6[1],out5[1],out4[1],out3[1],out3[0],a[11],1'b0};
    assign out = add1+add2;
endmodule

module Hadd(x,y,out);
    input x,y;
    output [1:0] out;
    assign out = x+y;
endmodule

module Fadd(x,y,c,out);
    input x,y,c;
    output [1:0] out;
    assign out = x+y+c;
endmodule

//*************测试代码***************
module wallace_tb;
    reg [3:0] x,y;
    wire [7:0] out;
    
    wallace U(.x(x),.y(y),.out(out));
    
    initial
    begin
        x=3;y=4;
        #20 x=2;y=3;
        #20 x=6;y=8;
    end
endmodule

相关