[笔记].串型DAC TLC5620生成锯齿波、三角波实验,Verilog版本

原理图

image

时序图

image

image

思路

image

源代码

顶层模块

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硬件仿真

image

image

posted @ 2011-04-27 23:33  _安德鲁  阅读(7495)  评论(1编辑  收藏  举报