如何利用verilog和VGA在fpga板上显示不同种类的图像

如何利用verilog和VGA在fpga板上显示不同种类的图像,verilog,fpga,Verilog,Fpga,我正在做我学校的项目,我想做的一个功能是当按下不同的按钮时显示不同类型的图片。正如我所知,我必须在内存中加载不同的图片。我现在尝试加载两张不同的图片并显示其中一张。然而,当我尝试只使用一张图片时,它工作正常,但当我尝试使用两张图片时,它不会显示任何内容。真的希望有人能帮助我!!!以下是我的代码 module top( input clk, input rst, output [3:0] vgaRed, output [3:0] vgaGreen, output [3:0] vgaBlue, ou

我正在做我学校的项目,我想做的一个功能是当按下不同的按钮时显示不同类型的图片。正如我所知,我必须在内存中加载不同的图片。我现在尝试加载两张不同的图片并显示其中一张。然而,当我尝试只使用一张图片时,它工作正常,但当我尝试使用两张图片时,它不会显示任何内容。真的希望有人能帮助我!!!以下是我的代码

module top(
input clk,
input rst,
output [3:0] vgaRed,
output [3:0] vgaGreen,
output [3:0] vgaBlue,
output hsync,
output vsync
 );

wire [11:0] data;
wire clk_25MHz;
wire clk_22;
wire [16:0] pixel_addr;
wire [11:0] pixel;
wire valid;
wire [9:0] h_cnt; //640
wire [9:0] v_cnt;  //480
wire [11:0] data_1;
wire [16:0] pixel_addr_1;
wire [11:0] pixel_1;
wire valid_1;
wire [9:0] h_cnt_1; //640
wire [9:0] v_cnt_1;  //480

assign {vgaRed, vgaGreen, vgaBlue} = (valid==1'b1) ? pixel:12'h0;

 clock_divisor clk_wiz_0_inst(
  .clk(clk),
  .clk1(clk_25MHz),
  .clk22(clk_22)
);

mem_addr_gen mem_addr_gen_inst(
.clk(clk_22),
.rst(rst),
.h_cnt(h_cnt),
.v_cnt(v_cnt),
.pixel_addr(pixel_addr)
);


blk_mem_gen_0 blk_mem_gen_0_inst(
  .clka(clk_25MHz),
  .wea(0),
  .addra(pixel_addr),
  .dina(data[11:0]),
  .douta(pixel)
);


mem_addr_gen mem_addr_gen_inst_1(
    .clk(clk_22),
    .rst(rst),
    .h_cnt(h_cnt_1),
    .v_cnt(v_cnt_1),
    .pixel_addr(pixel_addr_1)
    );


    blk_mem_gen_1 blk_mem_gen_1_inst(
      .clka(clk_25MHz),
      .wea(0),
      .addra(pixel_addr_1),
      .dina(data_1[11:0]),
      .douta(pixel_1)
    ); 


vga_controller   vga_inst(
  .pclk(clk_25MHz),
  .reset(rst),
  .hsync(hsync),
  .vsync(vsync),
  .valid(valid),
  .h_cnt(h_cnt),
  .v_cnt(v_cnt)
);      
endmodule

由于它可以以正确的方式工作,仅使用一张图片,我认为模块vga_控制器、时钟除数、内存添加和blk_内存_gen_0在模块的设计中不会有问题,因此,我只发布我的顶级模块的详细信息。谢谢

如果我正确理解了您的代码,您的目的是为要显示的每个图像实例化一个
mem\u addr\u gen
blk\u mem\u gen
。假设您的系统适用于单映像情况,那么以下是一些建议:

  • 只要您的所有图像大小相同(显然是640x480),您可能只需要一个
    mem\u addr\u gen
    模块的实例-您应该能够在
    blk\u mem\u gen
    集合上共享
    h\u cnt
    v\u cnt
    pixel\u addr
  • 您需要某种方法从图像集中进行选择
  • 考虑以下几点:

    reg [2:0] activeImage; //between 0 and 7
    wire [11:0] pixel_out [7:0]; // pixel outputs from the blk_mem_gen
    wire [11:0] pixel;
    
    assign {vgaRed, vgaGreen, vgaBlue} = (valid==1'b1) ? pixel:12'h0;
    assign pixel = pixel_out[activeImage];
    
    blk_mem_gen_0 blk_mem_gen_0_inst(
      .clka(clk_25MHz),
      .wea(0),
      .addra(pixel_addr),
      .dina(data[11:0]),
      .douta(pixel_out[0])
    );
    ...
    
    这将为VGA分配“活动”图像(本例中为0-7)

  • 最后,您需要一种方法来更改正在显示的图像 这更依赖于您的实现,但作为一个示例:

    input button;
    input clk;
    input rst;
    reg buttonPrev; //previous button value
    reg [2:0] activeImage; //between 0 and 7
    reg [2:0] nextImage;
    
    always@(posedge clk) begin
        buttonPrev <= button;
        if (rst) begin //reset
             activeImage <= 0;
             next_image <= 0;
        end
        else begin
            if (button && !buttonPrev) //button was just pressed
                nextImage <= nextImage + 1;
            if (h_cnt == 0 && v_cnt == 0) // starting a new frame
                activeImage <= nextImage;
        end
    end
    
    输入按钮;
    输入时钟;
    输入rst;
    reg按钮REV//上一个按钮值
    reg[2:0]activeImage//在0到7之间
    reg[2:0]下一代;
    始终@(posedge clk)开始
    
    按钮查看注释掉
    …inst_1
    电路时会发生什么情况?注意:对于3,使用
    h_cnt==639&&v_cnt==479
    可能更正确,具体取决于系统的定时。