Design of Four-bit Multiplier Based on Verilog

1. Introduction to binary multiplication

The binary number multiplication process can be modeled as the decimal number multiplication. But since binary numbers have only two possible multiplier bits, 0 or 1, binary multiplication is simpler. The rule of binary number multiplication is: 0X0=0,01=1X0=0,1X1=1.

From the low bit to the high bit, use each bit of the multiplier to multiply the multiplicand. If a bit of the multiplier is 1, the sub-part product is the multiplicand; if a bit of the multiplier is 0, the multiplicand The subpart product is 0. The lowest bit of a certain partial product must be aligned with the standard multiplier, and the result of adding all partial products is the product obtained by multiplication.

2. Flow chart design:

According to the above algorithm, first design a flow chart of binary multiplication, as shown in Figure 4. The first step in the flow chart is the idle step. In this step, the circuit does not do any work, waiting for the input of the multiplier and multiplicand and START signal input. After detecting that the START signal is valid, the circuit enters the initialization state, and in this state, the P product term, the G carry terminal and the C counter are cleared.

Then the circuit judges whether Qlsb, that is, the least significant bit of the Q register is 1. If it is 1, the addition operation of the high 4 bits of P and the R register is completed, and the carry bit is G. If Qlsb is 0, skip the addition operation and directly enter the shift operation. After the addition of P and R, the next step is to directly jump to the shift operation. In the shift step, the right shift operation of P and Q is completed, and the operation of adding 1 to the C counter is completed at the same time.

After the shift step, it is judged whether C is equal to 3. If it is equal to 3, it will directly enter the done step, and the multiplication calculation process ends. Otherwise, go to the step of judging Q_lsb again. The next step is to complete 4 shift operations in the flow chart as described above. Therefore, the final result of C should be 4. The judgment here is whether it is equal to 3 or not, considering that the circuit is in the process of implementation The result of adding 1 will only appear in the next cycle. In the current clock cycle, it can only be judged whether the result is equal to 4 or not.

3. Data channel design:

The data channel comes from the interpretation of the flow chart, and the flow chart is decomposed below. It can be seen in the flowchart that the R register is required to store the multiplicand. The Q shift register is needed, which can perform right shift operation and save data; the product term register P is needed in the circuit, and P can realize the right shift function and the data save function.

The G carry register is required, and this register can also realize the right shift function. An adder is needed during the addition operation. The adder completes the addition of the high 4 bits of P and the R multiplicand. The result of the addition is stored in the P register, and the carry bit is stored in the G register. A counter is needed in the counting process, and the counter counts once every time it completes a shift operation. The specific data channel is shown in Figure 4.7.

//DataPath overall data channel
module datapath(
    clk, clr, shift, cnt_en, ld_P, ld_R,
    ld_Q, ld_g, R, Q, P, eq_3, Q_lsb,
    P_H_OUT, P_L_OUT, ge, shi, bai, R_shi, Q_shi, R_ge, Q_ge
    );
input clk, clr, shift, cnt_en, ld_P, ld_R, ld_Q, ld_g;
input [3:0] R,Q;
output [7:0] P;
output [3:0] P_H_OUT,P_L_OUT,ge,shi,bai,R_shi,Q_shi,R_ge,Q_ge;
output eq_3;
output Q_lsb;
wire [3:0]R_to_add;//R register output
wire [3:0]R_and_P;//The sum of R and P
wire cout;//adder carry output
wire G_to_P;//G register output
wire [3:0]P_H_OUT;//P register high output
wire P_H_lsb;//The lowest bit of the high bit of the P register
wire [3:0] CQ,CR;
// instantiate comparator module
comparator comp(.a(R),.b(Q),.CR(CR),.CQ(CQ));

