always@(negedge reset)
begin error = 1'b0;
data_out = 8'b0000_0000;
addr = 8'b00000000;
write_enb_r = 3'b000;
fsm_write_enb = 1'b0;
state_r = 4'b0000;
state = 4'b0000;
parity = 8'b0000_0000;
parity_delayed = 8'b0000_0000;
sus_data_in = 1'b0;
end assign busy = sus_data_in;
always @(data_status) begin : addr_mux
if (data_status == 1'b1) begin case (data_in)
mem0 : begin write_enb_r[0] = 1'b1;
write_enb_r[1] = 1'b0;
write_enb_r[2] = 1'b0;
write_enb_r[3] = 1'b0;
end mem1 : begin write_enb_r[0] = 1'b0;
write_enb_r[1] = 1'b1;
write_enb_r[2] = 1'b0;
write_enb_r[3] = 1'b0;
end mem2 : begin write_enb_r[0] = 1'b0;
write_enb_r[1] = 1'b0;
write_enb_r[2] = 1'b1;
write_enb_r[3] = 1'b0;
end
mem3 : begin write_enb_r[0] = 1'b0;
write_enb_r[1] = 1'b0;
write_enb_r[2] = 1'b0;
write_enb_r[3] = 1'b1;
end default :write_enb_r = 3'b000;
endcase // $display(" data_inii %d ,mem0 %d ,mem1 %d ,mem2 %d mem3",data_in,mem0,mem1,mem2,mem3);
end //if
end //addr_mux;
always @(posedge clk) begin : fsm_state
state_r <= state;
end //fsm_state;
always @(state_r or data_status or ffee or hold or data_in)
begin : fsm_core
state = state_r; //Default state assignment
case (state_r)
ADDR_WAIT : begin if ((data_status == 1'b1) &&
((mem0 == data_in)||(mem1 == data_in)||(mem3 == data_in) ||(mem2 == data_in))) begin if (ffee == 1'b1) begin state = DATA_LOAD;
end elsebegin state = BUSY_STATE;
end //if
end //if;
sus_data_in = !ffee;
if ((data_status == 1'b1) &&
((mem0 == data_in)||(mem1 == data_in)||(mem3 == data_in) ||(mem2 == data_in)) &&
(ffee == 1'b1)) begin addr = data_in;
data_out = data_in;
fsm_write_enb = 1'b1;
end elsebegin fsm_write_enb = 1'b0;
end //if
end // of case ADDR_WAIT
PARITY_LOAD : begin state = ADDR_WAIT;
data_out = data_in;
fsm_write_enb = 1'b0;
end // of case PARITY_LOAD
DATA_LOAD : begin if ((data_status == 1'b1) &&
(hold == 1'b0)) begin state = DATA_LOAD;
end elseif ((data_status == 1'b0) &&
(hold == 1'b0)) begin state = PARITY_LOAD;
end elsebegin state = HOLD_STATE;
end //if
sus_data_in = 1'b0;
if ((data_status == 1'b1) &&
(hold == 1'b0)) begin data_out = data_in;
fsm_write_enb = 1'b1;
end elseif ((data_status == 1'b0) &&
(hold == 1'b0)) begin data_out = data_in;
fsm_write_enb = 1'b1;
end elsebegin fsm_write_enb = 1'b0;
end //if
end //end of case DATA_LOAD
HOLD_STATE : begin if (hold == 1'b1) begin state = HOLD_STATE;
end elseif ((hold == 1'b0) && (data_status == 1'b0)) begin state = PARITY_LOAD;
end elsebegin state = DATA_LOAD;
end //if
if (hold == 1'b1) begin sus_data_in = 1'b1;
fsm_write_enb = 1'b0;
end elsebegin fsm_write_enb = 1'b1;
data_out = data_in;
end //if
end //end of case HOLD_STATE
BUSY_STATE : begin if (ffee == 1'b0) begin state = BUSY_STATE;
end elsebegin state = DATA_LOAD;
end //if
if (ffee == 1'b0) begin sus_data_in = 1'b1;
end elsebegin addr = data_in; // hans
data_out = data_in;
fsm_write_enb = 1'b1;
end //if
end //end of case BUSY_STATE
endcase end //fsm_core