Verilog Code | Datapath and Controller Design | Design 1 | Multiplication by Repeated Addition

What are Data path and Control Paths in Digital domain ?


Whenever we are trying to build a complex system , it will consist of a mix of combinational and sequential circuits. In this blog we try to come up with Verilog code for  such complex systems.
To begin with a basic idea, we need to understand that in any  complex digital systems, the whole hardware is typically partitioned into two parts, data path and controller part.

The data path  consists of the functional units where all the computations are carried out. So essentially a data path will consist of typically some registers to store some data , multiplexers or adders, subtractors, multipliers, counters and similar functional blocks. So in a datapath part there are a lot of hardware and things which are there but we are not specifying or telling exactly what to do with those hardware. All I can tell is that there are three registers,  there is one adder , one subtractor and one counter but I am not specifying within the data path that exactly how I am going to use them.

So for that there will be a second part which is called a control path . Control path is nothing but a finite state machine (FSM) which s will be generating or providing some control signals for the data path in a particular sequence. And by doing that the data path will get activated accordingly and the operations will be carried out as per the intended requirement. The control path can also take some input from the data path okay to get information of status of the process.

Design Problem :

The first design we take in this regard is a very simple example where we are trying to multiply two integers by repeated addition. So the algorithm is like this we are let's say reading the two numbers A (multiplicand) and B (multiplier) , the product P .



                                                    Fig: Algorithm being implemented



Datapath Unit design :




The data is fed in by the data_in line to the databus. Whenever LdA, LdB control signals go HIGH, the daat from bus is taken and stored in register A and register B respectively. Initially register P, is set to 'zero' value via a control signal named clrP . Then , the data entries in A & P are fed into an Adder and the reuslt is stored back in P, whenver LdP signal goes high. The signals shown in blue are control signals .

After each iteration, we go on decrementing B by one unit . Data entry in register B is decremented to a value of B-1 , whenever control signal decB, goes HIGH. The value of B is monitored via the help of a comparator circuit , which produces an output signal eqz. This goes HIGH if B=0, else it's held in LOW state.

Control Path | FSM | Design :





Signal interfacing in b/w both units :





Verilog Code | Top Level Datapath Module :


`timescale 1ns / 1ps




module MUL_datapath(eqz, LdA, LdB, LdP, clrP, decB, data_in,clk);

input LdA, LdB, LdP, clrP, decB,clk;
input [15:0] data_in;
output eqz;
wire [15:0] X,Y,Z,Bout, Bus;



PIPO1 A (Bus,LdA,clk,X); // Register for A //
PIPO2 P (Z,LdP,clrP,clk,Y); // Register for P //
CNTR B(Bus,LdB,decB,clk,Bout); // Down counter for B //
ADD AD (Z,X,Y); // Adder Module //
EQZ COMP (eqz,Bout); // A comparator ,that checks if B = zero or not //



endmodule

Verilog Code | Blocks in  Datapath Module :

`timescale 1ns / 1ps

/************************* Register Module for data of A **********************/

module PIPO1(
    input [15:0] din,
    input ld,
    input clk,
    output reg [15:0] dout
    );

always@(posedge clk)

    if(ld)
            dout<= din;

endmodule

/************************* Register Module for data of P **********************/

module PIPO2(
    input [15:0] din,
    input ld,
     input clr,
    input clk,
    output reg [15:0] dout
    );

always@(posedge clk)

    if(clr)
            dout<= 16'b0;
            
    else if (ld)     
            dout<= din;

endmodule

/************************* Adder module for (A+P) **********************/

module ADD (out,in1,in2);
input [15:0] in1,in2;
output reg [15:0] out;

always@(*)
        out = in1 + in2 ;
        
endmodule

/*********** Comparator module for checking if B = zero or not ***************/

module EQZ (eqz,data);
input [15:0] data;
output eqz;

assign eqz = (data == 0); // eqz is assigned '1' , if data is equal to '0' //

endmodule

/************************* Down-counter module for B **********************/
module CNTR (
    input [15:0] din,
    input ld,
    input dec,
    input clk,
    output reg [15:0] dout
    );

always@(posedge clk)
        
        if(ld)              // if load is active, load data into register of B //
            dout<= din;
                
        else if(dec)       // If decrement signal is active, then decrement value of B //
            dout <= dout-1;
            
endmodule

Verilog Code | Control Path Module :


`timescale 1ns / 1ps

module controller (LdA, LdB, LdP, clrP, decB, done, clk, eqz, start);

input clk,eqz,start;
output reg LdA, LdB, LdP, clrP, decB, done;

reg [2:0] state;
parameter S0 = 3'b000 , S1 = 3'b001 , S2 = 3'b010 , S3 = 3'b011 , S4 = 3'b100 ;

/************************ State Transistions **********************/

always@(posedge clk)
        begin
                case (state)
                            
                            S0 : if(start) state <= S1;
                            S1 : state <= S2;
                            S2 : state <= S3;
                            S3 : #2 if(eqz) state <= S4;  // delay added so as to get better simulation results //
                            S4 : state <= S4;
                            default : state <= S0;
                        
                endcase
        end                    

/************************ Generation of Control Signals **********************/   
    
    always@(state)
        begin
                    case(state)
                        
                        S0 : begin #1 LdA = 0; LdB = 0; LdP = 0; clrP = 0; decB = 0; end
                        S1 : begin #1 LdA = 1; end
                        S2 : begin #1 LdA = 0; LdB = 1; clrP = 1;  end
                        S3 : begin #1 LdB = 0; LdP = 1; clrP = 0; decB = 1; end
                        S4 : begin #1 done = 1; LdB = 0; LdP = 0; decB = 0; end
                        default : begin #1 LdA = 0; LdB = 0; LdP = 0; clrP = 0; decB = 0; end
                    endcase
        end            
    
endmodule     
   

Verilog Code | Testbench :


`timescale 1ns / 1ps

module testbench;

reg [15:0] data_in;
reg clk,start;
wire done;
wire [15:0] X,Y,Z,Bout, Bus;

MUL_datapath DP (eqz, LdA, LdB, LdP, clrP, decB, data_in,clk);
controller CON (LdA, LdB, LdP, clrP, decB, done, clk, eqz, start);

initial 
begin clk = 1'b0;
#3 start = 1'b1;
#500 $finish;
end

always #5 clk = ~clk;

initial
begin 
    #17 data_in = 17;  // Value to be loaded in A (Multiplicand) //
    #10 data_in = 5;    // Value to be loaded in B (Multiplier) //
end    

initial 
begin 
$monitor ($time, "%d %b", DP.Y,done);
$dumpfile ("mul.vcd");
$dumpvars (0,testbench);


end
endmodule


We come to an end of this post. I hope by the end of this post,  reader realizes that  design of complex digital designs can often by simplified by following a systematic breakdown approach into data path and control path units.

Do share !
For more queries you can contact me at abhishekch0808@gmail.com










Comments

Post a Comment

Popular posts from this blog

Verilog Code | Datapath and Controller Design | Design 2 | GCD of two numbers