SRAM Graphic Interface for AVR

 

 

這是一個解析度為512 x 480 x 256色的繪圖界面,使用Memory模組的Synchronous SRAM作為frame buffer; VGA模組作為RGB Monitor的輸出, 由CPU模組直接存取SRAM做繪圖的動作

 

Source

 

1. 建立FPGA的Project : sramgfx.v, vrbuf.v, 及test module tsramgfx.v

 

2. 合成時須使用Leonardo Spectrum合成程式(vrbuf.v)

 

3. AVR C程式須使用GNU WinAVR C++ Compiler

 

4. Simulation 使用Micron的Flow-Through Synchronous SRAM Model

 

 

-- Top Module

 

sramgfx.v

 

'timescale 1ns / 100ps

 

module sramgfx

(

      mclk,hrst,

      mppg,mpad,mpah,mpale,mprd,mpwr,

      saddr,sdata,soe,swe,sbwe,scs,sadsc,sdrcs,

      vor,vog,vob,vvsyn,vhsyn,vblk,vsync

);

 

input mclk; // System clock

input hrst; // System reset

input[2:0] mppg; // host memory page address

inout[7:0] mpad; // host memory address[7:0]/data[7:0]

input[7:0] mpah; // host memory address[15:8]

input mpale;  // host address latch enable

input mprd,mpwr; // host read/write

 

output[15:0] saddr; // sram address

inout[31:0] sdata; // sram data

output soe;  // sram output enable

output swe;  // sram write enable

output scs;  // sram chip select

output sadsc;  // sram address select control

output sdrcs; // sdram chip select, that should be tied to 1 to disable SDRAM

output[3:0] sbwe; // sram byte enable

output[7:0] vor,vog,vob; // VGA Red, Green, Blue signal outputs

output vvsyn; // VGA vertical sync.

output vhsyn; // VGA horizontal sync.

output vblk;  // VGA blank signal, tie to 1 in this example

output vsync; // VGA sync. signal, tie to 1 in this example

 

reg[7:0] mpals;

wire[17:0] mpaddr;

reg mpwrs,mprds,mpwrss,mprdss,mpwrsps,mprdsps,mprdspss;

wire mpwrsp,mprdsp;

reg[9:0] hcnt;

wire vrdp;

reg vrbwe,vrbwes;

reg[4:0] hovs;

reg[1:0] vrbcnt,nvrbcnt;

reg[7:0] vrhcnt,nvrhcnt;

reg hov,hpov,hend,hsyns,hsyne;

reg hsyn,hen;

reg[9:0] vcnt;

reg vov,vend,vsyns,vsyne;

reg vsyn,ven;

reg[15:0] saddr;

wire voutrd;

reg soe,swe,sadsc;

reg[3:0] sbwe;

reg[7:0] vhens;

wire[7:0] vout;

reg[7:0] vouts;

reg[31:0] sdtis;

reg[7:0] mpdto;

reg nrstn,nrst;

 

always @(negedge mclk) nrstn<=hrst;  // synchronization of hrst

always @(posedge mclk) nrst<=nrstn;

 

always @(mpale or mpad) // lower address[7:0] latch

begin

if(mpale) mpals<=mpad;

end

 

assign mpaddr={mppg[2:0],mpah[6:0],mpals}; // host address

 

always @(negedge mclk) // synchronization of mpwr & mprd

begin

      mpwrs<=~mpwr&mpah[7];

      mprds<=~mprd&mpah[7];

end

 

always @(posedge mclk) // delayed signals

begin

      mprdss<=mprds;

      mpwrsps<=mpwrsp;

      mprdsps<=mprdsp;

end

 

always @(negedge mclk) // delayed signals

begin

      mprdspss<=mprdsps;

end

 

always @(posedge mclk or negedge nrst) // state signal for one shot

begin

if(~nrst)

      mpwrss<=0;

else begin

      case(mpwrss)

      0 : if(mpwrs&~vrbwe) mpwrss<=1; // pending when VGA read

      1 : if(~mpwrs) mpwrss<=0;

      endcase end

end

 

assign mpwrsp=mpwrs&~mpwrss&~vrbwe; // host write strobe (one shot)

assign mprdsp=mprds&~mprdss; // host read strobe (one shot)

 

// two entry (4 bytes x 2) VGA read buffer

vrbuf vrbuf(.mclk(mclk),.nrst(nrst),.clr(hsyns),

      .we(vrbwes),.rd(vhens[7]),

      .wdi(sdata),.rdo(vout));

 

