FPGA / ARM / DSP Wishbone SoC


< Using GNUARM >

 

 

 

 

 

Lab1 : Wishbone0

 

ARM SoC / FPGA Wishbone Bus 整合實驗1

 

 

 

Introduction

 

 

Lab.1是一個整合ARM SoCFPGA硬體的範例。FPGA部分為個Wishbone SoC Bus System Wishbone0包含Wishbone Bus Framework一個ARM9 Interface Master及一個簡單的GPIO Slave。實驗以ARM執行一段程式,控制GPIO Slave驅動之LED

ARM的程式是在Windows環境中,以GNUARM Compiler進行編譯,並以ARM模組的UBoot提供之命令直接載入記憶體執行。

 

 

 

 

Design Codes

 

 

 

在此實驗FPGA內的Wishbone0電路架構可分成三部分: Wishbone Bus Framework, Wishbone ARM Master及一個簡單的Wishbone GPIO Slave

 

 

 

 

 

 

 

 

 

wbbus8n8.v是一個最多可容納8Master8Slave的一個shared bus架構的Wishbone Bus Framework而沒有用到的MasterSlave Ports則連接到一個不使用並安全的狀態。 wbbus8n8.v內包還含一個Wishbone Master arbiter wbarb8.v,負責決定8個可能的Master何者可以開始一個讀或寫的bus transaction。連接ARM9 SoCWishbone ARM Master WrapperWishbone0的唯一Masterwbios.v則是一個簡單的具GPIO Wishbone Slave.

 

 

 

 

 

Hierarchy

 

 

 

 

 

 

  wbchip.v

 

 

`timescale 1ns / 100ps

 

module wbchip

(

 

mclk,

mrsti,mrstg,

 

 

ledo,

dpswi,

 

aadr,adt,

agcs2,anwe,anoe,

awbe,

anwt

 

);

 

input mclk;

input mrsti;

output mrstg;

 

output[23:0] ledo;

input[7:0] dpswi;

 

input[24:2] aadr;

inout[31:0] adt;

input agcs2;

input anwe,anoe;

input[3:0] awbe;

output anwt;

 

parameter cmdw=32+32+4+1+3+2+1+1;   

                           // addr+wdata+sel+we+cti+bte+stb+cyc

parameter rtnw=32+1+1+1;            

                           // rdata+err+rty+ack

 

wire[31:0] ardt;

 

 

wire[31:0]    m0_wbadr;

wire[31:0]    m0_wbwdt;

wire[3:0]     m0_wbsel;

wire     m0_wbwe;

wire[2:0]     m0_wbcti;

wire[1:0]     m0_wbbte;

wire     m0_wbcyc;

wire     m0_wbstb;

wire[31:0]    m0_wbrdt;

wire     m0_wberr;

wire     m0_wbrty;

wire     m0_wback;

 

wire[31:0]    s0_wbadr;

wire[31:0]    s0_wbwdt;

wire[3:0]     s0_wbsel;

wire     s0_wbwe;

wire[2:0]     s0_wbcti;

wire[1:0]     s0_wbbte;

wire     s0_wbcyc;

wire     s0_wbstb;

wire[31:0]    s0_wbrdt;

wire     s0_wberr;

wire     s0_wbrty;

wire     s0_wback;

 

 

wire mrst=~mrsti;

assign mrstg=1'b0;

 

 

assign m0_wbcti='b010,m0_wbbte='b00;

 

     // addr+wdata+sel+we+cti+bte+stb+cyc

 

 

wbbus8n8 wbbus(

.mclk(mclk),.mrst(mrst),

.m0_cmdi({m0_wbadr,m0_wbwdt,m0_wbsel,m0_wbwe,

           m0_wbcti,m0_wbbte,m0_wbstb,m0_wbcyc}),

.m0_rtno({m0_wbrdt,m0_wberr,m0_wbrty,m0_wback}),

.m1_cmdi({(cmdw){1'b0}}),

.m1_rtno(),

.m2_cmdi({(cmdw){1'b0}}),

.m2_rtno(),

.m3_cmdi({(cmdw){1'b0}}),

.m3_rtno(),

.m4_cmdi({(cmdw){1'b0}}),

.m4_rtno(),

.m5_cmdi({(cmdw){1'b0}}),

.m5_rtno(),

.m6_cmdi({(cmdw){1'b0}}),

.m6_rtno(),

.m7_cmdi({(cmdw){1'b0}}),

.m7_rtno(),

 

.s0_cmdo({s0_wbadr,s0_wbwdt,s0_wbsel,s0_wbwe,

           s0_wbcti,s0_wbbte,s0_wbstb,s0_wbcyc}),

.s0_rtni({s0_wbrdt,s0_wberr,s0_wbrty,s0_wback}),

.s1_cmdo(),

.s1_rtni(1),

.s2_cmdo(),

.s2_rtni(1),

.s3_cmdo(),

.s3_rtni(1),

.s4_cmdo(),

.s4_rtni(1),

.s5_cmdo(),

.s5_rtni(1),

.s6_cmdo(),

.s6_rtni(1),

.s7_cmdo(),

.s7_rtni(1)

 

);

 

assign adt=(~anoe&~agcs2)?ardt:32'bz;

 

wb_arm wb_arm(

.mclk(mclk),

.mrst(mrst),

.aadr(aadr),

.awdt(adt),

.ardt(ardt),

.agcs2(agcs2),

.anwe(anwe),

.anoe(anoe),

.awbe(awbe),

.anwt(anwt),

 

.wbadr (m0_wbadr),

.wbdin (m0_wbrdt),

.wbdout(m0_wbwdt),

.wbcyc (m0_wbcyc),

.wbstb (m0_wbstb),

.wbsel (m0_wbsel),

.wbwe  (m0_wbwe),

.wback (m0_wback),

.wberr (m0_wberr),

.wbrty (m0_wbrty)

);

 

 

wbios wbios

(

.mclk(mclk),

.mrst(mrst),

 

.ledo(ledo),

.dpswi(dpswi),

 

.wbadr (s0_wbadr),

.wbdin (s0_wbwdt),

.wbdout(s0_wbrdt),

.wbcyc (s0_wbcyc),

.wbstb (s0_wbstb),

.wbsel (s0_wbsel),

.wbwe  (s0_wbwe),

.wback (s0_wback),

.wberr (s0_wberr),

.wbrty (s0_wbrty)

 

);

 

endmodule

 

 

 

  wb_arm.v

 

 

 

`timescale 1ns / 100ps

 

