Verilog之基本算数运算

1.加减法

module addsub            
(            
    input [7:0] dataa,        
    input [7:0] datab,        
    input add_sub,      // if this is 1, add; else subtract    
    input clk,        
    output reg [8:0] result        
);            
            
    always @ (posedge clk)        
    begin        
        if (add_sub)    
            result <= dataa + datab;           //or "assign {cout,sum}=dataa+datab;"
        else    
            result <= dataa - datab;
    end        
            
endmodule            

 补码不仅可以执行正值和负值转换,其实补码存在的意义,就是避免计算机去做减法的操作。

  1101       -3 补
+   1000        8
    01015
假设 -3 + 8,只要将 -3 转为补码形式,亦即 0011 => 1101,然后和 8,亦即 1000 相加
就会得到 5,亦即 0101。至于溢出的最高位可以无视掉

2.乘法

module mult(outcome,a,b);
parameter SIZE=8;
input[SIZE:1] a,b;
output reg[2*SIZE:1] outcome;
integer i;
always @(a or b)
        begin outcome<=0;
        for(i=0,i<=SIZE;i=i+1)
        if(b[i]) outcome<=outcome+(a<<(i-1));
        end
endmodule

乘法-带符号位,在初始化之际,取乘数和被乘数的正负关系,然后取被乘数和乘数的正值。输出结果根据正负关系取得。

          else if( Start_Sig )                
              case( i )                
                        
                    0:         
                     begin    
                         
                         isNeg <= Multiplicand[7] ^ Multiplier[7];    
                          Mcand <= Multiplicand[7] ? ( ~Multiplicand + 1'b1 ) : Multiplicand;
                          Mer <= Multiplier[7] ? ( ~Multiplier + 1'b1 ) : Multiplier;
                          Temp <= 16'd0;
                          i <= i + 1'b1;
                        
                     end    
                         
                     1: // Multipling    
                     if( Mer == 0 ) i <= i + 1'b1;     
                     else begin Temp <= Temp + Mcand; Mer <= Mer - 1'b1; end                        //浪费时钟
                         
                     2:    
                     begin isDone <= 1'b1; i <= i + 1'b1; end    
                         
                     3:    
                     begin isDone <= 1'b0; i <= 2'd0; end    
                         
                endcase        
                        
    /*************************/                        
                         
     assign Done_Sig = isDone;                    
     assign Product = isNeg ? ( ~Temp + 1'b1 ) : Temp;                    
                         
     /*************************/                    
                        
endmodule                        

 乘法器.vt示例

`timescale 1 ps/ 1 ps
module multiplier_module_simulation();

    reg CLK;
     reg RSTn;
     
     reg Start_Sig;
    reg [7:0] Multiplicand;
    reg [7:0] Multiplier;

    wire Done_Sig;
    wire [15:0]Product;
     
     /***********************************/

    initial                                                
    begin      
     
        RSTn = 0; #10; RSTn = 1;
         CLK = 1; forever #10 CLK = ~CLK;
          
     end
     
     /***********************************/
    
    multiplier_module U1 
     (
        .CLK(CLK),
         .RSTn(RSTn),
         .Start_Sig(Start_Sig),
        .Multiplicand(Multiplicand),
        .Multiplier(Multiplier),
         .Done_Sig(Done_Sig),
        .Product(Product)
    );
     
     /***********************************/
     
     reg [3:0]i;

    always @ ( posedge CLK or negedge RSTn )
        if( !RSTn )
            begin
                    i <= 4'd0;
                    Start_Sig <= 1'b0;
                Multiplicand <= 8'd0;
                  Multiplier <= 8'd0;             
            end                
          else 
              case( i )
                
                    0: // Multiplicand = 10 , Multiplier = 2
                     if( Done_Sig ) begin Start_Sig <= 1'b0; i <= i + 1'b1; end
                     else begin Multiplicand <= 8'd10; Multiplier <= 8'd2; Start_Sig <= 1'b1; end
                     
                     1: // Multiplicand = 2 , Multiplier = 10
                     if( Done_Sig ) begin Start_Sig <= 1'b0; i <= i + 1'b1; end
                     else begin Multiplicand <= 8'd2; Multiplier <= 8'd10; Start_Sig <= 1'b1; end
                     
                     2: // Multiplicand = 11 , Multiplier = -5
                     if( Done_Sig ) begin Start_Sig <= 1'b0; i <= i + 1'b1; end
                     else begin Multiplicand <= 8'd11; Multiplier <= 8'b11111011; Start_Sig <= 1'b1; end
                
                    3: // Multiplicand = -5 , Multiplier = -11
                     if( Done_Sig ) begin Start_Sig <= 1'b0; i <= i + 1'b1; end
                     else begin Multiplicand <= 8'b11111011; Multiplier <= 8'b11110101; Start_Sig <= 1'b1; end
                
                    4:
                     begin i <= 4'd4; end
                
                
                endcase
                
    /***********************************/
                                             
                                                  
endmodule

循环除法器

module streamlined_divider_module
(
    input CLK,
     input RSTn,
     
     input Start_Sig,
     input [7:0]Dividend,
     input [7:0]Divisor,
     
     output Done_Sig,
     output [7:0]Quotient,
     output [7:0]Reminder,
     
     /**************************/
     
     output [15:0]SQ_Diff,
     output [15:0]SQ_Temp
);

    /******************************/
     
     reg [3:0]i;
     reg [8:0]s;
     reg [15:0]Temp;
     reg [15:0]Diff;
     reg isNeg;
     reg isDone;
     
     always @ ( posedge CLK or negedge RSTn )
         if( !RSTn )
              begin
                    i <= 4'd0;
                     s <= 9'd0;
                     Temp <= 16'd0;
                     Diff <= 16'd0;
                     isNeg <= 1'b0;
                     isDone <= 1'b0;
                end
          else if( Start_Sig )
              case( i )
                
                    0:
                     begin
                         
                         isNeg <= Dividend[7] ^ Divisor[7];
                          s <= Divisor[7] ? { 1'b1, Divisor } : { 1'b1 , ~Divisor + 1'b1 };
                          Temp <= Dividend[7] ? { 8'd0 , ~Dividend + 1'b1 } : { 8'd0 , Dividend };
                          Diff <= 16'd0;
                          i <= i + 1'b1;
                          
                     end
                     
                     1,2,3,4,5,6,7,8:
                     begin 
                         
                          Diff = Temp + { s , 7'd0 }; 
                          
                          if( Diff[15] ) Temp <= { Temp[14:0] , 1'b0 }; 
                        else Temp <= { Diff[14:0] , 1'b1 }; 
                     
                         i <= i + 1'b1;
                          
                end
                     
                     9:
                     begin isDone <= 1'b1; i <= i + 1'b1; end
                     
                     10:
                     begin isDone <= 1'b0; i <= 2'd0; end
                
                
                endcase
                
    /*********************************/
     
     assign Done_Sig = isDone;
     assign Quotient = isNeg ? ( ~Temp[7:0] + 1'b1 ) : Temp[7:0];
     assign Reminder = Temp[15:8];
     
     /**********************************/
     
     assign SQ_Diff = Diff;
     assign SQ_Temp = Temp;
        
     /**********************************/
     
 
endmodule
原文地址:https://www.cnblogs.com/shaogang/p/4103177.html