zoukankan      html  css  js  c++  java
  • verilog入门实例<一>分频器,信号灯

    verilog入门实例一

    1. 分频器设计,要求:对输入时钟clk,进行分2、5、10分频。例如输入时钟50Mhz,输出时钟就是25、10、5Mhz。
      主要思路:
       偶数分频:假设偶数为EVEN,对时钟信号周期进行计数,则先写一个模(EVEN)的计数器,只要计数至EVEN-1则使输出信号翻转,便形成了偶数分频。
       奇数分频:由两个信号作或运算而成。假设奇数为ODD。第一个信号,以时钟信号的上跳沿进行计数,形成一个模(ODD)的计数器,令计数至0,1,2...(EVEN-3)/2全部为高电平,其他为低电平,形成一个占空比不为0.5的信号。第二个信号,以时钟的下跳沿进行计数,形成一个模(ODD)的计数器令计数至0,1,2...(EVEN-1)/2全部为高电平,其他为低电平,形成一个占空比不为0.5的信号。这两个信号做或运算则可形成奇数分频。举例:5分频。以时钟上跳沿计数,计数为0,1时为高电平,计数为2,3,4为低电平,如此形成一个信号1。同理以时钟下跳沿进行计数,计数为0,1时为高电平,计数为2,3,4为低电平,如此形成一个信号2。两个信号做或运算可以形成奇数分频信号。
    module divider(
        input clk;
        input rst_n;
        output clk_div2;
        output clk_div5;
        output clk_div10
    );
        reg [3:0]cnt1;
        reg [3:0]cnt2;
        reg [3:0]cnt3;
        
     reg clk_div51,clk_div52;
        
        parameter NUM_DIV_ODD ==5;
        parameter NUM_DIV_EVEN ==10;
        
        //二分频
        always@(posedge clk or negedge rst_n)
            begin
                if(!rst_n)
                    clk_div2 <= 1'b0;
                else 
                    clk_div2 <= ~clk_div2;
            end
        
        //奇数五分频由两个占空比为0.4的信号相和而成
        
        //第一个上跳沿计数的信号clk_div51
        always@(posedge clk or negedge rst_n)
            begin
            	if(!rst_n)
                    cnt1 <= 1'b0;
                else if (cnt < NUM_DIV - 1)
                    cnt1 <= cnt1+1'b1;
                else
                    cnt1 <= 1'b0;
            end
        
        always@(posedge clk or negedge rst_n)
            begin
                if(!rst_n)
                   clk_div51 <= 1'b0;
                else if(cnt1<NUM_DIV/2)
                    clk_div51 <=1'b1;
                else
                    clk_div51 <= 1'b0;
            end
        
        //第二个下跳沿计数的信号clk_div52
        always@(negedge clk or negedge rst_n)
            begin
                if(!rst_n)
                    cnt2 <= 1'b0;
                else if (cnt < NUM_DIV -1 )
                    cnt2 <= cnt2 + 1'b1;
                else
                    cnt <= 1'b0;
            end
        
        always@(negedge clk or negedge rst_n)
            begin
                if(!rst_n)
                    clk_div52 <= 1'b0;
                else if (cnt2 < NUM_DIV/2)
                    clk_div52 <= 1'b1;
                else
                    clk_div52 <= 1'b0;
                
            end
        assign clk_div5 <= clk_div51 | clk_div52;
        
        //十分频
        always@(posedge clk or negedge rst_n)
            begin
                if (!rst_n)
                    begin
                    	clk_div10 <= 1'b0;
                		cnt3 <=0;
                    end
                else if (cnt3 < NUM_DIV_EVEN/2)
                    begin
                        cnt3 <= cnt3 + 1'b1;
                        clk_div10 <= clk_div10;
                    end
                else
                    begin
                        cnt3 <= 1'b0;
                        clk_div10 <= ~clk_div10;
                    end
            end
        
    
    endmodule
    

    testbench

    `timescale 1ns/1ps
    module tb_divider;
        reg clk;
        reg rst_n;
        
        wire clk_div2;
        wire clk_div5;
        wire clk_div10;
        
        parameter TIME = 20;
        divider uut(
            .clk(clk),
            .rst_div(rst_n),
            .clk_div2(clk_div2),
            .clk_div5(clk_div5),
            .clk_div10(clk_div10)
        );
        
        always@ #(TIME/2) clk = ~clk;
        
        initial
            begin
                clk = 0;
                rst_n = 0;
                #TIME rst_n = 1;
                #(TiME * 80000) $finish;
            end
    endmodule
    

    仿真效果:

    其中clk_div51和clk_div52是奇数5分频的信号1和信号2。

    1. 信号灯
      要求:东西方向和南北方向各有四盏灯,分别为左拐灯、绿灯、黄灯和红灯
      东西方向信号灯的时间为:红灯55s,黄灯5s,绿灯40s,左拐灯15s;
      南北方向信号灯的时间为:红灯65,黄灯5,绿灯30,左拐灯15s;

    思路:把信号灯分为以上7种状态,由于有时间要求,则以5s记一次数,信号灯跑完整个过程,需要120s,则形成一个模24计数器,下面流程图中白色中的数字就是计数值。

    真值表:

    Light_ns(南北信号灯) Light_ew(东西信号灯) 状态
    左 绿 黄 红 左 绿 黄 红
    0 0 1 0 0 0 1 0 IDLE
    1 0 0 0 0 0 0 1 S1
    0 1 0 0 0 0 0 1 S2
    0 0 1 0 0 0 0 1 S3
    0 0 0 1 1 0 0 0 S4
    0 0 0 1 0 1 0 0 S5
    0 0 0 1 0 0 1 0 S6

    流程图:

    design

    module signal_light(clk,rst_n,light_ns,light_ew,count);
        input clk,rst_n;
        output light_ns,light_ew;//ns:north sourth,ew:east west
        output count;
        //output clk_count;
        reg[3:0]light_ns,light_ew;
        reg[4:0]count;
        reg[2:0]current_state,next_state;
    
        
        
        parameter IDLE=3'b000;
        parameter S1=3'b001;
        parameter S2=3'b010;
        parameter S3=3'b011;
        parameter S4=3'b100;
        parameter S5=3'b101;
        parameter S6=3'b110;
    
       // reg clk_count;
        //reg count1;
        //parameter T=9'd250000000;
    /*
     always@(posedge clk or negedge rst_n)
            begin
                if (!rst_n)
                    begin
                    	clk_count <= 1'b0;
                		cnt1 <=0;
                    end
                else if (cnt1 < T/2)
                    begin
                        cnt1 <= cnt1 + 1'b1;
                        clk_count <= clk_count;
                    end
                else
                    begin
                        cnt1 <= 1'b0;
                        clk_count <= ~clk_count;
                    end
            end
        */
        //counter
        always@(posedge clk or negedge rst_n)
            begin
                if(!rst_n)
                    count<=1'b0;
                else if(count==5'b10111)
                    count<=1'd0;
                else
                    count<=count+1'b1;
                    
            end
        
        always@(posedge clk or negedge rst_n)
            begin
                if(!rst_n)
                    current_state<=IDLE;
                else
                    current_state<=next_state;
            end
        
        always@(*)
            begin
                case(current_state)
                    IDLE:if(!count)next_state=S1;
                  		 else next_state=IDLE;
                    
                    S1:if(count==2)next_state=S2;
                       else next_state=S3;
                    
                    S2:if(count==9)next_state=S3;
                       else next_state=S2;
                    
                    S3:begin
    			if(count==3)next_state=S2;
                       	else 
                               begin
                                   if(count==10)next_state=S4;
                                   else next_state=S3;
    			    end
    		   end
                    
                    S4:if(count==13)next_state=S6;
                       else next_state=S4;
                    
                    S5:if(count==22)next_state=S6;
                       else next_state=S5;
                    
                    S6:begin
    			if(count==14)next_state=S5;
                               else 
                                     begin
                                           if(count==23)next_state=S1;
                                           else next_state=S6;
                                     end
                    end
                    
                 default:next_state=IDLE;
                endcase
             end
    
        always@(posedge clk or negedge rst_n)
            begin
                if(!rst_n)
                    begin
                        light_ns<=4'b0010;
                        light_ew<=4'b0010;
                    end
                else 
    		case(next_state)
                    IDLE   :begin
    			light_ns<=4'b0010;
    			light_ew<=4'b0010;
    			end
                    S1     :begin
    			light_ns<=4'b1000;
                            light_ew<=4'b0001;
    			end
                    S2     :begin
    			light_ns<=4'b0100;
                            light_ew<=4'b0001;
    			end
                    S3     :begin
    			light_ns<=4'b0010;
                            light_ew<=4'b0001;
    			end
                    S4     :begin
    		light_ns<=4'b0001;
                            light_ew<=4'b1000;
    			end
                    S5     :begin
    			light_ns<=4'b0001;
                            light_ew<=4'b0100;
    			end
                    S6     :begin
    			light_ns<=4'b0001;
                            light_ew<=4'b0010;
    			end
                    default:begin
    			light_ns<=4'b0010;
                            light_ew<=4'b0010;
    			end
                endcase
            end
        
    endmodule
    
    

    testbench

    `timescale 1ns/1ps
    module tb_signal_light;
    reg clk;
    reg rst_n;
    
    wire [4:0]count;
    
    wire [3:0]light_ew;
    wire [3:0]light_ns;
    //wire clk_count;
    
    parameter TIME=20;
    
    signal_light uut(
        .clk(clk),
        .rst_n(rst_n),
        .light_ns(light_ns),
        .light_ew(light_ew),
        .count(count)
        //.clk_count(clk_count)
    );
     always #10 clk = ~clk;
        
        initial
            begin
                clk = 0;
                rst_n = 0;
                #TIME rst_n = 1;
                //#(TiME * 80000) $finish;
            end
    endmodule
    
    

    仿真结果:

    结果中还有一个问题就是未分频,应该是要写一个周期的5s的时钟信号。

  • 相关阅读:
    2,SFDC 管理员篇
    1,SFDC 管理员篇
    0,SFDC 管理员篇
    Java控制台中输入中文输出乱码的解决办法
    struts1和struts2线程安全问题
    PL/SQL Developer使用技巧、快捷键
    SpringMVC前传--从Struts 1.x-2.x MVC-Spring 3.0 MVC
    H5元素拖拽使用事件数据传输
    js实现拼图小游戏
    js实现简单轮播图效果
  • 原文地址:https://www.cnblogs.com/kefu/p/13408979.html
Copyright © 2011-2022 走看看