我想創建一個用於存儲ASCII字符的ROM(就像查找表一樣),當我從ROM中提取字符時,我可以將它顯示在視頻屏幕上。在不使用塊ROM的情況下在verilog中創建ROM
字符應該採取明智8個像素列和16個像素行明智(16 * 8)和每個像素得到一個10位的值 - 10'B 1111111111爲最大亮度和 10'B 0000000000最小。
因爲我不能在Verilog中創建二維數組,所以我應該如何創建一維數組並實現它?
我想創建一個用於存儲ASCII字符的ROM(就像查找表一樣),當我從ROM中提取字符時,我可以將它顯示在視頻屏幕上。在不使用塊ROM的情況下在verilog中創建ROM
字符應該採取明智8個像素列和16個像素行明智(16 * 8)和每個像素得到一個10位的值 - 10'B 1111111111爲最大亮度和 10'B 0000000000最小。
因爲我不能在Verilog中創建二維數組,所以我應該如何創建一維數組並實現它?
二維陣列不能在端口輸入/輸出 in Verilog。但是他們可以在模塊內部的內被聲明和使用。
這裏,存儲器80是位寬,並用16的深度因此,地址寬度必須log2(16) = 4
,4位寬。
您可以執行如下操作(寬視圖僞代碼)。在這裏,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問題。
可以使用一個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
非常感謝... – Sara
好吧,如果你認爲這個答案是你期望的答案,你可以將它標記爲你選擇的答案:) –
但按你的方法#1,我怎麼輸出整個MEM [0]或MEM [2]等包含80位當我所知道的是,視頻屏幕上的(X,Y)座標(該位置包含10個像素)。我的意思是我如何將X從包含10位擴展到現在在視頻屏幕上的80位。 – Sara
@Sara如果我理解正確,那麼在這種情況下,您需要爲模塊提供'address',即X(行數)'0'或'2'。輸出將是一個80位的塊。從該塊開始,根據Y(列號)屏蔽10位以獲得輸出中的10位。 – sharvil111
好的..讓我試試這個.. – Sara