FPGA——IO操作

FPGA——IO操作

  • IO作为输出——流水灯
  • IO作为输入——按键控制led

IO作为输出——流水灯

目标 :1s时间间隔实现流水灯
需要的信号:时钟信号,复位信号
说明:要实现流水灯,我们需要计时器、移位寄存器。

首先根据外部50MHz晶振得出每一个振荡周期时间间隔为20ns,要实现1s计时我们需要一个可以计数到
1 s / 20 n s = 50 , 000 , 000 1s/20ns=50,000,000 1s/20ns=50,000,000
的计数器
FPGA——IO操作_第1张图片
换算得二进制10 1111 1010 1111 0000 1000 0000。所以需要定义一个26位的cnt计数器。
同样实现流水效果时需要一个移位寄存器进行移位,例如:

         led[3:0] <= {led[2:0],led[3]};

每当计数器计满时,led移位寄存器进行移位,达到流水效果
直接上代码

module IOoperating(
   input           sys_clk,
   input           rst_n,    //定义输入信号
   
   output reg [3:0]led       //定义移位寄存器,作为输出
);

reg [25:0] cnt;              //定义26为计数器,计时1s

/*****************************************************
                     计时1s
        每当时钟上升沿或复位按下时,进行判断
*****************************************************/
always @(posedge sys_clk or negedge rst_n)
begin
  if(!rst_n)
     cnt <= 26'b0;                //如果复位被按下,计数器清零
  else if(cnt < 26'd5000_0000)    
     cnt <= cnt + 1'b1;           //如果没到1s,计数器+1
  else
     cnt <= 26'd0;                //达到1s,计数器清零
end
/*****************************************************
                     led移位输出
*****************************************************/
always @(posedge sys_clk or negedge rst_n)
begin
  if(!rst_n)
     led <= 4'b1110;                  //复位被按下,恢复到初始状态
  else if(cnt == 26'd5000_0000)
     led[3:0] <= {led[2:0],led[3]};   //计数器满,达到一秒,led寄存器移位
  else
     led <= led;
end

endmodule 

IO作为输入——按键控制led

目标:按下K0,led流水显示。按下K1,led闪烁。时间间隔均为1s。
主要方法:设置一个按键标志位,按下不同按键,给标志位不同值,从而控制效果

module key_led(
   input             sys_clk,
   input             rst_p,    //定义输入信号
   
   input      [2:0]  key,
   output reg [3:0]  led       //定义移位寄存器,作为输出
);

//reg define
reg  [25:0]  cnt;           //计数
reg  [1:0]   led_ctrl;      //状态控制
reg  [1:0]   led_flag;      //按键标志位

/*****************************************************
                     计时1s
        每当时钟上升沿或复位按下时,进行判断
*****************************************************/
always @(posedge sys_clk or posedge rst_p)
begin
     if(rst_p)
        cnt <= 26'd0;
     else 
        if(cnt < 25'd50_000_000)
            cnt <= cnt + 1'b1;
        else  
            cnt <= 26'd0;
end


/*****************************************************
                     状态计数器
   led_ctrl为2位寄存器,共4个状态,累加到5时自动清零
                 从而实现不同显示效果
*****************************************************/
always @(posedge sys_clk or posedge rst_p)
begin
     if(rst_p)
        led_ctrl <= 2'd0;
     else 
        if(cnt == 25'd50_000_000)
            led_ctrl <= led_ctrl + 2'b1;    //时间到达1s后led_ctrl+1,显示下一个状态
        else
            led_ctrl <= led_ctrl;
end

/*****************************************************
                     状态变化标志
            当key[0]按下时,led_flag 为01
            当key[1]按下时,led_flag 为10
*****************************************************/

always @(posedge sys_clk or posedge rst_p)
begin
     if(rst_p)
        led_flag <= 2'b0;
     else 
        if(key[0] == 1'b0)
            led_flag <= 2'b01;
        else if(key[1] == 1'b0)
            led_flag <= 2'b10;
        else
            led_flag <= led_flag;
end

/*****************************************************
                根据按键改变led灯
      判断led_flag 值,,通过led_ctrl的变化显示led
*****************************************************/
always @(posedge sys_clk or posedge rst_p)
begin
     if(rst_p)
        led <= 4'b1111;
     else 
        if(led_flag[0] == 1'b1)
            case(led_ctrl)
                2'd0:   led <= 4'b0111;
                2'd1:   led <= 4'b1011;
                2'd2:   led <= 4'b1101;
                2'd3:   led <= 4'b1110;
            endcase
         else if(led_flag[1] == 1'b1)
            case(led_ctrl)
                2'd0:   led <= 4'b1111;
                2'd1:   led <= 4'b0000;
                2'd2:   led <= 4'b1111;
                2'd3:   led <= 4'b0000;
            endcase
         else
             led <= 4'b1111;
end

endmodule

你可能感兴趣的:(fpga)