HDLbits Verilog Language

Verilog Language

Basics

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

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

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

Andgate
module top_module( 
    input a, 
    input b, 
    output out );
    assign out = a && b;
endmodule

Norgate

或非门(英语:NOR gate)是数字逻辑电路中的基本元件,实现逻辑或非功能。有多个输入端,1个输出端,多输入或非门可由2输入或非门和反相器构成。
只有当两个输入A和B为低电平(逻辑0)时输出为高电平(逻辑1)。也可以理解为任意输入为高电平(逻辑1),输出为低电平(逻辑0)。

module top_module( 
    input a, 
    input b, 
    output out );
    //或非门(英语:NOR gate)是数字逻辑电路中的基本元件,实现逻辑或非功能。
    //有多个输入端,1个输出端,多输入或非门可由2输入或非门和反相器构成。
    //只有当两个输入A和B为低电平(逻辑0)时输出为高电平(逻辑1)。也可以理解为任意输入为高电平(逻辑1),输出为低电平(逻辑0)。
    assign out = ((a == 1'b0) && (b == 1'b0) ) ? 1'b1 : 1'b0;
endmodule


Xnorgate
module top_module( 
    input a, 
    input b, 
    output out );
    //同或门(英语:XNOR gate或equivalence gate)也称为异或非门,
    //在异或门的输出端再加上一个非门就构成了异或非门,是数字逻辑电路的基本单元,有2个输入端、1个输出端。
    //当2个输入端中有且只有一个是低电平(逻辑0)时,输出为低电平。亦即当输入电平相同时,输出为高电平(逻辑1)。
    assign out = (a == b) ? 1'b1 :1'b0;
endmodule

同或门(英语:XNOR gate或equivalence gate)也称为异或非门,
在异或门的输出端再加上一个非门就构成了异或非门,是数字逻辑电路的基本单元,有2个输入端、1个输出端。
当2个输入端中有且只有一个是低电平(逻辑0)时,输出为低电平。亦即当输入电平相同时,输出为高电平(逻辑1)。

Wire decl
//`default_nettype none
module top_module(
    input a,
    input b,
    input c,
    input d,
    output out,
    output out_n   ); 
    wire first;
    wire second;
    assign first = a && b;
    assign second = c && d;
    assign out = first || second;
    assign out_n = ~out;
endmodule
7458
module top_module ( 
    input p1a, p1b, p1c, p1d, p1e, p1f,
    output p1y,
    input p2a, p2b, p2c, p2d,
    output p2y );
    wire wire1;
    wire wire2;
    wire wire3;
    wire wire4;
    assign wire1 =  p2a && p2b;
    assign wire2 =  p2c && p2d;
    assign p2y = wire1 || wire2;
    assign wire3 = p1a && p1b && p1c;
    assign wire4 = p1f && p1e && p1d;
    assign p1y = wire3 || wire4;
endmodule

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

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[5:3]        = ~b;
    assign out_not[2:0]        = ~a;
