特权同学

Verilog之Johnson计数器

0
阅读(4182)

简介:本示例是带停止控制的双向4bit  Johnson 计数器示例,可以通过LED灯直观的在开发板上进 行演示。

    sw2: 按键sw2 控制向左移动

    sw3: 按键sw3 控制向右移动

sw1: 按键sw1 第一次按下时将停止移动,再次按下时就会恢复移动

代码经过sp306板测试通过,且综合后0 error,0warning。

 

代码如下:

module johnson(clk,rst_n,key1,key2,key3,led1,led2,led3,led4);

 

input clk;

input rst_n;

input key1,key2,key3;

output led1,led2,led3,led4;

 

//------------------------------------

reg[23:0] delay;

 

always @ (posedge clk or negedge rst_n)

       if(!rst_n) delay <= 0;

       else delay <= delay+1;

 

reg[2:0] key_value;

 

always @ (posedge clk or negedge rst_n)

       if(!rst_n) key_value <= 3'b111;

       else if(delay == 24'hffffff) key_value <= {key3,key2,key1};//delay 20ms

 

//-------------------------------------

reg[2:0] key_value_r;

 

always @ (posedge clk or negedge rst_n)

       if(!rst_n) key_value_r <= 3'b111;

       else key_value_r <= key_value;

 

wire[2:0] key_change;

 

assign key_change = key_value_r & (~key_value);       //check key_value negedge per clk

 

//------------------------------------

reg stop_start,left_right;

 

always @ (posedge clk or negedge rst_n)

       if(!rst_n) begin

              stop_start <= 1;

              left_right <= 1;

              end

       else

              if(key_change[2]) stop_start <= ~stop_start;

              else if(key_change[1]) left_right <= 1;

              else if(key_change[0]) left_right <= 0;

 

//-------------------------------------

reg[3:0] led_value_r;

 

always @ (posedge clk or negedge rst_n)

       if(!rst_n) led_value_r <= 4'b1110;

       else if(delay == 24'h3fffff && stop_start)

              case (left_right)

                     1: led_value_r <= {led_value_r[2:0],led_value_r[3]};

                0: led_value_r <= {led_value_r[0],led_value_r[3:1]};

                     default: ;

                     endcase

 

assign {led4,led2,led3,led1} = led_value_r;

 

endmodule