HDLBits — Verilog Practice

HDLbits网址:https://hdlbits.01xz.net/wiki/Main_Page

Getting Started

Getting Started

module top_module( output one );

// Insert your code here
    assign one = 1'b1;

endmodule

Output Zero

module top_module(
    output zero
);// Module body starts after semicolon(分号)
		
		zero = 0;

endmodule

Verilog Language

Basics

Simple wire

https://imgs.itxueyuan.com/Wire.png

module top_module( input in, output out );

    assign out = in;  // wires are directional(有方向性)
    
endmodule

Four wires

https://imgs.itxueyuan.com/Wire4.png

module top_module( 
    input a,b,c,
    output w,x,y,z );

		assign w = a;
		assign x = b;
		assign y = b;
		assign z = c;
		// If we're certain about the width of each signal, using 
	  // the concatenation operator is equivalent and shorter:
	  // assign {w,x,y,z} = {a,b,b,c};

endmodule

Inverter

https://imgs.itxueyuan.com/Notgate.png

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

AND gate

https://imgs.itxueyuan.com/Andgate.png

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

    assign out = a & b;
    
endmodule

NOR gate

https://imgs.itxueyuan.com/Norgate.png

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

    assign out = ~(a|b);  // 或非
    
endmodule

XNOR gate

https://imgs.itxueyuan.com/Xnorgate.png

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

    assign out = a ^~ b;  // out = ~(a^b) 同或 = 异或的非
    
endmodule

Declaring wires

https://imgs.itxueyuan.com/Wiredecl2.png

module top_module (
	input a,
	input b,
	input c,
	input d,
	output out,
	output out_n );
	
	wire w1, w2;		      // **Declare two wires** (named w1 and w2)
	assign w1  = a & b;	  // First AND gate
	assign w2  = c & d;	  // Second AND gate
	assign out = w1 | w2;	// OR gate: Feeds both 'out' and the NOT gate

	assign out_n = ~out;	// NOT gate
	
endmodule

7458 chip

https://imgs.itxueyuan.com/7458.png

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

    assign p2y = (p2a & p2b)|(p2c & p2d);  
    assign p1y = (p1a & p1b & p1c)|(p1d & p1e & p1f);
    ****// 这里并没有像上一节声明中间线网

endmodule

Vectors

Vectors

https://imgs.itxueyuan.com/Vector0.png

module top_module(
	input [2:0] vec, 
	output [2:0] outv,
	output o2,
	output o1,
	output o0
);
	
	assign outv = vec;

	// This is ok too: assign {o2, o1, o0} = vec;
	assign o0 = vec[0];
	assign o1 = vec[1];
	assign o2 = vec[2];
	
endmodule

Vectors in more detail

/*
Build a combinational circuit that splits an input half-word (16 bits, [15:0] ) into lower [7:0] and upper [15:8] bytes.
*/
module top_module (
	input [15:0] in,
	output [7:0] out_hi,
	output [7:0] out_lo
);
	
	assign out_hi = in[15:8];
	assign out_lo = in[7:0];
	
	// Concatenation operator also works: assign {out_hi, out_lo} = in;
	
endmodule

Vector part select

/*
A 32-bit vector can be viewed as containing 4 bytes (bits [31:24], [23:16], etc.). Build a circuit that will reverse the byte ordering of the 4-byte word.

AaaaaaaaBbbbbbbbCcccccccDddddddd => DdddddddCcccccccBbbbbbbbAaaaaaaa
*/
module top_module (
	input [31:0] in,
	output [31:0] out
);

	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];	
// or you can write this:assign out ={in[7:0],in[15:8],in[23:16],in[31:24]};

endmodule

Bitwise operators

https://imgs.itxueyuan.com/Vectorgates.png

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[2:0] = ~a;	// Part-select on left side is o.
	assign out_not[5:3] = ~b;	//Assigning to [5:3] does not conflict with [2:0]
	
endmodule

HDLBits%20%E2%80%94%20Verilog%20Practice%2043488af42f944caba9609ddd2030dccb/wavedrom_(1).svg

Four-input gate

/*
Build a combinational circuit with four inputs, in[3:0].
There are 3 outputs:
out_and: output of a 4-input AND gate.
out_or: output of a 4-input OR gate.
out_xor: output of a 4-input XOR gate.
*/
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;
		//also you can do this:assign out_and = in[3]&in[2]&in[1]&in[0];

endmodule

Vector concatenation operator

