一、74HC595简介
74HC595 是一个 8 位串行输入、并行输出的位移缓存器。其内部具有 8 位移位寄存器和一个存储器,具有三态输出功能。简单来说是一个可以将串行数据转换为并行数据输出的芯片,可以节约FPGA引脚资源。
二、芯片主要引脚介绍
1、SHCP:移位寄存器时钟输入,在此时钟的上升沿将数据移入芯片;
2、STCP:存储寄存器时钟输入, 每将预定数据长度移入芯片后,生成一个高电平时钟信号;
3、/OE:输出使能输入,一般是低电平有效(看电路设计);
4、DS:串行数据输入;
上面这四个信号就是我们要用Verilog HDL生成的信号,这些信号提供给74HC595芯片,驱动74HC595正常工作;
三、时序设计
在本设计中,使用了两片74HC595芯片级联,串行输入12bit数据(DS),SH_CP由系统时钟信号分频得到,ST_CP信号的作用是在DS信号传输12bit的数据之后拉高,对传入芯片的数据进行锁存,OE一直保持低电平即可,在本设计中,由于板卡问题,设计为高电平。
三、源码

1 // ********************************************************************************* 2 // Project Name : HC595_driver 3 // Email : 4 // Create Time : 2020/12/04 21:20 5 // Module Name : 74HC595_driver 6 // editor : Qing 7 // Version : Rev1.0.0 8 // ********************************************************************************* 9 10 module HC595_driver( 11 input sclk , 12 input s_rst_n , 13 14 input [7:0] seg , 15 input [3:0] sel , 16 17 output reg sh_cp , 18 output reg st_cp , 19 output reg ds , 20 output oe 21 ); 22 23 //========================================================================\ 24 // =========== Define Parameter and Internal signals =========== 25 //========================================================================/ 26 27 reg [2:0] cnt0 = 3'd0 ; 28 reg [3:0] lsm_cnt = 4'd0 ; 29 30 wire [11:0] data ; 31 32 33 //============================================================================= 34 //**************************** Main Code ******************************* 35 //============================================================================= 36 37 always @(posedge sclk) begin 38 if(!s_rst_n) 39 cnt0 <= 3'd0; 40 else if(cnt0 == 3) 41 cnt0 <= 3'd0; 42 else 43 cnt0 <= cnt0 + 1'b1; 44 end 45 46 always @(posedge sclk) begin 47 if(!s_rst_n) 48 lsm_cnt <= 4'd0; 49 else if((lsm_cnt == 11) && (cnt0 == 3)) 50 lsm_cnt <= 4'd0; 51 else if(cnt0 == 3) 52 lsm_cnt <= lsm_cnt + 1'b1; 53 else 54 lsm_cnt <= lsm_cnt; 55 end 56 57 always @(posedge sclk) begin // 移位时钟 58 if(!s_rst_n) 59 sh_cp <= 1'b0; 60 else if(cnt0 >= 4'd2) 61 sh_cp <= 1'b1; 62 else 63 sh_cp <= 1'b0; 64 end 65 66 always @(posedge sclk) begin 67 if(!s_rst_n) 68 st_cp <= 1'b0; 69 else if((lsm_cnt == 4'd11) && (cnt0 == 3)) 70 st_cp <= 1'b1; 71 else 72 st_cp <= 1'b0; 73 end 74 75 assign data = {seg[0],seg[1],seg[2],seg[3],seg[4],seg[5],seg[6],seg[7],sel}; 76 77 always @ (posedge sclk) begin 78 if(s_rst_n == 1'b0) 79 ds <= 1'b0; 80 else if(cnt0 == 3'd0) 81 ds <= data[lsm_cnt]; 82 else 83 ds <= ds; 84 85 end 86 87 assign oe = 1'b1; 88 89 endmodule
testbench:

1 `timescale 1ns/1ps 2 module HC595_driver_tb; 3 reg sclk ; 4 reg s_rst_n ; 5 6 reg [7:0] seg ; 7 reg [3:0] sel ; 8 9 wire sh_cp ; 10 wire st_cp ; 11 wire ds ; 12 13 HC595_driver HC595_driver_inst( 14 .sclk ( sclk ), 15 .s_rst_n ( s_rst_n ), 16 .seg ( seg ), 17 .sel ( sel ), 18 .sh_cp ( sh_cp ), 19 .st_cp ( st_cp ), 20 .ds ( ds ) 21 ); 22 23 initial 24 sclk = 1'b0; 25 always #10 sclk = ~sclk; 26 27 initial 28 begin 29 #1; 30 s_rst_n = 1'b0; 31 seg = 8'd0; 32 sel = 4'd0; 33 #21; 34 35 s_rst_n = 1'b1; 36 #20; 37 seg = 8'b1010_1010; 38 sel = 4'b1111; 39 end 40 41 endmodule
四、Modelsim仿真