[HDLBits Brush Question 3] Verilog Language (3) Modules Hierarchy part

Hits: 0

Table of contents

write in front

Modules: Hierarchy

Module

Module pos

Module name

Module shift

Module shift8

Module add

Module fadd

Module cseladd

Module addsub

write in front

This part mainly gives the answers and waveform simulation images directly, and may explain the details of some topics.

Modules: Hierarchy

Module

Instantiating a module 
by name connects signals to the module’s ports allowing the wires to stay connected correctly even if the port list changes.    
mod_a instance2 ( 
.out(wc), 
.in1(wa), 
 .in2(wb) 
 );    
The above line instantiates a module of type named “instance2” and then connects the signal (external to the module) to a port named , named port, and named port. Note that the order of the ports is irrelevant here as the correct name will be established regardless of its position in the submodule’s port list. 

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

endmodule

Simulation waveform

Module pos

You will get a module called mod_a with 2 outputs and 4 inputs (in that order).
The 6 ports must be connected in that order to the ports of the top-level module by position.

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

endmodule

Simulation waveform

Module name

Instantiate the module, the port corresponding to the connection.

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

endmodule

Simulation waveform

Module shift

You will get a block with two inputs and one output (implementing a D flip-flop). Three of them are instantiated and then chained together to form a shift register of length 3. This 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 internal connections you need to declare some wires. Be careful when naming wire and module instances: the names must be unique.

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

    wire      shift1;
    wire      shift2;

my_dff my_dff_inst(
    .clk(clk),
    .d(d),
    .q(shift1)
    );

my_dff my_dff_u(
    .clk(clk),
    .d(shift1),
    .q(shift2)
    );

my_dff inst_my_dff(
    .clk(clk),
    .d(shift2),
    .q(q)
    );

endmodule

Simulation waveform

Module shift8

A block with two inputs and one output (implementing a set of 8 D flip-flops). Three of them are instantiated and then chained together to form an 8-bit wide shift register of length 3. Also, create a 4-to-1 multiplexer (not provided) that selects what the output depends on: the value at input d, after the first D, after the second multiplexer , or the value after the third D flip-flop. Essentially, choose the number of cycles to delay the input, from zero to three clock cycles.

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

    wire [7:0]    shift1;
    wire [7:0]    shift2;
    wire [7:0]    shift3;

my_dff8 my_dff8_inst(
    .clk(clk),
    .d(d),
    .q(shift1)
    );

my_dff8 my_dff8_u(
    .clk(clk),
    .d(shift1),
    .q(shift2)
    );

my_dff8 inst_my_dff8(
    .clk(clk),
    .d(shift2),
    .q(shift3)
    );

always  @(*) begin 
    case(sel) 
        0 : begin 
            q = d; 
        end 
        1 : begin 
            q = shift1; 
        end 
        2 : begin 
            q = shift2; 
        end 
        3 : begin 
            q = shift3; 
        end 
    endcase 
end

endmodule

Simulation waveform

Module add

A module that performs 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 execution from the first adder. 32-bit adders do not need to handle carry (assume 0) or execute (ignore), but internal modules do to work properly. (In other words, modules do 16-bit a + b + cin, while modules do 32-bit a + b).

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

wire  [15:0]   sum1;
wire  [15:0]   sum2;
wire           cout;

