URL
https://opencores.org/ocsvn/oms8051mini/oms8051mini/trunk
Subversion Repositories oms8051mini
[/] [oms8051mini/] [trunk/] [rtl/] [i2cm/] [i2cm_top.v] - Rev 36
Go to most recent revision | Compare with Previous | Blame | View Log
////////////////////////////////////////////////////////////////////// //// //// //// OMS8051 I2C Master Core Module //// //// WISHBONE revB.2 compliant I2C Master controller Top-level //// //// //// //// This file is part of the OMS 8051 cores project //// //// http://www.opencores.org/cores/oms8051mini/ //// //// //// //// Description //// //// OMS 8051 definitions. //// //// //// //// To Do: //// //// nothing //// //// //// //// Author(s): //// //// -Richard Herveille , richard@asics.ws, www.asics.ws //// //// -Dinesh Annayya, dinesha@opencores.org //// //// //// //// Revision : Jan 6, 2017 //// //// //// ////////////////////////////////////////////////////////////////////// // v0.0 - Dinesh A, 6th Jan 2017 // 1. Initail version picked from // http://www.opencores.org/projects/i2c/ // 2. renaming of reset signal to aresetn and sresetn // ////////////////////////////////////////////////////////////////////// //// //// //// Copyright (C) 2000 Authors and OPENCORES.ORG //// //// //// //// This source file may be used and distributed without //// //// restriction provided that this copyright statement is not //// //// removed from the file and that any derivative work contains //// //// the original copyright notice and the associated disclaimer. //// //// //// //// This source file is free software; you can redistribute it //// //// and/or modify it under the terms of the GNU Lesser General //// //// Public License as published by the Free Software Foundation; //// //// either version 2.1 of the License, or (at your option) any //// //// later version. //// //// //// //// This source 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 Lesser General Public License for more //// //// details. //// //// //// //// You should have received a copy of the GNU Lesser General //// //// Public License along with this source; if not, download it //// //// from http://www.opencores.org/lgpl.shtml //// //// //// ////////////////////////////////////////////////////////////////////// `include "i2cm_defines.v" module i2cm_top( // wishbone signals input wb_clk_i, // master clock input input sresetn, // synchronous reset input aresetn, // asynchronous reset input [2:0] wb_adr_i, // lower address bits input [7:0] wb_dat_i, // databus input output reg [7:0] wb_dat_o, // databus output input wb_we_i, // write enable input input wb_stb_i, // stobe/core select signal input wb_cyc_i, // valid bus cycle input output reg wb_ack_o, // bus cycle acknowledge output output reg wb_inta_o, // interrupt request signal output // 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) ); // // variable declarations // // registers reg [15:0] prer; // clock prescale register reg [ 7:0] ctr; // control register reg [ 7:0] txr; // transmit register wire [ 7:0] rxr; // receive register reg [ 7:0] cr; // command register wire [ 7:0] sr; // status register // done signal: command completed, clear command register wire done; // core enable signal wire core_en; wire ien; // status register signals wire irxack; reg rxack; // received aknowledge from slave reg tip; // transfer in progress reg irq_flag; // interrupt pending flag wire i2c_busy; // bus busy (start signal detected) wire i2c_al; // i2c bus arbitration lost reg al; // status register arbitration lost bit // // module body // // generate wishbone signals wire wb_wacc = wb_we_i & wb_ack_o; // generate acknowledge output signal always @(posedge wb_clk_i) wb_ack_o <= #1 wb_cyc_i & wb_stb_i & ~wb_ack_o; // because timing is always honored // assign DAT_O always @(posedge wb_clk_i) begin case (wb_adr_i) // synopsys parallel_case 3'b000: wb_dat_o <= #1 prer[ 7:0]; 3'b001: wb_dat_o <= #1 prer[15:8]; 3'b010: wb_dat_o <= #1 ctr; 3'b011: wb_dat_o <= #1 rxr; // write is transmit register (txr) 3'b100: wb_dat_o <= #1 sr; // write is command register (cr) 3'b101: wb_dat_o <= #1 txr; 3'b110: wb_dat_o <= #1 cr; 3'b111: wb_dat_o <= #1 0; // reserved endcase end // generate registers always @(posedge wb_clk_i or negedge aresetn) if (!aresetn) begin prer <= #1 16'hffff; ctr <= #1 8'h0; txr <= #1 8'h0; end else if (!sresetn) begin prer <= #1 16'hffff; ctr <= #1 8'h0; txr <= #1 8'h0; end else if (wb_wacc) case (wb_adr_i) // synopsys parallel_case 3'b000 : prer [ 7:0] <= #1 wb_dat_i; 3'b001 : prer [15:8] <= #1 wb_dat_i; 3'b010 : ctr <= #1 wb_dat_i; 3'b011 : txr <= #1 wb_dat_i; default: ; endcase // generate command register (special case) always @(posedge wb_clk_i or negedge aresetn) if (!aresetn) cr <= #1 8'h0; else if (!sresetn) cr <= #1 8'h0; else if (wb_wacc) begin if (core_en & (wb_adr_i == 3'b100) ) cr <= #1 wb_dat_i; end else begin if (done | i2c_al) cr[7:4] <= #1 4'h0; // clear command bits when done // or when aribitration lost cr[2:1] <= #1 2'b0; // reserved bits cr[0] <= #1 1'b0; // clear IRQ_ACK bit end // decode command register wire sta = cr[7]; wire sto = cr[6]; wire rd = cr[5]; wire wr = cr[4]; wire ack = cr[3]; wire iack = cr[0]; // decode control register assign core_en = ctr[7]; assign ien = ctr[6]; // hookup byte controller block i2cm_byte_ctrl u_byte_ctrl ( .clk ( wb_clk_i ), .sresetn ( sresetn ), .aresetn ( aresetn ), .ena ( core_en ), .clk_cnt ( prer ), .start ( sta ), .stop ( sto ), .read ( rd ), .write ( wr ), .ack_in ( ack ), .din ( txr ), .cmd_ack ( done ), .ack_out ( irxack ), .dout ( rxr ), .i2c_busy ( i2c_busy ), .i2c_al ( i2c_al ), .scl_i ( scl_pad_i ), .scl_o ( scl_pad_o ), .scl_oen ( scl_padoen_o ), .sda_i ( sda_pad_i ), .sda_o ( sda_pad_o ), .sda_oen ( sda_padoen_o ) ); // status register block + interrupt request signal always @(posedge wb_clk_i or negedge aresetn) if (!aresetn) begin al <= #1 1'b0; rxack <= #1 1'b0; tip <= #1 1'b0; irq_flag <= #1 1'b0; end else if (!sresetn) begin al <= #1 1'b0; rxack <= #1 1'b0; tip <= #1 1'b0; irq_flag <= #1 1'b0; end else begin al <= #1 i2c_al | (al & ~sta); rxack <= #1 irxack; tip <= #1 (rd | wr); irq_flag <= #1 (done | i2c_al | irq_flag) & ~iack; // interrupt request flag is always generated end // generate interrupt request signals always @(posedge wb_clk_i or negedge aresetn) if (!aresetn) wb_inta_o <= #1 1'b0; else if (!sresetn) wb_inta_o <= #1 1'b0; else wb_inta_o <= #1 irq_flag && ien; // interrupt signal is only generated when IEN (interrupt enable bit is set) // assign status register bits assign sr[7] = rxack; assign sr[6] = i2c_busy; assign sr[5] = al; assign sr[4:2] = 3'h0; // reserved assign sr[1] = tip; assign sr[0] = irq_flag; endmodule
Go to most recent revision | Compare with Previous | Blame | View Log