9086/system/peripherals/CPU_to_I2C_driver_bridge.v
(Tim) Efthimis Kritikos 1966ab78b4 Peripherals/I2C: Added a CPU I2C driver and wrote a bootloader that uses that to boot from an I2C eeprom
I'm happy to have reached 200 commits and with this, version v0.3.0 is functionally ready. I still need to do a fair bit of cleanup and bug fixing though before the actual release. With this commit I added a CPU I2C driver as well as a basic arbiter to have the hardware lcd controller and the software i2c communication pass through the same I2C driver and I2C bus. I also wrote a bootloader that reads code from an i2c eeprom to make sure the hardware works.
2024-02-09 23:30:58 +00:00

92 lines
2.5 KiB
Verilog

/* CPU_to_I2C_driver_bridge - Implements CPU interface for the I2C_driver
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 CPU_to_I2C_driver_bridge (
input wire clock,
input wire reset_n,
// CPU INTERFACE
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,
// I2C DRIVER INTERFACE
output wire [6:0] OUT_ADDRESS,
input wire OUT_BUSY,
output reg OUT_TRANSACT,
output reg DIR,
input wire [15:0] OUT_I2C_DATA_READ,
output reg [15:0] OUT_I2C_DATA_WRITE,
output reg TRANS_WIDTH,
output reg OUT_IGN_ACK
);
//assign data_bus_out=((address==3'h0)&&chip_select_n==1'b0&&read_n==1'b0)? 16'h0043 : 16'h0000;
//assign data_bus_out= (chip_select_n==1'b0&&read_n==1'b0) ? 16'h0043 : 16'h0000;
//assign data_bus_out= (1) ? 16'h0043 : 16'h0000;
reg [6:0] ADDRESS_REG=7'b1111111;
assign OUT_ADDRESS=ADDRESS_REG;
/* verilator lint_off UNUSEDSIGNAL */
reg [15:0]READ_DATA=16'h0;
/* verilator lint_on UNUSEDSIGNAL */
reg WAIT;
always @( posedge clock )begin
if ( reset_n==0 ) begin
WAIT<=0;
OUT_TRANSACT<=0;
end
if ( WAIT==1'b1 && OUT_BUSY==1'b1 )begin
WAIT<=1'b0;
OUT_TRANSACT<=0;
READ_DATA<=OUT_I2C_DATA_READ;
end
if ( chip_select_n==0 && read_n==0 )begin
case (address)
3'h0: data_bus_out <= {OUT_I2C_DATA_READ};
3'h2: data_bus_out <= {15'd0,OUT_BUSY|WAIT};
default: data_bus_out <= 16'h0;
endcase
end
if ( chip_select_n==0 && write_n==0 && address==3'd3 ) begin
OUT_TRANSACT<=1;
WAIT<=1;
end
if ( chip_select_n==0 && write_n==0 && address==3'd3 ) begin
DIR<=data_bus_in[8:8];
TRANS_WIDTH<=data_bus_in[9:9];
OUT_IGN_ACK<=data_bus_in[10:10];
end
if ( chip_select_n==0 && write_n==0 && address==3'd1 ) begin
ADDRESS_REG <= data_bus_in[14:8];
end
if ( chip_select_n==0 && write_n==0 && address==3'd2 ) begin
OUT_I2C_DATA_WRITE <= data_bus_in[15:0];
end
end
endmodule