⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 hc164_driver.v

📁 xilinx ISE 实例代码。可用ISE直接打开
💻 V
字号:
//////////////////////////////////////////////////////////////////////////////////       ____  _      __  ___                                                 ////      / __ \(_)____/ / / (_)____      本设计由 www.richic.com 提供,并在其低////     / /_/ / / ___/ /_/ / / ___/      端产品:FPGA学习板、FPGA试验系统以及其////    / _, _/ / /__/ __  / / /__        高端产品:FPGA开发系统中验证通过,您可////   /_/ |_/_/\___/_/ /_/_/\___/        以在此基础上修改,复制并分发。但我们并////                                      不承诺本设计可以用做商业产品,同时我们////  不保证设计的通用性。为了方便更新以及修改请保留设计的版本信息,请对自行修改////  部分添加足够注释。对设计如有其他建议请到 www.richic.com网站进行讨论       ////                                                                            ////////////////////////////////////////////////////////////////////////////////////                                                                            ////  FPGA实验教程          http://www.richic.com/lab                           ////  FPGA实验教程EDACN镜像 http://www.edacn.com/rhic/                          ////  本教程所有设计在本公司开发板上验证通过                                    ////                                                                            ////////////////////////////////////////////////////////////////////////////////////  Company:    www.richic.com                                                ////  Engineer:   mail007 (Gavin.xue)                                           ////                                                                            ////  Design Name:                                                              ////  Module Name:                                                              ////  Target Device:                                                            ////  Tool versions: Simulation:                                                ////                 Synthesis:     XST(ise6.3...sp2)                           ////                 Place&Routing: ISE6.3...sp2                                ////                 Others tools:                                              ////  Create Date:   2006-01-31 11:37                                           ////  Description:                                                              ////                                                                            ////  LOG:                                                                      ////                                                                            //////////////////////////////////////////////////////////////////////////////////`timescale 1ns/1ns  // ---------------------------------------------------------------------------  //HC164用来驱动数码管以及LED指示灯,动态扫描数码管的是利用视觉暂留的特性进行显  //示景物引起人的视觉印象,在景物消失后还能在视网膜上保持0。1秒的时间叫做视觉暂  //留。可以将数据刷新速率可以为10Hz(0.1s),同时我们需要对四位数据进行扫描,因此  //数据刷新速率最低应该为10Hz×4。最高可以为50MHz(HC164可以工作在50-175MHz)。  //根据实际情况我们可以定为 762.939453125 = 50MHz/2**16,  //因此接口处led,seg_value,dot数据的变化速率最大不能超过为50MHz/2**14  // ---------------------------------------------------------------------------module hc164_driver
(    clk,    rst_n,    led,    seg_value,    dot,    hc_si,    hc_cp    );  // ---------------------------------------------------------------------------  //  //  input signals  //  led[3:0] :       led3-led0 对应原理图中D5,D4,D3,D2四位LED灯,高电平有效。  //  seg_value[15:0] :四位共阴极数码显示的数据,从高到低每4bit为数码管一位。  //  dot[3:0] :       四位共阴极数码管显示的小数点位,从高到低  //  hc_si :          本模块数据串行输出,hc164数据串行输入。  //  hc_cp :          本模块输出,hc164时钟输入。  //    // ---------------------------------------------------------------------------  input           clk;  input           rst_n;    input   [3 :0]  led;          input   [15:0]  seg_value;    input   [3 :0]  dot;  output          hc_si;                //HC164 Data input  output  reg     hc_cp;                //HC164 Clock input active Rising edges  reg     [5 :0]  tx_cnt;  //  wire  [15:0]  seg_value = 16'h1234;//  wire  [3:0]   dot = 4'b0010; //  wire  [3:0]   led = 4'b1111;    // ---------------------------------------------------------------------------  //  //  信号命名说明  //  hc_data : 送到两个hc164中16bit的数据(每个hc164有8bit),hc164 data input  //  hc_data_44bit: hc_data的第四个4BIT数据,  //                 LED显示信号,对应原理图中HC_Q15,HC_Q14,HC_Q13,HC_Q12四位,  //                 用来点亮D5,D4,D3,D2四位LED灯,高电平有效。  //  hc_data_34bit: hc_data的第三个4bit数据,即hc_data[11:8];对应原理图中  //                 HC_Q11,HC_Q10,HC_Q9,HC_Q8数码管位选信号,低电平有效。  //  hc_data_31bit: hc_data的第三个1bit数据,即hc_data[2];对应原理图中HC_Q2,数  //                 码管小数点位,高电平有效。   //  hc_data[7:0]: 包括hc_data_31bit,这8bit用来做为数码管段选信号,高电平有效  //  // ---------------------------------------------------------------------------  reg   [6:0]   hex2led;        //hex-to-seven-segment decoder output   reg   [3:0]   hc_data_34bit;    reg           hc_data_31bit;        wire  [15:0]  hc_data = {led,                          hc_data_34bit,                          hex2led[6:2],                          hc_data_31bit,                          hex2led[1:0]                          };  // ---------------------------------------------------------------------------  //  //  之所以需要取反,是因为对hc_si赋值时从最低位开始,而原理图中设计希望从最高位  //  开始发送数据。  //  // ---------------------------------------------------------------------------  wire  [15:0]  hc_data_inv = {                          hc_data[0],                          hc_data[1],                          hc_data[2],                          hc_data[3],                          hc_data[4],                          hc_data[5],                          hc_data[6],                          hc_data[7],                          hc_data[8],                          hc_data[9],                          hc_data[10],                          hc_data[11],                          hc_data[12],                          hc_data[13],                          hc_data[14],                          hc_data[15]                          };  reg [15:0]  clk_cnt;  always @ ( posedge clk or negedge rst_n )    if ( !rst_n ) clk_cnt <= 16'd0;    else  clk_cnt <= clk_cnt + 1'b1;  //  reg [9:0]  clk_cnt;  //  always @ ( posedge clk or negedge rst_n )  //    if ( !rst_n ) clk_cnt <= 10'd0;  //    else  clk_cnt <= clk_cnt + 1'b1;        // ---------------------------------------------------------------------------  //   //  数据管4位计数器,本计数器用来区分每位数值,位码,以及每位的小数点等三个  //  信息,每一位数值将通过hex2led模块变换成数码管位码。  //  // ---------------------------------------------------------------------------  reg [1:0] seg_led_num;  always @ ( posedge clk or negedge rst_n )    if (!rst_n ) seg_led_num <= 2'b00;    else if ( clk_cnt == 16'hFFFF ) seg_led_num <= seg_led_num + 1'b1;  reg   [3:0] hex;  //  always @ ( * )  always @ ( seg_led_num or hex or seg_value )    case ( seg_led_num )      2'b00: hex = seg_value[15:12];      2'b01: hex = seg_value[11:8];      2'b10: hex = seg_value[7:4];      2'b11: hex = seg_value[3:0];    endcase     // ---------------------------------------------------------------------------  // hex-to-seven-segment decoder  //  // segment encoding  //      11  //      ---    //  10 |   | 7  //      ---   <- 5  //  1  |   | 4  //      --- .  3  //       2   //  Q[6:0] = p11 p10 p7 p5 _ p4 p2 p1   // ---------------------------------------------------------------------------//  always @ ( * )  always @ ( hex or hex2led )    begin      case (hex)                        //数值 	    4'H1  : hex2led = 7'b0010_100;	  //1          	    4'H2  : hex2led = 7'b1011_011;	  //2   	    4'H3  : hex2led = 7'b1011_110;	  //3   	    4'H4  : hex2led = 7'b0111_100;	  //4   	    4'H5  : hex2led = 7'b1101_110;	  //5   	    4'H6  : hex2led = 7'b1101_111;	  //6   	    4'H7  : hex2led = 7'b1010_100;	  //7   	    4'H8  : hex2led = 7'b1111_111;	  //8   	    4'H9  : hex2led = 7'b1111_100;	  //9   	    4'HA  : hex2led = 7'b1111_101;	  //A   	    4'HB  : hex2led = 7'b0101_111;	  //b   	    4'HC  : hex2led = 7'b1100_011;	  //C   	    4'HD  : hex2led = 7'b0011_111;	  //d   	    4'HE  : hex2led = 7'b1101_011;	  //E   	    4'HF  : hex2led = 7'b1101_001;	  //F   	    default : hex2led = 7'b1110_111;	//0       endcase  end//hex2led_common_cathode hex2led_inst(//    .hex    ( hex ),//    .led    ( hex2led )); //  always @ ( * )  always @ ( seg_led_num or hc_data_34bit )    case ( seg_led_num )      2'b00:hc_data_34bit[3:0] = 4'b0111;      2'b01:hc_data_34bit[3:0] = 4'b1011;      2'b10:hc_data_34bit[3:0] = 4'b1101;      2'b11:hc_data_34bit[3:0] = 4'b1110;    endcase  //  always @ ( * )  always @ ( seg_led_num or hc_data_31bit or dot )    case ( seg_led_num )      2'b00:hc_data_31bit = dot[3];      2'b01:hc_data_31bit = dot[2];      2'b10:hc_data_31bit = dot[1];      2'b11:hc_data_31bit = dot[0];    endcase      // ---------------------------------------------------------------------------  //   // HC164 的 hc_si 以及hc_cp信号的产生,通过一个6位的计数器来控制.hc_si从信号  // hc_data_inv的最低位开始发送,原理图中需要从最高位发送,因此在此之前需要对整  // 个信号取反。  //  // ---------------------------------------------------------------------------    always @ ( posedge clk or negedge rst_n )    if (!rst_n ) tx_cnt <= 6'd0;    else if ( clk_cnt[15] ) tx_cnt <= 6'd0;          else if ((!clk_cnt[15]) && (tx_cnt <= 6'd32 )) tx_cnt <= tx_cnt + 1'b1;  always @ ( posedge clk or negedge rst_n )    if (!rst_n)  hc_cp <= 1'b0;    else if ( clk_cnt[15] ) hc_cp <= 1'b0;    else if ((!clk_cnt[15]) && (tx_cnt < 6'd32 )) hc_cp <= !hc_cp;  assign  hc_si = hc_data_inv[tx_cnt[4:1]];    //  reg [5:0] tx_cnt;//  always @ ( posedge clk or negedge rst_n )//    if (!rst_n ) tx_cnt <= 6'd0;//    else if ( clk_cnt[9] ) tx_cnt <= 6'd0;      //    else if ( (!clk_cnt[9]) && (tx_cnt < 6'd32 )) tx_cnt <= tx_cnt + 1'b1;////  always @ ( posedge clk or negedge rst_n )//    if (!rst_n)  hc_cp <= 1'b0;//    else if ( clk_cnt[9] ) hc_cp <= 1'b0;//    else if ((!clk_cnt[9]) && (tx_cnt < 6'd32 )) hc_cp <= !hc_cp;    endmodule

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -