原理图
时序图
思路
源代码
顶层模块
module tlc5620_test(
input CLOCK_50, // 板载50MHz时钟
input RST_N,
//
output ADC549_CLK,
output ADC549_CS_N,
input ADC549_DATA,
//
output DAC5620_CLK,
output DAC5620_DATA,
output DAC5620_LOAD,
//
output [7:0] SEG7_SEG, // 七段数码管 段脚
output [7:0] SEG7_DIG // 七段数码管 位脚
);
function integer log2(input integer n);
integer i;
for(i=0; 2**i <=n; i=i+1) log2=i+1;
endfunction
/**************************************
* 生成20ms的tick时钟
**************************************/
reg [log2(1_1000_1000):1] cnt_20ms;
always@(posedge CLOCK_50, negedge RST_N)
if(!RST_N) cnt_20ms <= 0;
else begin
if(cnt_20ms < 999_999)
cnt_20ms <= cnt_20ms + 1'b1;
else cnt_20ms <= 0;
end
wire tick_20ms = (cnt_20ms == 999_999) ? 1 : 0;
/**************************************
* 锯齿波;接LED
**************************************/
reg [7:0] da0_data;
always@(posedge CLOCK_50, negedge RST_N)
if(!RST_N) da0_data <= 0;
else if(tick_20ms) begin
if(da0_data < 255)
da0_data <= da0_data + 1'b1;
else da0_data <= 0;
end
/**************************************
* 三角波;接LED
**************************************/
reg da1_highest_level_flag;
reg [7:0] da1_data;
always@(posedge CLOCK_50, negedge RST_N)
if(!RST_N) begin
da1_data <= 0;
da1_highest_level_flag <= 0;
end else if(tick_20ms) begin
if(da1_data == 255-1)
da1_highest_level_flag <= 1;
else if(da1_data == 0+1)
da1_highest_level_flag <= 0;
if(da1_highest_level_flag)
da1_data <= da1_data - 1'b1;
else
da1_data <= da1_data + 1'b1;
end
wire [7:0] da2_data = 0;
wire [7:0] da3_data = 0;
tlc5620_driver tlc5620_driver_inst
(
.CLOCK_50(CLOCK_50),
.RST_N(RST_N),
//
.da_enable(1'b1),
.da_range(0), // 0, 1倍参考电压; 1, 2倍参考电压
.da0_data(da0_data), // 0~255
.da1_data(da1_data), // 0~255
.da2_data(da2_data), // 0~255
.da3_data(da3_data), // 0~255
//
.SCK(DAC5620_CLK),
.SDI(DAC5620_DATA),
.LOAD(DAC5620_LOAD)
);
endmodule
tlc5620驱动
module tlc5620_driver
(
input CLOCK_50,
input RST_N,
//
input da_enable,
input da_range, // 0, 1倍参考电压; 1, 2倍参考电压
input [7:0] da0_data, // 0~255
input [7:0] da1_data, // 0~255
input [7:0] da2_data, // 0~255
input [7:0] da3_data, // 0~255
//
output reg SCK,
output reg SDI,
output reg LOAD
);
function integer log2(input integer n);
integer i;
for(i=0; 2**i <=n; i=i+1) log2=i+1;
endfunction
/**************************************
* 生成140ns的tick时钟
**************************************/
reg [log2(7):1]cnt_140ns;
always@(posedge CLOCK_50, negedge RST_N)
if(!RST_N) cnt_140ns <= 0;
else begin
if(cnt_140ns < 6)
cnt_140ns <= cnt_140ns + 1'b1;
else cnt_140ns <= 0;
end
wire tick_140ns = (cnt_140ns == 6) ? 1 : 0;
/**************************************
* 根据tick时钟生成da基准计数器
**************************************/
reg [log2(48):1] da_ref_cnt; // [0,47]
always@(posedge CLOCK_50, negedge RST_N)
if(!RST_N) da_ref_cnt <= 0;
else begin
if(!da_enable) da_ref_cnt <= 0;
else begin
if(tick_140ns) begin
if(da_ref_cnt < 47)
da_ref_cnt <= da_ref_cnt + 1'b1;
else da_ref_cnt <= 0;
end
end
end
wire tick_6720ns = (da_ref_cnt == 47) ? 1 : 0;
reg [1:0] da_sel_cnt;
always@(posedge CLOCK_50, negedge RST_N)
if(!RST_N) da_sel_cnt <= 2'b0;
else if (tick_6720ns) begin
if(da_sel_cnt < 3)
da_sel_cnt <= da_sel_cnt + 1'b1;
else da_sel_cnt <= 2'b0;
end
/**************************************
* 根据基准计数器生成串行信号
**************************************/
reg [7:0] da_data;
always@(posedge CLOCK_50, negedge RST_N)
if(!RST_N) da_data <= 8'b0;
else begin
case(da_sel_cnt)
2'b00: da_data <= da0_data;
2'b01: da_data <= da1_data;
2'b10: da_data <= da2_data;
2'b11: da_data <= da3_data;
endcase
end
always@(posedge CLOCK_50, negedge RST_N)
if(!RST_N) begin
SCK <= 0;
SDI <= 0;
LOAD <= 0;
end
else begin
if(tick_140ns) begin
// 生成SCK信号
case(da_ref_cnt)
2,6,10,14,18,22,26,30,34,38,42: SCK <= 1;
4,8,12,16,20,24,28,32,36,40,44: SCK <= 0;
default : ; // 缺省不操作
endcase
// 生成LOAD信号
case(da_ref_cnt)
0: LOAD <= 1;
46: LOAD <= 0;
default : ; // 缺省不操作
endcase
// 送入串型数据
case(da_ref_cnt)
3,4: SDI <= da_sel_cnt[1];
7,8: SDI <= da_sel_cnt[0];
11,12: SDI <= da_range;
15,16: SDI <= da_data[7];
19,20: SDI <= da_data[6];
23,24: SDI <= da_data[5];
27,28: SDI <= da_data[4];
31,32: SDI <= da_data[3];
35,36: SDI <= da_data[2];
39,40: SDI <= da_data[1];
43,44: SDI <= da_data[0];
default : SDI <= 1'b1;
endcase
end
end
endmodule
Signaltap硬件仿真