📄 hc164_driver.v
字号:
`timescale 1ns / 1ps//////////////////////////////////////////////////////////////////////////////////// Company: // Engineer: // // Create Date: 17:19:29 11/13/2007 // Design Name: // Module Name: hc164_driver // Project Name: // Target Devices: // Tool versions: // Description: //// Dependencies: //// Revision: // Revision 0.01 - File Created// Additional Comments: ////////////////////////////////////////////////////////////////////////////////////module hc164_driver (
iCLK50M , // system clock
iRST_N , // system reset, Active--Low
iLED_SEL , // led select, Width---4, Active---Low
iDOT_SEL , // dot select, Width---4, Active---High
iLED_VALUE , // led value, Width---16
oHC_SI , // serial data signal
oHC_CP // hc164 clock pulse
);
input iCLK50M ; // system clock
input iRST_N ; // system reset
input [3:0] iLED_SEL ; // led select, Width---4, Active---Low
input [3:0] iDOT_SEL ; // dot select, Width---4, Active---high
input [15:0] iLED_VALUE ; // led value, Width---16
output oHC_SI ; // serial data signal
output oHC_CP ; // hc164 clock pulse
/*==================================================*/
// sr_clk_counter //
/*==================================================*/
reg [15:0] sr_clk_counter ;
always @ ( posedge iCLK50M or negedge iRST_N )
if( !iRST_N )
sr_clk_counter <= 16'd0;
else
sr_clk_counter <= sr_clk_counter + 1;
/*==================================================*/
// sr_LED_num
//选位信号为65535/50*10^6,即763Hz,则遍历四段数码管只需0.05s,在视觉上人眼感觉数字在停留
/*==================================================*/
reg [1:0] sr_LED_num;
always @ ( posedge iCLK50M or negedge iRST_N )
if ( !iRST_N)
sr_LED_num <= 2'b00;
else if ( sr_clk_counter == 16'hffff)
sr_LED_num <= sr_LED_num + 1'b1;
/*==================================================*/
// sr_dot_select //
// 小数点选择信号,共四个小数点
/*==================================================*/
reg sr_dot_select ;
always @ ( sr_LED_num or iDOT_SEL )
sr_dot_select = iDOT_SEL[sr_LED_num];
/*==================================================*/
// sr_hex //
// 七段译码管的值直接通过iLED_VALUE赋值输入即可
/*==================================================*/
reg [3:0] sr_hex ;
always @ ( sr_LED_num or iLED_VALUE )
case ( sr_LED_num )
2'b00: sr_hex = iLED_VALUE[3:0];
2'b01: sr_hex = iLED_VALUE[7:4];
2'b10: sr_hex = iLED_VALUE[11:8];
2'b11: sr_hex = iLED_VALUE[15:12];
default: sr_hex = 4'b0000;
endcase
/*==================================================*/
// sr_led_sel
// 选段信号,每间隔763Hz,跳转一位.0.05s遍历一遍
/*==================================================*/
reg [3:0] sr_led_sel;
always @ ( sr_LED_num or iRST_N)
if ( !iRST_N )
sr_led_sel = 4'b0000;
else
case( sr_LED_num )
2'b00: sr_led_sel = 4'b1110;
2'b01: sr_led_sel = 4'b1101;
2'b10: sr_led_sel = 4'b1011;
2'b11: sr_led_sel = 4'b0111;
endcase
/*==================================================*/
// sr_hex2led //
// segment encoding
// 11
// ---
// 10 | | 7
// --- <- 5
// 1 | | 4
// --- . 3
// 2
// Q[6:0] = p11 p10 p7 p5 _ p4 p2 p1
/*==================================================*/
reg [6:0] sr_hex2led;
always @ ( sr_hex )
case ( sr_hex )
4'H1 : sr_hex2led = 7'b0010_100; //1
4'H2 : sr_hex2led = 7'b1011_011; //2
4'H3 : sr_hex2led = 7'b1011_110; //3
4'H4 : sr_hex2led = 7'b0111_100; //4
4'H5 : sr_hex2led = 7'b1101_110; //5
4'H6 : sr_hex2led = 7'b1101_111; //6
4'H7 : sr_hex2led = 7'b1010_100; //7
4'H8 : sr_hex2led = 7'b1111_111; //8
4'H9 : sr_hex2led = 7'b1111_100; //9
4'HA : sr_hex2led = 7'b1111_101; //A
4'HB : sr_hex2led = 7'b0101_111; //b
4'HC : sr_hex2led = 7'b1100_011; //C
4'HD : sr_hex2led = 7'b0011_111; //d
4'HE : sr_hex2led = 7'b1101_011; //E
4'HF : sr_hex2led = 7'b1101_001; //F
default : sr_hex2led = 7'b1110_111; //0
endcase
/*==================================================*/
// sr_hc_data_buffer //
/*==================================================*/
// ---------------------------------------------------------------------------
//
// 信号命名说明
// hc_data : 送到两个hc164中16bit的数据(每个hc164有8bit),hc164 data input
// iLED_SEL: hc_data的第四个4BIT数据,
// LED显示信号,对应原理图中HC_Q15,HC_Q14,HC_Q13,HC_Q12四位,
// 用来点亮D5,D4,D3,D2四位LED灯,高电平有效。
// sr_led_sel: hc_data的第三个4bit数据,即hc_data[11:8];对应原理图中
// HC_Q11,HC_Q10,HC_Q9,HC_Q8数码管位选信号,低电平有效。
// sr_dot_select: hc_data的第三个1bit数据,即hc_data[2];对应原理图中HC_Q2,数
// 码管小数点位,高电平有效。
// sr_hex2led[7:0]: 包括hc_data_31bit,这8bit用来做为数码管段选信号,高电平有效
//
// ---------------------------------------------------------------------------
reg [15:0] sr_hc_data_buffer ;
always @ ( sr_hex2led or sr_led_sel or sr_dot_select or iLED_SEL )
sr_hc_data_buffer[15:0] = { iLED_SEL, //15->12
sr_led_sel[3:0], //11->8
sr_hex2led[6:2], //7->3
sr_dot_select , //2
sr_hex2led[1:0] //1->0
};
/*==================================================*/
// sr_shift_counter //
/*==================================================*/
reg [5:0] sr_shift_counter;
always @ ( posedge iCLK50M or negedge iRST_N )
if ( !iRST_N )
sr_shift_counter <= 6'b000_000;
else if ( sr_clk_counter[15] )
sr_shift_counter <= 6'b000_000;
else if ( (!sr_clk_counter[15]) & (sr_shift_counter <= 32) )
sr_shift_counter <= sr_shift_counter + 1'b1;
/*==================================================*/
// sr_cp
// 通过系统时钟给入,使hc164能进行动作,每进入16个二进制数,重复上一次动作,以此往复 //
/*==================================================*/
reg sr_cp;
always @ ( posedge iCLK50M or negedge iRST_N )
if ( !iRST_N )
sr_cp <= 1'b0;
else if ( sr_clk_counter[15] )
sr_cp <= 1'b0;
else if ( (!sr_clk_counter[15]) & ( sr_shift_counter < 6'd32 ))
sr_cp <= ~sr_cp;
/*===================================================*/
// oHC_CP, oHC_SI //
/*====================================================*/
assign oHC_CP = sr_cp;
wire [15:0] s_hc_data ;
assign s_hc_data = {
sr_hc_data_buffer[0],
sr_hc_data_buffer[1],
sr_hc_data_buffer[2],
sr_hc_data_buffer[3],
sr_hc_data_buffer[4],
sr_hc_data_buffer[5],
sr_hc_data_buffer[6],
sr_hc_data_buffer[7],
sr_hc_data_buffer[8],
sr_hc_data_buffer[9],
sr_hc_data_buffer[10],
sr_hc_data_buffer[11],
sr_hc_data_buffer[12],
sr_hc_data_buffer[13],
sr_hc_data_buffer[14],
sr_hc_data_buffer[15]
};
assign oHC_SI = s_hc_data[sr_shift_counter[4:1]];
endmodule
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -