英特尔FPGA day7

今天比较痛苦,主要是下午的加法器一直没实现。而且调试半天没成功,有很大部分时间也浪费在了,忘了原来flash里面他们烧有程序了,然后相当于一直调试,白调了。还有就是我总感觉,可能是数码管显示那里,我没弄完全透,那部分出了些问题,因为感觉加法计算这一块,没啥逻辑问题,就算有,感觉还没到后面,就前面显示都有问题。 总之弄半天了,也挺难受的。

还是先总结今天写的吧。

学习内容:

按键输入密码锁,还有固化文件的设置(将文件写到flash中去)

下午就是实现加法器。

产生疑惑:

参数等正常传入,为啥,数码管不能正常显示给定数字,数码管的显示和数字表示的进制方式,位宽有关吗,即3’d2, 3'b10, 4'd2 这三种数字传入后,显示的数字是一样的吗?答案是不影响

感觉数码管那一块还是没掌握特别好。

其他的感觉今天讲的很少,下面就贴些代码吧。

密码锁:

module password(
    input clk,
    input rst_n,
    input [3:0] key,

    output reg [3:0] led
);
//状态空间
parameter IDLE = 3'd0;
parameter S1   = 3'd1;
parameter S2   = 3'd2;
parameter S3   = 3'd3;
parameter S4   = 3'd4;
parameter CNT_MAX = 26'd49_999_999;
parameter TIME    = 24'd9_999_999;
reg [23:0]cnt_200ms;
reg [25:0] cnt;
reg [2:0] cstate;//当前状态

wire add_cnt;
wire end_cnt;
wire add_cnt_200ms;
wire end_cnt_200ms;

always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        cnt <= 0;
    end 
    else if(add_cnt)begin 
        if (end_cnt) begin
            cnt <= 0;
        end
        else begin
            cnt <= cnt +1'd1;
        end
    end 

end

assign add_cnt = (cstate == S4);
assign end_cnt = add_cnt && cnt == CNT_MAX;



always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        cnt_200ms <= 0;
    end 
    else if(add_cnt_200ms)begin 
        if (end_cnt_200ms) begin
            cnt_200ms <= 0;
        end
        else begin
            cnt_200ms <= cnt_200ms +1'd1;
        end
    end 
    else begin 
        
    end 
end

assign add_cnt_200ms = (cstate == S4);
assign end_cnt_200ms = add_cnt_200ms && cnt_200ms == TIME;


always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        cstate <= IDLE;
    end
    else begin 
        case (cstate)
            IDLE: begin
                if(key[0])begin//1
                     cstate <= S1;
                end
                   
                else if (key[1]|key[2]|key[3]) begin
                        cstate = IDLE;
                        end
                else 
                cstate <= IDLE; 
            end  
            S1: begin
                if(key[3])begin//4
                     cstate <= S2;
                end
                   
                else if (key[1]|key[2]|key[0]) begin
                        cstate = IDLE;
                        end
                else 
                cstate <= S1;
            end
            S2: begin
                if(key[1])begin//2
                     cstate <= S3;
                end
                   
                else if (key[0]|key[2]|key[3]) begin
                        cstate = IDLE;
                        end
                else 
                cstate <= S2;
            end
            S3: begin
                if(key[2])begin//3
                     cstate <= S4;
                end
                   
                else if (key[0]|key[1]|key[3]) begin
                        cstate = IDLE;
                        end
                else 
                cstate <= S3;
            end
            S4: begin
                if (end_cnt) begin
                    cstate <= IDLE;
                end
                else
                    cstate <= S4;
                
            end    
            default: ;
        endcase
    end 
end

reg [0:0]flag;

always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        led <= 0;
        flag <= 1'b1;
    end 
    else begin 
        case (cstate)
            IDLE: led <= 4'b0000;
            S1  : led <= 4'b0001;
            S2  : led <= 4'b0011;
            S3  : begin
                led <= 4'b0111;
                flag <= 1'b1;                
            end
    
            S4  : begin
                if (flag) begin
                     led <= 4'b1111;  
                     flag <= 1'b0;                   
                end                
                else if(end_cnt_200ms)
                    begin
                        led <= ~led;                    
                end    
                else begin
                        led <= led;
                end               
                end
 
            default: ;
        endcase
    end 
end




endmodule

顶层文件

module top_key_lock(
    input clk,
    input rst_n,
    input [3:0]key,

    output [3:0]led
);
wire [3:0] key_reg;



password u_password(
.clk(clk),
.rst_n(rst_n),
.key(key_reg),

.led(led)

);