module wb_arm(

mclk, mrst,

 

aadr,

awdt,

ardt,

agcs2,

anwe,

anoe,

awbe,

anwt,

 

wbadr,

wbdin,

wbdout,

wbcyc,wbstb,

wbsel,

wbwe,

wback,wberr,wbrty

);

 

input mclk,mrst;

 

input[24:2] aadr;

input[31:0] awdt;

output[31:0] ardt;

input agcs2;

input anwe,anoe;

input[3:0] awbe;

output anwt;

 

output[31:0] wbadr;

input[31:0] wbdin;

output[31:0] wbdout;

output wbcyc,wbstb;

output[3:0]   wbsel;

output wbwe;

input wback,wberr,wbrty;

 

reg[31:0] wbadr;

reg[31:0] wbdout;

reg[3:0] wbsel;

reg mwes,moes;

reg[1:0] macss,nmacss;

reg wbcyc,wbstb;

reg[31:0] ardt;

 

always @(posedge mclk)

begin

wbadr<={7'b0,aadr[24:2],2'b0};

wbdout<=awdt;

wbsel<=~awbe;

mwes<=~anwe&~agcs2;

moes<=~anoe&~agcs2;

end

 

always @(posedge mclk or posedge mrst)

begin

if(mrst) macss<=2'b00;

else macss<=nmacss;

end

 

always @(macss or mwes or moes or wback)

begin

     case(macss)

     2'b00: begin wbcyc=(mwes|moes); wbstb=(mwes|moes);

                  nmacss=((mwes|moes)&wback)?'b01:'b00; end

     2'b01: begin wbcyc=1'b0; wbstb=1'b0;

                  nmacss=((~mwes&~moes)?'b00:'b01); end

     default: begin wbcyc=1'b0; wbstb=1'b0;

                  nmacss=2'b00; end

     endcase

end

 

//// wb signals

 

assign wbwe=mwes;

 

//// arm signals

 

always@(posedge mclk)

begin

     ardt<=(wbstb&wback)?wbdin:ardt;

end

 

/*

always@(wbdin)

begin

     ardt=wbdin;

end

*/

assign anwt=~((mwes|moes)&~macss[0]);

 

endmodule

 

 

 

 

 

 

  wbios.v


 

 

`timescale 1ns / 100ps

 

module wbios

(

mclk, mrst,

 

ledo,

dpswi,

 

wbadr,

wbdin,

wbdout,

wbcyc,wbstb,

wbsel,

wbwe,

wback,wberr,wbrty

 

);

 

 

input mclk,mrst;

 

output[23:0] ledo;

input[7:0] dpswi;

 

input[31:0] wbadr;

input[31:0] wbdin;

output[31:0] wbdout;

input wbcyc,wbstb;

input[3:0]    wbsel;

input wbwe;

output wback,wberr,wbrty;

 

reg[31:0] wbdout;

reg[23:0] ledo;

 

assign wback=wbcyc&wbstb;

assign wberr=1'b0;

assign wbrty=1'b0;

 

always @*

begin

     case(wbadr[7:2])

     ('h04>>2): wbdout={24'b0,dpswi};

     default: wbdout=32'b0;

     endcase

end

 

always @(posedge mclk or posedge mrst)

begin

if(mrst) begin

     ledo<=24'b0;

     end

else if(wbcyc&wbstb&wbwe) begin

     case(wbadr[7:2])

     ('h000>>2): begin

         if(wbsel[2]) ledo[23:16]<=wbdin[23:16];

         if(wbsel[1]) ledo[15: 8]<=wbdin[15: 8];

         if(wbsel[0]) ledo[ 7: 0]<=wbdin[ 7: 0]; end

     endcase end

end

 

endmodule

 

 

 

 

 

 

 

  wbbus8n8.v

 

 

`timescale 1ns / 100ps

 