// VGA read request

assign vrdp=~vrhcnt[7]&~nvrbcnt[1]&ven&hen&~mprdsp&~mpwrsp&~mpwrsps;

 

// VGA read buffer read signal(active for every 4 bytes/cycles)

assign voutrd=vhens[7]&(hcnt[1:0]==3);

 

// VGA read buffer write signal, 1 cycle after read request

always @(posedge mclk or negedge nrst)

begin

if(~nrst) vrbwe<=0;

else vrbwe<=vrdp;

end

 

// VGA read buffer write signal, 2 cycle after read request

always @(negedge mclk)

begin

vrbwes<=vrbwe;

end

 

// VGA read buffer counter(indicates numbers of valid entry in buffer)

always @(posedge mclk or negedge nrst)

begin

if(~nrst) vrbcnt<=0;

else vrbcnt<=nvrbcnt;

end

 

always @(vrbcnt or vrbwe or voutrd or hsyns)

begin

if(hsyns) nvrbcnt=0;

else if(vrbwe&~voutrd) nvrbcnt=vrbcnt+1;

else if(~vrbwe&voutrd) nvrbcnt=vrbcnt-1;

else nvrbcnt=vrbcnt;

end

 

// VGA read buffer horizontal(lower) address

always @(posedge mclk or negedge nrst)

begin

if(~nrst)

      vrhcnt<=0;

else

      vrhcnt<=nvrhcnt;

end

 

always @(vrhcnt or hsyns or vrbwe)

begin

if(hsyns)

      nvrhcnt=0;

else if(vrbwe)

      nvrhcnt=vrhcnt+1;

else nvrhcnt=vrhcnt;

end

 

always @(posedge mclk or negedge nrst) // VGA horizontal counter

begin

if(~nrst)

      hcnt<=0;

else if(hov)

      hcnt<=0;

else

      hcnt<=hcnt+1;

end

 

always @(posedge mclk or negedge nrst)

begin

if(~nrst)

      begin

      hov<=1'b0; hpov<=1'b0; hend<=1'b0; hsyns<=1'b0; hsyne<=1'b0;

      hovs<=0;

      end

else

      begin

      hov<=(hcnt==795);

      hpov<=(hcnt==788);

      hend<=(hcnt==509);

      hsyns<=(hcnt==652);

      hsyne<=(hcnt==747);

      hovs<={hovs[3:0],hpov};

      end

end

 

always @(posedge mclk or negedge nrst)

begin

if(~nrst)

      hsyn<=1'b0;

else

      begin

      case(hsyn)

      1'b0 : if(hsyns) hsyn<=1'b1;

      1'b1 : if(hsyne) hsyn<=1'b0;

      endcase

      end

end

 

always @(posedge mclk or negedge nrst)

begin

if(~nrst)

      hen<=1'b0;

else

      begin

      case(hen)

      1'b0 : if(hpov) hen<=1'b1;

      1'b1 : if(hend) hen<=1'b0;

      endcase

      end

end

 

always @(posedge mclk or negedge nrst) // VGA vertical counter

begin

if(~nrst)

      vcnt<=0;

else if(hpov) begin

      if(vov) vcnt<=0;

      else vcnt<=vcnt+1; end

end

 

always @(posedge mclk or negedge nrst)

begin

if(~nrst)

      begin

      vov<=1'b0; vend<=1'b0; vsyns<=1'b0; vsyne<=1'b0;

      end

else

      begin

      vov<=(vcnt==522);

      vend<=(vcnt==479);

      vsyns<=(vcnt==490);

      vsyne<=(vcnt==492);

      end

end

 

always @(posedge mclk or negedge nrst) // Vertical sync. signal of VGA

begin

if(~nrst)

      vsyn<=1'b0;

else

      begin

      case(vsyn)

      1'b0 : if(vsyns) vsyn<=1'b1;

      1'b1 : if(vsyne) vsyn<=1'b0;

      endcase

      end

end

 

always @(posedge mclk or negedge nrst) // Vertical video enable signal

begin

if(~nrst)

      ven<=1'b0;

else

      begin

      case(ven)

      1'b0 : if(vov&hpov) ven<=1'b1;

      1'b1 : if(vend) ven<=1'b0;

      endcase

      end

end

 

always @(posedge mclk or negedge nrst) // vhen delayed shift registers

begin

if(~nrst) vhens<=0;

else vhens<={vhens[7:0],ven&hen};

end

 

