HDLBits刷题之Verilg Language->Modules:Hierarchy

14 篇文章 0 订阅
14 篇文章 0 订阅

目录

Module

Write your solution here

Module pos

Write your solution here

Module name

 Write your solution here

Module shift

 Write your solution here

Module shift8

 Write your solution here

Module add

 Write your solution here

Module fadd

 Write your solution here

Module cseladd

 Write your solution here

Module addsub

 Write your solution here


Module

By now, you're familiar with a module, which is a circuit that interacts with its outside through input and output ports. Larger, more complex circuits are built by composing bigger modules out of smaller modules and other pieces (such as assign statements and always blocks) connected together. This forms a hierarchy, as modules can contain instances of other modules.

The figure below shows a very simple circuit with a sub-module. In this exercise, create one instance of module mod_a, then connect the module's three pins (in1, in2, and out) to your top-level module's three ports (wires a, b, and out). The module mod_a is provided for you — you must instantiate it.

When connecting modules, only the ports on the module are important. You do not need to know the code inside the module. The code for module mod_a looks like this:

module mod_a ( input in1, input in2, output out );
    // Module body
endmodule

The hierarchy of modules is created by instantiating one module inside another, as long as all of the modules used belong to the same project (so the compiler knows where to find the module). The code for one module is not written inside another module's body (Code for different modules are not nested).

You may connect signals to the module by port name or port position. For extra practice, try both methods.

Connecting Signals to Module Ports

There are two commonly-used methods to connect a wire to a port: by position or by name.

By position

The syntax to connect wires to ports by position should be familiar, as it uses a C-like syntax. When instantiating a module, ports are connected left to right according to the module's declaration. For example:

mod_a instance1 ( wa, wb, wc );

This instantiates a module of type mod_a and gives it an instance name of "instance1", then connects signal wa (outside the new module) to the first port (in1) of the new module, wb to the second port (in2), and wc to the third port (out). One drawback of this syntax is that if the module's port list changes, all instantiations of the module will also need to be found and changed to match the new module.

By name

Connecting signals to a module's ports by name allows wires to remain correctly connected even if the port list changes. This syntax is more verbose, however.

mod_a instance2 ( .out(wc), .in1(wa), .in2(wb) );

The above line instantiates a module of type mod_a named "instance2", then connects signal wa (outside the module) to the port named in1, wb to the port named in2, and wc to the port named out. Notice how the ordering of ports is irrelevant here because the connection will be made to the correct name, regardless of its position in the sub-module's port list. Also notice the period immediately preceding the port name in this syntax.

Write your solution here

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

    //top_module instance1(a,b,out);//按位置实例化
    mod_a instance2(.out(out),.in1(a),.in2(b));//按名字实例化
    
endmodule

Module pos

This problem is similar to the previous one (module). You are given a module named mod_a that has 2 outputs and 4 inputs, in that order. You must connect the 6 ports by position to your top-level module's ports out1, out2, a, b, c, and d, in that order.

You are given the following module:

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

Write your solution here

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 
    //module mod_a ( output, output, input, input, input, input );

endmodule

Module name

This problem is similar to module. You are given a module named mod_a that has 2 outputs and 4 inputs, in some order. You must connect the 6 ports by name to your top-level module's ports:

Port in mod_aPort in top_module
output out1out1
output out2out2
input in1a
input in2b
input in3c
input in4d

You are given the following module:

module mod_a ( output out1, output out2, input in1, input in2, input in3, input in4);

 Write your solution here

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

endmodule

Module shift

You are given a module my_dff with two inputs and one output (that implements a D flip-flop). Instantiate three of them, then chain them together to make a shift register of length 3. The clk port needs to be connected to all instances.

The module provided to you is: module my_dff ( input clk, input d, output q );

Note that to make the internal connections, you will need to declare some wires. Be careful about naming your wires and module instances: the names must be unique.

 Write your solution here

