mirror of
https://github.com/fairwaves/UHD-Fairwaves.git
synced 2025-11-03 05:23:14 +00:00
117 lines
3.5 KiB
Verilog
117 lines
3.5 KiB
Verilog
//
|
|
// Copyright 2012 Ettus Research LLC
|
|
//
|
|
// 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/>.
|
|
//
|
|
|
|
// Simple I2C core
|
|
|
|
// Settings reg map:
|
|
//
|
|
// BASE+0 control register
|
|
// byte0 - control bits, data byte, or command bits, prescaler
|
|
// byte1 - what to do? (documented in cpp file)
|
|
// write prescaler lo
|
|
// write prescaler hi
|
|
// write control
|
|
// write data
|
|
// write command
|
|
// read data
|
|
// read status
|
|
//
|
|
|
|
// Readback:
|
|
//
|
|
// byte0 has readback value based on the last read command
|
|
//
|
|
|
|
module simple_i2c_core
|
|
#(
|
|
//settings register base address
|
|
parameter BASE = 0,
|
|
|
|
//i2c line level at reset
|
|
parameter ARST_LVL = 1
|
|
)
|
|
(
|
|
//clock and synchronous reset
|
|
input clock, input reset,
|
|
|
|
//32-bit settings bus inputs
|
|
input set_stb, input [7:0] set_addr, input [31:0] set_data,
|
|
|
|
//32-bit data readback
|
|
output reg [31:0] readback,
|
|
|
|
//read is high when i2c core can begin another transaction
|
|
output reg ready,
|
|
|
|
// I2C signals
|
|
// i2c clock line
|
|
input scl_pad_i, // SCL-line input
|
|
output scl_pad_o, // SCL-line output (always 1'b0)
|
|
output scl_padoen_o, // SCL-line output enable (active low)
|
|
|
|
// i2c data line
|
|
input sda_pad_i, // SDA-line input
|
|
output sda_pad_o, // SDA-line output (always 1'b0)
|
|
output sda_padoen_o, // SDA-line output enable (active low)
|
|
|
|
//optional debug output
|
|
output [31:0] debug
|
|
);
|
|
|
|
//declare command settings register
|
|
wire [7:0] sr_what, sr_data;
|
|
wire sr_changed;
|
|
setting_reg #(.my_addr(BASE+0),.width(16)) i2c_cmd_sr(
|
|
.clk(clock),.rst(reset),.strobe(set_stb),.addr(set_addr),.in(set_data),
|
|
.out({sr_what, sr_data}),.changed(sr_changed));
|
|
|
|
//declare wb interface signals
|
|
wire [2:0] wb_addr;
|
|
wire [7:0] wb_data_mosi;
|
|
wire [7:0] wb_data_miso;
|
|
wire wb_we, wb_stb, wb_cyc;
|
|
wire wb_ack;
|
|
|
|
//create wishbone-based i2c core
|
|
i2c_master_top #(.ARST_LVL(ARST_LVL)) i2c
|
|
(.wb_clk_i(clock),.wb_rst_i(reset),.arst_i(1'b0),
|
|
.wb_adr_i(wb_addr),.wb_dat_i(wb_data_mosi),.wb_dat_o(wb_data_miso),
|
|
.wb_we_i(wb_we),.wb_stb_i(wb_stb),.wb_cyc_i(wb_cyc),
|
|
.wb_ack_o(wb_ack),.wb_inta_o(),
|
|
.scl_pad_i(scl_pad_i),.scl_pad_o(scl_pad_o),.scl_padoen_o(scl_padoen_o),
|
|
.sda_pad_i(sda_pad_i),.sda_pad_o(sda_pad_o),.sda_padoen_o(sda_padoen_o) );
|
|
|
|
//not ready between setting register and wishbone ack
|
|
always @(posedge clock) begin
|
|
if (reset || wb_ack) ready <= 1;
|
|
else if (sr_changed) ready <= 0;
|
|
end
|
|
|
|
//register wishbone data on every ack
|
|
always @(posedge clock) begin
|
|
if (wb_ack) readback <= {24'b0, wb_data_miso};
|
|
end
|
|
|
|
//assign wishbone signals
|
|
assign wb_addr = sr_what[2:0];
|
|
assign wb_stb = sr_changed;
|
|
assign wb_we = wb_stb && sr_what[3];
|
|
assign wb_cyc = wb_stb;
|
|
assign wb_data_mosi = sr_data;
|
|
|
|
endmodule //simple_i2c_core
|