(Tim) Efthimis Kritikos
1966ab78b4
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.
92 lines
2.5 KiB
Verilog
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
|