HDLBits 习题练习

Modules:Hierarchy

Modules and vectors

module top_module ( 
    input clk, 
    input [7:0] d, 
    input [1:0] sel, 
    output [7:0] q 
);
    wire [0:7]q0,q1,q2;
    my_dff8 my_dff8_1(.clk(clk),.d(d),.q(q0));
    my_dff8 my_dff8_2(.clk(clk),.d(q0),.q(q1));
    my_dff8 my_dff8_3(.clk(clk),.d(q1),.q(q2));
    always@(*)
        begin
            case(sel)
                0:q=d;
                1:q=q0;
                2:q=q1;
                3:q=q2;
            endcase
        end
endmodule

Adder 1

module top_module(
    input [31:0] a,
    input [31:0] b,
    output [31:0] sum
);
    wire cout;
    add16 add16_1(.a(a[15:0]),.b(b[15:0]),.cin(0),.cout(cout),.sum(sum[15:0]));
    add16 add16_2(.a(a[31:16]),.b(b[31:16]),.cin(cout),.cout(),.sum(sum[31:16]));
endmodule

Adder 2

module top_module (
    input [31:0] a,
    input [31:0] b,
    output [31:0] sum
);//
     wire cout;
    add16 add16_1(.a(a[15:0]),.b(b[15:0]),.cin(0),.cout(cout),.sum(sum[15:0]));
    add16 add16_2(.a(a[31:16]),.b(b[31:16]),.cin(cout),.cout(),.sum(sum[31:16]));
endmodule

   
module add1 ( input a, input b, input cin,   output sum, output cout );
    assign{cout,sum}=a+b+cin;    
// Full adder module here

endmodule

Carry-select adder

module top_module(
    input [31:0] a,
    input [31:0] b,
    output [31:0] sum
);
    wire cout;
    wire [15:0] x,y;
    add16 add16_1(.a(a[15:0]),.b(b[15:0]),.cin(0),.cout(cout),.sum(sum[15:0]));
    add16 add16_2(.a(a[31:16]),.b(b[31:16]),.cin(0),.cout(),.sum(y));
    add16 add16_3(.a(a[31:16]),.b(b[31:16]),.cin(1),.cout(),.sum(x));
    assign sum[31:16]=cout?x:y;
    
endmodule

Adder-substractor

module top_module(
    input [31:0] a,
    input [31:0] b,
    input sub,
    output [31:0] sum
);
reg [31:0]b_1;
wire cout;
 assign b_1=b^{32{sub}};
    //xor(b_1,b,{32{sub}});写成这样运行结果不对//
add16 add16_1( .a(a[15:0]),.b(b_1[15:0]),.cin(sub),.cout(cout),.sum(sum[15:0]));
add16 add16_2( .a(a[31:16]),.b(b_1[31:16]),.cin(cout),.cout(),.sum(sum[31:16]));
endmodule

 Procedures

Always block (combination)


module top_module(
    input a, 
    input b,
    output wire out_assign,
    output reg out_alwaysblock
);
    and(out_assign,a,b);
    always@(*)
        begin
            out_alwaysblock=a&b;
        end
endmodule

Always blocks (clocked)

module top_module(
    input clk,
    input a,
    input b,
    output wire out_assign,
    output reg out_always_comb,
    output reg out_always_ff   );
    xor(out_assign,a,b);
    always@(*)begin
        out_always_comb=a^b;
    end
    always@(posedge clk)begin
       out_always_ff<=a^b;
    end
endmodule

if statement

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&sel_b2)?b:a;
    always@(*)
        begin
            if(sel_b1&sel_b2)
                out_always=b;
            else
                out_always=a;
        end
endmodule

if statement latches

// 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 = ~gas_tank_empty;
        else
          keep_driving = 0;  
    end

endmodule

 case statement

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  // This is a combinational circuit
        case(sel)
            3'b000:out=data0;
            3'b001:out=data1;
            3'b010:out=data2;
            3'b011:out=data3;
            3'b100:out=data4;
            3'b101:out=data5;
            default:out=1'b0;
        endcase     
            
    end

endmodule

priority encoder

 4-2优先编码器

module top_module (
    input [3:0] in,
    output reg [1:0] pos  );
    always@(*)begin
        if (in[0]==1)           //case(1'b1)
            pos=2'b00;          //in[0]:pos=0;
        else if(in[1]==1)       //in[1]:pos=1;
            pos=2'b01;          //in[2]:pos=2;
        else if(in[2]==1)       //in[3]:pos=3;
            pos=2'b10;           //default:pos=0;
        else if(in[3]==1)        //endcase
            pos=2'b11;
        else
            pos=2'b00;
    end
endmodule

priority encoder with casez

有不确定状态的时候要用casez

module top_module (
    input [7:0] in,
    output reg [2:0] pos  );
    always@(*)begin
        casez(in[7:0])
            8'bzzzzzzz1:pos=0;
            8'bzzzzzz10:pos=1; 
            8'bzzzzz100:pos=2;
            8'bzzzz1000:pos=3;
            8'bzzz10000:pos=4;
            8'bzz100000:pos=5;
            8'bz1000000:pos=6;
            8'b10000000:pos=7;
            default:pos=0;
       endcase 
    end        
