blob: e79ad25ad87fa86205234063b8e0909824d11cad [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
//
// TL-UL error responder module, used by tlul_socket_1n to help response
// to requests to no correct address space. Responses are always one cycle
// after request with no stalling unless response is stuck on the way out.
module tlul_err_resp (
input clk_i,
input rst_ni,
input tlul_pkg::tl_h2d_t tl_h_i,
output tlul_pkg::tl_d2h_t tl_h_o
);
import tlul_pkg::*;
import prim_mubi_pkg::*;
tl_a_op_e err_opcode;
logic [$bits(tl_h_i.a_source)-1:0] err_source;
logic [$bits(tl_h_i.a_size)-1:0] err_size;
logic err_req_pending, err_rsp_pending;
mubi4_t err_instr_type;
tlul_pkg::tl_d2h_t tl_h_o_int;
tlul_rsp_intg_gen #(
.EnableRspIntgGen(1),
.EnableDataIntgGen(1)
) u_intg_gen (
.tl_i(tl_h_o_int),
.tl_o(tl_h_o)
);
always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin
err_req_pending <= 1'b0;
err_source <= {top_pkg::TL_AIW{1'b0}};
err_opcode <= Get;
err_size <= '0;
err_instr_type <= MuBi4False;
end else if (tl_h_i.a_valid && tl_h_o_int.a_ready) begin
err_req_pending <= 1'b1;
err_source <= tl_h_i.a_source;
err_opcode <= tl_h_i.a_opcode;
err_size <= tl_h_i.a_size;
err_instr_type <= tl_h_i.a_user.instr_type;
end else if (!err_rsp_pending) begin
err_req_pending <= 1'b0;
end
end
assign tl_h_o_int.a_ready = ~err_rsp_pending & ~(err_req_pending & ~tl_h_i.d_ready);
assign tl_h_o_int.d_valid = err_req_pending | err_rsp_pending;
assign tl_h_o_int.d_data = (mubi4_test_true_strict(err_instr_type)) ? DataWhenInstrError :
DataWhenError;
assign tl_h_o_int.d_source = err_source;
assign tl_h_o_int.d_sink = '0;
assign tl_h_o_int.d_param = '0;
assign tl_h_o_int.d_size = err_size;
assign tl_h_o_int.d_opcode = (err_opcode == Get) ? AccessAckData : AccessAck;
assign tl_h_o_int.d_user = '0;
assign tl_h_o_int.d_error = 1'b1;
always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin
err_rsp_pending <= 1'b0;
end else if ((err_req_pending || err_rsp_pending) && !tl_h_i.d_ready) begin
err_rsp_pending <= 1'b1;
end else begin
err_rsp_pending <= 1'b0;
end
end
// Waive unused bits of tl_h_i
logic unused_tl_h;
assign unused_tl_h = ^tl_h_i;
endmodule