模块化设计是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