您的位置:首页 > 其它

【黑金原创教程】【FPGA那些事儿-驱动篇I 】实验二十二:SDRAM模块⑤ — FIFO读写

2015-04-22 11:57 471 查看

 

经过漫长的战斗以后,我们终于来到最后。对于普通人而言,页读写就是一名战士的墓碑(最终战役) ... 然而,怕死的笔者想透过这个实验告诉读者,旅程的终点就是旅程的起点。一直以来,笔者都在烦恼“SDRAM是否应该成为储存类?”SDRAM作为一介储存资源(储存器),它的好处就是大容量空间,坏处则就是麻烦的控制规则,还有中规中矩的沟通速率。

相比之下,片上内存无论是控制的难度,还是沟通的速率,它都远远领先SDRAM。俗语常说,愈是强力的资源愈是珍贵 ... 对此,片上内容的容量可谓是稀罕的程度。实验二十二的要求非常单纯:

”请问如何建立基于SDRAM储存资源的FIFO存储模块呢?“,笔者问道。





图22.1 SDRAM基础模块。

图22.1是基于实验十八修改而成的SDRAM基础模块,修改对象除了SDRAM控制模块以外,SDRAM功能模块保持实验十八的状态,即单字读写。SDRAM控制模块,除了多出Tag以外,Addr的驱动也由该模块负责。具体的内容,让我们来看代码吧:

1.    module sdram_ctrlmod


[code]2. (


3.        input CLOCK,


4.        input RESET,


5.        input [1:0]iCall, // [1]Write, [0]Read


6.        output [1:0]oDone,


7.        output [3:0]oCall,


8.        input iDone,


9.        output [23:0]oAddr,


10.        output [1:0]oTag


11.    );


12.        parameter WRITE = 4'd1, READ = 4'd4, REFRESH = 4'd7, INITIAL = 4'd8;


13.        parameter TREF = 11'd1040;


14.

[/code]

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

以上内容为相关的出入端声明以及常量。其中多了24位宽的oAddr与2位宽的oTag。

15.reg [1:0]C7;


[code]16. reg [1:0]isDo;


17.


18.         always @ ( posedge CLOCK or negedge RESET ) // sub


19.             if( !RESET )


20.         begin


21.                C7 <= 2'b10;


22.                         isDo <= 2'b00;


23.                    end


24.              else


25.begin


26.


27.                        if( iCall[1] & C7[1] ) isDo[1] <= 1'b1;


28.                        else if( iCall[0] & C7[0] ) isDo[0] <= 1'b1;


29.


30.                        if( isDo[1] & isDone[1] ) isDo[1] <= 1'b0;


31.                        else if( isDo[0] & isDone[0] ) isDo[0] <= 1'b0;


32.


33.                        if( isDone ) C7 <= {isDo[0],isDo[1]};


34.               else if( iCall ) C7 <= { C7[0], C7[1] };


35.


36.                    end


37.

[/code]

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

以上内容为轮流协调的周边操作。具体内容与实验十七一样。

38.        reg [3:0]i;


[code]39. reg [10:0]C1;


40.        reg [3:0]isCall; //[3]Write [2]Read [1]A.Refresh [0]Initial


41.        reg [1:0]isDone;


42.        reg [23:0]D1;


43.        reg [24:0]C2,C3;  // N + 1


44.


45.        always @ ( posedge CLOCK or negedge RESET ) // core


46.            if( !RESET )


47.                 begin


48.                         i <= INITIAL;          // Initial SDRam at first


49.                C1 <= 11'd0;


50.                        isCall <= 4'b0000;


51.                        isDone <= 2'b00;


52.                        D1 <= 24'd0;


53.                        C2 <= 25'd0;


54.               C3 <= 25'd0;


55.         end

[/code]

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

以上内容为相关的寄存器声明与复位操作。其中C2是写指针,C3是读指针,位宽为oAddr + 1。D用来驱动oAddr。

56.             else


[code]57. case( i )


58.


59.       0: // IDLE


60.                        if( C1 >= TREF ) begin C1 <= 11'd0;  i <= REFRESH; end


