Skip to content

Commit

Permalink
rtl/ice40_i2c_wb: Import the SB_I2C wrapper
Browse files Browse the repository at this point in the history
Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
  • Loading branch information
smunaut committed Oct 3, 2020
1 parent 02bd8fc commit e2a0c69
Show file tree
Hide file tree
Showing 3 changed files with 160 additions and 0 deletions.
17 changes: 17 additions & 0 deletions doc/ice40_i2c_wb.md
@@ -0,0 +1,17 @@
`SB_I2C` wishbone wrapper
=========================

Memory map
----------

### `SB_I2C` registers ( Write Only, `0x00-0x3C` )

This wrapper directly maps each register of `SB_I2C` to a distinct wishbone
word address. In this case for `SB_I2C` since the native bus is only 8 bits wide
this means that each 32 bits word of the wishbone bus has the upper 24 bits unused.
Also, all accesses have to be full width ( 32 bits ).

Refer to Lattice TN1276 for the exact register description.

Note that the upper 4 bits of the native bus address are automatically filled
by the wrapper.
1 change: 1 addition & 0 deletions no2core.mk
Expand Up @@ -2,6 +2,7 @@ CORE := no2ice40

RTL_SRCS_no2ice40 := $(addprefix rtl/, \
ice40_ebr.v \
ice40_i2c_wb.v \
ice40_rgb_wb.v \
ice40_spi_wb.v \
ice40_spram_gen.v \
Expand Down
142 changes: 142 additions & 0 deletions rtl/ice40_i2c_wb.v
@@ -0,0 +1,142 @@
/*
* ice40_i2c_wb.v
*
* vim: ts=4 sw=4
*
* Wishbone wrapper to use the SB_I2C hardmacro a bit more easily
*
* Copyright (C) 2020 Sylvain Munaut <tnt@246tNt.com>
* SPDX-License-Identifier: CERN-OHL-P-2.0
*/

`default_nettype none

module ice40_i2c_wb #(
parameter integer WITH_IOB = 1,
parameter integer UNIT = 0 // Unit 0 or 1
)(
// IO
// IOBs included
inout wire i2c_scl,
inout wire i2c_sda,

// Raw signals
input wire i2c_scl_i,
output wire i2c_scl_o,
output wire i2c_scl_oe,

input wire i2c_sda_i,
output wire i2c_sda_o,
output wire i2c_sda_oe,

// Wishbone interface
input wire [ 3:0] wb_addr,
output wire [31:0] wb_rdata,
input wire [31:0] wb_wdata,
input wire wb_we,
input wire wb_cyc,
output wire wb_ack,

// Aux signals
output wire irq,
output wire wakeup,

// Common
input wire clk,
input wire rst
);

// Signals
// -------

wire [7:0] sb_addr;
wire [7:0] sb_di;
wire [7:0] sb_do;
wire sb_rw;
wire sb_stb;
wire sb_ack;


// Hard block
// ----------

`ifndef SIM
(* SCL_INPUT_FILTERED=1 *)
SB_I2C #(
.BUS_ADDR74(UNIT ? "0b0011" : "0b0001")
) i2c_I (
.SBCLKI (clk),
.SBRWI (sb_rw),
.SBSTBI (sb_stb),
.SBADRI7 (sb_addr[7]),
.SBADRI6 (sb_addr[6]),
.SBADRI5 (sb_addr[5]),
.SBADRI4 (sb_addr[4]),
.SBADRI3 (sb_addr[3]),
.SBADRI2 (sb_addr[2]),
.SBADRI1 (sb_addr[1]),
.SBADRI0 (sb_addr[0]),
.SBDATI7 (sb_di[7]),
.SBDATI6 (sb_di[6]),
.SBDATI5 (sb_di[5]),
.SBDATI4 (sb_di[4]),
.SBDATI3 (sb_di[3]),
.SBDATI2 (sb_di[2]),
.SBDATI1 (sb_di[1]),
.SBDATI0 (sb_di[0]),
.SCLI (i2c_scl_i),
.SDAI (i2c_sda_i),
.SBDATO7 (sb_do[7]),
.SBDATO6 (sb_do[6]),
.SBDATO5 (sb_do[5]),
.SBDATO4 (sb_do[4]),
.SBDATO3 (sb_do[3]),
.SBDATO2 (sb_do[2]),
.SBDATO1 (sb_do[1]),
.SBDATO0 (sb_do[0]),
.SBACKO (sb_ack),
.I2CIRQ (irq),
.I2CWKUP (wakeup),
.SCLO (i2c_scl_o),
.SCLOE (i2c_scl_oe),
.SDAO (i2c_sda_o),
.SDAOE (i2c_sda_oe)
);
`else
assign sb_ack = sb_stb;
assign sb_do = 8'h00;
`endif


// IOB (if needed)
// ---------------

generate
if (WITH_IOB) begin

SB_IO #(
.PIN_TYPE(6'b101001),
.PULLUP(1'b1)
) i2c_io_I[1:0] (
.PACKAGE_PIN ({i2c_scl, i2c_sda }),
.OUTPUT_ENABLE({i2c_scl_oe, i2c_sda_oe}),
.D_OUT_0 ({i2c_scl_o, i2c_sda_o }),
.D_IN_0 ({i2c_scl_i, i2c_sda_i })
);

end
endgenerate


// Bus interface
// -------------

assign sb_addr = { (UNIT ? 4'h3 : 4'h1), wb_addr };
assign sb_di = wb_wdata[7:0];
assign sb_rw = wb_we;
assign sb_stb = wb_cyc;

assign wb_rdata = { 24'h0000, wb_cyc ? sb_do : 8'h00 };
assign wb_ack = sb_ack;

endmodule // ice40_i2c_wb

0 comments on commit e2a0c69

Please sign in to comment.