data/full_repos/permissive/426072575/labs/final_project_digital_lock/codes/state_lock.v
1: b'%Warning-WIDTH: data/full_repos/permissive/426072575/labs/final_project_digital_lock/codes/state_lock.v:205: Operator ASSIGNDLY expects 2 bits on the Assign RHS, but Assign RHS\'s CONST \'3\'h0\' generates 3 bits.\n                                                                                                           : ... In instance Lock\n        open_result <= 3\'b000;\n                    ^~\n                ... Use "/* verilator lint_off WIDTH */" and lint_on around source to disable this message.\n%Warning-WIDTH: data/full_repos/permissive/426072575/labs/final_project_digital_lock/codes/state_lock.v:217: Operator ASSIGNDLY expects 2 bits on the Assign RHS, but Assign RHS\'s CONST \'3\'h2\' generates 3 bits.\n                                                                                                           : ... In instance Lock\n            open_result <= 3\'b010;\n                        ^~\n%Error: Exiting due to 2 warning(s)\n'
module Lock(
    clk, rst_in, rst_code, rst_open, rst_timer, rst,
    load, sure, change, open,
    din,
    succ, fail, locked, change_succ, cnt_open,
    open_now, change_now
);
input clk, rst_in, rst_code, rst_open, rst_timer, rst;
input load, sure, change, open;
input [9:0] din;
output reg succ, fail, locked, change_succ;
output reg open_now, change_now;
output reg [2:0] cnt_open;

reg [9:0] din_1, din_2, din_3, din_4;

reg [39:0] right_code, in_code;

reg [2:0] currentState, nextState;

parameter START_STATE = 3'b000;
parameter OPEN_STATE = 3'b001;
parameter CHANGE_STATE = 3'b010;
parameter PASS_STATE = 3'b011;
parameter LOCKED_STATE = 3'b100;
parameter CHANGE_SUCC_STATE = 3'b101;


always @(posedge clk or posedge rst) begin
    if (rst) currentState <= START_STATE;
    else currentState <= nextState;
end