61.                        else if( isDo[1] ) begin C1 <= C1 + 1'b1; i <= WRITE; end


62.else if( isDo[0] ) begin C1 <= C1 + 1'b1; i <= READ; end


63.                         else begin C1 <= C1 + 1'b1; end


64.


65.               /***********************/


66.

[/code]

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

以上内容为部分核心内容。步骤0是待机状态,其中61~62行改为 isDo[1] 与 isDo[2]。

67.                        1: //Write


[code]68. if( iDone ) begin isCall[3] <= 1'b0; C1 <= C1 + 1'b1; i <= i + 1'b1; end


69.                        else begin isCall[3] <= 1'b1; D1 <= C2[23:0]; C1 <= C1 + 1'b1; end


70.


71.                        2:


72.                        begin C2 <= C2 + 1'b1; isDone[1] <= 1'b1; C1 <= C1 + 1'b1; i <= i + 1'b1; end


73.


74.                        3:


75.               begin isDone[1] <= 1'b0; C1 <= C1 + 1'b1; i <= 4'd0; end


76.


77.                        /***********************/


78.

[/code]

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

以上内容为部分核心内容。步骤1~3是写操作,步骤1将C2[23:0]的内容赋值D。步骤2~3产生完成信号之余也递增C2.

79.                        4: // Read


[code]80. if( iDone ) begin isCall[2] <= 1'b0; C1 <= C1 + 1'b1; i <= i + 1'b1; end


81.                        else begin isCall[2] <= 1'b1; D1 <= C3[23:0]; C1 <= C1 + 1'b1; end


82.


83.                        5:


84.        begin C3 <= C3 + 1'b1; isDone[0] <= 1'b1; C1 <= C1 + 1'b1; i <= i + 1'b1; end


85.


86.                        6:


87.                        begin isDone[0] <= 1'b0; C1 <= C1 + 1'b1; i <= 4'd0; end


88.


89.                        /***********************/


90.

[/code]

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

以上内容为部分核心内容。步骤4~6是写操作,步骤4将C3[23:0]的内容赋值D。步骤5~7产生完成信号之余也递增C3.

91.                        7: // Auto Refresh


[code]92. if( iDone ) begin isCall[1] <= 1'b0; i <= 4'd0; end


93.                        else begin isCall[1] <= 1'b1; end


94.


95.               /***********************/


96.


97.                        8: // Initial


98.       if( iDone ) begin isCall[0] <= 1'b0; i <= 4'd0; end


99.                        else begin isCall[0] <= 1'b1; end


100.


101.                  endcase


102.

[/code]

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

以上内容为部分核心内容。步骤7~8保持不变。

103.        assign oDone = isDone;


[code]104. assign oCall = isCall;


105.        assign oAddr = D1;


106.        assign oTag[1] = ( C2[24]^C3[24] & C2[23:0] == C3[23:0] );


107.         assign oTag[0] = ( C2 == C3 );


108.


109.    endmodule

[/code]

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

以上内容为相关的输出驱动。D1驱动oAddr,第106~107行是写满状态与读空状态的声明。

sdram_funcmod.v

该功能模块与实验十八的内容一模一样。

sdram_demo.v

该组合模块的连线部署完全参照图22.1。

1.    module sdram_basemod


[code]2. (


3.         input CLOCK,


4.         input RESET,


5.


6.         output S_CKE, S_NCS, S_NRAS, S_NCAS, S_NWE,


7.         output [1:0]S_BA,


8.         output [12:0]S_A,


9.         output [1:0]S_DQM,


10.         inout [15:0]S_DQ,


11.


12.         input [1:0]iCall,


13.         output [1:0]oDone,


14. output [1:0]oTag,


15.input [15:0]iData,


16.         output [15:0]oData


17.    );


18.         wire [3:0]CallU1; // [3]Refresh, [2]Read, [1]Write, [0]Initial


19.         wire [23:0]AddrU2;


20.


21.        sdram_ctrlmod U1


