hc164_driver.v
上传用户:lcztgy
上传日期:2007-03-17
资源大小:70k
文件大小:11k
源码类别:

并行计算

开发平台:

VHDL

  1. ////////////////////////////////////////////////////////////////////////////////
  2. //                __     ___ _               ___ ____                         //
  3. //                    / (_) |__   ___  ___|_ _/ ___|                        //
  4. //                   / /| | '_  / _ / __|| | |                            //
  5. //                   V / | | |_) |  __/__ | | |___                         //
  6. //                   _/  |_|_.__/ ___||___/_______|                        //
  7. //                                                                            //
  8. ////////////////////////////////////////////////////////////////////////////////
  9. //     Copyright (C) 2003-2006 VibesIC, Inc.   All rights reserved.           //
  10. //----------------------------------------------------------------------------//
  11. // This source code is provided by VibesIC,and be verified on VibesIC FPGA    //
  12. // development kit. The source code may be used and distributed without       //
  13. // restriction provided that this copyright statement is not removed from the //
  14. // file and that any derivative work contains the original copyright notice   //
  15. // and the associated disclaimer.                                             //
  16. //----------------------------------------------------------------------------//
  17. // THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED     //
  18. // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF       //
  19. // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE//
  20. // AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,     //
  21. // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES(INCLUDING, BUT NOT LIMITED TO,//
  22. // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,OR PROFITS; //
  23. // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,   //
  24. // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR    //
  25. // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF     //
  26. // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.                                 //
  27. //----------------------------------------------------------------------------//
  28. // 本设计由威百仕( VibesIC )提供,并在其产品中验证通过,您可以在此基础上修改,//
  29. // 复制并分发,但请您保留版权声明部分。我们并不承诺本设计可以用做商业产品,同时//
  30. // 我们不保证设计的通用性。为了方便更新以及修改请保留设计的版本信息,并对自行 //
  31. // 修改部分添加足够的注释。对设计如有其他建议,请到网站进行讨论。              //
  32. //                                                                            //
  33. ////////////////////////////////////////////////////////////////////////////////
  34. //  Company:       www.richic.com                                             //
  35. //  Company bbs:   www.edacn.net                                              //
  36. //  Engineer:      mail007 (Gavin.xue)                                        //
  37. //                                                                            //
  38. //  Target Device: XC3S400-PQ208                                              //
  39. //  Tool versions: Simulation:    ModelSim SE 6.2a                            //
  40. //                 Synthesis:     XST(ise8.1...sp3)                           //
  41. //                 Place&Routing: ISE8.1...sp3                                //
  42. //                 Others tools:  UltraEdit-32 12.10a                         //
  43. //  Create Date:   2005-9-15 14:59                                            //
  44. //  Description:                                                              //
  45. //                                                                            //
  46. //  LOG:                                                                      //
  47. //       1. Revision 1.0 (Initial version)  2005-9-15 14:59    mail007        //
  48. //                                                                            //
  49. //       2. Revision 1.1  2006-12-22 11:48   alex_yang                        //
  50. //          Updata ISE version from v6.3 to v8.1                              //
  51. //          Modify for VX-SP306                                               //
  52. ////////////////////////////////////////////////////////////////////////////////
  53. `timescale 1ns/1ns
  54.   // ---------------------------------------------------------------------------
  55.   //HC164用来驱动数码管以及LED指示灯,动态扫描数码管的是利用视觉暂留的特性进行显
  56.   //示景物引起人的视觉印象,在景物消失后还能在视网膜上保持0。1秒的时间叫做视觉暂
  57.   //留。可以将数据刷新速率可以为10Hz(0.1s),同时我们需要对四位数据进行扫描,因此
  58.   //数据刷新速率最低应该为10Hz×4。最高可以为50MHz(HC164可以工作在50-175MHz)。
  59.   //根据实际情况我们可以定为 762.939453125 = 50MHz/2**16,
  60.   //因此接口处led,seg_value,dot数据的变化速率最大不能超过为50MHz/2**14
  61.   // ---------------------------------------------------------------------------
  62. module hc164_driver(
  63.     clk,
  64.     rst_n,
  65.     led,
  66.     dot,
  67.     seg_value,
  68.     hc_cp,
  69.     hc_si
  70.     );
  71.   // ---------------------------------------------------------------------------
  72.   //
  73.   //  input signals
  74.   //  led[3:0] :       led3-led0 对应原理图中D5,D4,D3,D2四位LED灯,高电平有效。
  75.   //  seg_value[15:0] :四位共阴极数码显示的数据,从高到低每4bit为数码管一位。
  76.   //  dot[3:0] :       四位共阴极数码管显示的小数点位,从高到低
  77.   //  hc_si :          本模块数据串行输出,hc164数据串行输入。
  78.   //  hc_cp :          本模块输出,hc164时钟输入。
  79.   //  
  80.   // ---------------------------------------------------------------------------
  81.   input           clk;
  82.   input           rst_n;  
  83.   input   [3 :0]  led; 
  84.   input   [3 :0]  dot;       
  85.   input   [15:0]  seg_value; 
  86.   output  reg     hc_cp;                //HC164 Clock input active Rising edges
  87.   output          hc_si;                //HC164 Data input
  88.   reg     [5 :0]  tx_cnt;
  89.  
  90.   // ---------------------------------------------------------------------------
  91.   //
  92.   //  信号命名说明
  93.   //  hc_data : 送到两个hc164中16bit的数据(每个hc164有8bit),hc164 data input
  94.   //  hc_data_44bit: hc_data的第四个4BIT数据,
  95.   //                 LED显示信号,对应原理图中HC_Q15,HC_Q14,HC_Q13,HC_Q12四位,
  96.   //                 用来点亮D5,D4,D3,D2四位LED灯,高电平有效。
  97.   //  hc_data_34bit: hc_data的第三个4bit数据,即hc_data[11:8];对应原理图中
  98.   //                 HC_Q11,HC_Q10,HC_Q9,HC_Q8数码管位选信号,低电平有效。
  99.   //  hc_data_31bit: hc_data的第三个1bit数据,即hc_data[2];对应原理图中HC_Q2,数
  100.   //                 码管小数点位,高电平有效。 
  101.   //  hc_data[7:0]: 包括hc_data_31bit,这8bit用来做为数码管段选信号,高电平有效
  102.   //
  103.   // ---------------------------------------------------------------------------
  104.   reg   [6:0]   hex2led;        //hex-to-seven-segment decoder output 
  105.   reg   [3:0]   hc_data_34bit;  
  106.   reg           hc_data_31bit;    
  107.   
  108.   wire  [15:0]  hc_data = {led,
  109.                           hc_data_34bit,
  110.                           hex2led[6:2],
  111.                           hc_data_31bit,
  112.                           hex2led[1:0]
  113.                           };
  114.   // ---------------------------------------------------------------------------
  115.   //
  116.   //  之所以需要取反,是因为对hc_si赋值时从最低位开始,而原理图中设计希望从最高位
  117.   //  开始发送数据。
  118.   //
  119.   // ---------------------------------------------------------------------------
  120.   wire  [15:0]  hc_data_inv = {
  121.                           hc_data[0],
  122.                           hc_data[1],
  123.                           hc_data[2],
  124.                           hc_data[3],
  125.                           hc_data[4],
  126.                           hc_data[5],
  127.                           hc_data[6],
  128.                           hc_data[7],
  129.                           hc_data[8],
  130.                           hc_data[9],
  131.                           hc_data[10],
  132.                           hc_data[11],
  133.                           hc_data[12],
  134.                           hc_data[13],
  135.                           hc_data[14],
  136.                           hc_data[15]
  137.                           };
  138.   reg [15:0]  clk_cnt;
  139.   always @ ( posedge clk or negedge rst_n )
  140.     if ( !rst_n ) clk_cnt <= 16'd0;
  141.     else  clk_cnt <= clk_cnt + 1'b1;
  142.       
  143.   // ---------------------------------------------------------------------------
  144.   // 
  145.   //  数据管4位计数器,本计数器用来区分每位数值,位码,以及每位的小数点等三个
  146.   //  信息,每一位数值将通过hex2led模块变换成数码管位码。
  147.   //
  148.   // ---------------------------------------------------------------------------
  149.   reg [1:0] seg_led_num;
  150.   always @ ( posedge clk or negedge rst_n )
  151.     if (!rst_n ) seg_led_num <= 2'b00;
  152.     else if ( clk_cnt == 16'hFFFF ) seg_led_num <= seg_led_num + 1'b1;
  153.   reg   [3:0] hex;
  154.   always @ ( * )
  155.     case ( seg_led_num )
  156.       2'b00: hex = seg_value[15:12];
  157.       2'b01: hex = seg_value[11:8];
  158.       2'b10: hex = seg_value[7:4];
  159.       2'b11: hex = seg_value[3:0];
  160.     endcase 
  161.   
  162.   // ---------------------------------------------------------------------------
  163.   // hex-to-seven-segment decoder
  164.   //
  165.   // segment encoding
  166.   //      11
  167.   //      ---  
  168.   //  10 |   | 7
  169.   //      ---   <- 5
  170.   //  1  |   | 4
  171.   //      --- .  3
  172.   //       2 
  173.   //  Q[6:0] = p11 p10 p7 p5 _ p4 p2 p1 
  174.   // ---------------------------------------------------------------------------
  175.   always @ ( * )
  176.     begin
  177.       case (hex)                        //数值 
  178.       4'h1  : hex2led = 7'b0010_100; //1          
  179.       4'h2  : hex2led = 7'b1011_011; //2   
  180.       4'h3  : hex2led = 7'b1011_110; //3   
  181.       4'h4  : hex2led = 7'b0111_100; //4   
  182.       4'h5  : hex2led = 7'b1101_110; //5   
  183.       4'h6  : hex2led = 7'b1101_111; //6   
  184.       4'h7  : hex2led = 7'b1010_100; //7   
  185.       4'h8  : hex2led = 7'b1111_111; //8   
  186.       4'h9  : hex2led = 7'b1111_100; //9   
  187.       4'hA  : hex2led = 7'b1111_101; //A   
  188.       4'hB  : hex2led = 7'b0101_111; //b   
  189.       4'hC  : hex2led = 7'b1100_011; //C   
  190.       4'hD  : hex2led = 7'b0011_111; //d   
  191.       4'hE  : hex2led = 7'b1101_011; //E   
  192.       4'hF  : hex2led = 7'b1101_001; //F   
  193.     default : hex2led = 7'b1110_111; //0   
  194.     endcase
  195.   end
  196.  
  197.   always @ ( * )
  198.     case ( seg_led_num )
  199.       2'b00:hc_data_34bit[3:0] = 4'b0111;
  200.       2'b01:hc_data_34bit[3:0] = 4'b1011;
  201.       2'b10:hc_data_34bit[3:0] = 4'b1101;
  202.       2'b11:hc_data_34bit[3:0] = 4'b1110;
  203.     endcase  
  204.   always @ ( * )
  205.     case ( seg_led_num )
  206.       2'b00:hc_data_31bit = dot[3];
  207.       2'b01:hc_data_31bit = dot[2];
  208.       2'b10:hc_data_31bit = dot[1];
  209.       2'b11:hc_data_31bit = dot[0];
  210.     endcase  
  211.   
  212.   // ---------------------------------------------------------------------------
  213.   // 
  214.   // HC164 的 hc_si 以及hc_cp信号的产生,通过一个6位的计数器来控制.hc_si从信号
  215.   // hc_data_inv的最低位开始发送,原理图中需要从最高位发送,因此在此之前需要对整
  216.   // 个信号取反。
  217.   //
  218.   // ---------------------------------------------------------------------------  
  219.   always @ ( posedge clk or negedge rst_n )
  220.     if (!rst_n ) tx_cnt <= 6'd0;
  221.     else if ( clk_cnt[15] ) tx_cnt <= 6'd0;      
  222.     else if ((!clk_cnt[15]) && (tx_cnt <= 6'd32 )) tx_cnt <= tx_cnt + 1'b1;
  223.   always @ ( posedge clk or negedge rst_n )
  224.     if (!rst_n)  hc_cp <= 1'b0;
  225.     else if ( clk_cnt[15] ) hc_cp <= 1'b0;
  226.     else if ((!clk_cnt[15]) && (tx_cnt < 6'd32 )) hc_cp <= !hc_cp;
  227.   assign  hc_si = hc_data_inv[tx_cnt[4:1]];
  228.     
  229. endmodule