[verilog] 倒计时系统设计(中)之BCD编码模块

[复制链接]
 楼主| zhangyuhua 发表于 2017-3-18 22:15 | 显示全部楼层 |阅读模式
      上篇写了倒计时系统的计时模块,这篇接着写倒计时系统的BCD编码模块。首先介绍下,BCD码的定义。      BCD码是指用4位二进制数来表示1位十进制数0——9中的一个。
      设计此模块的原因:假如上一篇计时模块的输出cnt_s=21、cnt_ms=45(即21.45),它是二进制数;而数码管显示是将cnt_s=21/cnt_ms=45的个位和十位分别显示的。故此需要将二进制数转化成BCD码。
      (一)二进制数转BCD码的原理(加3移位算法)
                首先,定义一个4*N位的BCD码,如bcd_data[7:0]=8'h00,需被转换的二进制数定义成din[7:0]。
                然后,将din[7]移入bcd_data[0],将bcd_data[7:0]每四位分成一组,这4位组成的二进制数若>=5,则加3后再赋值于bcd_data[7:0];若<5,则将bcd_data[7:0]保持不变。依次进行上步操作,直至将din[7:0]的数值全部移入bcd_data[7:0]中。
             需要注意的是,被转换的二进制数din是N位,则需要转移的次数就是N次,判断的次数是(N-1)次。
      (二) BCD编码的模块框图:

      (三)源代码:
  1. module bcd(
  2.                         //System Signals
  3.                         input                                        sclk                        ,
  4.                         input                                        rst_n                        ,
  5.                         //Others
  6.                         input                                        bcd_trig                ,
  7.                         input                        [7:0]        din                                ,        //max is 99
  8.                                                                                                                 //cnt_ms[7:0],cnt_s[7:0]
  9.                         output                reg        [7:0]        bcd_data                ,        //two smg:4bit+4bit
  10.                                                                                                                 //bcd_cnt_ms[7:0],bcd_cnt_s[7:0]
  11.                         output                reg                        bcd_data_vld       
  12.                 );
  13. //========================================================================\
  14. // **********Define Parameter and Internal Signals*******************
  15. //========================================================================/
  16. parameter        END_SHIFT        =        8                ;        //din is 8 bit
  17. parameter        IDLE                =        3'b001        ;
  18. parameter        SHIFT                =        3'b010        ;
  19. parameter        ADD                        =        3'b100        ;

  20. reg                [7:0]        din_temp                ;       
  21. reg                [3:0]        bcd_data_r1                ;        //unit
  22. reg                [3:0]        bcd_data_r2                ;        //ten
  23. reg                [2:0]        state                        ;
  24. reg                [3:0]        cnt_shift                ;
  25. reg                                flag_bcd                ;
  26. //========================================================================\
  27. // **********Main Code*******************
  28. //========================================================================/
  29. //flag_bcd
  30. always @(posedge sclk or negedge rst_n)
  31.         begin
  32.                 if(!rst_n)
  33.                         flag_bcd<=1'b0;
  34.                 else        if(bcd_trig==1'b1)
  35.                                         flag_bcd<=1'b1;
  36.                                 else        if(bcd_data_vld==1'b1)
  37.                                                         flag_bcd<=1'b0;
  38.         end
  39. always @(posedge sclk or negedge rst_n)
  40.         begin
  41.                 if(!rst_n)
  42.                         begin
  43.                                 bcd_data_r1<=4'b0000;
  44.                                 bcd_data_r2<=4'b0000;
  45.                                 bcd_data<=8'd0;
  46.                                 bcd_data_vld<=1'b0;
  47.                                 cnt_shift<=4'd0;
  48.                                 din_temp<=8'd0;
  49.                                 state<=IDLE;
  50.                         end
  51.                 else        //if(flag_bcd)
  52.                                         begin
  53.                                                 case(state)
  54.                                                         IDLE:        begin
  55.                                                                                 bcd_data_vld<=1'b0;
  56.                                                                                 if(flag_bcd==1'b1)
  57.                                                                                         begin
  58.                                                                                                 din_temp<=din;
  59.                                                                                                 bcd_data_r1<=4'b0000;
  60.                                                                                                 bcd_data_r2<=4'b0000;
  61.                                                                                                 state<=SHIFT;
  62.                                                                                         end
  63.                                                                                 else        state=IDLE;
  64.                                                                         end
  65.                                                         SHIFT:        begin
  66.                                                                                 if(cnt_shift<END_SHIFT)
  67.                                                                                         begin
  68.                                                                                                 bcd_data_r1<={bcd_data_r1[2:0],din_temp[7]};
  69.                                                                                                 bcd_data_r2<={bcd_data_r2[2:0],bcd_data_r1[3]};
  70.                                                                                                 din_temp<={din_temp[6:0],1'b0};
  71.                                                                                                 cnt_shift<=cnt_shift+1'b1;
  72.                                                                                                 state<=ADD;
  73.                                                                                         end
  74.                                                                                 else        begin
  75. bcd_data_vld<=1'b0;
  76. state<=IDLE;
  77. end
  78.                                                                         end
  79.                                                         ADD:        begin
  80.                                                                                 if(cnt_shift<END_SHIFT)
  81.                                                                                         begin
  82.                                                                                                 if(bcd_data_r1>='d5)
  83.                                                                                                         bcd_data_r1<=bcd_data_r1+'d3;
  84.                                                                                                 else        bcd_data_r1<=bcd_data_r1;
  85.                                                                                                
  86.                                                                                                 if(bcd_data_r2>='d5)
  87.                                                                                                         bcd_data_r2<=bcd_data_r2+'d3;
  88.                                                                                                 else        bcd_data_r2<=bcd_data_r2;
  89.                                                                                                
  90.                                                                                                 state<=SHIFT;
  91.                                                                                         end                                                                                        
  92.                                                                                 else        begin
  93.                                                                                                         bcd_data<={bcd_data_r2,bcd_data_r1};
  94.                                                                                                         bcd_data_vld<=1'b1;
  95.                                                                                                         cnt_shift<='d0;
  96.                                                                                                         state<=IDLE;
  97.                                                                                                 end
  98.                                                                         end
  99.                                                         default:        begin
  100.                                                                                         state<=IDLE;
  101.                                                                                         cnt_shift<='d0;
  102.                                                                                 end
  103.                                                 endcase
  104.                                         end
  105.         end

  106. endmodule
    (四)这个模块主要使用了一个状态机。这个状态机也比较简单,一共三个状态,分别是初始态(IDLE)、移位态(SHIFT)和判断加3态(ADD)。下面是其状态转移图:

     (五)总结
           在这个模块中也使用了自己代码的一贯风格:
               A.   定义了此模块被触发的开始信号bcd_trig;
               B.   BCD编码正在工作状态的信号flag_bcd;
               C.   BCD编码完成信号bcd_data_vld.






本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有账号?注册

×
teleagle 发表于 2017-3-25 23:35 | 显示全部楼层
学习了,但代码怎么这么乱,可能是我的编辑器出问题了.
您需要登录后才可以回帖 登录 | 注册

本版积分规则

14

主题

26

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部

14

主题

26

帖子

1

粉丝
快速回复 在线客服 返回列表 返回顶部