最新文章专题视频专题问答1问答10问答100问答1000问答2000关键字专题1关键字专题50关键字专题500关键字专题1500TAG最新视频文章推荐1 推荐3 推荐5 推荐7 推荐9 推荐11 推荐13 推荐15 推荐17 推荐19 推荐21 推荐23 推荐25 推荐27 推荐29 推荐31 推荐33 推荐35 推荐37视频文章20视频文章30视频文章40视频文章50视频文章60 视频文章70视频文章80视频文章90视频文章100视频文章120视频文章140 视频2关键字专题关键字专题tag2tag3文章专题文章专题2文章索引1文章索引2文章索引3文章索引4文章索引5123456789101112131415文章专题3
当前位置: 首页 - 正文

verilog HDL基础程序

来源:动视网 责编:小OO 时间:2025-09-27 21:48:39
文档

verilog HDL基础程序

涉及到需要时间的并且在不同的时间执行程序时就要用到分频计数器至于需要分频多少看需要执行多少次,也就是需要用到的时间有多少次。3-8译码器//学习38译码器的原理,//拨码开关的123作为输入//本实验采用拨码开关来作为输入,LED作为状态显示//当然如果你的学习板没有拨码开关,可以用key1key2key3作为数据输入。moduledecoder_38(out,key_in);output[7:0]out;//38译码器输出有8钟状态,所以要8个LED灯。input[2:0]key_in;//
推荐度:
导读涉及到需要时间的并且在不同的时间执行程序时就要用到分频计数器至于需要分频多少看需要执行多少次,也就是需要用到的时间有多少次。3-8译码器//学习38译码器的原理,//拨码开关的123作为输入//本实验采用拨码开关来作为输入,LED作为状态显示//当然如果你的学习板没有拨码开关,可以用key1key2key3作为数据输入。moduledecoder_38(out,key_in);output[7:0]out;//38译码器输出有8钟状态,所以要8个LED灯。input[2:0]key_in;//
涉及到需要时间的并且在不同的时间执行程序时就要用到分频计数器至于需要分频多少看需要执行多少次,也就是需要用到的时间有多少次。

3-8 译码器 

//学习3 8译码器的原理,

//拨码开关的 1 2 3作为输入

//本实验采用拨码开关来作为输入,LED作为状态显示

//当然如果你的学习板没有拨码开关,可以用key1 key2 key3 作为数据输入。

module decoder_38(out,key_in);

output[7:0] out;     //3 8译码器输出有8钟状态,所以要8个LED灯。

input[2:0] key_in;   //(1 2 3)key1 key2 key3 作为数据输入

reg[7:0] out;

always @(key_in)

begin

case(key_in)                       

3'd0: out=8'b11111110;  //LED作为状态显示,低电平有效

3'd1: out=8'b11111101;

3'd2: out=8'b11111011;

3'd3: out=8'b11110111;

3'd4: out=8'b11101111;

3'd5: out=8'b11011111;

3'd6: out=8'b10111111;

3'd7: out=8'b01111111;

endcase 

end 

endmodule

1位数码管动态显示

//一位数码管试验

//利用分频计数器得到数码管,效果

module SMG_LED (clk_50M,rst,led_bit,dataout);

input clk_50M,rst;      //系统时钟50M输入 从12脚输入。

output [7:0] dataout;   //我们这里用数码管,

output led_bit;         //一位数码管的位选择

reg [7:0] dataout;

reg       led_bit;  

reg [27:0] count; //分频计数器

//分频计数器

always @ ( posedge clk_50M )

 begin

count<=count+1; //计数器自加

 end

always @ ( posedge clk_50M or negedge rst)

 begin

led_bit <= 'b0; //是数码管的位选择处于导通状态

  case ( count[27:24] )

  //  case ( count[27:24] )这一句希望初学者看明白,

  //  也是分频的关键

  //  在数码管上面显示0到F

0: dataout<=8'b11000000; //0

1: dataout<=8'b11111001;

2: dataout<=8'b10100100;

3: dataout<=8'b10110000;

4: dataout<=8'b10011001;

5: dataout<=8'b10010010;

6: dataout<=8'b10000010;

7: dataout<=8'b11111000;

8: dataout<=8'b10000000;

9: dataout<=8'b10010000;

10:dataout<=8'b10001000;

11:dataout<=8'b10000011;

12:dataout<=8'b11000110;

13:dataout<=8'b10100001;

14:dataout<=8'b10000110;

15:dataout<=8'b10001110; //f

  endcase

 end

endmodule

7段数码管静态显示

//本实验就是学习单个数码管的显示

module SMG_LED (clk_50M,led_bit,dataout);

input clk_50M ;         //系统时钟50M输入 从12脚输入。

output [7:0] dataout;   //我们这里用数码管,

output led_bit;         //一位数码管的位选择

reg [7:0] dataout;

reg       led_bit;  

always @ ( posedge clk_50M )

 begin

led_bit <= 'b0; //是数码管的位选择处于导通状态

dataout<=8'b11000000; //修改7段码,可以显示不同的字符

                       //本实验初始是在数码管显示0

 end

数码管静态显示0到7

//7段数码管测试实验:以动态扫描方式在8位数码管

//“同时”显示0--7

//实验的目的是向用户介绍多个数码管动态显示的方法。

//动态显示的方法是,按一定的频率轮流向各个数码管的COM端送出低电平

//,同时送出对应的数据给各段

module led_0_7 (clk,rst,dataout,en);

input clk,rst;         //系统时钟50M输入 从12脚输入。

output[7:0] dataout;   //数码管的段码输出

output[7:0] en;        //数码管的位选使能输出

reg[7:0] dataout;     

reg[7:0] en;

reg[15:0] cnt_scan;//扫描频率计数器

reg[4:0] dataout_buf;

always@(posedge clk or negedge  rst)

begin

    if(!rst) begin

     cnt_scan<=0;

     end

    else begin

     cnt_scan<=cnt_scan+1;

        end

end

always @(cnt_scan)

begin

   case(cnt_scan[15:13])

       3'b000 :

          en = 8'b1111_1110;

       3'b001 :

          en = 8'b1111_1101;

       3'b010 :

          en = 8'b1111_1011;

       3'b011 :

          en = 8'b1111_0111;

       3'b100 :

          en = 8'b1110_1111;

       3'b101 :

          en = 8'b1101_1111;

       3'b110 :

          en = 8'b1011_1111;

       3'b111 :

          en = 8'b0111_1111;

       default :

          en = 8'b1111_1110;

    endcase

end

always@(en) //对应COM信号给出各段数据

begin

    case(en)

        8'b1111_1110:

            dataout_buf=0;

        8'b1111_1101:

            dataout_buf=1;

        8'b1111_1011:

            dataout_buf=2;

        8'b1111_0111:

            dataout_buf=3;    

        8'b1110_1111:

            dataout_buf=4;

        8'b1101_1111:

            dataout_buf=5;

        8'b1011_1111:

            dataout_buf=6;

        8'b0111_1111:

            dataout_buf=7;

        default: 

            dataout_buf=8;

     endcase

end

always@(dataout_buf)

begin

    case(dataout_buf)

        4'b0000:

            dataout=8'b1100_0000;

        4'b0001:

            dataout=8'b1111_1001;

        4'b0010:

            dataout=8'b1010_0100;

        4'b0011:

            dataout=8'b1011_0000;

        4'b0100:

            dataout=8'b1001_1001;

        4'b0101:

            dataout=8'b1001_0010;

        4'b0110:

            dataout=8'b1000_0010;

        4'b0111:

            dataout=8'b1111_1000;

        4'b1000:

            dataout=8'b1000_0000;

        4'b1001:

            dataout=8'b1001_1000;

        4'b1010:

            dataout=8'b1000_1000;

        4'b1011:

            dataout=8'b1000_0011;

        4'b1100:

            dataout=8'b1100_0110;

        4'b1101:

            dataout=8'b1010_0001;

        4'b1110:

            dataout=8'b1000_0110;

        4'b1111:

            dataout=8'b1000_1110;

     endcase

end

endmodule

8位优先编码器

//学习编码器的原理

//优先编码器,拨码开关来作为输入,结果由数码管显示 

module encode(a,c,en);

