0
votes

The code is synthesized properly but when I try to simulate it only lda changes from 0 to 1. The rest of the control signals remain just the same. The eqz signal never changes from x. The rest of the signals remain in 0 state. I have tried everything.Can anyone tell me where I have gone wrong?

Test bench

module multiplier(input clk, start, [15:0]datain , output done);
    wire eqz, lda, ldb, ldp, clrp, decb;
    mul_datapath D(eqz, clk, lda, ldb, ldp, clrp, decb, datain);
    mul_control C(done, lda, ldb, ldp, clrp, decb, clk, start, eqz, datain);
endmodule

Data path

module mul_datapath(eqz, clk, lda, ldb, ldp, clrp, decb, datain);
    input clk, lda, ldb, ldp, clrp, decb;
    input [15:0] datain;
    wire [15:0]x, y, z, bout;
    output eqz;
    PIPO1 P1(x, clk, lda, datain);
    PIPO2 P2(y, clk, ldp, clrp, z);
    ADD A(z, x, y);
    COUNT CNT(bout, clk, ldb, decb, datain);
    COMP com(eqz, bout);
endmodule

PIPO register A

module PIPO1(x, clk, lda, datain);
    input clk, lda;
    input [15:0] datain;
    output reg [15:0] x;
    always @(posedge clk)
        if(lda) x<= datain;
endmodule

PIPO register B

module PIPO2(y, clk, ldp, clrp, z);
    input clk, ldp, clrp; 
    input [15:0] z;
    output reg [15:0]y;
    always @(posedge clk)
        begin
            if(clrp) y<= 16'b0;
            else if(ldp) y<= z;
        end     
endmodule

Adder unit

module ADD(z, x, y);
    input [15:0]x, y;
    output reg [15:0]z;
    always @(*)
        z = x + y;
endmodule

Counter to decrement B

module COUNT(bout, clk, ldb, decb, datain);
    input clk, ldb, decb;
    input [15:0] datain;
    output reg [15:0]bout;
    always @(posedge clk)
        begin
            if(ldb) bout <= datain;
            else if(decb)
                bout <= bout -1;
        end
endmodule

Comparator to compare B to zero

module COMP(eqz, bout);
    input [15:0] bout;
    output eqz;
    assign eqz = (bout==0);
endmodule

Control path

module mul_control(done, lda, ldb, ldp, clrp, decb, clk, start, eqz, datain);
    input clk, start, eqz;
    input[15:0] datain;
    output reg lda, ldb, ldp, clrp, decb, done; 
    reg [2:0]state;
    parameter S0=000, S1=001, S2=010, S3=011, S4=100;
    always @(posedge clk)
        begin
            case(state)
                S0 : if(start) state<= S1;  
                S1 : state<=S2;
                S2 : state<= S3;
                S3 : begin if(eqz) state<=S4; else state<=S3; end 
                S4 : state<= S4;
                default : state<= S0; 
            endcase
        end 
    always @(state)
        begin
           case(state)
               S0: begin lda = 0; ldb = 0; ldp = 0; clrp = 0; decb = 0; done = 0; end
               S1: begin lda = 1; ldb = 0; ldp = 0; clrp = 0; decb = 0; done = 0; end
               S2: begin lda = 0; ldb = 1; ldp = 0; clrp = 0; decb = 0; done = 0; end
               S3: begin lda = 0; ldb = 0; ldp = 1; clrp =0; decb = 1; done = 0; end
               S4: begin lda = 0; ldb = 0; ldp = 0; clrp = 0; decb = 0; done = 1; end
               default : begin lda = 0; ldb = 0; ldp = 0; clrp = 0; decb = 0; done = 0; end 
           endcase
        end
endmodule
1
1/ Format your code. 2/ Provide your test-bench so we have a Minimal, Complete, and Verifiable example stackoverflow.com/help/mcve - Oldfart

1 Answers

0
votes

Your basic mistakes are in multiplier and mul_control modules.

As for multiplier module, you have declared ports incorrectly.

As I understand, you meant it to use it as test bench. Then theres no need of input or output ports. Also no need of the wire declarations. Just chance the first two lines. This should do

module multiplier;
    reg [15:0] datain;
    reg clk, start;
    wire done;

    mul_datapath D(eqz, clk, lda, ldb, ldp, clrp, decb, datain);
    mul_control C(done, lda, ldb, ldp, clrp, decb, clk, start, eqz, datain);
endmodule

But I'd suggest you add some code to actually add meaning to test bench so that you can test all your modules.

Also you don't need datain in mul_control.v. Removing datain would also require same change to its call in test bench. Moreover in mul_control.v, you should also add a delay where theres a conditional state change. Also you are forgetting to set clrp for state 2 in mul_control.v

And gravest of all mistakes, the state parameters you are saving as 000, 001, 0010 are all taken as decimal by default. Since you want 5 states from 0 to 5, assign the state values with binary notation as 3'b000, 3'b001, 3'b010, etc.

So now

mul_control.v

module mul_control(done, lda, ldb, ldp, clrp, decb, clk, start, eqz);
    input clk, start, eqz;
    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;
    always @(posedge clk)
        begin
            case(state)
                S0 : if(start) state<= S1;  
                S1 : state<=S2;
                S2 : state<= S3;
                S3 : #2 if(eqz) state<=S4; 
                S4 : state<= S4;
                default : state<= S0; 
            endcase
        end 
    always @(state)
        begin
           case(state)
               S0: begin lda = 0; ldb = 0; ldp = 0; clrp = 0; decb = 0; done = 0; end
               S1: begin lda = 1; ldb = 0; ldp = 0; clrp = 0; decb = 0; done = 0; end
               S2: begin lda = 0; ldb = 1; ldp = 0; clrp = 1; decb = 0; done = 0; end
               S3: begin lda = 0; ldb = 0; ldp = 1; clrp =0; decb = 1; done = 0; end
               S4: begin lda = 0; ldb = 0; ldp = 0; clrp = 0; decb = 0; done = 1; end
               default : begin lda = 0; ldb = 0; ldp = 0; clrp = 0; decb = 0; done = 0; end 
           endcase
        end
endmodule

multiplier.v

module multiplier;
    reg [15:0] datain;
    reg clk, start;
    wire done;

    mul_datapath D(eqz, clk, lda, ldb, ldp, clrp, decb, datain);
    mul_control C(done, lda, ldb, ldp, clrp, decb, clk, start, eqz);


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

    always #5 clk = ~clk;

    initial
        begin
            #17 datain = 5;
            #10 datain = 6;

        end 
    initial
        begin
            $monitor($time, " %d %b", D.y, done);
            $dumpfile("mul.vcd"); $dumpvars(0, multiplier);

        end 
endmodule

On running this, I got the following output:

$ iverilog add.v count.v PIPO2.v mul_datapath.v COMP.v PIPO1.v mul_control.v multiplier.v
$ vvp a.out
VCD info: dumpfile mul.vcd opened for output.
                   0     x x
                   5     x 0
                  35     0 0
                  45     5 0
                  55    10 0
                  65    15 0
                  75    20 0
                  85    25 0
                  95    30 0
                  97    30 1

Here the answer (value of y) is 30, as we gave 5 and 6 as datain.

In the testbench, I am also saving a waveform dumpfile name mul.vcd which can be opened using gtkwave as gtkwave mul.vcd &

Note: I am using iverilog and gtkwave to compile, run and simulate. More details on them can be found here: http://axayjha.github.io/pages/iverilog.html