挂在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

相关文章

SpringCloud整合MQ实现消息总线服务方式

《SpringCloud整合MQ实现消息总线服务方式》:本文主要介绍SpringCloud整合MQ实现消息总线服务方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、背景介绍二、方案实践三、升级版总结一、背景介绍每当修改配置文件内容,如果需要客户端也同步更新,

如何在Ubuntu上安装NVIDIA显卡驱动? Ubuntu安装英伟达显卡驱动教程

《如何在Ubuntu上安装NVIDIA显卡驱动?Ubuntu安装英伟达显卡驱动教程》Windows系统不同,Linux系统通常不会自动安装专有显卡驱动,今天我们就来看看Ubuntu系统安装英伟达显卡... 对于使用NVIDIA显卡的Ubuntu用户来说,正确安装显卡驱动是获得最佳图形性能的关键。与Windo

嵌入式Linux之使用设备树驱动GPIO的实现方式

《嵌入式Linux之使用设备树驱动GPIO的实现方式》:本文主要介绍嵌入式Linux之使用设备树驱动GPIO的实现方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐... 目录一、设备树配置1.1 添加 pinctrl 节点1.2 添加 LED 设备节点二、编写驱动程序2.1

嵌入式Linux驱动中的异步通知机制详解

《嵌入式Linux驱动中的异步通知机制详解》:本文主要介绍嵌入式Linux驱动中的异步通知机制,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言一、异步通知的核心概念1. 什么是异步通知2. 异步通知的关键组件二、异步通知的实现原理三、代码示例分析1. 设备结构

usb接口驱动异常问题常用解决方案

《usb接口驱动异常问题常用解决方案》当遇到USB接口驱动异常时,可以通过多种方法来解决,其中主要就包括重装USB控制器、禁用USB选择性暂停设置、更新或安装新的主板驱动等... usb接口驱动异常怎么办,USB接口驱动异常是常见问题,通常由驱动损坏、系统更新冲突、硬件故障或电源管理设置导致。以下是常用解决

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