zoukankan      html  css  js  c++  java
  • [笔记].串型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

  • 相关阅读:
    Go语言程序调试
    IDA FLIRT使用
    通过PEB寻找函数地址
    使用IWebBrowser2操控浏览器页面测试(IE)
    虚拟机检测手段
    初步了解PE分析
    CG-CTF simple-machine
    调试器原理初步学习
    简单shellcode编写
    使用ReportViewer的远程模式
  • 原文地址:https://www.cnblogs.com/yuphone/p/2031233.html
Copyright © 2011-2022 走看看