always @(posedge mclk)

begin

if(vrdp) saddr<= #4 {vcnt[8:0],nvrhcnt[6:0]};

else saddr<= #4 mpaddr[17:2];

end

 

always @(negedge mclk)

begin

soe<= #4 ~(vrbwe|mprdsps);

end

 

always @(posedge mclk)

begin

swe<= #4 ~mpwrsp;

sadsc<= #4 ~(vrdp|mpwrsp|mprdsp);

end

 

assign sdrcs=1'b1; // sdram disabled

assign scs=1'b0;

 

always @(mpaddr or sdtis)

begin

case(mpaddr[1:0])

2'b00 : mpdto=sdtis[7:0];

2'b01 : mpdto=sdtis[15:8];

2'b10 : mpdto=sdtis[23:16];

2'b11 : mpdto=sdtis[31:24];

default : mpdto=8'h00;

endcase

end

 

assign mpad=mprd?8'hzz:mpdto;

 

always @(negedge mclk)

begin

if(mprdspss) sdtis<=sdata;

end

 

assign  #4 sdata=swe?32'hzzzzzzzz:{mpad,mpad,mpad,mpad};

 

always @(mpaddr or swe)

begin

if(~swe) begin

      case(mpaddr[1:0])

      2'b00 :  #4 sbwe=4'b1110;

      2'b01 :  #4 sbwe=4'b1101;

      2'b10 :  #4 sbwe=4'b1011;

      2'b11 :  #4 sbwe=4'b0111;

      default :  #4 sbwe=4'b1111;

      endcase end

else #4 sbwe=4'b1111;

end

 

always @(posedge mclk)

begin

vouts<=vhens[7]?vout:8'h00;

end

 

