|
![](static/image/common/ico_lz.png)
楼主 |
发表于 2011-5-2 10:10:05
|
显示全部楼层
顶层模块
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
74HC595驱动模块
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 |
|