key_keep u0_key_keep(
.clk(clk),
.rst_n(rst_n),
.key_in(key[0]),

.key_down(key_reg[0])

);

key_keep u1_key_keep(
.clk(clk),
.rst_n(rst_n),
.key_in(key[1]),

.key_down(key_reg[1])

);

key_keep u2_key_keep(
.clk(clk),
.rst_n(rst_n),
.key_in(key[2]),

.key_down(key_reg[2])

);

key_keep u3_key_keep(
.clk(clk),
.rst_n(rst_n),
.key_in(key[3]),

.key_down(key_reg[3])

);

endmodule

按键消抖

module key_keep(//消抖模块
    input clk,
    input rst_n,
    input key_in,//未消抖的按键

    output reg key_down//消抖后的按键值
);

/****************************************************************
						main
				按键消抖用状态机方法实现
***************************************************************/


//定义按键按下的四个 状态
localparam IDLE = 4'b0001;
localparam FILTER_DOWN = 4'b0010;//按键按下过程
localparam HOLD_DOWN = 4'b0100 ;
localparam FILTER_UP = 4'b1000;  //按键松开过程

parameter TIME_DELAY = 20'd100_0000;

wire add_delay_cnt;//开始计时的标志
wire end_delay_cnt;//结束及时的标志

reg [19:0] cnt;
reg [3:0] state_c;//现态
reg [3:0] state_n;//次态

reg key_in_r0;
reg key_in_r1;

wire n_edge;//按键按下
wire p_edge;//按键松开 
wire idle2filter_down_start;
wire filter_down2hold_down_start;
wire filter_down2idle_start;
wire hold_down2filter_up_start;
wire filter_up2idle_start;

//接收按键信号
always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
         key_in_r0 <= 1'b1;
         key_in_r1 <= 1'b1;
    end 
    else begin 
        key_in_r0 <= key_in;
        key_in_r1 <= key_in_r0;
    end 
end

assign n_edge = ~key_in_r0 & key_in_r1;
assign p_edge = ~key_in_r1 & key_in_r0;

always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        state_c <= IDLE;
    end 
    else begin 
        state_c <= state_n;
    end 
end
always @(*)begin 
     if(!rst_n)begin
      state_n = IDLE;
     end 
     else begin 
        case (state_c)
            IDLE:begin
                if(idle2filter_down_start)
                state_n <=FILTER_DOWN;
                else
                state_n <=state_c;
            end 
            FILTER_DOWN:begin
                if(filter_down2hold_down_start)begin
                    state_n <= HOLD_DOWN;
                end
                else if (filter_down2idle_start) begin
                    state_n <=IDLE;
                end
                else
                    state_n <= state_c;
            end
            HOLD_DOWN: begin
                if (hold_down2filter_up_start) begin
                    state_n <= FILTER_UP;
                end
                else 
                    state_n <= state_c;
            end
            FILTER_UP: begin
                if (filter_up2idle_start)begin
                    state_n <= IDLE;
                end
                else 
                    state_n <= state_c;
            end
            default: ;
        endcase
     end 
end

always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        key_down <= 0;
    end 
    else if(hold_down2filter_up_start)begin 
        key_down <= ~key_in_r1;//如果不取反,按键按下就输出0,取反,按键按下就输出1
    end 
    else begin 
        key_down <= 1'b0;
    end 
end

assign idle2filter_down_start = (state_c == IDLE)&&(n_edge);
assign filter_down2idle_start = (state_c == FILTER_DOWN)&&(add_delay_cnt && p_edge);
assign filter_down2hold_down_start = (state_c == FILTER_DOWN)&&(end_delay_cnt && !p_edge);
assign hold_down2filter_up_start = (state_c == HOLD_DOWN)&&(p_edge);
assign filter_up2idle_start = (state_c == FILTER_UP)&&(end_delay_cnt);

/*计数条件与结束条件*/
assign  add_delay_cnt = (state_c==FILTER_DOWN) || (state_c==FILTER_UP);
assign  end_delay_cnt = add_delay_cnt && (cnt == TIME_DELAY-1);
always @(posedge clk or negedge rst_n)begin 
    if(!rst_n)begin
        cnt <= 20'd0;
    end 
    else if(add_delay_cnt)begin 
        if (end_delay_cnt) begin
            cnt <= 20'd0;
        end
        else begin
            cnt <= cnt +1'b1;
        end
    end 
    else begin 
        cnt <= cnt;
    end 
end

endmodule

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值