URL
https://opencores.org/ocsvn/oms8051mini/oms8051mini/trunk
Subversion Repositories oms8051mini
[/] [oms8051mini/] [trunk/] [rtl/] [i2cm/] [i2cm_byte_ctrl.v] - Rev 37
Go to most recent revision | Compare with Previous | Blame | View Log
////////////////////////////////////////////////////////////////////// //// //// //// OMS8051 I2C Master byte-controller Module //// //// WISHBONE rev.B2 compliant I2C Master byte-controller //// //// //// //// 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 //// v0.1 - Dinesh.A, 19th Jan 2017 //// 1. Lint Error fixes ////////////////////////////////////////////////////////////////////// //// //// //// 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_byte_ctrl ( // // inputs & outputs // input clk, // master clock input sresetn, // synchronous active high reset input aresetn, // asynchronous active low reset input ena, // core enable signal input [15:0] clk_cnt, // 4x SCL // control inputs input start, input stop, input read, input write, input ack_in, input [7:0] din, // status outputs output reg cmd_ack, output reg ack_out, output i2c_busy, output i2c_al, output [7:0] dout, // I2C signals input scl_i, output scl_o, output scl_oen, input sda_i, output sda_o, output sda_oen ); // // Variable declarations // // statemachine parameter [4:0] ST_IDLE = 5'b0_0000; parameter [4:0] ST_START = 5'b0_0001; parameter [4:0] ST_READ = 5'b0_0010; parameter [4:0] ST_WRITE = 5'b0_0100; parameter [4:0] ST_ACK = 5'b0_1000; parameter [4:0] ST_STOP = 5'b1_0000; // signals for bit_controller reg [3:0] core_cmd; reg core_txd; wire core_ack, core_rxd; // signals for shift register reg [7:0] sr; //8bit shift register reg shift, ld; // signals for state machine wire go; reg [2:0] dcnt; wire cnt_done; // // Module body // // hookup bit_controller i2cm_bit_ctrl u_bit_ctrl ( .clk ( clk ), .sresetn ( sresetn ), .aresetn ( aresetn ), .ena ( ena ), .clk_cnt ( clk_cnt ), .cmd ( core_cmd ), .cmd_ack ( core_ack ), .busy ( i2c_busy ), .al ( i2c_al ), .din ( core_txd ), .dout ( core_rxd ), .scl_i ( scl_i ), .scl_o ( scl_o ), .scl_oen ( scl_oen ), .sda_i ( sda_i ), .sda_o ( sda_o ), .sda_oen ( sda_oen ) ); // generate go-signal assign go = (read | write | stop) & ~cmd_ack; // assign dout output to shift-register assign dout = sr; // generate shift register always @(posedge clk or negedge aresetn) if (!aresetn) sr <= 8'h0; else if (!sresetn) sr <= 8'h0; else if (ld) sr <= din; else if (shift) sr <= {sr[6:0], core_rxd}; // generate counter always @(posedge clk or negedge aresetn) if (!aresetn) dcnt <= 3'h0; else if (!sresetn) dcnt <= 3'h0; else if (ld) dcnt <= 3'h7; else if (shift) dcnt <= dcnt - 3'h1; assign cnt_done = ~(|dcnt); // // state machine // reg [4:0] c_state; // synopsys enum_state always @(posedge clk or negedge aresetn) if (!aresetn) begin core_cmd <= `I2C_CMD_NOP; core_txd <= 1'b0; shift <= 1'b0; ld <= 1'b0; cmd_ack <= 1'b0; c_state <= ST_IDLE; ack_out <= 1'b0; end else if (!sresetn | i2c_al) begin core_cmd <= `I2C_CMD_NOP; core_txd <= 1'b0; shift <= 1'b0; ld <= 1'b0; cmd_ack <= 1'b0; c_state <= ST_IDLE; ack_out <= 1'b0; end else begin // initially reset all signals core_txd <= sr[7]; shift <= 1'b0; ld <= 1'b0; cmd_ack <= 1'b0; case (c_state) // synopsys full_case parallel_case ST_IDLE: if (go) begin if (start) begin c_state <= ST_START; core_cmd <= `I2C_CMD_START; end else if (read) begin c_state <= ST_READ; core_cmd <= `I2C_CMD_READ; end else if (write) begin c_state <= ST_WRITE; core_cmd <= `I2C_CMD_WRITE; end else // stop begin c_state <= ST_STOP; core_cmd <= `I2C_CMD_STOP; end ld <= 1'b1; end ST_START: if (core_ack) begin if (read) begin c_state <= ST_READ; core_cmd <= `I2C_CMD_READ; end else begin c_state <= ST_WRITE; core_cmd <= `I2C_CMD_WRITE; end ld <= 1'b1; end ST_WRITE: if (core_ack) if (cnt_done) begin c_state <= ST_ACK; core_cmd <= `I2C_CMD_READ; end else begin c_state <= ST_WRITE; // stay in same state core_cmd <= `I2C_CMD_WRITE; // write next bit shift <= 1'b1; end ST_READ: if (core_ack) begin if (cnt_done) begin c_state <= ST_ACK; core_cmd <= `I2C_CMD_WRITE; end else begin c_state <= ST_READ; // stay in same state core_cmd <= `I2C_CMD_READ; // read next bit end shift <= 1'b1; core_txd <= ack_in; end ST_ACK: if (core_ack) begin if (stop) begin c_state <= ST_STOP; core_cmd <= `I2C_CMD_STOP; end else begin c_state <= ST_IDLE; core_cmd <= `I2C_CMD_NOP; // generate command acknowledge signal cmd_ack <= 1'b1; end // assign ack_out output to bit_controller_rxd (contains last received bit) ack_out <= core_rxd; core_txd <= 1'b1; end else core_txd <= ack_in; ST_STOP: if (core_ack) begin c_state <= ST_IDLE; core_cmd <= `I2C_CMD_NOP; // generate command acknowledge signal cmd_ack <= 1'b1; end default: c_state <= ST_IDLE; endcase end endmodule
Go to most recent revision | Compare with Previous | Blame | View Log