挂在Avalon总线上的AD7656芯片驱动verilog程序实现

2024-04-20 21:44

本文主要是介绍挂在Avalon总线上的AD7656芯片驱动verilog程序实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

        AD7656是一款16位同步采样双极ADC转换器,本文中用状态机方式实现了AD7656芯片的Verilog驱动,并且将驱动直接挂在了altera芯片的Avalon总线上,使其altera芯片能够通过总线直接控制ADC芯片,其代码如下:

module AD7656_drive(clk,rst_n,slave_rd_n,slave_cs_n,slave_address,slave_rddata,ad_cs_n,sclking,sclk,CONVST,DOUTA,DOUTB); 
//-------------------------------------------- 
    input clk;
    input rst_n;
     input sclking; 
     wire  sclk;    
//-----------------------------------------
//Avalon--MM interface
    input  slave_rd_n;
    input  slave_cs_n;  
    output[31:0] slave_rddata;
    input [1:0]slave_address;
    
    reg  [31:0] slave_rddata;
//------------------------------------------
//AD7656 interface
    reg[31:0]data_in_A/* synthesis noprune */;
    reg[31:0]data_in_B/* synthesis noprune */;
    
    output reg   CONVST;///
    output       sclk; ///
    output reg   ad_cs_n;
    input        DOUTA;//
    input        DOUTB;
//------------------------------------------------    
    
     reg [5:0] bitnum; ///
     
     reg [3:0]  delay_200ns; //
     reg [8:0]  delay_4_us;

     reg [2:0] cstate;//
     reg [2:0] nstate;//
     parameter empty=0,start=1,delay_4us=2,data_transfer=3,stop=4,transfer_interval=5;
//----------------------------------------------------------------------------------------------------
assign  sclk=sclking;    ///the deg is 0 compared with the primitive input clk
//-----------------------------------------------------------------------------------------------------
//reset  module-----we apply the asynchronous reset and release the reset  signal synchronously
reg rst_nr1,rst_nr2;
always @(posedge clk or negedge rst_n)begin
    if(!rst_n)   rst_nr1<=0;
    else              rst_nr1<=1;
end

always @(posedge clk  or negedge rst_n)begin
    if(!rst_n)       rst_nr2<=0;
    else                  rst_nr2<=rst_nr1;
end
//-------------------------------------------------------------------------------------------------------
//pulse-generation technique---refer to Recommend Design Practices (9-7) in Quartus II Help for details 
reg pulse1,pulse2;
wire sclk_neg;  //check the  negedge edge of sclk
always @(posedge clk or  negedge  rst_nr2)begin
    if(!rst_nr2)begin
        pulse1<=1;
        pulse2<=1;    
    end
    else  begin
        pulse1<=sclk;
        pulse2<=pulse1;                
    end
end

assign  sclk_neg=(~pulse1)&&pulse2;
//------------------------------------------------------------------------------------------------------------
reg pulse3,pulse4;
wire sclk_pos;  //check the  posedge edge of sclk
always @(posedge clk or  negedge  rst_nr2)begin
    if(!rst_nr2)begin
        pulse3<=0;
        pulse4<=0;    
    end
    else  begin
        pulse3<=sclk;
        pulse4<=pulse3;                
    end
end
assign  sclk_pos=pulse3&&(~pulse4);
//---------------------------------------------------------------------------------------------------------
//assign ad_cs_n=~(nstate==data_transfer|nstate==start);
//----------------------------------------------------------------------------------------------------
always @(posedge clk or negedge rst_nr2)
begin
    if(!rst_nr2)                 bitnum<=6'd0; 
    else if(nstate==start)    bitnum<=6'd31;
    else if((nstate==data_transfer)&& sclk_neg)   bitnum<=bitnum-1;
    else if(nstate==stop)    bitnum<=0;
end
//-----------------------------------------------------------------------------------------------------
//delay  module-----------delay  4us to save conversion's time
always@(posedge clk or negedge rst_nr2)//develop  latch??
    if(!rst_nr2)                                      delay_4_us<=0;
    else if((nstate==delay_4us)&&sclk_pos)  delay_4_us<= delay_4_us+1'd1;//why nstate??
    else if(nstate==empty)                        delay_4_us<=0;    
   wire flag_4us=(delay_4_us==4);//the mark of counter's arrival 
