This module wraps i2c_master_top to provide a CtrlPort Interface. Original-commit: adceebe070d5b15be434aa07961958dafedf5095
185 lines
5.2 KiB
Verilog
185 lines
5.2 KiB
Verilog
//
|
|
// Copyright 2021 Ettus Research, A National Instruments Brand
|
|
//
|
|
// SPDX-License-Identifier: LGPL-3.0-or-later
|
|
//
|
|
// Module: ctrlport_to_i2c
|
|
//
|
|
// Description:
|
|
//
|
|
// This module wraps a I2C master and provides a ControlPort interface.
|
|
//
|
|
// Parameters:
|
|
//
|
|
// BASE_ADDRESS : Base address for CtrlPort registers.
|
|
//
|
|
|
|
`default_nettype wire
|
|
|
|
|
|
module ctrlport_to_wb_i2c #(
|
|
parameter BASE_ADDRESS = 0
|
|
) (
|
|
//---------------------------------------------------------------
|
|
// ControlPort Slave
|
|
//---------------------------------------------------------------
|
|
|
|
input wire ctrlport_clk,
|
|
input wire ctrlport_rst,
|
|
|
|
input wire s_ctrlport_req_wr,
|
|
input wire s_ctrlport_req_rd,
|
|
input wire [19:0] s_ctrlport_req_addr,
|
|
input wire [31:0] s_ctrlport_req_data,
|
|
|
|
output reg s_ctrlport_resp_ack,
|
|
output reg [ 1:0] s_ctrlport_resp_status = 0,
|
|
output reg [31:0] s_ctrlport_resp_data = 0,
|
|
|
|
//---------------------------------------------------------------
|
|
// I2C signals
|
|
//---------------------------------------------------------------
|
|
// i2c clock line
|
|
input wire scl_pad_i, // SCL-line input
|
|
output wire scl_pad_o, // SCL-line output
|
|
output wire scl_pad_en_o, // SCL-line output enable (active low)
|
|
|
|
// i2c data line
|
|
input wire sda_pad_i, // SDA-line input
|
|
output wire sda_pad_o, // SDA-line output
|
|
output wire sda_pad_en_o // SDA-line output enable (active low)
|
|
);
|
|
|
|
`include "../rfnoc/core/ctrlport.vh"
|
|
`include "../wishbone/i2c_master.vh"
|
|
|
|
//---------------------------------------------------------------
|
|
// Translating CtrlPort <-> Wishbone I2C core
|
|
//---------------------------------------------------------------
|
|
|
|
reg wb_cyc_i; // Active bus cycle
|
|
reg wb_we_i = 1'b0; // Write access
|
|
reg [ 4:0] wb_adr_i = 5'b0;
|
|
reg [31:0] wb_dat_i = 32'b0;
|
|
wire wb_ack_o;
|
|
wire [31:0] wb_dat_o;
|
|
|
|
// Check for address to be in range [base_addr..base_addr+8)
|
|
localparam NUM_ADDRESSES = 8;
|
|
wire address_in_range = (s_ctrlport_req_addr >= BASE_ADDRESS) &&
|
|
(s_ctrlport_req_addr < BASE_ADDRESS + NUM_ADDRESSES);
|
|
|
|
// Following chapter 3.2.3 (classic standard SINGLE WRITE cycle) of
|
|
// https://cdn.opencores.org/downloads/wbspec_b4.pdf
|
|
always @(posedge ctrlport_clk) begin
|
|
// Reset internal registers and responses
|
|
if (ctrlport_rst) begin
|
|
s_ctrlport_resp_ack <= 0;
|
|
s_ctrlport_resp_data <= 0;
|
|
s_ctrlport_resp_status <= CTRL_STS_OKAY;
|
|
wb_cyc_i <= 0;
|
|
wb_we_i <= 0;
|
|
wb_dat_i <= 0;
|
|
wb_adr_i <= 0;
|
|
end else begin
|
|
// Request independent default assignments
|
|
s_ctrlport_resp_ack <= 1'b0;
|
|
|
|
// Wait for ack on active bus transactions
|
|
if (wb_cyc_i) begin
|
|
if (wb_ack_o) begin
|
|
// End bus cycle and generate response
|
|
wb_cyc_i <= 1'b0;
|
|
s_ctrlport_resp_ack <= 1'b1;
|
|
s_ctrlport_resp_data <= wb_dat_o;
|
|
//removed error condition since there is no error signal in i2c master
|
|
s_ctrlport_resp_status <= CTRL_STS_OKAY;
|
|
end
|
|
|
|
// Write requests
|
|
end else if (s_ctrlport_req_wr) begin
|
|
// Assume there is a valid address
|
|
//1-1 translation of wb to ctrl port interface
|
|
if (s_ctrlport_req_addr < 8) begin
|
|
wb_cyc_i <= 1'b1;
|
|
wb_we_i <= 1'b1;
|
|
wb_dat_i <= s_ctrlport_req_data;
|
|
end
|
|
case (s_ctrlport_req_addr)
|
|
BASE_ADDRESS + WB_PRER_LO: begin
|
|
wb_adr_i = WB_PRER_LO;
|
|
end
|
|
BASE_ADDRESS + WB_PRER_HI: begin
|
|
wb_adr_i = WB_PRER_HI;
|
|
end
|
|
BASE_ADDRESS + WB_CTR: begin
|
|
wb_adr_i = WB_CTR;
|
|
end
|
|
BASE_ADDRESS + WB_TXR: begin
|
|
wb_adr_i = WB_TXR;
|
|
end
|
|
BASE_ADDRESS + WB_CR: begin
|
|
wb_adr_i = WB_CR;
|
|
end
|
|
|
|
endcase
|
|
|
|
// Read requests
|
|
end else if (s_ctrlport_req_rd) begin
|
|
// Assume there is a valid address
|
|
wb_cyc_i <= 1'b1;
|
|
wb_we_i <= 1'b0;
|
|
|
|
case (s_ctrlport_req_addr)
|
|
BASE_ADDRESS + WB_PRER_LO: begin
|
|
wb_adr_i <= WB_PRER_LO;
|
|
end
|
|
BASE_ADDRESS + WB_PRER_HI: begin
|
|
wb_adr_i <= WB_PRER_HI;
|
|
end
|
|
BASE_ADDRESS + WB_CTR: begin
|
|
wb_adr_i <= WB_CTR;
|
|
end
|
|
BASE_ADDRESS + WB_RXR: begin
|
|
wb_adr_i = WB_RXR;
|
|
end
|
|
BASE_ADDRESS + WB_SR: begin
|
|
wb_adr_i = WB_SR;
|
|
end
|
|
// Respond with 0
|
|
default: begin
|
|
s_ctrlport_resp_ack <= 1'b1;
|
|
s_ctrlport_resp_data <= 'b0;
|
|
end
|
|
|
|
endcase
|
|
end
|
|
end
|
|
end
|
|
|
|
//wishbone-based i2c core
|
|
i2c_master_top #(
|
|
.ARST_LVL(1)
|
|
) i2c_master (
|
|
.wb_clk_i(ctrlport_clk),
|
|
.wb_rst_i(ctrlport_rst),
|
|
.arst_i(1'b0),
|
|
.wb_adr_i(wb_adr_i),
|
|
.wb_dat_i(wb_dat_i),
|
|
.wb_dat_o(wb_dat_o),
|
|
.wb_we_i(wb_we_i),
|
|
.wb_stb_i(wb_cyc_i),
|
|
.wb_cyc_i(wb_cyc_i),
|
|
.wb_ack_o(wb_ack_o),
|
|
.wb_inta_o(),
|
|
.scl_pad_i(scl_pad_i),
|
|
.scl_pad_o(scl_pad_o),
|
|
.scl_padoen_o(scl_pad_en_o),
|
|
.sda_pad_i(sda_pad_i),
|
|
.sda_pad_o(sda_pad_o),
|
|
.sda_padoen_o(sda_pad_en_o)
|
|
);
|
|
|
|
endmodule
|
|
|