input[8:1] a;   //由键盘输入数据

output[7:0] c;  //结果由数码管显示

reg[7:0] c;

output[7:0] en;

reg[3:0] c_tmp;

integer i;

assign en=0;

always@(a) 

begin

    c_tmp=0;

for(i=1;i<9;i=i+1) begin

        if(a[i])

            c_tmp=i;

    end

end

always@(c_tmp)

begin

//下面是7段码显示的段码

    case(c_tmp)

        4'b0000:

            c=8'b11000000; //0

        4'b0001:

            c=8'b11111001;  //1

        4'b0010:

            c=8'b10100100;

        4'b0011:

            c=8'b10110000;

        4'b0100:

            c=8'b10011001;

        4'b0101:

            c=8'b10010010;

        4'b0110:

            c=8'b10000010;

        4'b0111:

            c=8'b11111000;

        4'b1000:

            c=8'b10000000;

        4'b1001:

            c=8'b10010000;

        4'b1010:

            c=8'b10001000;

        4'b1011:

            c=8'b10000011;

        4'b1100:

            c=8'b11000110;

        4'b1101:

            c=8'b10100001;

        4'b1110:

            c=8'b10000110;

        4'b1111:

            c=8'b10001110;  //f

     endcase

end

endmodule

buzzer

向蜂鸣器发送一定频率的方波可以使蜂鸣器发出相应的音调,该实验通过设计一个状态机和分频

器使蜂鸣器发出"多来咪发梭拉西多"的音调。

module buzzer(clk,rst,out);

input clk,rst;

output out;

reg out;

reg[3:0] clk_div1; //基频分频计数器,基频为4M

reg[12:0] clk_div2;//音阶分频计数器,由基频分频产生各个音阶

reg[21:0] cnt;//各音阶发声时间长短计数器

reg[2:0] state;

parameter   duo=3822,   //各个音调的分频系数

            lai=3405,

            mi=3034,

            fa=2865,

            suo=2551,

            la=2273,

            xi=2024,

            duo1=1911;

always@(posedge clk or negedge rst)

begin

    if(!rst) begin

     clk_div1<=0;

     end

    else begin

        if(clk_div1!=9)

         clk_div1<=clk_div1+1;

        else

         clk_div1<=0;

     end

end

always@(posedge clk or negedge rst)

