FPGA_时钟显示(时钟可调)

2023-11-19

1. 实验说明 

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

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

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

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 

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

FPGA_时钟显示(时钟可调) 的相关文章

  • 在vivado中使用tcl脚本(UG894)

    本文源自UG894 主要介绍如何在vivado中使用tcl脚本 1 vivado中如何获取tcl help vivado中任何自带的命令都可以通过 help 获取帮助信息 也可以直接输入 help 取得vivado命令合集 并通过 help
  • STM32【复习串口】

    串口复习加深理解笔记 杂谈 USART FLAG TXE发送缓冲区空标志 说明可以往数据寄存器写入数据了 但并不代码数据发送完成了 USART FLAG TC发送完成标志 这个才是代表USART在缓冲区的数据发送完成了 即从机接收到了数据
  • 各种FIFO硬件设计(FIFO概念、异步、同步、非2次幂深度FIFO)

    文章目录 一 FIFO概述 二 FIFO分类 三 FIFO重要信号与参数 3 1 信号 3 2 参数 3 2 1 data depth的确定 四 FIFO存储原理 五 同步FIFO 5 1 空满信号判断 5 2 同步FIFO源码 5 3 测
  • 8x8LED点阵

    点量这个只需要把9高电平 13低电平就可以了 共阳极点阵 行线是led的正极 列线是led的列线 左上角点亮 显示多个灯是动态扫描的 一个一个显示的 然后间隔速度要快就可以造成显示 点阵由两篇74Hc595级联在一起驱动的 只需要三个io口
  • Verilog:【1】时钟分频电路(clk_divider.sv)

    碎碎念 作为Basic Verilog的第一个学习笔记 打算用这种命名方式来对博客进行命名 应该有助于检索 简单阅览了部分工程的代码 发现里面有很多嵌套关系 因此决定先从基础模块开始 也是为了整个博客内容的流畅性 读者朋友有问题的话 也可以
  • Verilog的奇技淫巧[更新中]

    1 Verilog常用的数据选择语句vect a b 或vect a b 转载自 MDY常用的数据选择语句Verilog明德扬论坛 Powered by Discuz vect为变量名字 a为起始位置 加号或者减号代表着升序或者降序 b是进
  • 平头哥(T-Head )开源RISCV处理器OpenC906 RTL仿真

    在过去的几年里 阿里集团平头哥陆续推出了几款RISCV处理器 有些处理器已经在产业界得到了应用 比如在某志的D1处理器中 就嵌入了平头哥的玄铁C906内核为 芯 RISCV虽然是一个开放标准 并且网络上也不乏一些开源核的RTL实现 但是商用
  • MIPI D-PHY介绍(二) FPGA

    MIPI D PHY介绍 二 FPGA 随着移动设备的广泛普及 MIPI D PHY作为其最主要的物理层标准之一 被越来越多地使用在各种嵌入式系统中 本文将详细介绍MIPI D PHY的工作原理和在FPGA设计中的实现方法 MIPI D P
  • PLL时钟约束

    方法 1 自动创建基时钟和 PLL 输出时钟 例 derive pll clocks 这一方法使您能够自动地约束 PLL 的输入和输出时钟 ALTPLL megafunction 中指定的 所有 PLL 参数都用于约束 PLL 的输入和输出
  • 紫光同创 FPGA 开发跳坑指南(三)—— 联合 Modelsim 仿真

    Modelsim 是 FPGA 开发中重要的 EDA 设计仿真工具 主要用于验证数字电路设计是否正确 紫光 Pango Design Suite 开发套件支持联合 Modelsim 仿真 这里作简要的介绍 添加仿真库 方法一 打开 Pang
  • 实验1-FPGA编程入门

    文章目录 一 认识全加器 二 输入原理图实现1位加法器 一 半加器原理图输入 二 全加器原理图输入 三 Verilog语言实现全加器 四 总结 五 资料参考 一 认识全加器 一 半加器 1 逻辑分析 如下图所示 半加器只有两个输入和两个输出
  • 【Xilinx DDR3 MIG】Xilinx FPGA DDR3读写实验相关用户接口引脚解释

    目录 DDR3读写实验 实验框图 时钟模块 DDR3读写及LED指示模块 MIG IP核 用户接口解释
  • 【FPGA】面试问题及答案整理合集

    面试问题及答案整理合集 1 硬件描述语言和软件编程语言的区别 2 FPGA选型问题 3 建立时间和保持时间问题 3 亚稳态问题 4 竞争和冒险问题 5 乒乓操作问题 6 同步和异步逻辑电路 7 同步复位和异步复位 8 MOORE 与 MEE
  • 【数字IC】从零开始的Verilog SPI设计

    从零开始的Verilog SPI协议设计 一 写在前面 1 1 协议标准 1 2 数字IC组件代码 1 3 设计要求 1 4 其他协议解读 1 4 1 UART协议 1 4 2 SPI协议 1 4 3 I2C协议 1 4 4 AXI协议 二
  • [HDLBits] Exams/ece241 2014 q7a

    Design a 1 12 counter with the following inputs and outputs Reset Synchronous active high reset that forces the counter
  • 蓝桥杯真题:迷宫

    目录 题目描述 运行限制 dfs bfs 结果 题目描述 本题为填空题 只需要算出结果后 在代码中使用输出语句将所填结果输出即可 下图给出了一个迷宫的平面图 其中标记为 11 的为障碍 标记为 00 的为可以通行的地方 010000 000
  • 【FPGA多周期时序约束详解】- 解读FPGA多周期时序约束的全过程

    FPGA多周期时序约束详解 解读FPGA多周期时序约束的全过程 FPGA作为数字电路设计的常见工具 其设计中必然会遇到时序约束的问题 而多周期时序约束更是FPGA设计中不可避免的难点之一 本文将详细介绍FPGA多周期时序约束的全过程 并结合
  • [从零开始学习FPGA编程-24]:进阶篇 - 基本组合电路-编码器与译码器(Verilog语言)

    作者主页 文火冰糖的硅基工坊 文火冰糖 王文兵 的博客 文火冰糖的硅基工坊 CSDN博客 本文网址 https blog csdn net HiWangWenBing article details 125247358 目录 前言 Veri
  • 【ZYNQ学习】PL第一课

    这节课讲什么 这节课的名字本来是想写为LED 但这一课里除了LED也有按键 又想换为GPIO控制 但关于PL的GPIO控制 不应该这么草率和简单 而且这一课有很多和ZYNQ或者PL关联性不强的东西要说 所以我写了删删了写改了好几遍 终于定为
  • Matlab图像处理系列——图像复原之噪声模型仿真

    微信公众号上线 搜索公众号 小灰灰的FPGA 关注可获取相关源码 定期更新有关FPGA的项目以及开源项目源码 包括但不限于各类检测芯片驱动 低速接口驱动 高速接口驱动 数据信号处理 图像处理以及AXI总线等 本节目录 一 图像复原的模型 二

随机推荐