reg [3:0] cnt;
always @(rst_in or din or load) begin
    if(!rst_in) begin
        cnt <= 4'b1000;
        din_1 <= 0;
        din_2 <= 0;
        din_3 <= 0;
        din_4 <= 0; 
        din_temp_1 <= 0;
        din_temp_2 <= 0;
        din_temp_3 <= 0;
        din_temp_4 <= 0;
        in_code = 0;
    end
    else if (load)begin
        if(cnt == 4'b0000) begin
            cnt <= 4'b0000;
        end
        else begin
            if(cnt ==4'b1000) din_4 <= din;
            else if(cnt == 4'b0111) din_3 <= din;
            else if(cnt == 4'b0110) din_2 <= din;
            else if(cnt == 4'b0101) din_1 <= din;
            else if(cnt == 4'b0100) din_temp_4 <= din;
            else if(cnt == 4'b0011) din_temp_3 <= din;
            else if(cnt == 4'b0010) din_temp_2 <= din;
            else if(cnt == 4'b0001) din_temp_1 <= din;
            cnt = cnt - 1'b1;
        end 
    end
end

always @(currentState or action or open_result or time_stop or change_result or rst) begin
    if (rst) nextState <= START_STATE;
    else begin
        case (currentState)
            START_STATE : 
                if(action == 2'b01) nextState <= OPEN_STATE;
                else if (action == 2'b10) nextState <= CHANGE_STATE;
                else nextState <= START_STATE;
            OPEN_STATE : 
                if(open_result == 2'b01) nextState <= PASS_STATE;
                else if (open_result == 2'b10) nextState <= OPEN_STATE;
                else if (open_result == 2'b11) nextState <= LOCKED_STATE;
                else nextState <= START_STATE; 
            
            CHANGE_STATE : 
                if(change_result == 2'b01) nextState <= CHANGE_SUCC_STATE;
                else if(change_result == 2'b10) nextState <= CHANGE_STATE;
                else nextState <= START_STATE;
                
            PASS_STATE : 
                if(time_stop == 0) nextState <= PASS_STATE;
                else nextState <= START_STATE;

            LOCKED_STATE :
                if(time_stop == 0) nextState <= LOCKED_STATE;
                else nextState <= START_STATE; 
            CHANGE_SUCC_STATE :
                if(time_stop == 0) nextState <= CHANGE_SUCC_STATE;
                else nextState <= START_STATE;
            default: nextState <= START_STATE;
        endcase
    end
end



always @(rst or currentState) begin
    if (rst) begin
        open_now <= 0;
        change_now <= 0;
        succ <= 0;
        fail <= 0;
        locked <= 0; 
    end
    else begin
        case (currentState)
            START_STATE :begin
            open_now <= 0;
            change_now <= 0;
            succ <= 0;
            fail <= 0;
            locked <= 0;
            change_succ = 0;
            end 
            OPEN_STATE :begin
                open_now <= 1;
                fail <= 1;
                change_now <= 0;
                succ <= 0;
                locked <= 0;
                change_succ = 0;
            end
            CHANGE_STATE:begin
                change_now <= 1;
                open_now <= 0;
                succ <= 0;
                fail <= 0;
                locked <= 0;
                change_succ = 0;
            end
            PASS_STATE:begin
                succ <= 1;
                open_now <= 0;
                change_now <= 0;
                fail <= 0;
                locked <= 0;
                change_succ = 0;
            end 
            LOCKED_STATE:begin
                locked <= 1;
                fail <= 1;
                open_now <= 0;
                change_now <= 0;
                succ <= 0;
                change_succ = 0;
            end
            CHANGE_SUCC_STATE :begin
                locked <= 0;
                fail <= 0;
                open_now <= 0;
                change_now <= 0;
                succ <= 0;
                change_succ = 1;
            end
        endcase
    end 
end




reg [1:0] action;
always@(change or open) begin
    if(change && !open) action = 2'b10;
    else if(!change && open) action = 2'b01;
    else action = 2'b00;
end



reg [1:0] open_result;

always @(posedge sure or posedge open or posedge change or negedge rst_open or negedge rst_code) begin 
    if(!rst_open)begin
        cnt_open <= 3'b100;
        open_result <= 3'b000;
    end 
    else if(!rst_code) begin 
        right_code <= 0;
        change_result <= 2'b10;
    end
    else begin

    case (currentState)
    START_STATE:begin
        if(open) begin
            cnt_open <= 3'b100;
            open_result <= 3'b010;
        end
        else if (change) begin  
            change_result <= 2'b10;
        end
    end

    
    OPEN_STATE: begin

    if(sure) begin
        if(cnt_open == 3'b000) begin
            open_result <= 2'b11;
            cnt_open <= 3'b000;
        end
        else begin
            if({din_4, din_3, din_2, din_1} == right_code) begin
                open_result <= 2'b01;
                cnt_open <= 3'b100;
            end else begin
                open_result <= 2'b10;
                cnt_open <= cnt_open - 1'b1;
            end

            in_code <= {din_4, din_3, din_2, din_1};
        end        
    end
    end

    CHANGE_STATE:begin
    if(currentState == CHANGE_STATE) begin
        if ({din_4, din_3, din_2, din_1} == right_code) begin
            right_code <= {din_temp_4, din_temp_3, din_temp_2, din_temp_1};
            change_result <= 2'b01;
        end
        else begin
            change_result <= 2'b10;
        end
    end
    end
    
    endcase
    end
end





reg [9:0] din_temp_1, din_temp_2, din_temp_3, din_temp_4;
reg [1:0] change_result;



integer cnt_timer;

parameter T = 20;
reg time_stop;

always @(posedge clk or negedge rst_timer) begin
    if(!rst_timer) begin 
        time_stop <= 0; 
        cnt_timer <= 0;
    end
    else if(currentState == PASS_STATE || currentState == LOCKED_STATE || currentState == CHANGE_STATE) begin
        if(cnt_timer < T) begin
            cnt_timer = cnt_timer + 1'b1;
            time_stop <= 0;
        end else begin
            time_stop <= 1;
            cnt_timer <= 0;
        end
    end
end


endmodule
module Lock(
    clk, rst_in, rst_code, rst_open, rst_timer, rst,
    load, sure, change, open,
    din,
    succ, fail, locked, change_succ, cnt_open,
    open_now, change_now
);

input clk, rst_in, rst_code, rst_open, rst_timer, rst;
input load, sure, change, open;
input [9:0] din;
output reg succ, fail, locked, change_succ;
output reg open_now, change_now;
output reg [2:0] cnt_open;

reg [9:0] din_1, din_2, din_3, din_4;

reg [39:0] right_code, in_code;

reg [2:0] currentState, nextState;

parameter START_STATE = 3'b000;
parameter OPEN_STATE = 3'b001;
parameter CHANGE_STATE = 3'b010;
parameter PASS_STATE = 3'b011;
parameter LOCKED_STATE = 3'b100;
parameter CHANGE_SUCC_STATE = 3'b101;


always @(posedge clk or posedge rst) begin
    if (rst) currentState <= START_STATE;
    else currentState <= nextState;
end

reg [3:0] cnt;
always @(rst_in or din or load) begin
    if(!rst_in) begin
        cnt <= 4'b1000;
        din_1 <= 0;
        din_2 <= 0;
        din_3 <= 0;
        din_4 <= 0; 
        din_temp_1 <= 0;
        din_temp_2 <= 0;
        din_temp_3 <= 0;
        din_temp_4 <= 0;
        in_code = 0;
    end
    else if (load)begin
        if(cnt == 4'b0000) begin
            cnt <= 4'b0000;
        end
        else begin
            if(cnt ==4'b1000) din_4 <= din;
            else if(cnt == 4'b0111) din_3 <= din;
            else if(cnt == 4'b0110) din_2 <= din;
            else if(cnt == 4'b0101) din_1 <= din;
            else if(cnt == 4'b0100) din_temp_4 <= din;
            else if(cnt == 4'b0011) din_temp_3 <= din;
            else if(cnt == 4'b0010) din_temp_2 <= din;
            else if(cnt == 4'b0001) din_temp_1 <= din;
            cnt = cnt - 1'b1;
        end 
    end
end

always @(currentState or action or open_result or time_stop or change_result or rst) begin
    if (rst) nextState <= START_STATE;
    else begin
        case (currentState)
            START_STATE : 
                if(action == 2'b01) nextState <= OPEN_STATE;
                else if (action == 2'b10) nextState <= CHANGE_STATE;
                else nextState <= START_STATE;
            OPEN_STATE : 
                if(open_result == 2'b01) nextState <= PASS_STATE;
                else if (open_result == 2'b10) nextState <= OPEN_STATE;
                else if (open_result == 2'b11) nextState <= LOCKED_STATE;
                else nextState <= START_STATE; 
            
            CHANGE_STATE : 
                if(change_result == 2'b01) nextState <= CHANGE_SUCC_STATE;
                else if(change_result == 2'b10) nextState <= CHANGE_STATE;
                else nextState <= START_STATE;
                
            PASS_STATE : 
                if(time_stop == 0) nextState <= PASS_STATE;
                else nextState <= START_STATE;

            LOCKED_STATE :
                if(time_stop == 0) nextState <= LOCKED_STATE;
                else nextState <= START_STATE; 
            CHANGE_SUCC_STATE :
                if(time_stop == 0) nextState <= CHANGE_SUCC_STATE;
                else nextState <= START_STATE;
            default: nextState <= START_STATE;
        endcase
    end
end



always @(rst or currentState) begin
    if (rst) begin
        open_now <= 0;
        change_now <= 0;
        succ <= 0;
        fail <= 0;
        locked <= 0; 
    end
    else begin
        case (currentState)
            START_STATE :begin
            open_now <= 0;
            change_now <= 0;
            succ <= 0;
            fail <= 0;
            locked <= 0;
            change_succ = 0;
            end 
            OPEN_STATE :begin
                open_now <= 1;
                fail <= 1;
                change_now <= 0;
                succ <= 0;
                locked <= 0;
                change_succ = 0;
            end
            CHANGE_STATE:begin
                change_now <= 1;
                open_now <= 0;
                succ <= 0;
                fail <= 0;
                locked <= 0;
                change_succ = 0;
            end
            PASS_STATE:begin
                succ <= 1;
                open_now <= 0;
                change_now <= 0;
                fail <= 0;
                locked <= 0;
                change_succ = 0;
            end 
            LOCKED_STATE:begin
                locked <= 1;
                fail <= 1;
                open_now <= 0;
                change_now <= 0;
                succ <= 0;
                change_succ = 0;
            end
            CHANGE_SUCC_STATE :begin
                locked <= 0;
                fail <= 0;
                open_now <= 0;
                change_now <= 0;
                succ <= 0;
                change_succ = 1;
            end
        endcase
    end 
end




reg [1:0] action;
always@(change or open) begin
    if(change && !open) action = 2'b10;
    else if(!change && open) action = 2'b01;
    else action = 2'b00;
end



reg [1:0] open_result;

always @(posedge sure or posedge open or posedge change or negedge rst_open or negedge rst_code) begin 
    if(!rst_open)begin
        cnt_open <= 3'b100;
        open_result <= 3'b000;
    end 
    else if(!rst_code) begin 
        right_code <= 0;
        change_result <= 2'b10;
    end
    else begin

    case (currentState)
    START_STATE:begin
        if(open) begin
            cnt_open <= 3'b100;
            open_result <= 3'b010;
        end
        else if (change) begin  
            change_result <= 2'b10;
        end
    end

    
    OPEN_STATE: begin

    if(sure) begin
        if(cnt_open == 3'b000) begin
            open_result <= 2'b11;
            cnt_open <= 3'b000;
        end
        else begin
            if({din_4, din_3, din_2, din_1} == right_code) begin
                open_result <= 2'b01;
                cnt_open <= 3'b100;
            end else begin
                open_result <= 2'b10;
                cnt_open <= cnt_open - 1'b1;
            end

            in_code <= {din_4, din_3, din_2, din_1};
        end        
    end
    end

    CHANGE_STATE:begin
    if(currentState == CHANGE_STATE) begin
        if ({din_4, din_3, din_2, din_1} == right_code) begin
            right_code <= {din_temp_4, din_temp_3, din_temp_2, din_temp_1};
            change_result <= 2'b01;
        end
        else begin
            change_result <= 2'b10;
        end
    end
    end
    
    endcase
    end
end





reg [9:0] din_temp_1, din_temp_2, din_temp_3, din_temp_4;
reg [1:0] change_result;



integer cnt_timer;

parameter T = 20;
reg time_stop;

always @(posedge clk or negedge rst_timer) begin
    if(!rst_timer) begin 
        time_stop <= 0; 
        cnt_timer <= 0;
    end
    else if(currentState == PASS_STATE || currentState == LOCKED_STATE || currentState == CHANGE_STATE) begin
        if(cnt_timer < T) begin
            cnt_timer = cnt_timer + 1'b1;
            time_stop <= 0;
        end else begin
            time_stop <= 1;
            cnt_timer <= 0;
        end
    end
end


endmodule