74HC595驱动LED--FPGA设计技巧与案例开发详解
1赞
发表于 6/11/2016 10:54:18 AM
阅读(3505)
module led_74595_driver
/*-------------------------------------------------------------- Author : zhiqiuyiye Email Address : liangwenhao0603@163.com Filename : led_74595_driver.v Data : 2016-06-11 Description : The driver of led via serial ic 74hc595. Data By Version Change Description =========================================================================== 16/6/11 zhiqiuyiye 1.0 Original =========================================================================== */ `timescale 1ns/1ns module led_74595_driver ( input clk, input rst_n, output led595_dout, output led595_clk, output led595_latch, input [7:0] led_data ); //----------------------------- //update led display when led_data is update reg [7:0] led_data_r = 8'h00; reg updata_flag; always@(posedge clk or negedge rst_n) begin if(!rst_n) begin led_data_r <= 0; updata_flag <= 1; end else begin led_data_r <= led_data; updata_flag <= (led_data_r != led_data) ? 1'b1 : 1'b0; end end //----------------------------- //74hc595 clk delay for enough setup time localparam DELAY_CNT = 3'D7; reg [2:0] delay_cnt; reg shift_state; //led scan state always@(posedge clk or negedge rst_n) begin if(!rst_n) delay_cnt <= 0; else if(shift_state == 1'b1) delay_cnt <= (delay_cnt < DELAY_CNT) ? delay_cnt+1'b1:3'd0; else delay_cnt <= 0; end wire shift_flag = (delay_cnt == DELAY_CNT)?1'b1:1'b0; wire shift_clk = (delay_cnt >DELAY_CNT/2)?1'b1:1'b0; //----------------------------- //----------------------------- //74hc595 shift data output state reg [3:0] led_cnt; always@(posedge clk or negedge rst_n) begin if(!rst_n) begin led_cnt <= 0; shift_state <= 0; end else begin case(shift_state) 0: begin led_cnt <= 0; if(updata_flag) shift_state <= 1; else shift_state <= 0; end 1: begin if(shift_flag) begin if(delay_cnt < 4'd8) begin led_cnt <= led_cnt + 1'b1; shift_state <= 1'd1; end else begin led_cnt <= 0; shift_state <= 0; end end else begin led_cnt <= led_cnt; shift_state <= shift_state; end end endcase end end //----------------------------- assign led595_dout = (shift_state == 1'b1 && led_cnt < 4'd8) ? led_data[3'd7 - led_cnt] : 1'b0; assign led595_clk = (shift_state == 1'b1 && led_cnt < 4'd8) ? shift_clk : 1'b0; assign led595_latch = (shift_state == 1'b1 && led_cnt == 4'd8) ? 1'b1 : 1'b0; //----------------------------- endmodule
module LED_74595_Driver_TB;
`timescale 1ns/1ns module LED_74595_Driver_TB; //----------------------------------- //clock generate module reg clk; reg rst_n; localparam PERIOD = 20; initial begin clk = 0; forever #(PERIOD/2) clk = ~clk; end task task_reset; begin rst_n = 0; repeat(2)@(negedge clk); rst_n = 1; end endtask //----------------------------------- //the driver of 74hc595 reg [7:0] led_data; led_74595_driver u_led_74595_driver ( //global clock .clk (clk), .rst_n (rst_n), //74hc595 interface .led595_dout (led595_dout), //74hc595 serial data input .led595_clk (led595_clk), //74hc595 shift clock (rising edge) .led595_latch (led595_latch), //74hc595 latch clock (risign edge) //user interface .led_data (led_data) //led data input ); //----------------------------------- //--------------------------------------- //system initialization task task_sysinit; begin led_data = 0; end endtask //---------------------------------------- //testbench of the RTL initial begin task_sysinit; task_reset; #2000; led_data = 8'hA2; #2000; led_data = 8'hCB; end endmodule




