原创 分频引发的折腾

2013-7-15 23:18 1303 10 10 分类: FPGA/CPLD 文集: FPGA学习过程

总的来说今天做的相当失败,本来只是想跟着特权的视频实现个简单的分频,熟练下前两天学的,谁知道又是一堆事情。
分频本是实现相当简单,我自信绝对不会有问题,可问题出在了分频结束要让蜂鸣器响,而特权同学板子上用到的蜂鸣器是有源蜂鸣器,直接简单的控制接口低电平就行了,而我在用我买的板子时发现上面用的是无缘的,这就纠结了。
随后,我又看了板子附带的例程,看完我就火了,这卖板子的人也太没道德了吧,例程写的一点也不规范,反正我头一下愣是没看懂,看了好一会儿才有点意思。
always @(count[9])
begin
    beep_r = !(count[13]&count[24]&count[27]);
end
这个是上面主要的一段代码,是用来延时+一定频率蜂鸣的,频率是10^8/2^15(我的板子上用的是50MHZ的晶振),于是我准备用modelsim进行一下仿真。
但当我写testbench的时候又犯难了。
module    beep(clk,beep);                    //模块名称beep        
input    clk;                            //系统时钟50MHz    
output    beep;                            //蜂鸣器输出端                
reg beep_r;                                //寄存器
reg[27:0]count;
assign beep = beep_r;                    //脉冲输出
always@(posedge clk)
begin
    count <= count + 1'b1;
end
always @(count[9])
begin
    beep_r = !(count[13]&count[24]&count[27]);
end
endmodule
这是商家附的例程,没有任何复位操作,按理说也行,毕竟可以直接在板子上试验成功,但我如果直接用beep做仿真的话,出来的结果就会始终是x状态。
没办法,我对代码进行了修改。
module lc_cnt(
input    clk,                            //系统时钟50MHz    
input   asy_rst,
output    beep                            //蜂鸣器输出端        
);
/*---------------------------Internal registers and wires--------------------------------*/
/* Register Output Signals */
reg beep_r;                                //寄存器
reg beep_w;
/* internal logic use signals */
reg[27:0]count;
/* ----------------------Logical Implementation------------------------------------------*/
/*-----------------------------------------------------------------------------------------
gen the beep_w signal
-----------------------------------------------------------------------------------------*/
always@( posedge clk or negedge asy_rst )
begin
    if ( !asy_rst )
        beep_w <= 1'b1;
    else
        beep_w <= beep_r;
end
assign beep = beep_w;                    //脉冲输出
/*-----------------------------------------------------------------------------------------
gen the count signal
-----------------------------------------------------------------------------------------*/
always@(posedge clk or negedge asy_rst)
begin
    if ( !asy_rst )
        count <= 1'b0;
    else    
        count <= count + 1'b1;
end
always @(count[9])
begin
     beep_r <= !(count[13]&count[24]&count[27]);
end
endmodule
我在beep_r的基础上又加了个beep_w,原因是如果在加复位信号时直接对beep_r和asy_rst进行赋值时,如果在count[9]后面加上 or negedge asy_rst就会在编译时出现错误,电平触发和边沿触发不能在一起,但如果把beep_r放在别的always语句块里赋值,编译时还会出can't resolve multiple constant drivers for net的错误,两个进程里如果都有同一个条件判断的话,会产生并行信号冲突的问题,同一个信号不允许在多个进程中赋值,否则就为多驱动。进程的并行性决定了多进程不同能对同一个对象进行赋值,这也是并行处理的一个特征。因此我又加了个beep_w让beep的变化慢一拍,这样仿真就没问题了。
但在仿真时,又是一个不大不小的麻烦事,由于这个例程中并不是复位之后蜂鸣器就响了,而是等了大概两秒半才开始间断的响,我如果想看到蜂鸣器响的时候的波形图就得仿真差不多3秒,但我那时候脑子犯抽,直接仿真了十秒,结果悲剧了,我等啊等啊等啊等,配上我的破电脑,得有七八分钟吧,不过结果也行,蜂鸣周期真的是16384个时钟周期,但我不甘心啊,总不能每次仿真我都从头开始吧,
我就想咱不是能用板级仿真吗,我用的是altera,可以用signaltap进行板级仿真,说干就干,其实板级仿真也挺简单的,就是在工程文件里加了个.stp文件,再次编译,下载,就可以用signaltap进行板子与PC机的通信了,但在这里也要提醒一下,信号的检测深度要适度,太深了编译时会报错,资源不够,设小点,这也就是说像这种嵌入式逻辑分析仪局限性也是相当大的,但其成本低还是必须承认的(或者是零成本)。
总之,今天还是相当失败的,也可能是因为第一次完整的实现一个程序的编写到仿真到下载进行板级仿真吧,新手嘛,理解理解,不过,最大的感受还是,,,奸商啊奸商!!!!给的是什么例程,简直是误人子弟。同时也给买板子的伙计们提个醒,对FPGA来说,买板子时一定要买那些板子资料和例程齐全规范的,规范和齐全的例程不仅看起来相当舒服,对我们的帮助那也是不可替代的。

文章评论0条评论)

登录后参与讨论
我要评论
0
10
关闭 站长推荐上一条 /2 下一条