FPGA_时钟显示(时钟可调)

1. 实验说明 

      在数码管显示数据的基础上,让六位数码管显示数字时钟,并且通过按键可以对时间进行修改。

实验目标:六位数码管分别显示时间的时分秒,且通过按键可实现加减调整时间及清零功能。
    key1: 切换键:选择待调整的时间单位(时、分、秒)
    key2: 时间加键
    key3: 时间减键
    key4: 时钟清零键

效果如下图:时钟清零——>分钟加减——>时钟加减——>时钟正常运行

2. 模块设计

FPGA_时钟显示(时钟可调)_第1张图片

各模块功能说明:

FPGA_时钟显示(时钟可调)_第2张图片

       各模块原理之前在数码管动态显示的博客中有详细说明,不理解的朋友可以移步这篇文章:

https://mp.csdn.net/mp_blog/creation/editor/127933111

3. RTL代码设计

3.1 按键消抖模块

`timescale  1ns/1ns

module  key_filter
#(
    parameter CNT_MAX = 20'd999_999 //计数器计数最大值
)
(
    input   wire            sys_clk     ,   //系统时钟50Mhz
    input   wire            sys_rst_n   ,   //全局复位
    input   wire    [3:0]   key_in      ,   //按键输入信号

    output  reg     [3:0]   key_flag        //key_flag为1时表示消抖后检测到按键被按下
                                            //key_flag为0时表示没有检测到按键被按下
);

//reg   define
reg     [19:0]  cnt_20ms0    ;   //计数器
reg     [19:0]  cnt_20ms1    ;   //计数器
reg     [19:0]  cnt_20ms2    ;   //计数器
reg     [19:0]  cnt_20ms3    ;   //计数器

//cnt_20ms:如果时钟的上升沿检测到外部按键输入的值为低电平时,计数器开始计数
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_20ms0 <= 20'b0;
    else    if(key_in[0] == 1'b1)
        cnt_20ms0 <= 20'b0;
    else    if(cnt_20ms0 == CNT_MAX && key_in[0] == 1'b0)
        cnt_20ms0 <= cnt_20ms0;
    else
        cnt_20ms0 <= cnt_20ms0 + 1'b1;

//cnt_20ms1:如果时钟的上升沿检测到外部按键输入的值为低电平时,计数器开始计数
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_20ms1 <= 20'b0;
    else    if(key_in[1] == 1'b1)
        cnt_20ms1 <= 20'b0;
    else    if(cnt_20ms1 == CNT_MAX && key_in[1] == 1'b0)
        cnt_20ms1 <= cnt_20ms1;
    else
        cnt_20ms1 <= cnt_20ms1 + 1'b1;

//cnt_20ms:如果时钟的上升沿检测到外部按键输入的值为低电平时,计数器开始计数
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_20ms2 <= 20'b0;
    else    if(key_in[2] == 1'b1)
        cnt_20ms2 <= 20'b0;
    else    if(cnt_20ms2 == CNT_MAX && key_in[2] == 1'b0)
        cnt_20ms2 <= cnt_20ms2;
    else
        cnt_20ms2 <= cnt_20ms2 + 1'b1;

//cnt_20ms:如果时钟的上升沿检测到外部按键输入的值为低电平时,计数器开始计数
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_20ms3 <= 20'b0;
    else    if(key_in[3] == 1'b1)
        cnt_20ms3 <= 20'b0;
    else    if(cnt_20ms3 == CNT_MAX && key_in[3] == 1'b0)
        cnt_20ms3 <= cnt_20ms3;
    else
        cnt_20ms3 <= cnt_20ms3 + 1'b1;

//key_flag:当计数满20ms后产生按键有效标志位
//且key_flag在999_999时拉高,维持一个时钟的高电平
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        key_flag <= 4'b0000;
    else    if(cnt_20ms3 == CNT_MAX - 1'b1)
        key_flag <= 4'b0001;      //切换 S MIN H
    else    if(cnt_20ms2 == CNT_MAX - 1'b1)
        key_flag <= 4'b0010;      //减数
    else    if(cnt_20ms1 == CNT_MAX - 1'b1)
        key_flag <= 4'b0100;      //加数
    else    if(cnt_20ms0 == CNT_MAX - 1'b1)
        key_flag <= 4'b1000;      //清零
    else
        key_flag <= 4'b0000;

endmodule

3.2 数据生成模块

`timescale  1ns/1ns

