本帖最后由 feihufuture 于 2021-7-30 11:50 编辑
这个也是当年从事自动化时写的,可以参考下:
[payamount]3.00[/payamount]
[pay] module LY68L6400
(
input Clk40M,
input Clk,//40MHz
input Rst,
output PsramClk,
output PsramCsN,
inout [3 : 0] PsramData,
input UserRd,
input [23 : 0] UserRdAddr,//UserRdAddr[23] is the msb
output [63 : 0] UserDataRx,
input UserWr,
input [23 : 0] UserWrAddr,
input [63 : 0] UserDataTx,
output UserDataDone
);
//--------------------------------------------------------------------------------------------------
parameter IDLE = 3'd0;
parameter RD = 3'd1;
parameter WR = 3'd2;
parameter DONE = 3'd3;
//generate 20MHz SPI clock, not using the max frequency 40MHz.
reg [11 : 0] WorkCnt = 0;
reg [3 : 0] TxPhase = 0;
reg [3 : 0] RxPhase = 0;
reg PsramCsNReg = 0;
(*keep = "true"*)reg [2 : 0] Ws = 0;
reg [23 : 0] Address = 0;
reg [63 : 0] UserDataTx0 = 0;
reg [63 : 0] UserDataRx0 = 0;
reg [3 : 0] PsramDataReg = 0;
//8+6+1024*2=2062
always @ ( posedge Clk )
begin
if( Rst ) WorkCnt <= 12'b0;
else if( ( Ws == RD ) || ( Ws == WR ) ) WorkCnt <= WorkCnt + 1'b1;
else WorkCnt <= 12'b0;
end
always @ ( posedge Clk )
begin
if( Rst ) TxPhase <= 4'b0;
else if( WorkCnt > 12'd14 ) TxPhase <= TxPhase + 1'b1;
else TxPhase <= 4'b0;
end
always @ ( posedge Clk )
begin
if( Rst ) RxPhase <= 4'b0;
else if( WorkCnt > 12'd21 ) RxPhase <= RxPhase + 1'b1;
else RxPhase <= 4'b0;
end
reg [7:0] Loop = 0;
always @ ( posedge Clk )
begin
if( Rst ) Loop <= 8'b0;
else if( Ws == RD )
begin
if( &RxPhase ) Loop <= Loop + 1'b1;
end
else if( Ws == WR )
begin
if( &TxPhase ) Loop <= Loop + 1'b1;
end
else Loop <= 8'b0;
end
always @ ( posedge Clk )
begin
if( Rst ) Ws <= IDLE;
else
case( Ws )
IDLE : if( UserRd ) Ws <= RD;
else if( UserWr ) Ws <= WR;
RD : if( WorkCnt == 12'd2071 ) Ws <= DONE;
WR : if( WorkCnt == 12'd2064 ) Ws <= DONE;
DONE : Ws <= IDLE;
endcase
end
always @ ( posedge Clk )
begin
if( UserRd ) Address <= UserRdAddr;
else if( UserWr ) Address <= UserWrAddr;
end
always @ ( posedge Clk )
begin
if( UserWr ) UserDataTx0 <= UserDataTx;
end
assign PsramCsN = PsramCsNReg;
always @ ( posedge Clk )
begin
case( WorkCnt )
12'd0 : PsramCsNReg <= 1'b1;
12'd1 : PsramCsNReg <= 1'b0;
12'd2064 : PsramCsNReg <= ( Ws == WR ) ? 1'b1 : 1'b0;
12'd2070 : PsramCsNReg <= 1'b1;
default : ;
endcase
end
assign PsramClk = Clk40M & ( ( ( Ws == WR ) & ( WorkCnt > 12'b1 ) & ( WorkCnt < 12'd2064)
)||
( ( Ws == RD ) & ( WorkCnt > 12'b1 ) & ( WorkCnt < 12'd2069)
)
);
assign PsramData = ( ( Ws == WR ) || ( ( Ws == RD) && ( WorkCnt < 12'd16 ) ) ) ? PsramDataReg : 4'bzzzz;
always @ ( posedge Clk )
begin
case( WorkCnt )
12'd1 : PsramDataReg <= ( Ws == WR ) ? {3'bzzz,1'b0} : {3'bzzz,1'b1};
12'd2 : PsramDataReg <= ( Ws == WR ) ? {3'bzzz,1'b0} : {3'bzzz,1'b1};
12'd3 : PsramDataReg <= ( Ws == WR ) ? {3'bzzz,1'b1} : {3'bzzz,1'b1};
12'd4 : PsramDataReg <= ( Ws == WR ) ? {3'bzzz,1'b1} : {3'bzzz,1'b0};
12'd5 : PsramDataReg <= ( Ws == WR ) ? {3'bzzz,1'b1} : {3'bzzz,1'b1};
12'd6 : PsramDataReg <= ( Ws == WR ) ? {3'bzzz,1'b0} : {3'bzzz,1'b0};
12'd7 : PsramDataReg <= ( Ws == WR ) ? {3'bzzz,1'b0} : {3'bzzz,1'b1};
12'd8 : PsramDataReg <= ( Ws == WR ) ? {3'bzzz,1'b0} : {3'bzzz,1'b1};
12'd9 : PsramDataReg <= Address[23:20];
12'd10 : PsramDataReg <= Address[19:16];
12'd11 : PsramDataReg <= Address[15:12];
12'd12 : PsramDataReg <= Address[11:8];
12'd13 : PsramDataReg <= Address[7:4];
12'd14 : PsramDataReg <= Address[3:0];
default : begin
case( TxPhase )
4'd0: PsramDataReg <= UserDataTx0[7:4];
4'd1: PsramDataReg <= UserDataTx0[3:0];
4'd2: PsramDataReg <= UserDataTx0[15:12];
4'd3: PsramDataReg <= UserDataTx0[11:8];
4'd4: PsramDataReg <= UserDataTx0[23:20];
4'd5: PsramDataReg <= UserDataTx0[19:16];
4'd6: PsramDataReg <= UserDataTx0[31:28];
4'd7: PsramDataReg <= UserDataTx0[27:24];
4'd8: PsramDataReg <= UserDataTx0[39:36];
4'd9: PsramDataReg <= UserDataTx0[35:32];
4'd10: PsramDataReg <= UserDataTx0[47:44];
4'd11: PsramDataReg <= UserDataTx0[43:40];
4'd12: PsramDataReg <= UserDataTx0[55:52];
4'd13: PsramDataReg <= UserDataTx0[51:48];
4'd14: PsramDataReg <= UserDataTx0[63:60];
4'd15: PsramDataReg <= UserDataTx0[59:56];
endcase
end
endcase
end
always @ ( posedge Clk )
begin
case( RxPhase )
4'd0: UserDataRx0[7:4] <= PsramData;
4'd1: UserDataRx0[3:0] <= PsramData;
4'd2: UserDataRx0[15:12] <= PsramData;
4'd3: UserDataRx0[11:8] <= PsramData;
4'd4: UserDataRx0[23:20] <= PsramData;
4'd5: UserDataRx0[19:16] <= PsramData;
4'd6: UserDataRx0[31:28] <= PsramData;
4'd7: UserDataRx0[27:24] <= PsramData;
4'd8: UserDataRx0[39:36] <= PsramData;
4'd9: UserDataRx0[35:32] <= PsramData;
4'd10: UserDataRx0[47:44] <= PsramData;
4'd11: UserDataRx0[43:40] <= PsramData;
4'd12: UserDataRx0[55:52] <= PsramData;
4'd13: UserDataRx0[51:48] <= PsramData;
4'd14: UserDataRx0[63:60] <= PsramData;
4'd15: UserDataRx0[59:56] <= PsramData;
endcase
end
assign UserDataRx = UserDataRx0;
reg UserDataDoneReg = 0;
assign UserDataDone = UserDataDoneReg;
always @ ( posedge Clk )
begin
if( Rst ) UserDataDoneReg <= 0;
else
case( Ws )
RD : if( WorkCnt == 12'd2069 ) UserDataDoneReg <= 1;
else UserDataDoneReg <= 0;
WR : if( WorkCnt == 12'd2064 ) UserDataDoneReg <= 1;
else UserDataDoneReg <= 0;
default : UserDataDoneReg <= 0;
endcase
end
//--------------------------------------------------------------------------------------------------
endmodule[/pay]
|