• [笔记] Johnson计数器(十)


    一、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
    
  • 相关阅读:
    动态语言,别再说不
    你应当如何学习C++(以及编程)(rev#1)
    JobsPirate.com:工作信息搜索引擎
    找工作
    ORM, Code Generation and a bit about MDA[转]
    使用phpmaill发送邮件的例子
    一级域名和二级域名的区别是什么?作用怎样?
    css中,如何设置前景色的透明度?
    dede从www跟目录迁移,网站空间
    一个域名最多能对应几个IP地址?,一个IP地址可以绑定几个域名?
  • 原文地址:https://www.cnblogs.com/spartan/p/2224563.html
Copyright © 2020-2023  润新知