[笔记].74HC595驱动实验,Veilog版本

接线映射

To,         Location
CLOCK_50,   PIN_23
nRST,       PIN_4
//
SER,        PIN_48
nG,         PIN_47
RCK,        PIN_46
SCK,        PIN_45
nCLR,       PIN_44
//
Q[0],       PIN_114
Q[1],       PIN_116
Q[2],       PIN_118
Q[3],       PIN_128
Q[4],       PIN_134
Q[5],       PIN_137
Q[6],       PIN_139
Q[7],       PIN_142
//
//
VCC,        V3_3DC
GND,        GND

74HC595之内部框图

[笔记].74HC595驱动实验,Veilog版本_第1张图片

74HC595之时序图

[笔记].74HC595驱动实验,Veilog版本_第2张图片

驱动思路

[笔记].74HC595驱动实验,Veilog版本_第3张图片

测试源代码

顶层模块

module _74hc595_test
(
    // 全局时钟及复位信号
    input CLOCK_50,
    input nRST,
    // 74HC595接口
    output wire SER,
    output wire nG,
    output wire RCK,
    output wire SCK,
    output wire nCLR,
    // 将74HC595 QA~QH接至FPGA
    input [7:0] Q
);

function integer log2(input integer n);
    integer i;
    for(i=0; 2**i <=n; i=i+1) log2=i+1;
endfunction

localparam N_500ns=25;
reg [log2(N_500ns):1] cnt_500ns;
always@(posedge CLOCK_50, negedge nRST)
    if(!nRST) cnt_500ns <= 0;
    else if(cnt_500ns < N_500ns-1)
        cnt_500ns <= cnt_500ns + 1'b1;
    else cnt_500ns <= 0;
wire tick_500ns = (N_500ns-1 == cnt_500ns) ? 1 : 0;

reg [3:0] updata_cnt;
reg [7:0] tx_data;
reg _74hc595_enable;
always@(posedge CLOCK_50, negedge nRST)
    if(!nRST) updata_cnt <= 0;
    else if(tick_500ns) begin
        updata_cnt <= updata_cnt + 1'b1; 
        case(updata_cnt)
            0: begin tx_data <= 8'h1; _74hc595_enable = 1; end
            2: begin tx_data <= 8'h2; _74hc595_enable = 1; end
            4: begin tx_data <= 8'h4; _74hc595_enable = 1; end
            6: begin tx_data <= 8'h8; _74hc595_enable = 1; end
            8: begin tx_data <= 8'h10; _74hc595_enable = 1; end
            10: begin tx_data <= 8'h20; _74hc595_enable = 1; end
            12: begin tx_data <= 8'h40; _74hc595_enable = 1; end
            14: begin tx_data <= 8'h80; _74hc595_enable = 1; end
            default : begin tx_data <= 8'h0; _74hc595_enable <= 0; end
        endcase
    end
      

_74hc595_driver _74hc595_driver_inst(
    .CLOCK_50(CLOCK_50),
    .nRST(nRST),
    
    ._74hc595_enable(_74hc595_enable),
    .output_enable(1'b1),
    .tx_data(tx_data),

    .SER(SER),
    .nG(nG),
    .RCK(RCK),
    .SCK(SCK),
    .nCLR(nCLR)
);

endmodule

驱动模块

module _74hc595_driver(
    // 输入时钟及异步复位(上电复位)信号
    input CLOCK_50,
    input nRST,
    // 74HC595控制及数据信号
    input _74hc595_enable,
    input output_enable,
    input [7:0] tx_data,
    // 74HC595接口
    output reg SER,
    output reg nG,
    output reg RCK,
    output reg SCK,
    output reg nCLR
);

function integer log2(input integer n);
    integer i;
    for(i=1'b0; 2**i <=n; i=i+1) log2=i+1'b1;
endfunction

reg [log2(17):1] cnt_20ns;
always@(posedge CLOCK_50, negedge nRST)
    if(!nRST)
        cnt_20ns <= 0;
    else if(_74hc595_enable) begin
        if(cnt_20ns < 16) cnt_20ns <= cnt_20ns + 1'b1;
        else cnt_20ns <= 0;
    end else cnt_20ns <= 0;
    
    
always@(posedge CLOCK_50, negedge nRST)
    if(!nRST) begin
        SER <= 0;
        nG <= 1;
        RCK <= 0;
        SCK <= 0;
        nCLR <= 0; // 低电平复位
    end else begin
        nCLR <= 1; // 解除复位
        
        if(output_enable) nG <= 0;
        else nG <= 1;
        
        if(_74hc595_enable) begin
        
            // 产生SCK信号
            case(cnt_20ns)
                0,2,4,6,8,10,12,14 : SCK <= 0;
                1,3,5,7,9,11,13,15: SCK <= 1;
                16 : SCK <= 0;
                default : ; // 缺省不操作
            endcase
            
            // 产生RCK信号
            case(cnt_20ns)
                16: RCK <= 1;
                default: RCK <= 0;            
            endcase
            
            // 送出串型数据
            case(cnt_20ns)
                0,1 : SER <= tx_data[7];
                2,3 : SER <= tx_data[6];
                4,5 : SER <= tx_data[5];
                6,7 : SER <= tx_data[4];
                8,9 : SER <= tx_data[3];
                10,11 : SER <= tx_data[2];
                12,13 : SER <= tx_data[1];
                14,15 : SER <= tx_data[0];
                default: SER <= 0;
            endcase
        end else begin
            SCK <= 0;
            RCK <= 0;
            SER <= 0;
        end        
    end

endmodule 

SignalTap硬件仿真

[笔记].74HC595驱动实验,Veilog版本_第4张图片

[笔记].74HC595驱动实验,Veilog版本_第5张图片

[笔记].74HC595驱动实验,Veilog版本_第6张图片

你可能感兴趣的:([笔记].74HC595驱动实验,Veilog版本)