module wbbus8n8(

     mclk, mrst,

 

m0_cmdi,m0_rtno,

m1_cmdi,m1_rtno,

m2_cmdi,m2_rtno,

m3_cmdi,m3_rtno,

m4_cmdi,m4_rtno,

m5_cmdi,m5_rtno,

m6_cmdi,m6_rtno,

m7_cmdi,m7_rtno,

 

s0_rtni,s0_cmdo,

s1_rtni,s1_cmdo,

s2_rtni,s2_cmdo,

s3_rtni,s3_cmdo,

s4_rtni,s4_cmdo,

s5_rtni,s5_cmdo,

s6_rtni,s6_cmdo,

s7_rtni,s7_cmdo

 

);

 

 

parameter cmdw=32+32+4+1+3+2+1+1;    // addr+wdata+sel+we+cti+bte+stb+cyc

parameter rtnw=32+1+1+1;                 // rdata+err+rty+ack

parameter adcw=25+32+4+1+3+2+1+1;    // addr+wdata+sel+we+cti+bte+stb+cyc

 

                                         // a[24:20]

parameter s0_addrw = 5, s0_addr = 5'h00;

parameter s1_addrw = 5, s1_addr = 5'h01;

parameter s2_addrw = 5, s2_addr = 5'h02;

parameter s3_addrw = 5, s3_addr = 5'h03;

parameter s4_addrw = 5, s4_addr = 5'h04;

parameter s5_addrw = 5, s5_addr = 5'h05;

parameter s6_addrw = 5, s6_addr = 5'h06;

parameter s7_addrw = 5, s7_addr = 5'h07;

 

 

input mclk, mrst;

 

input[cmdw-1:0]        m0_cmdi, m1_cmdi, m2_cmdi, m3_cmdi, m4_cmdi, m5_cmdi, m6_cmdi, m7_cmdi;

output[cmdw-1:0]  s0_cmdo, s1_cmdo, s2_cmdo, s3_cmdo, s4_cmdo, s5_cmdo, s6_cmdo, s7_cmdo;

input [rtnw-1:0]  s0_rtni, s1_rtni, s2_rtni, s3_rtni, s4_rtni, s5_rtni, s6_rtni, s7_rtni;

output[rtnw-1:0]  m0_rtno, m1_rtno, m2_rtno, m3_rtno, m4_rtno, m5_rtno, m6_rtno, m7_rtno;

 

wire[7:0] mgnt;

wire[7:0] ss_dec;

 

reg[cmdw-1:0] mm_cmd;

reg[rtnw-1:0] ss_rtn;

 

//{s0_wbrdt,s0_wberr,s0_wbrty,s0_wback}

always @*

begin

     casex(ss_dec) // synthesis parallel_case full_case

     8'bxxxxxxx1 : ss_rtn=s0_rtni;

     8'bxxxxxx1x : ss_rtn=s1_rtni;

     8'bxxxxx1xx : ss_rtn=s2_rtni;

     8'bxxxx1xxx : ss_rtn=s3_rtni;

     8'bxxx1xxxx : ss_rtn=s4_rtni;

     8'bxx1xxxxx : ss_rtn=s5_rtni;

     8'bx1xxxxxx : ss_rtn=s6_rtni;

     8'b1xxxxxxx : ss_rtn=s7_rtni;

     default: ss_rtn=1;

     endcase

end

 

wbarb8   wbarb(

     .mclk(mclk), .mrst(mrst),

     .mreq({  m7_cmdi[0],

              m6_cmdi[0],

              m5_cmdi[0],

              m4_cmdi[0],

              m3_cmdi[0],

              m2_cmdi[0],

              m1_cmdi[0],

              m0_cmdi[0]}),

     .mgnt(mgnt)

);

 

//{m0_adr_i,m0_sel_i,m0_dat_i,m0_we_i,m0_cti,m0_bte,m0_stb_i,m0_cyc_i};

always @*

begin

     casex(mgnt) // synthesis parallel_case full_case

     8'bxxxxxxx1 : mm_cmd=m0_cmdi;

     8'bxxxxxx1x : mm_cmd=m1_cmdi;

     8'bxxxxx1xx : mm_cmd=m2_cmdi;

     8'bxxxx1xxx : mm_cmd=m3_cmdi;

     8'bxxx1xxxx : mm_cmd=m4_cmdi;

     8'bxx1xxxxx : mm_cmd=m5_cmdi;

     8'bx1xxxxxx : mm_cmd=m6_cmdi;

     8'b1xxxxxxx : mm_cmd=m7_cmdi;

     default: mm_cmd=0;

     endcase

end

 

assign ss_dec[0]=(mm_cmd[adcw-1:adcw-s0_addrw] == s0_addr);

assign ss_dec[1]=(mm_cmd[adcw-1:adcw-s1_addrw] == s1_addr);

assign ss_dec[2]=(mm_cmd[adcw-1:adcw-s2_addrw] == s2_addr);

assign ss_dec[3]=(mm_cmd[adcw-1:adcw-s3_addrw] == s3_addr);

