//--------------------------------------------------------------------------------------------------
//
// Title       : GPIO
// Design      : U4
// Author      : mbari###
// Company     : MBARI
//
//-------------------------------------------------------------------------------------------------
//
// File        : c:\Projects\genosensor\2g\CPLDs\Core\U4\src\GPIO.v
// Generated   : Wed Dec 17 13:23:50 2003
// From        : interface description file
// By          : Itf2Vhdl ver. 1.20
//
//-------------------------------------------------------------------------------------------------
//
// Description : 
//
//-------------------------------------------------------------------------------------------------
`timescale 1ps / 1ps

//{{ Section below this comment is automatically maintained
//   and may be overwritten
//{module {GPIO}}
module GPIO ( inDATA ,outDATA ,Reset ,AS ,RD ,Mclk ,WR ,ADDR ,GPIO );

input WR ;
wire WR ;
input [7:0] inDATA ;
wire [7:0] inDATA ;
input Reset ;
wire Reset ;
input [7:0] ADDR ;
wire [7:0] ADDR ;
input AS ;
wire AS ;
input RD ;
wire RD ;
input Mclk ;
wire Mclk ;

output [7:0] outDATA ;
wire [7:0] outDATA ;

inout [12:0] GPIO ;
wire [12:0] GPIO ;

//}} End of automatically maintained section

// -- Enter your statements here -- //
parameter 
ddrlow = 8'h0c,
ddrhigh = 8'h0d,
gpiolow = 8'h0e,
gpiohigh = 8'h0f;

reg [12:0] GPIOr;
reg [12:0] DDR;

wire enable;
wire slcddrlow;
wire slcddrhigh;
wire slcgpiolow;
wire slcgpiohigh;


//define the output based on the state of the pins Data Direction Register
//a 1 is an output
//a 0 is an input
assign GPIO[0] = (DDR[0]) ? GPIOr[0] : 1'bz;
assign GPIO[1] = (DDR[1]) ? GPIOr[1] : 1'bz;
assign GPIO[2] = (DDR[2]) ? GPIOr[2] : 1'bz;
assign GPIO[3] = (DDR[3]) ? GPIOr[3] : 1'bz;
assign GPIO[4] = (DDR[4]) ? GPIOr[4] : 1'bz;
assign GPIO[5] = (DDR[5]) ? GPIOr[5] : 1'bz;
assign GPIO[6] = (DDR[6]) ? GPIOr[6] : 1'bz;
assign GPIO[7] = (DDR[7]) ? GPIOr[7] : 1'bz;
assign GPIO[8] = (DDR[8]) ? GPIOr[8] : 1'bz;
assign GPIO[9] = (DDR[9]) ? GPIOr[9] : 1'bz;
assign GPIO[10] = (DDR[10]) ? GPIOr[10] : 1'bz;
assign GPIO[11] = (DDR[11]) ? GPIOr[11] : 1'bz;
assign GPIO[12] = (DDR[12]) ? GPIOr[12] : 1'bz;

assign enable = (!AS & RD & !WR); 
assign slcddrlow = ((ADDR == ddrlow) & enable);
assign slcddrhigh = ((ADDR == ddrhigh) & enable);
assign slcgpiolow = ((ADDR == gpiolow) & enable);
assign slcgpiohigh = ((ADDR == gpiohigh) & enable);

//I'm removeing a lot of read back features for now to keep this at a 256 part
//assign outDATA = slcddrlow ? DDR[7:0] :
//			  slcddrhigh ? {3'b0, DDR[12:8]} :
//			  slcgpiolow ? GPIO[7:0] :
//			  slcgpiohigh ? {3'b0, GPIO[12:8]} : 8'bz;
			  
always @ (posedge Mclk)
	begin
		if (Reset)
			begin
				GPIOr <= 13'b0;
				DDR <= 13'b0;
			end				 
		else		 
			if (WR & !AS)
				case (ADDR)
					8'h0c: DDR[7:0] <= inDATA;
					8'h0d: DDR[12:8] <= inDATA[4:0];
					8'h0e: GPIOr[7:0] <= inDATA;
					8'h0f: GPIOr[12:8] <= inDATA[4:0];
				endcase
			
	end
endmodule
