led跑马灯(模糊时钟ambiguous color,非法字符 non printable character,寄存器初值,计数器计数注意事项)

1.设计定义

  让8个led以100ns的速度循环闪烁。

2.设计输入

  循环闪烁,还是周期问题,用时钟驱动,所以需要一个时钟信号clk。再给一个复位输入reset八个输出led信号

  每100ns只有一个led亮,其它灭,顺序循环,所以一个周期有800ns。用条件语句来判断可以实现每次只亮一个且循环。

  开发板的时钟脉冲信号周期为20ns,故引入计数变量counter,每计数满5则换状态。根据5的倍数来确定哪个灯亮。

  需要注意的是,每一次时钟沿上升沿到来都要保证计数器+1才能正常运行,如果得不到保证,就会困在某个状态里面出不来,如果是复位信号时钟沿到来则无需保证,因为是异步的,异步要第一个执行。

 

module led_run(
    clk,
    reset,
    led    
    );
    
    input clk;
    input reset;
    output reg[7:0]led;//8个灯
    
    reg [5:0]counter;//程序员计数器确定宽度
    
    
    always@(posedge clk or negedge reset)begin
    if ( reset == 1'b0 ) begin    //复位信号
        counter <= 6'd0;
         end
    else if ( counter == 6'b0 )begin
        led <= 8'b0000_0001;
         counter <= counter + 1'b1;  end
    else if ( counter == 6'b00_0101 ) begin
        led <= 8'b0000_0010;
        counter <= counter + 1'b1;  end
    else if ( counter == 6'b00_1010 )begin
        led <= 8'b0000_0100;
        counter <= counter + 1'b1;  end
    else if ( counter == 6'b00_1111 )begin
        led <= 8'b0000_1000;
        counter <= counter + 1'b1;  end
    else if ( counter == 6'b01_0100 )begin
        led <= 8'b0001_0000;
        counter <= counter + 1'b1;  end
    else if ( counter == 6'b01_1001 )begin
        led <= 8'b0010_0000;
        counter <= counter + 1'b1;  end
    else if ( counter == 6'b01_1110 )begin
        led <= 8'b0100_0000;
        counter <= counter + 1'b1;  end
   else if ( counter == 6'b10_0011 )begin
        led <= 8'b1000_0000;      
        counter <= counter + 1'b1;  end
   else if ( counter == 6'b10_1000 )begin
       led <= 8'b0000_0001;
        counter <= 6'd1 ;        //这里要加1,不然第一个灯就不再是周期100ns,而是120ns

        end        
   else
        counter <= counter + 1'b1;    
    end
    
    
    
endmodule

 

下面是分开写的,要十分注意的是,两者的always触发条件最好相同,第一个语句也要是复位信号条件语句。在这如果第二个always删了negedge 和 led=00000000的话,那么上一个always执行复位,下一个always并行执行counter==0,会使灯亮着,不符合要求。应该在复位时让灯全熄灭。如果是上面的合并写法,就不需要额外加led=00000000,因为只进入一个always,只判断一次,下面写法并行进入了两个always,判断两次。

module led_run(
    clk,
    reset,
    led    
    );
    
    input clk;
    input reset;
    output reg[7:0]led;
    
    reg [5:0]counter;
    
    
    always@(posedge clk or negedge reset)begin
    if ( reset == 1'b0 ) begin
        counter <= 6'd0;
         counter <= counter + 1'b1;  end
    else if ( counter == 6'b0 )begin
         counter <= counter + 1'b1;  end
    else if ( counter == 6'b00_0101 ) begin
        counter <= counter + 1'b1;  end
    else if ( counter == 6'b00_1010 )begin
        counter <= counter + 1'b1;  end
    else if ( counter == 6'b00_1111 )begin
        counter <= counter + 1'b1;  end
    else if ( counter == 6'b01_0100 )begin
        counter <= counter + 1'b1;  end
    else if ( counter == 6'b01_1001 )begin
        counter <= counter + 1'b1;  end
    else if ( counter == 6'b01_1110 )begin
        counter <= counter + 1'b1;  end
   else if ( counter == 6'b10_0011 )begin   
        counter <= counter + 1'b1;  end
   else if ( counter == 6'b10_1000 )begin
        counter <= 6'd1 ;    
        end        
   else
        counter <= counter + 1'b1;    
    end
    
    always@(posedge clk or negedge reset )begin
    if ( reset == 1'b0 ) begin
        led <= 8'b0000_0000;   end
    else if ( counter == 6'b0 )begin
        led <= 8'b0000_0001;  end
    else if ( counter == 6'b00_0101 ) begin
        led <= 8'b0000_0010; end
    else if ( counter == 6'b00_1010 )begin
        led <= 8'b0000_0100;  end
    else if ( counter == 6'b00_1111 )begin
        led <= 8'b0000_1000; end
    else if ( counter == 6'b01_0100 )begin
        led <= 8'b0001_0000; end
    else if ( counter == 6'b01_1001 )begin
        led <= 8'b0010_0000;  end
    else if ( counter == 6'b01_1110 )begin
        led <= 8'b0100_0000; end
   else if ( counter == 6'b10_0011 )begin
        led <= 8'b1000_0000;      end
   else if ( counter == 6'b10_1000 )begin
       led <= 8'b0000_0001;   
        end        

    end    
    
endmodule

 

  •  遇到的错误

  自己不看视频写就容易遇到许多错误。

1.syntax error near non-printable character with the hex value“0xa3“ 出现非法字符

  说明符号半角全角,中英文出错了。这种情况可能出现在1.写错。2.从别的网站复制代码过来出错。

  这次我把代码从vivoda复制到博客园,再复制回去就出错了,说明不同的地方可能编码不同,容易出错,最好是出错的地方自己先打一遍,看看错误会不会消失,再看其它情况。

  

 

 

2.ambiguous clock in event control 事件控制中的模糊时钟

  2.1always中的时钟信号变量没有初始化,没有用上。

  

 

 

  在这里不会在编辑器中出现语法报错,但综合时会出错。如图,因为我触发条件写了reset下降沿,但是下文都没提及reset。只要把 negedge reset删了或者把//删了就可以解决。 

  2.2赋值冲突。多个if满足条件,且他们都对同个变量处理。由于fpga硬件的处理是并行的,电路会不知道应该进行哪个处理,就出现了错误。

3.寄存器初始值问题

  寄存器的初始值有多种情况。

  3.1不赋初值不复位:初始值为0

  3.2不赋初值复位:初始值为复位语句值

  3.3赋初值不复位:初始值为初值

  3.4赋初值复位:初始值为初值。

  总结:有赋初值则为初值,没赋则为复位值,都没有则为0。

注:初始值查看方法:

 4.计数器计数注意事项

  每一次时钟沿上升沿到来都要保证计数器+1才能正常运行,如果得不到保证,就会困在某个状态里面出不来,如果是复位信号时钟沿到来则无需保证,因为是异步的,异步要第一个执行。

 

 

 

 

 

 

 

 

  

 

 

posted @ 2022-05-11 11:04  little_breeze  阅读(395)  评论(0)    收藏  举报