首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

分频引发的折腾

分频引发的折腾

总的来说今天做的相当失败,本来只是想跟着特权的视频实现个简单的分频,熟练下前两天学的,谁知道又是一堆事情。
分频本是实现相当简单,我自信绝对不会有问题,可问题出在了分频结束要让蜂鸣器响,而特权同学板子上用到的蜂鸣器是有源蜂鸣器,直接简单的控制接口低电平就行了,而我在用我买的板子时发现上面用的是无缘的,这就纠结了。
随后,我又看了板子附带的例程,看完我就火了,这卖板子的人也太没道德了吧,例程写的一点也不规范,反正我头一下愣是没看懂,看了好一会儿才有点意思。
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的变化慢一拍,这样仿真就没问题了。
返回列表