begin

    if(!rst) begin

     clk_div2<=0;

     state<=0;

     cnt<=0;

     out<=0;

     end

    else if(clk_div1==9) begin

        case(state)

            3'b000: begin               //发“多”

             cnt<=cnt+1;

                if(cnt==22'h3fffff) 

                 state<=3'b001;

                if(clk_div2!=duo)

                 clk_div2<=clk_div2+1;

                else begin

                 clk_div2<=0;

                 out<=~out;

                end

             end

            3'b001: begin                //发“来”

             cnt<=cnt+1;

                if(cnt==22'h3fffff) 

                 state<=3'b010;

                if(clk_div2!=lai)

                 clk_div2<=clk_div2+1;

                else begin

                 clk_div2<=0;

                 out<=~out;

                end

             end

            3'b010:begin                //发"米“

             cnt<=cnt+1;

                if(cnt==22'h3fffff) 

                 state<=3'b011;

                if(clk_div2!=mi)

                 clk_div2<=clk_div2+1;

                else begin

                 clk_div2<=0;

                 out<=~out;

                end

             end

            3'b011: begin                 //发"法“

             cnt<=cnt+1;

                if(cnt==22'h3fffff) 

                 state<=3'b100;

                if(clk_div2!=fa)

                 clk_div2<=clk_div2+1;

                else begin

                 clk_div2<=0;

                 out<=~out;

                end

             end

            3'b100: begin               //发"梭“   

             cnt<=cnt+1;

                if(cnt==22'h3fffff) 

                 state<=3'b101;

                if(clk_div2!=suo)

                 clk_div2<=clk_div2+1;

                else begin

                 clk_div2<=0;

                 out<=~out;

                end

             end

            3'b101: begin                  //发"拉“

             cnt<=cnt+1;

                if(cnt==22'h3fffff) 

                 state<=3'b110;

                if(clk_div2!=la)

                 clk_div2<=clk_div2+1;

                else begin

                 clk_div2<=0;

                 out<=~out;

                end

             end

            3'b110: begin                   //发"西“

             cnt<=cnt+1;

                if(cnt==22'h3fffff) 

                 state<=3'b111;

                if(clk_div2!=xi)

                 clk_div2<=clk_div2+1;

                else begin

                 clk_div2<=0;

                 out<=~out;

                end

             end

            3'b111: begin                   //发"多“(高音)

             cnt<=cnt+1;

                if(cnt==22'h3fffff) 

                 state<=3'b000;

                if(clk_div2!=duo1)

                 clk_div2<=clk_div2+1;

                else begin

                 clk_div2<=0;

                 out<=~out;

                end

             end

         endcase

     end

end

endmodule

LCD1602_B

//www.21eda.com

//本实验是用LCD1602显示英文。(LCD带字库)

module lcd(clk, rs, rw, en,dat);  

input clk;          //系统时钟输入50M

 output [7:0] dat;  //LCD的8位数据口

 output  rs,rw,en;  //LCD的控制脚

 reg e; 

 reg [7:0] dat; 

 reg rs;   

 reg  [15:0] counter; 

 reg [4:0] current,next; 

 reg clkr; 

 reg [1:0] cnt; 

 parameter  set0=4'h0; 

 parameter  set1=4'h1; 

 parameter  set2=4'h2; 

 parameter  set3=4'h3; 

 parameter  dat0=4'h4; 

 parameter  dat1=4'h5; 

 parameter  dat2=4'h6; 

 parameter  dat3=4'h7; 

 parameter  dat4=4'h8; 

 parameter  dat5=4'h9; 

 parameter  dat6=4'hA; 

 parameter  dat7=4'hB; 

 parameter  dat8=4'hC; 

 parameter  dat9=4'hD; 

 parameter  dat10=4'hE; 

 parameter  dat11=5'h10; 

 parameter  nul=4'hF; 

always @(posedge clk)      

 begin 

  counter=counter+1; 

  if(counter==16'h000f)  

  clkr=~clkr; 

end 

always @(posedge clkr) 

begin 

 current=next; 

  case(current) 

set0: begin rs<=0; dat<=8'h31; next<=set1; end //*设置8位格式,2行,5*7*

set1: begin rs<=0; dat<=8'h0C; next<=set2; end //*整体显示,关光标,不闪烁*/  

set2: begin rs<=0; dat<=8'h6; next<=set3; end //*设定输入方式,增量不移位*/  

set3: begin rs<=0; dat<=8'h1; next<=dat0; end //*清除显示*/    

    //上面是LCD的初始化

dat0: begin rs<=1; dat<=8'h3C; next<=dat1; end

dat1: begin rs<=1; dat<="F"; next<=dat2; end

dat2: begin rs<=1; dat<="P"; next<=dat3; end

dat3: begin rs<=1; dat<="G"; next<=dat4; end

dat4: begin rs<=1; dat<="A"; next<=dat5; end

dat5: begin rs<=1; dat<=8'h3E; next<=dat6; end

dat6: begin rs<=1; dat<="G"; next<=dat7; end

dat7: begin rs<=1; dat<="O"; next<=dat8; end

dat8: begin rs<=1; dat<="O"; next<=dat9; end

dat9: begin rs<=1; dat<="D"; next<=dat10; end

dat10: begin rs<=1; dat<="!"; next<=dat11; end

dat11: begin rs<=1; dat<="!"; next<=nul; end

    //上面是在这12个状态中要显示的字符 FPGA GOOD!!

nul: begin rs<=0; dat<=8'h00; //行一遍 然后 把液晶的E 脚 拉高 

              if(cnt!=2'h2)  

                  begin  

e<=0;next<=set0;cnt<=cnt+1;

                  end  

                   else  

begin next<=nul; e<=1;

                    end    

              end 

   default:   next=set0; 

    endcase 

 end 

assign en=clkr|e; 

assign rw=0; 

endmodule  

LCD128显示汉字

//利用VHDL驱动LCD128

//视频教程适合我们21EDA电子的所有学习板)

//本实验是用LCD128显示汉字。(LCD带字库)

module  LCD128 (clk, rs, rw, en,dat);  

input clk;           //系统时钟输入50M

 output [7:0] dat;   //LCD的8位数据口

 output  rs,rw,en;   //LCD的控制脚

 reg e; 

 reg [7:0] dat; 

 reg rs;   

 reg  [15:0] counter; 

 reg [6:0] current,next; 

 reg clkr; 

 reg [1:0] cnt; 

 parameter  set0=6'h0; 

 parameter  set1=6'h1; 

 parameter  set2=6'h2; 

 parameter  set3=6'h3; 

 parameter  set4=6'h4; 

 parameter  set5=6'h5;

 parameter  set6=6'h6;  

 parameter  dat0=6'h7; 

 parameter  dat1=6'h8; 

 parameter  dat2=6'h9; 

 parameter  dat3=6'hA; 

 parameter  dat4=6'hB; 

 parameter  dat5=6'hC;

 parameter  dat6=6'hD; 

 parameter  dat7=6'hE; 

 parameter  dat8=6'hF; 

 parameter  dat9=6'h10;

 parameter  dat10=6'h12; 

 parameter  dat11=6'h13; 

 parameter  dat12=6'h14; 

 parameter  dat13=6'h15; 

 parameter  dat14=6'h16; 

 parameter  dat15=6'h17;

 parameter  dat16=6'h18; 

 parameter  dat17=6'h19; 

 parameter  dat18=6'h1A; 

 parameter  dat19=6'h1B; 

 parameter  dat20=6'h1C;

 parameter  dat21=6'h1D; 

 parameter  dat22=6'h1E; 

 parameter  dat23=6'h1F; 

 parameter  dat24=6'h20; 

 parameter  dat25=6'h21; 

 parameter  dat26=6'h22; 

 parameter  dat27=6'h23; 

 parameter  dat28=6'h24; 

 parameter  dat29=6'h25; 

 parameter  dat30=6'h26; 

 parameter  dat31=6'h27; 

 parameter  dat32=6'h28; 

 parameter  dat33=6'h29; 

 parameter  dat34=6'h2A; 

 parameter  dat35=6'h2B;

 parameter  dat36=6'h2C; 

 parameter  dat37=6'h2E; 

 parameter  dat38=6'h2F; 

 parameter  dat39=6'h30;

 parameter  dat40=6'h31; 

 parameter  dat41=6'h32; 

 parameter  dat42=6'h33; 

 parameter  dat43=6'h34; 

 parameter  nul=6'h35; 

always @(posedge clk)         //da de shi zhong pinlv 

 begin 

  counter=counter+1; 

  if(counter==16'h000f)  

  clkr=~clkr; 

end 

always @(posedge clkr) 

begin 

 current=next; 

  case(current) 

set0: begin rs<=0; dat<=8'h31; next<=set1; end //*设置8位格式,2行,5*7*

set1: begin rs<=0; dat<=8'h0C; next<=set2; end //*整体显示,关光标,不闪烁*/  

set2: begin rs<=0; dat<=8'h6; next<=set3; end //*设定输入方式,增量不移位*/  

set3: begin rs<=0; dat<=8'h1; next<=dat0; end //*清除显示*/  

dat0: begin rs<=1; dat<=8'hc9; next<=dat1; end //显示第一行

dat1: begin rs<=1; dat<=8'hee; next<=dat2; end

dat2: begin rs<=1; dat<=8'hdb; next<=dat3; end

dat3: begin rs<=1; dat<=8'hda;next<=dat4; end

dat4: begin rs<=1; dat<=8'hca; next<=dat5; end

dat5: begin rs<=1; dat<=8'hd0; next<=dat6; end

dat6: begin rs<=1; dat<="2"; next<=dat7; end

dat7: begin rs<=1; dat<="1";next<=dat8; end

dat8: begin rs<=1; dat<="E"; next<=dat9; end

dat9: begin rs<=1; dat<="D";next<= dat10 ; end

dat10: begin rs<=1; dat<=8'hB5; next<=dat11; end

dat11: begin rs<=1; dat<=8'hE7; next<=dat12; end

dat12: begin rs<=1; dat<=8'hd7;next<=dat13; end

dat13: begin rs<=1; dat<=8'hd3; next<=set4; end

set4: begin rs<=0; dat<=8'h90; next<=dat14; end //显示第二行

dat14: begin rs<=1; dat<="C"; next<=dat15; end

dat15: begin rs<=1; dat<="P"; next<=dat16; end

dat16: begin rs<=1; dat<="L"; next<=dat17; end

dat17: begin rs<=1; dat<="D"; next<=dat18; end

dat18: begin rs<=1; dat<="-"; next<=dat19; end

dat19: begin rs<=1; dat<="2"; next<=dat20; end

dat20: begin rs<=1; dat<="1"; next<=dat21; end

dat21: begin rs<=1; dat<="E"; next<=dat22; end

dat22: begin rs<=1; dat<="D"; next<=dat23; end

dat23: begin rs<=1; dat<="A"; next<=dat24 ; end

dat24: begin rs<=1; dat<=8'hbf; next<=dat25; end

dat25: begin rs<=1; dat<=8'haa; next<=dat26; end

dat26: begin rs<=1; dat<=8'hb7; next<=dat27; end

dat27: begin rs<=1; dat<=8'ha2; next<=dat28; end

dat28: begin rs<=1; dat<=8'hb0; next<=dat29; end

dat29: begin rs<=1; dat<=8'he5; next<=set5 ; end

set5: begin rs<=0; dat<=8'h88; next<=dat30; end //显示第三行

dat30: begin rs<=1; dat<="L"; next<=dat31; end

dat31: begin rs<=1; dat<="C"; next<=dat32; end

dat32: begin rs<=1; dat<="D"; next<=dat33; end

dat33: begin rs<=1; dat<="-"; next<=dat34; end

dat34: begin rs<=1; dat<=8'hbf; next<=dat35; end

dat35: begin rs<=1; dat<=8'hd8; next<=dat36; end

dat36: begin rs<=1; dat<=8'hd6; next<=dat37; end

dat37: begin rs<=1; dat<=8'hc6; next<=set6; end

set6: begin rs<=0; dat<=8'h9C; next<=dat38; end //显示第四行

dat38: begin rs<=1; dat<="G"; next<=dat39; end

dat39: begin rs<=1; dat<="O"; next<=dat40; end

dat40: begin rs<=1; dat<="O"; next<=dat41; end

dat41: begin rs<=1; dat<="D"; next<=dat42; end

dat42: begin rs<=1; dat<="!"; next<=dat43; end

dat43: begin rs<=1; dat<="!"; next<=nul; end

nul: begin rs<=0; dat<=8'h00; // 把液晶的E 脚 拉高 

              if(cnt!=2'h2)  

                  begin  

e<=0;next<=set0;cnt<=cnt+1;

                  end  

                   else  

begin next<=nul; e<=1;

                    end    

              end 

   default:   next=set0; 

    endcase 

 end 

assign en=clkr|e; 

assign rw=0; 

endmodule  

LED花样流水灯

//LED流水灯试验

//利用分频计数器得到显示流水灯的效果

module ledwater (clk_50M,rst,dataout);

input clk_50M,rst;     //系统时钟50M输入 从12脚输入。

output [11:0] dataout;  //我们这里用12个LED灯,

reg [11:0] dataout;

reg [27:0] count; //分频计数器

//分频计数器

always @ ( posedge clk_50M )

 begin

count<=count+1;

 end

always @ ( posedge clk_50M or negedge rst)

 begin

  case ( count[27:24] )

  //  case ( count[25:22] )这一句希望初学者看明白,

  //  也是分频的关键

  //  只有在0的那一位 对应的LED灯才亮。

0: dataout<=12'b111000111000;

1: dataout<=12'b000111000111;

2: dataout<=12'b110110110110;

3: dataout<=12'b101101101101;

4: dataout<=12'b011011011011;

5: dataout<=12'b000000000000;

6: dataout<=12'b010000010000;

7: dataout<=12'b111000111000;

8: dataout<=12'b111101111101;

9: dataout<=12'b111111111111;

10: dataout<=12'b111101111101;

11:dataout<=12'b111000111000;

12:dataout<=12'b010000010000;

13:dataout<=12'b000000000000;

14:dataout<=12'b111110000011;

15:dataout<=12'b000011111110;

  endcase

 end

endmodule

PWM+LED

//学习PWM原理,

//拨码开关的 1 2 3 4 5 6 7 8作为输入

//本实验采用拨码开关来控制LED灯的亮暗

//当然如果你的学习板没有拨码开关,可以用key1 key2 key3 key4 作为输入。

//视频教程适合我们21EDA电子的所有学习板

module pwm(

       switch,

       clk,

       led0

         ); 

input clk;          //系统时钟输入50M           

input [7:0]switch;  //拨码开关的 1 2 3 4 5 6 7 8作为输入

output led0;        //LED灯输出显示亮暗强度

reg led0; 

reg [7:0]counter; 

always @(posedge clk) 

begin 

  counter=counter+1; 

if(counter>=switch)

    led0=0; 

  else 

    led0=1;           

end 

endmodule   

按键与数码管显示

//学习按键识别,FPGA检测 

//key1 key2 key3 key4的状态作为数据输入,数码管作为状态显示

//视频教程适合我们21EDA电子的所有学习板

module key_led(clk_50M,key,duan_ma,wei_ma);

input clk_50M;         //系统时钟50M输入 从12脚输入。

input [3:0] key;       //key1 key2 key3 key4为输入的键码的值

output [3:0] wei_ma;   //数码管的位选

output [7:0] duan_ma;  //数码管的段码ABCDEFGH

wire [3:0] key;

reg [7:0] duan_ma;

reg [3:0] wei_ma;

reg [3:0] key_temp;  //设置了一个寄存器

always @ (posedge clk_50M )

begin

key_temp<=key; //把键码的值赋给寄存器

case ( key_temp )

4'b1110:duan_ma<=8'b1111_1001; //段码//KEY1按下去显示1

4'b1101:duan_ma<=8'b1010_0100; //段码//KEY2按下去显示2

4'b1011:duan_ma<=8'b1011_0000; //段码//KEY3按下去显示3

4'b0111:duan_ma<=8'b1001_1001; //段码//KEY4按下去显示4

endcase

end

always @ ( posedge clk_50M )

begin

case( key_temp )

4'b0111:wei_ma<=4'b0111; //位选信号

4'b1011:wei_ma<=4'b1011;

4'b1101:wei_ma<=4'b1101;

4'b1110:wei_ma<=4'b1110;

endcase

end

endmodule

拨码开关_LED

//拨码开关的 1 2 3 4 5 6 7 8作为输入

//本实验采用拨码开关来控制LED灯

//当然如果你的学习板没有拨码开关,可以用key1 key2 key3 key4 作为输入。

//视频教程适合我们21EDA电子的所有学习板

module led(

        switch,

        led

        );                        // 模块名led

input    [7:0]     switch;            //拨码开关

output    [7:0]    led;            //LED灯输出显示

assign led =switch;            //把拨码开关的数据在LED灯上面显示

endmodule

还没弄懂

除法器

//两个3位二进制数的除法,结果(整数商)输出到数码管显示

module div(a,b,c,en);

input[2:0] a,b;//a 被除数,b 除数

output[7:0] c;

reg[7:0] c;

output[7:0] en;

reg[3:0] c_tmp;//商(整数部分)

reg[2:0] temp_reg;//计算的中间结果寄存器

integer i;

assign en=0;

always@(a or b or temp_reg)

begin

    temp_reg=0;

    c_tmp=0;

    if(b==0)

        c_tmp=4'he;

    else begin

     if(a[2]>=b) begin

            c_tmp[2]=1;

            temp_reg[2]=a[2]-b;

         end

        else begin

            c_tmp[2]=0;

            temp_reg[2]=a[2];

         end

     if({temp_reg[2],a[1]}>=b) begin

            c_tmp[1]=1;

            temp_reg[2:1]={temp_reg[2],a[1]}-b;

         end

        else begin

            c_tmp[1]=0;

            temp_reg[2:1]={temp_reg[2],a[1]};

         end

     if({temp_reg[2:1],a[0]}>=b) begin

            c_tmp[0]=1;

            temp_reg=0;

         end

        else begin

            c_tmp[0]=0;

            temp_reg=0;

        end

     end

end    

always@(c_tmp)

begin

    case(c_tmp)

        4'b0000:

            c=8'b11000000;

        4'b0001:

            c=8'b11111001;

        4'b0010:

            c=8'b10100100;

        4'b0011:

            c=8'b10110000;

        4'b0100:

            c=8'b10011001;

        4'b0101:

            c=8'b10010010;

        4'b0110:

            c=8'b10000010;

        4'b0111:

            c=8'b11111000;

        4'b1000:

            c=8'b10000000;

        4'b1001:

            c=8'b10010000;

        4'b1010:

            c=8'b10001000;

        4'b1011:

            c=8'b10000011;

        4'b1100:

            c=8'b11000110;

        4'b1101:

            c=8'b10100001;

        4'b1110:

            c=8'b10000110;

        4'b1111:

            c=8'b10001110;

     endcase

end

endmodule

串口与电脑通信

//本模块的功能是验证实现和PC机进行基本的串口通信的功能。需要在

//PC机上安装一个串口调试工具来验证程序的功能。

//程序实现了一个收发一帧10个bit(即无奇偶校验位)的串口控

//制器,10个bit是1位起始位,8个数据位,1个结束

//位。串口的波特律由程序中定义的div_par参数决定,更改该参数可以实

//现相应的波特率。程序当前设定的div_par 的值是0x145,对应的波特率是

//9600。用一个8倍波特率的时钟将发送或接受每一位bit的周期时间

//划分为8个时隙以使通信同步.

//程序的工作过程是:串口处于全双工工作状态,按动key1,FPGA向PC发送“21 EDA"

//字符串(串口调试工具设成按ASCII码接受方式);PC可随时向FPGA发送0-F的十六进制

//数据,FPGA接受后显示在7段数码管上。

//视频教程适合我们21EDA电子的所有学习板

module serial(clk,rst,rxd,txd,en,seg_data,key_input,lowbit);

input clk,rst;

input rxd;//串行数据接收端

input key_input;//按键输入

output[7:0] en;

output[7:0] seg_data;

reg[7:0] seg_data;

output txd;//串行数据发送端

output lowbit;

// 没弄明白

////////////////////inner reg////////////////////

reg[15:0] div_reg;//分频计数器,分频值由波特率决定。分频后得到频率8倍波特率的时钟

reg[2:0]  div8_tras_reg;//该寄存器的计数值对应发送时当前位于的时隙数

reg[2:0]  div8_rec_reg;//该寄存器的计数值对应接收时当前位于的时隙数

reg[3:0] state_tras;//发送状态寄存器

reg[3:0] state_rec;//接受状态寄存器

reg clkbaud_tras;//以波特率为频率的发送使能信号

reg clkbaud_rec;//以波特率为频率的接受使能信号

reg clkbaud8x;//以8倍波特率为频率的时钟,它的作用是将发送或接受一个bit的时钟周期分为8个时隙

reg recstart;//开始发送标志

reg recstart_tmp;

reg trasstart;//开始接受标志

reg rxd_reg1;//接收寄存器1

reg rxd_reg2;//接收寄存器2,因为接收数据为异步信号,故用两级缓存

reg txd_reg;//发送寄存器

reg[7:0] rxd_buf;//接受数据缓存

reg[7:0] txd_buf;//发送数据缓存

reg[2:0] send_state;//每次按键给PC发送"Welcome"字符串,这是发送状态寄存器

reg[19:0] cnt_delay;//延时去抖计数器

reg start_delaycnt;//开始延时计数标志

reg key_entry1,key_entry2;//确定有键按下标志

////////////////////////////////////////////////

parameter div_par=16'h145;//分频参数,其值由对应的波特率计算而得,按此参数分频的时钟频率是波倍特率的8    

          //倍,此处值对应9600的波特率,即分频出的时钟频率是9600*8  (CLK  50M)

////////////////////////////////////////////////

assign txd=txd_reg;

assign lowbit=0;

assign en=0;//7段数码管使能信号赋值

always@(posedge clk )

begin

    if(!rst) begin 

     cnt_delay<=0;

     start_delaycnt<=0;

     end

    else if(start_delaycnt) begin

        if(cnt_delay!=20'd800000) begin

         cnt_delay<=cnt_delay+1;

         end

        else begin

         cnt_delay<=0;

         start_delaycnt<=0;

         end

     end

    else begin

        if(!key_input&&cnt_delay==0)

             start_delaycnt<=1;

     end

end

always@(posedge clk)

begin

    if(!rst) 

     key_entry1<=0;

    else begin

        if(key_entry2)

         key_entry1<=0;

        else if(cnt_delay==20'd800000) begin

            if(!key_input)

             key_entry1<=1;

         end

     end

end

always@(posedge clk )

begin

    if(!rst)

     div_reg<=0;

    else begin

        if(div_reg==div_par-1)

         div_reg<=0;

        else

         div_reg<=div_reg+1;

     end

end

always@(posedge clk)//分频得到8倍波特率的时钟

begin

    if(!rst)

     clkbaud8x<=0;

    else if(div_reg==div_par-1)

     clkbaud8x<=~clkbaud8x;

end

always@(posedge clkbaud8x or negedge rst)

begin

    if(!rst)

     div8_rec_reg<=0;

    else if(recstart)//接收开始标志

     div8_rec_reg<=div8_rec_reg+1;//接收开始后,时隙数在8倍波特率的时钟下加1循环

end

always@(posedge clkbaud8x or negedge rst)

begin

    if(!rst)

     div8_tras_reg<=0;

    else if(trasstart)

     div8_tras_reg<=div8_tras_reg+1;//发送开始后,时隙数在8倍波特率的时钟下加1循环

end

always@(div8_rec_reg)

begin

    if(div8_rec_reg==7)

        clkbaud_rec=1;//在第7个时隙,接收使能信号有效,将数据打入

    else

        clkbaud_rec=0;

end

always@(div8_tras_reg)

begin

    if(div8_tras_reg==7)

        clkbaud_tras=1;//在第7个时隙,发送使能信号有效,将数据发出

    else

        clkbaud_tras=0;

end

always@(posedge clkbaud8x or negedge rst)

begin

    if(!rst) begin

     txd_reg<=1;

     trasstart<=0;

     txd_buf<=0;

     state_tras<=0;

     send_state<=0;

     key_entry2<=0;

     end

    else begin

        if(!key_entry2) begin

            if(key_entry1) begin

             key_entry2<=1;

             txd_buf<=8'd50; //"2"

             end

         end

        else  begin

            case(state_tras)

                4'b0000: begin  //发送起始位

                 if(!trasstart&&send_state<7)

                     trasstart<=1;

                 else if(send_state<7) begin

                        if(clkbaud_tras) begin

                         txd_reg<=0;

                         state_tras<=state_tras+1;

                         end

                     end

                    else begin

                     key_entry2<=0;

                     state_tras<=0;

                     end                    

                end        

                4'b0001: begin //发送第1位

                    if(clkbaud_tras) begin

                     txd_reg<=txd_buf[0];

                     txd_buf[6:0]<=txd_buf[7:1];

                     state_tras<=state_tras+1;

                     end

                 end

                4'b0010: begin //发送第2位

                    if(clkbaud_tras) begin

                     txd_reg<=txd_buf[0];

                     txd_buf[6:0]<=txd_buf[7:1];

                     state_tras<=state_tras+1;

                     end

                 end

                 4'b0011: begin //发送第3位

                     if(clkbaud_tras) begin

                     txd_reg<=txd_buf[0];

                     txd_buf[6:0]<=txd_buf[7:1];

                     state_tras<=state_tras+1;

                     end

                 end

                4'b0100: begin //发送第4位

                    if(clkbaud_tras) begin

                     txd_reg<=txd_buf[0];

                     txd_buf[6:0]<=txd_buf[7:1];

                     state_tras<=state_tras+1;

                     end

                 end

                4'b0101: begin //发送第5位

                    if(clkbaud_tras) begin

                     txd_reg<=txd_buf[0];

                     txd_buf[6:0]<=txd_buf[7:1];

                     state_tras<=state_tras+1;

                     end

                 end

                4'b0110: begin //发送第6位

                    if(clkbaud_tras) begin

                     txd_reg<=txd_buf[0];

                     txd_buf[6:0]<=txd_buf[7:1];

                     state_tras<=state_tras+1;

                     end

                 end

                4'b0111: begin //发送第7位

                    if(clkbaud_tras) begin

                     txd_reg<=txd_buf[0];

                     txd_buf[6:0]<=txd_buf[7:1];

                     state_tras<=state_tras+1;

                     end

                 end

                4'b1000: begin //发送第8位

                    if(clkbaud_tras) begin

                     txd_reg<=txd_buf[0];

                     txd_buf[6:0]<=txd_buf[7:1];

                     state_tras<=state_tras+1;

                     end

                 end

                4'b1001: begin //发送停止位

                    if(clkbaud_tras) begin

                     txd_reg<=1;

                     txd_buf<=8'h55;

                     state_tras<=state_tras+1;

                     end

                 end

                4'b1111:begin 

                    if(clkbaud_tras) begin

                     state_tras<=state_tras+1;

                     send_state<=send_state+1;

                     trasstart<=0;

                        case(send_state)

                            3'b000:

                             txd_buf<=8'd49;//"1"

                            3'b001:

                             txd_buf<=8'd32;//" "

                            3'b010:

                             txd_buf<=8'd69;//"E"

                            3'b011:

                             txd_buf<=8'd68;//"D"

                            3'b100:

                             txd_buf<=8'd65;//"A"

                            3'b101:

                             txd_buf<=8'd10;//"e"

                            default:

                             txd_buf<=0;

                         endcase

                     end

                 end

                default: begin

                    if(clkbaud_tras) begin

                     state_tras<=state_tras+1;

                     trasstart<=1;

                     end

                 end

             endcase

         end

     end

end

always@(posedge clkbaud8x or negedge rst)//接受PC机的数据

begin

    if(!rst) begin

     rxd_reg1<=0;

     rxd_reg2<=0;

     rxd_buf<=0;

     state_rec<=0;

     recstart<=0;

     recstart_tmp<=0;

     end

    else  begin

     rxd_reg1<=rxd;

     rxd_reg2<=rxd_reg1;

         if(state_rec==0) begin

             if(recstart_tmp==1) begin

              recstart<=1;

              recstart_tmp<=0;

             state_rec<=state_rec+1;

                end

              else if(!rxd_reg1&&rxd_reg2) //检测到起始位的下降沿,进入接受状态

             recstart_tmp<=1;

           end

     else if(state_rec>=1&&state_rec<=8) begin

              if(clkbaud_rec) begin

              rxd_buf[7]<=rxd_reg2;

             rxd_buf[6:0]<=rxd_buf[7:1];

             state_rec<=state_rec+1;

              end

          end

         else if(state_rec==9) begin

             if(clkbaud_rec) begin

              state_rec<=0;

             recstart<=0;

             end

          end

      end

end

always@(rxd_buf) //将接受的数据用数码管显示出来

begin

      case (rxd_buf)

        8'h30:

            seg_data=8'b11000000;

        8'h31:

            seg_data=8'b11111001;

        8'h32:

            seg_data=8'b10100100;

        8'h33:

            seg_data=8'b10110000;

        8'h34:

            seg_data=8'b10011001;

        8'h35:

            seg_data=8'b10010010;

        8'h36:

            seg_data=8'b10000010;

        8'h37:

            seg_data=8'b11111000;

        8'h38:

            seg_data=8'b10000000;

        8'h39:

            seg_data=8'b10010000;

        8'h41:

            seg_data=8'b10001000;//a

        8'h42:

            seg_data=8'b10000011;

        8'h43:

            seg_data=8'b11000110;

        8'h44:

            seg_data=8'b10100001;

        8'h45:

            seg_data=8'b10000110;

        8'h46:

            seg_data=8'b10001110;

        default:

            seg_data=8'b11111111;

     endcase

end    

endmodule

点阵显示爱心形

//本实验学习点阵模块的使用

//其实原理和使用动态数码管的原理一样的

//在点阵上面显示一个爱心

//视频教程适合我们21EDA电子的所有学习板

module led_0_7 (clk,rst,dataout,en);

input clk,rst;         //系统时钟50M输入 从12脚输入。

output[7:0] dataout;   //数码管的段码输出

output[7:0] en;       //数码管的位选使能输出

reg[7:0] dataout;     

reg[7:0] en;

reg[15:0] cnt_scan;//扫描频率计数器

reg[4:0] dataout_buf;

always@(posedge clk or negedge  rst)

begin

    if(!rst) begin

     cnt_scan<=0;

        

     end

    else begin

     cnt_scan<=cnt_scan+1;

        end

end

always @(cnt_scan)

begin

   case(cnt_scan[15:13])

       3'b000 :

          en = 8'b1111_1110;

       3'b001 :

          en = 8'b1111_1101;

       3'b010 :

          en = 8'b1111_1011;

       3'b011 :

          en = 8'b1111_0111;

       3'b100 :

          en = 8'b1110_1111;

       3'b101 :

          en = 8'b1101_1111;

       3'b110 :

          en = 8'b1011_1111;

       3'b111 :

          en = 8'b0111_1111;

       default :

          en = 8'b1111_1110;

    endcase

end

always@(en) //对应COM信号给出各段数据

begin

    case(en)

        8'b1111_1110:

            dataout_buf=0;

        8'b1111_1101:

            dataout_buf=1;

        8'b1111_1011:

            dataout_buf=2;

        8'b1111_0111:

            dataout_buf=3;    

        8'b1110_1111:

            dataout_buf=4;

        8'b1101_1111:

            dataout_buf=5;

        8'b1011_1111:

            dataout_buf=6;

        8'b0111_1111:

            dataout_buf=7;

        default: 

            dataout_buf=8;

     endcase

end

always@(dataout_buf)

begin

//在点阵上面显示一个爱心需要的点阵代码

    case(dataout_buf)

        4'b0000:

            dataout=8'b11111111;

        4'b0001:

            dataout=8'b11111111;

        4'b0010:

            dataout=8'b10011001;

        4'b0011:

            dataout=8'b01100110;

        4'b0100:

            dataout=8'b01111110;

        4'b0101:

            dataout=8'b10111101;

        4'b0110:

            dataout=8'b11011011;

        4'b0111:

            dataout=8'b11100111;

     endcase

end

endmodule

多路选择器

//学习多路选择器的原理,

//拨码开关的 4     作为A的输入

//多路选择器,a为1则选择b,为0则选择c,

//拨码开关的 1 2 3 作为B的输入

//拨码开关的 6 7 8 作为C的输入

//结果输出到数码管显示

//当然如果你的学习板没有拨码开关,可以用key1 key2 key3 key4 作为输入。

//视频教程适合我们21EDA电子的所有学习板

module mux(a,b,c,d,en);

input a;        //拨码开关的 4     作为A的输入

                //多路选择器,a为1则选择b,为0则选择c

input[2:0]b;    //拨码开关的 1 2 3 作为B的输入

input[2:0]c;    //拨码开关的 6 7 8 作为C的输入

output[7:0] d;  //7段码显示的段码

reg[7:0] d;

output en;

wire[3:0] d_tmp;

assign en=0;

assign d_tmp=a? b:c;

always@(d_tmp)

begin

//下面是7段码显示的段码

    case(d_tmp)

        4'b0000:

            d=8'b11000000;

        4'b0001:

            d=8'b11111001;

        4'b0010:

            d=8'b10100100;

        4'b0011:

            d=8'b10110000;

        4'b0100:

            d=8'b10011001;

        4'b0101:

            d=8'b10010010;

        4'b0110:

            d=8'b10000010;

        4'b0111:

            d=8'b11111000;

        4'b1000:

            d=8'b10000000;

        4'b1001:

            d=8'b10010000;

        4'b1010:

            d=8'b10001000;

        4'b1011:

            d=8'b10000011;

        4'b1100:

            d=8'b11000110;

        4'b1101:

            d=8'b10100001;

        4'b1110:

            d=8'b10000110;

        4'b1111:

            d=8'b10001110;

     endcase

end

endmodule

// 没弄明白

二进制转BCD码

4位二进制数转BCD码,由键盘输入,结果由数码管显示

module bcd (clk,a,c,en )

input clk;

input [3:0] a ;

output[7:0] c ;

reg [7:0] c ;

output[1:0] en ;

reg[1:0] en;

reg[7:0] code_data;

reg[3:0] c_tmp;

reg[19:0] cnt;

always@(posedge clk ) 

begin

    if(cnt!=20'h5ffff)

     cnt<=cnt+1;

    else

     cnt<=0;

end

always@(posedge clk )

begin

        if(cnt==20'h5ffff)

     en<=~en;

     end

always@(en)

begin

    case(en)

        2'b01:

            c_tmp=code_data[3:0];

        2'b10:

            c_tmp=code_data[7:4];

        default:

            c_tmp=0;

     endcase

end

        

always @(a) //转化过程

begin

    case (a[3:0]) 

        3'b0000 : code_data [7:1] = 7'b0000000;

        3'b0001 : code_data [7:1] = 7'b0000001;

        3'b0010 : code_data [7:1] = 7'b0000010;

        3'b0011 : code_data [7:1] = 7'b0000011;

        3'b0100 : code_data [7:1] = 7'b0000100;

        3'b0101 : code_data [7:1] = 7'b0001000;

        3'b0110 : code_data [7:1] = 7'b0001001;

        3'b0111 : code_data [7:1] = 7'b0001010;

        default : code_data [7:1] = 7'b0000000;

     endcase

    code_data[0] = a[0];

end

always@(c_tmp)

begin

    case(c_tmp)

        4'b0000:

            c=8'b1100_0000;

        4'b0001:

            c=8'b1111_1001;

        4'b0010:

            c=8'b1010_0100;

        4'b0011:

            c=8'b1011_0000;

        4'b0100:

            c=8'b1001_1001;

        4'b0101:

            c=8'b1001_0010;

        4'b0110:

            c=8'b1000_0010;

        4'b0111:

            c=8'b1111_1000;

        4'b1000:

            c=8'b1000_0000;

        4'b1001:

            c=8'b1001_1000;

        4'b1010:

            c=8'b1000_1000;

        4'b1011:

            c=8'b1000_0011;

        4'b1100:

            c=8'b1100_0110;

        4'b1101:

            c=8'b1010_0001;

        4'b1110:

            c=8'b1000_0110;

        4'b1111:

            c=8'b1000_1110;

     endcase

end

endmodule

分频1秒和0.5秒

//利用计数器分频

//利用分频计数器得到显示一秒和0.5的闪烁效果

//视频教程适合我们21EDA电子的所有学习板

module ledwater (clk_50M,led_out,f_led_out);

input   clk_50M;              //系统时钟输入50M

output  led_out;

output  f_led_out;

reg [24:0] count;  //分频计数器,25000000分频 一秒

reg [24:0] f_count;//分频计数器,12500000分频 0.5秒

reg  div_clk, f_div_clk;

reg  led_out, f_led_out;

//分频计数器。得到一秒的频率

always @ ( posedge clk_50M )

begin

if ( count==25000000 )

 begin

div_clk<=~div_clk;

count<=0;

  end

else

count<=count+1;

led_out<=~div_clk;

end

//分频计数器。得到0.5秒的频率

always @ ( posedge clk_50M )

begin

if ( f_count==12500000 )

 begin

f_div_clk<=~f_div_clk;

f_count<=0;

  end

else

f_count<=f_count+1;

f_led_out<=~f_div_clk;

end

endmodule

简单状态机控制步进电机

//简单的状态机,利用状态机控制步进电机

//state0--state1--state2--state3--state4--state5--state6-state7--state0

//视频教程适合我们21EDA电子的所有学习板

module state_machine(clk,rst,c);

input clk,rst;    //系统时钟50M输入 从12脚输入。

output [3:0] c;   //输出控制步进电机

reg    [3:0] c;

parameter state0=3'b000,

          state1=3'b001,

          state2=3'b010,

          state3=3'b011,

          state4=3'b100,

          state5=3'b101,

          state6=3'b110,

          state7=3'b111;    

reg[2:0] state;

reg[23:0] cnt;

always@(posedge clk or negedge rst)

begin

    if(!rst) begin

     state<=state0;

     cnt<=0;

     end

    else begin

     cnt<=cnt+1;

        if(cnt==24'hffffff) begin

            case(state)

                state0:

                 state<=state1;

                state1:

                 state<=state2;

                state2:

                 state<=state3;

                state3:

                 state<=state4;

                state4:

                 state<=state5;

                state5:

                 state<=state6;

                state6:

                 state<=state7;

                state7:

                 state<=state0;

             endcase

         end

     end

end

always@(state)

begin

    case(state)

        state0:

            c=8'b0001;

        state1:

            c=8'b0100;

        state2:

            c=8'b0010;

        state3:

            c=8'b1000;

        state4:

            c=8'b0001;

        state5:

            c=8'b0100;

        state6:

            c=8'b0010;

        state7:

            c=8'b1000;

     endcase

end

endmodule

矩阵键盘

矩阵键盘实验1:向用户介绍矩阵键盘扫描实现的方法,没有考虑去抖和判断键弹起的问题;把相应的键值显示在数码管上

module key1(clk,rst,row,column,dataout,en) 

input clk,rst;

input[3:0] column;//列线

output[3:0] row;//行线

output[7:0] dataout;//数码管显示数据

reg[7:0] dataout;

output[7:0] en;//数码管显示使能

reg[3:0] row;

reg[3:0] scan_key; //扫描码寄存器

reg[15:0] cnt_scan;//扫描频率计数器

assign en=0;

always@(posedge clk or negedge rst)

begin

    if(!rst) begin

     row<=4'b1110;

     cnt_scan<=0;

     end

    else begin

     cnt_scan<=cnt_scan+1;

        if(cnt_scan==16'hffff) begin

         row[3:1]<=row[2:0];//没弄明白

         row[0]<=row[3]; //4根行线循环送出低电平

         end

     end

end

always@(posedge clk or negedge rst)

begin

    if(!rst) begin

     scan_key<=0;

     end

    else begin

        case(row)  //该case结果检测何处有键按下

            4'b1110:

                case(column)

                    4'b1110: begin

                     scan_key<=0;

                     end

                    4'b1101: begin

                     scan_key<=1;

                     end

                    4'b1011: begin

                     scan_key<=2;

                     end

                    4'b0111: begin

                     scan_key<=3;

                     end

                 endcase

            4'b1101:

                case(column)

                    4'b1110: begin

                     scan_key<=4;

                     end

                    4'b1101: begin

                     scan_key<=5;

                     end

                    4'b1011: begin

                     scan_key<=6;

                     end

                    4'b0111: begin

                     scan_key<=7;

                     end

                 endcase

            4'b1011:

                case(column)

                    4'b1110: begin

                     scan_key<=8;

                     end

                    4'b1101: begin

                     scan_key<=9;

                     end

                    4'b1011: begin

                     scan_key<=10;

                     end

                    4'b0111: begin

                     scan_key<=11;

                     end

                 endcase

            4'b0111:

                case(column)

                    4'b1110: begin

                     scan_key<=12;

                     end

                    4'b1101: begin

                     scan_key<=13;

                     end

                    4'b1011: begin

                     scan_key<=14;

                     end

                    4'b0111: begin

                     scan_key<=15;

                     end

                 endcase

             default:

             scan_key<=15;

         endcase

     end

end

always@(scan_key)

begin

    case(scan_key)

        4'b0000:

         dataout<=8'b11000000;

        4'b0001:

         dataout<=8'b11111001;

        4'b0010:

         dataout<=8'b10100100;

        4'b0011:

         dataout<=8'b10110000;

        4'b0100:

         dataout<=8'b10011001;

        4'b0101:

         dataout<=8'b10010010;

        4'b0110:

         dataout<=8'b10000010;

        4'b0111:

         dataout<=8'b11111000;

        4'b1000:

         dataout<=8'b10000000;

        4'b1001:

         dataout<=8'b10010000;

        4'b1010:

         dataout<=8'b10001000;

        4'b1011:

         dataout<=8'b10000011;

        4'b1100:

         dataout<=8'b11000110;

        4'b1101:

         dataout<=8'b10100001;

        4'b1110:

         dataout<=8'b10000110;

        4'b1111:

         dataout<=8'b10001110;

     endcase

end    

endmodule        

秒表 数码管显示

//程序的思想和我们用的51单片机的思想一样

//视频教程适合我们21EDA电子的所有学习板

    module watch(clk,out_wei,out_duan,rst,key2);    //key2==27pin

    input rst;

    input clk;

    input key2;

    output [5:0]out_wei;

    output [7:0]out_duan; 

    reg [5:0]out_wei=6'b000000;

    reg [7:0]out_duan=8'b00000011;  //a b c d e f g dp

    reg [4:0]count; 

    reg [3:0]count1;

    reg [14:0]count2;

    reg [7:0]sec_l=8'b00000011;        //zero at first

    reg [7:0]sec_h=8'b00000011;

    reg [7:0]fen_l=8'b00000011;

    reg [7:0]fen_h=8'b00000011;

    reg [7:0]msec_l=8'b00000011;

    reg [7:0]msec_h=8'b00000011;

    reg [3:0]s_1=0;    

    reg [3:0]s_2=0;    

    reg [3:0]s_3=0;    

    reg [3:0]s_4=0; 

    reg [3:0]s_5=0;    

    reg [3:0]s_6=0;    

    reg clk_out; 

    reg pause;//信号

    always@(posedge clk) begin        //fenpin 

        if(count2==25000)        begin   //one of thousand secend  25000

         count2<=0;

         clk_out<=~clk_out;

        end

     else count2<=count2+1;

    end

    always@(posedge clk_out) begin        //scan

     count<=count+1'b1;

        case(count)

              1     :begin 

                     out_wei<=6'b111110;

                     out_duan<=msec_l;

                     end

             3:begin

                     out_wei<=6'b111101;

                     out_duan<=msec_h;    

                    end                    

             6:begin

                     out_wei<=6'b111011;

                     out_duan<=sec_l;

                    end

             9:begin

                     out_wei<=6'b110111;

                     out_duan<=sec_h;

                    end

             12:begin

                     out_wei<=6'b101111;

                     out_duan<=fen_l;

                    end

             15:begin

                     out_wei<=6'b011111;

                     out_duan<=fen_h;

                    end

         18:count<=0;

        endcase

    end 

    

    always@(negedge key2)  begin        

     pause<=~pause;

    end            

    always@(posedge clk_out or negedge rst) begin    //minite  secend  

        if(!rst)  begin

         s_1<=0;    

         s_2<=0;    

         s_3<=0;    

         s_4<=0;

         s_5<=0;

         s_6<=0;

        end

        else    if(count1==10)begin        //if 1s l+1 

         count1<=0;

            if(s_6==9)  begin

             s_6<=0;

                if(s_5==9)    begin

                 s_5<=0;

                    if(s_1==9)        begin  

                     s_1<=0;

                        if(s_2==5)  begin

                         s_2<=0;

                            if(s_3==9)    begin

                             s_3<=0;

                                if(s_4==5)    

                                 s_4<=0;

                                else  s_4<=s_4+1;

                            end     else s_3<=s_3+1;

                     end else s_2<=s_2+1;

                 end else s_1<=s_1+1;

             end else s_5<=s_5+1;

         end else s_6<=s_6+1;

        end

        

        else  if(pause==1)  begin 

         count1<=count1+1;

        end     

    end  

//这下面全部是扫描显示用的。

    always@(s_1 or s_2 or s_3 or s_4 or s_5 or s_6) begin 

        case(s_1)

            0:sec_l=8'b11000000;

            1:sec_l=8'b11111001;

            2:sec_l=8'b10100100;

            3:sec_l=8'b10110000;

            4:sec_l=8'b10011001;

            5:sec_l=8'b10010010;

            6:sec_l=8'b10000010;

            7:sec_l=8'b11111000;

            8:sec_l=8'b10000000;

            9:sec_l=8'b10010000;

            default:sec_l=1'bx;

        endcase 

        case(s_2)

            0:sec_h=8'b11000000;

            1:sec_h=8'b11111001;

            2:sec_h=8'b10100100;

            3:sec_h=8'b10110000;

            4:sec_h=8'b10011001;

            5:sec_h=8'b10010010;

            6:sec_h=8'b10000010;

            default:sec_h=1'bx;

        endcase

        case(s_3)

            0:fen_l=8'b11000000;

            1:fen_l=8'b11111001;

            2:fen_l=8'b10100100;

            3:fen_l=8'b10110000;

            4:fen_l=8'b10011001;

            5:fen_l=8'b01001001;

            6:fen_l=8'b10010010;

            7:fen_l=8'b10000010;

            8:fen_l=8'b10000000;

            9:fen_l=8'b10010000;

            default:fen_l=1'bx;

        endcase

        case(s_4)

            0:fen_h=8'b11000000;

            1:fen_h=8'b11111001;

            2:fen_h=8'b10100100;

            3:fen_h=8'b10110000;

            4:fen_h=8'b10011001;

            5:fen_h=8'b01001001;

            6:fen_h=8'b10010010;

            default:fen_h=1'bx;

        endcase

        case(s_6)

            0:msec_l=8'b11000000;

            1:msec_l=8'b11111001;

            2:msec_l=8'b10100100;

            3:msec_l=8'b10110000;

            4:msec_l=8'b10011001;

            5:msec_l=8'b10011001;

            6:msec_l=8'b10010010;

            7:msec_l=8'b10000010;

            8:msec_l=8'b10000000;

            9:msec_l=8'b10010000;

            default:msec_l=1'bx;

        endcase

        case(s_5)

            0:msec_h=8'b11000000;

            1:msec_h=8'b11111001;

            2:msec_h=8'b10100100;

            3:msec_h=8'b10110000;

            4:msec_h=8'b10011001;

            5:msec_h=8'b10011001;

            6:msec_h=8'b10010010;

            7:msec_h=8'b10000010;

            8:msec_h=8'b10000000;

            9:msec_h=8'b10010000;

            default:msec_h=1'bx;

        endcase

    end 

endmodule

//没弄明白

时钟_clock

.//学习数码管显示时钟原理

//视频教程适合我们21EDA电子的所有学习板

module clock(clk,key_in,sm_bit,sm_seg);                //模块名clock

input clk;                                          //输入时钟

input[1:0] key_in;                                //输入按键

output[0:7]    sm_bit;                            //数码管选择输出引脚

output[7:0] sm_seg;                            //数码管段输出引脚

reg[7:0] sm_seg_r;                                //定义数码管输出寄存器

reg[7:0] sm_bit_r;                                //定义数码管选择输出寄存器

reg[3:0] disp_dat;                            //定义显示数据寄存器

reg[24:0]count;                                //定义计数寄存器

reg[23:0]hour;                                //定义现在时刻寄存器

reg sec,keyen;                                //定义标志位

reg[1:0]dout1,dout2,dout3;                    //寄存器

wire[1:0]key_done;                            //按键消抖输出

assign sm_bit = sm_bit_r;                            //输出数码管选择

assign sm_seg = sm_seg_r;                            //输出数码管译码结果    

//秒信号产生部分

always @(posedge clk)                       //定义clock上升沿触发

begin

    count = count + 1'b1;

    if(count == 25'd25000000)                //0.5S到了吗?

    begin

        count = 25'd0;                        //计数器清零

        sec = ~sec;                        //置位秒标志

    end

end

//按键消抖处理部分

assign key_done = (dout1 | dout2 | dout3);    //按键消抖输出

always @(posedge count[17])

begin

dout1 <= key_in;

dout2 <= dout1;

dout3 <= dout2;    

end

always @(negedge key_done[0])

begin

    keyen = ~keyen;                            //将琴键开关转换为乒乓开关

end

//数码管动态扫描显示部分

always @(posedge clk)                       //count[17:15]大约1ms改变一次

begin

    case(count[17:15])                        //选择扫描显示数据

        3'd0:disp_dat = hour[3:0];            //秒个位

        3'd1:disp_dat = hour[7:4];            //秒十位

        3'd2:disp_dat = 4'ha;                //显示"-"

        3'd3:disp_dat = hour[11:8];            //分个位

        3'd4:disp_dat = hour[15:12];        //分十位

        3'd5:disp_dat = 4'ha;                //显示"-"

        3'd6:disp_dat = hour[19:16];        //时个位

        3'd7:disp_dat = hour[23:20];        //时十位

    endcase

    case(count[17:15])                        //选择数码管显示位

        3'd0:sm_bit_r = 8'b11111110;            //选择第一个数码管显示

        3'd1:sm_bit_r = 8'b11111101;            //选择第二个数码管显示

        3'd2:sm_bit_r = 8'b11111011;            //选择第三个数码管显示

        3'd3:sm_bit_r = 8'b11110111;            //选择第四个数码管显示

        3'd4:sm_bit_r = 8'b11101111;            //选择第五个数码管显示

        3'd5:sm_bit_r = 8'b11011111;            //选择第六个数码管显示

        3'd6:sm_bit_r = 8'b10111111;            //选择第七个数码管显示

        3'd7:sm_bit_r = 8'b01111111;            //选择第八个数码管显示

    endcase    

end

always @(posedge clk)

begin

    case(disp_dat)

        4'h0:sm_seg_r = 8'hc0;                    //显示0

        4'h1:sm_seg_r = 8'hf9;                    //显示1

        4'h2:sm_seg_r = 8'ha4;                    //显示2

        4'h3:sm_seg_r = 8'hb0;                    //显示3

        4'h4:sm_seg_r = 8'h99;                    //显示4

        4'h5:sm_seg_r = 8'h92;                    //显示5

        4'h6:sm_seg_r = 8'h82;                    //显示6

        4'h7:sm_seg_r = 8'hf8;                    //显示7

        4'h8:sm_seg_r = 8'h80;                    //显示8

        4'h9:sm_seg_r = 8'h90;                    //显示9

        4'ha:sm_seg_r = 8'hbf;                    //显示-

        default:sm_seg_r = 8'hff;                //不显示

    endcase

    if((count[17:15]== 3'd2)&sec)

        sm_seg_r = 8'hff;

end

//计时处理部分

always @(negedge sec or negedge key_done[1])//计时处理

begin

    if(!key_done[1])                        //是清零键吗?

    begin

        hour = 24'h0;                        //是,则清零

    end

    else if(!keyen)

    begin

        hour[3:0] = hour[3:0] + 1'b1;        //秒加1

        if(hour[3:0] == 4'ha)

        begin

            hour[3:0] = 4'h0;

            hour[7:4] = hour[7:4] + 1'b1;    //秒的十位加一

            if(hour[7:4] == 4'h6)

            begin

                hour[7:4] = 4'h0;

                hour[11:8] = hour[11:8] + 1'b1;//分个位加一

                if(hour[11:8] == 4'ha)

                begin

                    hour[11:8] = 4'h0;

                    hour[15:12] = hour[15:12] + 1'b1;//分十位加一

                    if(hour[15:12] == 4'h6)

                    begin

                        hour[15:12] = 4'h0;

                        hour[19:16] = hour[19:16] + 1'b1;//时个位加一

                        if(hour[19:16] == 4'ha)

                        begin

                            hour[19:16] = 4'h0;

                            hour[23:20] = hour[23:20] + 1'b1;//时十位加一

                        end

                        if(hour[23:16] == 8'h24)

                            hour[23:16] = 8'h0;

                    end

                end

            end

        end

    end

end

endmodule

文档

verilog HDL基础程序

涉及到需要时间的并且在不同的时间执行程序时就要用到分频计数器至于需要分频多少看需要执行多少次,也就是需要用到的时间有多少次。3-8译码器//学习38译码器的原理,//拨码开关的123作为输入//本实验采用拨码开关来作为输入,LED作为状态显示//当然如果你的学习板没有拨码开关,可以用key1key2key3作为数据输入。moduledecoder_38(out,key_in);output[7:0]out;//38译码器输出有8钟状态,所以要8个LED灯。input[2:0]key_in;//
推荐度:
  • 热门焦点

最新推荐

猜你喜欢

热门推荐

专题
Top