今天再接再励,字符在电脑上也显示出来了,这个字符和昨天的图片有点不一样,昨天显示的是一幅图片,可以行取模,然后将行地址赋给rom_addr,若要显示多幅图片,这个方法,还有待改进!今天要在电脑液晶屏上显示多个字符,可以列取模,然后,将列地址赋给rom_addr,然后,根据rom_data逐行判断点阵是否该点亮。还是,那句话其实大家只要把VGA的时序,、怎样取字模存入FPGA的ROM中,以及采取怎样的扫描方式在电脑上显示,这几个问题弄明白了,我想VGA接口也不是那么难!

  

//程序实现的功能:在电脑液晶屏上显示“大家来一起学习  FPGA”几个字符;64*640点阵

module vga_zifu
        (
          clk,
          rst_n,
          hsync,
          vsync,
          vga_rgb
             
        );

input       clk;           //系统时钟50MHZ;
input       rst_n;         //复位信号,低电平有效;

output      hsync;       //列同步信号;
output      vsync;      //行同步信号;
output[2:0] vga_rgb;      //色彩信号;


reg[9:0] x_cnt;        //行坐标;
always @ (posedge clk or negedge rst_n)
  begin
         if(!rst_n)
            x_cnt<=10'd0;
         else if(x_cnt==10'd665)
            x_cnt<=10'd0;
         else if(y_cnt==11'd1039)
            x_cnt<=x_cnt+1'b1;
  end 

reg [10:0] y_cnt;       //列坐标;
always @(posedge clk or negedge rst_n)
  begin
         if(!rst_n)
            y_cnt<=11'd0;
         else if(y_cnt==1039)
            y_cnt<=11'd0;
         else  
            y_cnt<=y_cnt+1'b1;
  end

wire[9:0]   x_pos;         //有效显示区域坐标;
wire[10:0]  y_pos;

assign  x_pos=x_cnt-10'd31;        // 显示的初始位置,相当于坐标(0,0);
assign  y_pos=y_cnt-11'd187;      

wire valid;                //有效显示区;

assign   valid=((x_cnt>=10'd31)&&(x_cnt<10'd631)&&(y_cnt>=11'd187)&&(y_cnt<11'd987));  
  
            
                  
    

 reg vsync_r;             //行同步信号的产生;
always @ (posedge clk or negedge rst_n)
  begin
         if(!rst_n)
           vsync_r<=1'b1;
         else if(x_cnt==0)
           vsync_r<=1'b0;
         else if(x_cnt==6)
          vsync_r<=1'b1;
         else 
          vsync_r<=vsync_r; 
  end
assign  vsync=vsync_r;
 
reg hsync_r;             //列同步信号的产生;
always @ (posedge clk or negedge rst_n)
  begin
        if(!rst_n)
          hsync_r<=1'b1;
        else if(y_cnt==0)
          hsync_r<=1'b0;
        else if(y_cnt==120)
          hsync_r<=1'b1;
        else 
          hsync_r<=hsync_r;    
  end

assign  hsync=hsync_r;

reg [9:0]  rom_addr;          //64*640点阵,逐列取字模;      
reg [63:0] rom_data;

vga_hanzi    vga_hanzi_inst (
    .address ( rom_addr ),
    .clock ( clk ),
    .q ( rom_data )
    );


always @(posedge clk or negedge rst_n)
    if(!rst_n) rom_addr <= 8'd0;
    else if(y_pos == 10'd55) rom_addr <= 8'd0;
    else rom_addr <= rom_addr+1'b1;

    
wire dis_play = (x_pos >=10'd250) && (x_pos < 10'd315)               //字符显示区;
                    && (y_pos >=10'd58) && (y_pos < 10'd699);

reg [2:0] vga_rgb_r;
always @ (posedge clk )
 begin
  if(!valid) 
     vga_rgb_r<=3'b000;
   else if(dis_play)
        begin     
            if(rom_data[10'd314-x_pos])
               vga_rgb_r<=3'b100;                     
            else 
               vga_rgb_r<=3'b001;
            
        end
    else
      vga_rgb_r<=3'b001; 
  end        
        

assign  vga_rgb=vga_rgb_r;


endmodule