驱动模块
module HC595_Driver(
input clk , // 时钟信号
input rst_n , // 复位信号(低有效)
input [15:0] Data , //
input S_EN , //移位使能,为1则开始输入数据
output reg SH_CP, // 12.5MHZ,上升沿采样
output reg ST_CP , // 为1则发送并行数据
output reg DS // 数据输出
);
reg [15:0] r_data;
always @ (posedge clk)begin
if(S_EN)
r_data <= Data;
end
reg [7:0] divider_cnt;
parameter CNT_MAX = 2;
always @ (posedge clk or negedge rst_n) begin
if (!rst_n)
divider_cnt <= 1'b0;
else if(divider_cnt == CNT_MAX - 1)
divider_cnt <= 1'b0;
else
divider_cnt <= divider_cnt + 1'b1;
end
wire src_plus = (divider_cnt == CNT_MAX - 1);
reg [5:0] SHCP_EDGE_CNT;
always @(posedge clk or negedge rst_n) begin
if (!rst_n)
SHCP_EDGE_CNT <= 0;
else if(src_plus)begin
if(SHCP_EDGE_CNT == 6'd32)
SHCP_EDGE_CNT <= 0;
else
SHCP_EDGE_CNT <= SHCP_EDGE_CNT + 1;
end
else
SHCP_EDGE_CNT <= SHCP_EDGE_CNT;
end
always @(posedge clk or negedge rst_n) begin
if (!rst_n)begin
SH_CP <= 0;
ST_CP <= 0;
DS <= 0;
end
else begin
case(SHCP_EDGE_CNT)
0: begin SH_CP <= 0; ST_CP <= 0; DS <= r_data[15]; end
1: begin SH_CP <= 1; ST_CP <= 0; end
2: begin SH_CP <= 0; ST_CP <= 0; DS <= r_data[14]; end
3: begin SH_CP <= 1; ST_CP <= 0; end
4: begin SH_CP <= 0; ST_CP <= 0; DS <= r_data[13]; end
5: begin SH_CP <= 1; ST_CP <= 0; end
6: begin SH_CP <= 0; ST_CP <= 0; DS <= r_data[12]; end
7: begin SH_CP <= 1; ST_CP <= 0; end
8: begin SH_CP <= 0; ST_CP <= 0; DS <= r_data[11]; end
9: begin SH_CP <= 1; ST_CP <= 0; end
10: begin SH_CP <= 0; ST_CP <= 0; DS <= r_data[10]; end
11: begin SH_CP <= 1; ST_CP <= 0; end
12: begin SH_CP <= 0; ST_CP <= 0; DS <= r_data[9]; end
13: begin SH_CP <= 1; ST_CP <= 0; end
14: begin SH_CP <= 0; ST_CP <= 0; DS <= r_data[8]; end
15: begin SH_CP <= 1; ST_CP <= 0; end
16: begin SH_CP <= 0; ST_CP <= 0; DS <= r_data[7]; end
17: begin SH_CP <= 1; ST_CP <= 0; end
18: begin SH_CP <= 0; ST_CP <= 0; DS <= r_data[6]; end
19: begin SH_CP <= 1; ST_CP <= 0; end
20: begin SH_CP <= 0; ST_CP <= 0; DS <= r_data[5]; end
21: begin SH_CP <= 1; ST_CP <= 0; end
22: begin SH_CP <= 0; ST_CP <= 0; DS <= r_data[4]; end
23: begin SH_CP <= 1; ST_CP <= 0; end
24: begin SH_CP <= 0; ST_CP <= 0; DS <= r_data[3]; end
25: begin SH_CP <= 1; ST_CP <= 0; end
26: begin SH_CP <= 0; ST_CP <= 0; DS <= r_data[2]; end
27: begin SH_CP <= 1; ST_CP <= 0; end
28: begin SH_CP <= 0; ST_CP <= 0; DS <= r_data[1]; end
29: begin SH_CP <= 1; ST_CP <= 0; end
30: begin SH_CP <= 0; ST_CP <= 0; DS <= r_data[0]; end
31: begin SH_CP <= 1; ST_CP <= 0; end
32: ST_CP <= 1;
default: begin
SH_CP <= 0;
ST_CP <= 0;
DS <= 0;
end
endcase
end
end
endmodule
测试模块:
`timescale 1ns/1ps
`define clock_period 20
module HC595_tb;
reg clk ; // 时钟信号
reg rst_n ; // 复位信号(低有效)
reg [15:0] Data ; //
reg S_EN ; //移位使能
wire SH_CP; // 12.5MHZ
wire ST_CP ; //
wire DS; //
HC595_Driver HC(
.clk(clk), // 时钟信号
.rst_n(rst_n), // 复位信号(低有效)
.Data(Data) , //
.S_EN(S_EN) , //移位使能
.SH_CP(SH_CP) , // 12.5MHZ
.ST_CP(ST_CP) , //
.DS(DS) //
);
initial clk = 1;
always #(`clock_period / 2) clk = ~clk;
initial begin
rst_n = 1'b0;
Data = 16'h1234;
S_EN = 0;
#201;
S_EN = 1;
rst_n = 1'b1;
#2000;
S_EN = 0;
#200;
Data = 16'h8765;
S_EN = 1;
#2000;
S_EN = 0;
#2000;
$stop;
end
endmodule