//Instantiate the shift register
shift_reg Qreg(
.clk(clk),
.reset(clr),
.shift(shift),
.load(ld_Q),
.in_data(CQ),
.shift_in_data(1'b0),
.shift_reg(),
.shift_reg_lsb(Q_lsb)
);
//Instantiate the shift register
shift_reg Rreg(
.clk(clk),
.reset(clr),
.shift(1'b0),
.load(ld_R),
.in_data(CR),
.shift_in_data(1'b0),
.shift_reg(R_to_add),
.shift_reg_lsb()
);

//Instantiate the shift register
shift_reg P_Hreg(
.clk(clk),
.reset(clr),
.shift(shift),
.load(ld_P),
.in_data(R_and_P),
.shift_in_data(G_to_P),
.shift_reg(P_H_OUT),
.shift_reg_lsb(P_H_lsb)
);

//Instantiate the shift register
shift_reg P_L(
.clk(clk),
.reset(clr),
.shift(shift),
.load(1'b0),
.in_data(4'b0),
.shift_in_data(P_H_lsb),
.shift_reg(P_L_OUT),
.shift_reg_lsb()
);
//Instantiate the C counter
counter counter(
.clk(clk),
.clr(clr),
.cnt_en(cnt_en),
.eq_3 (eq_3)
);
//instantiate adder
adder adder(
.a(R_to_add),
.b(P_H_OUT),
.c(cout),
.sum(R_and_P)
);
//Instantiate the G register
G_reg G_reg(
    .clk(clk),
    .ld_g(ld_g),
    .din(cout),
    .dout(G_to_P),
    .clr (clr)
);
assign P = {P_H_OUT,P_L_OUT};
//Instantiate a hundred conversion modules
Multiplier_out Multiplier_out(
    .sumin(P),
    .ge(ge),
    .shi(shi),
    .bai(bai)
);
//Instantiate a hundred conversion modules
Multiplier_out R_out(
    .sumin(R),
    .ge(R_ge),
    .shi(R_shi),
    .bai()
);
//Instantiate a hundred conversion modules
Multiplier_out Q_out(
    .sumin(Q),
    .ge(Q_ge),
    .shi(Q_shi),
    .bai()
);

endmodule

4. State machine design:

The state machine is shown in the figure, and the state machine is drawn according to the flow chart. Each action in the flow chart corresponds to a state, so 5 states are required. The following describes each state separately. Idle is an idle state. No matter what state the circuit is in, when the reset signal is valid, the circuit must enter the idle state. In the idle state, the next state enters the init state when the start signal is valid, otherwise the next state is still waiting in the idle state. In the init state, if the input signal Q_Isb is 1, the next state will enter the add state, otherwise the next state will enter the shift state. The down-state of the add state goes directly to the shift state. In the shift state, if the egl_3 signal is 1, the next state enters the done state, otherwise check whether the Q_lsb signal is valid, if the eql_3 signal is 0 and the Q_lsh signal is 1, the next state of the shift state enters the add state state. If the eql_3 signal is 0 and the Q_lsb signal is 0, the next state of the shift state enters the shift state. The next state of the done state is still done, and returns to the idle state until the circuit reset signal is valid.

//state machine
module state_machine(clk, reset, clr, shift, ld_P, ld_R, ld_Q, ld_g, eq_3, Q_lsb, START, DONE, cnt_en, present_state, next_state);
input clk,reset,eq_3,START,Q_lsb;
output shift, ld_P, ld_R, ld_Q, ld_g, DONE, clr, cnt_en, present_state, next_state;
reg shift, ld_P, ld_R, ld_Q, ld_g, DONE, clr, cnt_en;
reg [2:0]c;//present_state is the current state, next_state is the next state
reg [2:0] present_state, next_state;
parameter idle=3'b000;//idle state
parameter init=3'b001;//initialization status
parameter add=3'b010;//addition status
parameter Shift=3'b011;//Shift state
parameter done=3'b100;//completion status
parameter empty=3'b101;//delay status
always@(posedge clk,negedge reset)
if(1'b0==reset)//When reset is low level, the state machine returns to the idle state
    present_state<=idle;
else
    present_state<=next_state;//Otherwise the state machine enters the next state
always@(present_state,eq_3,START,Q_lsb)
case(present_state)
idle:begin if(1'b0==START)//When START is pressed
    next_state=init;
    else
    next_state=idle;//Otherwise the state machine is still in idle state
    {shift, ld_P, ld_Q, ld_R, ld_g, cnt_en, DONE, clr}=8'b00000000;//The output of the state machine
end
init:begin if(1'b1==Q_lsb)//When Q_lsb is high level, the state machine enters the addition state
    next_state=add;
    else
    next_state=empty;//Otherwise the state machine is still in the initialization state
    {shift, ld_P, ld_Q, ld_R, ld_g, cnt_en, DONE, clr}=8'b00110001;//The output of the state machine
end
add:begin
    next_state=empty;//The state machine enters the shift state
    {shift, ld_P, ld_Q, ld_R, ld_g, cnt_en, DONE, clr}=8'b01001001;//The output of the state machine
    end
Shift:begin
    if(1'b1==eq_3)//When eq_3 is high, the state machine enters the completion state
        next_state=done;
        else
        if(!eq_3 & amp; & amp; Q_lsb)
            next_state=add;//Otherwise the state machine is still in the shift state
            else
            next_state=Shift;//Otherwise the state machine is still in the shift state
            {shift, ld_P, ld_Q, ld_R, ld_g, cnt_en, DONE, clr}=8'b10001101;//Initialize the output of the state machine
    end
empty:begin
    {shift, ld_P, ld_Q, ld_R, ld_g, cnt_en, DONE, clr}=8'b00000001;//The output of the state machine
    next_state=Shift;//Otherwise the state machine enters the completion state*/
end
done:begin
/*
    next_state<=done;//The state machine enters the delay state
    {shift, ld_P, ld_Q, ld_R, ld_g, cnt_en, DONE, clr}=8'b00000011;//The output of the state machine
*/
{shift, ld_P, ld_Q, ld_R, ld_g, cnt_en, DONE, clr}=8'b00000011;//The output of the state machine
\t
if(1'b0==START)begin//When START is pressed
     next_state=idle;
//{shift,ld_P,ld_Q,ld_R,ld_g,cnt_en,DONE,clr}=8'b00000000;//The output of the state machine
end
    else begin
    next_state=done;//Keep the current state
    end

end
  default: next_state=idle;
end case
endmodule

5. Top-level design:

//top-level design
module Multiplier(
    START, done, clk, reset, Q,
    R, P, present_state, next_state,
    eq_3, Q_lsb, P_H_OUT,
    P_L_OUT,shift,ge,shi,bai,
    data_ge, data_shi, data_bai,
R_shi, Q_shi, R_ge, Q_ge,
data_Q_shi, data_R_ge, data_R_shi, data_Q_ge
    );
input START,clk,reset;
input [3:0] R,Q;
output [7:0] P;
output [3:0] P_H_OUT,P_L_OUT,ge,shi,bai,R_shi,Q_shi,R_ge,Q_ge;
output [2:0] present_state, next_state;
output done, eq_3, Q_lsb, shift;
wire done;
wire shift, ld_P, ld_R, ld_Q, ld_g, clr, cnt_en, eq_3, Q_lsb;
wire [7:0] P;
wire [3:0] P_H_OUT,P_L_OUT;
output [6:0] data_ge, data_shi, data_bai, data_Q_ge, data_Q_shi, data_R_ge, data_R_shi;
wire [6:0] data_ge, data_shi, data_bai, data_Q_ge, data_Q_shi, data_R_ge, data_R_shi;
//Instantiate the state machine
state_machine state_machine(.clk(clk),.reset(reset),.cnt_en(cnt_en),
.clr(clr), .shift(shift), .ld_P(ld_P), .ld_R(ld_R), .ld_Q(ld_Q), .ld_g(ld_g),
.eq_3(eq_3),.Q_lsb(Q_lsb),.START(START),.DONE(done),
.present_state(present_state), .next_state(next_state));
//Instantiate the data path
datapath datapath(
.clk(clk), .clr(clr), .shift(shift),
.cnt_en (cnt_en), .ld_P (ld_P), .ld_R (ld_R),
.ld_Q(ld_Q), .ld_g(ld_g), .R(R), .Q(Q),
.P(P), .eq_3(eq_3), .Q_lsb(Q_lsb),
.P_H_OUT(P_H_OUT), .P_L_OUT(P_L_OUT),
.ge(ge), .shi(shi), .bai(bai), .R_ge(R_ge),
.R_shi(R_shi),.Q_ge(Q_ge),.Q_shi(Q_shi)
);
//Instantiate the digital tube module
 seven_seg out_ge(
   .num1(ge),
   .data1(data_ge)
);
//Instantiate the digital tube module
 seven_seg out_shi(
   .num1(shi),
   .data1(data_shi)
);
//Instantiate the digital tube module
 seven_seg out_bai(
   .num1(bai),
   .data1(data_bai)
);
//Instantiate the digital tube module
 seven_seg out_R_ge(
   .num1(R_ge),
   .data1(data_R_ge)
);
//Instantiate the digital tube module
 seven_seg out_R_shi(
   .num1(R_shi),
   .data1(data_R_shi)
);
//Instantiate the digital tube module
 seven_seg out_Q_ge(
   .num1(Q_ge),
   .data1(data_Q_ge)
);
//Instantiate the digital tube module
 seven_seg out_Q_shi(
   .num1(Q_shi),
   .data1(data_Q_shi)
);
endmodule

6. Shift register module

//shift register (general purpose)
module shift_reg(clk,reset,in_data,shift,load,shift_reg_lsb,shift_in_data,shift_reg);
input clk,reset,shift,load;
input [3:0] in_data;
input shift_in_data;
output shift_reg_lsb;
output [3:0] shift_reg;
reg [3:0] shift_reg;
always @(posedge clk,negedge reset)
    if(1'b0===reset)//reset is low, the register is cleared
        shift_reg<=4'b0;
    else if(1'b1===load)//When load is high level, assign in_data to shift_reg
        shift_reg<=in_data;
    else if(1'b1===shift)//shift is high, shift shift_reg left one bit
        shift_reg<={shift_in_data,shift_reg[3:1]};
    else
        shift_reg<=shift_reg;//otherwise shift_reg remains unchanged
assign shift_reg_lsb=shift_reg[0];//shift_reg_lsb is the lowest bit of shift_reg
endmodule

//C counter
module counter(clk,clr,cnt_en,eq_3);
input clk, clr, cnt_en;
output eq_3;
reg eq_3;
reg [2:0] cnt_reg;
always@(posedge clk,negedge clr)
if(1'b0==clr)//clr is low, the counter is cleared
    cnt_reg<=3'b0;
else if(1'b1==cnt_en)//When cnt_en is high level, the counter is incremented by one
    cnt_reg<=cnt_reg + 1'b1;
    else
    cnt_reg<=cnt_reg;//Otherwise the counter remains unchanged
always@(cnt_reg)
if(3'b100==cnt_reg)//When the counter is 3, eq_3 is high
    eq_3=1'b1;
else
    eq_3=1'b0;//otherwise eq_3 is low level
endmodule

7. Adder module

//adder
module adder(a,b,c,sum);
input [3:0] a,b;
output [3:0] sum;
output c;
reg [3:0] sum;
reg c;
always@(a,b)
{c,sum}=a + b;
endmodule

8.G register module

//G register
module G_reg(clk,ld_g,din,dout,clr);
input clk, ld_g, din, clr;
output dout;
reg dout;
always@(posedge clk)
if(clr==1'b0)//When clr is low level, the G register is cleared
    dout<=1'b0;
else if(ld_g)//When ld_g is high level, assign din to dout
    dout<=din;
else
    dout<=dout;//Otherwise dout remains unchanged
endmodule

9. Other modules

//Seven-segment digital tube module
module seven_seg(num1,data1);
input[3:0]num1;
output [6:0]data1;
reg[6:0]data1;
always@(num1) begin
case (num1)
      4'd0: begin data1 = 7'b1000000; end
4'd1: begin data1 = 7'b1111001; end
4'd2: begin data1= 7'b0100100; end
4'd3: begin data1 = 7'b0110000; end
4'd4: begin data1 = 7'b0011001; end
4'd5: begin data1 = 7'b0010010; end
4'd6: begin data1 = 7'b0000010; end
4'd7: begin data1 = 7'b1111000; end
4'd8: begin data1 = 7'b0000000; end
4'd9: begin data1 = 7'b0010000; end
      default: begin data1 = 7'b0000001; end
end case
end
endmodule

//digital conversion module
module Multiplier_out(
    sumin, // multiplier output
    ge,//unit
    shi,//ten
    bai,//hundreds
);
input [7:0]sumin;
output [3:0]ge,shi,bai;
reg [3:0]ge,shi,bai;
always@(sumin) begin
    bai=sumin/100;//hundreds
    shi=(sumin-bai*100)/10;//ten digits
    ge=sumin-bai*100-shi*10;//unit
end
endmodule

// compare converter module
module comparator(
    a,b,//comparison number
    CQ, CR
);
input [3:0]a,b;
output [3:0]CQ,CR;
reg [3:0]CQ,CR,TMP;
always@(a,b) begin
    if(a>b) begin
CR<=b;
CQ<=a;
end
    else
begin
        CR<=a;
        CQ<=b;
end
end
endmodule