rtl/verilog/tpio.v

Fri, 13 Aug 2010 10:41:29 +0100

author
Philip Pemberton <philpem@philpem.me.uk>
date
Fri, 13 Aug 2010 10:41:29 +0100
changeset 0
267b5a25932f
child 1
dfc32cad81ba
permissions
-rw-r--r--

Initial commit, GPIO v3.1

     1 // =============================================================================
     2 //                           COPYRIGHT NOTICE
     3 // Copyright 2006 (c) Lattice Semiconductor Corporation
     4 // ALL RIGHTS RESERVED
     5 // This confidential and proprietary software may be used only as authorised by
     6 // a licensing agreement from Lattice Semiconductor Corporation.
     7 // The entire notice above must be reproduced on all authorized copies and
     8 // copies may only be made to the extent permitted by a licensing agreement from
     9 // Lattice Semiconductor Corporation.
    10 //
    11 // Lattice Semiconductor Corporation        TEL : 1-800-Lattice (USA and Canada)
    12 // 5555 NE Moore Court                            408-826-6000 (other locations)
    13 // Hillsboro, OR 97124                     web  : http://www.latticesemi.com/
    14 // U.S.A                                   email: techsupport@latticesemi.com
    15 // ============================================================================/
    16 //                         FILE DETAILS
    17 //                         FILE DETAILS
    18 // Project          : GPIO for LM32
    19 // File             : tpio.v
    20 // Title            : Tri State IO control 
    21 // Dependencies     : system_conf.v
    22 // Description      : Implements the logic to interface tri-state IO with 
    23 //                    Wishbone bus.
    24 // =============================================================================
    25 //                        REVISION HISTORY
    26 // Version          : 7.0
    27 // Mod. Date        : Jun 27, 2005
    28 // Changes Made     : Initial Creation
    29 //
    30 // Version          : 7.0SP2, 3.0
    31 // Mod. Date        : 20 Nov. 2007
    32 // Changes Made     : Code clean up and add the BB for the inout port.
    33 //
    34 // Version          : 3.1
    35 // Mod. Date        : 11 Oct. 2008
    36 // Changes Made     : Update the Edge Capture Register clean method
    37 //                    Make IRQ Mask register readable
    38 // =============================================================================
    39 `ifndef TPIO_V
    40 `define TPIO_V
    41 `timescale 1ns/100 ps
    42 `include "system_conf.v"
    43 module TRI_PIO #(parameter DATA_WIDTH = 16,
    44                  parameter IRQ_MODE = 1,
    45 		 parameter LEVEL = 0,
    46                  parameter EDGE = 1,
    47                  parameter POSE_EDGE_IRQ = 1,
    48 		 parameter NEGE_EDGE_IRQ = 0,
    49 		 parameter EITHER_EDGE_IRQ = 0)
    50       (RST_I,
    51        CLK_I,
    52        DAT_I,
    53        DAT_O,
    54        PIO_IO,
    55        IRQ_O,
    56        PIO_TRI_WR_EN,
    57        PIO_TRI_RE_EN,
    58        PIO_DATA_RE_EN,
    59        PIO_DATA_WR_EN,
    60        IRQ_MASK_RE_EN,
    61        IRQ_MASK_WR_EN,
    62        EDGE_CAP_WR_EN);
    64    parameter UDLY = 1;//user delay
    66    input  RST_I;
    67    input  CLK_I;
    68    input  DAT_I;
    69    input  PIO_TRI_RE_EN;
    70    input  PIO_TRI_WR_EN;
    71    input  PIO_DATA_RE_EN;
    72    input  PIO_DATA_WR_EN;
    73    output DAT_O;
    74    input  IRQ_MASK_RE_EN;
    75    input  IRQ_MASK_WR_EN;
    76    input  EDGE_CAP_WR_EN;
    77    output IRQ_O;
    78    inout  PIO_IO;
    80    wire  PIO_IO_I;
    81    wire  DAT_O;
    82    wire  IRQ_O;
    83    reg   PIO_DATA_O;
    84    reg   PIO_DATA_I;
    85    reg   PIO_TRI;
    86    reg   IRQ_MASK;
    87    reg   IRQ_TEMP;
    88    reg   EDGE_CAPTURE;
    89    reg   PIO_DATA_DLY;
    91    always @(posedge CLK_I or posedge RST_I)
    92      if (RST_I)
    93        PIO_TRI <= #UDLY 0;
    94      else if (PIO_TRI_WR_EN)
    95        PIO_TRI <= #UDLY DAT_I;
    97    always @(posedge CLK_I or posedge RST_I)
    98      if (RST_I)
    99        PIO_DATA_O <= #UDLY 0;
   100      else if (PIO_DATA_WR_EN)
   101        PIO_DATA_O <= #UDLY DAT_I;
   103    always @(posedge CLK_I or posedge RST_I)
   104      if (RST_I)
   105        PIO_DATA_I <= #UDLY 0;
   106      else if (PIO_DATA_RE_EN)
   107        PIO_DATA_I <= #UDLY PIO_IO_I;
   109    BB tpio_inst(.I(PIO_DATA_O), .T(~PIO_TRI), .O(PIO_IO_I), .B(PIO_IO));
   110    assign  DAT_O =  PIO_TRI_RE_EN ? PIO_TRI  : 
   111                    IRQ_MASK_RE_EN ? IRQ_MASK : PIO_DATA_I;
   113    //IRQ_MODE
   115    generate
   116      if (IRQ_MODE == 1) begin
   117        //CONFIG THE IRQ_MASK REG.  
   118        always @(posedge CLK_I or posedge RST_I)
   119          if (RST_I)
   120            IRQ_MASK <= #UDLY 0;
   121          else if (IRQ_MASK_WR_EN)
   122            IRQ_MASK <= #UDLY DAT_I;
   123        end
   124    endgenerate   
   126    generate
   127       if (IRQ_MODE == 1 && LEVEL == 1) begin
   128           always @(posedge CLK_I or posedge RST_I)
   129             if (RST_I)
   130               IRQ_TEMP <= #UDLY 0;
   131             else
   132               IRQ_TEMP <= #UDLY PIO_IO_I & IRQ_MASK & ~PIO_TRI;//bit-and
   133           assign    IRQ_O = IRQ_TEMP;
   134           end
   135       else if (IRQ_MODE == 1 &&  EDGE == 1) begin   
   136           always @(posedge CLK_I or posedge RST_I)
   137             if (RST_I)
   138               PIO_DATA_DLY <= #UDLY 0;
   139             else
   140               PIO_DATA_DLY <= PIO_IO_I;
   142              always @(posedge CLK_I or posedge RST_I)
   143                if (RST_I)
   144                  EDGE_CAPTURE <= #UDLY 0;
   145                else  if ((PIO_IO_I & ~PIO_DATA_DLY & ~PIO_TRI) && POSE_EDGE_IRQ == 1)
   146                  EDGE_CAPTURE <= #UDLY PIO_IO_I & ~PIO_DATA_DLY;
   147                else  if ((~PIO_IO_I & PIO_DATA_DLY & ~PIO_TRI) && NEGE_EDGE_IRQ == 1)
   148                  EDGE_CAPTURE <= #UDLY ~PIO_IO_I & PIO_DATA_DLY;
   149                else if ((PIO_IO_I & ~PIO_DATA_DLY & ~PIO_TRI)  && EITHER_EDGE_IRQ == 1)
   150                  EDGE_CAPTURE <= #UDLY PIO_IO_I & ~PIO_DATA_DLY;
   151                else if ((~PIO_IO_I & PIO_DATA_DLY & ~PIO_TRI)  && EITHER_EDGE_IRQ == 1)
   152                  EDGE_CAPTURE <= #UDLY ~PIO_IO_I & PIO_DATA_DLY;
   153                else if ( (~IRQ_MASK) & DAT_I & IRQ_MASK_WR_EN )
   154                  // interrupt mask's being set, so clear edge-capture
   155                  EDGE_CAPTURE <= #UDLY 0;
   156                else if ( EDGE_CAP_WR_EN )
   157                  // user's writing to the edge-register, so update edge-capture
   158                  // register
   159                  EDGE_CAPTURE <= #UDLY EDGE_CAPTURE & DAT_I;
   161          assign IRQ_O = |(EDGE_CAPTURE & IRQ_MASK);
   162        end  
   163      else // IRQ_MODE ==0
   164          assign IRQ_O = 0;      
   165    endgenerate
   166 endmodule
   167 `endif // TPIO_V