verilog学习 | HDLBits:在线学习答案

HDLBits 在提供 Verilog 基础语法教程的同时,还能够在线仿真 Verilog 模块。
以下是各单元解法答案。希望可以帮助您了解 Verilog 的工作原理。


前言

HDLBits 在提供 Verilog 基础语法教程的同时,还能够在线仿真 Verilog 模块。


一、入门 Getting Started

⚠️注意:顶层的模块名称和端口名称 top_module 不能更改,否则会出现仿真错误。

1.Step one

module top_module ( output one );

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

2.Zero

module top_module ( zero );
    output zero;
    
endmodule

二、Verilog 语言 Verilog Language

第一部分:Basics

1. Wire

module top_module( input in, output out );

    assign out = in;

endmodule

2. Wire 4

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


//或者使用拼接运算符{} 

module top_module( 
    input a,b,c,
    output w,x,y,z );
 
    assign {w,x,y,z} = {a,b,b,c};
 
endmodule

3. Notgate

module top_module( input in, output out );

    assign out = ~ in;

endmodule

4. Andgate

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

endmodule

5. Norgate

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

endmodule

6. Xnorgate

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

endmodule

7. Wire decl

当没有使用`default_nettype none 时,一个变量没有被定义就使用,系统会默认该变量为wire型,结果有warning,但无error。

当使用了`default_nettype none 时,一个变量没有定义就使用,由于编译指令的存在,系统会报error,从而检查出书写错误。

`default_nettype none
module top_module(
    input a,
    input b,
    input c,
    input d,
    output out,
    output out_n   ); 
    
    wire ab,cd;
    
    assign ab = a & b;
    assign cd = c & d;
    assign out = ab | cd;
    assign out_n = ~ out;

endmodule

8. 7458

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

第二部分:Vectors

1. Vector 0

在这里插入图片描述

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

endmodule

2. Vector 1

`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

3. Vector 2

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

    // assign out[31:24] = ...;
    assign out = {in[7:0], in[15:8], in[23:16], in[31:24]};

endmodule

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

5. Gates 4

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

endmodule

6. Vector 3

在这里插入图片描述


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

    // assign { ... } = { ... };
    
    // assign {w[7:0], x[7:0], y[7:0], z[7:0]} = {a[4:0], b[4:0], c[4:0], d[4:0], e[4:0], f[4:0], 2'b11};
    
    //assign {w, x, y, z} = {a, b, c, d, e, f, 2'b11};
    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

7. Vectorr

  给定一个 8 位输入向量 [7:0],反转其位顺序输出。


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;	
	
    assign out = {in[0], in[1], in[2], in[3], in[4], in[5], in[6], in[7]};
    
endmodule

8. Vector 4

  构建一个将 8 位数字符号扩展为 32 位的电路。这需要连接 24 个符号位副本(即复制位 [7] 24 次),然后是 8 位数字本身。


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

9. Vector 5

在这里插入图片描述

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}};
    
    assign out[24:20] = ~ {5{a}} ^ {a, b, c, d, e};
    assign out[19:15] = ~ {5{b}} ^ {a, b, c, d, e};
    assign out[14:10] = ~ {5{c}} ^ {a, b, c, d, e};
    assign out[9:5]   = ~ {5{d}} ^ {a, b, c, d, e};
    assign out[4:0]   = ~ {5{e}} ^ {a, b, c, d, e};
    
endmodule

第三部分:Modules: Hierarchy

1. Module

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

endmodule

2. Module pos

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

endmodule

3. Module name

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

endmodule

4. Module shift

在这里插入图片描述

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

	wire a, b;	// 声明两个wire变量,命名为a, b

	// 对my_dff进行了三次实例化,用了三个不用的名字 (d1, d2, and d3).
	// 端口使用了位置连接的方式( 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

5. Module shift 8

在这里插入图片描述