module top_module ( input clk, input d, output q );
	//module my_dff ( input clk, input d, output q );
    wire q1,q2;//实例化模块与模块直接的连线用唯一的wire定义
    
    my_dff instance1(.q(q1),.clk(clk),.d(d));//my_dff instance1(clk,d,q1);
    my_dff instance2(clk,q1,q2);
    my_dff instance3(clk,q2,q);
    
endmodule

Module shift8

This exercise is an extension of module_shift. Instead of module ports being only single pins, we now have modules with vectors as ports, to which you will attach wire vectors instead of plain wires. Like everywhere else in Verilog, the vector length of the port does not have to match the wire connecting to it, but this will cause zero-padding or trucation of the vector. This exercise does not use connections with mismatched vector lengths.

You are given a module my_dff8 with two inputs and one output (that implements a set of 8 D flip-flops). Instantiate three of them, then chain them together to make a 8-bit wide shift register of length 3. In addition, create a 4-to-1 multiplexer (not provided) that chooses what to output depending on sel[1:0]: The value at the input d, after the first, after the second, or after the third D flip-flop. (Essentially, sel selects how many cycles to delay the input, from zero to three clock cycles.)

The module provided to you is: module my_dff8 ( input clk, input [7:0] d, output [7:0] q );

The multiplexer is not provided. One possible way to write one is inside an always block with a case statement inside. (See also: mux9to1v)

 Write your solution here

module top_module ( 
    input clk, 
    input [7:0] d, 
    input [1:0] sel, 
    output [7:0] q 
);
    //module my_dff8 ( input clk, input [7:0] d, output [7:0] q );
    wire [7:0] q1,q2,q3;//模块与模块中的连线有三条
    my_dff8 instance1(.clk(clk),.d(d),.q(q1));
    my_dff8 instance2(.clk(clk),.d(q1),.q(q2));
    my_dff8 instance3(.clk(clk),.d(q2),.q(q3));

    always@(*)
        case(sel)
            2'b11:q=q3;//注意顺序和图中一样
            2'b10:q=q2;
            2'b01:q=q1;
            2'b00:q=d;
        endcase
endmodule

Module add

You are given a module add16 that performs a 16-bit addition. Instantiate two of them to create a 32-bit adder. One add16 module computes the lower 16 bits of the addition result, while the second add16 module computes the upper 16 bits of the result, after receiving the carry-out from the first adder. Your 32-bit adder does not need to handle carry-in (assume 0) or carry-out (ignored), but the internal modules need to in order to function correctly. (In other words, the add16 module performs 16-bit a + b + cin, while your module performs 32-bit a + b).

Connect the modules together as shown in the diagram below. The provided module add16 has the following declaration:

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

 Write your solution here

module top_module(
    input [31:0] a,
    input [31:0] b,
    output [31:0] sum
);
	//module add16 ( input[15:0] a, input[15:0] b, input cin, output[15:0] sum, output cout );
    wire cin1,cout;
    //add16 instance1(a[15:0],b[15:0],0,sum[15:0],cin1);
    add16 instance1(.a(a[15:0]),.b(b[15:0]),.cin(0),.sum(sum[15:0]),.cout(cin1));
    add16 instance2(a[31:16],b[31:16],cin1,sum[31:16],cout);
endmodule

Module fadd

In this exercise, you will create a circuit with two levels of hierarchy. Your top_module will instantiate two copies of add16 (provided), each of which will instantiate 16 copies of add1 (which you must write). Thus, you must write two modules: top_module and add1.

Like module_add, you are given a module add16 that performs a 16-bit addition. You must instantiate two of them to create a 32-bit adder. One add16 module computes the lower 16 bits of the addition result, while the second add16 module computes the upper 16 bits of the result. Your 32-bit adder does not need to handle carry-in (assume 0) or carry-out (ignored).

Connect the add16 modules together as shown in the diagram below. The provided module add16 has the following declaration:

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

Within each add16, 16 full adders (module add1, not provided) are instantiated to actually perform the addition. You must write the full adder module that has the following declaration:

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

Recall that a full adder computes the sum and carry-out of a+b+cin.

