gateware/icE1usb: Replace local I2C core with no2misc one

This core has been merged (and improved) upstream, so
update the submodule, remove local copy and make the required
tweaks.

Signed-off-by: Sylvain Munaut <tnt@246tNt.com>
Change-Id: I79fca561fee32bbaec94882b4f65c7ecaa44be11
This commit is contained in:
Sylvain Munaut 2022-05-03 13:38:51 +02:00
parent 9e02d4cd99
commit 921f4779f5
5 changed files with 7 additions and 313 deletions

@ -1 +1 @@
Subproject commit 16103ac61c8f11e63e043229a0a7a085bc38bde0
Subproject commit f9d1d47620ce81e9545287c585a5e8f0873b1661

View File

@ -3,8 +3,6 @@ PROJ=icE1usb
PROJ_DEPS := no2e1 no2ice40 no2misc no2usb
PROJ_RTL_SRCS := $(addprefix rtl/, \
i2c_master.v \
i2c_master_wb.v \
led_blinker.v \
misc.v \
sr_btn_if.v \

View File

@ -1,192 +0,0 @@
/*
* i2c_master.v
*
* vim: ts=4 sw=4
*
* Copyright (C) 2019-2020 Sylvain Munaut <tnt@246tNt.com>
* SPDX-License-Identifier: CERN-OHL-P-2.0
*/
`default_nettype none
module i2c_master #(
parameter integer DW = 3
)(
// IOs
output reg scl_oe,
output reg sda_oe,
input wire sda_i,
// Control
input wire [7:0] data_in,
input wire ack_in,
input wire [1:0] cmd,
input wire stb,
output wire [7:0] data_out,
output wire ack_out,
output wire ready,
// Clock / Reset
input wire clk,
input wire rst
);
// Commands
localparam [2:0] CMD_START = 3'b00;
localparam [2:0] CMD_STOP = 3'b01;
localparam [2:0] CMD_WRITE = 3'b10;
localparam [2:0] CMD_READ = 3'b11;
// FSM states
localparam
ST_IDLE = 0,
ST_LOWER_SCL = 1,
ST_LOW_CYCLE = 2,
ST_RISE_SCL = 3,
ST_HIGH_CYCLE = 4;
// Signals
// -------
reg [2:0] state;
reg [2:0] state_nxt;
reg [1:0] cmd_cur;
reg [DW:0] cyc_cnt;
wire cyc_now;
reg [3:0] bit_cnt;
wire bit_last;
reg [8:0] data_reg;
// State Machine
// -------------
always @(posedge clk)
if (rst)
state <= ST_IDLE;
else
state <= state_nxt;
always @(*)
begin
// Default is to stay put
state_nxt = state;
// Act depending on current state
case (state)
ST_IDLE:
if (stb)
state_nxt = ST_LOW_CYCLE;
ST_LOW_CYCLE:
if (cyc_now)
state_nxt = ST_RISE_SCL;
ST_RISE_SCL:
if (cyc_now)
state_nxt = ST_HIGH_CYCLE;
ST_HIGH_CYCLE:
if (cyc_now)
state_nxt = (cmd_cur == 2'b01) ? ST_IDLE : ST_LOWER_SCL;
ST_LOWER_SCL:
if (cyc_now)
state_nxt = bit_last ? ST_IDLE : ST_LOW_CYCLE;
endcase
end
// Misc control
// ------------
always @(posedge clk)
if (stb)
cmd_cur <= cmd;
// Baud Rate generator
// -------------------
always @(posedge clk)
if (state == ST_IDLE)
cyc_cnt <= 0;
else
cyc_cnt <= cyc_cnt[DW] ? 0 : (cyc_cnt + 1);
assign cyc_now = cyc_cnt[DW];
// Bit count
// ---------
always @(posedge clk)
if ((state == ST_LOWER_SCL) && cyc_now)
bit_cnt <= bit_cnt + 1;
else if (stb)
case (cmd)
2'b00: bit_cnt <= 4'h8; // START
2'b01: bit_cnt <= 4'h8; // STOP
2'b10: bit_cnt <= 4'h0; // Write
2'b11: bit_cnt <= 4'h0; // Read
default: bit_cnt <= 4'hx;
endcase
assign bit_last = bit_cnt[3];
// Data register
// -------------
always @(posedge clk)
if ((state == ST_HIGH_CYCLE) && cyc_now)
data_reg <= { data_reg[7:0], sda_i };
else if (stb)
// Only handle Write / Read. START & STOP is handled in IO mux
data_reg <= cmd[0] ? { 8'b11111111, ack_in } : { data_in, 1'b1 };
// IO
// --
always @(posedge clk)
if (rst)
scl_oe <= 1'b0;
else if (cyc_now) begin
if (state == ST_LOWER_SCL)
scl_oe <= 1'b1;
else if (state == ST_RISE_SCL)
scl_oe <= 1'b0;
end
always @(posedge clk)
if (rst)
sda_oe <= 1'b0;
else if (cyc_now) begin
if (~cmd_cur[1]) begin
if (state == ST_LOW_CYCLE)
sda_oe <= cmd_cur[0];
else if (state == ST_HIGH_CYCLE)
sda_oe <= ~cmd_cur[0];
end else begin
if (state == ST_LOW_CYCLE)
sda_oe <= ~data_reg[8];
end
end
// User IF
// -------
assign data_out = data_reg[8:1];
assign ack_out = data_reg[0];
assign ready = (state == ST_IDLE);
endmodule

View File

@ -1,102 +0,0 @@
/*
* i2c_master_wb.v
*
* vim: ts=4 sw=4
*
* Wishbone wrapper with optional buffering for i2c_master core
*
* Copyright (C) 2019-2020 Sylvain Munaut <tnt@246tNt.com>
* SPDX-License-Identifier: CERN-OHL-P-2.0
*/
`default_nettype none
module i2c_master_wb #(
parameter integer DW = 3,
parameter integer FIFO_DEPTH = 0
)(
// IOs
output wire scl_oe,
output wire sda_oe,
input wire sda_i,
// Wishbone
output wire [31:0] wb_rdata,
input wire [31:0] wb_wdata,
input wire wb_we,
input wire wb_cyc,
output wire wb_ack,
output wire ready,
// Clock / Reset
input wire clk,
input wire rst
);
// Signals
// -------
wire [7:0] data_in;
wire ack_in;
wire [1:0] cmd;
wire stb;
wire [7:0] data_out;
wire ack_out;
// Core
// ----
i2c_master #(
.DW(DW)
) core_I (
.scl_oe (scl_oe),
.sda_oe (sda_oe),
.sda_i (sda_i),
.data_in (data_in),
.ack_in (ack_in),
.cmd (cmd),
.stb (stb),
.data_out(data_out),
.ack_out (ack_out),
.ready (ready),
.clk (clk),
.rst (rst)
);
// Bus interface (no buffer)
// -------------
if (FIFO_DEPTH == 0) begin
// No buffer
assign wb_rdata = wb_cyc ? { ready, 22'd0, ack_out, data_out } : 32'h00000000;
assign cmd = wb_wdata[13:12];
assign ack_in = wb_wdata[8];
assign data_in = wb_wdata[7:0];
assign stb = wb_cyc & wb_we;
assign wb_ack = wb_cyc;
end
// Bus interface (FIFO)
// -------------
if (FIFO_DEPTH > 0) begin
// Signals
// -------
// FIFOs
// -----
end
endmodule

View File

@ -105,6 +105,7 @@ module top (
// I2C
wire i2c_scl_oe;
wire i2c_scl_i;
wire i2c_sda_oe;
wire i2c_sda_i;
@ -319,6 +320,7 @@ module top (
.FIFO_DEPTH(0)
) i2c_I (
.scl_oe (i2c_scl_oe),
.scl_i (i2c_scl_i),
.sda_oe (i2c_sda_oe),
.sda_i (i2c_sda_i),
.wb_rdata(wb_rdata[2]),
@ -326,34 +328,22 @@ module top (
.wb_we (wb_we),
.wb_cyc (wb_cyc[2]),
.wb_ack (wb_ack[2]),
.ready (),
.clk (clk_sys),
.rst (rst_sys)
);
// IOBs
SB_IO #(
.PIN_TYPE(6'b110101),
.PULLUP(1'b1),
.IO_STANDARD("SB_LVCMOS")
) i2c_scl_iob_I (
.PACKAGE_PIN (i2c_scl),
.OUTPUT_CLK (clk_sys),
.OUTPUT_ENABLE(i2c_scl_oe),
.D_OUT_0 (1'b0)
);
SB_IO #(
.PIN_TYPE(6'b110100),
.PULLUP(1'b1),
.IO_STANDARD("SB_LVCMOS")
) i2c_sda_iob_I (
.PACKAGE_PIN (i2c_sda),
) i2c_iob_I[1:0] (
.PACKAGE_PIN ({i2c_scl, i2c_sda}),
.INPUT_CLK (clk_sys),
.OUTPUT_CLK (clk_sys),
.OUTPUT_ENABLE(i2c_sda_oe),
.OUTPUT_ENABLE({i2c_scl_oe, i2c_sda_oe}),
.D_OUT_0 (1'b0),
.D_IN_0 (i2c_sda_i)
.D_IN_0 ({i2c_scl_i, i2c_sda_i})
);
`else