Verilog Code, последовательный множитель с использованием сложения и сдвига

verilog fsm multiplying

6801 просмотра

2 ответа

1 Репутация автора

это мой verilog-код для последовательного умножения / сложения. Я получаю «XXXXXXX» в качестве выхода, если я установлю сброс на высокий, я получу все нули в качестве выхода. Может кто-нибудь помочь мне определить, что я делаю неправильно?

Спасибо за любые советы / подсказки.

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

Вот мой тестовый стенд: любые советы о том, как написать лучшую, были бы также хороши.

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 Источник Размещён: 07.06.2014 06:48

Ответы (2)


0 плюса

127 Репутация автора

Как отметил Чиано, вы неправильно запускаете часы. Также вы никогда не утверждаете перезагрузку в ТБ.

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

initial
  begin
    reset = 1;
    // set all inputs to quiescent
    #100;
    reset = 0;
    // continue stimulus
  end
Автор: Guy Размещён: 11.06.2014 05:55

0 плюса

34 Репутация автора

Следующее должно помочь вам проверить ваш модуль. Но, похоже, ваш модуль не работает.

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;
Автор: user3719021 Размещён: 12.06.2014 01:32
Вопросы из категории :
32x32