module  data_gen
#(
    parameter   cnt_1ms_MAX  =   16'd49_999 ,
	parameter   cnt_s_MAX   =    10'd999    ,
	parameter   cnt_1s_MAX   =   6'd59      ,
	parameter   cnt_1min_MAX =   6'd59      ,
	parameter   cnt_1h_MAX =     5'd23      
)
(
    input   wire            sys_clk     ,   
    input   wire            sys_rst_n   , 
    input   wire    [3:0]   key_flag    , 
	
   
    output  reg     [19:0]  data    ,   
    output  reg             seg_en  ,   
    output  wire     [5:0]  point   ,   
    output  wire            sign      
);

reg  [15:0]  cnt_1ms   ;
reg  [9:0]   cnt_s     ;
reg  [5:0]   cnt_1s    ;
reg  [5:0]   cnt_1min  ;
reg  [4:0]   cnt_1h    ;
reg  [2:0]       cnt   ;

assign     point  = 6'b010100;
assign     sign   = 1'b0;

//时分秒数值选择
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0 ||  key_flag == 4'b0001)
	    cnt <= 3'b0;
    else  if(cnt == 3'd3 && key_flag == 4'b1000)
	    cnt <= 3'd1;
    else  if(key_flag == 4'b1000) 
	    cnt <= cnt + 1'b1;
	else
    	 cnt <= cnt;
 
//1ms计数器
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0  ||  key_flag == 4'b0001)
	   	cnt_1ms <= 16'b0;
	else  if(cnt_1ms == cnt_1ms_MAX)
	    cnt_1ms <= 16'b0;
	else 
	    cnt_1ms <= cnt_1ms + 1'b1;
		
//1s计数器
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0  ||  key_flag == 4'b0001)
	    cnt_s <= 10'b0;
	else  if(cnt_s == cnt_s_MAX  &&  cnt_1ms == cnt_1ms_MAX)
	    cnt_s <= 10'b0;	
	else if(cnt_1ms == cnt_1ms_MAX)
	    cnt_s <= cnt_s + 1'b1;
	else
	    cnt_s <= cnt_s;
//60s计数器
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0  ||  key_flag == 4'b0001)
	    cnt_1s <=6'b0;
	else  if((cnt_1s == cnt_1s_MAX  &&  cnt_s == cnt_s_MAX  &&  cnt_1ms == cnt_1ms_MAX)||(cnt_1s == cnt_1s_MAX && key_flag == 4'b0100 ))  //重点1: 转换条件
	    cnt_1s <= 6'b0;
	else  if(cnt == 3'd3 && key_flag == 4'b0100)
	    cnt_1s <= cnt_1s + 1'b1;
	else  if(cnt == 3'd3 && key_flag == 4'b0010 && cnt_1s ==6'b0 )
    	cnt_1s <= cnt_1s_MAX;
	else  if(cnt == 3'd3 && key_flag == 4'b0010)
	     cnt_1s <= cnt_1s - 1'b1;
	else if(cnt_s == cnt_s_MAX &&  cnt_1ms == cnt_1ms_MAX)
	    cnt_1s <= cnt_1s + 1'b1;
	else
	    cnt_1s <= cnt_1s;
		
//1min计数器
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0  ||  key_flag == 4'b0001)
	    cnt_1min <= 6'b0;
	else  if ((cnt_1min == cnt_1min_MAX && cnt_1s == cnt_1s_MAX   &&  cnt_s == cnt_s_MAX  &&  cnt_1ms == cnt_1ms_MAX)||(cnt_1min == cnt_1min_MAX && key_flag == 4'b0100 ))
	    cnt_1min <= 6'b0;
	else  if(cnt == 3'd2 && key_flag == 4'b0100)	
		cnt_1min <= cnt_1min + 1'b1;
	else  if(cnt == 3'd2 && key_flag == 4'b0010 &&  cnt_1min == 6'b0)
	    cnt_1min <= cnt_1min_MAX;
	else  if(cnt == 3'd2 && key_flag == 4'b0010)	
		cnt_1min <= cnt_1min - 1'b1;	
    else  if(cnt_1s == cnt_1s_MAX &&  cnt_s == cnt_s_MAX  &&  cnt_1ms == cnt_1ms_MAX)
	    cnt_1min <= cnt_1min + 1'b1;
	else
	    cnt_1min <= cnt_1min;
			
//1h计数器
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0  ||  key_flag == 4'b0001)		
        cnt_1h <=  5'b0;
    else  if (( cnt_1h == cnt_1h_MAX  &&   cnt_1min == cnt_1min_MAX && cnt_1s == cnt_1s_MAX   &&  cnt_s == cnt_s_MAX  &&  cnt_1ms == cnt_1ms_MAX) ||(cnt_1h == cnt_1h_MAX && key_flag == 4'b0100 ))
        cnt_1h <= 5'b0;
	else  if(cnt == 3'd1 && key_flag == 4'b0100)
	    cnt_1h <= cnt_1h + 1'b1;
	else  if(cnt == 3'd1 && key_flag == 4'b0010 &&  cnt_1h == 5'b0)	
	      cnt_1h <= cnt_1h_MAX;
	else  if(cnt == 3'd1 && key_flag == 4'b0010)
	    cnt_1h <= cnt_1h - 1'b1;
	else  if(cnt_1min == cnt_1min_MAX && cnt_1s == cnt_1s_MAX   &&  cnt_s == cnt_s_MAX  &&  cnt_1ms == cnt_1ms_MAX)
	    cnt_1h <= cnt_1h + 1'b1;
	else
	    cnt_1h <= cnt_1h;   
		
//生产待显示数据
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)	    
        data <= 20'd0;
	else 
      data <= cnt_1h*10000 + cnt_1min*100 + cnt_1s;         //重点2: 时钟数合并
	  
//数码管使能控制		
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)	   
	    seg_en  <= 1'b0;
	else  
        seg_en  <= 1'b1;
		
endmodule
	

3.3 数码管显示驱动模块

`timescale  1ns/1ns

module  seg_dynamic
(
    input   wire            sys_clk     , 
    input   wire            sys_rst_n   , 
    input   wire    [19:0]  data        , 
    input   wire    [5:0]   point       , 
    input   wire            seg_en      , 
    input   wire            sign        , 

    output  reg     [5:0]   sel         , 
    output  reg     [7:0]   seg           
);

parameter   CNT_MAX =   16'd49_999;  

wire    [3:0]   unit        ;   //个位数
wire    [3:0]   ten         ;   //十位数
wire    [3:0]   hun         ;   //百位数
wire    [3:0]   tho         ;   //千位数
wire    [3:0]   t_tho       ;   //万位数
wire    [3:0]   h_hun       ;   //十万位数

reg     [23:0]  data_reg    ;   //待显示数据寄存器
reg     [15:0]  cnt_1ms     ;   //1ms计数器
reg             flag_1ms    ;   //1ms标志信号
reg     [2:0]   cnt_sel     ;   //数码管位选计数器
reg     [3:0]   data_disp   ;   //当前数码管显示的数据
reg             dot_disp    ;
  


/*************************   二、6毫秒计数   ************************/
//cnt_1ms:1ms循环计数
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_1ms <=  16'd0;
    else    if(cnt_1ms == CNT_MAX)
        cnt_1ms <=  16'd0;
    else
        cnt_1ms <=  cnt_1ms + 1'b1;

//cnt_sel:从0到5循环数,用于选择当前显示的数码管
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        cnt_sel <=  3'd0;
    else    if((cnt_sel == 3'd5) && (cnt_1ms == CNT_MAX))
        cnt_sel <=  3'd0;
    else    if(cnt_1ms == CNT_MAX)
        cnt_sel <=  cnt_sel + 1'b1;
    else
        cnt_sel <=  cnt_sel;
/*********************************************************************/

/********************   三、位选段选显示驱动      ********************/
//数码管位选信号驱动
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        sel <=  6'b000_000;
    else    if((cnt_sel == 3'd0) && (cnt_1ms == CNT_MAX))
        sel <=  6'b000_001;
    else    if(cnt_1ms == CNT_MAX)
        sel <=  sel << 1;
    else
        sel <=  sel;

//控制数码管的位选信号,使六个数码管轮流显示
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        data_disp    <=  4'b0;
    else    if((seg_en == 1'b1) && (cnt_1ms == CNT_MAX))
        case(cnt_sel)
        3'd0:   data_disp    <=  data_reg[3:0]  ;  //给第1个数码管赋个位值
        3'd1:   data_disp    <=  data_reg[7:4]  ;  //给第2个数码管赋十位值
        3'd2:   data_disp    <=  data_reg[11:8] ;  //给第3个数码管赋百位值
        3'd3:   data_disp    <=  data_reg[15:12];  //给第4个数码管赋千位值
        3'd4:   data_disp    <=  data_reg[19:16];  //给第5个数码管赋万位值
        3'd5:   data_disp    <=  data_reg[23:20];  //给第6个数码管赋十万位值
        default:data_disp    <=  4'b0        ;
        endcase
    else
        data_disp   <=  data_disp;

//控制数码管段选信号,显示数字
always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        seg <=  8'b1111_1111;
    else    
        case(data_disp)
            4'd0  : seg  <=  {dot_disp,7'b100_0000};    //显示数字0
            4'd1  : seg  <=  {dot_disp,7'b111_1001};    //显示数字1
            4'd2  : seg  <=  {dot_disp,7'b010_0100};    //显示数字2
            4'd3  : seg  <=  {dot_disp,7'b011_0000};    //显示数字3
            4'd4  : seg  <=  {dot_disp,7'b001_1001};    //显示数字4
            4'd5  : seg  <=  {dot_disp,7'b001_0010};    //显示数字5
            4'd6  : seg  <=  {dot_disp,7'b000_0010};    //显示数字6
            4'd7  : seg  <=  {dot_disp,7'b111_1000};    //显示数字7
            4'd8  : seg  <=  {dot_disp,7'b000_0000};    //显示数字8
            4'd9  : seg  <=  {dot_disp,7'b001_0000};    //显示数字9
            4'd10 : seg  <=  8'b1011_1111          ;    //显示负号
            4'd11 : seg  <=  8'b1111_1111          ;    //不显示任何字符
            default:seg  <=  8'b1100_0000;
        endcase
		
//dot_disp:小数点低电平点亮,需对小数点有效信号取反
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        dot_disp    <=  1'b1;
    else    if(cnt_1ms == CNT_MAX)
        dot_disp    <=  ~point[cnt_sel];
    else
        dot_disp    <=  dot_disp;
		
/*********************************************************************/
		
/***********************  一、数据处理    ****************************/

//data_reg:无效位是否以零显示
 always@(posedge sys_clk or  negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        data_reg    <=  24'b0;
//若显示的十进制数的十万位为非零数据或需显示小数点,则六个数码管全显示
    else    if((h_hun) || (point[5]))
        data_reg    <=  {h_hun,t_tho,tho,hun,ten,unit};
//若显示的十进制数的万位为非零数据或需显示小数点,则值显示在5个数码管上
    else    if(((t_tho) || (point[4])) && (sign == 1'b1))//显示负号
        data_reg <= {4'd10,t_tho,tho,hun,ten,unit};//4'd10我们定义为显示负号
    else    if(((t_tho) || (point[4])) && (sign == 1'b0))
        data_reg <= {h_hun,t_tho,tho,hun,ten,unit};//4'd11我们定义为不显示
//若显示的十进制数的千位为非零数据或需显示小数点,则值显示4个数码管
    else    if(((tho) || (point[3])) && (sign == 1'b1))
        data_reg <= {4'd11,4'd10,tho,hun,ten,unit};
    else    if(((tho) || (point[3])) && (sign == 1'b0))
        data_reg <= {h_hun,t_tho,tho,hun,ten,unit};
//若显示的十进制数的百位为非零数据或需显示小数点,则值显示3个数码管
    else    if(((hun) || (point[2])) && (sign == 1'b1))
        data_reg <= {4'd11,4'd11,4'd10,hun,ten,unit};
    else    if(((hun) || (point[2])) && (sign == 1'b0))
        data_reg <= {h_hun,t_tho,tho,hun,ten,unit};
//若显示的十进制数的十位为非零数据或需显示小数点,则值显示2个数码管
    else    if(((ten) || (point[1])) && (sign == 1'b1))
        data_reg <= {4'd11,4'd11,4'd11,4'd10,ten,unit};
    else    if(((ten) || (point[1])) && (sign == 1'b0))
        data_reg <= {h_hun,t_tho,tho,hun,ten,unit};
//若显示的十进制数的个位且需显示负号
    else    if(((unit) || (point[0])) && (sign == 1'b1))
        data_reg <= {4'd11,4'd11,4'd11,4'd11,4'd10,unit};
//若上面都不满足都只显示一位数码管
    else
        data_reg <= {h_hun,t_tho,tho,hun,ten,unit};
		
//二进制转BCD
bcd_8421    bcd_8421_inst
(
    .sys_clk     (sys_clk  ),   //系统时钟,频率50MHz
    .sys_rst_n   (sys_rst_n),   //复位信号,低电平有效
    .data        (data     ),   //输入需要转换的数据

    .unit        (unit     ),   //个位BCD码
    .ten         (ten      ),   //十位BCD码
    .hun         (hun      ),   //百位BCD码
    .tho         (tho      ),   //千位BCD码
    .t_tho       (t_tho    ),   //万位BCD码
    .h_hun       (h_hun    )    //十万位BCD码
);
/*********************************************************************/

endmodule

3.4 二进制转BCD码模块

`timescale  1ns/1ns

module  bcd_8421
(
    input   wire            sys_clk     ,   
    input   wire            sys_rst_n   , 
    input   wire    [19:0]  data        , 	
   
    output  reg     [3:0]   unit        ,   //个位BCD码
    output  reg     [3:0]   ten         ,   //十位BCD码
    output  reg     [3:0]   hun         ,   //百位BCD码
    output  reg     [3:0]   tho         ,   //千位BCD码
    output  reg     [3:0]   t_tho       ,   //万位BCD码
    output  reg     [3:0]   h_hun           //十万位BCD码
);
//wire     [19:0]     data;       //待显示的数值
reg     [4:0]   cnt_shift   ;  //操作次数计数
reg     [43:0]  data_shift  ;  //数值转换寄存器
reg             shift_flag  ;  //移位或判断标志

//assign data = 20'd520520;

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
	    cnt_shift <= 5'b0;
	else   if(shift_flag == 1'b1)    //防止在初始化时的 0值时开始加数
	    cnt_shift <= cnt_shift + 1'b1;
	else   if(shift_flag == 1'b1  && cnt_shift == 5'd21)	
	    cnt_shift <= 5'b0;
	else	
		cnt_shift <= cnt_shift;
		
always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        shift_flag  <= 1'b0;
    else  
        shift_flag  <= ~shift_flag;	

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)		
        data_shift <= 44'b0;
    else    if(cnt_shift == 5'd0)   //计数器为0时赋初值
        data_shift  <=  {24'b0,data};
	else    if((cnt_shift <= 20)&&(shift_flag == 1'b0)) //<=为小于等于,移位后判断
        begin
            data_shift[23:20]   <=  (data_shift[23:20] > 4) ?
			(data_shift[23:20] + 2'd3) : (data_shift[23:20]);
            data_shift[27:24]   <=  (data_shift[27:24] > 4) ? 
			(data_shift[27:24] + 2'd3) : (data_shift[27:24]);
            data_shift[31:28]   <=  (data_shift[31:28] > 4) ? 
			(data_shift[31:28] + 2'd3) : (data_shift[31:28]);
            data_shift[35:32]   <=  (data_shift[35:32] > 4) ?
			(data_shift[35:32] + 2'd3) : (data_shift[35:32]);
            data_shift[39:36]   <=  (data_shift[39:36] > 4) ? 
			(data_shift[39:36] + 2'd3) : (data_shift[39:36]);
            data_shift[43:40]   <=  (data_shift[43:40] > 4) ? 
			(data_shift[43:40] + 2'd3) : (data_shift[43:40]);
        end
    else    if((cnt_shift <= 20) && (shift_flag == 1'b1))
        data_shift  <=  data_shift << 1;
    else
        data_shift  <=  data_shift;

always@(posedge sys_clk or negedge sys_rst_n)
    if(sys_rst_n == 1'b0)
        begin
            unit    <=  4'b0;
            ten     <=  4'b0;
            hun     <=  4'b0;
            tho     <=  4'b0;
            t_tho   <=  4'b0;
            h_hun   <=  4'b0;
        end
    else  if ((cnt_shift == 21)  &&  (shift_flag == 1'b1))
       	    begin
       	        unit    <=  data_shift[23:20];
	            ten     <=  data_shift[27:24];
	            hun     <=  data_shift[31:28];
	            tho     <=  data_shift[35:32];
	            t_tho   <=  data_shift[39:36];
	            h_hun   <=  data_shift[43:40];
	        end
endmodule

3.5 顶层设计模块

`timescale  1ns/1ns

module top_seg_dynamic
(
    input   wire            sys_clk     , 
    input   wire            sys_rst_n   ,
    input   wire    [3:0]   key_in,
    
    output  wire     [5:0]   sel         , 
    output  wire     [7:0]   seg           
);
//各模块间的连接线
wire    [19:0]  data    ;   //数码管要显示的值
wire    [5:0]   point   ;   //小数点显示,高电平有效top_seg_595
wire            seg_en  ;   //数码管使能信号,高电平有效
wire            sign    ;   //符号位,高电平显示负号
wire    [3:0]   key_flag;

key_filter  key_filter_inst
(
   .sys_clk  (sys_clk    ),
   .sys_rst_n(sys_rst_n  ),
   .key_in   (key_in     ),
  
   .key_flag (key_flag   ) 
);
data_gen  data_gen_inst
(   
    .key_flag (key_flag   ),
    .sys_clk   (sys_clk  ) ,  
    .sys_rst_n (sys_rst_n) ,  
  
    .data      (data     ) ,   
    .seg_en    (seg_en   ) ,   
    .point     (point    ) ,   
    .sign      (sign     )   
   
);

seg_dynamic   seg_dynamic_inst
(
    .sys_clk   (sys_clk  ) ,  
    .sys_rst_n (sys_rst_n) ,  
	.data      (data  ),
    .seg_en    (seg_en),
	.point     (point ),
	.sign      (sign  ),

    .sel       (sel      ),
    .seg       (seg      )
);

endmodule

4. 总结

1. 重点学习模块:数据生成模块、数码管显示驱动模块。

2. 在写rtl代码时,重要的一个提升代码效率的方法是逐步加功能,逐步验证其正确性。

说明:

       本人学习时使用的是野火家Xilinx Spartan6系列开发板及配套教程,以上内容如有疑惑或错误欢迎评论区指出。

开发软件:ise14.7     仿真:modelsim 10.5 

如需上述资料私信或留下邮箱。

你可能感兴趣的:(FPGA_拓展练习,fpga开发)