Efficient ASMD-based Sequential Binary Multiplier

来源:互联网 发布:java交换两个数的值 编辑:程序博客网 时间:2024/06/01 14:27

ASMD: Alogorithm state machine chart and datapath

Reference: “Advanced digital design with the Verilog HDL”, Michael D. Ciletti

image


`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: SEU.IC
// Engineer: RAY
//
// Create Date:    11:58:13 03/31/2011
// Design Name: Multiplier_ASM
// Module Name:    Multiplier_ASM
//////////////////////////////////////////////////////////////////////////////////
module Multiplier_ASM(
    Start_in,
     Clock,
     Reset,
     Word1_in,
     Word2_in,
     Ready_out,
     Product_out
     );
     parameter WORDWIDTH = 4;
    input Start_in;
    input Clock;
    input Reset;
    input [WORDWIDTH - 1:0] Word1_in;
    input [WORDWIDTH - 1:0] Word2_in;
    output Ready_out;
    output [2*WORDWIDTH - 1:0] Product_out;

   
     reg state, next_state;
     reg [2*WORDWIDTH - 1:0] multiplicand;
     reg [WORDWIDTH - 1:0] multiplier;
     reg [2*WORDWIDTH - 1:0] Product_out;
     reg Load_words;
     reg Flush, shift, add_and_shift;
    
    
     parameter idle = 1'b0, running = 1'b1;
    
     wire Empty = (Word1_in == 'd0) || (Word2_in == 'd0);
     wire Ready_out = (state == idle) && (!Reset);


always @(posedge Clock or posedge Reset)
if(Reset)
   state <= idle;
else
   state <= next_state;


always @(state or Start_in or Empty or multiplier)
begin
  Flush = 0; Load_words = 0;  shift = 0; add_and_shift = 0;
   case (state)
    idle:   if(!Start_in) next_state = idle;
            else if(Empty)
                   begin
                      next_state = idle;
                      Flush = 1;
                    end
                  else
                    begin
                      Load_words = 1;
                      next_state = running;
                    end   
    running:  if(~|multiplier) next_state = idle;
              else if(multiplier == 1)
                    begin
                        add_and_shift = 1;
                        next_state = idle;
                    end
                   else if(multiplier[0])
                         begin
                          add_and_shift = 1;
                          next_state = running;
                         end
                        else
                          begin
                            shift = 1;
                            next_state = running;
                           end
     default:    next_state = idle;
    endcase
  end


always @ (posedge Clock or posedge Reset)
if(Reset)
   begin
      multiplier     <=  0;
      multiplicand   <=  0;
      Product_out    <=  0;
   end
else
    begin
      if(Flush)   Product_out <= 0;
      else if(Load_words == 1)
            begin
              multiplicand   <= Word1_in;
              multiplier     <= Word2_in;
              Product_out    <= 0;
            end
           else if(shift)
                    begin
                         multiplicand    <=   multiplicand << 1;
                          multiplier      <=   multiplier   >> 1;
                        end
                      else if(add_and_shift)
                             begin
                                  Product_out   <=  Product_out  + multiplicand;
                                  multiplicand  <=  multiplicand  << 1;
                                  multiplier    <= multiplier     >> 1;
                                end
        end
endmodule


testbench


`timescale 1ns / 1ps

////////////////////////////////////////////////////////////////////////////////
// Company: SEU.IC
// Engineer:RAY
//
// Create Date:   13:35:18 03/31/2011
// Design Name:   Multiplier_ASM
// Module Name:   E:/ray_study_verilog/Multiplier/tb_mul.v
// Project Name:  Multiplier
////////////////////////////////////////////////////////////////////////////////

module tb_mul;

    // Inputs
    reg Start_in;
    reg Clock;
    reg Reset;
    reg [3:0] Word1_in;
    reg [3:0] Word2_in;

    // Outputs
    wire Ready_out;
    wire [7:0] Product_out;

    // Instantiate the Unit Under Test (UUT)
    Multiplier_ASM uut (
        .Start_in(Start_in),
        .Clock(Clock),
        .Reset(Reset),
        .Word1_in(Word1_in),
        .Word2_in(Word2_in),
        .Ready_out(Ready_out),
        .Product_out(Product_out)
    );

initial begin Clock = 0; forever #10 Clock = ~Clock;end
initial
begin
  #2 Reset = 1;
  #15 Reset = 0;
  end
initial begin #5 Start_in = 1; #10 Start_in = 15; end
initial
begin
    //for(Word1_in = 0; Word1_in <= 15 ; Word1_in = Word1_in + 1) begin
     for(Word2_in = 0; Word2_in <= 15 ; Word2_in = Word2_in + 1) begin
        Word1_in = Word2_in + 1;
        Start_in = 0;
         #40 Start_in = 1;
         #20 Start_in = 0;
         #200;
         end
         #140;
         end
        // end
   

endmodule



image

原创粉丝点击