zoukankan      html  css  js  c++  java
  • 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
  • 相关阅读:
    hdu 1251(字典树)(3种方法)
    HDU 2203(KMP算法)
    九度oj 题目1335:闯迷宫
    poj3894 bfs+记录路径
    状压dp--P2704
    状压dp--洛谷P2622
    动态规划--牛客多校number
    完全背包
    01背包--hdu
    莫比乌斯反演模板--Gym 101982B
  • 原文地址:https://www.cnblogs.com/shaogang/p/4103177.html
Copyright © 2011-2022 走看看