久久国产成人av_抖音国产毛片_a片网站免费观看_A片无码播放手机在线观看,色五月在线观看,亚洲精品m在线观看,女人自慰的免费网址,悠悠在线观看精品视频,一级日本片免费的,亚洲精品久,国产精品成人久久久久久久

分享

一天一個設計實例-RAM、ROM模塊程序設計

 比特波特 2021-02-26
1.1.1RAM和ROM
前面已經(jīng)介紹了,,RAM和SRAM之間的區(qū)別,,這里就詳細介紹RAM和ROM。
前面說,,存儲分為“存儲資源”和“存儲方式”,。
代碼3?3 簡單的靜態(tài) ROM 模塊
1.module rom( input [1:0]iAddr, output [7:0]oData );  
2.  
3.
4.reg [7:0]D1;  
5.always @ (*)  
6.    if( iAddr == 2’ b00 ) D1 = 8’ hA;  
7.    else if( iAddr == 2’ b01 ) D1 = 8’ hB;  
8.    else if( iAddr == 2’ b10 ) D1 = 8’ hC;  
9.    else if( iAddr == 2’ b11 ) D1 = 8’ hD;  
10.    else D1 = 8’ dx;  
11.  
12.assign oData = D1;  
13.  
14.endmodule  
例如一個簡單的靜態(tài) ROM 模塊,它可以基于寄存器或者片上內(nèi)存,,結(jié)果如代碼3?3代碼3?4所示,。代碼代碼3?3是基于寄存器的靜態(tài) ROM,它有 2 位 iAddr 與 8 位的 oData,,其中第 3~8 行是 ROM 的內(nèi)容定義,,第 10 行則是輸出驅(qū)動,為此 oData 會根據(jù) iAddr的輸入產(chǎn)生不同的輸出,。
代碼3?4 基于片上內(nèi)存的靜態(tài) ROM
1.module rom( input [1:0]iAddr, output [7:0]oData );  
2.  
3.reg [7:0] RAM [3:0];  
4.  
5.initial begin  
6.    RAM[0] = 8’ hA;  
7.    RAM[1] = 8’ hB;  
8.    RAM[2] = 8’ hC;  
9.    RAM[3] = 8’ hD;  
10.end  
11.  
12.assign oData = RAM[ iAddr ];  
13.  
14.endmodule  
反之,,代碼3?4是基于片上內(nèi)存的靜態(tài) ROM,它也有 2 位 iAddr 與 8 位 oData,,第 3~7行是內(nèi)容的定義也是初始化片上內(nèi)存,,第 12 行則是輸出驅(qū)動, oData 會根據(jù) iAddr 的輸出產(chǎn)生不同的輸出,。
代碼3?3代碼3?4雖然都是靜態(tài) ROM,,不過卻有根本性的不同,因為兩者源于不同的儲存資源,,其中最大的證據(jù)就是第 12 行的輸出驅(qū)動,,前者由寄存器驅(qū)動,后者則由片上內(nèi)存驅(qū)動,。不同的儲存資源也有不同的性質(zhì),,例如寄存器操作簡單,而且布線有余,,不過不支持大容量的儲存行為,。換之,片上內(nèi)存雖然操作麻煩,,布線也緊湊,,可是卻支持大容量的儲存行為。
儲存方式相較儲存資源理解起來稍微抽象一點,,而且想象范圍也非常廣大 ... 如果儲存資源是“容器的種類”,,那么儲存方式就是“容器的用法”。舉例而言,,一個簡單靜態(tài)ROM,,根據(jù)需要它還可以演變成為其它亞種,例如常見的單口 ROM 或者雙口 ROM 或等,。
代碼3?5 單口 ROM
1.module rom( input CLOCK,, input [1:0]iAddr, output [7:0]oData );  
2.reg [7:0] RAM [3:0];  
3.initial begin  
4.    RAM[0] = 8’ hA;  
5.    RAM[1] = 8’ hB;  
6.    RAM[2] = 8’ hC;  
7.    RAM[3] = 8’ hD;  
8.end  
9.  
10.reg [1:0] D1;  
11.always @ ( posedge CLOCK)  
12.    D1 <= iAddr;  
13.  
14.  
15.assign oData = RAM[ D1 ];  
16.  
17.endmodule  
代碼3?5所示,那是單口 ROM 的典型例子,,然而單口 ROM 與靜態(tài) ROM 之間的差別就在于前者有時鐘信號,,后者沒有時鐘信號。期間,,代碼3?5用 D1 暫存 iAddr,,然后再由 D1 充當 RAM 的尋址工具。
代碼3?6 雙口 ROM
1.module rom( input CLOCK,, input [1:0]iAddr1, iAddr2,, output [7:0]oData1, oData2 );  
2.reg [7:0] RAM [3:0];  
3.initial begin  
4.    RAM[0] = 8’ hA;  
5.    RAM[1] = 8’ hB;  
6.    RAM[2] = 8’ hC;  
7.    RAM[3] = 8’ hD;  
8.end  
9.  
10.reg [1:0] D1;  
11.always @ ( posedge CLOCK)  
12.    D1 <= iAddr1;  
13.  
14.assign oData1 = RAM[ D1 ];  
15.  
16.reg [1:0] D2;17. always @ ( posedge CLOCK)  
17.    D2 <= iAddr2;  
18.  
19.assign oData2 = RAM[ D2 ];  
20.  
21.endmodule  
代碼3?6所示,,那是雙口 ROM 的典型例子,,如果將其比較單口 ROM,,它則多了一 iAddr 與 oData 而已,即 iAddr1 與 oData1,, iAddr2 與 oData2,。第 10~14 行是第一組(第一口),第 16~20 行則是第二組(第二口),,不過兩組 iAddr 與 oData 都從同樣的RAM 資源哪里讀取結(jié)果,。
事實上, ROM 還會根據(jù)更多不同要求產(chǎn)生更多亞種,,而且亞種的種類也絕非局限在于專業(yè)規(guī)范,, 因為亞種的儲存模塊會依照設計者的欲望——有多畸形就多畸形,死守傳統(tǒng)只會固步自封而已,。無論模塊對象是靜態(tài) ROM,,單口 ROM 還是雙口 ROM 等 ... 筆者眼中,它們都是任意的“儲存方式”而已,。
根據(jù)筆者的妄想,,儲存方式的覆蓋范圍非常之廣。簡單而言,,凡是模塊涉及數(shù)據(jù)的儲存操作,,低級建模 II 都視為儲存類,。舉例而言,, ROM 模塊儲存自讀不寫的數(shù)據(jù),;RAM模塊儲存又讀又寫的數(shù)據(jù); FIFO 模塊儲存先寫先讀的數(shù)據(jù),。
為此,,我們可以這樣命名它們:
rom_savemod.v // rom 儲存模塊
ram_savemod.v // ram 儲存模塊
FIFO_savemod.v // FIFO 儲存模塊
FPGA和查找表
查表就是順序語言“空間換速度”的優(yōu)化手段。查表既是 ROM 也是一種儲存方式,。如果把話說難聽一點,,所謂查表也不過是順序語言在利用數(shù)組模仿 ROM 而已,它除了便捷性好以外,,無論是資源的消耗,,還是時鐘的消耗等效率都遠遠不及描述語言的 ROM。順序語言偶爾雖然也有山寨的 FIFO,, Shift 等儲存方式,,不過性能卻是差強人意。
順序語言之所以那么遜色,,那是因為被鋼鐵一般堅固的順序結(jié)構(gòu)綁得死死,。述語言是自由的語言,結(jié)構(gòu)也是自由。雖然自由結(jié)構(gòu)為人們帶來許多麻煩,,但是“儲存方式”可以描述的范疇,,絕對超乎人們的估量。歸根究底,,究竟是順序語言好,,還是描述語言模比較厲害呢?除了見仁見智以外,,答案也只有天知曉,。
隨著時代不斷變遷,,“儲存方式”的需求也逐漸成長,,例如 50 年代需要 rom, 60 年代需 ram,, 70 年代需要 FIFO,。二十一世紀的今天,保守的規(guī)范再也無法壓抑“儲存方式”的放肆衍生,,例如 rom 衍生出來靜態(tài) rom,,單口 rom,雙口 rom 等許多亞種,;此外,, FIFO也衍生出同步 FIFO 或者異步 FIFO 等亞種。至于 ram 的亞種,,比前兩者更加恐怖,!不管怎么樣,大伙都是筆者的好孩子,,亦即 ××_savemod,。
雖然偉大的官方早已準備數(shù)之不盡的儲存模塊,但是筆者還是強調(diào)手動建模比較好,,因為官方的東西有太多限制了,。此刻,可能有人跳出來反駁道:“為什么不用官方插件模塊,,它們既完整又便捷,,那個白癡才不吃天上掉下來的餡餅!筆者是呆子,!蠢貨,!“。
話說這位同學也別那么激動,,如果讀者一路索取它人的東西,,學習只會本末倒置而已。除此之外,,官方插件模塊是商業(yè)的產(chǎn)物,,不僅自定義有限內(nèi)容也是隱性,,而且還是不擇不扣的快餐??觳图疵牢兑卜奖?,偶爾吃下還不錯,但是長期食用就會危害健康,,危害學習,。
FIFO 插件的數(shù)據(jù)位寬能不能設為 11 位?”,,某人求救道,。
ram 插件怎樣調(diào)用?怎樣仿真,?”,,某人求救道。
類似問題每月至少出現(xiàn)數(shù)十次,,而且還是快餐愛好者提問的,。筆者也有類似的經(jīng)驗,所以非常明白這種心境,。年輕的筆者就是愛好快餐,,凡事拿來主義,伸手比吃飯更多,。漸漸地,筆者愈來愈懶,,能不增反降,,最終變成只會求救的肥仔而已。后悔以后,,筆者才腳踏實地自力建模,,慢慢減肥,。
在此,,筆者滔滔不絕只想告知讀者 ... 自由結(jié)構(gòu)雖然麻煩,不過這是將想象力具體化的關鍵因素,,儲存模塊的潛能遠超保守的規(guī)范。規(guī)范有時候就像一粒絆腳石,讓人不經(jīng)意跌倒一次又一次,,阻礙人們前進,限制人們想象,,最后讓人成為不動手即不動腦的懶人,。
1.1.2ROM和RAM組合程序設計
3?12 實驗建模圖
3?12本次設計的建模圖,組合模塊 savemod_demo 的內(nèi)容包括一支核心操作,,一只數(shù)碼管基礎模塊,,還有一個儲存模塊。核心操作會拉高 oEn,,并且將相關的 Addr 與 Data 寫入儲存模塊,,緊接著該儲存模塊會經(jīng)由 oData 驅(qū)動數(shù)碼管基礎模塊。
3?13 推擠位移存儲模塊的建模圖
顧名思義,,該模塊是推擠功能再加上位移功能的儲存模塊,,左邊是儲存模塊常見的 iEn,,iAddr 與 iData,,右邊則是超乎常規(guī)的 oData。
代碼3?7 推擠位移存儲模塊代碼
1.module pushshift_savemod  
2.(  
3.    input CLOCK,RESET,  
4.     input iEn,  
5.     input [3:0]iAddr,  
6.     input [3:0]iData,  
7.     output [23:0]oData  
8.);  
9.    reg [3:0] RAM [15:0];  
10.     reg [23:0] D1;  
11.  
12.    always @ ( posedge CLOCK or negedge RESET )  
13.         if( !RESET )  
14.              begin  
15.                    D1 <=  24'd0;   
16.                end  
17.          else if( iEn )  
18.              begin  
19.                    RAM[ iAddr ] <= iData;  
20.                     D1[3:0] <= RAM[ iAddr ];  
21.                     D1[7:4] <= D1[3:0];  
22.                     D1[11:8] <= D1[7:4];  
23.                     D1[15:12] <= D1[11:8];  
24.                     D1[19:16] <= D1[15:12];  
25.                     D1[23:20] <= D1[19:16];  
26.                end  
27.                  
28.    assign oData = D1;  
29.      
30.endmodule  
3~7 行是相關的出入端聲明,。
9 行是片上內(nèi)存 RAM 的聲明,,第 10 行則是寄存器 D1 的聲明。第 15 行則是 D1 的復位操作,。
17 行表示 iEn 不拉高該模塊就不工作,。第 18~26 行是該模塊的核心操作,第 19 行表 RAM 將 iData 儲存至 iAddr 指定的位置,;第 20 行表示,, RAM 將 iAddr 指定的內(nèi)容賦予 D1[3:0]。如此一來,,第 19 行與第 20 行的結(jié)合就成為推擠功能,。至于第 21~25 行則是 6 個深度的位移功能(即 4 位寬為一個深度), iEn 每拉高一個時鐘,, D1 的內(nèi)容就向左移動一個深度,。
savemod_demo.v組合模塊的連線部署根據(jù)3?12,具體內(nèi)容我們還是來看代碼吧,。
代碼3?8 savemod_demo.v組合代碼
1.module savemod_demo  
2.(  
3.    input CLOCK,RESET,  
4.     output [7:0]DIG,  
5.     output [5:0]SEL  
6.);     
7.     reg [3:0]i;  
8.     reg [3:0]D1,D2;  // D1 for Address, D2 for Data  
9.     reg isEn;  
10.       
11.    always @ ( posedge CLOCK or negedge RESET ) // Core  
12.         if( !RESET )  
13.              begin  
14.                    i <= 4'd0;  
15.                     { D1,D2 } <= 8'd0;  
16.                     isEn <= 1'b0;  
17.                end  
18.          else  
19.              case( i )  
20.                      
21.                     0:  
22.                     begin isEn <= 1'b1; D1 <= 4'd0; D2 <= 4'hA; i <= i + 1'b1; end  
23.                  
24.                     1:  
25.                     begin isEn <= 1'b1; D1 <= 4'd0; D2 <= 4'hB; i <= i + 1'b1; end  
26.                       
27.                     2:  
28.                     begin isEn <= 1'b1; D1 <= 4'd0; D2 <= 4'hC; i <= i + 1'b1; end  
29.                       
30.                     3:  
31.                     begin isEn <= 1'b1; D1 <= 4'd0; D2 <= 4'hD; i <= i + 1'b1; end  
32.                       
33.                     4:  
34.                     begin isEn <= 1'b1; D1 <= 4'd0; D2 <= 4'hE; i <= i + 1'b1; end  
35.                       
36.                     5:  
37.                     begin isEn <= 1'b1; D1 <= 4'd0; D2 <= 4'hF; i <= i + 1'b1; end  
38.                       
39.                     6:  
40.                     begin isEn <= 1'b1; D1 <= 4'd0; D2 <= 4'h0; i <= i + 1'b1; end  
41.                       
42.                     7:  
43.                     begin isEn <= 1'b0; i <= i; end  
44.                  
45.                endcase  
46.                  
47.     wire [23:0]DataU1;  
48.                  
49.    pushshift_savemod U1  
50.     (  
51.         .CLOCK( CLOCK ),  
52.          .RESET( RESET ),  
53.          .iEn( isEn ),  // < Core  
54.          .iAddr( D1 ),  // < Core  
55.          .iData( D2 ),  // < Core  
56.          .oData( DataU1 ) // > U2  
57.     );  
58.       
59.     smg_basemod U2  
60.     (  
61.         .CLOCK( CLOCK ),  
62.          .RESET( RESET ),  
63.          .DIG( DIG ),     // top  
64.          .SEL( SEL ),     // top  
65.          .iData( DataU1 )  // < U1  
66.     );  
67.  
68.endmodule  
第3~5內(nèi)容是相關的出入端聲明,。
7~18內(nèi)容是相關的寄存器聲明以及復位操作。其中 D1 用來暫存地址數(shù)據(jù),, D2 用來暫存讀寫數(shù)據(jù),。第 12~17 行是這些寄存器的復位操作
19~45行內(nèi)容為核心操作,操作過程如下:
步驟 0 為地址 0 寫入數(shù)據(jù) 4’hA;,將原本的數(shù)據(jù)擠出來,,并且發(fā)生位移,。
步驟 1 為地址 0 寫入數(shù)據(jù) 4’hB;,將 4’hA 擠出來,,并且發(fā)生位移,。
步驟 2 為地址 0 寫入數(shù)據(jù) 4’hC;,將 4’hB 擠出來,,并且發(fā)生位移,。
步驟 3 為地址 0 寫入數(shù)據(jù) 4’hD;,將 4’hC 擠出來,,并且發(fā)生位移,。
步驟 4 為地址 0 寫入數(shù)據(jù) 4’hE;,將 4’hD 擠出來,,并且發(fā)生位移,。
步驟 5 為地址 0 寫入數(shù)據(jù) 4’hF,將 4’hE 擠出來,,并且發(fā)生位移,。
步驟 6 為地址 0 寫入數(shù)據(jù) 4’d0,將 4’hF 擠出來,,并且發(fā)生位移,。
步驟 7 結(jié)束操作。
3?14 savemod_demo 部分時序圖
3?14是 savemod_demo 部分重要的理想時序圖,,其中 isEn,, D1 與 D2 是核心操作所發(fā)送的數(shù)據(jù),至于 RAM[0]與 oData 是推擠位移儲存模塊的內(nèi)部狀況與輸出結(jié)果,。時序過程如下:
T0,,核心操作拉高 isEn,發(fā)送 4’d0 地址數(shù)據(jù)與 4’hA 讀寫數(shù)據(jù),。
T1,,核心操作拉高 isEn,發(fā)送 4’d0 地址數(shù)據(jù)與 4’hB 讀寫數(shù)據(jù),。儲存模塊將 4’hA 載入地址 0,。
T2,核心操作拉高 isEn,,發(fā)送 4’d0 地址數(shù)據(jù)與 4’hC 讀寫數(shù)據(jù),。儲存模塊將 4’hB 載入地址 0,并且將數(shù)據(jù) 4’hA 擠出,, oData 的結(jié)果為 24’h00000A,。
T3,,核心操作拉高 isEn,發(fā)送 4’d0 地址數(shù)據(jù)與 4’hD 讀寫數(shù)據(jù),。儲存模塊將 4’hC 載入地址 0,,并且將數(shù)據(jù) 4’hB 擠出,同時發(fā)生位移,, oData 的結(jié)果為 24’h0000AB,。
T4,核心操作拉高 isEn,,發(fā)送 4’d0 地址數(shù)據(jù)與 4’hE 讀寫數(shù)據(jù),。儲存模塊將 4’hD 載入地址 0,并且將數(shù)據(jù) 4’hC 擠出,,同時發(fā)生位移,, oData 的結(jié)果為 24’h000ABC。
T5,,核心操作拉高 isEn,,發(fā)送 4’d0 地址數(shù)據(jù)與 4’hF 讀寫數(shù)據(jù)。儲存模塊將 4’hE 載入地址 0,,并且將數(shù)據(jù) 4’hD 擠出,,同時發(fā)生位移, oData 的結(jié)果為 24’h00ABCD,。
T6,,核心操作拉高 isEn,,發(fā)送 4’d0 地址數(shù)據(jù)與 4’d0 讀寫數(shù)據(jù),。儲存模塊將 4’hF 載入地 0,并且將數(shù)據(jù) 4’hE 擠出,,同時發(fā)生位移,, oData 的結(jié)果為 24’h0ABCDE。
T7,,儲存模塊將 4’d0 載入地址 0,,并且將數(shù)據(jù) 4’hF 擠出,同時發(fā)生位移,, oData 的結(jié)果為 24’hABCDEF,。
47~58 行是該儲存模塊的實例化。
59~66 行是數(shù)碼管基礎模塊的實例化,。編譯完畢便下載程序,,如果數(shù)碼管從左至右顯示“ABCDEF”,那么表示實驗成功,。最后還是要強調(diào)一下,,推擠位移目前是沒有意義的儲存模塊,,可是實驗十四的目的也非常清楚,就是解釋儲存模塊,,演示畸形的儲存模塊,。



    轉(zhuǎn)藏 分享 獻花(0

    0條評論

    發(fā)表

    請遵守用戶 評論公約

    類似文章 更多