zhchynnu 发表于 2011-10-7 08:37:38

1个状态机写的配置AD5734的程序,程序仿真正确,加上PLL后出错,请指教。

请教个问题:
写了个配置AD5734寄存器的小程序,程序仿真正确,结果再程序前端加了个PLL模块,结果整个顶层的仿真就不对了,请大家帮忙看看
http://cache.amobbs.com/bbs_upload782111/files_46/ourdev_682716OJA0AH.jpg
(原文件名:1顶层文件.jpg)

当我仿真上图中画红色圈模块的时候,仿真波形能出来
但是仿真整个模块[只多加了个PLL],波形就出不了
http://cache.amobbs.com/bbs_upload782111/files_46/ourdev_682717OP3GGT.jpg
(原文件名:2顶层中画圈部分模块单独仿真.jpg)
http://cache.amobbs.com/bbs_upload782111/files_46/ourdev_682718B33ZXV.jpg
(原文件名:3顶层模块仿真 出来波形不正确 且没数据出来.jpg)

PLL单独仿真:
http://cache.amobbs.com/bbs_upload782111/files_46/ourdev_682719IQ57D7.jpg
(原文件名:4PLL单独仿真.jpg)

附上原码:
module cfg_ad5734(
rst_n,
clk_10Mhz,

SL,
SCK,
SDATA,
LDAC,

ESD_EN,
OSC_EN
);

parameterbitsize= 48;
parameterwordsize = 31;

reg reg_ad5734;            //寄存器;把存储器出来的值放到里面
reg reg_cfg_ad5734;//reg_cfg_ad5734为AD5734的寄存器配置存储器,低地址部分(12位)为配置寄存器地址,高地址部分(28位)为该配置寄存器所需配置的值

input rst_n,clk_10Mhz;

outputSL,SCK,SDATA,LDAC,ESD_EN,OSC_EN;
reg   SL,SCK,SDATA,LDAC,ESD_EN,OSC_EN;

regcell_cnt;//reg_cfg_ad57340地址单元计数器,共32个寄存器
regbit_cnt;//为reg_cfg_ad5734每个地址单元的位计数器,每个地址单元有48位,故共需6位寄存器

reg   state;
//reg   n_cs;

parameteridle = 6'b000001;
parametercssd = 6'b000010;
parametercsbc = 6'b000100;
parametersltp = 6'b001000;
parameterccss = 6'b010000;
parameterstop = 6'b100000;

initial
         begin
         reg_cfg_ad5734<= 48'b101011101001000011110001001000110100010101100111; //测试用,完了之后删除该行 48'b1010 1110 1001 0000 1111 0001 0010 0011 0100 0101 0110 0111;
         //reg_cfg_ad5734<= 48'h1c00001c0000 ; //addr:0x000;data:0x000000;
         reg_cfg_ad5734<= 48'h180000048000 ; //reg_cfg_ad5734为AD5734的寄存器配置存储器,低地址部分(12位)为配置寄存器地址,高地址部分(28位)为该配置寄存器所需配置的值
         reg_cfg_ad5734<= 48'h1d00001d0000 ;
         end
   

always@(posedge clk_10Mhz)
begin   
    if(!rst_n)begin
            SCK      <= 1;
            SL       <= 1;             //默认为高电平,低电平有效,才开始写
            LDAC   <= 1;             //LDAC初始化为高电平,只有在写完一组数据之后,才为低电平
            cell_cnt <= 0;             //从存储器的第一个值开始
            bit_cnt<= 48;            //从最高位开始输出
            OSC_EN   <= 0;             //默认为低电平
            ESD_EN   <= 0;             //默认为低电平
            state    <= idle;
            
            end
    else begin
      case(state)
      idle:begin                                  //初始化
            SCK      <= 0;
            SL         <= 0;
            reg_ad5734 <= reg_cfg_ad5734; //把存储器的第一个数据 载入到寄存器reg_ad5734内,然后对该值进行并转串 后一个一个输出
            state      <= cssd;                     //原来语句为:reg_ad5734 <= reg_cfg_ad5734;
      end
      
      cssd:begin
            SCK   <= 1;                         //时钟高电平,开始写入数据
            SDATA <= reg_ad5734;   //bit_cnt初始值为47,从寄存器的最高位开始输出 共48位
            state <= csbc;
      end
      
      csbc:begin                              //该部分得考虑,第0位数据怎么输出去??
            if(bit_cnt > 0)
                begin
                  SCK   <= 0;
                  bit_cnt <= bit_cnt - 6'b1;
                  state   <= cssd;
                end
            else
                begin            //写完一组48位的数据后,状态转移到判断是否写完存储器内所有的数据组
                  bit_cnt <= 47;
                  SCK   <= 1;
                  state   <= sltp;
                end
            end
      
      sltp:begin
          SL    <= 1;
          state <= ccss;
          end
      
      ccss:begin
          LDAC<= 0;
          state <= stop;
          end
      
      stop:begin                              //该状态到后面加上,当cell_cnt等于5时,输出OSC_en为高电平
            LDAC <= 1;
            if(cell_cnt < wordsize)               //wordsize值为31,共31组数据。原来语句为:if(cell_cnt < wordsize - 1)
               if(cell_cnt == 4) begin
                         cell_cnt <= cell_cnt + 5'b1;//cell_cnt值加1,开始写存储器的下一组值
                  state    <= idle;             //转到idle状态:把存储器的下一组赋值给寄存器,开始串行写循环
                         ESD_EN   <= 1;                  //在写完第5个寄存器值的同时,使能ESD_EN
                  end
               else begin
                  cell_cnt <= cell_cnt + 5'b1;//cell_cnt值加1,开始写存储器的下一组值
                  state    <= idle;             //转到idle状态:把存储器的下一组赋值给寄存器,开始串行写循环
                  end
            else
                begin
                  SCK    <= 1;
                  SL   <= 1;
                  OSC_EN <= 1;                  //当写AD5734结束的时候,使能OSC_EN
                  //ESD_EN <= 1; // 做实验,待会调整使能位置
                  //cell_cnt <= 0;
                end
            end
      
      default:state <= idle;
      endcase
    end
end

endmodule

zhchynnu 发表于 2011-10-7 08:43:11

昨天在一个FPGA群内问了下,但还是没发现问题,先猜测:
1、是否是PLL模块出来的10M信号有几个周期的延时,影响后面cfg_5734模块的正常运行?但是后面模块是检测10M的上升沿 always@(posedge clk_10Mhz) ?还是该语句不检测上升沿?我打算在rst_n后面价格延时模块,看看是否这个问题,结果会发上来,给像我这样的菜鸟,有个参考。
2、请楼下补充!
直接联系我也可以,Q35384645。

zhchynnu 发表于 2011-11-29 11:26:01

自己发的贴,没人来光顾,自己解决吧。
最后发现,程序没问题,是软件版本问题,QuartusII8.0和9.0仿真都会莫名其妙的问题,后来不小心弄到8.1版本上,没问题了。
程序给后人做个小_参考。

xtqxtq111 发表于 2011-11-30 15:54:52

回复【2楼】zhchynnu
-----------------------------------------------------------------------

还请兄弟多发几个状态机的帖子,我在学习用状态机写程序的~~~

yueshengzing 发表于 2011-11-30 16:02:03

回复【3楼】xtqxtq111
-----------------------------------------------------------------------

要用这么多QuartusII版本去试?感觉学FPGA真是很复杂。
页: [1]
查看完整版本: 1个状态机写的配置AD5734的程序,程序仿真正确,加上PLL后出错,请指教。