diff --git a/README.md b/README.md new file mode 100644 index 0000000..68e5e7f --- /dev/null +++ b/README.md @@ -0,0 +1,4 @@ +AEMB 32-bit Microprocessor Core. +=============================== + +Smallest and fastest processor it its class! diff --git a/sim/Makefile b/sim/Makefile new file mode 100644 index 0000000..9d5b2ff --- /dev/null +++ b/sim/Makefile @@ -0,0 +1,28 @@ +# Copyright (C) 2011 Aeste Works (M) Sdn Bhd. + +TMP := $(shell mktemp -d)/v +DMP := $(shell hostname)-$(shell date -I) +RND := $(shell od -d -N2 -vAn /dev/urandom) + +VER = $(wildcard verilog/*.v) + +LIB = -y ../rtl/verilog +LOG = $(DMP).log +VCD = $(DMP).vcd + +edk63: edk63.v vvp clean + +edk63.v: + iverilog $(LIB) -tnull -M$(TMP).ls verilog/edk63.v + uniq $(TMP).ls | sed 1d > $(TMP).fs + iverilog -c$(TMP).fs -E -tnull -o $(TMP).v verilog/edk63.v + +vvp: + iverilog -Wall -o $(TMP).vvp $(TMP).v + time -p vvp -l $(LOG) $(TMP).vvp +randseed=$(RND) +dumpfile=$(VCD) + +clean: + rm -rf $(TMP)* + +clear: + rm -f *.log diff --git a/sim/iversim b/sim/iversim index 2c7bbe8..e78937b 100755 --- a/sim/iversim +++ b/sim/iversim @@ -1,10 +1,11 @@ -#!/bin/sh +#!/bin/bash # Copyright (C) 2008-2011 Aeste Works (M) Sdn Bhd. -HERE=$(dirname $0) -SIM="/tmp/isim" -IVERLIB="-y$HERE/../rtl/verilog" RANDOM=$$ +HERE="$(dirname $0)" +SIM="$(mktemp -d)/sim" +DUMP="$(hostname)-$$" +IVERLIB="-y$HERE/../rtl/verilog" # pre-processor iverilog $IVERLIB -tnull -M$SIM.ls $@ && \ @@ -14,8 +15,7 @@ iverilog -c$SIM.fs -E -tnull -o $SIM.v $@ && \ # simulation if [ -e "$SIM.v" ]; then iverilog -Wall -o $SIM.vvp $SIM.v && \ - $SIM.vvp +randseed=$RANDOM && \ - rm $SIM.vvp + $SIM.vvp +randseed=$RANDOM +dumpfile=$DUMP fi # recompress @@ -23,5 +23,3 @@ if [ -e "dump.vcd" ]; then vcd2lxt dump.vcd dump.lxt -stats && \ rm dump.vcd fi - -echo "DONE" diff --git a/sim/verilog/edk63.v b/sim/verilog/edk63.v index fd5f982..bce3750 100644 --- a/sim/verilog/edk63.v +++ b/sim/verilog/edk63.v @@ -130,10 +130,6 @@ module edk63(); always @(posedge sys_clk_i) begin - // FAUX timer implementation - triggers every 32k counts (e.g. 1s on RTC) - timer0 <= timer0 + 1; - if (timer0 % 32768 == 0) sys_int_i <= 1'b1; - iadr <= #1 iwb_adr_o; dadr <= #1 dwb_adr_o; @@ -144,9 +140,10 @@ module edk63(); // SPECIAL PORTS if (dwb_wre_o & dwb_stb_o & dwb_ack_i) begin case ({dwb_adr_o,2'o0}) - 32'hFFFFFFD0: $displayh(dwb_dat_o); - 32'hFFFFFFC0: $write("%c",dwb_dat_o[31:24]); - 32'hFFFFFFE0: sys_int_i <= #1 !sys_int_i; + 32'hFFFFFFD0: $displayh(dwb_dat_o); // display data + 32'hFFFFFFC0: $write("%c",dwb_dat_o[31:24]); // stdout output + 32'hFFFFFFE0: sys_int_i <= #1 !sys_int_i; // acknowledge interrupt. + 32'hFFFFFFF0: timer0 <= dwb_dat_o; // write to Timer0 endcase // case ({dwb_adr_o,2'o0}) case (dwb_sel_o) @@ -163,7 +160,13 @@ module edk63(); end endcase // case (dwb_sel_o) end // if (dwb_wre_o & dwb_stb_o & dwb_ack_i) + else begin + // FAUX timer implementation - triggers every 32k counts (e.g. 1s on RTC) + timer0 <= timer0 + 1; + if (timer0 % 32768 == 0) sys_int_i <= 1'b1; + end + if (dwb_stb_o & !dwb_wre_o) begin case (dwb_sel_o) 4'h1,4'h2,4'h4,4'h8,4'h3,4'hC,4'hF: begin diff --git a/sw/Makefile b/sw/Makefile new file mode 100644 index 0000000..a348c13 --- /dev/null +++ b/sw/Makefile @@ -0,0 +1,32 @@ +# +# Makefile for AEMB Software +# + +CC = mb-g++ +LFLAGS = -Wl,-defsym -Wl,_STACK_SIZE=0x2000 -Wl,-defsym -Wl,_HEAP_SIZE=0x2000 +CFLAGS = -mtune=v5.00 -mxl-soft-div -msoft-float -mxl-barrel-shift -mno-xl-soft-mul -g +IFLAGS = -I cc/ +OFLAGS = -Os + +OBJDUMP = mb-objdump +OBJCOPY = mb-objcopy + +testbench: testbench.cc sim + @echo "DONE" + +uxe: uxe.cc sim + @echo "DONE" + +testbench.cc: cc/testbench.cc + $(CC) $(CFLAGS) $(IFLAGS) $(LFLAGS) $(OFLAGS) -specs=aemb.specs -o rom.elf cc/testbench.cc + +uxe.cc: cc/uxe.cc + $(CC) $(CFLAGS) $(IFLAGS) $(LFLAGS) $(OFLAGS) -specs=aemb.specs -o rom.elf cc/uxe.cc + +sim: + $(OBJDUMP) -DSCz rom.elf > rom.dump + $(OBJCOPY) -O srec rom.elf rom.srec + srec_cat rom.srec -fill 0xAE -within rom.srec -range-pad 4 -o ../sim/dump.vmem -vmem 32 + +clean: + rm *.dump *.srec *.elf diff --git a/sw/cc/corefunc.hh b/sw/cc/corefunc.hh index 5762823..a0250d7 100644 --- a/sw/cc/corefunc.hh +++ b/sw/cc/corefunc.hh @@ -89,6 +89,7 @@ INTERRUPT TEST ROUTINE int interruptTest(int timeout) { + setTimer0(0); // reset TMR0 aembEnableInterrupts(); for (int timer=0; (timer < timeout * 100); ++timer) asm volatile ("nop"); // delay loop diff --git a/sw/cc/simboard.hh b/sw/cc/simboard.hh index 1d170f6..dc14096 100644 --- a/sw/cc/simboard.hh +++ b/sw/cc/simboard.hh @@ -53,6 +53,12 @@ inline int getTimer0() return *TMR0; } +inline int setTimer0(int timer) +{ + volatile int *TMR0 = (int *) 0xFFFFFFF0; + *TMR0 = timer; +} + #ifdef __cplusplus } #endif diff --git a/sw/cc/testbench.cc b/sw/cc/testbench.cc index 8517dcd..34ba074 100644 --- a/sw/cc/testbench.cc +++ b/sw/cc/testbench.cc @@ -38,15 +38,16 @@ AEMB. It can be compiled by the GCC compiler. void checkcode(int code) { if (code == EXIT_SUCCESS) - iprintf("\t\t-PASS-\n"); + puts("\t[PASS]"); else - iprintf("\t\t*FAIL*\n"); + puts("\t[FAIL]"); } void printtest(char *msg) { static int count = 1; - iprintf("\t%d. %s\n",count++, msg); + //iprintf("\t%d. %s\n",count++, msg); + fputs(msg, stdout); } void numtests() @@ -60,7 +61,7 @@ void numtests() checkcode(euclideanTest(MAX_TEST)); // *** 3. NEWTON-RHAPSON *** - printtest("Floating Point Arithmetic"); + printtest("Floating Point"); checkcode(newtonTest(MAX_TEST)); } @@ -87,7 +88,8 @@ void coretests() // run tests int main() { - iprintf("AEMB2 32-bit Microprocessor Core Tests\n"); + puts("AEMB2 32-bit Microprocessor Core Tests"); + //iprintf("Timer0\t: %d\n",getTimer0()); numtests(); coretests(); diff --git a/sw/cc/uxe.cc b/sw/cc/uxe.cc new file mode 100644 index 0000000..b7ad40a --- /dev/null +++ b/sw/cc/uxe.cc @@ -0,0 +1,79 @@ +/* +** AEMB Micro Execution Environment +** Copyright (C) 2011 Aeste Works (M) S/B. +** +** This file is part of AEMB. +** +** AEMB is free software: you can redistribute it and/or modify it +** under the terms of the GNU General Public License as published by +** the Free Software Foundation, either version 3 of the License, or +** (at your option) any later version. +** +** AEMB is distributed in the hope that it will be useful, but WITHOUT +** ANY WARRANTY; without even the implied warranty of MERCHANTABILITY +** or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public +** License for more details. +** +** You should have received a copy of the GNU General Public License +** along with AEMB. If not, see . +*/ + +/** + AEMB Early Boot-Loader + @file uxe.cc + +*/ + +#define BOOT_BASE 0x00020000 ///< Base address of the kernel + +#define SRAM_BASE 0x00001000 ///< Base address of RAM block +#define SRAM_SIZE 0x00010000 ///< Size of RAM block + +#include "aemb/core.hh" + +typedef void (boot_addr)(void); + +// Replacements for STDIO + +void uxe_putc(char c) +{ + volatile char *COUT = (char *) 0xFFFFFFC0; + *COUT = c; +} + +void uxe_putw(char * msg) +{ + for (char *c = msg; *c != 0; c++) uxe_putc(*c); +} + +void uxe_puts(char * msg) +{ + uxe_putw(msg); + uxe_putc('\n'); +} + + +// Main execution environment. + +int main () +{ + // Welcome banner + uxe_puts("Micro Execution Environment 11.07"); + uxe_puts("Copyright (C) 2011 Aeste Works (M) S/B."); + //uxe_puts("\nThis program comes with ABSOLUTELY NO WARRANTY;\nThis is free software, and you are welcome to redistribute it under certain conditions;\nFor more details, see the GPL3.txt file included.\n"); + + // Load kernel image (SD/MMC) + + // Print kernel base address (only works with 0-9) + uxe_putw("Boot @"); + for (unsigned int i = 0, k = BOOT_BASE; i < 8; ++i, k <<= 4) { + uxe_putc( (k >> 28) + 0x30 ); + } + uxe_putc('\n'); + + // Jump to next stage + ((boot_addr*) BOOT_BASE)(); + + // This should *NEVER* execute. + return -1; +}