模块化设计是FPGA设计中一个很重要的技巧,它能够使一个大型设计的分工协作、仿真测试更加容易,是代码维护升级更加便利!

     今天弄了大半天总算学会了怎样在quartus中来进行模块化编程。接下来写的这个程序的功能是:两个按键控制数码管加减数。

   

// 程序实现的功能:
//当key1被按下时,数码管上的数加1(到9后不加了);
//当key2被按下时,数码管上的数减1(到0后不减了);
module key_smg_top
       (
        sysclk,
        rst_b,
        key1,        
        key2,         
        smg_sel,
        smg_data
        );
input       sysclk;      //系统时钟 50MHZ;
input       rst_b;       //复位信号,低电平有效;
input       key1;        //键盘按下,加1,对应硬件电路图SW5;
input       key2;        //键盘按下,减1,对应硬件电路图SW4;
output      smg_sel;     //数码管片选;
output[6:0] smg_data;    //数码管段选,不包括小数点;
wire[1:0] key_edge;
key  key(
         .sysclk(sysclk),
         .rst_b(rst_b),
         .key1(key1),
         .key2(key2),
         .key_edge(key_edge)      
        ); 

smg  smg(
        .sysclk(sysclk),
        .rst_b(rst_b),
        .key_edge(key_edge),
        .smg_sel(smg_sel),
        .smg_data(smg_data)

     );

endmodule           
// 程序实现的功能:键盘消抖
module key 
     (
      sysclk,
      rst_b,
      key1,
      key2,
      key_edge  
     );
input       sysclk;
input       rst_b;
input       key1;         //对应硬件电路图SW4;
input       key2;         //对应硬件电路图SW5;
output[1:0] key_edge;

wire         sysclk;
wire         rst_b;
wire         key1;
wire         key2;
wire[1:0]    key_edge;
//--------------------------------------------------//
reg[1:0] key;
always @ (posedge sysclk or negedge rst_b)
 begin
      if(!rst_b)
         key<=2'b11;
      else
         key<={key1,key2};     
 end

reg[1:0] key_r;
always @ (posedge sysclk or negedge rst_b)
  begin
      if(!rst_b)
        key_r<=2'b11;
      else
        key_r<=key;  
  end 

wire[1:0] key_change;
assign  key_change=key_r&(~key);
//-----------------------------------------------------//
reg[19:0]  time_cnt;
always @ (posedge sysclk or negedge rst_b)
  begin
       if(!rst_b)
          time_cnt<=20'h0;
        else if(key_change)
          time_cnt<=20'h0;
        else 
          time_cnt<=time_cnt+20'h1; 
  end
//-----------------------------------------------------//
reg[1:0] key_rst;
always @ (posedge sysclk or negedge rst_b)
 begin
       if(!rst_b)
         key_rst<=2'b11;
       else if(time_cnt==20'hfffff)
         key_rst<={key1,key2};
          
 end 
 
reg [1:0] key_rst_r;
always @ (posedge sysclk or negedge rst_b)
 begin
       if(!rst_b)
         key_rst_r<=2'b11;
       else 
         key_rst_r<=key_rst;
 end 

assign  key_edge=key_rst_r&(~key_rst);
endmodule
         
  
      
//程序实现的功能:数码管显示
module smg
     (
      sysclk,
      rst_b,
      key_edge,
      smg_sel,
      smg_data
      );
input       sysclk;
input       rst_b;
input[1:0]  key_edge;
output      smg_sel;
output[6:0] smg_data; 
//-------------------------------------------------------//
wire       sysclk;
wire       rst_b;
wire[1:0]  key_edge;
wire       smg_sel;
reg[6:0]   smg_data; 
//--------------------------------------------------------//
assign smg_sel=1'h0;
//--------------------------------------------------------// 
reg[3:0] smg_data_num;
always @(posedge sysclk or negedge rst_b  )
  begin
       if(!rst_b)
          smg_data_num<=4'h0;
       else if(key_edge[0]&&smg_data_num<4'h9)
         smg_data_num<=smg_data_num+4'h1;
       else if (key_edge[1]&&smg_data_num>4'h0)
         smg_data_num<=smg_data_num-4'h1;
       else
         smg_data_num<=smg_data_num;  
     
        
  end

always @ (*)
 begin
       case(smg_data_num)
          4'h0 :smg_data=7'b100_0000;
          4'h1: smg_data=7'b111_1001;
          4'h2: smg_data=7'b010_0100;
          4'h3: smg_data=7'b011_0000;
          4'h4: smg_data=7'b001_1001;
          4'h5: smg_data=7'b001_0010;
          4'h6: smg_data=7'b000_0010;
          4'h7: smg_data=7'b111_1000;
          4'h8: smg_data=7'b000_0000;
          4'h9: smg_data=7'b001_0000;
          default:smg_data=7'b111_1111; 
       endcase   
          
 end  
endmodule