一个简易的8位计算器,可实现加减乘除,testbench写的较为简易,代码覆盖率有点低。方法比较笨,综合之后的频率不高。

来源:互联网 发布:学校奖学金算法 编辑:程序博客网 时间:2024/04/30 19:22

(只限整数)

module   calculator(
                    num,
                    num_sig,
                    cal,
                    enter,
                    result_int,
                    result_sig,
                    yshang,
                    yyushu,
                    clk,
                    rst
                  
                   
                    );

input            clk;
input            rst;

input    [7:0]    num;
input            num_sig;

input    [3:0]    cal;
input            enter;

output    [15:0]    result_int;
output            result_sig;
output     [7:0]   yshang; 
output     [7:0]   yyushu;





reg        [7:0]    num1;
reg                num1_sig;
reg        [7:0]    num2;
reg                num2_sig;

reg        [7:0]    num1cal;
reg                num1cal_sig;
reg        [7:0]    num2cal;
reg                num2cal_sig;

reg        [15:0]   num1calreg;
reg        [15:0]   num2calreg;

reg        [7:0]     yshang;
reg        [7:0]     yyushu;
reg        [15:0]    result_int;
reg                  result_sig;

reg        [3:0]    cal_tmp;
reg        [3:0]    cal_st;


reg         [2:0] count;
reg         [3:0] count1;
reg               div_done;
reg         [1:0] state;
reg         [15:0] p,t;
reg         [7:0]  m;
parameter  s0=0,s1=1,s2=2;
always@(posedge clk or negedge rst)
begin
    if(~rst)
    begin
        cal_tmp=4'b0000;
        num1=0;
        num2=0;
        num1_sig=0;
        num2_sig=0;
      
        num1cal=0;
        num2cal=0;
        num1cal_sig=0;
        num2cal_sig=0;
       
        result_int=0;
        result_sig=0;
       
        cal_st=0;
        count=0;
        count1=0;
        state=2'b00;
       
       num1calreg=16'b0000000000000000;
       num2calreg=16'b0000000000000000;
        div_done = 1'b0;
       
        yshang=8'b00000000;
        yyushu=8'b00000000;
       
    end
    else
    begin
        if(cal!=4'b0000)
        begin
            num1_sig=num_sig;
            num1=num;
          
            cal_tmp=cal;
        end
        else
        begin
            if(enter)
            begin
                num2_sig=num_sig;
                num2=num;
              
               case({num1_sig,num2_sig,cal_tmp})
                   6'b000001://num1+num2
                    begin
                        cal_st=1;//num1+num2,result_sig=num1_sig&num2_sig
                       num1cal_sig=num1_sig;
                       num1cal=num1;
                     
                       num2cal_sig=num2_sig;
                        num2cal=num2;
                      
                    end
                   6'b010001://num1+(-num2)=num1-num2
                    begin
                       cal_st=2;//num1-num2,num1_sig=num2_sig=0
                       num1cal_sig=num1_sig;
                        num1cal=num1;
                       
                       num2cal_sig=0;
                       num2cal=num2;
                      
                    end
                   6'b100001://-num1+num2
                    begin
                        cal_st=2;
                        //alternate num1and num2, then it's still num1-num2
                       num1cal_sig=0;
                       num1cal=num2;
                       
                       num2cal_sig=0;
                        num2cal=num1;
                       
                    end
                   6'b110001://-num1+(-num2)
                    begin
                       cal_st=1;//num1+num2,result_sig=num1_sig&num2_sig
                        num1cal_sig=num1_sig;
                       num1cal=num1;
                      
                       num2cal_sig=num2_sig;
                       num2cal=num2;
                       
                    end
                   6'b000010://num1-num2
                    begin
                       cal_st=2;//num1-num2,num1_sig=num2_sig=0
                       num1cal_sig=num1_sig;
                       num1cal=num1;
                       
                       num2cal_sig=num2_sig;
                        num2cal=num2;
                     
                    end
                   6'b010010://num1-(-num2)
                    begin
                       cal_st=1;//num1+num2,result_sig=num1_sig&num2_sig
                       num1cal_sig=0;
                        num1cal=num1;
                       
                       num2cal_sig=0;
                       num2cal=num2;
                       
                    end
                   6'b100010://-num1-num2
                    begin
                        cal_st=1;//num1+num2,result_sig=num1_sig&num2_sig
                       num1cal_sig=num1_sig;
                       num1cal=num1;
                     
                       num2cal_sig=1;
                       num2cal=num2;
                     
                    end
                   6'b110010://-num1-(-num2)=num2-num1
                    begin
                       cal_st=2;//num1-num2,num1_sig=num2_sig=0
                       num1cal_sig=0;
                        num1cal=num2;
                       
                       num2cal_sig=0;
                       num2cal=num1;
                    
                    end
                   6'b000100://num1*num2,result_sig=num1_sig^num2_sig
                    begin
                        cal_st=3;
                       num1cal_sig=num1_sig;
                       num1cal=num1;
                     
                       num2cal_sig=num2_sig;
                       num2cal=num2;
                      
                       
                    end
                   6'b010100://num1*(-num2)
                    begin
                        cal_st=3;
                       num1cal_sig=num1_sig;
                       num1cal=num1;
                  
                        num2cal_sig=num2_sig;
                       num2cal=num2;
                       
                    end
                   6'b100100://(-num1)*num2
                    begin
                        cal_st=3;
                        num1cal_sig=num1_sig;
                       num1cal=num1;
                  
                       num2cal_sig=num2_sig;
                       num2cal=num2;
                   
                    end
                   6'b110100://(-num1)*(-num2)
                    begin
                        cal_st=3;
                       num1cal_sig=num1_sig;
                       num1cal=num1;
                    
                       num2cal_sig=num2_sig;
                       num2cal=num2;
                       
                    end
                   6'b001000://num1/num2
                    begin
                        cal_st=4;
                       num1cal_sig=num1_sig;
                       num1cal=num1;
                     
                        num2cal_sig=num2_sig;
                       num2cal=num2;
                 
                    end
                   6'b011000://num1/(-num2)
                    begin
                        cal_st=4;
                        num1cal_sig=num1_sig;
                       num1cal=num1;
                
                       num2cal_sig=num2_sig;
                       num2cal=num2;
                 
                    end
                   6'b101000://(-num1)/num2
                    begin
                        cal_st=4;
                       num1cal_sig=num1_sig;
                       num1cal=num1;
              
                       num2cal_sig=num2_sig;
                       num2cal=num2;
                     
                       

                       
                    end
                   6'b111000://(-num1)/(-num2)
                    begin
                        cal_st=4;
                       num1cal_sig=num1_sig;
                        num1cal=num1;
                 
                       num2cal_sig=num2_sig;
                       num2cal=num2;
                      
                  

                     
                    end
                endcase
               
                
                case(cal_st)
                   4'd1://num1cal+num2cal,result_sig=num1cal_sig&num2cal_sig,wherenum1cal_sig=num2cal_sig
                    begin
                       result_sig=num1cal_sig&num2cal_sig;
                        result_int=num1cal+num2cal;
                      
                    end
                   4'd2://num1cal-num2cal,num1cal_sig=num2cal_sig=0
                    begin
                       if(num1cal<num2cal)//-(num2cal-num1cal)
                        begin
                           result_sig=1;
                           result_int=num2cal-num1cal;
                        end
                      else
                            begin
                           result_sig=0;
                            result_int=num1cal-num2cal;
                          end
                      end 
                    4'd3:
                    begin
                       result_sig=num1cal_sig^num2cal_sig;
                        begin
                            case(state)
                             2'b00:begin
                                  count=3'b000;
                                  p=0;
                                  t={{8{1'b0}},num1cal};
                                  m=num2cal;
                                  state=2'b01;
                                end
                             2'b01:
                                  begin
                                     if(count==3'b111)
                                            state=2'b10;
                                       else
                                          begin
                                             if(m[0]==1'b1)
                                                p=p+t;
                                              else
                                                begin
                                                  p=p;
                                                end
                                                  m=m>>1;
                                                   t=t<<1;
                                                  count=count+1'b1;
                                                  state=2'b01;
                                         end
                                               
                                           
                                end
                             2'b10:
                               begin
                                    result_int=p;
                                     state=2'b00;
                                 end
                        endcase
                    end
                end
                   4'd4://num1cal/num2cal
                    begin
                       result_sig=num1cal_sig^num2cal_sig;
                        if(count1==0)begin
                                                 num1calreg={8'b00000000,num1cal};
                                             num2calreg={num2cal,8'b00000000};
                                              count1=count1+1;
                        end
                      else
                     if(count1<9) 
                          
                               begin
                                   num1calreg={num1calreg[14:0],1'b0};
                                 if(num1calreg[15:8]>=num2cal)
                                     begin
                                          num1calreg=num1calreg-num2calreg+1'b1;
                                     end
                                          
                                   else 
                                         begin 
                                             num1calreg = num1calreg;  
                                         end 
                           
                                        count1= count1 + 1; 
                                        div_done = 1'b0; 
                               end 
                      else 
                           begin 
                               count1 = 0; 
                               div_done =1'b1; 
                                 
                               yshang =num1calreg[7:0]; 
                               yyushu =num1calreg[15:8]; 
                            end       
                 end
                endcase
            end
        end
    end
end

endmodule




 以下是testbench:

`timescale 1ns/1ns
module test_calculator;
  reg [7:0] num;
  reg       num_sig;
  reg[3:0]  cal;
  reg       enter;
  reg       clk;
  reg       rst;
 
  wire [15:0] result_int;
  wire        resulr_sig;
  wire [7:0]  yshang;
  wire [7:0]  yyushu;
 

 
  calculator  c_test (
                    num,
                    num_sig,
                    cal,
                    enter,
                    result_int,
                    result_sig,
                    yshang,
                    yyushu,
                    clk,
                    rst
                   
                    );
                    
  always
  #10 clk=~clk;
 
  initial
    begin
          rst=0;
          clk=0;
          enter=0;
          num=0;
          num_sig=0;
          cal=4'b0000;
         
          #20;
         
          begin
              rst=1;
              cal=4'b0001;
              num=30;
              num_sig=0;
          end
         
          #20;
         
          begin
              cal=4'b0000;
              enter=1;
              num=15;
              num_sig=0;
          end
         
         
      begin 
          #20;
         
          begin
             rst=0;
             enter=0;
             num=0;
             num_sig=0;
          end
         
          #20;
         
          begin
              rst=1;
              cal=4'b0001;
              num=30;
              num_sig=0;
          end
         
          #20;
         
          begin
              cal=4'b0000;
              enter=1;
              num=15;
              num_sig=1;
          end
      end
                
      begin 
          #20;
         
          begin
             rst=0;
             enter=0;
             num=0;
             num_sig=0;
          end
         
          #20;
         
          begin
              rst=1;
              cal=4'b0001;
              num=30;
              num_sig=1;
          end
         
          #20;
         
          begin
              cal=4'b0000;
              enter=1;
              num=15;
              num_sig=0;
          end
      end   
     
     
      begin 
          #20;
         
          begin
             rst=0;
             enter=0;
             num=0;
             num_sig=0;
          end
         
          #20;
         
          begin
              rst=1;
              cal=4'b0001;
              num=30;
              num_sig=1;
          end
         
          #20;
         
          begin
              cal=4'b0000;
              enter=1;
              num=15;
              num_sig=1;
          end
      end   
     
       begin 
          #20;
         
          begin
             rst=0;
             enter=0;
             num=0;
             num_sig=0;
          end
          
          #20;
         
          begin
              rst=1;
              cal=4'b0010;
              num=30;
              num_sig=0;
          end
         
          #20;
         
          begin
              cal=4'b0000;
              enter=1;
              num=15;
              num_sig=0;
          end
      end
     
         begin 
          #20;
         
          begin
             rst=0;
             enter=0;
             num=0;
             num_sig=0;
          end
         
         #20;
         
          begin
              rst=1;
              cal=4'b0010;
              num=30;
              num_sig=0;
          end
         
          #20;
         
          begin
              cal=4'b0000;
              enter=1;
              num=15;
              num_sig=1;
          end
      end
     
     
         begin 
          #20;
         
          begin
             rst=0;
             enter=0;
             num=0;
             num_sig=0;
          end
         
          #20;
         
          begin
              rst=1;
              cal=4'b0010;
              num=30;
              num_sig=1;
          end
         
          #20;
         
          begin
              cal=4'b0000;
              enter=1;
              num=15;
              num_sig=0;
          end
      end
         
         
          begin 
          #20;
         
          begin
             rst=0;
             enter=0;
             num=0;
             num_sig=0;
          end
          
          #20;
         
          begin
              rst=1;
              cal=4'b0010;
              num=30;
              num_sig=1;
          end
         
          #20;
         
          begin
              cal=4'b0000;
              enter=1;
              num=15;
              num_sig=1;
          end
      end  
         
        begin 
          #20;
         
          begin
             rst=0;
             enter=0;
             num=0;
             num_sig=0;
          end
         
          #20;
         
          begin
              rst=1;
              cal=4'b0100;
              num=30;
              num_sig=0;
          end
         
          #20;
         
          begin
              cal=4'b0000;
              enter=1;
              num=15;
              num_sig=0;
          end
      end    
         
        begin 
          #200;
         
          begin
             rst=0;
             enter=0;
             num=0;
             num_sig=0;
          end
         
          #20;
         
          begin
              rst=1;
              cal=4'b0100;
              num=30;
              num_sig=0;
          end
         
          #20;
         
          begin
              cal=4'b0000;
              enter=1;
              num=15;
              num_sig=1;
          end
      end    
         
        begin 
          #200;
         
          begin
             rst=0;
             enter=0;
             num=0;
             num_sig=0;
          end
         
          #20;
         
          begin
              rst=1;
              cal=4'b0100;
              num=30;
              num_sig=1;
          end
         
          #20;
         
          begin
              cal=4'b0000;
              enter=1;
              num=15;
              num_sig=0;
          end
      end    
         
        begin 
          #200;
         
          begin
             rst=0;
             enter=0;
             num=0;
             num_sig=0;
          end
         
          #20;
         
          begin
              rst=1;
              cal=4'b0100;
              num=30;
              num_sig=1;
          end
         
          #20;
         
          begin
              cal=4'b0000;
              enter=1;
              num=15;
              num_sig=1;
          end
      end    
                     
        begin 
          #200;
         
          begin
             rst=0;
             enter=0;
             num=0;
             num_sig=0;
          end
          
          #20;
         
          begin
              rst=1;
              cal=4'b1000;
              num=30;
              num_sig=0;
          end
         
          #20;
         
          begin
              cal=4'b0000;
              enter=1;
              num=14;
              num_sig=0;
          end
      end    
                  
      begin 
          #200;
         
          begin
             rst=0;
             enter=0;
             num=0;
             num_sig=0;
          end
         
          #20;
         
          begin
              rst=1;
              cal=4'b1000;
              num=30;
              num_sig=0;
          end
         
          #20;
         
          begin
              cal=4'b0000;
              enter=1;
              num=14;
              num_sig=1;
          end
      end                
                   
      begin 
          #200;
         
          begin
             rst=0;
             enter=0;
             num=0;
             num_sig=0;
          end
         
          #20;
         
          begin
              rst=1;
              cal=4'b1000;
              num=30;
              num_sig=1;
          end
         
          #20;
         
          begin
              cal=4'b0000;
              enter=1;
              num=14;
              num_sig=0;
          end
      end                
                   
      begin 
          #200;
         
          begin
             rst=0;
             enter=0;
             num=0;
             num_sig=0;
          end
         
          #20;
         
          begin
              rst=1;
              cal=4'b1000;
              num=30;
              num_sig=1;
          end
         
          #20;
         
          begin
              cal=4'b0000;
              enter=1;
              num=14;
              num_sig=1;
          end
      end
end  

 
endmodule




 


原创粉丝点击