`timescale 1ns / 1ps module rom_wb ( input wb_clk_i, input wb_rst_i, input [31:0] wb_dat_i, input [4:0] wb_adr_i, input wb_we_i, input [3:0] wb_sel_i, input wb_cyc_i, input wb_stb_i, output [31:0] wb_dat_o, output wb_ack_o ); reg ack_d1 = 1'b0; wire ack_w; wire[4:0] rom_addr_i; wire[31:0] rom_dat_i, rom_dat_o; wire rom_clk_i, rom_read_i, rom_write_i; assign rom_read_i = wb_cyc_i & wb_stb_i & !wb_we_i; assign rom_write_i = wb_cyc_i & wb_stb_i & wb_we_i; assign rom_dat_i = wb_dat_i; assign rom_addr_i = wb_adr_i; assign rom_clk_i = wb_clk_i; rom_ctrl rom_ctrl( .clk_i(rom_clk_i), .rst_i(0), .adr_i(rom_addr_i), .rd_i(rom_read_i), .dat_o(rom_dat_o), .wr_i(rom_write_i), .dat_i(rom_dat_i), .ack_o(ack_w) ); always @(posedge wb_clk_i, posedge wb_rst_i ) if( wb_rst_i ) ack_d1 <= 0; else ack_d1 <= ack_w; // если контроллер был занят, а стал свободен, значит контроллер завершил операцию и // нужно дёрнуть один раз ACK_O и положить на следующем такте, чтобы wishbone // master оповестился о конце операции slave'а assign wb_ack_o = ( ack_d1 ) && ( !ack_w ); assign wb_dat_o = rom_dat_o; endmodule