endmodule

 Avoiding latches

为了避免产生锁存器,所有的输出都必须在所有可能的条件下被分配一个值。仅仅拥有一个默认情况是不够的。你必须在所有四种情况下和默认情况下为所有四个输出赋值。这可能涉及到很多不必要的输入。一个简单的方法是在case语句之前给输出分配一个 "默认值"。

module top_module (
    input [15:0] scancode,
    output reg left,
    output reg down,
    output reg right,
    output reg up  ); 
    always@(*)begin
        up=1'b0;down=1'b0;left=1'b0;right=1'b0;
        case(scancode)
            16'he06b:left=1'b1;
            16'he072:down=1'b1;
            16'he074:right=1'b1;
            16'he075:up=1'b1;
            default:;
        endcase
    end
endmodule

 condition ternary operator

module top_module (
    input [7:0] a, b, c, d,
    output [7:0] min);//输出四个数中最小的那一个
    wire [7:0]min1,min2;
    always@(*)begin
        min1=(a<b)?a:b;
        min2=(c<d)?c:d;
        min=(min1<min2)?min1:min2;
    end
    // assign intermediate_result1 = compare? true: false;

endmodule

 Reduction operators

为一个8位字节计算一个奇偶校验位(这将为该字节增加一个第9位)。我们将使用 "偶数 "奇偶校验,其中奇偶校验位只是所有8个数据位的XOR。

& a[3:0] // AND: a[3]&a[2]&a[1]&a[0]. Equivalent to (a[3:0] == 4’hf)
| b[3:0] // OR: b[3]|b[2]|b[1]|b[0]. Equivalent to (b[3:0] != 4’h0)
^ c[2:0] // XOR: c[2]^c[1]^c[0]

module top_module (
    input [7:0] in,
    output parity); 
   assign parity=^in[7:0];
endmodule

Reduction:Even wider gates

Build a combinational circuit with 100 inputs, in[99:0].

There are 3 outputs:

  • out_and: output of a 100-input AND gate.
  • out_or: output of a 100-input OR gate.
  • out_xor: output of a 100-input XOR gate.
    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

Combination for-loop vector reversal 2

输入100bit位的数据,讲这个数据的输入位顺序翻转

module top_module( 
    input [99:0] in,
    output [99:0] out
);
    integer i;
    always@(*)begin
        for(i=0;i<100;i=i+1)
            out[i]<=in[99-i];
    end
endmodule

Combination for-loop:255-bit population count

输出输入向量中1的个数

module top_module( 
    input [254:0] in,
    output [7:0] out );
  
integer n,k;
    always@(*)begin
        k=1'b0;//需要先给k一个值,避免出现latches
        for(n=0;n<255;n=n+1)begin
            if (in[n]==1)
                k=k+1;
        else k=k;
        out=k;
        end
    end
endmodule

Generate for-loop:100-bit binary adder2 

通过实例化100个全加器来创建一个100位的二进制行波进位加法器。该加法器将两个100位的数字和一个进位相加,产生一个100位的和进位。

全加器的实现:

  1. assign s = a ^ b ^ cin;

  2. assign cout = a & b | (cin & (a ^ b));

       module top_module( 
        input [99:0] a, b,
        input cin,
        output [99:0] cout,
        output [99:0] sum );
     
        integer i;
        always@(*)begin
            {cout[0],sum[0]} = a[0]+b[0]+cin; 
            for(i=1;i< 100;i=i+1)begin
                {cout[i],sum[i]} = a[i]+b[i]+cout[i-1];
            end
        end
    
    endmodule
    module top_module( 
        input [99:0] a, b,
        input cin,
        output [99:0] cout,
        output [99:0] sum );
        
       reg [100:0]C;
       genvar i;
       assign C[0]=cin;
       assign cout=C[100:1];
        
        generate
            for(i=0;i<=99;i=i+1)
                begin:addbit
                    fulladd stage(C[i],a[i],b[i],sum[i],C[i+1]); 
            end
        endgenerate
        
    endmodule
    
    module fulladd(cin,a,b,sum,cout);
        input a,b,cin;
        output sum,cout;
        assign sum=a^b^cin;
        assign cout = a & b | (cin & (a ^ b));
    
     endmodule

    Generate for-loop:100-bit binary adder2

    module top_module( 
        input [399:0] a, b,
        input cin,
        output cout,
        output [399:0] sum );
        wire[99:0]	cout_1;
    
         generate 
          genvar i;
             for(i=0;i<=99;i=i+1)begin:adder
                 if(i==0)begin
              bcd_fadd fadd_1(
                  .a(a[3:0]),
                  .b(b[3:0]),
                  .cin(cin),
                  .cout	(cout_1[0]),
                  .sum(sum[3:0])
              );
               end
                  else begin
                   bcd_fadd bcd_2(
        				.a(a[4*i+3:4*i]),
                		.b(b[4*i+3:4*i]),
                       .cin(cout_1[i-1]),
                       .cout(cout_1[i]),
                    .sum(sum[4*i+3:4*i]) 
      					);
                  end
                      end
        assign cout = cout_1[99];	
     	endgenerate
    
    endmodule

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值