-1

this is my verilog code for a sequential add / shift multiplier. I am receiving "XXXXXXX" as an output, if I set reset to high, I receive all zeroes as an output. Can someone please help me identify what I am doing wrong?

Thank you for any tips/hints.

module MULTIPLY_revision (
  input              clk, reset, start,
  input       [7:0]  A_in, B_in,
  output reg         done_tick,
  output wire [15:0] product 
);

localparam [1:0]
    idle  = 2'b00,
    op    = 2'b01,
    shift = 2'b10;

// signal declaration
reg       carry, next_carry;
reg [1:0] state, next_state;
reg [7:0] reg_PL, PL, reg_PH, PH, reg_a_multiplicand, a_multiplicand;   
reg [4:0] counter, next_counter;

assign product = {reg_PH, reg_PL};

always @(posedge clk, posedge reset)
  if (reset) begin
    state              <= idle;
    counter            <= 0;
    carry              <= 0;
    reg_PL             <= 0;
    reg_PH             <= 0;
    reg_a_multiplicand <= 0;
  end
  else begin
    state              <= next_state;
    carry              <= next_carry;
    counter            <= next_counter;
    reg_PL             <= PL;
    reg_PH             <= PH;
    reg_a_multiplicand <= a_multiplicand; 
  end

// next state logic 
always @ * begin
  done_tick      = 1'b0;
  PL             = reg_PL;
  PH             = reg_PH;
  a_multiplicand = reg_a_multiplicand; 
  next_carry     = carry;
  next_counter   = counter;
  next_state     = state;

  case(state)
    idle: begin
      if(start) begin
        next_counter   = 7; // load 7 for 8 bits down counter
        PL             = B_in; // load multiplier into lower half
        PH             = 8'b0; // clear upper half. 
        a_multiplicand = A_in; // load A multiplicand into register. 
        next_state     = op;
      end
    end

    op: begin
      if(reg_PL[0] == 1) begin
        {next_carry,PH} = reg_PH + reg_a_multiplicand;      // add A multiplicand to upper half with carry bit. 
      end
      next_counter = counter - 1;
      next_state   = shift;             
    end

    shift: begin
      {next_carry,PH,PL} = {carry,reg_PH,reg_PL} >> 1;  // putting everything back together and shifting everything to the right once. 
      if(next_counter == 0) begin
        next_state = idle;
      end
      else begin
        next_state = op;
      end
    end

    default: begin
      next_state = idle;
    end
  endcase
end


endmodule


   `timescale 1ns / 1ps

Here is my testbench: any tips on how to write a better one would be great also.

module mytest;

// Inputs
reg clk;
reg reset;
reg start;
reg [7:0] A_in;
reg [7:0] B_in;

// Outputs
wire done_tick;
wire [15:0] product;

// Instantiate the Unit Under Test (UUT)
MULTIPLY_revision uut (
    .clk(clk), 
    .reset(reset), 
    .start(start), 
    .A_in(A_in), 
    .B_in(B_in), 
    .done_tick(done_tick), 
    .product(product)
);


initial begin
    // Initialize Inputs
    clk = 0;
    reset = 0;
    start = 0;
    A_in = 0;
    B_in = 0;

    // Wait 100 ns for global reset to finish
    #100;

            clk = 1;
    reset = 0;
    start = 1;
    A_in = 4;
    B_in = 4;

    #100

    clk = 1;
    reset = 0;
    start = 1;
    A_in = 5;
    B_in = 6;

    end

always
#20 clk = !clk;


endmodule
user3533556
  • 1
  • 1
  • 3
  • 1
    You might want to post your testbench. If you are conditioning your inputs correctly, you shouldn't be seeing any X's on your outputs. – Ciano Jun 07 '14 at 15:04
  • 1
    And also, when you deassert reset and assert start, and your A_in and B_in signals are non-zero, your output will become non-zero after several clock cycles. – Ciano Jun 07 '14 at 15:49
  • 1
    Thank you so much, it was indeed my testbench, I wasn't setting the clock correctly. – user3533556 Jun 07 '14 at 17:19

2 Answers2

1

As Ciano pointed out, you are not kickstarting the clock correctly. Also you never assert reset in the TB.

initial clk = 0;
always clk = #20 ~clk;

initial
  begin
    reset = 1;
    // set all inputs to quiescent
    #100;
    reset = 0;
    // continue stimulus
  end
Guy
  • 167
  • 9
0

The following should help you test your module. But it seems like your module doesnt work.

initial begin
    // Initialize Inputs
    clk = 0;
    reset = 0;
    start = 0;
    A_in = 0;
    B_in = 0;

     @(posedge clk);
     reset = 1;
     repeat(2)@(posedge clk); 
     reset = 0;
     @(posedge clk); 
     start = 1 ;
     A_in = 5;
    B_in = 6;
     wait(done_tick == 1);
     $display("A_In = %d B_In = %d Product =  %d",A_in,B_in,product);





    end

always
#20 clk = !clk;
GoChanGo
  • 61
  • 1
  • 1
  • 8