blob: 9fd3ac0a1c8aa358af71dd867491b9846d92b50b [file]
//
// Copyright (c) 2023 Renesas Electronics Corporation
// Copyright (c) 2010-2024 Antmicro
//
// This file is licensed under the MIT License.
// Full license text is available in 'LICENSE'.
//
`timescale 1ns / 1ps
import renode_pkg::renode_runtime, renode_pkg::bus_connection, renode_pkg::LogWarning;
module renode_ahb_manager #(int RenodeToCosimIndex = 0) (
ref renode_runtime runtime,
renode_ahb_if bus
);
import renode_ahb_pkg::*;
typedef logic [bus.AddressWidth-1:0] address_t;
typedef logic [bus.DataWidth-1:0] data_t;
wire clk = bus.hclk;
always @(runtime.controllers[RenodeToCosimIndex].reset_assert_request) begin
bus.hresetn = 0;
bus.haddr = '0;
bus.htrans = Idle;
repeat (2) @(posedge clk);
runtime.controllers[RenodeToCosimIndex].reset_assert_respond();
end
always @(runtime.controllers[RenodeToCosimIndex].reset_deassert_request) begin
bus.hresetn = 1;
repeat (2) @(posedge clk);
runtime.controllers[RenodeToCosimIndex].reset_deassert_respond();
end
always @(runtime.controllers[RenodeToCosimIndex].read_transaction_request) read_transaction();
always @(runtime.controllers[RenodeToCosimIndex].write_transaction_request) write_transaction();
task static write_transaction();
renode_pkg::valid_bits_e valid_bits;
data_t data;
bit is_invalid;
valid_bits = runtime.controllers[RenodeToCosimIndex].write_transaction_data_bits;
data = data_t'(runtime.controllers[RenodeToCosimIndex].write_transaction_data & valid_bits);
configure_transfer(runtime.controllers[RenodeToCosimIndex].write_transaction_address, valid_bits, Write, is_invalid);
if (is_invalid) begin
runtime.controllers[RenodeToCosimIndex].write_respond(is_invalid);
return;
end
bus.hwstrb = bus.transfer_size_to_strobe(bus.valid_bits_to_transfer_size(valid_bits));
bus.hwdata = data;
bus.htrans <= Idle;
do @(posedge clk); while (!bus.hready);
runtime.controllers[RenodeToCosimIndex].write_respond(is_response_error(bus.hresp));
endtask
task static read_transaction();
renode_pkg::valid_bits_e valid_bits;
data_t data;
bit is_invalid;
bit is_error;
valid_bits = runtime.controllers[RenodeToCosimIndex].read_transaction_data_bits;
configure_transfer(runtime.controllers[RenodeToCosimIndex].read_transaction_address, valid_bits, Read, is_invalid);
if (is_invalid) begin
runtime.controllers[RenodeToCosimIndex].read_respond(renode_pkg::data_t'(0), is_invalid);
return;
end
bus.htrans <= Idle;
do @(posedge clk); while (!bus.hready);
data = bus.hrdata;
is_error = is_response_error(bus.hresp);
runtime.controllers[RenodeToCosimIndex].read_respond(renode_pkg::data_t'(data) & valid_bits, is_error);
endtask
task static configure_transfer(renode_pkg::address_t address, renode_pkg::valid_bits_e valid_bits, transfer_direction_e direction, output logic is_invalid);
is_invalid = 0;
if (!bus.are_valid_bits_supported(valid_bits)) begin
is_invalid = 1;
runtime.connection.log(LogWarning, $sformatf("Unsupported transaction width of %d for AHB bus with width %d. No transaction will be performed.", renode_pkg::valid_bits_to_transaction_width(valid_bits), bus.DataWidth));
return;
end
bus.hwrite = direction;
bus.hsize = bus.valid_bits_to_transfer_size(valid_bits);
bus.hburst = Single;
bus.haddr = address_t'(address);
bus.htrans <= NonSequential;
do @(posedge clk); while (!bus.hready);
endtask
function static bit is_response_error(response_t response);
if (response == Okay) begin
return 0;
end
runtime.connection.log(LogWarning, $sformatf("Error response from a Subordinate: 'h%h", response));
return 1;
endfunction
endmodule