endmodule
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]) ? 1'b0 : 1'b1;
endmodule
Vector3
module top_module (
    input [4:0] a, b, c, d, e, f,
    output [7:0] w, x, y, z );//

    // assign { ... } = { ... };
    assign w = {a,b[4:2]};
    assign x = {b[1:0],c,d[4]};
    assign y = {d[3:0],e[4:1]};
    assign z = {e[0],f,2'b11};
endmodule
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
// I know you're dying to know how to use a loop to do this:

	//Create a combinational always block. This creates combinational logic that computes the same result
	//as sequential code. for-loops describe circuit *behaviour*, not *structure*, so they can only be used 
	//inside procedural blocks (e.g., always block).
	//The circuit created (wires and gates) does NOT do any iteration: It only produces the same result
	//AS IF the iteration occurred. In reality, a logic synthesizer will do the iteration at compile time to
	//figure out what circuit to produce. (In contrast, a Verilog simulator will execute the loop sequentially
	//during simulation.)
	//always @(*) begin	
	//	for (int i=0; i<8; i++)	// int is a SystemVerilog type. Use integer for pure Verilog.
	//		out[i] = in[8-i-1];
	//end


	//It is also possible to do this with a generate-for loop. Generate loops look like procedural for loops,
	//but are quite different in concept, and not easy to understand. Generate loops are used to make instantiations
	//of "things" (Unlike procedural loops, it doesn't describe actions). These "things" are assign statements,
	//module instantiations, net/variable declarations, and procedural blocks (things you can create when NOT inside 
	//a procedure). Generate loops (and genvars) are evaluated entirely at compile time. You can think of generate
	//blocks as a form of preprocessing to generate more code, which is then run though the logic synthesizer.
	//In the example below, the generate-for loop first creates 8 assign statements at compile time, which is then
	//synthesized.
	//Note that because of its intended usage (generating code at compile time), there are some restrictions
	//on how you use them. Examples: 1. Quartus requires a generate-for loop to have a named begin-end block
	//attached (in this example, named "my_block_name"). 2. Inside the loop body, genvars are read only.
	//generate
	//	genvar i;
	//	for (i=0; i<8; i = i+1) begin: my_block_name
	//		assign out[i] = in[8-i-1];
	//	end
	//endgenerate

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

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

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

Modules Hierarchy

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

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

Module shift
module top_module ( input clk, input d, output q );
wire wire1;
wire wire2;
my_dff my_dff_1(
    .clk(clk),
    .d(d),
    .q(wire1)
);
my_dff my_dff_2(
    .clk(clk),
    .d(wire1),
    .q(wire2)
);
my_dff my_dff_3(
    .clk(clk),
    .d(wire2),
    .q(q)
);
endmodule

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 my_dff8_u1(
    .clk(clk),
    .d(d),
    .q(wire1)
);
my_dff8 my_dff8_u2(
    .clk(clk),
    .d(wire1),
    .q(wire2)
);
my_dff8 my_dff8_u3(
    .clk(clk),
    .d(wire2),
    .q(wire3)
);
always @( *) begin
    case (sel)
        2'd0:q <= d;
        2'd1:q <= wire1;
        2'd2:q <= wire2;
        2'd3:q <= wire3;


    endcase
end
endmodule

Module add
module top_module(
    input [31:0] a,
    input [31:0] b,
    output [31:0] sum
);
wire [15:0] low;
wire [15:0] heigh;
wire        wire1;
add16 add16_low(
    .a(a[15:0]),
    .b(b[15:0]),
    .cin(1'b0),
    .sum(low),
    .cout(wire1)
);
add16 add16_heigh(
    .a(a[31:16]),
    .b(b[31:16]),
    .cin(wire1),
    .sum(heigh),
    .cout()
);
assign sum = {heigh,low};
endmodule

Module fadd
module top_module (
    input [31:0] a,
    input [31:0] b,
    output [31:0] sum
);//
wire [15:0] low;
wire [15:0] heigh;
wire        wire1;
add16 add16_low(
    .a(a[15:0]),
    .b(b[15:0]),
    .cin(1'b0),
    .sum(low),
    .cout(wire1)
);
add16 add16_heigh(
    .a(a[31:16]),
    .b(b[31:16]),
    .cin(wire1),
    .sum(heigh),
    .cout()
);
assign sum = {heigh,low};
endmodule

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

// Full adder module here
/*
reg sum1;
reg cout1;
always @( *) begin
    case (a + b + cin)
        1'b0:begin
        cout1 <= 1'b0;
        sum1  <= 1'b0;
        end
        1'b1:
        begin
        cout1 <= 1'b0;
        sum1  <= 1'b1;
        end
        2'b10:
        begin
        cout1 <= 1'b1;
        sum1  <= 1'b0;
        end
        2'b11:
        begin
        cout1 <= 1'b1;
        sum1  <= 1'b1;
        end
    endcase        
end
assign sum = sum1;
assign cout = cout1;*/
//Full adder equations:
assign sum = a ^ b ^ cin;//位异或,加法器可以用异或来实现
assign cout = a&b | a&cin | b&cin;
//太复杂了,直接位运算就好了
endmodule
Module cseladd
module top_module(
    input [31:0] a,
    input [31:0] b,
    output [31:0] sum
);
wire [15:0] low;
wire [15:0] heigh1;
wire [15:0] heigh2;

wire        wire1;
add16 add16_low(
    .a(a[15:0]),
    .b(b[15:0]),
    .cin(1'b0),
    .sum(low),
    .cout(wire1)
);
add16 add16_heigh0(
    .a(a[31:16]),
    .b(b[31:16]),
    .cin(1'b0),
    .sum(heigh1),
    .cout()
);
add16 add16_heigh1(
    .a(a[31:16]),
    .b(b[31:16]),
    .cin(1'b1),
    .sum(heigh2),
    .cout()
);
assign sum = (wire1) ? {heigh2,low} : {heigh1,low};
endmodule
Module addsub
module top_module(
    input [31:0] a,
    input [31:0] b,
    input sub,
    output [31:0] sum
);
wire [31:0] new_b;
wire [15:0] low;
wire [15:0] heigh;
wire        wire1;
assign new_b = (sub == 1'b1) ? ((~b) + 1'b1) : (b);//补码
add16 add16_low(
    .a(a[15:0]),
    .b(new_b[15:0]),
    .cin(1'b0),
    .sum(low),
    .cout(wire1)
);
add16 add16_heigh(
    .a(a[31:16]),
    .b(new_b[31:16]),
    .cin(wire1),
    .sum(heigh),
    .cout()
);
assign sum = {heigh,low};
endmodule

Procedures

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

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

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

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)
            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 <= 4'b0;
        endcase
    end

endmodule
Always case2
// synthesis verilog_input_version verilog_2001
module top_module (
    input [3:0] in,
    output reg [1:0] pos  );
always @( *) begin
    casez (in[3:0])
        4'b0000:
        pos = 2'd0;
        4'bzzz1:
        pos = 2'd0;
        4'bzz1z:
        pos = 2'd1;
        4'bz1zz:
        pos = 2'd2;
        4'b1zzz:
        pos = 2'd3;
        default :
            pos <= 2'd0;


    endcase
end
endmodule

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

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 = 1'b0;
    down = 1'b0;
    right = 1'b0;
    up = 1'b0;
    case (scancode)
        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
module top_module (
    input [7:0] a, b, c, d,
    output [7:0] min);//

    // assign intermediate_result1 = compare? true: false;
    wire [7:0] ab;
    wire [7:0] cd;
    assign ab = (a < b) ? a : b;
    assign cd = (c < d) ? c : d;
    assign min = (ab < cd) ? ab : cd;
endmodule
Reduction
module top_module (
    input [7:0] in,
    output parity); 
    assign parity = ^ in[7:0];
endmodule

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

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

/*
integer类型也是一种寄存器数据类型,integer类型的变量为有符号数,而reg类型的变量则为无符号数,用integer的变量都可以用reg定
义,只是用于计数更方便而已。
module top_module (
	input [99:0] in,
	output reg [99:0] out
);
	
	always @(*) begin
		for (int i=0;i<$bits(out);i++)		// $bits() is a system function that returns the width of a signal.
			out[i] = in[$bits(out)-i-1];	// $bits(out) is 100 because out is 100 bits wide.
	end
	
endmodule

*/
Popcount255
module top_module( 
    input [254:0] in,
    output  [7:0] out );
reg [7:0]  out1;
always @( *) begin
    out1 = 8'b0;//赋值语句一定要放在always块里
    for (integer i =0 ;i<=254 ;i=i+1 ) begin
        if (in[i] == 1'b1) begin
            out1 <= out1 +1'b1;
        end
        else
            out1 <= out1;
    end
end
assign out = out1;
endmodule
Adder100i
module top_module( 
    input [99:0] a, b,
    input cin,
    output [99:0] cout,
    output [99:0] sum );

assign sum[0] = a[0] ^ b[0]^ cin;
assign cout[0] = a[0]&b[0] | a[0]&cin | b[0]&cin;
//这两句就可以实现一个一位全加器


genvar	i;
generate
    for( i=1; i<=99; i=i+1) begin:add1
        assign sum[i] = a[i] ^ b[i]^ cout[i-1];
        assign cout[i] = a[i]&b[i] | a[i]&cout[i-1] | b[i]&cout[i-1];
    end
endgenerate
endmodule



Bcdadd100
module top_module( 
    input [399:0] a, b,
    input cin,
    output cout,
    output [399:0] sum );
reg [99:0] cout_reg;
bcd_fadd (
            .a(a[3:0]),
            .b(b[3:0]),
            .cin(cin),
            .cout(cout_reg[0]),
            .sum(sum[3:0])
        );

genvar i;
generate
    for (i = 1;i<=99 ; i=i+1) begin:fadd
        bcd_fadd fadd(
            .a(a[4*(i+1)-1:4*(i+1)-4]),
            .b(b[4*(i+1)-1:4*(i+1)-4]),
            .cin(cout_reg[i-1]),
            .cout(cout_reg[i]),
            .sum(sum[4*(i+1)-1:4*(i+1)-4])
        );
    end
endgenerate
assign cout = cout_reg[99];
endmodule

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值