FPGA学习入门1

1. 初始化与时序控制

编写下面的代码控制clk_i和rst_n_i寄存器
其中#20表示延时20ns,20ns相当于模拟对应50MHZ的晶振

module tb_test();


reg clk_i;
reg rst_n_i;
wire[4:0]result1_o,result2_o;


 unblock unblcok_inst
(
    .clk_i(clk_i),
    .rst_n_i(rst_n_i),
    .result_o(result1_o)
 );
 
 block blcok_inst
(
    .clk_i(clk_i),
    .rst_n_i(rst_n_i),
    .result_o(result2_o)
 );
    
    initial begin
     clk_i =0;
     rst_n_i =0;
     #20;
     rst_n_i =1;
     #20; 
   end

    always #10 clk_i = ~clk_i;   
endmodule

2. 赋值 block or unblock

2.1 非阻塞赋值《=

module unblock(
input clk_i,
input rst_n_i,
output reg [4:0]result_o);
    reg [3:0]A;
    reg [3:0]B;
    reg [4:0]C;
 always @(posedge clk_i ) //上升沿触发
    if(!rst_n_i)
    begin
    #2 
     A <= 4'd4;
     B <= 4'd12;
     C <= 5'd0;
     result_o = 5'd0;
    end 
    else  begin
    #2 
     C <= A + B;
     result_o <= (C >> 1);
    //由于上两行是并行处理的(可以交换位置),c值赋为16时,对result_o 而言c还是0,所以result_o 还要延后20ns
    end 
endmodule

2.2 阻塞赋值 =


module block(
input clk_i,
input rst_n_i,
output reg [4:0]result_o
    );
    reg [3:0]A;
    reg [3:0]B;
    reg [4:0]C;

always @(posedge clk_i)   //上升沿触发
    if(!rst_n_i)
    begin
     #2   A = 4'd4;
     #0.2 B = 4'd12;
     #0.2 C = 5'd0;
     #0.2 result_o = 5'd0;
    end 
    else  begin
    #2   C = A + B;
    #0.2 result_o = (C >> 1);
    //上两行是串行处理的(不可以交换位置),c值赋为16时,对result_o 而言c已经是16
    end
 
endmodule

result1_o及上面的ABC是unblock,result2_o是block

3. 流水灯实验介绍

LED相关的GPIO口

c0作为寄存器用于计数使用,CLK_i来源于ZYNQ-MZ702P的时钟,RSTn_i属于上电置1。

module run_led(
input CLK_i,
input RSTn_i,
output reg [3:0]LED_o
);
reg [31:0]C0;
always @(posedge CLK_i)
if(!RSTn_i)
begin
 LED_o <= 4'b1;
 C0 <= 32'h0;
end
else
begin
 if(C0 == 32'd50_000_000)
 begin
 C0 <= 32'h0;
 if(LED_o == 4'b1000)
 LED_o <= 4'b1;
 else LED_o <= LED_o << 1;
 end
 else 
 begin
 C0 <= C0 + 1'b1; 
 LED_o <= LED_o; 
 end
end
endmodule

4. 按键消抖实验

下图SW0,SW1,SW2,SW3是FPGA MZ702P的四个按键:

对应原理图如下:
按钮按下导通,置0,松开为1。

下面两段程序是约束文件下配置管脚,指明了M16用于复位,K16用于按键。

set_property IOSTANDARD LVCMOS33 [get_ports key_i]
set_property PACKAGE_PIN K16 [get_ports key_i]

set_property PACKAGE_PIN M16 [get_ports rst_n_i]
set_property IOSTANDARD LVCMOS33 [get_ports rst_n_i]

下面这段程序实现了本实验的功能

module Key_Jitter(
input clk_i,
input rst_n_i,
input key_i,
output [3:0] led_o

);
(*mark_debug = "true"*) reg [3:0] led_o;
(*mark_debug = "true"*) wire key_cap;

always @(posedge clk_i)begin
    if(!rst_n_i)begin     //此处SW1可以控制全亮,按下SW1,rst_n_i置0,四个LED都变为0,LED都导通
        led_o <= 4'b0000;
    end
    else if(key_cap)begin  //一旦检测到按过按钮SW2,key_cap置为1,具体定义在key #中
        led_o <= ~led_o;  //由key#控制,所有led翻转
    end
end

key#
(
.CLK_FREQ(100000000)
)
key0
(
.clk_i(clk_i),
.key_i(key_i),
.key_cap(key_cap)
);


endmodule

下面这段程序定义了key #模块

module key #
(
    parameter CLK_FREQ = 100000000
)
(
input clk_i,
input key_i,
output key_cap
);
//10ms
parameter CNT_10MS = (CLK_FREQ/100 - 1'b1);         //分屏10ms?
parameter KEY_S0 = 2'd0;
parameter KEY_S1 = 2'd1;
parameter KEY_S2 = 2'd2;
parameter KEY_S3 = 2'd3;

reg [24:0] cnt10ms = 25'd0;
(*mark_debug = "true"*) reg [1:0] key_s = 2'b0;
(*mark_debug = "true"*) reg [1:0] key_s_r = 2'b0;
(*mark_debug = "true"*) wire en_10ms ;
 
assign en_10ms = (cnt10ms == CNT_10MS);
assign key_cap = (key_s==KEY_S2)&&(key_s_r==KEY_S1);   //说明按键按下又松开,算一次按按键

always @(posedge clk_i)begin
    if(cnt10ms < CNT_10MS) 
        cnt10ms <= cnt10ms + 1'b1;
    else 
        cnt10ms <= 25'd0;
end

always @(posedge clk_i)begin
    key_s_r <= key_s;
end

always @(posedge clk_i)begin
    if(en_10ms)begin
        case(key_s)
        KEY_S0:begin
           if(!key_i)
               key_s <= KEY_S1; 
        end  
        KEY_S1:begin
           if(!key_i)
               key_s <= KEY_S2; 
            else 
               key_s <= KEY_S0; 
        end 
        KEY_S2:begin
           if(key_i)
               key_s <= KEY_S3; 
        end  
        KEY_S3:begin
           if(key_i)
              key_s <= KEY_S0;
            else   
              key_s <= KEY_S2; 
        end
        endcase                  
    end
end


endmodule

posted @ 2022-10-04 19:33  静候佳茵  阅读(65)  评论(0编辑  收藏  举报