搜索
bottom↓
回复: 4

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

[复制链接]

出0入0汤圆

发表于 2011-10-7 08:37:38 | 显示全部楼层 |阅读模式
请教个问题:
写了个配置AD5734寄存器的小程序,程序仿真正确,结果再程序前端加了个PLL[40M分10M]模块,结果整个顶层的仿真就不对了,请大家帮忙看看

(原文件名:1顶层文件.jpg)

当我仿真上图中画红色圈模块的时候,仿真波形能出来
但是仿真整个模块[只多加了个PLL],波形就出不了

(原文件名:2顶层中画圈部分模块单独仿真.jpg)

(原文件名:3顶层模块仿真 出来波形不正确 且没数据出来.jpg)

PLL单独仿真:

(原文件名:4PLL单独仿真.jpg)

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

SL,
SCK,
SDATA,
LDAC,

ESD_EN,
OSC_EN
);

parameter  bitsize  = 48;
parameter  wordsize = 31;

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

input rst_n,clk_10Mhz;

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

reg[4:0]  cell_cnt;//reg_cfg_ad57340地址单元计数器,共32个寄存器
reg[5:0]  bit_cnt;//为reg_cfg_ad5734每个地址单元的位计数器,每个地址单元有48位,故共需6位寄存器

reg[5:0]   state;
//reg[3:0]   n_cs;

parameter  idle = 6'b000001;
parameter  cssd = 6'b000010;
parameter  csbc = 6'b000100;
parameter  sltp = 6'b001000;
parameter  ccss = 6'b010000;
parameter  stop = 6'b100000;

initial
         begin
         reg_cfg_ad5734[0]  <= 48'b101011101001000011110001001000110100010101100111; //测试用,完了之后删除该行 48'b1010 1110 1001 0000 1111 0001 0010 0011 0100 0101 0110 0111;
         //reg_cfg_ad5734[0]  <= 48'h1c00001c0000 ; //addr:0x000;data:0x000000;
         reg_cfg_ad5734[1]  <= 48'h180000048000 ; //reg_cfg_ad5734为AD5734的寄存器配置存储器,低地址部分(12位)为配置寄存器地址,高地址部分(28位)为该配置寄存器所需配置的值  
         reg_cfg_ad5734[2]  <= 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[cell_cnt]; //把存储器的第一个数据 载入到寄存器reg_ad5734内,然后对该值进行并转串 后一个一个输出
            state      <= cssd;                     //原来语句为:reg_ad5734 <= reg_cfg_ad5734[cell_cnt - 1];
        end
        
        cssd:begin
            SCK   <= 1;                         //时钟高电平,开始写入数据
            SDATA <= reg_ad5734[bit_cnt - 1];   //bit_cnt初始值为47,从寄存器的最高位开始输出 [47:0] 共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

阿莫论坛20周年了!感谢大家的支持与爱护!!

知道什么是神吗?其实神本来也是人,只不过神做了人做不到的事情 所以才成了神。 (头文字D, 杜汶泽)

出0入0汤圆

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

出0入0汤圆

 楼主| 发表于 2011-11-29 11:26:01 | 显示全部楼层
自己发的贴,没人来光顾,自己解决吧。
最后发现,程序没问题,是软件版本问题,QuartusII8.0和9.0仿真都会莫名其妙的问题,后来不小心弄到8.1版本上,没问题了。
程序给后人做个小_参考。

出0入0汤圆

发表于 2011-11-30 15:54:52 | 显示全部楼层
回复【2楼】zhchynnu
-----------------------------------------------------------------------

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

出0入0汤圆

发表于 2011-11-30 16:02:03 | 显示全部楼层
回复【3楼】xtqxtq111
-----------------------------------------------------------------------

要用这么多QuartusII版本去试?感觉学FPGA真是很复杂。
回帖提示: 反政府言论将被立即封锁ID 在按“提交”前,请自问一下:我这样表达会给举报吗,会给自己惹麻烦吗? 另外:尽量不要使用Mark、顶等没有意义的回复。不得大量使用大字体和彩色字。【本论坛不允许直接上传手机拍摄图片,浪费大家下载带宽和论坛服务器空间,请压缩后(图片小于1兆)才上传。压缩方法可以在微信里面发给自己(不要勾选“原图),然后下载,就能得到压缩后的图片。注意:要连续压缩2次才能满足要求!!】。另外,手机版只能上传图片,要上传附件需要切换到电脑版(不需要使用电脑,手机上切换到电脑版就行,页面底部)。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

手机版|Archiver|amobbs.com 阿莫电子技术论坛 ( 粤ICP备2022115958号, 版权所有:东莞阿莫电子贸易商行 创办于2004年 (公安交互式论坛备案:44190002001997 ) )

GMT+8, 2024-7-24 11:18

© Since 2004 www.amobbs.com, 原www.ourdev.cn, 原www.ouravr.com

快速回复 返回顶部 返回列表