https://imgs.itxueyuan.com/Vector3.png

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{1'b1}} };

endmodule

Vector reverasal 1

// Given an 8-bit input vector [7:0], reverse its bit ordering.
module top_module (
		input [7:0] in,
		output [7:0] out
);
		
		assign {out[0],out[1],out[2],out[3],out[4],out[5],out[6],out[7]} = in;
	
endmodule
-----------------------------------------------------------------------------
module top_module (
		input [7:0] in,
		output [7:0] out
);

		integer i;
		always @(*) begin	
				for (i=0; i<8; i++)
		    // int is a SystemVerilog type. Use integer for pure Verilog.
						out[i] = in[8-i-1];
  	end

endmodule
-----------------------------------------------------------------------------
module top_module (
		input [7:0] in,
		output [7:0] out
);

		generate
				genvar i;
				for (i=0; i<8; i = i+1) begin: my_block_name
						assign out[i] = in[8-i-1];
				end
		endgenerate

endmodule
// ***Todo* 后续还会提到,没理解不要紧**

Replication operator

/*
Build a circuit that sign-extends an 8-bit number to 32 bits. This requires a concatenation of 24 copies of the sign bit (i.e., replicate bit[7] 24 times) followed by the 8-bit number itself.
*/
**module top_module (
	input [7:0] in,
	output [31:0] out
);

	// Concatenate two things together:
	// 1: {in[7]} repeated 24 times (24 bits)
	// 2: in[7:0] (8 bits)
	assign out = { {24{in[7]}}, in };
	
endmodule**

More replication

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

	wire [24:0] top, bottom;
	assign top    = { {5{a}}, {5{b}}, {5{c}}, {5{d}}, {5{e}} };
	assign bottom = {5{a,b,c,d,e}};
	assign out = ~top ^ bottom;	// Bitwise XNOR

	// This could be done on one line:
	// assign out = ~{ {5{a}}, {5{b}}, {5{c}}, {5{d}}, {5{e}} } ^ {5{a,b,c,d,e}};
	
endmodule

Modules : Hierarchy

Modules

https://imgs.itxueyuan.com/Module.png

/* 
module mod_a ( input in1, input in2, output out );
    // Module body
endmodule 
*/
module top_module (
	input a,
	input b,
	output out
);

	// Create an instance of "mod_a" named "inst1", and connect ports by name:
	mod_a inst1 ( 
		.in1(a), 	// Port"in1"connects to wire "a"
		.in2(b),	// Port "in2" connects to wire "b"
		.out(out)	// Port "out" connects to wire "out" 
		  // (Note: mod_a's port "out" is not related to top_module's wire "out". 
			// It is simply coincidence that they have the same name)
	);

endmodule

Connecting ports by position

https://imgs.itxueyuan.com/Module_pos.png

//You are given the following module:
//module mod_a ( output, output, input, input, input, input );
//本题中mod_a这个模块的端口名未标明,只能按照位置的顺序来连接
//写文档的时候这样只表注输入输出端口而没有名字是不规范的
module top_module ( 
    input a, 
    input b, 
    input c,
    input d,
    output out1,
    output out2
);
    mod_a instance1(out1,out2,a,b,c,d);

endmodule

Connecting ports by name

https://imgs.itxueyuan.com/Module_name.png

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

    mod_a name(
        .in1(a),
        .in2(b),
        .in3(c),
        .in4(d),
        .out1(out1),
        .out2(out2),
    );
    
endmodule

Three modules

https://imgs.itxueyuan.com/Module_shift.png

module top_module ( input clk, input d, output q );

    wire mid1;
    wire mid2;
    
    my_dff inst1(
        .clk(clk),
        .d(d),
        .q(mid1)
    );
    my_dff inst2(
        .clk(clk),
        .d(mid1),
        .q(mid2)
    );    
    my_dff inst3(
        .clk(clk),
        .d(mid2),
        .q(q)
    );
    
endmodule
-----------------------------------------------------------------------------
**Web** **Solution**:
module top_module (
	input clk,
	input d,
	output q
);

	wire a, b;	// Create two wires. I called them a and b.

	// Create three instances of my_dff, with three different instance names (d1, d2, and d3).
	// Connect ports by position: ( input clk, input d, output q)
	my_dff d1 ( clk, d, a );
	my_dff d2 ( clk, a, b );
	my_dff d3 ( clk, b, q );

endmodule

HDLBits%20%E2%80%94%20Verilog%20Practice%2043488af42f944caba9609ddd2030dccb/wavedrom.svg

相当于三级延时 一次一个clk

D触发器 ( D Flip-flop ):

   D触发器有一个输入、一个输出和一个时脉输入,当时脉由0转为1时,输出的值会和输入的值相等。S为1时强迫Q值为1,R为1时强迫Q值为0。

HDLBits%20%E2%80%94%20Verilog%20Practice%2043488af42f944caba9609ddd2030dccb/150px-D-Type_Flip-flop.svg.png

Modules and vectors

https://imgs.itxueyuan.com/Module_shift8.png

//module my_dff8 ( input clk, input [7:0] d, output [7:0] q );
//my first answer
module top_module ( 
    input clk, 
    input [7:0] d, 
    input [1:0] sel, 
    output [7:0] q 
);
    wire [7:0] a,b,c;
    
    my_dff8 d1(clk,d,a);
    my_dff8 d2(clk,a,b);
    my_dff8 d3(clk,b,c);
    
    always@(*)
    if(sel==0) begin q <= d;end
    else if(sel==1) begin q <= a;end
    else if(sel==2) begin q <= b;end
    else if(sel==3) begin q <= c;end
            
endmodule
----------------------------------------------------------------------------- 
**Web** **Solution**:
module top_module (
	input clk,
	input [7:0] d,
	input [1:0] sel,
	output reg [7:0] q
);

	wire [7:0] o1, o2, o3;		// output of each my_dff8
	
	// Instantiate three my_dff8s
	my_dff8 d1 ( clk, d, o1 );
	my_dff8 d2 ( clk, o1, o2 );
	my_dff8 d3 ( clk, o2, o3 );

	// This is one way to make a 4-to-1 multiplexer
	always @(*)		// Combinational always block
		case(sel)
			2'h0: q = d;
			2'h1: q = o1;
			2'h2: q = o2;
			2'h3: q = o3;
		endcase

endmodule

Adder 1

https://imgs.itxueyuan.com/Module_add.png

/*
module add16 ( input[15:0] a, input[15:0] b, input cin, output[15:0] sum, output cout );
*/
module top_module(
    input  [31:0] a,
    input  [31:0] b,
    output [31:0] sum
);
    wire [15:0] a1,a2,b1,b2,sum1,sum2;
    wire [ 0:0]cout;
    assign a1 = a[15: 0];
    assign a2 = a[31:16];
    assign b1 = b[15: 0];
    assign b2 = b[31:16];
    add16 add_low(
        .a(a1),
        .b(b1),
        .cin(),
        .sum(sum1),
        .cout(cout)
    );
    add16 add_hig(
        .a(a2),
        .b(b2),
        .cin(cout),
        .sum(sum2),
        .cout()
    );
    assign sum[31:16] = sum2;
    assign sum[15: 0] = sum1;

endmodule
-----------------------------------------------------------------------------
//**Web Solution:
module top_module(
    input  [31:0] a,
    input  [31:0] b,
    output [31:0] sum
);

    wire cout1;
    //线网信号可以是截位的
    add16 add1(a[15: 0],b[15: 0], 1'b0,sum[15: 0],cout1);
    add16 add2(a[31:16],b[31:16],cout1,sum[31:16],);//注意这里进位信号没有线网所连接
    
endmodule**

Adder 2

https://imgs.itxueyuan.com/Module_fadd.png

//行波进位加法器(RCA: Ripple-Carry Adder)
//缺点 进位输出延迟
//add16 web里提供 其中例化了16个add1
//module add16 ( input[15:0] a, input[15:0] b, input cin, output[15:0] sum, output cout );
module top_module (
    input [31:0] a,
    input [31:0] b,
    output [31:0] sum
);
    wire cout1;
	  add16 add1(a[15: 0],b[15: 0], 1'b0,sum[15: 0],cout1);
    add16 add2(a[31:16],b[31:16],cout1,sum[31:16],);
    
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

https://imgs.itxueyuan.com/Module_cseladd.png

// module add16 ( input[15:0] a, input[15:0] b, input cin, output[15:0] sum, output cout );
module top_module(
    input [31:0] a,
    input [31:0] b,
    output [31:0] sum
);

    wire cout1;
    wire [15:0] sum1,sum2;
	  add16 add1(a[15: 0],b[15: 0],1'b0,sum[15: 0],cout1);
    add16 add2(a[31:16],b[31:16],1'b0,sum1);
    add16 add3(a[31:16],b[31:16],1'b1,sum2);
    always @(*)
        case(cout1)
            1'b0: sum[31:16] = sum1;
            1'b1: sum[31:16] = sum2;
        endcase

endmodule
-----------------------------------------------------------------------------
// Web Solution
module top_module(
    input [31:0] a,
    input [31:0] b,
    output [31:0] sum
);

    wire carry;
    wire [31:16] sum0;
    wire [31:16] sum1;
    
    add16 al(a[15:0],b[15:0],1'b0,sum[15:0],carry);
    add16 ah0(a[31:16],b[31:16],1'b0,sum0[31:16],);
    add16 ah1(a[31:16],b[31:16],1'b1,sum1[31:16],);
    
    assign sum[31:16] = carry?sum1:sum0;  // 二选一
    
endmodule

Adder-subtractor

https://imgs.itxueyuan.com/Module_addsub.png

// 减去一个数等于奖赏这个数的补码
module top_module(
    input [31:0] a,
    input [31:0] b,
    input sub,
    output [31:0] sum
);
    //module add16 ( input[15:0] a, input[15:0] b, input cin, output[15:0] sum, output cout );
    wire [31:0] c;
    wire cout;
    assign c = b^{32{sub}};
    
    add16 d1(a[15: 0],c[15: 0], sub,sum[15: 0],cout);
    add16 d2(a[31:16],c[31:16],cout,sum[31:16],);
    
endmodule

Procedures

More Verilog Featureas


Circuits


Verification : Reading Simulations


Verification : Writing Testbenches


内容来源于网络如有侵权请私信删除

文章来源: 博客园

原文链接: https://www.cnblogs.com/liumunanchun/p/14811609.html

你还没有登录,请先登录注册
  • 还没有人评论,欢迎说说您的想法!