在verilog中创建ROM而不使用块ROM

在verilog中创建ROM而不使用块ROM,verilog,Verilog,我想创建一个ROM(就像一个查找表)来存储ASCII字符,当我从ROM中提取字符时,我可以在视频屏幕上显示它 字符按列顺序取8像素,按行顺序取16像素(16*8),每个像素取10位值- 10'b 1111,最大亮度和 最低10'b 0000000000 既然我不能在verilog中创建2D数组,我该如何创建1D数组并实现它 二维数组不能位于Verilog的输入/输出端口。但是它们可以在模块内部声明和使用 这里,内存为80位宽,深度为16。因此,地址的宽度必须是log2(16)=4,4位宽 您可以

我想创建一个ROM(就像一个查找表)来存储ASCII字符,当我从ROM中提取字符时,我可以在视频屏幕上显示它

字符按列顺序取8像素,按行顺序取16像素(16*8),每个像素取10位值- 10'b 1111,最大亮度和 最低10'b 0000000000


既然我不能在verilog中创建2D数组,我该如何创建1D数组并实现它

二维数组不能位于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
使用压缩数组和非压缩数组之间没有差别(或者可能有一点差别)。因此,更喜欢使用混合块数组

有关将数据从文件加载到ROM的信息,请参阅链接。虽然
$readmemh
应使其不可合成

有关使用访问内存的更多信息,请参阅链接。此站点显示可合成模块


有关二维数组,请参阅问题。

您可以使用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
要使charmem在视频控制器不更新活动区域时输出黑色像素,您可以向其添加
videoenable
信号,因此如果它为“1”,则该像素为从ROM检索到的像素,否则为黑色

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

但是按照你的方法#1,我怎么能输出包含80位的整个mem[0]或mem[2]等,而我所知道的只是视频屏幕上的(X,Y)坐标(该位置包含10个像素)。我的意思是如何在视频屏幕上将X从包含10位扩展到包含80位。@Sara如果我理解正确,那么在这种情况下,您需要向模块提供
地址
,即X(行数)
0
2
。输出将是一个80位的块。从该块中,根据Y(列号)屏蔽10位,以获得输出中的10位。是的,当然。如果有任何困难,请告诉我。:)如果我想使用块RAM创建一个ROM,我该怎么做?方法#1与块ROM大致相同。有关更多信息,请参阅。如果您认为此答案是您期望的答案,可以将其标记为您选择的答案:)
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
wire [9:0] pixel;

charmem chartable (
  .clk(clk),
  .charaddr(character),
  .scanaddr(y[3:0]),
  .pixeladdr(x[2:0]),
  .pixel(pixel)
);
  always @(posedge clk) begin
    if (videoenable == 1'b1)
      scan <= chars[{charaddr,scanaddr,pixeladdr}];
    else
      scan <= 10'h000;
  end
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