tag 标签: 进位

相关博文
  • 热度 17
    2013-7-31 14:28
    1241 次阅读|
    0 个评论
    今天半想半参考的写完了一个16位乘法器,整个过程还算简单,代码最主要的部分就是移位计算的部分。 在写的过程中,最开始的一次移位部分的代码只有 /*----------------------------------------------------------------------------------------- gen the yout signal -----------------------------------------------------------------------------------------*/ always @ ( posedge clk or negedge asy_rst ) begin     if ( !asy_rst )         yout = 32'd0;     else if ( cnt == 5'd1 )                     //start拉高结束后一时钟周期内清零yout         yout = 32'd0;     else if ( cnt 5'd1 cnt 5'd18 )       //cnt为1~16进行移位计算(最高位在下边另行计算)     begin         if ( breg )                      //移位且累加             yout = {yout +areg,yout };         else                                    //只移位             yout = yout 1;     end     else         yout = yout; end 经过波形仿真发现,在位数低的情况下都是正确的,但被乘数上的最高位为1时总会出错,说明在最高位的移位操作中出现问题呢。 经过分析,是由于移位相加满足条件会产生进位但yout = {yout +areg,yout };中yout +areg会在计算结果的yout中的30~15位上相加后(yout满位数为0~31位),本想直接在31位上进位,但运行时却会忽略这种进位,因此应该主动添加进位,因此改进后应该为:yout = {{1'b0,yout }+areg,yout };这样就会主动添加了一个空的位,用于收集进位。 所以在会出现进位的情况下,一定要考虑该进位是否会影响运算结果。 最后附上改进后的程序。 /*----------------------------------------------------------------------------------------- Module Name:    test_mul16.v File Author:    creation Finish Time:    2013-07-27 Description:    16位乘法器实验 ------------------------------------------------------------------------------------------- Version         Design      Coding      Simulate        Review      Rel data V1.0 ------------------------------------------------------------------------------------------- Version         Modified History V1.0            draft -----------------------------------------------------------------------------------------*/ `timescale 1ns / 10ps module test_mul16(             input       wire            asy_rst         ,//复位             input       wire            clk             ,//50MHZ晶振             input       wire            start           ,//开始标志位             input       wire      ain             ,//16位被乘数             input       wire      bin             ,//16位乘数             output      wire      o_yout          ,//输出结果             output      wire            o_done           //输出标志位 ); /*---------------------------Internal registers and wires--------------------------------*/ /* Register Input Signals */ reg           areg;                   //被乘数寄存器 reg           breg;                   //乘数寄存器 /* Register Output Signals */ reg           yout;                   //输出结果寄存器 reg                 done;                   //输出标志位寄存器 /* internal logic use signals */ reg            cnt;                    //位移位数寄存器 /* ----------------------Logical Implementation------------------------------------------*/ /*----------------------------------------------------------------------------------------- gen the cnt signal -----------------------------------------------------------------------------------------*/ always @ ( posedge clk or negedge asy_rst ) begin     if ( !asy_rst )         cnt = 1'b0;     else if ( start == 1'b1 )                   //开始标志位拉高时,cnt赋值1,开始移位         cnt = 1'b1;     else if ( cnt 0 cnt 18 )              //cnt为1~17时,进行移位计算,18时,拉高done         cnt = cnt + 1'b1;     else                                        //不在1~17范围内时,不是进行移位         cnt = 1'b0;                            //计算状态,cnt为0          end /*----------------------------------------------------------------------------------------- gen the areg signal -----------------------------------------------------------------------------------------*/ always @ ( posedge clk or negedge asy_rst ) begin     if ( !asy_rst )         areg = 16'd0;     else if ( cnt == 1'b1)                  //在start拉高结束后一时钟周期内锁存被乘数ain         areg = ain;     else         areg = areg; end /*----------------------------------------------------------------------------------------- gen the breg signal -----------------------------------------------------------------------------------------*/ always @ ( posedge clk or negedge asy_rst ) begin     if ( !asy_rst )         breg = 16'd0;     else if ( cnt == 1'b1 )                 //在start拉高结束后一时钟周期内锁存乘数bin         breg = bin;     else         breg = breg; end /*----------------------------------------------------------------------------------------- gen the yout signal -----------------------------------------------------------------------------------------*/ always @ ( posedge clk or negedge asy_rst ) begin     if ( !asy_rst )         yout = 32'd0;     else if ( cnt == 5'd1 )                     //start拉高结束后一时钟周期内清零yout         yout = 32'd0;     else if ( cnt 5'd1 cnt 5'd18 )       //cnt为1~16进行移位计算(最高位在下边另行计算)     begin         if ( breg )                      //移位且累加             yout = {{1'b0,yout }+areg,yout };         else                                    //只移位             yout = yout 1;     end     else         yout = yout; end /*----------------------------------------------------------------------------------------- gen the done signal -----------------------------------------------------------------------------------------*/ always @ ( posedge clk or negedge asy_rst ) begin     if ( !asy_rst )         done = 1'b0;     else if ( cnt == 18 )           //cnt为18,时结束计算操作,可以进行读取         done = 1'b1;     else         done = 1'b0; end assign o_done = done;               //输出结束标志 assign o_yout = yout;               //输出结果 endmodule
相关资源