In summary, there are three modules in this design:

  • top_module — Your top-level module that contains two of...
  • add16, provided — A 16-bit adder module that is composed of 16 of...
  • add1 — A 1-bit full adder module.


If your submission is missing a module add1, you will get an error message that says Error (12006): Node instance "user_fadd[0].a1" instantiates undefined entity "add1"

 Write your solution here

module top_module (
    input [31:0] a,
    input [31:0] b,
    output [31:0] sum
);//
//module add16 ( input[15:0] a, input[15:0] b, input cin, output[15:0] sum, output cout );
    wire cout1,cout2;
    add16 instance1(a[15:0], b[15:0], 0,sum[15:0], cout1);
    add16 instance2(a[31:16], b[31:16], cout1,sum[31:16], cout2);
endmodule

module add1 ( input a, input b, input cin,   output sum, output cout );
    //全加器
    //真值表
    //  cin  a  b  sum  cout
    //   0   0  0   0    0
    //   0   0  1   1    0
    //   0   1  0   1    0
    //   0   1  1   0    1
    //   1   0  0   1    0
    //   1   0  1   0    1
    //   1   1  0   0    1
    //   1   1  1   1    1

	assign sum=a^b^cin; // ^异或
    assign cout=(cin&(a^b))|(a&b);
    
// Full adder module here

endmodule

Module cseladd

One drawback of the ripple carry adder (See previous exercise) is that the delay for an adder to compute the carry out (from the carry-in, in the worst case) is fairly slow, and the second-stage adder cannot begin computing its carry-out until the first-stage adder has finished. This makes the adder slow. One improvement is a carry-select adder, shown below. The first-stage adder is the same as before, but we duplicate the second-stage adder, one assuming carry-in=0 and one assuming carry-in=1, then using a fast 2-to-1 multiplexer to select which result happened to be correct.

In this exercise, you are provided with the same module add16 as the previous exercise, which adds two 16-bit numbers with carry-in and produces a carry-out and 16-bit sum. You must instantiate three of these to build the carry-select adder, using your own 16-bit 2-to-1 multiplexer.

Connect the modules together as shown in the diagram below. The provided module add16 has the following declaration:

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

 Write your solution here

module top_module(
    input [31:0] a,
    input [31:0] b,
    output [31:0] sum
);
    
//module add16 ( input[15:0] a, input[15:0] b, input cin, output[15:0] sum, output cout );
    wire cout1,cout2,cout3;
    wire [15:0] sum2,sum3;//注意位宽  和上面一位不一样
    add16 instance1(a[15:0],b[15:0],0,sum[15:0],cout1);
    add16 instance2(a[31:16],b[31:16],0,sum2,cout2);
    add16 instance3(a[31:16],b[31:16],1,sum3,cout3);
    always@(*)
        case(cout1)
            1'b0:sum[31:16]=sum2;
            1'b1:sum[31:16]=sum3;   
        endcase
endmodule

Module addsub

An adder-subtractor can be built from an adder by optionally negating one of the inputs, which is equivalent to inverting the input then adding 1. The net result is a circuit that can do two operations: (a + b + 0) and (a + ~b + 1). See Wikipedia if you want a more detailed explanation of how this circuit works.

Build the adder-subtractor below.

You are provided with a 16-bit adder module, which you need to instantiate twice:

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

Use a 32-bit wide XOR gate to invert the b input whenever sub is 1. (This can also be viewed as b[31:0] XORed with sub replicated 32 times. See replication operator.). Also connect the sub input to the carry-in of the adder.

 Write your solution here

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 cout1,cout2;
    wire [31:0] b2;
    always@(*)
        case(sub)
            1'b0:b2=b;
            1'b1:b2=~b;
        endcase
    //等于
    //if(sub)
    //	b2=~(b[31:0]);
    //else
    //	b2=b[31:0];
    add16 instance1(a[15:0],b2[15:0],sub,sum[15:0],cout1);
    add16 instance2(a[31:16],b2[31:16],cout1,sum[31:16],cout2);
endmodule

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值