blob: 1790c1c58bea643f0efa97aca9597a5d6ee66d11 [file] [log] [blame]
// Copyright lowRISC contributors.
// Licensed under the Apache License, Version 2.0, see LICENSE for details.
// SPDX-License-Identifier: Apache-2.0
/**
* Tile-Link UL adapter for Register interface
*/
module tlul_adapter_reg import tlul_pkg::*; #(
parameter int RegAw = 8,
parameter int RegDw = 32, // Shall be matched with TL_DW
localparam int RegBw = RegDw/8
) (
input clk_i,
input rst_ni,
// TL-UL interface
input tl_h2d_t tl_i,
output tl_d2h_t tl_o,
// Register interface
output logic re_o,
output logic we_o,
output logic [RegAw-1:0] addr_o,
output logic [RegDw-1:0] wdata_o,
output logic [RegBw-1:0] be_o,
input [RegDw-1:0] rdata_i,
input error_i
);
localparam int IW = $bits(tl_i.a_source);
localparam int SZW = $bits(tl_i.a_size);
logic outstanding; // Indicates current request is pending
logic a_ack, d_ack;
logic [RegDw-1:0] rdata;
logic error;
logic [IW-1:0] reqid;
logic [SZW-1:0] reqsz;
tl_d_op_e rspop;
assign a_ack = tl_i.a_valid & tl_o.a_ready;
assign d_ack = tl_o.d_valid & tl_i.d_ready;
// Request signal
assign we_o = a_ack & ((tl_i.a_opcode == PutFullData) | (tl_i.a_opcode == PutPartialData));
assign re_o = a_ack & (tl_i.a_opcode == Get);
assign addr_o = tl_i.a_address[RegAw-1:0];
assign wdata_o = tl_i.a_data;
assign be_o = tl_i.a_mask;
always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) outstanding <= 1'b0;
else if (a_ack) outstanding <= 1'b1;
else if (d_ack) outstanding <= 1'b0;
end
always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin
reqid <= '0;
reqsz <= '0;
rspop <= AccessAck;
end else if (a_ack) begin
reqid <= tl_i.a_source;
reqsz <= tl_i.a_size;
rspop <= (re_o) ? AccessAckData : AccessAck ;
end
end
always_ff @(posedge clk_i or negedge rst_ni) begin
if (!rst_ni) begin
rdata <= '0;
error <= 1'b0;
end else if (a_ack) begin
rdata <= rdata_i;
error <= error_i | (tl_i.a_user.parity_en == 1'b1);
end
end
assign tl_o = '{
a_ready: ~outstanding,
d_valid: outstanding,
d_opcode: rspop,
d_param: '0,
d_size: reqsz,
d_source: reqid,
d_sink: '0,
d_data: rdata,
d_user: '0,
d_error: error
};
`ASSERT_INIT(MatchedWidthAssert, RegDw == top_pkg::TL_DW)
endmodule