HDLBits答案第二波verilog语言——Verilog Language

目录

Verilog Language

Vectors

Vectors

Vectors in more detail

Vector part select

Bitwise operators

Four-input gates

Vector concatenation operator

Vector reversal 1

Replication operator

More replication

Modules: Hierarchy

Modules

Connecting ports by position

Connecting ports by name

Three modules

Modules and vectors

Adder 1

Adder 2

Carry-select adder

Adder-subtractor

Procedures

Always blocks (combinational)

Always blocks (clocked)

If statement

If statement latches

Case statement

Priority encoder

Priority encoder with casez

Avoiding latches

More Verilog Features

Conditional ternary operator

Reduction operators

Reduction: Even wider gates

Combinational for-loop: Vector reversal 2

Combinational for-loop: 255-bit population count

Generate for-loop: 100-bit binary adder 2

Generate for-loop: 100-digit BCD adder


代码中有些根据自己的理解做了一下注释

Verilog Language

Vectors

Vectors

module top_module ( 
    input wire [2:0] vec,
    output wire [2:0] outv,
    output wire o2,
    output wire o1,
    output wire o0  ); // 模块主体在模块声明后开始
    assign outv = vec;
    assign {o2,o1,o0} = vec;
endmodule

Vectors in more detail

`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

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

    assign out[31:24] = in[7:0];   //将输入的低8位赋给输出的高8位
    assign out[23:16] = in[15:8];
    assign out[15:8] = in[23:16];
    assign out[7:0] = in[31:24];

endmodule

Bitwise operators

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

Four-input gates

module top_module( 
    input [3:0] in,
    output out_and,
    output out_or,
    output out_xor
);
    assign out_and = ∈
    assign out_or = |in;
    assign out_xor = ^in;
endmodule

Vector concatenation operator

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

    // assign { ... } = { ... };
    assign {w,x,y,z} = {a,b,c,d,e,f,2'b11};  //后面两个11需要说明其位数和类型

endmodule

Vector reversal 1

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

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

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

More replication

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}},{5{b}},{5{c}},{5{d}},{5{e}} } ^ {5{a,b,c,d,e}};
   
endmodule

Modules: Hierarchy

Modules

module top_module ( input a, input b, output out );

    mod_a mod_a_inst1 (.in1(a), .in2(b), .out(out) ); //调用模块,随便取一个模块名,括号外面是内部要牵出来的线,
                                                      //括号里面是外部要连接的线
endmodule

Connecting ports by position

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

Connecting ports by name

module top_module ( 
    input a, 
    input b, 
    input c,
    input d,
    output out1,
    output out2
);
   mod_a mod_a_inst1(.in1(a), .in2(b), .in3(c), .in4(d), .out1(out1), .out2(out2) ); //按照名字来例化
   
endmodule

Three modules

module top_module ( input clk, input d, output q );
    
    wire w1,w2;
    my_dff my_dff_inst1(.clk(clk), .d(d), .q(w1));
    my_dff my_dff_inst2(.clk(clk), .d(w1), .q(w2));
    my_dff my_dff_inst3(.clk(clk), .d(w2), .q(q));
endmodule

Modules and vectors

module top_module ( 
    input clk, 
    input [7:0] d, 
    input [1:0] sel, 
    output [7:0] q 
);
    wire [7:0] w1,w2,w3;
    my_dff8 my_dff8_inst1(.clk(clk), .d(d), .q(w1));
    my_dff8 my_dff8_inst2(.clk(clk), .d(w1), .q(w2));
    my_dff8 my_dff8_inst3(.clk(clk), .d(w2), .q(w3));
    always @(*) 
        begin
            case(sel)
                2'b00 : begin q = d; end
                2'b01 : begin q = w1; end
                2'b10 : begin q = w2; end
                2'b11 : begin q = w3; end
            endcase
        end
endmodule

Adder 1

module top_module(
    input [31:0] a,
    input [31:0] b,
    output [31:0] sum
);
    wire [15:0] sum1,sum2;
    wire count_temp;
    add16 add16_inst1(.a(a[15:0]), .b(b[15:0]), .cin(1'b0), .sum(sum1), .cout(count_temp));
    add16 add16_inst2(.a(a[31:16]), .b(b[31:16]), .cin(count_temp), .sum(sum2));
  
            assign sum = {sum2,sum1};
        


endmodule

Adder 2

module top_module (
    input [31:0] a,
    input [31:0] b,
    output [31:0] sum
);//
    wire [15:0] sum1,sum2;
    wire w1;
    add16 add16_inst1(.a(a[15:0]), .b(b[15:0]), .cin(1'b0), .sum(sum1), .cout(w1) );
    add16 add16_inst2(.a(a[31:16]), .b(b[31:16]), .cin(w1), .sum(sum2) );
    assign sum = {sum2,sum1};
    
endmodule

module add1 ( input a, input b, input cin,   output sum, output cout );

// Full adder module here
  
    assign sum = a ^ b ^ cin;
    assign cout = (a & b) | (a & cin) | (b & cin);

    
endmodule

Carry-select adder

module top_module(
    input [31:0] a,
    input [31:0] b,
    output [31:0] sum
);
    wire w1;
    wire [15:0] sum0,sum1;
    add16 add16_inst1(.a(a[15:0]), .b(b[15:0]), .cin(1'b0), .cout(w1), .sum(sum[15:0]) );
    add16 add16_inst2(.a(a[31:16]), .b(b[31:16]), .cin(1'b0), .sum(sum0) );
    add16 add16_inst3(.a(a[31:16]), .b(b[31:16]), .cin(1'b1), .sum(sum1) );
    always @(*) begin  //所有的行为语句需要在initial  或 always 块中执行
    case (w1)
        1'b0 : begin
            sum[31:16] = sum0; 
        end
        1'b1 : begin 
            sum[31:16] = sum1;
        end
    endcase
    end
endmodule

Adder-subtractor

module top_module(
    input [31:0] a,
    input [31:0] b,
    input sub,
    output [31:0] sum
);
    wire [31:0]sub_b;
    wire w1;
    assign sub_b = {32{sub}} ^ b;  //位宽不同进行异或
                                   //先把小数位的值进行扩展,然后在进行按位异或。
    add16 add16_low(.a(a[15:0]), .b(sub_b[15:0]), .cin(sub), .cout(w1), .sum(sum[15:0]) );
    add16 add16_high(.a(a[31:16]), .b(sub_b[31:16]), .cin(w1), .sum(sum[31:16]) );

endmodule

Procedures

Always blocks (combinational)

// 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)

// 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

If statement

// 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)
                begin
                    out_always = b;
                end
            else 
                begin
                   out_always = a;
                end
        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

// 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)
            3'b000 : begin
                out = data0 ;
            end
            3'b001 : begin
                out = data1;
            end
            3'b010 : begin
                out = data2;
            end
            3'b011 : begin
                out = data3;
            end
            3'b100 : begin
                out = data4;
            end
            3'b101 : begin
                out = data5;
            end
            default : out = 4'b0000;
        endcase
                    
    end

endmodule

Priority encoder

// synthesis verilog_input_version verilog_2001
module top_module (
    input [3:0] in,
    output reg [1:0] pos  );
    always @(*) begin
        casex(in)
            4'bxxx1 : pos = 2'b00;  //第0位为有效位
            4'bxx1x : pos = 2'b01;  //第1位为有效位
            4'bx1xx : pos = 2'b10;  //第2位为有效位
            4'b1xxx : pos = 2'b11;  //第3位为有效位
            default : pos = 2'b00;  //所有位为0时
        endcase
    end

endmodule

Priority encoder with 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'b000;
            8'bzzzz_zz1z : pos = 3'b001;
            8'bzzzz_z1zz : pos = 3'b010;
            8'bzzzz_1zzz : pos = 3'b011;
            8'bzzz1_zzzz : pos = 3'b100;
            8'bzz1z_zzzz : pos = 3'b101;
            8'bz1zz_zzzz : pos = 3'b110;
            8'b1zzz_zzzz : pos = 3'b111;
            default : pos = 3'b000;
        endcase
    end

endmodule

Avoiding latches

// 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 = 1'b0;
            down = 1'b0; 
            right = 1'b0; 
            up = 1'b0;
    case(scancode[15:0])
        16'he06b : left = 1'b1;
        16'he072 : down = 1'b1;
        16'he074 : right = 1'b1;
        16'he075 : up = 1'b1;
    endcase
        end

endmodule

More Verilog Features

Conditional ternary operator

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

    // assign intermediate_result1 = compare? true: false;
    assign min = (a<b ? (a<c ? (a<d ? a : d) :(c<d ? c:d) ) : (b<c ? (b<d ? b :d):(c<d ? c:d) ) );
endmodule

Reduction operators

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

Reduction: Even wider gates

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

module top_module( 
    input [99:0] in,
    output [99:0] out
);
    reg [7:0] i;  //i是系统默认为二进制数
    always @(*)
        begin
            for(i=0;i<100;i=i+1)
                out[99-i] = in[i];
        end

endmodule

Combinational for-loop: 255-bit population count

module top_module( 
    input [254:0] in,
    output [7:0] out );
    always @(*) begin
        out = 0;
        for(int i=0;i<255;i=i+1)
            out = out +in[i];    //计算in中有多少个1;
    end
endmodule

Generate for-loop: 100-bit binary adder 2

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++)
        begin :adder100i   //生成块的名字必须要有
            if(i==0)               
           assign {cout[0],sum[0]} = a[0] + b[0] + cin;  //cin为进位输入,cout为进位输出
            else
            assign {cout[i],sum[i]} = a[i] + b[i] + cout[i-1];  //100位的全加器是将上一个的进位输出与下一个的进位输入相连
        end
    endgenerate

endmodule

Generate for-loop: 100-digit BCD adder

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值