HDLbits刷题系列1-Verilog/Module

  • 概述

电路设计中通过module进行实例化设计来组合成更复杂的电路,连接module时,只要知道module的端口即可,无须关注内部实现。关于连接信号到module有两种方式:端口名称或端口位置。

  1. 按位置连线:根据module端口的定义顺序进行端口连接;例如:mod_a instance1(a, b, out);
  2. 按名称连线:根据模块名进行连接。例如:mod_a instance2(.out(out), .in1(a), .in2(b)); 实际项目中推荐使用该方法。
  • 原理图+代码+仿真截图

  • Modules

//Modules 
module top_module ( input a, input b, output out );
    mod_a instance1(.in1(a), .in2(b), .out(out)); //by name
    // mod_a instance2(a, b, out); //by position
endmodule

 

  •  Module pos

module top_module ( 
    input a, 
    input b, 
    input c,
    input d,
    output out1,
    output out2
);
    mod_a instance1(out1, out2, a, b, c, d); // by position
endmodule

 

 Module Name

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

 

  •  Module shift

 

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

    wire q1,q2;
    
    my_dff int1(.clk(clk), .d(d), .q(q1));
    my_dff int2(.clk(clk), .d(q1), .q(q2));
    my_dff int3(.clk(clk), .d(q2), .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] q1, q2, q3, q4;
    
    my_dff8 inst1(.clk(clk), .d(d), .q(q1));
    my_dff8 inst2(.clk(clk), .d(q1), .q(q2));
    my_dff8 inst3(.clk(clk), .d(q2), .q(q3));
    
    always @(sel)
        begin
            case(sel)
                0: q4 = d;
                1: q4 = q1;
                2: q4 = q2;
                3: q4 = q3;
            endcase
        end
            
	assign q = q4;
endmodule

 

  •  Module add

使用两个16位的加法器,组成一个32位的加法器。

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

    wire low_cout, high_cout;
    wire [15:0] low_sum, high_sum;
    
    add16 low(.a(a[15:0]), .b(b[15:0]), .cin(0), .sum(low_sum), .cout(low_cout)); // create low 16bits adder
    add16 high(.a(a[31:16]), .b(b[31:16]), .cin(low_cout), .sum(high_sum), .cout(high_cout));// create high 16bits adder
    
    assign sum = {high_sum, low_sum};
endmodule

 

  •  Module fadd

 加法器是数字设计中最重要的基本模块,开始这道题目实现错误了,原因是因为add1模块的sum和cout的书写顺序错误导致的( assign {cout, sum} = a + b + cin),应该先写进位,后写和

另外这种加法器的缺点就是时间效率太差,后一位加法器,必须等待前一位加法器的进位。

 

module top_module (
    input [31:0] a,
    input [31:0] b,
    output [31:0] sum
);//
	wire cout_low, cout_high;
    add16 low16(
        .a(a[15:0]),
        .b(b[16:0]),
        .cin(0),
        .sum(sum[15:0]),
        .cout(cout_low)
    );
    add16 high16(
        .a(a[31:16]),
        .b(b[31:16]),
        .cin(cout_low),
        .sum(sum[31:16]),
        .cout(cout_high)
    );
endmodule


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

// Full adder module here
    assign {cout, sum} = a + b + cin;

endmodule

 

  •  Module cseladd

为了克服前一个加法器的时间效率的问题,这个就是改进版的题目。

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

    wire cout_low;
    wire [15:0] sum1, sum2;
    
    add16 low16(
        .a(a[15:0]),
        .b(b[15:0]),
        .cin(0),
        .cout(cout_low),
        .sum(sum[15:0])
    );
    
    add16 high16_1(
        .a(a[31:16]),
        .b(b[31:16]),
        .cin(0),
        .cout(),
        .sum(sum1)
    );
    
    add16 high16_2(
        .a(a[31:16]),
        .b(b[31:16]),
        .cin(1),
        .cout(),
        .sum(sum2)
    );
    
    assign sum[31:16] = (cout_low == 1) ? sum2 : sum1;
endmodule

  •  Module addsub 

练习了加法器,那减法器就是加上一个负数来实现,负数的补码表示原码取反加1。电路原理图如下:

另外,xor异或实现取反的操作。根据电路图实现代码。

 

module top_module(
    input [31:0] a,
    input [31:0] b,
    input sub,
    output [31:0] sum
);
	
    wire cout_low;
    wire [31:0] b_cin;
    
    add16 low(
        .a(a[15:0]),
        .b(b_cin[15:0]),
        .cin(sub),
        .cout(cout_low),
        .sum(sum[15:0])
    );
    
    add16 hight(
        .a(a[31:16]),
        .b(b_cin[31:16]),
        .cin(cout_low),
        .cout(),
        .sum(sum[31:16])
    );
    
    assign b_cin = b ^ {32{sub}};
    
endmodule

  • 总结

本节刷题,目的是使用module模块时按名称连线,这样代码代码可读性较强,即使端口列表顺序变化了。

 

 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值