HDLBits note03-Module
1. Module
problem statement
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.
answer
module top_module ( input a, input b, output out );
mod_a intance (a,b,out);
endmodule
2.Module pos
problem statement
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 );
answer
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
3. Module name
problem statement
You are given the following module:
module mod_a ( output out1, output out2, input in1, input in2, input in3, input in4);
answer
module top_module (
input a,
input b,
input c,
input d,
output out1,
output out2
);
mod_a instance1 (.out1(out1),.out2(out2),.in1(a),.in2(b),.in3(c),.in4(d));
endmodule
4. Module shift
problem statement
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.
answer
module top_module ( input clk, input d, output q );
wire q1_2,q2_3;
my_dff mod1(.clk(clk),.d(d),.q(q1_2));
my_dff mod2(.clk(clk),.d(q1_2),.q(q2_3));
my_dff mod3(.clk(clk),.d(q2_3),.q(q));
endmodule
5.Module shift8
problem statement
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 );
answer
module top_module (
input clk,
input [7:0] d,
input [1:0] sel,
output [7:0] q
);
wire [7:0] q1_2,q2_3,q3_4;
my_dff8 mod1(clk,d,q1_2);
my_dff8 mod2(clk,q1_2,q2_3);
my_dff8 mod3(clk,q2_3,q3_4);
always@(*)begin
case (sel)
2'b00: q = d;
2'b01: q = q1_2;
2'b10: q = q2_3;
2'b11: q = q3_4;
endcase
end
endmodule
6. Module add
problem statement
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 );
answer
module top_module(
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire [15:0] midsum1;
wire [15:0] midsum2;
wire midcout1;
wire midcout2;
add16 low (a[15:0],b[15:0],0,midsum1,midcout1);
add16 high (a[31:16],b[31:16],midcout1,midsum2,midcout2);
assign sum={midsum2,midsum1};
endmodule
7. Module fadd
problem statement
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.
answer
module top_module (
input [31:0] a,
input [31:0] b,
output [31:0] sum
);//
wire tmp_cout;
add16 low (a[15:0],b[15:0],0,sum[15:0],tmp_cout);
add16 high (a[31:16],b[31:16],tmp_cout,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
tips: full adder cal also be writen as assign {cout,sum} = a + b + cin;
8. Module cseladd
problem statement
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 );
answer
module top_module(
input [31:0] a,
input [31:0] b,
output [31:0] sum
);
wire tmp_cout;
wire [15:0] output1,output2;
add16 mod (a[15:0],b[15:0],0,sum[15:0],tmp_cout);
add16 mod_0 (a[31:16],b[31:16],0,output1);
add16 mod_1(a[31:16],b[31:16],1,output2);
assign sum[31:16]=(tmp_cout)?output2:output1;
endmodule
9. Module addsub
problem statement
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.
answer
module top_module(
input [31:0] a,
input [31:0] b,
input sub,
output [31:0] sum
);
wire tmp_cout;
wire [31:0] mid_b;
assign mid_b=b^{32{sub}};
add16 low(a[15:0],mid_b[15:0],sub,sum[15:0],tmp_cout);
add16 high(a[31:16],mid_b[31:16],tmp_cout,sum[31:16]);
endmodule
tips: a+b+0 and a+~b+1, represent the add and sub situation.