2015-11-28 321 views
0

我想創建一個用於存儲ASCII字符的ROM(就像查找表一樣),當我從ROM中提取字符時,我可以將它顯示在視頻屏幕上。在不使用塊ROM的情況下在verilog中創建ROM

字符應該採取明智8個像素列和16個像素行明智(16 * 8)和每個像素得到一個10位的值 - 10'B 1111111111爲最大亮度和 10'B 0000000000最小。

因爲我不能在Verilog中創建二維數組,所以我應該如何創建一維數組並實現它?

回答

0

二維陣列不能在端口輸入/輸出 in Verilog。但是他們可以在模塊內部的內被聲明和使用。

這裏,存儲器80是位寬,並用16的深度因此,地址寬度必須log2(16) = 44位寬

您可以執行如下操作(寬視圖僞代碼)。在這裏,mem[0]是至少地址塊,每塊有第0位爲LSB與第79位爲MSB:

module memory(address,read_en,clk,reset,out); 

// clk,reset declarations 

// address to be accessed in memory 
input reg [3:0] address; 
// read/write signal 
input read_en; 
//output signal, for data read from memory 
output [79:0] out; 

// internal memory, accessed through address only 
reg [79:0] mem [16]; 

// inside always block 
// clock synchronous block 
always @(posedge clk, negedge reset) 
begin 
// reset logic, followed by: 
if(read_en) 
begin 
out <= mem[address]; 
end 
end 

endmodule 

沒有使用內部存儲器,這將是一個有點困難通過地址來獲得。存儲器是此時被聲明爲堆積陣列,所以它的1280(16×80)位wide.Following是用於填充陣列的方法:

// rest all declarations are same. 
reg [1279:0] mem; 
out<=mem[(((address+1)*80)-1) -: 80]; 

-:運算符用於位分片。如下所示,請參閱Verilog slicing link瞭解更多信息。

x -: Y, the start position is x and count down from x by Y. Y is necessarily a constant. 

沒有差別(或者,有點差)使用打包和壓縮數組之間。所以,更喜歡使用混合模塊陣列

要從文件加載數據到ROM中,請參閱this鏈接。儘管$readmemh將使其不可合成

有關詳細信息,請參閱this鏈接訪問內存。此網站顯示可合成模塊

對於二維陣列,請參閱this問題。

+0

但按你的方法#1,我怎麼輸出整個MEM [0]或MEM [2]等包含80位當我所知道的是,視頻屏幕上的(X,Y)座標(該位置包含10個像素)。我的意思是我如何將X從包含10位擴展到現在在視頻屏幕上的80位。 – Sara

+0

@Sara如果我理解正確,那麼在這種情況下,您需要爲模塊提供'address',即X(行數)'0'或'2'。輸出將是一個80位的塊。從該塊開始,根據Y(列號)屏蔽10位以獲得輸出中的10位。 – sharvil111

+0

好的..讓我試試這個.. – Sara

0

可以使用一個reg,像這樣創造這樣的記憶:

module charmem (
    input wire clk, 
    input wire [7:0] charaddr, 
    input wire [3:0] scanaddr, 
    input wire [2:0] pixeladdr, 
    output reg [9:0] pixel 
); 

    reg [9:0] chars[0:32767]; // 256 chars, 16 scans, 8 pixels 
    initial begin 
    $readmemh ("chardef.hex", chars, 0); // this IS synthesizable on Xilinx 
    end 

    always @(posedge clk) begin 
    scan <= chars[{charaddr,scanaddr,pixeladdr}]; 
    end 
endmodule 

chardef.hex將每行10位十六進制數的文本文件。前8個十六進制數字將是第一個字符第一次掃描的像素。接下來,對於第一個字符的第二次掃描,以下8個像素,直到第一個字符的第16次掃描的8個像素。然後,第二個字符的第一個掃描的8個像素,依此類推。

請注意,即使您不能在Verilog中使用n維矩陣(n> = 3),您可以利用尺寸爲2的冪(256x16x8),因此可以使用1D矢量來實現它,通過將索引連接起來形成一個唯一的內存地址(就像用戶一樣,如果將它看作是位元素矩陣而不是10位元素矢量,它實際上是一個2D矢量)。

請注意,儘管您已經要求使用非Block-RAM解決方案,但您仍然希望將其用作分佈式內存解決方案,因此這樣的分區內存將肯定會佔用您的許多寶貴邏輯資源,並且會花費很長時間綜合,我沒有看到爲什麼這個ROM不能在block-RAM中實現的原因。

假設您的視頻控制器將有兩個計數器:例如x,y。假設你的活動區域爲640x480,並且要繪製的字符的ASCII代碼存儲在character(一個8位REG),你可以這樣做,因爲這:

wire [9:0] pixel; 

charmem chartable (
    .clk(clk), 
    .charaddr(character), 
    .scanaddr(y[3:0]), 
    .pixeladdr(x[2:0]), 
    .pixel(pixel) 
); 

爲了charmem輸出黑色像素時視頻控制器沒有更新活動區域,您可以添加一個videoenable信號給它,所以如果它是'1',像素是從ROM中檢索的像素,否則是黑色的。

always @(posedge clk) begin 
    if (videoenable == 1'b1) 
     scan <= chars[{charaddr,scanaddr,pixeladdr}]; 
    else 
     scan <= 10'h000; 
    end 

videoenable將被更新爲這樣:

reg videoenable; 
always @* begin 
    if (x >= 10'd0 && x <= 10'd639 && 
     y >= 10'd0 && y <= 10'd479) 
     videoenable = 1'b1; 
    else 
     videoenable = 1'b0; 
end 
+0

非常感謝... – Sara

+0

好吧,如果你認爲這個答案是你期望的答案,你可以將它標記爲你選擇的答案:) –

相關問題