It might be easier to use a state transition table to realize squeeze operations.
//------- ELK Test Bench --------- `timescale 1ms/1us module tb_elk; reg RST_N; reg CLK; reg IN_DOT; reg IN_DASH; ELK ELK_0(.RST_N (RST_N), .CLK (CLK) , .IN_DOT (IN_DOT) , .IN_DASH (IN_DASH) , .KEY_OUT (KEY_OUT) ); initial begin CLK <= 1'b1; forever begin #10; CLK <= ~CLK; end end initial begin RST_N <= 1'b0; #50; RST_N <= 1'b1; #1100000; $finish; end initial begin IN_DOT <= 1'b1; #063; IN_DOT <= 1'b0; #073; IN_DOT <= 1'b1; #323; IN_DOT <= 1'b0; #223; IN_DOT <= 1'b1; #243; IN_DOT <= 1'b0; #023; IN_DOT <= 1'b1; #1000000; end initial begin IN_DASH <= 1'b1; #183; IN_DASH <= 1'b0; #123; IN_DASH <= 1'b1; #223; IN_DASH <= 1'b0; #023; IN_DASH <= 1'b1; #260; IN_DASH <= 1'b0; #300; IN_DASH <= 1'b1; #1000000; end endmodule
module ELK(RST_N, CLK, IN_DOT, IN_DASH, KEY_OUT); input RST_N; input CLK; input IN_DOT; input IN_DASH; output KEY_OUT; reg KEY_OUT; reg m_dot; reg m_dash; reg[2:0] r_state; //--------- dot memory --------------------- always @ (negedge IN_DOT or negedge RST_N) begin if ( RST_N == 1'b0 ) begin m_dot <= 1'b0; end if ( IN_DOT == 1'b0) begin m_dot <= 1'b1; end end //--------- dash memory --------------------- always @ (negedge IN_DASH or negedge RST_N) begin if ( RST_N == 1'b0 ) begin m_dash <= 1'b0; end if ( IN_DASH == 1'b0) begin m_dash <= 1'b1; end end //--------- state output --------------------- always @ (r_state) begin case(r_state) 3'b000: begin KEY_OUT <= 1'b0; end 3'b001: begin KEY_OUT <= 1'b1; end 3'b010: begin KEY_OUT <= 1'b1; end 3'b011: begin KEY_OUT <= 1'b1; end 3'b100: begin KEY_OUT <= 1'b0; end 3'b101: begin KEY_OUT <= 1'b1; end 3'b110: begin KEY_OUT <= 1'b0; end default:begin end endcase end //--------- state transition --------------------- always @ (posedge CLK or negedge RST_N) begin if ( RST_N == 1'b0 ) begin r_state <= 3'b000; end else case (r_state) 3'b000:begin // idle if(IN_DASH == 1'b0) begin r_state <= 3'b001; end else if(IN_DOT == 1'b0) begin r_state <= 3'b101; end end 3'b001:begin // dash running 1 r_state <= 3'b010; m_dash <= 1'b0; end 3'b010:begin // dash running 2 r_state <= 3'b011; end 3'b011:begin // dash running 3 r_state <= 3'b100; end 3'b100:begin // dash running 4 if(IN_DOT == 1'b0 || m_dot == 1'b1) begin r_state <= 3'b101; m_dot <= 1'b0; end else if(IN_DASH == 1'b0) begin r_state <= 3'b001; end else begin r_state <= 3'b000; end end 3'b101:begin // dot running 1 r_state <= 3'b110; m_dot <= 1'b0; end 3'b110:begin // dot running 2 if(IN_DASH == 1'b0 || m_dash == 1'b1) begin r_state <= 3'b001; m_dash <= 1'b0; end else if(IN_DOT == 1'b0) begin r_state <= 3'b101; end else begin r_state <= 3'b000; end end default:begin end endcase end endmodule