assign ss_dec[4]=(mm_cmd[adcw-1:adcw-s4_addrw] == s4_addr);

assign ss_dec[5]=(mm_cmd[adcw-1:adcw-s5_addrw] == s5_addr);

assign ss_dec[6]=(mm_cmd[adcw-1:adcw-s6_addrw] == s6_addr);

assign ss_dec[7]=(mm_cmd[adcw-1:adcw-s7_addrw] == s7_addr);

 

 

assign m0_rtno={ss_rtn[rtnw-1:3],mgnt[0]?ss_rtn[2:0]:3'b0};

assign m1_rtno={ss_rtn[rtnw-1:3],mgnt[1]?ss_rtn[2:0]:3'b0};

assign m2_rtno={ss_rtn[rtnw-1:3],mgnt[2]?ss_rtn[2:0]:3'b0};

assign m3_rtno={ss_rtn[rtnw-1:3],mgnt[3]?ss_rtn[2:0]:3'b0};

assign m4_rtno={ss_rtn[rtnw-1:3],mgnt[4]?ss_rtn[2:0]:3'b0};

assign m5_rtno={ss_rtn[rtnw-1:3],mgnt[5]?ss_rtn[2:0]:3'b0};

assign m6_rtno={ss_rtn[rtnw-1:3],mgnt[6]?ss_rtn[2:0]:3'b0};

assign m7_rtno={ss_rtn[rtnw-1:3],mgnt[7]?ss_rtn[2:0]:3'b0};

 

assign s0_cmdo={mm_cmd[cmdw-1:2],ss_dec[0]?mm_cmd[1:0]:2'b0};

assign s1_cmdo={mm_cmd[cmdw-1:2],ss_dec[1]?mm_cmd[1:0]:2'b0};

assign s2_cmdo={mm_cmd[cmdw-1:2],ss_dec[2]?mm_cmd[1:0]:2'b0};

assign s3_cmdo={mm_cmd[cmdw-1:2],ss_dec[3]?mm_cmd[1:0]:2'b0};

assign s4_cmdo={mm_cmd[cmdw-1:2],ss_dec[4]?mm_cmd[1:0]:2'b0};

assign s5_cmdo={mm_cmd[cmdw-1:2],ss_dec[5]?mm_cmd[1:0]:2'b0};

assign s6_cmdo={mm_cmd[cmdw-1:2],ss_dec[6]?mm_cmd[1:0]:2'b0};

assign s7_cmdo={mm_cmd[cmdw-1:2],ss_dec[7]?mm_cmd[1:0]:2'b0};

 

 

endmodule

 

 

 

 

 

  wbarb8.v

 

 

`timescale 1ns / 100ps

 

module wbarb8

(

mclk, mrst,

mreq,

mgnt

);

 

input mclk;

input mrst;

input [7:0]   mreq;

output [7:0] mgnt;

 

 

reg[7:0] msta,nmsta;

reg[7:0] mgnt,mgnts;

reg[7:0] mgcnt;

 

reg mfsw;

wire mrqe;

 

assign mrqe=((mgnt&mreq)=='b0);

 

always @(posedge mclk or posedge mrst)

begin

if(mrst) mfsw<=1'b0;

else mfsw<=(mgcnt=='h40);

end

 

always@(posedge mclk or posedge mrst)

begin

if(mrst) mgcnt<=0;

else if(~(mgnts==mgnt)|mrqe) mgcnt<=0;

else mgcnt<=mgcnt+1;

end

 

always@(posedge mclk or posedge mrst)

begin

if(mrst) begin msta<=1; mgnt<=0; mgnts<=0; end

else begin

         msta<=mrqe?nmsta:msta;

         mgnt<=mfsw?0:mrqe?nmsta:mgnt;

         mgnts<=mgnt;

     end

end

 

 

always @*

begin

     casex(msta) // synthesis parallel_case full_case

     8'bxxxxxxx1 : begin nmsta=mreq[7]?1<<7:mreq[6]?1<<6:mreq[5]?1<<5:mreq[4]?1<<4

                                :mreq[3]?1<<3:mreq[2]?1<<2:mreq[1]?1<<1:1<<0; end

     8'bxxxxxx1x : begin nmsta=mreq[6]?1<<6:mreq[5]?1<<5:mreq[4]?1<<4:mreq[3]?1<<3

                                :mreq[2]?1<<2:mreq[1]?1<<1:mreq[0]?1<<0:1<<7; end

     8'bxxxxx1xx : begin nmsta=mreq[5]?1<<5:mreq[4]?1<<4:mreq[3]?1<<3:mreq[2]?1<<2

                                :mreq[1]?1<<1:mreq[0]?1<<0:mreq[7]?1<<7:1<<6; end

     8'bxxxx1xxx : begin nmsta=mreq[4]?1<<4:mreq[3]?1<<3:mreq[2]?1<<2:mreq[1]?1<<1

                                :mreq[0]?1<<0:mreq[7]?1<<7:mreq[6]?1<<6:1<<5; end

     8'bxxx1xxxx : begin nmsta=mreq[3]?1<<3:mreq[2]?1<<2:mreq[1]?1<<1:mreq[0]?1<<0

                                :mreq[7]?1<<7:mreq[6]?1<<6:mreq[5]?1<<5:1<<4; end

     8'bxx1xxxxx : begin nmsta=mreq[2]?1<<2:mreq[1]?1<<1:mreq[0]?1<<0:mreq[7]?1<<7

                                :mreq[6]?1<<6:mreq[5]?1<<5:mreq[4]?1<<4:1<<3; end

     8'bx1xxxxxx : begin nmsta=mreq[1]?1<<1:mreq[0]?1<<0:mreq[7]?1<<7:mreq[6]?1<<6

                                :mreq[5]?1<<5:mreq[4]?1<<4:mreq[3]?1<<3:1<<2; end

     8'b1xxxxxxx : begin nmsta=mreq[0]?1<<0:mreq[7]?1<<7:mreq[6]?1<<6:mreq[5]?1<<5

                                :mreq[4]?1<<4:mreq[3]?1<<3:mreq[2]?1<<2:1<<1; end

     default : begin nmsta=1<<0; end

     endcase

end

 

endmodule

 

 

 

 

 

 

 

 

 

ARM9 C Programs : gatest00

 

 

這個測試程式指透過UARTHyperterm上顯示一字串, ARM並未在Wishbone上發出讀或寫的trnasactions. 目的只是驗證編譯工具與程式下載機制.

 

 

 

  gatest00.c

 

#include <stdio.h>

#include <serial.h>

 

 

int main()

{

     void (*prst)(void)=0;

 

     serial_puts ("************* Hello World !!! *************");

 

     (*prst)();    // reset

 

     return 0;

}

 

 

 

 

  serial.c

 

 

#include "serial.h"

 

/*

 * Read a single byte from the serial port. Returns 1 on success, 0

 * otherwise. When the function is succesfull, the character read is

 * written into its argument c.

 */

int serial_getc (void)

{

     S3C24X0_UART * const uart = S3C24X0_GetBase_UART(UART_NR);

 

     /* wait for character to arrive */

     while (!(uart->UTRSTAT & 0x1));

 

     return uart->URXH & 0xff;

}

 

/*

 * Output a single byte to the serial port.

 */

void serial_putc (const char c)

{

     S3C24X0_UART * const uart = S3C24X0_GetBase_UART(UART_NR);

 

     /* wait for room in the tx FIFO */

     while (!(uart->UTRSTAT & 0x2));

 

     uart->UTXH = c;

 

     /* If \n, also do \r */

     if (c == '\n')

         serial_putc ('\r');

}

 

/*

 * Test whether a character is in the RX buffer

 */

int serial_tstc (void)

{

     S3C24X0_UART * const uart = S3C24X0_GetBase_UART(UART_NR);

 

     return uart->UTRSTAT & 0x1;

}

 

void serial_puts (const char *s)

{

     while (*s) {

         serial_putc (*s++);

     }

}

 

 

 

 

 

  serial.h

 

 

typedef enum {

     S3C24X0_UART0,

     S3C24X0_UART1,

     S3C24X0_UART2

} S3C24X0_UARTS_NR;

 

 

#define S3C24X0_UART_BASE       0x50000000

 

typedef unsigned char u8;

typedef unsigned short u16;

typedef unsigned int u32;

typedef unsigned long ulong;

 

typedef volatile u8        S3C24X0_REG8;

typedef volatile u16   S3C24X0_REG16;

typedef volatile u32   S3C24X0_REG32;

 

#define UART_NR   S3C24X0_UART0

 

 

 

/* UART (see manual chapter 11) */

typedef struct {

     S3C24X0_REG32 ULCON;

     S3C24X0_REG32 UCON;

     S3C24X0_REG32 UFCON;

     S3C24X0_REG32 UMCON;

     S3C24X0_REG32 UTRSTAT;

     S3C24X0_REG32 UERSTAT;

     S3C24X0_REG32 UFSTAT;

     S3C24X0_REG32 UMSTAT;

     S3C24X0_REG8  UTXH;

     S3C24X0_REG8  res1[3];

     S3C24X0_REG8  URXH;

     S3C24X0_REG8  res2[3];

     S3C24X0_REG32 UBRDIV;

} /*__attribute__((__packed__))*/ S3C24X0_UART;

 

 

static inline S3C24X0_UART * const S3C24X0_GetBase_UART(S3C24X0_UARTS_NR nr)

{

     return (S3C24X0_UART * const)(S3C24X0_UART_BASE + (nr * 0x4000));

}

 

 

 

  crt.s

 

                       

.set MISCCR   ,0x56000080    

                           /*Miscellaneous control                             */

.set DCKCON   ,0x56000084    

                           /*DCLK0/1 control                                   */

.set EXTINT0  ,0x56000088    

                           /*External interrupt control register 0             */

.set EXTINT1  ,0x5600008c    

                           /*External interrupt control register 1             */

.set EXTINT2  ,0x56000090    

                           /*External interrupt control register 2             */

.set EINTFLT0 ,0x56000094    

                           /*Reserved                                          */

.set EINTFLT1 ,0x56000098    

                           /*Reserved                                          */

.set EINTFLT2 ,0x5600009c    

                           /*External interrupt filter control register 2      */

.set EINTFLT3 ,0x560000a0    

                           /*External interrupt filter control register 3      */

.set EINTMASK ,0x560000a4    

                           /*External interrupt mask                           */

.set EINTPEND ,0x560000a8    

                           /*External interrupt pending                        */

.set GSTATUS0 ,0x560000ac    

                           /*External pin status                               */

.set GSTATUS1 ,0x560000b0    

                           /*Chip ID(0x32410000)                               */

.set GSTATUS2 ,0x560000b4    

                           /*Reset type                                        */

.set GSTATUS3 ,0x560000b8    

                           /*Saved data0(32-bit) before entering POWER_OFF mode*/

.set GSTATUS4 ,0x560000bc    

                           /*Saved data1(32-bit) before entering POWER_OFF mode*/

 

 

 

.set WTCON        ,0x53000000

.set INTSUBMSK    ,0x4a00001c

.set INTMSK       ,0x4a000008

 

.set LOCKTIME   ,0x4c000000     /*PLL lock time counter   */

.set MPLLCON    ,0x4c000004     /*MPLL Control            */

.set UPLLCON    ,0x4c000008     /*UPLL Control            */

.set CLKCON     ,0x4c00000c     /*Clock generator control */

.set CLKSLOW    ,0x4c000010     /*Slow clock control      */

.set CLKDIVN    ,0x4c000014     /*Clock divider control   */

 

.set BWSCON        ,0x48000000   /*Bus width & wait status     */

.set BANKCON0      ,0x48000004   /*Boot ROM control            */

.set BANKCON1      ,0x48000008   /*BANK1 control               */

.set BANKCON2      ,0x4800000c   /*BANK2 cControl              */

.set BANKCON3      ,0x48000010   /*BANK3 control               */

.set BANKCON4      ,0x48000014   /*BANK4 control               */

.set BANKCON5      ,0x48000018   /*BANK5 control               */

.set BANKCON6      ,0x4800001c   /*BANK6 control               */

.set BANKCON7      ,0x48000020   /*BANK7 control               */

.set REFRESH       ,0x48000024   /*DRAM/SDRAM refresh          */

.set BANKSIZE      ,0x48000028   /*Flexible Bank Size          */

.set MRSRB6        ,0x4800002c   /*Mode register set for SDRAM */

.set MRSRB7        ,0x48000030   /*Mode register set for SDRAM */

 

 

 

/*FCLK = 176000000 */

.set M_MDIV  ,105                  /*Fin=12.0MHz Fout=176.0MHz  */

.set M_PDIV  ,2

.set M_SDIV  ,2

 

.set DW8  , (0x0)   

.set DW16 , (0x1)  

.set DW32 , (0x2)  

.set WAIT , (0x1<<2)

.set UBLB , (0x1<<3)

 

 

.set B1_BWSCON , (DW32)

.set B2_BWSCON , (DW32)

.set B3_BWSCON , (DW32)

.set B4_BWSCON , (DW32)

.set B5_BWSCON , (DW32)

.set B6_BWSCON , (DW32)

.set B7_BWSCON , (DW32)

 

 

.set B0_Tacs ,0x3

.set B0_Tcos ,0x3

.set B0_Tacc ,0x7

.set B0_Tcoh ,0x3

.set B0_Tah  ,0x3

.set B0_Tacp ,0x3

.set B0_PMC  ,0x0

 

.set B1_Tacs ,0x3

.set B1_Tcos ,0x3

.set B1_Tacc ,0x7

.set B1_Tcoh ,0x3

.set B1_Tah  ,0x3

.set B1_Tacp ,0x3

.set B1_PMC  ,0x0

 

.set B2_Tacs ,0x3

.set B2_Tcos ,0x3

.set B2_Tacc ,0x7

.set B2_Tcoh ,0x3

.set B2_Tah  ,0x3

.set B2_Tacp ,0x3

.set B2_PMC  ,0x0

 

.set B3_Tacs ,0x3

.set B3_Tcos ,0x3

.set B3_Tacc ,0x7

.set B3_Tcoh ,0x3

.set B3_Tah  ,0x3

.set B3_Tacp ,0x3

.set B3_PMC  ,0x0

 

.set B4_Tacs ,0x3

.set B4_Tcos ,0x3

.set B4_Tacc ,0x7

.set B4_Tcoh ,0x3

.set B4_Tah  ,0x3

.set B4_Tacp ,0x3

.set B4_PMC  ,0x0

 

.set B5_Tacs ,0x3

.set B5_Tcos ,0x3

.set B5_Tacc ,0x7

.set B5_Tcoh ,0x3

.set B5_Tah  ,0x3

.set B5_Tacp ,0x3

.set B5_PMC  ,0x0

 

.set B6_MT   ,0x3  

/*.set B6_Trcd ,0x0 */

.set B6_Trcd ,0x1

.set B6_SCAN ,0x1

 

.set B7_MT   ,0x3  

/*.set B7_Trcd ,0x0 */

.set B7_Trcd ,0x1

.set B7_SCAN ,0x1

 

 

.set REFEN   ,0x1 

.set TREFMD  ,0x0

.set Trp     ,0x0   

.set Trc     ,0x3    

                        

.set Tchr    ,0x2  

.set REFCNT  ,1113

 

/* identify all GLOBAL symbols */

.global _start

 

/* GNU assembler controls */

.text /* all assembler code that follows will go into .text section */

.arm /* compile for 32?bit ARM instruction set */

.align /* align section on 32?bit boundary */

 

_start:

 

        /* Set memory control registers*/

        ldr    r0,=SMRDATA

        ldr    r1,=BWSCON           /* BWSCON Address*/

        add    r2, r0, #52          /* End address of SMRDATA*/

0:

        ldr    r3, [r0], #4   

        str    r3, [r1], #4   

        cmp    r2, r0       

        bne    0b

 

ldr r0, =_stack_end /* r0 = top?of?stack */

mov sp, r0 /* set stack pointer for SYS mode */

 

/* copy initialized variables .data section (Copy from ROM to RAM) */

ldr R1, =_text_end

ldr R2, =_data

ldr R3, =_data_end

1: cmp R2, R3

ldrlo R0, [R1], #4

strlo R0, [R2], #4

blo 1b

/* Clear uninitialized variables .bss section (Zero init) */

mov R0, #0

ldr R1, =_bss_start

ldr R2, =_bss_end

2: cmp R1, R2

strlo R0, [R1], #4

blo 2b

/* Enter the C code */

bl main

 

1:

     b  1b

 

SMRDATA:

/*

   Memory configuration should be optimized for best performance

   The following parameter is not optimized.                    

   Memory access cycle parameter strategy

   1) The memory settings is  safe parameters even at HCLK=75Mhz.

   2) SDRAM refresh period is for HCLK=75Mhz.

*/

 

        .word (0+(B1_BWSCON<<4)+(B2_BWSCON<<8)+(B3_BWSCON<<12)+

                (B4_BWSCON<<16)+(B5_BWSCON<<20)+(B6_BWSCON<<24)+(B7_BWSCON<<28))

        .word ((B0_Tacs<<13)+(B0_Tcos<<11)+(B0_Tacc<<8)+(B0_Tcoh<<6)+

                (B0_Tah<<4)+(B0_Tacp<<2)+(B0_PMC))   /* GCS0 */

        .word ((B1_Tacs<<13)+(B1_Tcos<<11)+(B1_Tacc<<8)+(B1_Tcoh<<6)+

                (B1_Tah<<4)+(B1_Tacp<<2)+(B1_PMC))   /* GCS1 */

        .word ((B2_Tacs<<13)+(B2_Tcos<<11)+(B2_Tacc<<8)+(B2_Tcoh<<6)+

                (B2_Tah<<4)+(B2_Tacp<<2)+(B2_PMC))   /* GCS2 */

        .word ((B3_Tacs<<13)+(B3_Tcos<<11)+(B3_Tacc<<8)+(B3_Tcoh<<6)+

                (B3_Tah<<4)+(B3_Tacp<<2)+(B3_PMC))   /* GCS3 */

        .word ((B4_Tacs<<13)+(B4_Tcos<<11)+(B4_Tacc<<8)+(B4_Tcoh<<6)+

                (B4_Tah<<4)+(B4_Tacp<<2)+(B4_PMC))   /* GCS4 */

        .word ((B5_Tacs<<13)+(B5_Tcos<<11)+(B5_Tacc<<8)+(B5_Tcoh<<6)+

                (B5_Tah<<4)+(B5_Tacp<<2)+(B5_PMC))   /* GCS5 */

        .word ((B6_MT<<15)+(B6_Trcd<<2)+(B6_SCAN))

                                                            /* GCS6 */

        .word ((B7_MT<<15)+(B7_Trcd<<2)+(B7_SCAN))

                                                            /* GCS7 */

        .word ((REFEN<<23)+(TREFMD<<22)+(Trp<<20)+(Trc<<18)+(Tchr<<16)+REFCNT)   

        .word 0x20                    /* SCLK power saving mode, BANKSIZE 128M/128M  */

        .word 0x30                   /* MRSR6 CL=3clk   */

        .word 0x30                   /* MRSR7           */

/*        .word 0x20                 /* MRSR6 CL=2clk   */

/*        .word 0x20                 /* MRSR7           */

 

.end

 

 

 

 

 

  gatest00.ld

 

 

 

ENTRY(_start)

 

MEMORY

{

     flash : ORIGIN = 0, LENGTH = 256K

     ram : ORIGIN = 0x40000000, LENGTH = 4K

     sdram : ORIGIN = 0x30000000, LENGTH = 32*1024K

}

 

_stack_end = 0x30100000;

 

SECTIONS

{

     . = 0x30000000;

     .text :

     {

         *(.init)

         *(.text)

         *(.rodata)

         *(.glue_7)

         *(.glue_7t)

         _text_end = .;

     } >sdram

     .data :

     {

         _data = .;

         *(.data)

         _data_end = .;

     } >sdram

     .bss : /* collect all uninitialized .bss sections that go into RAM */

     {

         _bss_start = .;

         *(.bss)

     } >sdram

     . = ALIGN(4);

     _bss_end = . ;

}

 

 

 

 

  Makefile

 

 

 

GNUARM = c:/sdk4arm/gat/garm/bin/

NAME = gatest00

CC = $(GNUARM)arm-elf-gcc

LD = $(GNUARM)arm-elf-ld -v

AR = $(GNUARM)arm-elf-ar

AS = $(GNUARM)arm-elf-as

CP = $(GNUARM)arm-elf-objcopy

OD = $(GNUARM)arm-elf-objdump

 

CFLAGS = -I . -I c:/sdk4arm/gat/garm/arm-elf/

                  include -c -fno-common -O0 -g

AFLAGS = -ahls -mapcs-32

LFLAGS = -Map $(NAME).map -T$(NAME).ld

CPFLAGS = --output-target=binary

ODFLAGS = -x --syms -D

 

 

all: $(NAME).bin

 

clean:

     -rm *.lst *.o *.out *.bin *.map *.lst

 

 

$(NAME).bin: $(NAME).out

     @ echo "...copying"

     $(CP) $(CPFLAGS) $< $@

     $(OD) $(ODFLAGS) $< > $(NAME).lst

 

$(NAME).out: crt.o serial.o $(NAME).o

     @ echo "..linking"

     $(LD) $(LFLAGS) -o $@ $^

%.o: %.s

     @ echo ".assembling"

     $(AS) $(AFLAGS) -o $@ $< > $%.lst

%.o: %.c

     @ echo ".compiling"

     $(CC) $(CFLAGS) -o $@ $<

 

 

 

ARM9 C Programs : gatest01

 

 

 

 

這個測試程式, ARM會透過Wishbone讀取wbios.v所連接的DIP Switch之值,並將此值做位移後,再透過Wishbone寫至wbios.v所連接的LED

 

 

    gatest01.c

 

 

 

 

#include <stdio.h>

#include <serial.h>

 

void delayms(unsigned int ms)

{

     unsigned int i,j;

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

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

         { asm("nop"); }

 

}

 

int main()

{

     int i,dpsw;

     void (*prst)(void)=0;

 

     serial_puts (" LED tests !!! \n");

 

     do

     {

         dpsw=*(volatile unsigned int*)0x10000004;

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

         {

              *(volatile unsigned int*)0x10000000=((dpsw<<i)>>8);

              delayms(100);

              serial_puts ("*");

         }

         serial_puts ("\n");

     } while(!serial_tstc());

 

     serial_getc();

 

     (*prst)();    // reset

 

     return 0;

}

 

 

 

  serial.c / serial.h / crt.hcode內容和gatest00共用

 

  gatest01.ld

 

 

 

ENTRY(_start)

 

 

MEMORY

{

     flash : ORIGIN = 0, LENGTH = 256K

     ram : ORIGIN = 0x40000000, LENGTH = 4K

     sdram : ORIGIN = 0x30000000, LENGTH = 32*1024K

}

 

_stack_end = 0x30100000;

 

SECTIONS

{

     . = 0x30000000;

     .text :

     {

         *(.init)

         *(.text)

         *(.rodata)

         *(.glue_7)

         *(.glue_7t)

         _text_end = .;

     } >sdram

     .data :

     {

         _data = .;

         *(.data)

         _data_end = .;

     } >sdram

     .bss : /* collect all uninitialized .bss sections that go into RAM */

     {

         _bss_start = .;

         *(.bss)

     } >sdram

     . = ALIGN(4);

     _bss_end = . ;

}

 

 

 

 

  Makefile

 

 

 

GNUARM = c:/sdk4arm/gat/garm/bin/

NAME = gatest01

CC = $(GNUARM)arm-elf-gcc

LD = $(GNUARM)arm-elf-ld -v

AR = $(GNUARM)arm-elf-ar

AS = $(GNUARM)arm-elf-as

CP = $(GNUARM)arm-elf-objcopy

OD = $(GNUARM)arm-elf-objdump

 

CFLAGS = -I . -I c:/sdk4arm/gat/garm/arm-elf/

                         include -c -fno-common -O0 -g

AFLAGS = -ahls -mapcs-32

LFLAGS = -Map $(NAME).map -T$(NAME).ld

CPFLAGS = --output-target=binary

ODFLAGS = -x --syms -D

 

 

all: $(NAME).bin

 

clean:

     -rm *.lst *.o *.out *.bin *.map *.lst

 

 

$(NAME).bin: $(NAME).out

     @ echo "...copying"

     $(CP) $(CPFLAGS) $< $@

     $(OD) $(ODFLAGS) $< > $(NAME).lst

 

$(NAME).out: crt.o serial.o $(NAME).o

     @ echo "..linking"

     $(LD) $(LFLAGS) -o $@ $^

%.o: %.s

     @ echo ".assembling"

     $(AS) $(AFLAGS) -o $@ $< > $%.lst

%.o: %.c

     @ echo ".compiling"

     $(CC) $(CFLAGS) -o $@ $<

 

 

 

 

Setup & Verification

 


 

 

 

 

 

 

 

 

 

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

ZEPPE

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