FPGA的ADC控制器

2019-03-25 08:27发布

这两个写了个AD1308的控制器程序,发现控制信号都正常但AD转换后低8位没有输出信号,程序如下
module ad1308(rst_n,clk_ADI,clk_100M,ADI1,ADI2,
clk_ADO,EOC_L,EOLC_L,CHSHDN_L,SHDN,convst,CS_L,RD_L,WR_L,over_flag,ADO,start_flag1,e,el,o,led0,led1);
input rst_n,clk_100M,clk_ADI,EOC_L,EOLC_L;
output clk_ADO,CHSHDN_L,SHDN,convst,CS_L,RD_L,WR_L,over_flag,start_flag1,e,el,led0,led1,o;
output[11:0] ADO;
//output[7:0] ADI1S;
input [3:0] ADI2;
inout [7:0] ADI1;
reg SHDN,CHSHDN_L,convst,CS_L,RD_L,WR_L,write_over,start_flag1,start_flag2,over_flag,led0,led1;
wire clk_ADI;
//wire start_flag0;
wire[11:0] ADO;
wire e;
wire o;
wire el;
//wire[7:0]  ADI0;
reg [7:0]  counter;
reg [15:0] counter1;
reg [7:0]  current_state;
reg [7:0]  next_state;
reg [11:0] ADbuf;
reg [7:0]  ADI1S;
reg [2:0]  counter_channel;
assign ADO = ADbuf;
assign ADI1 = (WR_L)?8'bzzzz_zzzz:ADI1S;
//assign ADI1 = ADI0;
assign clk_ADO = clk_ADI;//ADC clock
assign e = EOC_L;
assign el = EOLC_L;
assign o = over_flag;

//sampling rate counter 20kHz
always @(posedge clk_100M or negedge rst_n )
      if(!rst_n)begin
        counter1 <= 0;
        start_flag1 <=0;
        end
      else if(counter1 <= 4999)
             begin
             counter1 <= counter1+1;
               if((counter1>=2499) && (counter1<= 2503))
                 start_flag1 <=1;
               else
                 start_flag1 <=0;
             end
           else
             counter1 <= 0;

parameter idle     = 8'b0000_0001,
          write    = 8'b0000_0010,
          start    = 8'b0000_0100,
          acq      = 8'b0000_1000,
          read     = 8'b0001_0000,
          over     = 8'b0010_0000;

// state transfer
always @ (posedge clk_100M or negedge rst_n)//异步复位
      begin
      if(!rst_n)
        current_state <= idle;
      else
        current_state <= next_state;//注意,使用的是非阻塞赋值
      end

// transfer condition
always @ (* )
      begin
        case(current_state)
        idle:
          next_state = write;
        write:
          if (write_over)
            next_state = start;
          else
            next_state = write;
        start:   
          if (start_flag1)
            next_state = acq;
          else
            next_state = start;
        acq:
           if (start_flag2)
             next_state = read;   
           else
             next_state = acq;
        read:
           if (!counter_channel)
             next_state = over;
           else
             next_state = read;
        over:
          next_state = idle;
        default:
          next_state = idle;   
        endcase  
      end

