原创 一位BCD码加减模块的设计

2011-3-22 19:27 6813 6 6 分类: FPGA/CPLD

     为了完成大学里最后一个作品——毕业设计,所以要好好的下个苦工,给大学留下一个美好的结尾。我做的是基于CPLD的数字倍频器。里面有一个同步测周计数的模块,原本设想用二进制的方式来计数,但为了计算和显示的方便,还是采用BCD码方式来计数。显示部分是8位的,故需要BCD码加法器的位数也是8位的。8位BCD码加法器由8个一位BCD码加法器级联而成。如图1所示。


f63f9eb8-f09c-4429-90f6-7c731b083bc7.jpg


图1  8位BCD码加减法器


下面是原理,我想了下,干脆做一个加减法通用的计数器好。当用到减法的时候还能能派得上用场。模块化设计。


 


1位BCD码加减法器的实现原理


        BCD码是一种用4位的二进制来表示十进制的一种编码方式。加法的转换原理为当运算结果大于9(1001)时,其正确的结果为运算结果+6,但运算结果小于9(1001)时,其正确的结果即为运算结果。举个例子数字7加上数字6,其十进制结果为13,其二进制的结果为1101,值大于9,所以要加上6作为补数,才能得到正确的结果。如图2所示。


6e3e9bcc-7052-4bc0-96f5-75b6c8ef96fc.jpg


图2  BCD码加法示意图


        在Verilog代码设计时我采用先相加在调整的办法。不过这种方法有两个特殊的情况需要注意,当两个数相加刚好为16时,即二进制结果为1 0000,但是正确结果为1 0110,前面的一个1是需要进位的,剩下的4位存储空间的二进制的结果为0,可以看出必须加个6才正确。


        4位存储空间的二进制的结果为0的另外一种情况是两个数都为0时,这个时候我们不能加上6哦。故得排除这种情况,避免误操作。所以最终的调整方式为:


        当结果大于9时,补6,当结果由不同时为0的加数相加得0时,补6。语句如下:


        if((result > 4'd9 )||((result == 4'd0)&&(dataa != 0)))


        减法器的原理与加法器大致是相同的,只不多一个是补上6,而减法则是要减去多出来的6。其减法的其转换原理为当运算结果大于9(1001)时,其正确的结果为运算结果减去6,但运算结果小于9(1001)时,其运算结果就是正确的结果。


        上代码,这是自己编的,大家可以参考参考,也可以提出算法上的改进,毕竟是Verilog HDL初学者,得谦虚点,谢谢啊!


 


Verilog代码


/*


功能:    一位BCD码加减法模块


输入参数:标准时钟clk,被减数/加数dataa,减数/加数datab,低位来的借位/进位cin


输出参数:向高位的借位/进位cout,差/和result


备注:    


*/


module bcd1_add_sub (


        add_sub,//加减法选择标志位


        dataa, //被减数/加数


        datab,  //减数/加数


        cin, //低位来的借位/进位


        cout, //向高位的借位/进位


        result);//差/和



        input    add_sub;//加减法选择标志位,add_sub=1时为加法运算,add_sub=0时为减法运算


        input [3:0]   dataa;


        input [3:0]   datab;


        input cin;


        output reg cout;


        output reg[3:0]result;


always @(*)


begin


        if(add_sub)//加法运算


                begin


                result = dataa + datab + cin; // 二进制加法


                if((result > 4'd9 )||((result == 4'd0)&&(dataa != 0))) 


                /*当结果大于9时,补6,当结果由不同时为0的加数相加得0时,补6*/


                        begin


                                result = result + 4'd6;


                                cout = 1;


                        end


                else


                        begin


                                result = result;


                                cout =0;


                        end


                end


        else //减法运算


                begin


                        result = dataa - datab - cin; //二进制减法


                        if((result > 4'd9 )) /*当result>9时,result自动向高位借了1(编译器决定),这个“1”的权是16,当我们借的“1”是10,所以得减去6*/


                                begin


                                result = result - 4'd6;


                                cout = 1;//输出向高一位借位信号


                                end


                        else


                                begin


                                result = result;


                                cout =0;


                                end


                end


end



endmodule


 



上仿真波形,看看我们的BCD码加减法器结果是否正确。


波形仿真报告说明


5065a75c-f353-4e0d-b2bf-50138611d587.jpg


图3  1位BCD码加减法模块仿真图


        验证功能时,在减法操作时主要观察进位等于0和1时,dataa大于datab,dataa等于datab,dataa小于datab的情况。在加法操作时主要观察当结果大于9时以及当结果由不同时为0的加数相加得0时的情况。由仿真图得到不管是加法操作还是减法操作,都能得到正确的结果和进位,说明仿真报告正确。


 


分析综合报告


7d68590f-5b45-4de3-8853-fb522ffe0b2b.jpg   


图4 分析综合报告


        功能实现了,那就看看资源占用的情况吧,从报告中可以看出,设计占用的LE只有21个,可以说还是比较少的。


        这个毕业设计的资料貌似很少,最近被文献综述而烦恼。不过,这也是一个不断提高自己的过程,引用一句话——路漫漫其修远兮,吾将上下而求索!

PARTNER CONTENT

文章评论0条评论)

登录后参与讨论
EE直播间
更多
我要评论
0
6
关闭 站长推荐上一条 /3 下一条