實驗目的:

   熟悉CPLD的使用

   學習CPLD基本原理,掌握CPLD的開發流程。

module BUF2410(clock,nReset,nEXTBUS,BUFDIR,BUFDIR1,nFCE,nOE,nGCS,nFWE,nFRE,dmaMode,nDmaStart,nDREQ,nDACK,addr,data,nWAIT_OD);
input clock,nReset;
input nDmaStart;
input nFCE;
// input [1:0] dmaMode; //remove by eric rong 2003-7-8
input dmaMode;
input nDACK;
output nDREQ;

// input [3:0] addr; //remove by eric rong 2003-7-8
input [2:0] addr;
output [3:0] data;
// input [6:0] nGCS; //remove by eric rong 2003-7-8
input [5:0] nGCS;
input nOE;
input nFWE;
input nFRE;

output nWAIT_OD;
output nEXTBUS;
output BUFDIR;
output BUFDIR1;

//unused temporarily
// wire [3:0] addr; //remove by eric rong 2003-7-8
wire [2:0] addr;
wire nDmaStart;
// wire [1:0] dmaMode; //remove by eric rong 2003-7-8
wire dmaMode;
wire nXDACK;
wire clock;
wire nReset;
wire nFCE;

wire [3:0] wdata;

// wire nXDREQ;
// wire [3:0] data;
wire nWAIT;

//why don't work?
//assign nXDREQ = 1'bz;
//assign data[3:0] = 4'bz;
assign nWAIT_OD = (!nGCS[4] && !nWAIT) ? 1'b0:1'bz;
assign data[3:0] = (!nGCS[4] && !nOE ) ? wdata:4'bz;
assign BUFDIR1 = BUFDIR;

DMATEST m0(clock,nReset,dmaMode,nDmaStart,nDREQ,nDACK,dmaState);
WAITTEST w0(clock,nReset,nWAIT,wdata,nGCS[4],nOE);
//nGCS4 is used as the nCS signal for nWAIT test.

BUFCTRL b0(nEXTBUS,nGCS,nFWE,nFRE);
BUFDIR b1(BUFDIR,nOE,nFRE);
endmodule




module BUFCTRL(nEXTBUS,nGCS,nFWE,nFRE);
output nEXTBUS;
// input [6:0] nGCS; //remove by eric rong 2003-7-8
input [5:0] nGCS;
input nFWE;
input nFRE;

// assign nEXTBUS = nGCS[0] && nGCS[1] && nGCS[2] && nGCS[3] && nGCS[4] && nGCS[5] && nGCS[6] && nFWE && nFRE;
// the up code is remove by eric rong 2003-7-8
assign nEXTBUS = nGCS[0] && nGCS[1] && nGCS[2] && nGCS[3] && nGCS[4] && nGCS[5] && nFWE && nFRE;

endmodule




module BUFDIR(BUFDIR,nOE,nFRE);
output BUFDIR;
input nOE;
input nFRE;

assign BUFDIR = nOE && nFRE;
endmodule




module DMATEST(clock,nReset,dmaMode,nDmaStart,nDREQ,nDACK,state);
input clock,nReset;
input nDmaStart;
// input [1:0] dmaMode; //remove by eric rong 2003-7-8
input dmaMode;
input nDACK;
output nDREQ;
output [4:0] state;

reg nDREQ;
reg enCounter;
reg preset16,preset1;
reg [4:0] state;
reg [3:0] counter;
reg snDACK;
reg snDmaStart;

parameter [1:0] HS16=1,WHOLE=2; //mode
parameter [4:0] READY=0,HS0=1,HS1=2,HS2=3,HS3=4,
HS4=5,WH0=6,FL0=7,DM0=8,ERR=9;

always @(posedge clock or negedge nReset)
begin
if(!nReset)counter=0;
else if(enCounter)counter=counter-1;
else if(preset16)counter=0;
else if(preset1)counter=1;
end

//always @(negedge clock) //for more faster nXDREQ generation
always @(posedge clock) //because device is slow, negedge may not operate in 66Mhz
begin
snDACK=nDACK;
end

always @(posedge clock)
begin
snDmaStart=nDmaStart;
end


//CAUTION:
//set dmaMode bits first. And then,set dmaStart bit.
//After DMA is started, cleare dmaStart bit.
always @(posedge clock or negedge nReset)
begin
if(!nReset)
state=READY;
else
case(state)
READY:
if(!snDmaStart)
begin
case(dmaMode)
HS16:state=HS0;
WHOLE:state=WH0;
default:state=READY;
endcase
end
else
state=READY;
HS0: state=HS1;
HS1:
if(snDACK)
state=HS1;
else
state=HS2;
HS2:
if(snDACK==0)state=HS2;
else state=HS3;
HS3:state=HS4; //counter--
HS4:if(counter!=0)
state=HS1; //next DMA request.
else begin
if(!nDmaStart) //check dmaStart bit is cleared?
state=HS4;
else
state=READY;
end

WH0: state=HS1;
FL0: state=FL0; //not implemented yet.
DM0: state=DM0; //not implemented yet.
default:state=ERR;
endcase
end


always @(state)
begin
preset16=0;
preset1=0;
nDREQ=1;
enCounter=0;
case(state)
HS0:
preset16=1;
HS1:
nDREQ=0;
HS3:
enCounter=1;
WH0:
preset1=1;
endcase
end
endmodule



module WAITTEST(clock,nReset,nWAIT,data,nGCS,nOE);
input clock,nReset;
input nGCS,nOE;
output nWAIT;
output [3:0] data;

reg nWAIT;
reg preset;
reg enCounter;
reg [3:0] data;
reg [2:0] wState;
reg [3:0] counter;

parameter [1:0] W0=0,W1=1,W2=2,W3=3,W4=4,W5=5,W6=6;

always @(posedge clock or negedge nReset)
begin
if(!nReset)counter=0;
else if(enCounter)counter=counter-1;
else if(preset)counter=0;
end

always @(posedge clock or negedge nReset)
begin
if(!nReset)
wState=W0;
else
case(wState)
W0: if(nGCS)
wState=W0;
else
wState=W1;
W1: wState=W2;
W2: wState=W3;
W3: if(counter>0)
wState=W3;
else
wState=W4;
W4: wState=W5;
W5: if(nOE==0)
wState=W5;
else
if(nGCS==0)
wState=W6;
else
wState=W0;
W6: if(nGCS==0)
wState=W6;
else
wState=W0;
endcase
end

always @(wState)
begin
preset=0;
enCounter=0;
nWAIT=1;
data=4'b0101;
case(wState)
W1: begin
preset=1;
nWAIT=0;
end
W2: begin
enCounter=1;
nWAIT=0;
end
W3: begin
nWAIT=0;
enCounter=1;
end
W4: begin
nWAIT=1;
data=4'b1010;
end
W5: data=4'b1010;
endcase
end

endmodule