Verilog 定点乘法器实现

Verilog 两种乘法器比较

      • 串行与流水乘法器

串行与流水乘法器

  • 串行
module multi_serial #(
                  parameter M = 8,
                  parameter N = 8
)
(
                  input               clk,  
                  input               rst,
                  input   [M-1:0]     x,
                  input   [N-1:0]     y,
                  output   reg           enable,
                  output reg [M+N-1:0]   result
);
reg[1:0] state ,next;
reg [N:0] count;
reg [M+N-1: 0] Acc,Tmp;
reg [N-1:0] y_reg;
parameter S0 = 2'b00;
parameter S1 = 2'b01;
parameter S2 = 2'b10;

always@(posedge clk or negedge rst) begin 
  if (!rst) 
    state <= S0;
  else 
    state <= next;
end

always@(posedge clk) begin
  case(state)
    S0: begin
        count = 0;
        Acc = 0;
        y_reg = y;
        Tmp = x;
        next = S1;
        end
    S1: begin
        if (count == N) 
          next = S2;
        else begin
          if (y_reg[0] == 1'b1) 
            Acc = Acc + Tmp;
          else  
            Acc = Acc;
          y_reg = y_reg >> 1;
          Tmp = Tmp << 1;
          count = count + 1;
          state = S1;
        end
        end
     S2: begin
         next = S0;
         end
     default: next = S0;
   endcase
 end

always@(posedge clk or negedge rst) begin
  if (!rst) begin
    enable <= 1'b0;
    result <= 1'b0;
  end
  else if (state  == S2) begin
    result <= Acc;
    enable <= 1'b1;
  end
  else begin 
    result <= 1'b0;
    enable <= 1'b0;
  end
end
endmodule
  • 流水线
module multi_pipeline #(
                  parameter M = 8,
                  parameter N = 8
)
(
                  input               clk,  
                  input               rst,
                  input   [M-1:0]     x,
                  input   [N-1:0]     y,
                  output   reg           enable,
                  output reg [M+N-1:0]   result
);
reg[15:0] mult0; 
reg[15:0] mult1; 
reg[15:0] mult2; 
reg[15:0] mult3; 
reg[15:0] mult4; 
reg[15:0] mult5; 
reg[15:0] mult6; 
reg[15:0] mult7; 
reg[15:0] add0 ; 
reg[15:0] add1 ; 

always@(posedge clk or negedge rst) begin 
 if (!rst) begin
 mult0 <= 1'b0; 
 mult1 <= 1'b0; 
 mult2 <= 1'b0; 
 mult3 <= 1'b0; 
 mult4 <= 1'b0; 
 mult5 <= 1'b0; 
 mult6 <= 1'b0; 
 mult7 <= 1'b0; 
 add0  <= 1'b0 ;
 add1  <= 1'b0;
 add   <= 1'b0;
 end
 else begin
 mult0 <= y[0]?{{8'b0},x}:16'b0;
 mult1 <= y[1]?{{7'b0},x,{1'b0}}:16'b0;
 mult2 <= y[2]?{{6'b0},x,{2'b0}}:16'b0;
 mult3 <= y[3]?{{5'b0},x,{3'b0}}:16'b0;
 mult4 <= y[4]?{{4'b0},x,{4'b0}}:16'b0;
 mult5 <= y[5]?{{3'b0},x,{5'b0}}:16'b0;
 mult6 <= y[6]?{{2'b0},x,{6'b0}}:16'b0;
 mult7 <= y[7]?{{1'b0},x,{7'b0}}:16'b0;

 add0 <= mult0 + mult1 + mult2 + mult3;
 add1 <= mult4 + mult5 + mult6 + mult7;

 result <= add1 + add0;
 end
 end
endmodule

  • 测试
module test();
reg clk;
reg rst;
reg[7:0]  A;
reg[7:0]  B;
wire ena_out;
wire enable;
wire[15:0] Dout1;
wire[15:0] Dout2;

multi_serial     #(
                   .M(8),
                   .N(8)
                  )
                 u1                
                 ( .clk(clk),
                   .rst(rst),
                   .x(A),
                   .y(B),
                   .enable(enable),
                   .result(Dout1)
                 );
multi_pipeline     #(
                   .M(8),
                   .N(8)
                  )
                 u2                
                 ( .clk(clk),
                   .rst(rst),
                   .x(A),
                   .y(B),
                   .enable(enable),
                   .result(Dout2)
                 );

initial begin
  rst = 1;
  #20 rst = 0;
  #40 rst = 1;
end

parameter period = 20;
initial begin
  clk = 0;
  forever #(period/2) clk = ~clk;
end

initial begin
A = 4;
B = 3;
#400
A = 9;
B = 4;
#200
A = 10;
B= 6;
#2000 $finish ;
end

initial begin
  $fsdbDumpfile("mult_serial.fsdb");
  $fsdbDumpvars;
 end
 endmodule

  • 仿真结果
    Verilog 定点乘法器实现_第1张图片

你可能感兴趣的:(IC,verilog)