|
本帖最后由 wuyongduoduo 于 2016-8-23 08:40 编辑
今天是进行矩阵键盘计算器项目的第3天,主要任务是设计十进制数转换成BCD码模块,该模块属于数码管模块,模块名称为smg_bcd。
将十进制数转换成BCD码有多种方法,其中一种方法如下:将十进制数a对10取余(a%10),即可得到个位;将a整除10后再对10取余((a/10)%10),即可得到十位;以此类推即可得到各位上的数。但由于除法器电路非常庞大,耗费资源且延迟较大,影响整个电路的运行,一般不采用这种方法。
今天设计的转BCD码用了一种算法,具体如下:
上图举了一个例子,将十进制数255转化成BCD码。首先将十进制数转换成了8位二进制数格式(系统自动就能转换,不需另外进行),自左至右排列以下数据:待转换的数据、BCD码的个位(4位二进制数)、BCD码的十位(4位二进制数)、BCD码的百位(4位二进制数)。然后将上述数据一位一位地向左移动,每移动一位就判断一下BCD码的个位、十位、百位是否大于或者等于5,是则加3后左移,否则继续左移,直至将8位待转换的数据全部左移完成。
我们所用的开发板上共有6个数码管,最大可显示的十进制数是999999,转换成二进制数是1111_0100_0010_0011_1111(20位)。定义一个20位的变量[19:0]bcd_num_r0来存放待转换的十进制数,再定义6个4位的变量[3:0]bcd_num_r1~ bcd_num_r6来作为上图中BCD码的各个位(个位、十位、百位等),还需定义一个24位的变量来存放最终转换完成的bcd码[23:0]bcd_num_r,然后按照上面例子的算法进行转换,主要代码如下:
case(bcd_state)
IDLE: begin /**************各变量在空闲状态要清零,若不清零容易导致第二次进行转码时出现错误**********************/
bcd_num_r0 <= dec_num;
bcd_num_r6 <= 4'd0;
bcd_num_r5 <= 4'd0;
bcd_num_r4 <= 4'd0;
bcd_num_r3 <= 4'd0;
bcd_num_r2 <= 4'd0;
bcd_num_r1 <= 4'd0;
bcd_state <= LEFT;
end
LEFT: begin /****************8将bcd_num_r6~r0中的数据左移*************************/
bcd_num_r6 <= {bcd_num_r6[2:0],bcd_num_r5[3]};
bcd_num_r5 <= {bcd_num_r5[2:0],bcd_num_r4[3]};
bcd_num_r4 <= {bcd_num_r4[2:0],bcd_num_r3[3]};
bcd_num_r3 <= {bcd_num_r3[2:0],bcd_num_r2[3]};
bcd_num_r2 <= {bcd_num_r2[2:0],bcd_num_r1[3]};
bcd_num_r1 <= {bcd_num_r1[2:0],bcd_num_r0[19]};
bcd_num_r0 <= {bcd_num_r0[18:0],1'b0};
if(cnt >= 19)
begin
cnt <= 0;
bcd_state <= END;/***************左移(19+1)次后完成移动跳转至END状态**********************/
end
else
begin
bcd_state <= ADD;/****************若未完成移动则跳转至ADD状态**************************/
cnt <= cnt + 1'b1;
end
end
ADD: begin /************************************判断bcd_num_r1~r6中的数据是否需要加3**********************************/
if(bcd_num_r6 >= 5)
begin
bcd_num_r6 <= bcd_num_r6 + 4'd3;
bcd_state <= LEFT;
end
else
begin
bcd_num_r6 <= bcd_num_r6;
bcd_state <= LEFT;
end
if(bcd_num_r5 >= 5)
begin
bcd_num_r5 <= bcd_num_r5 + 4'd3;
bcd_state <= LEFT;
end
else
begin
bcd_num_r5 <= bcd_num_r5;
bcd_state <= LEFT;
end
if(bcd_num_r4 >= 5)
begin
bcd_num_r4 <= bcd_num_r4 + 4'd3;
bcd_state <= LEFT;
end
else
begin
bcd_num_r4 <= bcd_num_r4;
bcd_state <= LEFT;
end
if(bcd_num_r3 >= 5)
begin
bcd_num_r3 <= bcd_num_r3 + 4'd3;
bcd_state <= LEFT;
end
else
begin
bcd_num_r3 <= bcd_num_r3;
bcd_state <= LEFT;
end
if(bcd_num_r2 >= 5)
begin
bcd_num_r2 <= bcd_num_r2 + 4'd3;
bcd_state <= LEFT;
end
else
begin
bcd_num_r2 <= bcd_num_r2;
bcd_state <= LEFT;
end
if(bcd_num_r1 >= 5)
begin
bcd_num_r1 <= bcd_num_r1 + 4'd3;
bcd_state <= LEFT;
end
else
begin
bcd_num_r1 <= bcd_num_r1;
bcd_state <= LEFT;
end
end
END: begin /********************转码成功,输出bcd_num_r********************************8/
bcd_num_r <= {bcd_num_r6,bcd_num_r5,bcd_num_r4,
bcd_num_r3,bcd_num_r2,bcd_num_r1};
bcd_state <= IDLE;
end
default: bcd_state <= IDLE;
endcase
assign bcd_num = bcd_num_r; |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?我要注册
x
|