【Verilog】HDLBits题解——Verilog Language

Basics

  • Simple wire

题目链接

module top_module( input in, output out );
	assign out = in;
endmodule
  • Four wires

题目链接

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
  • Inverter

题目链接

module top_module( input in, output out );
	assign out = ~in;
endmodule

  • AND gate

题目链接

module top_module( 
    input a, 
    input b, 
    output out );
	assign out = a & b;
endmodule
  • NOR gate

题目链接

module top_module( 
    input a, 
    input b, 
    output out );
    assign out = ~(a | b);
endmodule

  • XNOR gate

题目链接

module top_module( 
    input a, 
    input b, 
    output out );
    assign out = ~(a ^ b);
endmodule

  • Declaring wires

题目链接

`default_nettype none
module top_module(
    input a,
    input b,
    input c,
    input d,
    output out,
    output out_n   ); 
	wire twowires_a, twowires_b,onewire;
    assign twowires_a = a & b;
    assign twowires_b = c & d;
    assign onewire = twowires_a | twowires_b;
    assign out = onewire;
    assign out_n = ~onewire;
endmodule

  • 7458 chip

7458题目链接

module top_module ( 
    input p1a, p1b, p1c, p1d, p1e, p1f,
    output p1y,
    input p2a, p2b, p2c, p2d,
    output p2y );
    assign p1y = (p1c & p1b & p1a) | (p1f & p1e & p1d);
    assign p2y = (p2a & p2b) | (p2c & p2d);

endmodule

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[2:0];
    assign o2 = vec[2];
    assign o1 = vec[1];
    assign o0 = vec[0];
endmodule

  • 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 = in[15:8];
    assign out_lo = in[7:0];
endmodule

  • Vector part select

Vector2题目链接

module top_module( 
    input [31:0] in,
    output [31:0] out );//
	
    // assign out[31:24] = ...;
    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

  • 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[2:0] = b[2:0] | a[2:0];
    assign out_or_logical = b || a;
    assign out_not[5:0] = {~b[2:0], ~a[2:0]};
endmodule

  • 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:0];
    assign out_or = |in[3:0];
    assign out_xor = ^in[3:0];
endmodule

  • Vector concatenation operator

Vector3题目链接

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

    // assign { ... } = { ... };
    assign w = {a[4:0],b[4:2]};
    assign x = {b[1:0],c[4:0],d[4:4]};
    assign y = {d[3:0],e[4:1]};
    assign z = {e[0:0],f[4:0],2'b11};
endmodule

  • 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

  • Replication operator

Vector4题目链接

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

    // assign out = { replicate-sign-bit , the-input };
    assign out = {{25{in[7]}}, in[6:0]};
endmodule

  • More replication

Vector5题目链接

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

    // The output is XNOR of two vectors created by 
    // concatenating and replicating the five inputs.
    // assign out = ~{ ... } ^ { ... };
    assign out = ~{{5{a,b,c,d,e}}} ^ {{5{a}}, {5{b}}, {5{c}}, {5{d}}, {5{e}}};
endmodule

Modules: Hierarchy

  • Modules

Module题目链接

module top_module ( input a, input b, output out );
    mod_a mod_a_instance(
        .in1(a),
        .in2(b),
        .out(out)
    );
endmodule

  • Connecting ports by position

Module pos题目链接

module top_module ( 
    input a, 
    input b, 
    input c,
    input d,
    output out1,
    output out2
);
    mod_a mod_a_instance(out1, out2, a, b, c, d);

endmodule

  • Connecting ports by name

Module name题目链接

module top_module ( 
    input a, 
    input b, 
    input c,
    input d,
    output out1,
    output out2
);
    mod_a mod_a_instance ( .out1(out1), .out2(out2), .in1(a), .in2(b), .in3(c), .in4(d));
endmodule

  • Three modules

Module shift题目链接

module top_module ( input clk, input d, output q );
    wire q_1,q_2;
    my_dff my_dff_instance1(.clk(clk), .d(d), .q(q_1));
    my_dff my_dff_instance2(.clk(clk), .d(q_1), .q(q_2));
    my_dff my_dff_instance3(.clk(clk), .d(q_2), .q(q));
endmodule

  • 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] q_1,q_2,q_3;
    my_dff8 my_dff8_instance1(.clk(clk), .d(d), .q(q_1));
    my_dff8 my_dff8_instance2(.clk(clk), .d(q_1), .q(q_2));
    my_dff8 my_dff8_instance3(.clk(clk), .d(q_2), .q(q_3));
    
    always@(*) begin
        case(sel[1:0])
            2'b00: q <= d[7:0];
            2'b01: q <= q_1[7:0];
            2'b10: q <= q_2[7:0];
            2'b11: q <= q_3[7:0];
        endcase
    end

endmodule

  • Adder 1

Module add题目链接

module top_module(
    input [31:0] a,
    input [31:0] b,
    output [31:0] sum
);
    wire cout_1;
    wire cout_2;
    add16 add16_instance1(.a(a[15:0]), .b(b[15:0]), .cin(1'b0), .sum(sum[15:0]), .cout(cout_1));
    add16 add16_instance2(.a(a[31:16]), .b(b[31:16]), .cin(cout_1), .sum(sum[31:16]), .cout(cout_2));
endmodule

  • Adder 2

Module fadd题目链接

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

/*module add16 (input [15:0] a, input [15:0] b, input cin, output [15:0] sum, output cout);
    wire [15:0] cout_wire;
    add1 add1_instance1(.a(a[0]), .b(b[0]), .cin(0), .sum(sum[0]), .cout(cout_wire[0]));
    add1 add1_instance2(.a(a[1]), .b(b[1]), .cin(cout_wire[0]), .sum(sum[1]), .cout(cout_wire[1]));
    add1 add1_instance3(.a(a[2]), .b(b[2]), .cin(cout_wire[1]), .sum(sum[2]), .cout(cout_wire[2]));
    add1 add1_instance4(.a(a[3]), .b(b[3]), .cin(cout_wire[2]), .sum(sum[3]), .cout(cout_wire[3]));
    add1 add1_instance5(.a(a[4]), .b(b[4]), .cin(cout_wire[3]), .sum(sum[4]), .cout(cout_wire[4]));
    add1 add1_instance6(.a(a[5]), .b(b[5]), .cin(cout_wire[4]), .sum(sum[5]), .cout(cout_wire[5]));
    add1 add1_instance7(.a(a[6]), .b(b[6]), .cin(cout_wire[5]), .sum(sum[6]), .cout(cout_wire[6]));
    add1 add1_instance8(.a(a[7]), .b(b[7]), .cin(cout_wire[6]), .sum(sum[7]), .cout(cout_wire[7]));
    add1 add1_instance9(.a(a[8]), .b(b[8]), .cin(cout_wire[7]), .sum(sum[8]), .cout(cout_wire[8]));
    add1 add1_instance10(.a(a[9]), .b(b[9]), .cin(cout_wire[8]), .sum(sum[9]), .cout(cout_wire[9]));
    add1 add1_instance11(.a(a[10]), .b(b[10]), .cin(cout_wire[9]), .sum(sum[10]), .cout(cout_wire[10]));
    add1 add1_instance12(.a(a[11]), .b(b[11]), .cin(cout_wire[10]), .sum(sum[11]), .cout(cout_wire[11]));
    add1 add1_instance13(.a(a[12]), .b(b[12]), .cin(cout_wire[11]), .sum(sum[12]), .cout(cout_wire[12]));
    add1 add1_instance14(.a(a[13]), .b(b[13]), .cin(cout_wire[12]), .sum(sum[13]), .cout(cout_wire[13]));
    add1 add1_instance15(.a(a[14]), .b(b[14]), .cin(cout_wire[13]), .sum(sum[14]), .cout(cout_wire[14]));
    add1 add1_instance16(.a(a[15]), .b(b[15]), .cin(cout_wire[14]), .sum(sum[15]), .cout(cout_wire[15]));
endmodule*/

module add1 ( input a, input b, input cin, output sum, output cout);
// Full adder module here
    assign cout = (a && b) || (a && cin) || (b && cin);
    assign sum = (a && ~b && ~cin) || (~a && ~b && cin) || (~a && b && ~cin)|| (a && b && cin);
endmodule

  • Carry-select adder

Module cseladd题目链接

module top_module(
    input [31:0] a,
    input [31:0] b,
    output [31:0] sum
);
    wire sel;
    wire [15:0] output1,output2;
    add16 add16_instance1(.a(a[15:0]), .b(b[15:0]), .cin(0), .sum(sum[15:0]), .cout(sel));
    add16 add16_instance2(.a(a[31:16]), .b(b[31:16]), .cin(0), .sum(output1));
    add16 add16_instance3(.a(a[31:16]), .b(b[31:16]), .cin(1), .sum(output2));
    
    always@* begin
        case(sel)
            0: sum[31:16] = output1;
            1: sum[31:16] = output2;
        endcase
    end
endmodule

  • Adder-subtractor

Module addsub题目链接

module top_module(
    input [31:0] a,
    input [31:0] b,
    input sub,
    output [31:0] sum
);
    wire [31:0] b_in;
    wire cout_1;
    assign b_in = b[31:0] ^ {32{sub}};
    
    add16 add16_instance1(.a(a[15:0]), .b(b_in[15:0]), .cin(sub), .sum(sum[15:0]), .cout(cout_1));
    add16 add16_instance2(.a(a[31:16]), .b(b_in[31:16]), .cin(cout_1), .sum(sum[31:16]));
endmodule

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

  • 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@* out_always_comb <= a ^ b;
    always@(posedge clk) out_always_ff <= a ^ b;
endmodule

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

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

endmodule

  • 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  // This is a combinational circuit
        case(sel[2:0])
            3'd0: out <= data0[3:0];
            3'd1: out <= data1[3:0];
            3'd2: out <= data2[3:0];
            3'd3: out <= data3[3:0];
            3'd4: out <= data4[3:0];
            3'd5: out <= data5[3:0];
            default: out <= 4'b0;
        endcase
    end

endmodule

  • Priority encoder

Always case 2题目链接

// synthesis verilog_input_version verilog_2001
module top_module (
    input [3:0] in,
    output reg [1:0] pos  );
	
    always@* begin
        case(in[3:0])
            0: pos <= 0;
            1: pos <= 0;
            2: pos <= 1;
            3: pos <= 0;
            4: pos <= 2;
            5: pos <= 0;
            6: pos <= 1;
            7: pos <= 0;
            8: pos <= 3;
            9: pos <= 0;
            10: pos <= 1;
            11: pos <= 0;
            12: pos <= 2;
            13: pos <= 0;
            14: pos <= 1;
            15: pos <= 0;
            
        endcase
        
    end
    
endmodule

  • 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'bzzzzzzz1: pos <= 3'd0;
            8'bzzzzzz1z: pos <= 3'd1;
            8'bzzzzz1zz: pos <= 3'd2;
            8'bzzzz1zzz: pos <= 3'd3;
            8'bzzz1zzzz: pos <= 3'd4;
            8'bzz1zzzzz: pos <= 3'd5;
            8'bz1zzzzzz: pos <= 3'd6;
            8'b1zzzzzzz: pos <= 3'd7;
			default: pos <= 3'd0;
       	endcase
    end
endmodule

  • 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
        up = 1'b0; down = 1'b0; left = 1'b0; right = 1'b0;
        case (scancode)
            16'he06b: left <= 1;
            16'he072: down <= 1;
            16'he074: right <= 1;
            16'he075: up <= 1;
        endcase
    end
endmodule

More Verilog Features

  • Conditional ternary operator

Conditional题目链接

module top_module (
    input [7:0] a, b, c, d,
    output [7:0] min);//

    // assign intermediate_result1 = compare? true: false;
    wire [7:0] min_a_b, min_c_d;
    assign min_a_b = (a>b) ? b : a;
    assign min_c_d = (c>d) ? d : c;
    assign min = (min_a_b>min_c_d) ? min_c_d : min_a_b;
endmodule

  • Reduction operators

Reduction题目链接

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

  • 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

  • Combinational for-loop: Vector reversal 2

Vector100r题目链接

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

  • Combinational for-loop: 255-bit population count

Popcount255题目链接

module top_module( 
    input [254:0] in,
    output [7:0] out );
	
    
    always@* begin
        integer i;
        out = 8'b0;
        for(i = 0; i < $bits(in); i++) begin
            if(in[i] == 1) begin
                out = out[7:0] + 8'b1;
            end
        end
    end
endmodule

  • Generate for-loop: 100-bit binary adder 2

Adder100i题目链接

module top_module( 
    input [99:0] a, b,
    input cin,
    output [99:0] cout,
    output [99:0] sum );
    
    always@* begin
        integer i = 0;
        cout[0] = (a[0] && b[0]) || (a[0] && cin) || (b[0] && cin);
        sum[0] = a[0] ^ b[0] ^ cin;
        for(i = 1; i < $bits(a); i++) begin
            cout[i] = (a[i] && b[i]) || (a[i] && cout[i-1]) || (b[i] && cout[i-1]);
            sum[i] = a[i] ^ b[i] ^ cout[i-1];
        end
    end
endmodule

  • Generate for-loop: 100-digit BCD adder

Bcdadd100题目链接

module top_module( 
    input [399:0] a, b,
    input cin,
    output cout,
    output [399:0] sum );
    
	genvar i;
    wire [100:0] cin_wire;
    assign cin_wire[0] = cin;
    assign cout = cin_wire[100];
    generate
        for(i=0;i<100;i=i+1) begin : bcd_fadd_inst_for
            bcd_fadd bcd_fadd_inst (
                .a(a[4*i + 3:4*i]),
                .b(b[4*i + 3:4*i]),
                .cin(cin_wire[i]),
                .cout(cin_wire[i+1]),
                .sum(sum[4*i + 3:4*i]));
        end
    endgenerate
    
endmodule

你可能感兴趣的:(#,Verilog入门,HDLBits,Verilog,题解)