一、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仿真