add16 add16_inst_l(
    .a(a[15:0]),
    .b(b[15:0]),
    .cin('d0),
    .cout(cout),
    .sum(sum1)
    );

add16 add16_inst_h(
    .a(a[31:16]),
    .b(b[31:16]),
    .cin(cout),
    .sum(sum2)
    );

assign sum = {sum2,sum1};

endmodule

Simulation waveform

Module fadd

A module that performs 16-bit addition. Two of them must be instantiated to create a 32-bit adder. One module computes the lower 16 bits of the addition result, while the second module computes the upper 16 bits of the result. 32-bit adders do not need to handle carry (assume 0) or execute (ignore).  
     module add16 ( 
         input[15:0] a, 
         input[15:0] b, 
         input cin, 
         output[15:0] sum, 
         output cout 
     );     
in each, 16 full adders (module, not provided ) is instantiated to actually perform the addition. A complete adder module module add1 (          input a,          input b,          input cin,          output sum,          output cout    )     
must be written with the following declarations ; there are three modules in this design: top_module The top-level module, which contains two add16s, provides a 16-bit add The adder module consists of 16 add1 1-bit complete adder modules.

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

wire  [15:0]   sum1;
wire  [15:0]   sum2;
wire           cout;

add16 add16_inst_l(
    .a(a[15:0]),
    .b(b[15:0]),
    .cin('d0),
    .cout(cout),
    .sum(sum1)
    );

add16 add16_inst_h(
    .a(a[31:16]),
    .b(b[31:16]),
    .cin(cout),
    .sum(sum2)
    );
assign sum = {sum2,sum1};

endmodule

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

assign {cout,sum} = a+b+cin;

endmodule

Simulation waveform

Module cseladd

The disadvantage of choosing an adder is the delay in the calculation of the adder, and the calculation of the next stage can only be performed by obtaining the carry value of the previous stage. An improved method is to use a selection adder. The first stage adder is the same as before, but we duplicate the second stage adder, assuming one carries a 0 and the other a 1, using a 2-to-1 multiplexer to choose which result happens to be correct. Provides the same module as the previous exercise that adds two 16-bit numbers and generates a carry and 16-bit sum Three of them must be instantiated to use their own 16-bit 2-to-1 multiplexer Build a carry-select adder.
module add16 ( 
    input[15:0] a, 
    input[15:0] b, 
    input cin, 
    output[15:0] sum, 
    output cout 
);

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

wire  [15:0]   sum1;
wire  [15:0]   sum2;
wire  [15:0]   sum3;
wire           cout;

add16 add16_inst_l(
    .a(a[15:0]),
    .b(b[15:0]),
    .cin('d0),
    .cout(cout),
    .sum(sum1)
    );

add16 add16_inst_h_0(
    .a(a[31:16]),
    .b(b[31:16]),
    .cin('d0),
    .sum(sum2)
    );

add16 add16_inst_h_1(
    .a(a[31:16]),
    .b(b[31:16]),
    .cin('d1),
    .sum(sum3)
    );

always @(*) begin
    case(cout)
        0:begin
            sum = {sum2,sum1};
        end
        1:begin
            sum = {sum3,sum1};
        end
    endcase
end

endmodule

Simulation waveform

Module addsub

Adder-Subtractor can be constructed from an adder by selectively negating one of the inputs, which is equivalent to inverting the input and then adding 1.
The end result is a circuit that does two things: (a + b + 0) and (a + ~b + 1).
XOR with 0 remains unchanged, XOR with 1 is equivalent to negation.
A 16-bit adder module is provided, you need to instantiate it twice:
module add16 ( 
    input[15:0] a, 
    input[15:0] b, 
    input cin, 
    output[15:0] sum, 
    output cout 
);
uses a 32-bit wide XOR gate that inverts the b input when sub is 1. (This can also be seen as b[31:0]XORed, the
sub is copied 32 times. See the copy operator) Also connect the sub input to the adder’s carry. 

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

reg   [31:0]   c;
wire  [15:0]   sum1;
wire  [15:0]   sum2;
wire           cout;

always @(*) begin
    if (~sub) begin
        c = b;
    end
    else begin
        c = ~b;
    end
end

add16 add16_inst_l(
    .a(a[15:0]),
    .b(c[15:0]),
    .cin( sub ),
    .cout(cout),
    .sum(sum1)
    );

add16 add16_inst_h(
    .a(a[31:16]),
    .b(c[31:16]),
    .cin(cout),
    .sum(sum2)
    );

assign sum = {sum2,sum1};

endmodule

Simulation waveform

You may also like...

Leave a Reply

Your email address will not be published.