assign vor={vouts[2:0],5'b00000};

assign vog={vouts[5:3],5'b00000};

assign vob={vouts[7:6],6'b000000};

assign vvsyn=vsyn;

assign vhsyn=hsyn;

assign vblk=1'b1;

assign vsync=1'b1;

 

endmodule

 

 

 

 

--  VGA Read Buffer

 

vrbuf.v

 

'timescale 1ns / 100ps

 

module vrbuf

(

mclk,nrst,clr,

we,rd,

wdi,rdo

);

 

input mclk,nrst,clr;

input we,rd;

input[31:0] wdi;

output[7:0] rdo;

 

reg[2:0] raddr;

reg waddr;

reg[31:0] vrb[0:1];

wire[31:0] rdop;

reg[7:0] rdo;

 

always @(posedge mclk or negedge nrst)

begin

if(~nrst) raddr<=0;

else if(clr) raddr<=0;

else if(rd) raddr<=raddr+1;

end

 

always @(negedge mclk or negedge nrst)

begin

if(~nrst) waddr<=0;

else if(clr) waddr<=0;

else if(we) waddr<=waddr+1;

end

 

assign rdop=vrb[raddr[2]];

 

always @(rdop or raddr)

begin

case(raddr[1:0])

0 : rdo=rdop[7:0];

1 : rdo=rdop[15:8];

2 : rdo=rdop[23:16];

3 : rdo=rdop[31:24];

default rdo=8'h00;

endcase

end

 

always @(negedge mclk)

begin

if(we)

      vrb[waddr]<=wdi;

end

 

endmodule

 

 

 

 

--  Test Bench

 

tsramgfx.v

 

'timescale 1ns / 100ps

 

module tsramgfx

( );

 

parameter tcyc=20;

reg mclk,hrst;

reg[2:0] mppg;

wire[7:0] mpad;

reg[7:0] mpah;

reg mpale,mprd,mpwr;

 

wire[15:0] saddr;

wire[31:0] sdata;

wire[3:0] sbwe;

reg[7:0] mpado;

 

wire[7:0] vor,vog,vob;

wire vvsyn,vhsyn,vblk,vsync;

wire soe,swe,sadsc,sdrcs;

 

task tmpwr;

input[15:0] addr;

input[7:0] data;

begin

mpale=1'b1;

#10;

mpah=addr[15:8]; mpado=addr[7:0];

#22.5;

mpale=1'b0;

#67.5;

mpado=data;

#27.5;

mpwr=1'b0;

#167.5;

mpwr=1'b1;

mpado=8'hzz; mpah=8'hxx;

#22.5;

end

endtask

 

task tmprd;

input[15:0] addr;

output[7:0] data;

begin

mpale=1'b1;

#10;

mpah=addr[15:8]; mpado=addr[7:0];

#22.5;

mpale=1'b0;

#15.0;

mpado=8'hzz;

#27.5;

mprd=1'b0;

#195;

data=mpad;

#35;

mprd=1'b1;

mpah=8'hxx;

#22.5;

end

endtask

 

assign mpad=mpado;

 

sramgfx sramgfx

(

      mclk,hrst,

      mppg,mpad,mpah,mpale,mprd,mpwr,

      saddr,sdata,soe,swe,sbwe,sadsc,sdrcs,

      vor,vog,vob,vvsyn,vhsyn,vblk,vsync

);

 

mt58l64l32f sram(.Dq(sdata), .Addr(saddr), .Mode(1'b0), .Adv_n(1'b1),

      .Clk(mclk), .Adsc_n(sadsc), .Adsp_n(1'b1),

      .Bwa_n(sbwe[0]), .Bwb_n(sbwe[1]), .Bwc_n(sbwe[2]), .Bwd_n(sbwe[3]),

      .Bwe_n(swe), .Gw_n(1'b1), .Ce_n(1'b0),

      .Ce2(1'b1), .Ce2_n(1'b0), .Oe_n(soe), .Zz(1'b0));

 

 

initial

begin

      mclk=0;

      forever begin #tcyc; mclk=~mclk; end

end

 

reg[8:0] dlyc;

integer seed,i,j;

initial

begin

      hrst=0; mppg=0; mpado=0; mpah=0; mpale=0; mprd=1; mpwr=1;

#(8*tcyc); hrst=1;

#(10000 * tcyc);

for(i=0;i<'h400;i=i+1)

      begin

      dlyc=$random(seed);

      #(dlyc);

      tmpwr('h8000+i,i);

      tmprd('h8000+i,j);

      if(i[7:0]!=j) $display(" Mem Error (%x,%x)\n",i,j);

      end

 

@(sramgfx.vhens);

for(i=0;i<'h400;i=i+1)

      begin

      dlyc=$random(seed);

      //#(dlyc);

      tmpwr('h8400+i,i);

      //tmprd('h8000+i,j);

      //if(i[7:0]!=j) $display(" Mem Error (%x,%x)\n",i,j);

      end

 

@(sramgfx.vhens);

for(i=0;i<'h400;i=i+1)

      begin

      dlyc=$random(seed);

      //#(dlyc);

      tmpwr('h9000+i,i);

      end

 

#(500000 * tcyc);

$stop;

end

 

endmodule

 

 

 

 

--  AVR C Program (Compiled with GNU AVR C Compiler WinAVR)

 

agfx.c

 

#include <inttypes.h>

#include <avr/delay.h>

#include <avr/io.h>

#include <avr/pgmspace.h>

 

unsigned char tfont[768] PROGMEM = {

  0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

  0x04, 0x04, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00,

  0x0A, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

  0x0A, 0x1F, 0x0A, 0x1F, 0x0A, 0x00, 0x00, 0x00,

  0x0E, 0x14, 0x0E, 0x05, 0x0E, 0x00, 0x00, 0x00,

  0x19, 0x1A, 0x04, 0x0B, 0x13, 0x00, 0x00, 0x00,

  0x0C, 0x0A, 0x0C, 0x12, 0x0D, 0x00, 0x00, 0x00,

  0x04, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

  0x04, 0x08, 0x08, 0x08, 0x04, 0x00, 0x00, 0x00,

  0x04, 0x02, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00,

  0x15, 0x0E, 0x04, 0x0E, 0x15, 0x00, 0x00, 0x00,

  0x04, 0x04, 0x1F, 0x04, 0x04, 0x00, 0x00, 0x00,

  0x00, 0x00, 0x00, 0x06, 0x02, 0x04, 0x00, 0x00,

  0x00, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00, 0x00,

  0x00, 0x00, 0x00, 0x06, 0x06, 0x00, 0x00, 0x00,

  0x01, 0x02, 0x04, 0x08, 0x10, 0x00, 0x00, 0x00,

  0x0E, 0x11, 0x15, 0x11, 0x0E, 0x00, 0x00, 0x00,

  0x04, 0x0C, 0x04, 0x04, 0x0E, 0x00, 0x00, 0x00,

  0x0E, 0x01, 0x0E, 0x10, 0x1F, 0x00, 0x00, 0x00,

  0x0E, 0x01, 0x0E, 0x01, 0x0E, 0x00, 0x00, 0x00,

  0x12, 0x12, 0x1F, 0x02, 0x02, 0x00, 0x00, 0x00,

  0x1E, 0x10, 0x1E, 0x01, 0x1E, 0x00, 0x00, 0x00,

  0x0E, 0x10, 0x1E, 0x11, 0x0E, 0x00, 0x00, 0x00,

  0x1F, 0x02, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00,

  0x0E, 0x11, 0x0E, 0x11, 0x0E, 0x00, 0x00, 0x00,

  0x0E, 0x11, 0x0F, 0x01, 0x0E, 0x00, 0x00, 0x00,

  0x00, 0x06, 0x06, 0x00, 0x06, 0x06, 0x00, 0x00,

  0x00, 0x06, 0x06, 0x00, 0x06, 0x0C, 0x00, 0x00,

  0x02, 0x04, 0x08, 0x04, 0x02, 0x00, 0x00, 0x00,

  0x00, 0x1F, 0x00, 0x1F, 0x00, 0x00, 0x00, 0x00,

  0x08, 0x04, 0x02, 0x04, 0x08, 0x00, 0x00, 0x00,

  0x0E, 0x01, 0x06, 0x00, 0x04, 0x00, 0x00, 0x00,

  0x0E, 0x17, 0x17, 0x10, 0x0E, 0x00, 0x00, 0x00,

  0x0E, 0x11, 0x1F, 0x11, 0x11, 0x00, 0x00, 0x00,

  0x1E, 0x11, 0x1E, 0x11, 0x1E, 0x00, 0x00, 0x00,

  0x0E, 0x10, 0x10, 0x10, 0x0E, 0x00, 0x00, 0x00,

  0x1E, 0x11, 0x11, 0x11, 0x1E, 0x00, 0x00, 0x00,

  0x1F, 0x10, 0x1C, 0x10, 0x1F, 0x00, 0x00, 0x00,

  0x1F, 0x10, 0x1E, 0x10, 0x10, 0x00, 0x00, 0x00,

  0x0E, 0x10, 0x13, 0x11, 0x0E, 0x00, 0x00, 0x00,

  0x11, 0x11, 0x1F, 0x11, 0x11, 0x00, 0x00, 0x00,

  0x0E, 0x04, 0x04, 0x04, 0x0E, 0x00, 0x00, 0x00,

  0x01, 0x01, 0x01, 0x11, 0x0E, 0x00, 0x00, 0x00,

  0x11, 0x12, 0x1C, 0x12, 0x11, 0x00, 0x00, 0x00,

  0x10, 0x10, 0x10, 0x10, 0x1F, 0x00, 0x00, 0x00,

  0x11, 0x1B, 0x15, 0x11, 0x11, 0x00, 0x00, 0x00,

  0x11, 0x19, 0x15, 0x13, 0x11, 0x00, 0x00, 0x00,

  0x0E, 0x11, 0x11, 0x11, 0x0E, 0x00, 0x00, 0x00,

  0x1E, 0x11, 0x1E, 0x10, 0x10, 0x00, 0x00, 0x00,

  0x0E, 0x11, 0x11, 0x13, 0x0F, 0x00, 0x00, 0x00,

  0x1E, 0x11, 0x1E, 0x12, 0x11, 0x00, 0x00, 0x00,

  0x0E, 0x10, 0x0E, 0x01, 0x0E, 0x00, 0x00, 0x00,

  0x1F, 0x04, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00,

  0x11, 0x11, 0x11, 0x11, 0x0E, 0x00, 0x00, 0x00,

  0x11, 0x11, 0x0A, 0x0A, 0x04, 0x00, 0x00, 0x00,

  0x11, 0x11, 0x15, 0x15, 0x0A, 0x00, 0x00, 0x00,

  0x11, 0x0A, 0x04, 0x0A, 0x11, 0x00, 0x00, 0x00,

  0x11, 0x0A, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00,

  0x1F, 0x02, 0x04, 0x08, 0x1F, 0x00, 0x00, 0x00,

  0x0E, 0x08, 0x08, 0x08, 0x0E, 0x00, 0x00, 0x00,

  0x10, 0x08, 0x04, 0x02, 0x01, 0x00, 0x00, 0x00,

  0x0E, 0x02, 0x02, 0x02, 0x0E, 0x00, 0x00, 0x00,

  0x04, 0x0A, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,

  0x00, 0x00, 0x00, 0x00, 0x1F, 0x00, 0x00, 0x00,

  0x08, 0x08, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00,

  0x00, 0x0C, 0x02, 0x1E, 0x0E, 0x00, 0x00, 0x00,

  0x10, 0x1C, 0x12, 0x12, 0x1C, 0x00, 0x00, 0x00,

  0x00, 0x0E, 0x10, 0x10, 0x0E, 0x00, 0x00, 0x00,

  0x02, 0x0E, 0x12, 0x12, 0x0E, 0x00, 0x00, 0x00,

  0x00, 0x0C, 0x1E, 0x10, 0x0C, 0x00, 0x00, 0x00,

  0x04, 0x08, 0x1C, 0x08, 0x08, 0x00, 0x00, 0x00,

  0x00, 0x0C, 0x12, 0x12, 0x0E, 0x02, 0x0C, 0x00,

  0x10, 0x1C, 0x12, 0x12, 0x12, 0x00, 0x00, 0x00,

  0x00, 0x0C, 0x04, 0x04, 0x0E, 0x00, 0x00, 0x00,

  0x00, 0x06, 0x02, 0x02, 0x02, 0x12, 0x0C, 0x00,

  0x10, 0x12, 0x1C, 0x1C, 0x12, 0x00, 0x00, 0x00,

  0x0C, 0x04, 0x04, 0x04, 0x0E, 0x00, 0x00, 0x00,

  0x00, 0x1A, 0x15, 0x11, 0x11, 0x00, 0x00, 0x00,

  0x00, 0x1C, 0x12, 0x12, 0x12, 0x00, 0x00, 0x00,

  0x00, 0x0C, 0x12, 0x12, 0x0C, 0x00, 0x00, 0x00,

  0x00, 0x1C, 0x12, 0x12, 0x1C, 0x10, 0x10, 0x00,

  0x00, 0x0E, 0x12, 0x12, 0x0E, 0x02, 0x02, 0x00,

  0x00, 0x1C, 0x12, 0x10, 0x10, 0x00, 0x00, 0x00,

  0x00, 0x0E, 0x18, 0x06, 0x1C, 0x00, 0x00, 0x00,

  0x04, 0x0E, 0x04, 0x04, 0x04, 0x00, 0x00, 0x00,

  0x00, 0x12, 0x12, 0x12, 0x0E, 0x00, 0x00, 0x00,

  0x00, 0x12, 0x12, 0x14, 0x08, 0x00, 0x00, 0x00,

  0x00, 0x11, 0x11, 0x15, 0x0A, 0x00, 0x00, 0x00,

  0x00, 0x12, 0x0C, 0x0C, 0x12, 0x00, 0x00, 0x00,

  0x00, 0x12, 0x12, 0x12, 0x0E, 0x02, 0x0C, 0x00,

  0x00, 0x1E, 0x04, 0x08, 0x1E, 0x00, 0x00, 0x00,

  0x04, 0x08, 0x1C, 0x08, 0x04, 0x00, 0x00, 0x00,

  0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00,

  0x04, 0x02, 0x07, 0x02, 0x04, 0x00, 0x00, 0x00,

  0x08, 0x15, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,

  0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x1F, 0x00

};

 

void plot(unsigned int , unsigned int  ,unsigned char);

void putch(unsigned int,unsigned int , unsigned char , unsigned char);

 

int

main (void)

{

      unsigned int ii,jj;

      unsigned char i,j,k;

MCUCR=0xc0;

PORTB=0x00;

DDRB=0x07;

 k=0;

             //for(i=0;i<0x7;i++,k++)

      for(ii=0;ii<512;ii++) for(jj=0;jj<512;jj++) plot(jj,ii,k);

             unsigned int x=0,y=40;

      for(j=0;j<0xff;j++)

      for(y=0,k=0;y<(512-8);k++)

      {    

             for(i=0x0;i<0x40;i++,x+=8)

                     putch(x,y,(i+j-k)&0x5f,i+j+k);

             x=0; y+=8;

             /*for(i=0x40;i<0x60;i++,x+=8)

                     putch(x,y,i,i+j+k);

             x=0; y+=8;*/

      }

 

while(1);

 

    return (0);

}

 

void plot(unsigned int x, unsigned int y,unsigned char c)

{

      unsigned int p,q,r;

      p=x; r=q=y; q<<=9; q&=0x7e00;

      p|=q; p|=0x8000; r>>=6;

      PORTB=(unsigned char)r;

      *(unsigned char *)p=c;

}

 

 

void putch(unsigned int x,unsigned int y, unsigned char c, unsigned char co)

{

      unsigned int i,j;

      unsigned int pp=(unsigned short)tfont+(((unsigned short)c)<<3);

      for(i=0; i<7;i++)

      {

              unsigned char bb=__LPM(pp); pp++;

               for(j=0;j<=7;j++)

              {

                      if(bb&0x80)  plot(x+j,y+i,co);

                               //plot(y+i,x+j,co);

                      else plot(x+j,y+i,0);

                      bb<<=1;

              }

      }

}

 

 

 

 

WinAVR Makefile

 

Makefile

PRG            = demo

OBJ            = demo.o

MCU_TARGET     = at90s8515

OPTIMIZE       = -O2

 

DEFS           =

LIBS           =

 

# You should not have to change anything below here.

 

CC             = avr-gcc

 

# Override is only needed by avr-lib build system.

 

override CFLAGS        = -g -Wall $(OPTIMIZE) -mmcu=$(MCU_TARGET) $(DEFS)

override LDFLAGS       = -Wl,-Map,$(PRG).map

 

OBJCOPY        = avr-objcopy

OBJDUMP        = avr-objdump

 

all: $(PRG).elf lst text eeprom

 

$(PRG).elf: $(OBJ)

      $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ $(LIBS)

 

clean:

      rm -rf *.o $(PRG).elf *.eps *.png *.pdf *.bak

      rm -rf *.lst *.map $(EXTRA_CLEAN_FILES)

 

lst:  $(PRG).lst

 

%.lst: %.elf

      $(OBJDUMP) -h -S $< > $@

 

# Rules for building the .text rom images

 

text: hex bin srec

 

hex:  $(PRG).hex

bin:  $(PRG).bin

srec: $(PRG).srec

 

%.hex: %.elf

      $(OBJCOPY) -j .text -j .data -O ihex $< $@

 

%.srec: %.elf

      $(OBJCOPY) -j .text -j .data -O srec $< $@

 

%.bin: %.elf

      $(OBJCOPY) -j .text -j .data -O binary $< $@

 

# Rules for building the .eeprom rom images

 

eeprom: ehex ebin esrec

 

ehex:  $(PRG)_eeprom.hex

ebin:  $(PRG)_eeprom.bin

esrec: $(PRG)_eeprom.srec

 

%_eeprom.hex: %.elf

      $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O ihex $< $@

 

%_eeprom.srec: %.elf

      $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O srec $< $@

 

%_eeprom.bin: %.elf

      $(OBJCOPY) -j .eeprom --change-section-lma .eeprom=0 -O binary $< $@

 

# Every thing below here is used by avr-libc's build system and can be ignored

# by the casual user.

 

FIG2DEV                 = fig2dev

EXTRA_CLEAN_FILES       = *.hex *.bin *.srec

 

dox: eps png pdf

 

eps: $(PRG).eps

png: $(PRG).png

pdf: $(PRG).pdf

 

%.eps: %.fig

      $(FIG2DEV) -L eps $< $@

 

%.pdf: %.fig

      $(FIG2DEV) -L pdf $< $@

 

%.png: %.fig

      $(FIG2DEV) -L png $< $@

 

 

 

 

 

 

 

 

 

--  Port Signals of sramgfx

 

signal

type

Description

mclk

IN

System clock

hrst

IN

System reset

mppg[2:0]

IN

Host(AVR) memory page address

mpad[7:0]

INOUT

Host memory multiplexed address[7:0]/data[7:0]

mpah[7:0]

IN

Host memory address[15:8]

mpale

IN

Host address latch enable

mprd

IN

Host read

mpwr

IN

Host write

saddr[15:0]

OUT

SRAM address

sdata[31:0]

INOUT

SRAM data

soe

OUT

SRAM output enable

swe

OUT

SRAM write enable

scs

OUT

SRAM chip select

sadsc

OUT

SRAM address select control

sbwe[3:0]

OUT

SRAM byte enable

sdrcs

OUT

SDRAM chip select, for disabling the unused SDRAM in the module

vor[7:0]

OUT

VGA Red signal output

vog[7:0]

OUT

VGA Green signal output

vob[7:0]

OUT

VGA Blue signal output

vvsyn

OUT

VGA vertical sync.

vhsyn

OUT

VGA horizontal sync.

vblk

OUT

VGA DAC blank signal, tie to 1

vsync

OUT

VGA DAC sync. signal, tie to 1

 

 

 

--  Internal Signals of sramgfx

 

signal

Description

mpals[7:0]

Latched lower host address from mpad[7:0]

mpaddr[17:0]

Host address aggregation, = {mppg[2:0],mpah[6:0],mpals[7:0]}; mpah[7] should be 1 for access of the SRAM space

mpwrs

= ~mpwr&mpah[7], synchronized mpwr, mpah[7] should be 1 for SRAM access

mprds

= ~mprd&mpah[7], synchronized mprd, mpah[7] should be 1 for SRAM access

mpwrss

delayed (register latched) mpwrs; state machine for mpwrsp one-shot signal

mprdss

delayed (register latched) mprds; state machine for mprdsp one-shot signal

mpwrsp

= mpwrs&~mpwrss&~vrbwe, one-shot of host write mpwrs, inhibited when previous vrbwe (video display read buffer write enable) is still active

mpwrsps

delayed (register latched) mpwrsp

mprdsp

= mprds&~mprdss, one-shot of host read mprds

mprdsps

delayed (register latched) mprdsp

mprdspss

delayed (register latched) mprdsps

vrdp

= ~vrhcnt[7]&~nvrbcnt[1]&ven&hen&~mprdsp&~mpwrsp&~mpwrsps, video dispaly read buffer read request, activated when :

      ~vrhcnt[7]: bytes already read <128 x 4 bytes, in this horizontal cycle

      ~nvrbcnt[1]: the two entry video read buffer vrbuf is not full

      ven&hen: active region of video disaply area

      ~mprdsp&~mpwrsp: inhibited when host is about to read or write; this is       the arbitor that host read/write has higher prioirty

      ~mpwrsps: also inhabited when host write still in progress

vrbwe

write enable of video display read buffer vrbuf; delayed vrdp

vrbwes

delayed vrbwe

hcnt[9:0]

video display horizontal counter for generating video timing signals

vcnt[9:0]

video display veritical counter for generating video timing signals

vrhcnt[7:0]

video read buffer counter for generating read address in one horizontal cycle

nvrhcnt[7:0]

next state for vrhcnt[7:0]

vrbcnt[1:0]

video read buffer fifo counter for preventing FIFO full

nvrbcnt[1:0]

next state for vrbcnt[1:0]

hov

= (hcnt==795), overflow of hcnt[9:0], makes hcnt counts from 0 to 796, that determines the period of a horizontal line

hpov

= (hcnt==788), a few cycles ahead of hov, triggers signals of hen,vcnt and ven

hend

= (hcnt==509), for turning off hen

hsyns

= (hcnt==652), signal for turning on hsyn

hsyne

= (hcnt==747), signal for turning off hsyn

hovs[4:0]

delayed signals of hpov

hsyn

horizontal synchronous signal of VGA

hen

horizontal enable of display active region

vov

vertical counter overflow

vend

end of vertical enable cycle

vsyns

start of vertical synchronous signal

vsyne

end of vertical synchronous signal

vsyn

vertical synchronous signal of VGA

ven

horizontal enable of active display region

saddr[15:0]

SRAM address lines

voutrd

= (vhens[7]&(hcnt[1:0]==3)), asserts for every four bytes read from the FIFO

soe

SRAM output enable

swe

SRAM write enable

sadsc

SRAM address select control

sbwe[3:0]

SRAM byte enable for write cycles

vhens[7:0]

delayed registers of (ven&hen) indicating the active display region with various latencies

vout[7:0]

video read data out from the FIFO for display

vouts[7:0]

register latched of vout[7:0]

sdtis[31:0]

register latched of SRAM data sdata[31:0] of host read cycles

mpdto[7:0]

selected bytes from sdits[31:0] for host read data return

nrstn

synchronized system reset hrst

nrst

synchronized nrstn

 

 

 

1. Micro Processor Lower Address mpals[7:0] is latched from the address/data multiplexed mpad[7:0] and forms the full host address mpaddr[17:0] and the SRAM write-byte-enable sbwe[3:0].

 

2. Micro Processor data bus mpad[7:0] duplicates and drives the 32-bits SRAM data bus sdata[31:0] when swe asserts.

 

 3. Video data from the SRAM data bus sdata [31:0] is written to the two-entry RAM buffer vrbuf when vrbwes asserts, which is then transported to the RGB outputs (vor,vog,vob) of the scanning display.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

文章標籤
全站熱搜
創作者介紹
創作者 zeppe 的頭像
zeppe

ZEPPE

zeppe 發表在 痞客邦 留言(0) 人氣(383)