//---------------------------------------------------------------------------------------------------
//delay  module-----------delay  200ns to indicate transfer interval
always@(posedge clk or negedge rst_nr2)//develop  latch
    if(!rst_nr2)                                      delay_200ns<=0;
    else if((nstate==transfer_interval)&&sclk_neg)    delay_200ns<= delay_200ns+1'd1;
    else if(nstate==empty)                        delay_200ns<=0;    
   wire flag_200ns=(delay_200ns==1); //the mark of counter's arrival     
//----------------------------------------------------------------------------------------------------
always @(posedge clk or negedge rst_nr2)    
begin
     if(!rst_nr2) cstate<=empty;
     else begin
            cstate <= nstate;
         end
end
//----------------------------------------------------------------------------------------------------
always @(cstate or sclk_neg or bitnum or flag_4us or flag_200ns)  //this is a combinational logic
        begin
                case (cstate)
                empty:  nstate <= delay_4us;                                 
                delay_4us: begin   ///
                    if (flag_4us&&sclk_neg)
                        nstate = start;                                                 
                    else
                        nstate = delay_4us;
                end
                start: begin
                    if (sclk_neg)
                    begin
                        nstate = data_transfer;
                    end
                    else
                        nstate = start;
                end
                data_transfer: begin
                    if (sclk_neg&&(bitnum==6'd0))
                        nstate = stop;
                    else
                        nstate = data_transfer;
                end
                stop: begin   //question 
                    if (sclk_neg)
                        nstate = transfer_interval;
                    else
                        nstate = stop;
                end
                transfer_interval: begin //cun zai wen  ti 
                    if (flag_200ns&&sclk_neg)
                        nstate = empty;
                    else
                        nstate = transfer_interval;
                end
               default:  begin 
                          nstate  = 'hx; 
                     end        
            endcase
            end
//---------------------------------------------------------------------------------------------------
//3rd always block,the sequential FSM output
always @(posedge clk or negedge rst_nr2)    
     if(!rst_nr2) begin
             CONVST<=0;
                ad_cs_n<=1; 
                end
     else begin
                begin
                CONVST<=0;
                ad_cs_n<=1; 
                end
            case(cstate)
            empty:          begin 
                        CONVST<=0;
                        ad_cs_n<=1; 
                            end
            delay_4us:  begin 
                        CONVST<=1;
                            ad_cs_n<=1; 
                            end
            start:          begin 
                            CONVST<=1; 
                            ad_cs_n<=0; 
                            end
            data_transfer:begin 
                            if(bitnum==16&&(sclk ==1))
                              begin
                                CONVST<=1;
                                ad_cs_n<=1; 
                              end
                            else
                              begin
                               CONVST<=1;
                                ad_cs_n<=0; 
                              end
                            end
            stop:            begin 
                            CONVST<=1;
                            ad_cs_n<=1; 
                            end
            transfer_interval:begin
                        CONVST<=0;
                            ad_cs_n<=1; 
                            end
         endcase
         end
//-------------------------------------------------------------------------------------------------------
//Avalon--MM interface
wire slave_rdcs_n=slave_rd_n|slave_cs_n;

always@(posedge clk or negedge rst_nr2)
begin 
        if(!rst_nr2)     slave_rddata[31:0]<=0;
        else if(slave_rdcs_n && slave_address==2'h0)  
        slave_rddata[31:0]<=data_in_A;
        else if(slave_rdcs_n && slave_address==2'h1)  
        slave_rddata[31:0]<=data_in_B;
        else
        slave_rddata[31:0]<=slave_rddata[31:0];        
end
//----------------------------------------------------------------------------------------------------
always @(posedge clk or negedge rst_nr2)
    if(!rst_nr2)begin            
        data_in_A[31:0]<=0;
        data_in_B[31:0]<=0;
        end
    else if((nstate==data_transfer)&&sclk_neg)begin   
       data_in_A[bitnum]<=DOUTA; 
        data_in_B[bitnum]<=DOUTB;
        end
        
//------------------------------------------------------------------------------------------------------
endmodule 

这篇关于挂在Avalon总线上的AD7656芯片驱动verilog程序实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/921398

相关文章

Linux_kernel驱动开发11

一、改回nfs方式挂载根文件系统         在产品将要上线之前,需要制作不同类型格式的根文件系统         在产品研发阶段,我们还是需要使用nfs的方式挂载根文件系统         优点:可以直接在上位机中修改文件系统内容,延长EMMC的寿命         【1】重启上位机nfs服务         sudo service nfs-kernel-server resta

驱动(RK3588S)第七课时:单节点设备树

目录 需求一、设备树的概念1、设备树的后缀名:2、设备树的语法格式3、设备树的属性(重要)4、设备树格式举例 二、设备树所用函数1、如何在内核层种获取设备树节点:2、从设备树上获取 gpio 口的属性3、获取节点上的属性只针对于字符串属性的4、函数读取 np 结点中的 propname 属性的值,并将读取到的 u32 类型的值保存在 out_value 指向的内存中,函数的返回值表示读取到的

驱动安装注册表指令

HKCR: HKEY_CLASSES_ROOT HKCU: HKEY_CURRENT_USER HKLM: HKEY_LOCAL_MACHINE HKU: HEKY_USER HER: 相对根键

UMDF驱动安装

VS2013 + WDF8.1,UMDF驱动选择User Mode Driver,不要选User Mode Driver 2.0,否则Win7安装有问题,如图 另外,在驱动安装时不要忘记WUDFUpdate_<主版本号><次版本号>.dll文件,具体文件名在INF中查找。此文件可在WDF的安装目录中找到。注意:在WDF的安装目录中会有3个WUDFUpdate_xxx.dll文件,x86,x6

在亚马逊云科技上利用Graviton4代芯片构建高性能Java应用(上篇)

简介 在AI迅猛发展的时代,芯片算力对于模型性能起到了至关重要的作用。一款能够同时兼具高性能和低成本的芯片,能够帮助开发者快速构建性能稳定的生成式AI应用,同时降低开发成本。今天小李哥将介绍亚马逊推出的4代高性能计算处理器Gravition,带大家了解如何利用Graviton芯片为Java生成式AI应用提高性能、优化成本。 本篇文章将介绍如何在云平台上创建Graviton芯片服务器,并在Gra

2024年AI芯片峰会——边缘端侧AI芯片专场

概述 正文 存算一体,解锁大模型的边端侧潜力——信晓旭 当下AI芯片的亟需解决的问题 解决内存墙问题的路径 产品 面向大模型的国产工艺边缘AI芯片创新与展望——李爱军 端侧AI应用“芯”机遇NPU加速终端算力升级——杨磊 边缘端的大模型参数量基本小于100B AI OS:AI接口直接调用AI模型完成任务 具身智能的大脑芯片 大模

电脑驱动分类

电脑驱动程序(驱动程序)是操作系统与硬件设备之间的桥梁,用于使操作系统能够识别并与硬件设备进行通信。以下是常见的驱动分类: 1. 设备驱动程序 显示驱动程序:控制显卡和显示器的显示功能,负责图形渲染和屏幕显示。 示例:NVIDIA、AMD 显示驱动程序。打印机驱动程序:允许操作系统与打印机通信,控制打印任务。 示例:HP、Canon 打印机驱动程序。声卡驱动程序:管理音频输入和输出,与声卡硬件

电子电气架构---私有总线通信和诊断规则

电子电气架构—私有总线通信和诊断规则 我是穿拖鞋的汉子,魔都中坚持长期主义的汽车电子工程师。 老规矩,分享一段喜欢的文字,避免自己成为高知识低文化的工程师: 屏蔽力是信息过载时代一个人的特殊竞争力,任何消耗你的人和事,多看一眼都是你的不对。非必要不费力证明自己,无利益不试图说服别人,是精神上的节能减排。 无人问津也好,技不如人也罢,你都要试着安静下来,去做自己该做的事.而不是让内心的烦躁、

数字电路专题:verilog 阻塞赋值和非阻塞赋值

verilog 阻塞赋值 和 非阻塞赋值 “=”阻塞赋值, ”<=”非阻塞赋值。阻塞赋值为执行完一条赋值语句,再执行下一条,可理解为顺序执行,而且赋值是立即执行; 非阻塞赋值可理解为并行执行,不考虑顺序,在 always 块语句执行完成后,才进行赋值。 如下面的阻塞赋值: //代码如下:module top(din,a,b,c,clk);input din;input clk;out

麒麟系统安装GPU驱动

1.nvidia 1.1显卡驱动 本机显卡型号:nvidia rtx 3090 1.1.1下载驱动 打开 https://www.nvidia.cn/geforce/drivers/ 也可以直接使用下面这个地址下载 https://www.nvidia.com/download/driverResults.aspx/205464/en-us/ 1.1.3安装驱动 右击,