module top_module (
	input clk,
	input [7:0] d,
	input [1:0] sel,
	output [7:0] q
);

	wire [7:0] o1, o2, o3;		// 声明每一个触发器的输出
	
	// 对 my_dff进行了三次实例化
	my_dff8 d1 ( clk, d, o1 );
	my_dff8 d2 ( clk, o1, o2 );
	my_dff8 d3 ( clk, o2, o3 );

	// 4选1
	always @(*)		// 组合逻辑always块
		case(sel)
			2'h0: q = d;
			2'h1: q = o1;
			2'h2: q = o2;
			2'h3: q = o3;
		endcase

endmodule

6. Module add

在这里插入图片描述

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

7. Module fadd

在这里插入图片描述

全加器的逻辑表达式:
sum = a ^ b ^ cin;
cout = (a & b) | ((a ^ b) & cin);
或者 { cout , sum } = a + b + cin;

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

8. Module cseladd

在这里插入图片描述

module top_module(
    input [31:0] a,
    input [31:0] b,
    output [31:0] sum
);

    wire cout1;
    wire [31:16] sum0,sum1;
    
    add16 a1(a[15:0],b[15:0],1'b0,sum[15:0],cout1);
    add16 a2(a[31:16],b[31:16],1'b0,sum0[31:16],);
    add16 a3(a[31:16],b[31:16],1'b1,sum1[31:16],);
    
	//assign sum[31:16] = carry?sum1:sum0;
	
	// 组合逻辑always块
	always @(*)		
		case(cout1)
			1'b0: sum[31:16] = sum0;
			1'b1: sum[31:16] = sum1;
		endcase
    
endmodule

9. module addsub

在这里插入图片描述

加减法器可以由加法器来构建,可以对其中一个数取相反数(对输入数据取反,然后加1)。
最终结果是一个可以执行以下两个操作的电路:
a + b + 0
a + ~b + 1

module top_module(
    input [31:0] a,
    input [31:0] b,
    input sub,
    output [31:0] sum
);
        
    wire [31:0] b_n;
    wire cout;
    
    assign b_n = b^{32{sub}}; //当sub为1时,使用32位的异或门对B进行取反。
    
    add16 a0(a[15:0],b_n[15:0],sub,sum[15:0],cout);
    add16 a1(a[31:16],b_n[31:16],cout,sum[31:16],);

endmodule

第四部分:Procedures

1. alwaysblock 1

有两种 always块 是可以综合出电路硬件的:
组合逻辑:always @(*)
时序逻辑:always @(posedge clk)
【posedge上升沿 、negedge下降沿】

在这里插入图片描述

// 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 @(*) 
        out_alwaysblock = a & b;
    
endmodule

2. alwaysblock 2

在Verilog中有以下三种赋值方法:
连续赋值( assign x=y; ):不能在过程块内使用;
过程阻塞性赋值( x=y; ):只能在过程块中使用;
过程非阻塞性复制( x<=y ):只能在过程块内使用。

在组合always块中,使用阻塞性赋值。
在时序always块中,使用非阻塞性赋值。

在这里插入图片描述

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

3. 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 :a;
    assign out_assign = (sel_b1& sel_b2)? b:a;
    
    always@(*)
        if(sel_b1&sel_b2)
            out_always = b;
        else
            out_always = a;

endmodule

4. Always if 2

组合电路输出必须在所有输入的情况下都有值。这意味着必须需要else子句或着输出默认值。

否则会形成 锁存器

// 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 = ~arrived;
    end

endmodule

5. always_case

case项 允许重复和部分重叠,执行程序匹配到的第一个,而C语言不允许重复的case项目。

【题目】61,其他输出0
// 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: out = data0;
	            3'b001: out = data1;
	            3'b010: out = data2;
	            3'b011: out = data3;
	            3'b100: out = data4;
	            3'b101: out = data5;
	            default: out = 4'b0000;
	        endcase
	    end

endmodule

6. always case 2

【题目】输出 输入向量中的右边第一个1的位置
// synthesis verilog_input_version verilog_2001
module top_module (
    input [3:0] in,
    output reg [1:0] pos  );

    always@(*) 
        begin  // This is a combinational circuit
            case(in)
                4'h0: pos = 2'h0;
                4'h1: pos = 2'h0;
                4'h2: pos = 2'h1;
                4'h3: pos = 2'h0;
                4'h4: pos = 2'h2;
                4'h5: pos = 2'h0;
                4'h6: pos = 2'h1;
                4'h7: pos = 2'h0;
                4'h8: pos = 2'h3;
                4'h9: pos = 2'h0;
                4'ha: pos = 2'h1;
                4'hb: pos = 2'h0;
                4'hc: pos = 2'h2;
                4'hd: pos = 2'h0;
                4'he: pos = 2'h1;
                4'hf: pos = 2'h0;
                default: pos = 2'b0; //本题默认项可有可无,因为以上包含了16种组合
       		endcase
        end

endmodule

7. always casez

casez语句不考虑z的比较过程
casex语句不考虑x与z的比较过程

// synthesis verilog_input_version verilog_2001
module top_module (
    input [7:0] in,
    output reg [2:0] pos  );
    always @(*)
        casez (in)
            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

endmodule

8. 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;
	        casez(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

1. conditional

Verilog跟C语言一样有一个三元运算符( ? : )
condition ? if_true : if_false

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

    // assign intermediate_result1 = compare? true: false;
    wire [7:0] com1; //第一组比较的结果
    wire [7:0] com2; //第二组比较的结果

    assign com1 = a<b? a: b;
    assign com2 = c<d? c: d;
    assign min = com1<com2? com1: com2;

endmodule

2. Reduction

&a [3:0] // AND: a[3] & a[2] & a[1] & a [0] 相当于(a[3:0]== 4’hf)
|b [3:0] // OR: b[3] | b[2] | b[1] | b [0] 相当于(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; 
    
endmodule

3. gates100

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

endmodule

4. Vector100r

  长度是100的向量,翻转输出。

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

    always@(*)begin
        for (int i=0;i<=99;i=i+1)
        	begin
            	out[i]=in[99-i];
       		 end
    end
    
endmodule

5. Popcount 255

  判断输入中 ’1‘ 的个数。

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

    always @ (*)
        begin
            out = 8'b0000_0000;     //为了后面的计数累加,此处先初始化为0.
            for (int i=0; i<255; i++)
                begin
                    if(in[i] == 1'b1)
                        out = out + 1'b1;
                    else
                        out = out + 1'b0;
                end
        end
    
endmodule

6. Adder100i

全加器的逻辑表达式:
sum = a ^ b ^ cin;
cout = (a & b) | ((a ^ b) & cin);
或者 { cout , sum } = a + b + cin;

module top_module( 
    input [99:0] a, b,
    input cin,
    output [99:0] cout,
    output [99:0] sum );
    
    always@(*)
        begin
    		{cout[0],sum[0]} = a[0] + b[0] + cin;
    		for(integer i=1;i<100;i=i+1)
    			{cout[i],sum[i]} = a[i] + b[i] + cout[i-1];
    	end

endmodule

7. bcdadd100

module top_module( 
    input [399:0] a, b,
    input cin,
    output cout,
    output [399:0] sum );

    wire [399:0] cout_temp;
    genvar i;

    bcd_fadd inst1_bcd_fadd (
        .a(a[3:0]),
        .b(b[3:0]),
        .cin(cin),
        .cout(cout_temp[0]),
        .sum(sum[3:0])
    );
    //与上题同理,还是先计算cout[0],我声明一个wire型的cout_temp来存放每次计算后cout的值。


    generate
        for(i=4; i<400; i=i+4)
            begin: bcd
                bcd_fadd inst_bcd_fadd(
                    .a(a[i+3:i]), 
                    .b(b[i+3:i]), 
                    .cin(cout_temp[i-4]), //上次计算输出的cout
                    .cout(cout_temp[i]), //本次计算输出的cout,在下次计算中变为cin
                    .sum(sum[i+3:i])
                );
            end
    endgenerate 

    assign cout = cout_temp[396];   

endmodule

三、电路 Circuits

第一部分 : Combinational Logic

第一节 : BasIc Gates

1. Wire

在这里插入图片描述

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

endmodule

2. GND

在这里插入图片描述

module top_module (
    output out);
    
    assign out = 1'b0;

endmodule

3. NOR

在这里插入图片描述

module top_module (
    input in1,
    input in2,
    output out);

    assign out = ~(in1 | in2);
    
endmodule

4. Another gate

在这里插入图片描述

module top_module (
    input in1,
    input in2,
    output out);

    assign out = in1 & (~in2);

endmodule

5. Two gates

在这里插入图片描述

module top_module (
    input in1,
    input in2,
    input in3,
    output out);
    
    wire out1;
    
    assign out1 = ~(in1 ^ in2);
    assign out = out1 ^in3;

endmodule

6. More logic gates

module top_module( 
    input a, b,
    output out_and,
    output out_or,
    output out_xor,
    output out_nand,
    output out_nor,
    output out_xnor,
    output out_anotb
);
        
    assign out_and = a & b;
    assign out_or  = a | b;
    assign out_xor = a ^ b;
    assign out_nand = ~(a & b);
    assign out_nor = ~(a | b);
    assign out_xnor = ~(a ^ b);
    assign out_anotb = a & (~b);

endmodule

7. 7420 chip

在这里插入图片描述

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

8. Truth tables 真值表

在这里插入图片描述

F = X 3 ‾ X 2 + X 3 ( X 2 ‾ X 1 + X 2 X 1 ) F = X 3 ‾ X 2 + X 3 X 1 \begin{aligned} &\mathrm{F}=\overline{X 3} X 2+X 3(\overline{X 2} X 1+X 2 X 1) \\ &\mathrm{F}=\overline{X 3} X 2+X 3 X 1 \end{aligned} F=X3X2+X3(X2X1+X2X1)F=X3X2+X3X1

module top_module( 
    input x3,
    input x2,
    input x1,  // three inputs
    output f   // one output
);
     
    assign f = (!x3 & x2) | (x3 & x1);

endmodule

9. Two-bit equality

  创建一个两输入inputs A [1:0], B[1:0],一输出Z。当A 与 B 相等时,Z 输出为1, 否则为0;

module top_module ( input [1:0] A, input [1:0] B, output z ); 
    
    always@(*)
        begin
            if(A==B)
                z = 1;
            else
                z=0;
        end

endmodule

10. Simple circuit A

module top_module (input x, input y, output z);
    
    assign z = (x ^ y) & x;

endmodule

11. Simple circuit B

仿真时序

module top_module ( input x, input y, output z );
    
    assign z = x ^ ~y; 

endmodule

12. Combine circuits A and B

在这里插入图片描述

module top_module (input x, input y, output z);
    
    wire IA1z,IB1z,IA2z,IB2z;
    wire tempz1,tempz2;
    
    assign IA1z = (x ^ y) & x;
    assign IB1z = x ^ ~y;
    assign IA2z = (x ^ y) & x;
    assign IB2z = x ^ ~y;
    
    assign tempz1 = IA1z | IB1z;
    assign tempz2 = IA2z & IB2z;
    
    assign z = tempz1 ^ tempz2;
    

endmodule

13. Ring or vibrate

在这里插入图片描述

module top_module (
    input ring,
    input vibrate_mode,
    output ringer,       // Make sound
    output motor         // Vibrate
);

    assign motor = ring & vibrate_mode;
    assign ringer  = ring & (!vibrate_mode);

endmodule

14. Thermostat

module top_module (
    input too_cold,
    input too_hot,
    input mode,
    input fan_on,
    output heater,
    output aircon,
    output fan
); 
    assign heater = mode  & too_cold;
	assign aircon = !mode & too_hot;
	assign fan    = (mode & too_cold) | (!mode & too_hot) | fan_on;

endmodule

15. Popcount3

  ​ 设计一个电路来计算输入中 ‘ 1 ’ 个数。

module top_module( 
    input [2:0] in,
    output [1:0] out );

    always @(*)
        begin
        out = 2'b00;
            for(integer i = 0; i<3; i++)
                begin
                    if(in[i] == 1'b1)
                        out = out + 1'b1;
                end
        end

endmodule

16. Gatesv

module top_module( 
    input [3:0] in,
    output [2:0] out_both,
    output [3:1] out_any,
    output [3:0] out_different);

    assign out_both      = {{in[3] & in[2]}, {in[2] & in[1]}, {in[1] & in[0]}};
    assign out_any       = {{in[3] | in[2]} , {in[2] | in[1]} , {in[1] | in[0]}};
    assign out_different = {{in[0] ^ in[3]}, {in[3] ^ in[2]}, {in[2] ^ in[1]}, {in[1] ^ in[0]}};

endmodule

17. gatesv100

module top_module( 
    input [99:0] in,
    output [98:0] out_both,
    output [99:1] out_any,
    output [99:0] out_different );

    assign out_both = in[98:0] & in[99:1];
    assign out_any  = in[99:1] | in[98:0];
    assign out_different = in ^ {in[0],in[99:1]};

endmodule

第二节: Multiplexers

1. Mux2to1

  2 选 1 选择器,sel 信号作为选择信号,当 sel = 1 时选择 b,反之选择 a。

module top_module( 
    input a, b, sel,
    output out );
    
    assign out = (sel) ? b : a;
    
endmodule

2. Mux2to1v

module top_module( 
    input [99:0] a, b,
    input sel,
    output [99:0] out );
    
    assign out = (sel) ? b : a;

endmodule

3. Mux9to1v

  本题中需要实现一个 9 选 1 选择器,sel 信号作为选择信号,当 sel = 0 时选择 a,sel = 1 时选择 b,以此类推。sel 信号位宽为 4bit,当 sel 大于 8 时,输出 16’hffff。

module top_module( 
    input [15:0] a, b, c, d, e, f, g, h, i,
    input [3:0] sel,
    output [15:0] out );

    always @(*)begin
        case(sel)
            4'd0:out = a;
            4'd1:out = b;
            4'd2:out = c;
            4'd3:out = d;
            4'd4:out = e;
            4'd5:out = f;
            4'd6:out = g;
            4'd7:out = h;
            4'd8:out = i;
            default:out=16'hffff;
        endcase
    end

endmodule

4. mux256to1

  本题中需要实现一个 256 选 1 选择器,sel 信号作为选择信号,当 sel = 0 时选择 in[0],sel = 1 时选择 in[1],以此类推。

module top_module( 
    input [255:0] in,
    input [7:0] sel,
    output out );
    
    assign out = in[sel];

endmodule

5. mux256to1v

  本题中需要实现一个 256 选 1 选择器,sel 信号作为选择信号,当 sel = 0 时选择 in[3:0],sel = 1 时选择 in[7:4],以此类推。同上一题的区别在于,位宽从 1 位变到了 4 位。

module top_module( 
    input [1023:0] in,
    input [7:0] sel,
    output [3:0] out );
    
    assign out = {in[sel*4+3], in[sel*4+2], in[sel*4+1], in[sel*4+0]};

endmodule

  本题如果延续上一题的思考方式: assign out = in[ sel* 4+3 : sel* 4 ]; 但这个表达式不符合 Verilog 片选操作符的语法。片选多个比特的正确语法有两种:

assign out = in[sel*4 +: 4];	// 从 sel*4 开始,选择比特序号大于sel*4 的 4 位比特,相当于[sel*4+3:sel*4]
assign out = in[sel*4+3 -: 4];	// 从 sel*4+3 开始,选择比特序号小于 sel*4+3 的 4 位比特,相当于[sel*4+3:sel*4]

第三节: Arithmetic Circuits

1. Half adder (Hadd)

  本题中需要实现一个 2 进制 1bit 加法器,加法器将输入的两个 1bit 数相加,产生两数相加之和以及进位。

module top_module( 
    input a, b,
    output cout, sum );
    
    assign {cout,sum} = a + b;

endmodule

2. Full adder (Fadd)

  本题中需要实现一个 2 进制 1bit 全加器,全加器与上一题中的加法器的区别在于,除了将输入的两个 1bit 数相加之外,还累加来自前级的进位,产生相加之和以及进位。

module top_module( 
    input a, b, cin,
    output cout, sum );
    
    assign{cout,sum} = a + b + cin;

endmodule

3. 3-bit binary adder(Adder3 )

module top_module( 
    input [2:0] a, b,
    input cin,
    output [2:0] cout,
    output [2:0] sum 
	);
    
    adder U1(
        .a(a[0])
        ,.b(b[0])
        ,.cin(cin)
        ,.cout(cout[0])
        ,.sum(sum[0])
    );
    adder U2(
        .a(a[1])
        ,.b(b[1])
        ,.cin(cout[0])
        ,.cout(cout[1])
        ,.sum(sum[1])
    );
    adder U3(
        .a(a[2])
        ,.b(b[2])
        ,.cin(cout[1])
        ,.cout(cout[2])
        ,.sum(sum[2])

	);

endmodule

module adder( 
    input a, b, cin,
    output cout, sum 
	);
    
    assign{cout,sum} = a + b + cin;
endmodule

4. Adder(Exams/m2014 q4j)

在这里插入图片描述

module top_module (
    input [3:0] x,
    input [3:0] y, 
    output [4:0] sum);
    
    assign sum = x+y; 	// 如果有进位自动扩展成 5 bit数
    assign sum = {x+y}; // 限制为 4 bit数
	
endmodule

5. Signed addition overflow (Exams/ece241 2014 q1c)

module top_module (
    input [7:0] a,
    input [7:0] b,
    output [7:0] s,
    output overflow
); 
 
    assign s = a + b;
    assign overflow = ( a[7] && b[7] && ~s[7] ) || (~a[7] && ~b[7] && s[7]);

endmodule

6. 100-bit binary adder (Adder100)

module top_module( 
    input [99:0] a, b,
    input cin,
    output cout,
    output [99:0] sum );
    
    assign {cout, sum} = a + b + cin;

endmodule

7. 4-digit BCD adder (Bcdadd4)

module top_module ( 
    input [15:0] a, b,
    input cin,
    output cout,
    output [15:0] sum );
    
    wire [4:0] tmp;
    assign tmp[0]=cin;
    assign cout=tmp[4];
    genvar i;
    generate
        for (i=0;i<4;i=i+1)
            begin: bcd
        	bcd_fadd fadd(a[i*4+:4],b[i*4+:4],tmp[i],tmp[i+1],sum[i*4+:4]);
        end
    endgenerate

endmodule

第四节: Karnaugh Map to Circuit

1. 3-variable (Kmap1)

在这里插入图片描述

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

endmodule

2. 4-variable (Kmap2)

在这里插入图片描述

module top_module(
    input a,
    input b,
    input c,
    input d,
    output out  ); 
    
    assign out = ~b&~c | ~a&~d | a&c&d | ~a&b&c;

endmodule

3. 4-variable (Kmap3)

在这里插入图片描述

module top_module(
    input a,
    input b,
    input c,
    input d,
    output out  ); 
    
    assign out = a | (!b & c);

endmodule

4. 4-variable (Kmap4)

在这里插入图片描述

module top_module(
    input a,
    input b,
    input c,
    input d,
    output out  ); 
    
    assign out = (~a&b&~c&~d) | (a&~b&~c&~d) | (~a&~b&~c&d) |  (a&b&~c&d) |  (~a&b&c&d) |  (a&~b&c&d) |  (~a&~b&c&~d) |  (a&b&c&~d);

endmodule

5. Minimum SOP and POS (Exams/ece241 2013 q2)

module top_module (
    input a,
    input b,
    input c,
    input d,
    output out_sop,
    output out_pos
); 

    assign out_sop = (c&d) | (~a&~b&c&~d);
    assign out_pos = (c&~b&~a) | (c&d&~a) | (c&d&b);

endmodule

6. Karnaugh map (Exams/m2014 q3)

在这里插入图片描述

module top_module (
    input [4:1] x, 
    output f );
    
    assign f = (~x[1] & x[3]) |(x[2] & ~x[3] & x[4]);

endmodule

7. Karnaugh map (Exams/2012 q1g)

在这里插入图片描述

module top_module (
    input [4:1] x,
    output f
); 

    assign f = (~x[1] & x[3]) | (x[1]&x[2]&x[3]&x[4]) | (x[1] &~x[2] &~x[4]) | (~x[1] & ~x[2] & ~x[3] & ~x[4]);

endmodule

8. K-map implemented witha multiplexer(Exams/ece241 2014 q3)

在这里插入图片描述

module top_module (
    input c,
    input d,
    output [3:0] mux_in
); 

	always @(*)begin
    	mux_in = 4'b0000; // default
    	case({c,d})
			2'b00: mux_in = 4'b0100;
        	2'b01: mux_in = 4'b0001;
       	 	2'b11: mux_in = 4'b1001;
        	2'b10: mux_in = 4'b0101;
    	endcase
 	end

endmodule

第二部分: Sequential Logic

第一节: Latches and Flip-Flops

1. D flip-flop (DFF)

module top_module (
    input clk,    // Clocks are used in sequential circuits
    input d,
    output reg q );//
	
    always@(posedge clk) 
        q <= d;
    // Use a clocked always block
    //   copy d to q at every positive edge of clk
    //   Clocked always blocks should use non-blocking assignments

endmodule

2. D flip-flops(DFF8)

module top_module (
    input clk,
    input [7:0] d,
    output [7:0] q
);

    always@(posedge clk) 
        q <= d ;
endmodule

3. DFF with reset(DFF8r)

module top_module (
    input clk,
    input reset,            // Synchronous reset
    input [7:0] d,
    output [7:0] q
);
    
    always @ (posedge clk) begin
        if(reset)
            q <= 8'd0;
        else
            q <= d;
    end

endmodule

4. DFF with reset value(DFF8p)

module top_module (
    input clk,
    input reset,
    input [7:0] d,
    output [7:0] q
);

    always @ (negedge clk) begin
        if(reset)
            q = 8'h34;
        else
            q <= d;
    end

endmodule

5. DFF with asynchronous reset(Dff8ar)

module top_module (
    input clk,
    input areset,   // active high asynchronous reset
    input [7:0] d,
    output [7:0] q
);
    
    always @ (posedge clk or posedge areset) begin
        if(areset)
            q <= 8'd0;
        else
            q <= d;
    end
endmodule

6. DFF with byte enable(Dff16e)

module top_module (
    input clk,
    input resetn,
    input [1:0] byteena,
    input [15:0] d,
    output [15:0] q
);

    always @(posedge clk) begin
        if(~resetn)
            q <= 8'b0;
        else
            begin
                if(byteena[0]) 
                    q[7:0] <= d[7:0];
                if(byteena[1])
                    q[15:8] <= d[15:8];
            end
    end
    
endmodule

7. D Latch(Exams/m2014 q4a)

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

    always@ (*)begin
        if(ena)
            q<=d;
    end
endmodule

8. DFF(Exams/m2014 q4b)

module top_module (
    input clk,
    input d, 
    input ar,   // asynchronous reset
    output q);

    
    always@(posedge clk or posedge ar)begin
        if(ar)
            q<=1'b0;
        else
            q<=d;
    end
        
endmodule

9. DFF(Exams/m2014 q4c)

module top_module (
    input clk,
    input d, 
    input r,   // synchronous reset
    output q);
    
    always@(posedge clk) begin
        if(r)
            q<=1'b0;
        else
            q<=d;
    end

endmodule

10. DFF+gate(Exams/m2014 q4d)

module top_module (
    input clk,
    input in, 
    output out);

    always@(posedge clk)
        out <= out^in;
endmodule

11. Mux and DFF(Mt2015 muxdff)

在这里插入图片描述

module top_module (
	input clk,
	input L,
	input r_in,
	input q_in,
	output reg Q);

    wire D;
    assign D = L?r_in:q_in;
    
    always@(posedge clk) 
        Q <= D;
endmodule

12. Mux and DFF(Exams/2014 q4a)

在这里插入图片描述

module top_module (
    input clk,
    input w, R, E, L,
    output Q
);

    wire D0,D1;
    
    assign D0 = E?w:Q;
    assign D1 = L?R:D0;
    
    always@(posedge clk)
        Q <= D1;
    
endmodule

13.

在这里插入图片描述

module top_module (
    input clk,
    input x,
    output z
); 
    wire D1,D2,D3,Q1,Q2,Q3;
    
    assign D1 = x ^ Q1;
    assign D2 = x & ~Q2;
    assign D3 = x | ~Q3	;
    
    assign z = ~(Q1|Q2|Q3);
    
    always@(posedge clk)
        begin
           Q1 <= D1;
           Q2 <= D2;
           Q3 <= D3;
        end

endmodule

14. Create circuit from truth table(Exams/ece241 2013 q7)

在这里插入图片描述
在这里插入图片描述

module top_module (
    input clk,
    input j,
    input k,
    output Q); 

    wire D;
    assign D  = (j&~Q) |(~k&Q);
    
    always@(posedge clk)
        Q <= D;
endmodule

第二节: Counters

1. Four-bit binary counter(Count15)

在这里插入图片描述

module top_module (
    input clk,
    input reset,      // Synchronous active-high reset
    output [3:0] q);

    always @(posedge clk)begin
        if(reset)
            q <= 4'd0;
        else
            q <= q+1'b1;   
    end

endmodule

2. Decade counter(Count10)

在这里插入图片描述

module top_module (
    input clk,
    input reset,        // Synchronous active-high reset
    output [3:0] q);

    always @(posedge clk)begin
        if(reset)
            q <= 4'd0;
        else if(q == 4'd9)
             q <= 4'd0;
        else
            q <= q+1'b1;   
    end
endmodule

3. Decade counter again(Count1to10)

在这里插入图片描述

module top_module (
    input clk,
    input reset,
    output [3:0] q);

    always @(posedge clk)begin
        if(reset || q == 10)
            q <= 1'b1;
        else
            q <= q + 1'b1;
    end
endmodule

4. Slow decade counter(Countslow)

module top_module (
    input clk,
    input slowena,
    input reset,
    output [3:0] q);

    always@(posedge clk)
        if(reset)
            q <= 4'd0;
    	else if(slowena)
            begin
                if(q == 4'd9)
                    q <= 4'd0;
                else
                    q <= q+1'b1;
            end
    	else
            q <= q;
endmodule

5. Counter 1-12


6. Counter 1000


7. 4-digit decimal counter


8. 12-hour clock


第三节: Shift Registers

1.


2.


3.


4.


5.


6.


7.


8.


9.


第四节: More Circuits

1.


2.


3.


第五节: Finite State Machines

1.


2.


3.


4.


5.


6.


7.


8.


9.


10.


11.


12.


13.


14.


15.


16.


17.


18.


第三部分: Building Larger Circuits

四、验证阅读模拟 Verification: Reading Simulations

第一部分: Finding bugs in code

第二部分: Build a circuit from a simulation waveform

五、验证编写测试平台 Verification: Writting Testbenches

第一部分: Clock

第二部分: Testbench1

第三部分: AND gate

第四部分: Testbench2

第五部分: T flip-flop


总结

以上就是各单元解法答案。后续会继续更新。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值