HDLBits答案(3)_Verilog模块的例化与调用

HDLBits_Verilog模块的例化与调用

HDLBits链接


模块

只要使用的所有模块都属于同一个项目,就可以通过在模块内部实例化一个模块来创建模块的层次结构。一个模块的代码不能在另一个模块的主体中编写(不同模块的代码不是嵌套的)。

有两种常见的方式将wire信号连接到端口上,分别是按位置和按名称连接。

按位置:mod_a instance1 ( wa, wb, wc );

按名称:mod_a instance2 ( .out(wc), .in1(wa), .in2(wb) );

  • By position:mod_a instance1 ( wa, wb, wc );

题目描述:完成mod_a模块的调用

Solution

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

[David说]:模块调用两种方式:按位置调(简洁但不稳,顺序不可乱),按名称调(繁琐但很稳,顺序可变)


按位置连接端口

题目描述

已有一个名为mod_a的模块,它有2个输出和4个输入。您必须按位置将这6个端口连接到顶层模块的端口out1、out2、a、b、c和d,并按顺序进行连接。

给定如下的模块:

module mod_a ( output, output, input, input, input, input );

1.png

Solution:

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

按名称连接端口

题目描述:按名称调模块mod_a

2.png

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

三个模块的调用

题目描述

已有一个模块my_dff,其中有两个输入和一个输出(D触发器)。实例化三个D触发器然后将它们连接在一起,实现一个长度为3的移位寄存器。clk端口需要连接到所有my_dff实例。

已有模块: module my_dff ( input clk, input d, output q );

3.png

Solution

module top_module ( input clk, input d, output q );
	wire temp1;
    wire temp2;
    my_dff block1(clk,d,temp1);
    my_dff block2(clk,temp1,temp2);
    my_dff block3(clk,temp2,q);
endmodule

[David说]:内部调用多个模块时,定义合理的wire信号连接内部的模块。


模块输入为向量

题目描述

已有一个模块my_dff8,它具有两个输入和一个输出(实现一组8位的D触发器)。实例化其中的三个,然后将它们连接在一起,实现一个长度为3的8位宽移位寄存器。另外,构造一个4-1多路选择器,根据sel[1:0]选择输出值。本质上,sel选择的是延迟输入的周期。

已有模块: module my_dff8 ( input clk, input [7:0] d, output [7:0] q );

4.png

Solution

module top_module ( 
    input clk, 
    input [7:0] d, 
    input [1:0] sel, 
    output [7:0] q 
);
    wire [7:0] out1;
    wire [7:0] out2;
    wire [7:0] out3;
    
    my_dff8 block1(clk,d,out1);
    my_dff8 block2(clk,out1,out2);
    my_dff8 block3(clk,out2,out3);
    
    always @(*) begin
        case(sel)
            2'b00:
                q=d;
            2'b01:
                q=out1;                
            2'b10:
                q=out2;                
            2'b11:
                q=out3;                
        endcase
    end
endmodule

[David说]:wire与wire类型之间的连接直接用非阻塞赋值=连接即可。


加法器模块1

题目描述:用两个带进位的16bit加法器组成一个32bit加法器。

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

5.png

Solution

module top_module(
    input [31:0] a,
    input [31:0] b,
    output [31:0] sum
);
    wire [15:0] low_out;
    wire [15:0] high_out;
    wire temp_cout;
    wire cout;
    
    add16 low (a[15:0],b[15:0],0,low_out,temp_cout);
    add16 high(a[31:16],b[31:16],temp_cout,high_out,cout);
    
    assign sum={high_out,low_out};    
endmodule

[David说]:注意采用流拼接简化代码,无用信号接口作为输出也可以不进行管脚信号的定义。


加法器模块2

题目描述

自定义一个1bit的全加器,构成一个16bit全加器,然后用两个16bit全加器完成32bit加法模块的搭建,忽略进位。

1、定义一个1bit全加器。2、在顶层完成两个16bit全加器的调用。

6.png

Solution

module top_module (
    input [31:0] a,
    input [31:0] b,
    output [31:0] sum
);
    wire temp_cout;
  
    add16 low (a[15:0],b[15:0],0,sum[15:0],temp_cout);
    add16 high(a[31:16],b[31:16],temp_cout,sum[31:16]);
endmodule

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

进位选择加法器

题目描述

在这个练习中,已有和上一个练习相同的模块add16,本题将两个带进位的16位数字相加,并生成一个输出进位和16位的和。需构造一个16位2-1多路选择器。

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

7.png

[David说]:提前加法器进位的计算,用资源换速度。

Solution:

module top_module(
    input [31:0] a,
    input [31:0] b,
    output [31:0] sum
);
    wire [15:0] highout0;
    wire [15:0] highout1;
    wire cout;
    
    add16 low(a[15:0],b[15:0],0,sum[15:0],cout);
    add16 high0(a[31:16],b[31:16],0,highout0);
    add16 high1(a[31:16],b[31:16],1,highout1);
    
    assign sum[31:16]=cout? highout1:highout0;
endmodule

加法器→减法器

题目描述:利用sub信号和两个16bit的全加器,实现32bit的加减法运算。

对输入的sub信号进行判断,如果sub=0,则输出(a + b + 0);如果sub=1,则输出(a + ~b + 1)。

已有模块:

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

tip: Use a 32-bit wide XOR gate to invert the b input whenever sub is 1.

8.png

Solution:

module top_module(
    input [31:0] a,
    input [31:0] b,
    input sub,
    output [31:0] sum
);
    wire [31:0] b_processed;
    wire cout_temp;
    assign b_processed = b ^ {32{sub}};
    
    add16 lower(a[15:0],b_processed[15:0],sub,sum[15:0],cout_temp);
    add16 higher(a[31:16],b_processed[31:16],cout_temp,sum[31:16]);
endmodule

[David说]:巧用sub信号对输入b处理,妙!


总结:

学习了模块的例化与调用,深刻理解对着电路图写HDL这句话。

Verilog模块例化是指在代码中调用其他模块以构建更大的系统。它类似于面向对象编程中的函数调用。这种方法可以使设计过程更加高效,代码更易于管理。下面是verilog模块例化语法的详细介绍。 Verilog模块例化是通过实例化模块来使用的。在模块调用之前,需要定义模块的接口。在verilog中,模块接口由输入、输出和其他模块参数组成。模块定义使用“module”关键字并指定模块名称。模块接口由“input”和“output”关键字加上端口名称和端口宽度组成。例如: module MyModule(input a, output b, output [0:7] c); 模块接口定义后,可以在其他模块中实例化模块并将其连接到其他模块模块例化使用“instan”关键字,指定模块名称、实例名称和连接的端口。例如: MyModule my_inst(.a(input_signal), .b(output_signal), .c(output[3:5])); 上面的例子中,MyModule被实例化为名为my_inst的实例。输入信号input_signal连接到a端口,输出信号output_signal连接到b端口,output[3:5]连接到c端口,这是将output端口中的3~5位连接到my_inst的端口。 在实例化的过程中,如果想要连接一个未命名的端口,可以使用“.”加上端口名称进行连接。例如: MyModule my_inst(.a, .b, .c); 在这种情况下,连接的端口的信号将默认为当前环境中有同名的信号,也可以使用其他方式进行连接。 总之,Verilog模块例化是将多个模块连接在一起,建立复杂的电路系统的方法。它本质上是在不同的模块之间创建通道,以实现数据和信号的传输。模块例化可以使设计过程更具模块化、可维护性和灵活性。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

日拱一卒_未来可期

若复习顺利望有闲钱的同学支持下

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值