22.         (


23.              .CLOCK( CLOCK ),


24.              .RESET( RESET ),


25.     .iCall( iCall ),       // < top ,[1]Write [0]Read


26.              .oDone( oDone ),     // > top ,[1]Write [0]Read


27.              .oAddr( AddrU2 ),    // > U2


28.              .oTag( oTag ),        // > top


29.              .oCall( CallU1 ),      // > U2


30.              .iDone( DoneU2 )           // < U2


31.         );


32.


33.         wire DoneU2;


34.


35.sdram_funcmod U2


36.         (


37.      .CLOCK( CLOCK ),


38.              .RESET( RESET ),


39.              .S_CKE( S_CKE ),           // > top


40.              .S_NCS( S_NCS ),           // > top


41.              .S_NRAS( S_NRAS ),         // > top


42.              .S_NCAS( S_NCAS ),         // > top


43.              .S_NWE( S_NWE ),         // > top


44.      .S_BA( S_BA ),           // > top


45.     .S_A( S_A ),             // > top


46.              .S_DQM( S_DQM ),         // > top


47.              .S_DQ( S_DQ ),           // <> top


48.              .iCall( CallU1 ),            // < U1


49.     .oDone( DoneU2 ),          // > U1


50.              .iAddr( AddrU2 ),          // < U1


51.              .iData( iData ),               // < top


52.              .oData( oData )           // > top


53.         );


54.


55.    endmodule

[/code]

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

连线内容请自己看着办吧。

sdram_demo.v





图22.3 实验二十二的建模图。

图22.3是实验二十二的建模图,左边的周边操作负责写入数据,右边的核心操作负责读取数据并且经由TXD发送出去。具体内容我们还是来看代码吧。

1.    module sdram_demo


[code]2. (


3.        input CLOCK,


4.        input RESET,


5.        output S_CLK,


6.        output S_CKE, S_NCS, S_NRAS, S_NCAS, S_NWE,


7.        output [12:0]S_A,


8.        output [1:0]S_BA,


9.        output [1:0]S_DQM,


10.        inout [15:0]S_DQ,


11.        output TXD


12.    );

[/code]

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

以上内容为相关的出入端声明。

13.         wire CLOCK1,CLOCK2;


[code]14.


15.pll_module U1


16.         (


17.        .inclk0 ( CLOCK ), // 50Mhz


18.                .c0 ( CLOCK1 ),  // 133Mhz -210 degree phase


19.                .c1 ( CLOCK2 )   // 133Mhz


20.);


21.

[/code]

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

以上内容为PLL模块的实例化。

22.         wire [1:0]DoneU2;


[code]23. wire [15:0]DataU2;


24.         wire [1:0]TagU2;


25.


26.         sdram_basemod U2


27.         (


28.             .CLOCK( CLOCK1 ),


29.             .RESET( RESET ),


30.              .S_CKE( S_CKE ),


31.              .S_NCS( S_NCS ),


32.     .S_NRAS( S_NRAS ),


33.              .S_NCAS( S_NCAS ),


34.     .S_NWE( S_NWE ),


35.     .S_A( S_A ),


36.              .S_BA( S_BA ),


37.      .S_DQM( S_DQM ),


38.              .S_DQ( S_DQ ),


39.              .iCall( {isWR,isRD} ),


40.              .oDone( DoneU2 ),


41.              .iData( D2 ),


42.              .oData( DataU2 ),


43.              .oTag( TagU2 )


44. );

[/code]

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

以上内容为SDRAM基础模块的实例化,注意第39行的iCall是由 isWR与isRD联合驱动。此外,第43行也多了oTag。

46.         reg [5:0]i;


[code]47. reg [15:0]D2;


48.         reg isWR;


49.


50.         always @ ( posedge CLOCK1 or negedge RESET )


51.             if( !RESET )


52.                 begin


53.                           i <= 6'd0;


54.                 D2 <= 16'hA000;


55.                 isWR <= 1'b0;


56.                 end


57.             else


58.                 case( i )


59.


60.                          0:


61.                         if( !TagU2[1] ) i <= i + 1'b1;


62.


63.                         1:


64.                     if( DoneU2[1] ) begin isWR <= 1'b0; i <= i + 1'b1; end


