blob: b2d5198b48da637a7fb5b57769fb7db525f24fa7 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// Description: interface between a req/ack interface and a fifo
//
module edn_ack_sm (
input logic clk_i,
input logic rst_ni,
input logic req_i,
output logic ack_o,
input logic fifo_not_empty_i,
output logic fifo_pop_o
);
// Encoding generated with ./sparse-fsm-encode.py -d 3 -m 3 -n 6 -s 4028491767
// Hamming distance histogram:
//
// 0: --
// 1: --
// 2: --
// 3: |||||||||||||||||||| (33.33%)
// 4: |||||||||||||||||||| (33.33%)
// 5: |||||||||||||||||||| (33.33%)
// 6: --
//
// Minimum Hamming distance: 3
// Maximum Hamming distance: 5
//
localparam int StateWidth = 6;
typedef enum logic [StateWidth-1:0] {
Idle = 6'b110101, // idle (hamming distance = 3)
AckImmed = 6'b001011, // ack the request immediately
AckWait = 6'b111010 // wait until the fifo has an entry
} state_e;
state_e state_d, state_q;
logic [StateWidth-1:0] state_raw_q;
// This primitive is used to place a size-only constraint on the
// flops in order to prevent FSM state encoding optimizations.
prim_flop #(
.Width(StateWidth),
.ResetValue(StateWidth'(Idle))
) u_state_regs (
.clk_i,
.rst_ni,
.d_i ( state_d ),
.q_o ( state_raw_q )
);
assign state_q = state_e'(state_raw_q);
always_comb begin
state_d = state_q;
ack_o = 1'b0;
fifo_pop_o = 1'b0;
unique case (state_q)
Idle: begin
if (req_i) begin
if (fifo_not_empty_i) begin
state_d = AckImmed;
end else begin
state_d = AckWait;
end
end
end
AckImmed: begin
ack_o = 1'b1;
fifo_pop_o = 1'b1;
state_d = Idle;
end
AckWait: begin
if (fifo_not_empty_i) begin
ack_o = 1'b1;
fifo_pop_o = 1'b1;
state_d = Idle;
end
end
default: state_d = Idle;
endcase
end
endmodule