2023-12-03 19:24:12 +00:00
|
|
|
/* Wishbone_driver.v - Implements a classic wishbone master
|
|
|
|
|
|
|
|
This file is part of the 9086 project.
|
|
|
|
|
2024-02-10 15:52:13 +00:00
|
|
|
Copyright (c) 2024 Efthymios Kritikos
|
2023-12-03 19:24:12 +00:00
|
|
|
|
|
|
|
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_IO_driver (
|
|
|
|
input wire clock,
|
|
|
|
input wire reset_n,
|
|
|
|
|
|
|
|
input wire [2:0] address,
|
|
|
|
input wire [15:0] data_bus_in,
|
|
|
|
output reg [15:0] data_bus_out,
|
|
|
|
input read_n,
|
|
|
|
input write_n,
|
|
|
|
input chip_select_n,
|
|
|
|
|
|
|
|
input wire wb_ctrl_ack,
|
|
|
|
output wire [29:0] wb_ctrl_adr,
|
|
|
|
output wire [1:0] wb_ctrl_bte,
|
|
|
|
output wire [2:0] wb_ctrl_cti,
|
|
|
|
output wire wb_ctrl_cyc,
|
|
|
|
input wire [31:0] wb_ctrl_dat_r,
|
|
|
|
output wire [31:0] wb_ctrl_dat_w,
|
|
|
|
input wire wb_ctrl_err,
|
|
|
|
output wire [3:0] wb_ctrl_sel,
|
|
|
|
output wire wb_ctrl_stb,
|
|
|
|
output wire wb_ctrl_we
|
|
|
|
);
|
|
|
|
|
|
|
|
reg [13:0]WISHBONE_ADDR=14'd0;
|
|
|
|
reg WISHBONE_ACTIVE_CYCLE=1'b0;
|
|
|
|
wire WISHBONE_ERROR_IN;
|
|
|
|
reg [3:0]WISHBONE_SELECT=4'd0;
|
|
|
|
reg WISHBONE_VALID_TRANSFER=1'b0;
|
|
|
|
reg WISHBONE_WRITE=1'b1;
|
|
|
|
wire WISHBONE_ACK_IN;
|
|
|
|
reg [31:0]WISHBONE_DATA_READ=32'd0;
|
|
|
|
wire [31:0]WISHBONE_DATA_WRITE;
|
|
|
|
|
|
|
|
assign WISHBONE_ACK_IN=wb_ctrl_ack;
|
|
|
|
assign wb_ctrl_adr={16'd0,WISHBONE_ADDR};
|
|
|
|
assign WISHBONE_ERROR_IN=wb_ctrl_err;
|
|
|
|
assign wb_ctrl_sel=WISHBONE_SELECT;
|
|
|
|
assign wb_ctrl_stb=WISHBONE_VALID_TRANSFER;
|
|
|
|
assign wb_ctrl_cyc=WISHBONE_ACTIVE_CYCLE;
|
|
|
|
assign wb_ctrl_we=WISHBONE_WRITE;
|
|
|
|
assign wb_ctrl_bte=2'b00; // Burst Type Extension 00:Linear burst
|
|
|
|
assign wb_ctrl_cti=3'b000; // Cycle Type Idenfier 000:Classic cycle
|
|
|
|
assign WISHBONE_DATA_WRITE=wb_ctrl_dat_r;
|
|
|
|
assign wb_ctrl_dat_w=WISHBONE_DATA_READ;
|
|
|
|
|
|
|
|
reg [31:0]WISHBONE_READ_BUFFER;
|
|
|
|
|
|
|
|
reg [1:0]just_transacted;
|
|
|
|
|
|
|
|
reg [1:0]WISHBONE_STATUS;
|
|
|
|
|
|
|
|
wire CYCLE_END=(WISHBONE_ACK_IN==1'b1);//||WISHBONE_ERROR_IN==1'b1);
|
|
|
|
|
|
|
|
always @( posedge clock )begin
|
|
|
|
if(reset_n==0)begin
|
|
|
|
just_transacted<=2'b0;
|
|
|
|
end
|
|
|
|
if(just_transacted==2'd1&&CYCLE_END==1'b1)begin
|
|
|
|
WISHBONE_READ_BUFFER<=WISHBONE_DATA_WRITE;
|
|
|
|
end
|
|
|
|
if(chip_select_n==0 && write_n==0 )begin
|
|
|
|
case (address)
|
|
|
|
3'h0: WISHBONE_DATA_READ[15:0] <=data_bus_in;
|
|
|
|
3'h1: WISHBONE_DATA_READ[31:16]<=data_bus_in;
|
|
|
|
3'h2: WISHBONE_ADDR[13:0]<=data_bus_in[13:0];
|
|
|
|
3'h3: begin end
|
|
|
|
default: begin end
|
|
|
|
endcase
|
|
|
|
|
|
|
|
case (address)
|
|
|
|
3'h3: begin
|
|
|
|
WISHBONE_ACTIVE_CYCLE<=1;
|
|
|
|
WISHBONE_VALID_TRANSFER<=1;
|
|
|
|
WISHBONE_SELECT<=4'hF;
|
|
|
|
end
|
|
|
|
default: begin end
|
|
|
|
endcase
|
|
|
|
if(address==3'h3)begin
|
|
|
|
WISHBONE_WRITE<=1'b1;//data_bus_in[0:0];
|
|
|
|
if(data_bus_in[0:0]==1'b1)begin //write req
|
|
|
|
just_transacted<=2'd2;
|
|
|
|
end else begin
|
|
|
|
just_transacted<=2'd1;
|
|
|
|
end
|
|
|
|
end
|
2024-02-10 15:52:13 +00:00
|
|
|
end else if(just_transacted!=2'd0&&CYCLE_END==1'b1)begin // In the unlikely scenario that the CPU wants to write without having checked for the previous write
|
2023-12-03 19:24:12 +00:00
|
|
|
WISHBONE_STATUS[0:0]<=WISHBONE_ACK_IN;
|
|
|
|
WISHBONE_STATUS[1:1]<=WISHBONE_ERROR_IN;
|
|
|
|
WISHBONE_ACTIVE_CYCLE<=0;
|
|
|
|
WISHBONE_VALID_TRANSFER<=0;
|
|
|
|
just_transacted<=2'b0;
|
|
|
|
end
|
|
|
|
|
|
|
|
if ( chip_select_n==0 && read_n==0 )begin
|
|
|
|
case (address)
|
|
|
|
/* verilator lint_off BLKSEQ */
|
|
|
|
/* Makes icarus verilog work as expected, not too sure if it helps real hardware yet*/
|
|
|
|
3'h0: data_bus_out = WISHBONE_READ_BUFFER[15:0];
|
|
|
|
3'h1: data_bus_out = WISHBONE_READ_BUFFER[31:16];
|
|
|
|
3'h2: data_bus_out = {13'd0,WISHBONE_STATUS,just_transacted==2'd0||CYCLE_END==1'b1}; //1:NOT BUSY 0:BUSY
|
|
|
|
default: data_bus_out = 16'h0;
|
|
|
|
/* verilator lint_on BLKSEQ */
|
|
|
|
endcase
|
|
|
|
end
|
|
|
|
end
|
|
|
|
|
|
|
|
endmodule
|