OpenCores
URL https://opencores.org/ocsvn/cxd9731/cxd9731/trunk

Subversion Repositories cxd9731

[/] [cxd9731/] [chip.v] - Rev 5

Compare with Previous | Blame | View Log

`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company: 
// Engineer: 
// 
// Create Date:    13:53:18 09/05/2008 
// Design Name: 
// Module Name:    chip - Behavioral 
// Project Name: 
// Target Devices: 
// Tool versions: 
// Description: 
//
// Dependencies: 
//
// Revision: 
// Revision 0.01 - File Created
// Additional Comments: 
//
//////////////////////////////////////////////////////////////////////////////////
 
 
module chip(
	inout [15:0] iD	,
	// iD15..8	= LQFP(32);LQFP(31);LQFP(30);LQFP(29);LQFP(28);LQFP(27);LQFP(25);LQFP(24);
	// iD7..0	= LQFP(49);LQFP(48);LQFP(47);LQFP(46);LQFP(21);LQFP(20);LQFP(19);LQFP(42);
	output [2:0] iA,
	// iA2 = I50(3)/LQFP(8);		iA1 = I50(5)/LQFP(5);		iA0 = I50(4)/LQFP(7);
	output ibCS0		, 			// LQFP(10)/I50(2)
	output ibCS1		, 			// LQFP(11)/I50(1)
	output ibRST		, 			// LQFP(121)/I50(50)
	input	iIRQ		,   			// LQFP(12)/I50(6) ( needs pull up)
	output ibWr		,				// LQFP(3)/I50(14)
	output ibRd		,				// LQFP(6)/I50(12)
	input iDQ 		,   			// LQFP(18)/I50(16)(1) DMA request - (need pull low) drive inform chip that it wishes to do DMA
	output ibDK		, 				// LQFP(4)/I50(8)(0) DMA acknoledge - chip inform drive that DMA is in progress
	input iRdy		,   			// LQFP(16)/I50(10)(1) high - will means IO channel ready, (needs pull up)
	input ibDASP	,   			// LQFP(13)/I50(7)(0) low - will shows drive is active
//////- the CN110 interface
	input CLKin		,  			// LQFP(129)/J110(81) = 36.6MHz (27.27nS clock pulses)
	input bCSRST	,  			// LQFP(69)/J110(49)power on is high
	input bCRST		,  			// LQFP(70)/J110(52)actual reset signal
	inout [15:0] cDP		,  	// data bus
	// cDP(15..8) = LQFP/J110 = (114/2,113/6,112/8,111/12,110/14,105/18,104/20,103/24)
	// cDP(7 ..0) = LQFP/J100 = (102/26,101/30,99/32,98/36,120/38,117/42,116/44,115/48)
	inout [15:0] cAP		, 	// address bus
	// cAP(15..8) = LQFP/J110 = (96/1,93/3,92/7,91/9,90/13,88/15,87/19,85/21)
	// cAP(7 ..0) = LQFP/J110 = (84/25,83/27,82/31,79/33,78/37,77/39,76/43,75/45)
//
	input bcCS		,  		// LQFP(50)/J110(72)
	input bcWr		,  		// LQFP(60)/J110(73)
	input bcRd		,  		// LQFP(58)/J110(77)
	input bCRT		,  		// LQFP(51)/J110(70)
//
	output	bcWait 	, 		// LQFP(64)/J110(59) ** high a 120ns pulse
	output	bcIRQ		, 		// LQFP(68)/J110(55) ** high at int9 
	output	cDQ		, 		// LQFP(54)/J110(66)
	input		cDK		,  	// LQFP(55)/J110(62)
//
	output	DR245		,		// LQFP(45)
	output	OE245		,		// LQFP(43)
//
 
////- the following signals are connected but never change
	input ACS_LED  ,  		// LQFP(63)/J110(90) measured high always (pull-high)
	input HDD_ACK  ,  		// LQFP(59)/J110(92) measured high always (pull-high)
////- the following signals are unconnected in the original board
//	input INP1		,			// LQFP(33)
//	input INP2		,			// LQFP(35)
//	input INP3		,			// LQFP(53)
//	input INP4		,			// LQFP(80)
//	input INP5		,			// LQFP(97)
//	input INP6		,			// LQFP(123)
//	input INP7		,			// LQFP(140)
	inout		TFD0	,			// LQFP(124)	TFlash SD D0 (I/OPP) or SPI Data Out (OPP)
	inout		TFD1	,			// LQFP(125)	TFlash SD D1 (I/OPP) or SPI reserve
	inout 	TFD2	,			// LQFP(126)	TFlash SD D2 (I/OPP) or SPI reserve
	inout		TFD3	,			// LQFP(127)	TFlash SD D3 (I/OPP) or SPI Chip Select bCS (I)
	output	TFCLK	,			// LQFP(130)	TFlash CLK
	input		TFSENSE	,		// LQFP(131)	TFlash Sense ( low if TF inserted )
	output	TFCMD		,		// LQFP(132)	TFlash Command		or SPI Data In (I)
 
// Fixed signals for connecting the SPI external flash
//	FbCS,FMOSI,FDIN,FCCLK {LQFP(41,62,71,72)}
//
// testing signals
//
	output	JT_Result		,		// LQFP(44)
	output	JT_Pin1		,		// LQFP(37)
	input		JT_bTest				// LQFP(38)
);
 
wire DCM_RST,CLK1,CLK4,DCM_LOCKED ;
 
reg DWrite;
wire IDERd,IDEWr;
reg iIRQ1;
reg iDQ1,SiIRQ,SiDQ;
wire iDMARd,iDMAWr ;
wire BufEmpty ;
wire PA_HvSpace,PA_OD_Rdy ;
wire PB_HvSpace,PB_OD_Rdy ;
wire WithinBBlock,BBurstEnd;
wire WithinABlock;
 
wire iCS0,iCS1,cWr,cRd,iWr,iRd,iDK ;
wire [15:0] RegData;
wire [31:0] DMARAMQ;
reg  [31:0] DMARAMD;
reg  [15:0] DIn1,DIn2;
wire cDMA_OE ;
wire cRdt;		// tri-state control signal
wire RegEB;		// the register control signal 
 
 
//////
//wire RegSC,RegCMD	_vector(7 downto 0);
//////-=============================================
//// read only registers ( logical wire groups )
wire	[7:0] Reg0038 ;
//// wire	Reg0002,Reg0004,Reg000E _vector(7 downto 0);
wire	[15:0] Reg0028 ;
//// write only registers
//wire Reg002C,Reg0070,Reg0072,Reg0074	_vector(7 downto 0);
////- read write registers //// =====================
reg	[7:0] Reg002A;
wire [7:0] Reg002E;
reg [7:0] Reg0064;
////////- ===========================================
//wire AICtrl,DICtrl ;
wire cDOE,cAOE ;
wire IDE_CS;
reg DMA_ARM,DMARMC,PS2WrIDE ;
wire PA_AlmostFull ;
wire [3:0] BufSize;
reg [2:0] R44;
wire INT9,INT9OE,DMA_IrqCond;
reg DMA_IrqMask, DMA_IrqFF;		// set high if DMA IRQ condition met
wire DMA_IrqCTRL ;
wire bHardReset;
reg ATV1,ATV2,ATV;
wire UDMAC,CmdIsEF,UDMA_SEL,MDMA_SEL,D_UnChg ;
reg R42Is03,R44Is2X,R44Is4X;
wire [2:0] UDMA,MDMA;
reg  [2:0] UDO;
reg [2:1] MDO;
 
wire Combo_CS,Combo_OE ;
reg cWr1,cRd1,ScWr,ScRd,ScWr1,ScRd1 ;
wire [15:0] cAi,cDi,CRC_Q,iDi,iDO,DOutA;
wire iDOEnb,CRC_MUX ;
wire IDEiOE,iDMA_OE ;
reg [6:0] cRgA;
reg [7:0] cRgD;
wire cRgRd2E,cRgWr;
reg bcRd2E;
reg cRgWrEnb ;
reg [5:0] Rd2ECnt;
reg [3:0] cWaitCnt;
reg cWait;
//// wire BusMatch ;
wire iD_245_In,IDE_Rd_Env ;	// standard logic for envelop
reg SiRdy2,SiRdy1; // a short input buffer
reg IgnoreIRdyPin;		// if IORDY from the drive is always low, then ignore it in normal IDE IO-Read Write cycles
reg Ph0,Ph1,Ph2,Phase3;
 
wire Reg002E_0, Reg002E_1, Reg002E_2, Reg002E_3, Reg002E_5, Reg002E_6, Reg002E_7;
reg Reg002E_4;
assign Reg002E = {Reg002E_7, Reg002E_6, Reg002E_5, Reg002E_4, Reg002E_3, Reg002E_2, Reg002E_1, Reg002E_0};
//wire ProbeOut ;
//wire ClrDMAPulse,ClrD1,ClrD2 ;
//// =====================
//wire	IDE_INTF_STATE,IDE_DMA_STATE,PS2_DMA_STATE _vector(15 downto 0);
//wire	D_RAM_ReportOut _vector(15 downto 0);
//wire	D_RAM_ReportIn	 _vector(1 downto 0);
//wire	ReportOut		_vector(15 downto 0);
//wire	ReportC			_vector(5 downto 0);
//wire   R380016			_VECTOR(15 DOWNTO 0);
//wire  iRdd1,iRdd2,DOEnb	;
//// ================================================
 
//wire	[63:0] dna64bits;
//reg	[7:0] dnac;
wire	DNA_Pass,DNA_RST;
wire [3:0] KILL;				// 4 bit killer signals
//reg	DNAS0,DNAS1,DNAS2;		// the DNA output control
//wire	DNA_CS,DNA_OE;				// signal to show the DNA value to IDE bus
//wire  [15:0] DNAO;
//// =========== test stubs ========================
//ReportOut <= X"AAAA"				when (ReportC(5 downto 2) = "0010") else
//				 X"5555"				when (ReportC(5 downto 2) = "0011") else
//				 D_RAM_ReportOut	when (ReportC(5 downto 4) = "01") else
//				 PS2_DMA_STATE		when (ReportC(5 downto 2) = "1000") else
//				 IDE_DMA_STATE		when (ReportC(5 downto 2) = "1001") else
//				 IDE_INTF_STATE	when (ReportC(5 downto 2) = "1010") else
//				 Reg0028				when (ReportC(5 downto 2) = "1011") else
//				 R380016				when (ReportC(5 downto 2) = "1100") else
//				 X"CCCC";
//D_RAM_ReportIn(1 downto 0)	<= ReportC(3 downto 2);
//R380016(15 DOWNTO 8) <= X"00";
//R380016(7 DOWNTO 0) <= Reg0038;
 
////////////////////////////////////////////////////-
////////////////////////////////////////////////////-
 
dcm3	Inst_DCM(
	.CLKIN_IN		(CLKin),
	.RST_IN			(DCM_RST),
	.CLKFX_OUT		(CLK4),
	.CLKIN_IBUFG_OUT(),			// same phase as CLKin
	.CLK0_OUT		(CLK1),				// same phase as CLK
	.LOCKED_OUT		(DCM_LOCKED)
);
 
////- ===== TF machine ======
TF_Stub	Inst_TF_Stub(
	.RESET (DNA_RST),
	.CLK4	(CLK4),
	.TFD0	(TFD0),
	.TFD1	(TFD1),
	.TFD2	(TFD2),
	.TFD3	(TFD3),			// same phase as CLKin
	.TF_CLK		(TFCLK),				// same pahse as CLK
   .TF_CMD		(TFCMD), 
	.TF_SENSE	(TFSENSE)
);
 
 
////- ===== DNA 
Top dna1 (
    .reset(DNA_RST), 
    .clk4(CLK4),
	 .IDE_CS(IDE_CS),
    .dna_pass(DNA_Pass),
	 .KILL(KILL)
    );
 
////- ===============================================
Reg38	R_38(
	.UDMAC		(UDMAC),
	.PS2WrIDE	(PS2WrIDE),
	.iIRQ			(SiIRQ),
	.cDQ			(cDQ),
	.iDQ			(SiDQ),		// synchronize iDQ
	.iDK			(iDK),
	.BufEmpty	(BufEmpty),
	.PB_HvSpace	(PB_HvSpace),
	.BufSize		(BufSize),
	.DOut			(Reg0038)
);
////=========================================================
PS2_DMA	PS2DMA(
//	PS2_DMA_STATE	(PS2_DMA_STATE),
	.CLK4			(CLK4),
	.Phase3		(Phase3),		// the phases
////// external pin interface
	.cDQ			(cDQ),  		// DMA request output
	.cDK			(cDK),  		// DMA acknowledge input
	.cRd			(cRd),		// read signal pulse
	.DWrite		(DWrite),	// write and counter pulse
////// controlling signal
	.DMA_ARM		(DMA_ARM),		// signal from ctrllr to inits DMA
	.PS2WrIDE	(PS2WrIDE),	// level indicating that PS2 is DMA writing IDE bus
//// PS2 DMA connecting to RAM interface
	.PB_HvSpace	(PB_HvSpace),		// there is empty space for Port B
	.PB_OD_Rdy	(PB_OD_Rdy),		// some data availabe for output from Port B
////
	.WithinBBlock	(WithinBBlock),	// high if (AddrB(6) OR AddrB(5)) = 1
	.BBurstEnd	(BBurstEnd),			// high if AddrB = xxxx11111 = 1F
	.IncAddrB	(IncAddrB),
	.RegEB		(RegEB),
	.EnbB			(EnbB),
	.WrB			(WrB )			// write pulse
);
////-======================================================
D_RAM		DMARAM(
	.CLK4			(CLK4),
	.DMA_ARM		(DMA_ARM),
	.PS2WrIDE	(PS2WrIDE), 			// High if PS2 DMA write to IDE bus
//// =====
	.CRC_ARM		(CRC_ARM),
	.CRC_ENB		(CRC_ENB),
	.CRC_Q		(CRC_Q),
//// =====
	.PA_HvSpace	(PA_HvSpace),		// there is empty space for Port A
	.PA_OD_Rdy	(PA_OD_Rdy),		// some data availabe for output from Port A
	.PA_AlmostFull	(PA_AlmostFull),
	.PA_Full		(PA_Full),
	.PA_Empty	(PA_Empty),
	.WithinABlock	(WithinABlock),
//// =====	
	.PB_HvSpace	(PB_HvSpace),		// there is empty space for Port B
	.PB_OD_Rdy	(PB_OD_Rdy),		// some data availabe for output from Port B
//// =====
	.BufSize		(BufSize),
	.BufEmpty	(BufEmpty),			// set when no words in the FIFO buffer
//// =====
	.DInA			(DIn2),
	.DOutA		(DOutA),
	.DInB 		(DMARAMD), 
//// ==== 1st port RAM access
	.A0			(A0),
	.HWOE			(HWOE),
	.IncAddrA	(IncAddrA),
	.EnbA		(EnbA),
	.WrA			(WrA),
	.RegEA	(RegEA),
//// ==== 2nd port RAM access
	.WithinBBlock	(WithinBBlock),		// high if (AddrB(6) OR AddrB(5)) = 1
	.BBurstEnd	(BBurstEnd),				// high if AddrB = xxxx11111 = 1F
	.IncAddrB		(IncAddrB),
	.EnbB			(EnbB),
	.RegEB			(RegEB),
	.WrB 			(WrB),  
	.DOutB 		(DMARAMQ)
);
//// =========================================
IDE_DMA	IDEDMA (
//	IDE_DMA_STATE	(IDE_DMA_STATE),
	.CLK4		(CLK4),
	.Phase3	(Phase3),
////// external pin interface
	.iDK		(iDK),  			// (o) DMA acknowledge output to harddisk
	.iDQ		(SiDQ),  			// (i) DMA request input from harddisk
	.SiRdy1	(SiRdy1),				// (i) IDE bus ready signal
	.SiRdy2	(SiRdy2),
////// system signal
	.DMA_ARM(DMA_ARM),	// do not request transaction if this is not armed
	.PS2WrIDE	(PS2WrIDE), 		// (i) '1' if direction is from PS2 to IDE
	.UDMA 		(UDMA),
	.MDMA		(MDMA),
	.iDMARd	(iDMARd),			// (o) active high signal to indicate DMA read
	.iDMAWr	(iDMAWr), 			// (o) active high signal to indicate DMA write
	.iDMA_OE	(iDMA_OE),			// (o) active high signal showing DMA wishes to drive iD bus
	.iD_245_In	(iD_245_In),	// (o) active high envelop signal to drive output bus
	.CRC_MUX	(CRC_MUX),			// inform system that need to drive the CRC Q to IDE bus
	.CRC_ARM	(CRC_ARM),			// a signal indicate that to clear the CRC state
	.CRC_ENB	(CRC_ENB),
////// interface the RAM buffer), DMA machine will act according to buffer
	.PA_HvSpace	(PA_HvSpace),		// there is empty space for Port A
	.PA_OD_Rdy	(PA_OD_Rdy),		// some data availabe for output from Port A
	.WithinABlock	(WithinABlock),
	.PA_AlmostFull(PA_AlmostFull),
	.PA_Full		(PA_Full),
	.PA_Empty	(PA_Empty),
	.IDE_DSTB	(IDE_DSTB),
	.IncAddrA	(IncAddrA),
	.A0		(A0),
	.HWOE		(HWOE),
	.EnbA		(EnbA),
	.WrA			(WrA),
	.RegEA	(RegEA)
);
//// =========================================
 
//- Probes
// (I/P) JT_bTest is the tester control port, during config, this is high; this should be DONE signal inverted by a 74LS04
// (I/P) JT_Pin1 is the selection port of ROM
// (O/P) JT_Result is the result port (if DNA_Pass then it is low)
assign JT_Result	= (JT_bTest == 1'b0) ? ( ~DNA_Pass ) : ( HDD_ACK | ACS_LED | ibDASP | bCRT ); // will output low if DNA_Pass
assign JT_Pin1		=  TFCLK;			// pull low for 50A, left high for 50AN
 
/// ===========================================================================
/// ===========================================================================
//	ClrDMAPulse = ~(bcCS) & ~(bcWr) & ClrD1 & ClrD2;
//	ClrD1	= '1' when (cAi(15 downto 0) = X"0032") else '0';
//	ClrD2 = '1' when (cDi(15 downto 0) = X"0003") else '0';
 
////- ===  CLOCK & reset signals ===========================================
assign DCM_RST		= ~bCRST | ~bCSRST;		// drive high if any pin is low
assign bHardReset	=  bCRST & DCM_LOCKED;	// the lowest level of reset
assign DNA_RST		= ~DCM_LOCKED;					// active high reset signal
/// ===== Phase generation logic ==================================
always @(negedge CLK1) begin
	if (DCM_LOCKED == 1'b0) begin
		Ph0 <= 1'b0;
	end else begin
		Ph0 <= ~Ph0;				// a toggling signal
	end
end
 
always @(negedge CLK4) begin
	Ph1	<=	Ph0;
	Ph2	<= Ph1;
end
 
always @(posedge CLK4) begin
	Phase3	<= Ph1 ^ Ph2;
end
//// ==========================================================================
 
 
//// ==========================================================================
// output signal
//// Register 64 signals
	assign ibRST	= ~(Reg0064[7]);
	assign ibCS0	= ~(iCS0);		// convert to correct pin polarity
	assign ibCS1	= ~(iCS1);
	assign ibRd		= ~(iRd);
	assign ibWr		= ~(iWr);
	assign ibDK		= ~(iDK);		// DMA acknowledge output, active low
//// IDE Data bus control signal
	assign iRd	= ( IDERd & ~iDK ) | (iDMARd & iDK);
	assign iWr	= ( IDEWr & ~iDK ) | (iDMAWr & iDK);
//////- the CN110 interface
// input signal
	assign cRd	= ~bcRd & ~KILL[0];
	assign cRdt	= ~bCRT & ~KILL[0];		// tristate control circuit
	assign cWr	= ~bcWr & ~KILL[0];
//// ============================================================================================
//// Interrupt signal
// interrupt will be set either by IDE interrupt line | an interrupt signal by DMA F/F
	assign INT9OE	= Reg002A[1] | Reg002A[0];
	assign bcIRQ	= (INT9OE == 1'b1) ? ~(INT9) : 1'bZ;
	assign INT9		= (SiIRQ & Reg002A[0]) | (DMA_IrqFF & DMA_IrqCTRL);
////============= c-Connector data bus  =======================
	assign cDMA_OE	=	cRdt & cDK;					// output the data bus
	assign cDOE	= ATV & (cDMA_OE | Combo_OE);	// DMA/CS PS2 read will drive the bus
	assign cDP 	=	(cDOE		== 1'b0) ?	{16{1'bZ}}		:
						(cDK 		== 1'b1) ?	DMARAMQ[15:0]	:
						(IDE_CS	== 1'b1)	?	iDi[15:0]		:	RegData[15:0];
	assign cDi	= cDP;
//- c-Connector Address bus
	assign cAOE	= ATV &  cDMA_OE;					// DMA PS2 read will drive the bus
	assign cAP 	=	(cAOE == 1'b0) ? {16{1'bZ}}		: DMARAMQ[31:16];
	assign cAi	= cAP;
////
//// ============================================================================================
//// Control signals // must wait until bus matching for IDE signals
//	assign BusMatch = ((cDi[15] ~^ iDi[15]) & (cDi[14] ~^ iDi[14]) & (cDi[13] ~^ iDi[13]) &
//					 (cDi[12] ~^ iDi[12]) & (cDi[11] ~^ iDi[11]) & (cDi[10] ~^ iDi[10]) &
//					 (cDi[9]  ~^ iDi[9])  & (cDi[8]  ~^ iDi[8])  & (cDi[7]  ~^ iDi[7])  &
//					 (cDi[6]  ~^ iDi[6])  & (cDi[5]  ~^ iDi[5])  & (cDi[4]  ~^ iDi[4])  &
//					 (cDi[3]  ~^ iDi[3])  & (cDi[2]  ~^ iDi[2])  & (cDi[1]  ~^ iDi[1])  &
//					 (cDi[0]  ~^ iDi[0]));
//- the combo chip select range = 0x0000-0x007F
	assign Combo_CS = ATV & ~cDK & ~(bcCS | cAi[15] | cAi[14] | cAi[13] | cAi[12] |
												cAi[11] |	cAi[10] | cAi[9] | cAi[8] | cAi[7]);
	assign Combo_OE = cRd & Combo_CS;			// asynchronous active reading signal
 
//// ================== IDE interface section =================================================
 
//====== iDE data bus ================================
// IDE data bus control
//	ProbeOut				= (cWr | cRd) & ~(IDE_CS) & ~(iDK) & ~(cDK);
//	iDOEnb				= IDEiOE | iDMA_OE | ProbeOut;		// signal we can drive the bus
//
// 090313
//  The ORIGINAL signal
	assign iD[15:0]	= (iDOEnb == 1'b1) ? iDO[15:0] : {16{1'bZ}};
	assign iDOEnb		= IDEiOE | iDMA_OE;		// signal we can drive the bus
	assign iDi[15:0]	= iD[15:0];
	assign iDO[15:0]	=	(IDE_CS  == 1'b1) ?	 cDi[15:0] : 
								(CRC_MUX == 1'b1) ? CRC_Q[15:0] : DOutA[15:0];
//
//// --- iD out also output DNA data
//// ==== The DNA showing session ====
//	assign	iDOEnb		= 1'b1;
//	assign	iD[15:0]		= iDO[15:0];
//	assign	iDO[15:0]	=	(dnac[7] == 1'b0) ? 
//										((dnac[6] == 1'b0) ? dna64bits[63:48] : dna64bits[47:32] ) :
//										((dnac[6] == 1'b0) ?	dna64bits[31:16] : dna64bits[15:0] );
//	assign	iDi[15:0]	= iD[15:0];
//// 
//
// 090313
//
//
//  0000 0000 010* **** = 0x0040-0x005F
assign IDE_CS	= Combo_CS & ~iDK & cAi[6] & ~cAi[5]; //- if address range is correct and we are not doing iDK
assign iCS1		= IDE_CS &  cAi[4] & ~KILL[2];
assign iCS0		= IDE_CS & ~cAi[4] & ~KILL[2];
assign iA[2]	= IDE_CS & cAi[3] & ~KILL[1];
assign iA[1]	= IDE_CS & cAi[2] & ~KILL[2];
assign iA[0]	= IDE_CS & cAi[1] & ~KILL[3];
assign IDERd	= IDE_CS & cRd & ~KILL[1];
assign IDEWr	= IDE_CS & cWr & ~KILL[2];	// narrow down the write pulse
assign IDEiOE	= IDE_CS & cWr;	// writing IDE, we drive the IDE i Bus
//	IDE_Rd_Env	= (IDE_CS & cRd) | IDERd1;		// reading, we drive the 245 inwards
assign IDE_Rd_Env	= IDE_CS & cRd;
//////////////////////////////////////////////////////////////////////
//- Local Register Block
//// ===== Read only registers
//	Reg0002(7 downto 2) = "000100";	// prepare to be 13
//	Reg0002(1) = ~(DNA_Fail);		// should always be 1 ( ~ fail)
//	Reg0002(0) = DNA_Pass;				// should always be 1 (pass)
//	Reg0002[7:0] = "00010011";	// fixed at 13
//	Reg0004	= X"0B";
//	Reg000E	= X"02";
// Reg0028 has many bits being zero ////////////////////////
// Reg0028 is probably the DMA RAM Buffer register
//	assign Reg0028[15]	= Reg2815;			// set when buffer is full
	assign Reg0028[15]	= BufSize[3];		// set when buffer is full
	assign Reg0028[14]	= BufEmpty;
//	Reg0028(14) = (~(PS2WrIDE) & BufEmpty) | (PS2WrIDE & (AlmostEmpty | BufEmpty));			// BufEmpty
//	Reg0028(14) = (~(PS2WrIDE) & (AlmostEmpty | BufEmpty)) | (PS2WrIDE & HaveSpace);			// Performs much better than BufEmpty in xboot writing
//	Reg0028(14) = AlmostEmpty;			// Performs much better than BufEmpty in xboot writing
	assign Reg0028[13:2] = 12'b0000_0000_0000;
	assign Reg0028[1]	= cDQ;
	assign Reg0028[0]	= SiIRQ;				// the interrupt condition of external
//// Reg002A the interrupt control register ///////////////////////////////////////////
//// local registers //////////////////////////
	assign RegData[15:8] =	(cAi[6:0] == 7'h28)	?	Reg0028[15:8]	: 8'h00;
////////////////////////////////////////
	assign RegData[7:0]	=	(cAi[6:0] == 7'h02)	?	8'h13 			:
									(cAi[6:0] == 7'h04)	?	8'h0B 			:
									(cAi[6:0] == 7'h0E)	?	8'h02				:
									(cAi[6:0] == 7'h28)	?	Reg0028[7:0]	:
									(cAi[6:0] == 7'h2A)	?	Reg002A[7:0]	:
						//			(cAi[6:0] == 7'h2C)	?	Reg002C[7:0]	:
									(cAi[6:0] == 7'h2E)	?	Reg002E[7:0]	:
									(cAi[6:0] == 7'h38)	?	Reg0038[7:0]	:
									(cAi[6:0] == 7'h64)	?	Reg0064[7:0]	: 8'h00;
////- Reg0064 has zero bits write 4C then will write IDECmd87 to set direction
//	Probably Reg0064 is the reset & interrupt control
// if reading & PortB have data
//  | Writing & PortA have space
	assign DMA_IrqCond	=	(~(PS2WrIDE) & PB_OD_Rdy) | (PS2WrIDE & PB_HvSpace);
	assign DMA_IrqCTRL	= Reg002A[1];
 
////- ====================================	
	assign UDMAC	= UDO[2] | UDO[1] | UDO[0];
//////////////////////////////////////////////////////////////////
 
 
//- ===== selecting the drive mode is by ===
//- ATA command set features (EF,xx,xx,xx,xx,Table20,03)
assign CmdIsEF		= cRgD[7] & cRgD[6] & cRgD[5] & ~(cRgD[4]) &	cRgD[3] & cRgD[2] & cRgD[1] & cRgD[0];
assign UDMA_SEL	= CmdIsEF & R44Is4X & R42Is03;
assign MDMA_SEL 	= CmdIsEF & R44Is2X & R42Is03;
assign D_UnChg		= ~(UDMA_SEL | MDMA_SEL);		// do not change the data if both control are low
assign UDMA[2:0]	= UDO[2:0];
assign MDMA[2] 	= MDO[2];
assign MDMA[1]		= MDO[1];
assign MDMA[0]		= ~(UDO[2] | UDO[1] | UDO[0] | MDO[2] | MDO[1]);
//////- =======================================
assign Reg002E_7 = 1'b1;
assign Reg002E_6 = 1'b1;
assign Reg002E_5 = 1'b0;
 
assign Reg002E_3 = 1'b1;
assign Reg002E_2 = 1'b1;
assign Reg002E_1 = 1'b1;
assign Reg002E_0 = 1'b0;
// Reg002E is always CE | DE
 
//////- =======================================
assign cRgWr	= ATV & ScWr1 & ~(ScWr) & cRgWrEnb;		// old time is 1, new is off
assign cRgRd2E	= ATV & ScRd1 & ~(ScRd) & bcRd2E;			// the single read pulse for 2E
//////- =============== control the direction of the buffers ============
assign OE245	= ~(ATV);		// almost always valid
assign DR245	= ~(IDE_Rd_Env | iD_245_In);			// high = 3V3 bus drives disk I/O, = iWR |
																		//- low when ( iRd for MDMA and normal, or iDK AND UDI mode)
////- ===================================================================
always @(posedge bcWr) begin
	cRgWrEnb		<=	Combo_CS & ScWr & ScWr1;		// if selecting the register, then we might have write pulse
	cRgA[6:0]	<= cAi[6:0];
	cRgD[7:0]	<= cDi[7:0];
end
 
always @(posedge bcRd) begin
	bcRd2E	<= Combo_CS & ScRd & ScRd1 & ~(cAi[6]) & cAi[5] & ~(cAi[4]) & cAi[3] & cAi[2] & cAi[1] & ~(cAi[0]);
end
 
//// =============================
//always @(negedge CLK1) begin
//	DMARAMD[15:0] 	<= cDi[15:0];		// lower word to RAM
//	DMARAMD[31:16]	<= cAi[15:0];		// upper word to RAM
//end
always @(posedge CLK4) begin
	if ((Ph1 ^ Ph2) == 1'b1) begin
		DMARAMD[15:0] 	<= cDi[15:0];		// lower word to RAM
		DMARAMD[31:16]	<= cAi[15:0];		// upper word to RAM
	end
end
//// =============================
always @(posedge CLK1) begin
	DWrite	<= cWr & cDK;
end
 
//// ============================================================================================
//// ===== IDE bus interface wait engine ========================================================
//// ============================================================================================
assign bcWait	= (IDE_CS == 1'b1) ? ~cWait : 1'bZ; // will output low if cWait = '1'
 
always @(posedge CLK4) begin
	if (IDE_CS == 1'b0) begin
		cWaitCnt	<= 4'b0000;		// clear wait counter
		cWait		<= 1'b1;			// must wait
		IgnoreIRdyPin	<= ~SiRdy2;		// if IORDY is always low then ignore it, it will not affect our engine
	end else begin
		if (cWaitCnt == 4'b1010) begin 
//			if ((SiRdy2 == 1'b1) && (BusMatch == 1'b1)) begin
			if ((IgnoreIRdyPin == 1'b1) || (SiRdy2 == 1'b1)) begin
				cWait	<= 1'b0;		// end if
			end
		end else begin
			cWaitCnt <= cWaitCnt + 1;
		end
	end
end
//// ============================================================================================
//// ============================================================================================
 
always @(posedge CLK4) begin
//// synchronous Reset section
	if (bHardReset == 1'b0) begin
////
		Reg002A		<= 8'h00;
		Reg002E_4	<= 1'b0;		// first data is CE, next data can be CE or DE
		Rd2ECnt		<= 6'b000001;	// clear the Rd2E counter
		Reg0064		<= 8'h80;		// activate the IDE reset signal
		DMA_IrqMask	<= 1'b0;
		DMA_IrqFF 	<= 1'b0;			// clear the DMA request flipflop
		PS2WrIDE	 	<= 1'b0;			// set up the direction
		MDO[2]		<= 1'b0;		// DMA mode is multiword mode 0
		MDO[1]		<= 1'b0;
		UDO			<= 3'b000;		// not UDMA mode
		DMARMC		<= 1'b0;
		DMA_ARM		<= 1'b0;
////--- first filter
		iDQ1			<= 1'b0;
		iIRQ1			<= 1'b0;
		cWr1			<= 1'b0;
		cRd1			<= 1'b0;
		SiRdy1		<= 1'b1;
//// ========  2nd filter ========
		SiDQ			<= 1'b0;
		SiIRQ			<= 1'b0;
		ScWr			<= 1'b0;
		ScRd			<= 1'b0;
		SiRdy2		<= 1'b1;
//// ========= 3rd filter ======
		ScRd1			<= 1'b0;
		ScWr1			<= 1'b0;
//// =============================
		ATV1			<= 1'b0;
		ATV2			<= 1'b0;
		ATV			<= 1'b0;
//// =========
//		DNAS0			<= 1'b0;
//		DNAS1			<= 1'b0;
	end else begin
		ATV1			<= 1'b1;
		ATV2			<= ATV1;
		ATV			<= ATV2;		// 2 filter for ATV signal
//// ======== first filter =====
		iDQ1		<= iDQ;			// try to synchronize the system clock
		iIRQ1		<= iIRQ;			// synchronize again
		cWr1		<= cWr;
		cRd1 		<= cRd;
		SiRdy1	<= iRdy;
		DIn1		<= iDi;							// get the data
//		IDERd1	<= IDERd;		// one delay signal to control output buffer direction
//// ========  2nd filter ========
		SiDQ		<= iDQ1;
		SiIRQ		<= iIRQ1;
		ScWr		<= cWr1;
		ScRd		<= cRd1;
		SiRdy2	<= SiRdy1;
		if (IDE_DSTB == 1'b1) DIn2		<= DIn1;
//// ========= 3rd filter ======
		ScRd1		<= ScRd;
		ScWr1		<= ScWr;
//// =============================
//		The DNA output counter value
//		if (((ScRd1 == 1'b1) && (ScRd == 1'b0)) || ((ScWr1 == 1'b1) && (ScWr == 1'b0))) begin
//			DNAS0		<= ~DNAS0;
//			DNAS1		<= DNAS1 ^ DNAS0;
//		end
//		Reg2815	<= PS2WrIDE & (PA_AlmostFull | (~(PA_HvSpace) & Reg2815));
//// =======================================
		if (cRgRd2E == 1'b1) begin		// read pulse post processing, check which register is read
			if ((Rd2ECnt == 6'b000110) || (Rd2ECnt == 6'b010010) || (Rd2ECnt == 6'b010011) || (Rd2ECnt == 6'b010101) ||
				(Rd2ECnt == 6'b010111) || (Rd2ECnt == 6'b011100) || (Rd2ECnt == 6'b011101) || (Rd2ECnt == 6'b011110) ||
				(Rd2ECnt == 6'b011111) || (Rd2ECnt == 6'b100000) || (Rd2ECnt == 6'b100011) || (Rd2ECnt == 6'b100100) ||
				(Rd2ECnt == 6'b100101) || (Rd2ECnt == 6'b100110) || (Rd2ECnt == 6'b100111) || (Rd2ECnt == 6'b101000) ||
				(Rd2ECnt == 6'b101001) || (Rd2ECnt == 6'b101110) || (Rd2ECnt == 6'b110000) || (Rd2ECnt == 6'b110001) ||
				(Rd2ECnt == 6'b110011) || (Rd2ECnt == 6'b110101) || (Rd2ECnt == 6'b110110) || (Rd2ECnt == 6'b111000) ||
				(Rd2ECnt == 6'b111001) || (Rd2ECnt == 6'b111011) || (Rd2ECnt == 6'b111110))
			begin
				Reg002E_4	<= 1'b1;		// Reg002E <= x"DE";
			end else begin
				Reg002E_4	<= 1'b0;		// Reg002E <= x"CE";
			end
			Rd2ECnt <= Rd2ECnt + 1;
		end
////- ==============================
		if (cRgWr == 1'b0) begin
	//// Always running section the DMA controller reset section ////
			DMARMC	<= ATV;			// DMA_ARM is two clock width
			DMA_ARM	<= DMARMC;		// DMA_ARM is two clock width, put to clear register
	//// The interrupt controller section always running after hard reset////
			if (DMA_IrqMask == 1'b1) begin
				DMA_IrqMask <= DMA_IrqCond;		// only interrupt once until the condition is remove
			end
			if ((DMA_IrqCond == 1'b1) && (DMA_IrqMask == 1'b0)) begin
				DMA_IrqMask	<= DMA_IrqCTRL;	// no more retrigger
				DMA_IrqFF 	<= DMA_IrqCTRL;	// the DMA interrupt request pulse from DMA/IDE unit
			end
		end else begin		// only one write pulse
	//// 002A
		case (cRgA[6:0])
			7'b0101010: begin		// 002A
				Reg002A[7:0] <= cRgD[7:0];
				if (cRgD[7:0] == 8'h00) DMA_IrqFF <= 1'b0;			// clear the DMA_IrqFF
			end
	//// 002C
			7'b0101100: begin		// 002C
				if (cRgD == 8'hE1) begin
					Rd2ECnt <= 6'b00_0001;		// start up the counter
	//				Reg002C[7:0]	<= cRgD[7:0];
				end
			end
	//// 0032
			7'b0110010: begin		// 0032
				DMARMC		<= 1'b0;
				DMA_ARM		<= 1'b0;	//// clear the ARM signal
				DMA_IrqFF	<= 1'b0;	// clear all possible old DMA interrupt
				Reg0064[2]	<= 1'b0;
				PS2WrIDE		<= cRgD[0];		// set the direction
			end
	//// 0038
	//			if (cRgA[6:0]= "0111000") begin		// 0038
	//				if (cRgD = X"03") begin
	//					DMA_ARM	<= 1'b0;
	//				end if;
	//			end if;
	//// 0042
			7'b1000010: begin		// 0042
				R42Is03	<= ~(cRgD[7] | cRgD[6] | cRgD[5] | cRgD[4] | cRgD[3] | cRgD[2]) & cRgD[1] & cRgD[0];
			end
	//// 0044
			7'b1000100: begin		// 0044
				R44Is2X	<= ~(cRgD[7] | cRgD[6] | cRgD[4] | cRgD[3]) & cRgD[5];
				R44Is4X	<= ~(cRgD[7] | cRgD[5] | cRgD[4] | cRgD[3]) & cRgD[6];
				R44[2]	<= cRgD[2];
				R44[1]	<= cRgD[1];
				R44[0]	<= cRgD[0];
			end
	//// 004E
			7'b1001110: begin		// 004E
				UDO[2]	<= (D_UnChg & UDO[2]) | (~(D_UnChg) & UDMA_SEL & R44[2]);
				UDO[1]	<= (D_UnChg & UDO[1]) | (~(D_UnChg) & UDMA_SEL & R44[1]);
				UDO[0]	<= (D_UnChg & UDO[0]) | (~(D_UnChg) & UDMA_SEL & R44[0]);
				MDO[2]	<= (D_UnChg & MDO[2]) | (~(D_UnChg) & MDMA_SEL & R44[2]);
				MDO[1]	<= (D_UnChg & MDO[1]) | (~(D_UnChg) & MDMA_SEL & R44[1]);
			end
	//// 0064
			7'b1100100: begin		// 0064 
				Reg0064[7:0] <= cRgD[7:0];
			end
		endcase
		end	// Write Pulse group
	end // bcRST group
end	// clock
endmodule
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.