65.                else begin isWR <= 1'b1; end


66. 


67.                         2:


68.                         if( D2 == 16'hA1FF ) i <= i + 1'b1;


69.                         else begin D2[11:0] <= D2[11:0] +  1'b1; i <= 6'd0; end


70. 


71.                         3:


72.                         i <= i;


73.


74.                endcase


75.       

[/code]

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

以上内容为写作用的周边操作。步骤0检测是否写满,步骤1写入数据,步骤2判断是否写满512次,不是的话就递增内容。步骤3是写完发呆。

76.         reg [5:0]j,Go;


[code]77. reg [10:0]C1;


78.         reg [15:0]D3;


79.         reg [10:0]T;


80.         reg isRD;


81.         reg rTXD;


82.


83.         parameter B115K2 = 11'd1157, TXFUNC = 6'd16;


84.


85.        always @ ( posedge CLOCK1 or negedge RESET )


86.             if( !RESET )


87.                 begin


88.                     j <= 6'd0;


89.                          Go <= 6'd0;


90.  C1 <= 11'd0;


91.                          D3 <= 16'd0;


92.                          T <= 11'd0;


93.                          isRD <= 1'b0;


94.  rTXD <= 1'b1;


95.        end


96.             else


97.                 case( j )


98.


99.                         0:


100. if( !TagU2[0] ) j <= j + 1'b1;


101.


102.                 1:


103.                         if( DoneU2[0] ) begin D3 <= DataU2; isRD <= 1'b0; j <= j + 1'b1; end


104.                         else begin isRD <= 1'b1; end


105.                


106.                         2:


107.                         begin T <= { 2'b11, D3[15:8], 1'b0 }; j <= TXFUNC; Go <= j + 1'b1; end


108.                 


109.                         3:


110.                         begin T <= { 2'b11, D3[7:0], 1'b0 }; j <= TXFUNC; Go <= j + 1'b1; end


111.                


112.                         4:


113.                         if( D3 == 16'hA1FF ) j <= j + 1'b1;


114.                 else j <= 6'd0;


115.                


116.                        5:


117.                j <= j;


118.


119.                        /******************************/


120.

[/code]

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

以上内容为部分核心操作。步骤0检测是否读空,步骤1读出数据,步骤2~3将数据发送数据,步骤4判断是否执行512次?如果不是的话就返回步骤0,是的话就递增i进入发呆的步骤5。


121.                 16,17,18,19,20,21,22,23,24,25,26:


[code]122. if( C1 == B115K2 -1 ) begin C1 <= 11'd0; j <= j + 1'b1; end


123.                         else begin rTXD <= T[j - 16]; C1 <= C1 + 1'b1; end


124.


125.       27:


126.     j <= Go;


127.


128.                endcase


129.


130.         assign S_CLK = CLOCK2;


131.         assign TXD = rTXD;


132.


133.    endmodule

[/code]

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, "Courier New", courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

以上内容为核心操作以及输出驱动·。综合完毕便下载程序,如果串口调试软件出现 A000~A1FF,表示实验成功。

细节一:完整的个体模块

本实验的SDRAM基础模块已经准备就绪。

细节二:小谈储存类

FIFO机制的SDRAM很可能实用性不强。相对低级建模II而言,SDRAM已经脱离死板的印象,任何畸形的储存方式,都有可能实现在任何储存资源之上。举例而言,片上内存储存资源可以实现FIFO功能,IIC储存资源也可以实现FIFO功能,SDRAM储存资源也可以实现FIFO功能。

如果按照这条思路逆向思考的话,如果SDRAM储存资源可以实现功能C,那么IIC储存资源还有片上内存储存资源同样也可以实现功能C。如此一来,建模的自由度会大大增高,喜爱建模的孩子也会开心至极。如果读者是变态,那么一块小小的SDRAM储存资源实现多功能读写如:单字读写,多字读写,页读写,甚至FIFO读写,集于一身是有可能的。不管怎么样,实验二十二所要表达的信息已经非常清晰,即储存类的伸缩性与可塑性。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