概述
一、Code
module johnson(
// input
input clk_50,
input rst_n,
input key3,key2,key1,
// output
output[17:0] ledr
);
//parameter ledr_dir = 1'b0; //1'b1--right,1'b0--left
//parameter ledr_on = 1'b1; //1'b1--on,1'b0--off
reg ledr_dir; //1'b1--right,1'b0--left
reg ledr_on; //1'b1--on,1'b0--off
//--------------------------------------------
reg[21:0] cnt22;
always@(posedge clk_50 or negedge rst_n)
if(!rst_n)
cnt22 <= 22'd0;
else
cnt22 <= cnt22 + 1'b1;
//--------------------------------------------
reg[17:0] ledr_r;
always@(posedge clk_50 or negedge rst_n)
if(!rst_n)
ledr_r <= 18'b00_0000_0000_0000_0001;
else if(cnt22==22'h3fffff && ledr_on)
begin
if(ledr_dir)
ledr_r <= {ledr_r[0],ledr_r[17:1]}; //right
else
ledr_r <= {ledr_r[16:0],ledr_r[17]}; //left
end
assign ledr = ledr_r;
//--------------------------------------------
reg[2:0] key_rst;
always@(posedge clk_50 or negedge rst_n)
if(!rst_n)
key_rst <= 3'b111;
else
key_rst <= {key3,key2,key1};
reg[2:0] key_rst_r;
always@(posedge clk_50 or negedge rst_n)
if(!rst_n)
key_rst_r <= 3'b111;
else
key_rst_r <= key_rst;
wire[2:0] key_an;
//当寄存器key_rst由1变为0时,key_an的值变为高,维持一个时钟周期
assign key_an = key_rst_r & (~key_rst);
/*
key_rst 1 1 1 0 0 1
~key_rst 0 0 0 1 1 0
key_rst_r 1 1 1 0 0 1 //滞后key_rst一个时钟周期
key_an 0 0 1 0 0 //由此可以发现当key_rst的一个周期由1变为0时,key_an由0变为1;
*/
reg[19:0] cnt; //20ns一周期,20ms为10的6次方,相当于2的20次方=1024x1024>1000x1000;
always@(posedge clk_50 or negedge rst_n)
if(!rst_n)
cnt <= 20'b0;
else if(key_an)
cnt <= 20'b0;
else
cnt <= cnt+1'b1;
reg[2:0] low_key;
always@(posedge clk_50 or negedge rst_n)
if(!rst_n)
low_key <= 3'b111;
else if(cnt==20'hfffff) //满20ms,将按键值锁存到寄存器low_key中
low_key <= {key3,key2,key1};
reg[2:0] low_key_r; //每个时钟的上升沿将low_key信号锁存到low_key_r中
always@(posedge clk_50 or negedge rst_n)
if(!rst_n)
low_key_r <= 3'b111;
else
low_key_r <= low_key;
wire[2:0] led_ctrl;
//当寄存器low_key由1变为0时,led_ctrl的值变高,维持一个时钟周期
/*
low_sw 111 111 111 110 110 110
~low_sw 000 000 000 001 001 001
low_sw_r 111 111 111 110 110 110
led_ctrl 000 000 000 001 000 000
*/
assign led_ctrl = low_key_r[2:0] & (~low_key[2:0]);
always@(posedge clk_50 or negedge rst_n)
if(!rst_n)
begin
ledr_dir = 1'b0;
ledr_on = 1'b0;
end
else
begin
if(led_ctrl[2]) ledr_dir <= 1'b1; //led翻转输出
if(led_ctrl[1]) ledr_dir <= 1'b0;
if(led_ctrl[0]) ledr_on <= ~ledr_on;
end
endmodule
转载于:https://www.cnblogs.com/spartan/archive/2011/10/25/2224563.html
最后
以上就是懵懂面包为你收集整理的[笔记] Johnson计数器(十)的全部内容,希望文章能够帮你解决[笔记] Johnson计数器(十)所遇到的程序开发问题。
如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。
本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
发表评论 取消回复