//output
always @ (posedge clk_100M or negedge rst_n)//异步复位
      begin
        if(!rst_n)
          begin
          //counter <= counter+1;
          SHDN <= 0;
          CHSHDN_L <= 0;
          convst <= 1;
          RD_L <= 1;
          WR_L <= 1;
          CS_L <= 1;
          counter <= 0;
          counter_channel <= 1;
          write_over <= 0;
          start_flag2 <=0;
          led0<=0;
          led1<=0;
          end
        else
          begin
            case(next_state)
            idle:
              begin

              SHDN <= 0;
              CHSHDN_L <= 0;
              convst <= 1;
              RD_L <= 1;
              WR_L <= 1;
              CS_L <= 1;
              counter <= 0;
              counter_channel <= 1;
              write_over <= 0;
              start_flag2 <=0;

              end      
            write:
              begin
              if(counter <= 'd6)
                 begin
                 ///ok led0<=1;
                 convst <= 1;
                 WR_L <= 0;
                 RD_L <= 1;
                 CS_L <= 0;
                 write_over <= 0;
                 ADI1S <= 8'b0001_0000;
                 counter_channel <= 1;
                 counter <=  counter+1;
                 end  
              else
                begin
                WR_L <= 1;
                CS_L <= 1;
                convst <= 1;
                write_over <= 1;
                ADI1S <= 8'b0001_0000;//note
                counter <= 0;
                //ok led1<=1;
                end
              end
            start:
            begin
                 //if(counter <= 'd3)
                 over_flag <=0;
                 //led1<=1;
                 end
            acq:
              begin
               //led1<=1;

              if(counter<100)//data acquisition
                begin
                convst <=0;
                CS_L <= 1;
                RD_L <= 1;
                WR_L <= 1;
                counter <= counter+1;
                start_flag2 <= 0;
                //ok led0<=1;
                end
              else
                begin
                convst <=1;
                RD_L <= 1;
                WR_L <= 1;
                counter <= 0;
                start_flag2 <= 1;
                // ok led1<=1;
                end
              end
            read:
              begin
              // ok led0<=1;
              if(!EOC_L)
              begin
                //led0<=1;
                if(counter <= 'd5)//tRDL
                begin
                CS_L <= 0;
                WR_L <= 1;
                RD_L <= 0;
                ADbuf[7:0]<=ADI1;
                ADbuf[11:8]<=ADI2;
                counter <= counter+1;
                led0<=1;
                end
               else
                 begin
                 RD_L <= 1;
                 WR_L <= 1;
                 CS_L <= 1;
                 counter <= 0;
                 counter_channel <= counter_channel-1;
                 led1<=1;
                 end
               end
             else
               ;//led1<=1;
             end
             over:begin
                  over_flag <=1 ;
                   //led1<=1;
                  end
             default:
                  ;

             endcase
           end
      end
endmodule

其中ADIS是写AD转换通道的寄存器,ADI1是AD转后后的低8位数据(用的是双向口),ADI2是AD转后后的高4位数据,ADbuf是读AD转换结果的缓冲寄存器,ADO是将AD转换后给经FPGA输出给DA的12位数据;
看了下QUARTUS的警告:
Warning: Tri-state node(s) do not directly drive top-level pin(s)
Warning: Converted the fan-out from the tri-state buffer "ad1308:inst|ADI1[4]" to the node "ad1308:inst|ADbuf[4]" into an OR gate


Warning: Open-drain buffer(s) that do not directly drive top-level pin(s) are removed
Warning: Converted the fanout from the open-drain buffer "ad1308:inst|ADI1[7]" to the node "ad1308:inst|ADbuf[7]" into a wire
Warning: Converted the fanout from the open-drain buffer "ad1308:inst|ADI1[6]" to the node "ad1308:inst|ADbuf[6]" into a wire
Warning: Converted the fanout from the open-drain buffer "ad1308:inst|ADI1[5]" to the node "ad1308:inst|ADbuf[5]" into a wire
Warning: Converted the fanout from the open-drain buffer "ad1308:inst|ADI1[3]" to the node "ad1308:inst|ADbuf[3]" into a wire
Warning: Converted the fanout from the open-drain buffer "ad1308:inst|ADI1[2]" to the node "ad1308:inst|ADbuf[2]" into a wire
Warning: Converted the fanout from the open-drain buffer "ad1308:inst|ADI1[1]" to the node "ad1308:inst|ADbuf[1]" into a wire
Warning: Converted the fanout from the open-drain buffer "ad1308:inst|ADI1[0]" to the node "ad1308:inst|ADbuf[0]" into a wire

三态缓冲ADI 我用的是这个语句assign ADI1 = (WR_L)?8'bzzzz_zzzz:ADI1S;
不知道为什么三态缓冲ADI是顶层信号,警告中却将ADI变成了 open-drain buffer ?
不知道这个是不是导致低8位 ADI1 没有数据输出的原因?
如果还有其他错误请大神们指教,在下新手!谢谢!


0条回答

一周热门 更多>