/* Wishbone_driver.v - Implements a classic wishbone master that maps directly in memory space

   This file is part of the 9086 project.

   Copyright (c) 2024 Efthymios Kritikos

   This program is free software: you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation, either version 3 of the License, or
   (at your option) any later version.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.

   You should have received a copy of the GNU General Public License
   along with this program.  If not, see <http://www.gnu.org/licenses/>.  */

module Wishbone_memory_driver (
	input wire clock,

/* verilator lint_off UNUSEDSIGNAL */
	input wire reset_n,
/* verilator lint_on UNUSEDSIGNAL */

	input wire [19:0] address,
	input wire [15:0] data_bus_in,
	output reg [15:0] data_bus_out,
	output wire wait_state,
	input read_n,
	input write_n,
	input chip_select_n,
	input BHE,

	input  wire          wb_mem_ack,
	output wire   [24:0] wb_mem_adr,
	output reg          wb_mem_cyc,

/* verilator lint_off UNUSEDSIGNAL */
// I don't yet use the upper word
	input  wire   [31:0] wb_mem_data_r,
/* verilator lint_on UNUSEDSIGNAL */

	output wire   [31:0] wb_mem_data_w,

/* verilator lint_off UNUSEDSIGNAL */
	input  wire          wb_mem_err,
/* verilator lint_on UNUSEDSIGNAL */

	output wire    [3:0] wb_mem_sel,
	output reg          wb_mem_stb,
	output wire          wb_mem_we
);

assign wb_mem_adr={6'd0,address[19:1]};
assign wb_mem_sel={2'b11,!BHE,!address[0]};

always @(posedge clock)begin
	wb_mem_cyc<=( (!read_n||!write_n)^(wb_mem_ack) )&(!chip_select_n);
	wb_mem_stb<=( (!read_n||!write_n)^(wb_mem_ack) )&(!chip_select_n);
end

always @(posedge wb_mem_ack)begin
	data_bus_out<=wb_mem_data_r[15:0];
end
assign wb_mem_data_w={16'd0,data_bus_in};

assign wait_state=( (!read_n||!write_n)^(wb_mem_ack) )&(!chip_select_n);

assign wb_mem_we=read_n;

endmodule
