打印

【求助】:基于verilog的数字密码锁

[复制链接]
3050|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
anshasha|  楼主 | 2010-5-4 13:58 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
求达人帮我看下我的代码哪里有问题啊,我用ISE10.1不能仿真出结果~一直没找到错误,拜托帮忙看下,有点长,麻烦大家了
module passwd_lock(clk,resetb,cmd,alarmed,passed);
input                        clk;                        //输入时钟信号
input                        resetb;                //输入复位信号
input         [4:0]        cmd;                //输入命令信号
output                        alarmed;                //输出警报信号
output                        passed;                //输出通过信号
wire                        clk;
wire                        resetb;
wire        [4:0]        cmd;
reg                                alarmed;
reg                                passed;
parameter                PASSWORD=16'b0001_0010_0011_0100;//盛放密码的参数1234
reg                [15:0]        password;//输入数值盛放寄存器
reg                        one=5'b10001,
                                two=5'b10010,
                                three=5'b10011,
                                four=5'b10100,
                                five=5'b10101,
                                six=5'b10110,
                                seven=5'b10111,
                                eight=5'b11000,
                                nine=5'b11001,
                                zero=5'b11000,
                                enter=5'b11010,
                                cancel=5'b11011;
reg                        cmd_t;//检验是否有按键按下
reg                        [2:0]        main_state;//主状态
reg                        [2:0]        next_state;//下一个状态
parameter                waits=3'b001,
                                        pass=3'b010,
                                        alarm=3'b100;
reg                [2:0]        sub_state;
reg                [2:0]        next_sub_state;
parameter                first=3'b000,
                                        second=3'b001,
                                        third=3'b010,
                                        fourth=3'b011,
                                        finish=3'b100;
//通过计时寄存器
reg                [7:0]        pass_count;
//警报计时寄存器
reg                [10:0]        alarm_count;
//尝试次数寄存器
reg                [1:0]        try_count;
//输入状态寄存器:error和correct
reg                        error;
reg                        correct;
//主机状态机部分
always@(main_state or correct or error)
begin
        case(main_state)
                waits:
                        if(correct==1) //由waits转换到pass的条件
                                next_state=pass;
                        else if(error==1&&try_count==2)
                                next_state=alarm; //由waits转换到alarm的条件
                        else
                                next_state=waits;
                pass:
                        if(pass_count[7]==1)//由pass转换到waits的条件
                                next_state=waits;
                        else
                                next_state=pass;
                alarm:
                        if(alarm_count[10]==1)// 由alarm转换到waits的条件
                                next_state=waits;
                        else
                                next_state=alarm;
                default://默认状态:waits
                        next_state=waits;
                endcase
        end
//状态转换
always@(posedge clk or negedge resetb)
begin
        if(!resetb)
                main_state<=waits;
        else
                main_state<=next_state;
end
//输出控制部分
always@(posedge clk or negedge resetb)
begin
        if(!resetb)//复位时,开锁输出与警报输出都为零
                begin
                        passed<=0;
                        alarmed<=0;
                end
        else if(main_state==pass)//当主机状态为pass时,开锁
                begin
                        passed<=1;
                        alarmed<=0;
                end
        else if(main_state==alarm)//当主机状态为alarm时,警报
                begin
                        passed<=0;
                        alarmed<=1;
                end
        else//其它状态复位
                begin
                        passed<=0;
                        alarmed<=0;
                end
end

//alarm一段时间后,自动进入waits状态
//alarm定时器
always@(posedge clk or negedge resetb)
begin
        if(!resetb)
                alarm_count<=0;
        else if(main_state==alarm)//alarm状态计时器alarm定时器加1
                alarm_count<=alarm_count+1;
        else
                alarm_count<=0;
end
//锁pass以后计数开始,当规定的时间到达后自动上锁,并进入waits状态
//pass定时器
always@(posedge clk or negedge resetb)
        begin
                if(!resetb)
                        pass_count<=0;
                else if(main_state==pass) //pass状态计时器pass定时器加1
                        pass_count<=pass_count+1;
                else
                        pass_count<=0;
        end
//从状态机,用于输入4位密码
always@(posedge clk or negedge resetb)
begin
        if(!resetb)
                cmd_t<=0;
        else
                cmd_t<=~cmd[4];
end

always@(posedge clk or negedge resetb)
begin
        if(!resetb)
                sub_state<=first;
        else
                sub_state<=next_sub_state;
end

always@(cmd or cmd_t or sub_state)
begin
        if(cmd_t==0&&cmd[4]==1)
                case(cmd)
                        cancel://密码输入错误时,重复上一个状态
                        begin
                                if(sub_state==first)// 第1个密码输入错误
                                        next_sub_state=first;
                                else
                                        case(sub_state)
                                        second: // 第2个密码输入错误
                                                next_sub_state=first;
                                        third: // 第3个密码输入错误
                                                next_sub_state=second;
                                        fourth: // 第4个密码输入错?                                                next_sub_state=third;
                                        finish:
                                                next_sub_state=fourth;
                                        endcase
                        end
                        enter://4个密码输完时,进行确认
                                next_sub_state=first;
                        //以下4个命令位无效的命令,状态保持不变
                        5'b11100:
                                next_sub_state=next_sub_state;
                        5'b11101:
                                next_sub_state=next_sub_state;
                        5'b11110:
                                next_sub_state=next_sub_state;
                        5'b11111:
                                next_sub_state=next_sub_state;
//default为输入了某位密码,输入完自动将状态转入下一位
                        default:
                                case(sub_state)
                                first:
                                        next_sub_state=second;
                                second:
                                        next_sub_state=third;
                                third:
                                        next_sub_state=fourth;
                                fourth:
                                        next_sub_state=finish;
//当输入完4位密码以后状态保持不变,等待输入enter命令
                                finish:
                                        next_sub_state=finish;        
                                endcase
                        endcase
                else
                        next_sub_state=sub_state;
end
//比较密码
always@(posedge clk or negedge resetb)
begin
        if(!resetb)
                begin
                        correct<=0;
                        error<=0;
                end
        else if(cmd_t ==0&&cmd==enter)
                if(password==PASSWORD)//密码正确时
                        begin
                                correct<=1;
                                error<=0;
                        end
                else//密码错误时
                        begin
                                error<=1;
                                correct<=0;
                        end
                else
                        begin
                                correct<=0;
                                error<=0;
                        end
end
//记录密码
always@(posedge clk or negedge resetb)
begin
        if(!resetb)
                password<=0;
        else if(cmd_t==0&&cmd[4]==1)
                case(sub_state)
                first:
                        password[15:12]<=cmd[3:0];
                second:
                        password[11:8]<=cmd[3:0];
                third:
                        password[7:4]<=cmd[3:0];
                fourth:
                        password[3:0]<=cmd[3:0];
                default:
                        password<=password;
                endcase
        else
                password<=password;
end
//记录错误次数
always@(posedge clk or negedge resetb)
begin
if(!resetb)
                try_count<=0;
        else if(error==1)
                try_count<=try_count+1;
        else if(main_state==pass||main_state==alarm)
                try_count<=0;
        end
endmodule

相关帖子

沙发
fyshuljj| | 2010-5-5 23:09 | 只看该作者
给出中和后的提示信息啊

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

6

帖子

1

粉丝