1// 2// Copyright (c) 2023 Renesas Electronics Corporation 3// Copyright (c) 2010-2024 Antmicro 4// 5// This file is licensed under the MIT License. 6// Full license text is available in 'LICENSE'. 7// 8 9`timescale 1ns / 1ps 10 11import renode_pkg::renode_runtime, renode_pkg::bus_connection, renode_pkg::LogWarning; 12 13module renode_ahb_manager #(int RenodeToCosimIndex = 0) ( 14 ref renode_runtime runtime, 15 renode_ahb_if bus 16); 17 import renode_ahb_pkg::*; 18 19 typedef logic [bus.AddressWidth-1:0] address_t; 20 typedef logic [bus.DataWidth-1:0] data_t; 21 wire clk = bus.hclk; 22 23 always @(runtime.controllers[RenodeToCosimIndex].reset_assert_request) begin 24 bus.hresetn = 0; 25 bus.haddr = '0; 26 bus.htrans = Idle; 27 repeat (2) @(posedge clk); 28 runtime.controllers[RenodeToCosimIndex].reset_assert_respond(); 29 end 30 31 always @(runtime.controllers[RenodeToCosimIndex].reset_deassert_request) begin 32 bus.hresetn = 1; 33 repeat (2) @(posedge clk); 34 runtime.controllers[RenodeToCosimIndex].reset_deassert_respond(); 35 end 36 37 always @(runtime.controllers[RenodeToCosimIndex].read_transaction_request) read_transaction(); 38 always @(runtime.controllers[RenodeToCosimIndex].write_transaction_request) write_transaction(); 39 40 task static write_transaction(); 41 renode_pkg::valid_bits_e valid_bits; 42 data_t data; 43 bit is_invalid; 44 45 valid_bits = runtime.controllers[RenodeToCosimIndex].write_transaction_data_bits; 46 data = data_t'(runtime.controllers[RenodeToCosimIndex].write_transaction_data & valid_bits); 47 configure_transfer(runtime.controllers[RenodeToCosimIndex].write_transaction_address, valid_bits, Write, is_invalid); 48 if (is_invalid) begin 49 runtime.controllers[RenodeToCosimIndex].write_respond(is_invalid); 50 return; 51 end 52 53 bus.hwstrb = bus.transfer_size_to_strobe(bus.valid_bits_to_transfer_size(valid_bits)); 54 bus.hwdata = data; 55 bus.htrans <= Idle; 56 57 do @(posedge clk); while (!bus.hready); 58 runtime.controllers[RenodeToCosimIndex].write_respond(is_response_error(bus.hresp)); 59 endtask 60 61 task static read_transaction(); 62 renode_pkg::valid_bits_e valid_bits; 63 data_t data; 64 bit is_invalid; 65 bit is_error; 66 67 valid_bits = runtime.controllers[RenodeToCosimIndex].read_transaction_data_bits; 68 configure_transfer(runtime.controllers[RenodeToCosimIndex].read_transaction_address, valid_bits, Read, is_invalid); 69 if (is_invalid) begin 70 runtime.controllers[RenodeToCosimIndex].read_respond(renode_pkg::data_t'(0), is_invalid); 71 return; 72 end 73 74 bus.htrans <= Idle; 75 76 do @(posedge clk); while (!bus.hready); 77 data = bus.hrdata; 78 is_error = is_response_error(bus.hresp); 79 runtime.controllers[RenodeToCosimIndex].read_respond(renode_pkg::data_t'(data) & valid_bits, is_error); 80 endtask 81 82 task static configure_transfer(renode_pkg::address_t address, renode_pkg::valid_bits_e valid_bits, transfer_direction_e direction, output logic is_invalid); 83 is_invalid = 0; 84 if (!bus.are_valid_bits_supported(valid_bits)) begin 85 is_invalid = 1; 86 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)); 87 return; 88 end 89 bus.hwrite = direction; 90 bus.hsize = bus.valid_bits_to_transfer_size(valid_bits); 91 bus.hburst = Single; 92 bus.haddr = address_t'(address); 93 bus.htrans <= NonSequential; 94 do @(posedge clk); while (!bus.hready); 95 endtask 96 97 function static bit is_response_error(response_t response); 98 if (response == Okay) begin 99 return 0; 100 end 101 runtime.connection.log(LogWarning, $sformatf("Error response from a Subordinate: 'h%h", response)); 102 return 1; 103 endfunction 104endmodule 105