Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
78b2eb28cb |
@@ -68,13 +68,19 @@ proc_reg_write:
|
||||
reg_cmem_high <= (others => '0');
|
||||
reg_bank_sel <= (others => '0');
|
||||
reg_int_ctrl.enable <= '0';
|
||||
reg_int_ctrl.polarity <= '1';
|
||||
reg_int_ctrl.edge_sens <= '1';
|
||||
elsif rising_edge(clk) then
|
||||
reg_int_ctrl.request <= '0';
|
||||
if we = '1' then
|
||||
case addr is
|
||||
when X"01" =>
|
||||
reg_bank_sel(bank_sel_t'range) <= din(bank_sel_t'range);
|
||||
when X"03" =>
|
||||
reg_int_ctrl.enable <= din(0);
|
||||
reg_int_ctrl.polarity <= din(1);
|
||||
reg_int_ctrl.edge_sens <= din(2);
|
||||
reg_int_ctrl.request <= din(7);
|
||||
when X"04" =>
|
||||
reg_cmem_high <= din(IMEM_ADDR_WIDTH-DMEM_ADDR_WIDTH-1 downto 0);
|
||||
when X"05" =>
|
||||
@@ -97,7 +103,7 @@ proc_reg_read:
|
||||
when X"02" => -- CPU status
|
||||
dout <= "000000" & ctrl_in.alu.carry & ctrl_in.alu.zero;
|
||||
when X"03" => -- Interrupt control
|
||||
dout <= "0000000" & reg_int_ctrl.enable;
|
||||
dout <= "00000" & reg_int_ctrl.edge_sens & reg_int_ctrl.polarity & reg_int_ctrl.enable;
|
||||
when X"04" => -- Upper stack bits out
|
||||
dout <= "0000" & reg_cmem_high;
|
||||
when X"05" => -- Upper cmem bits out
|
||||
|
||||
@@ -39,6 +39,7 @@ entity cpu is
|
||||
ce : in STD_LOGIC;
|
||||
int_in : in STD_LOGIC;
|
||||
int_ack : out STD_LOGIC;
|
||||
xmem_wait : in STD_LOGIC;
|
||||
xmem_we : out STD_LOGIC;
|
||||
xmem_re : out STD_LOGIC;
|
||||
instr_din : in unsigned (IMEM_DATA_WIDTH-1 downto 0);
|
||||
@@ -214,6 +215,7 @@ begin
|
||||
pc_inc <= cpu_active and ctrl.lines.pc_inc;
|
||||
stk_addr <= '0' & stk_ptr;
|
||||
cpu_status.alu <= alu_status;
|
||||
cpu_status.xmem_wait <= xmem_wait;
|
||||
creg_ctrl_in.alu <= alu_status;
|
||||
|
||||
xmem_dout <= mem_data;
|
||||
|
||||
@@ -49,7 +49,7 @@ package cpu_pkg is
|
||||
constant IMEM_DATA_WIDTH : integer := INST_OPCODE_WIDTH + DMEM_DATA_WIDTH + REG_SIZE_BITS;
|
||||
|
||||
-- Microcode ROM
|
||||
constant MUCODE_ADDR_WIDTH : integer := 9;
|
||||
constant MUCODE_ADDR_WIDTH : integer := 10;
|
||||
|
||||
-- Stack depth (uses lower half of CHIPRAM)
|
||||
constant STACK_SIZE_BITS : integer := CHIPRAM_SIZE_BITS-1;
|
||||
@@ -100,6 +100,7 @@ package cpu_pkg is
|
||||
|
||||
type cpu_status_t is record
|
||||
alu : alu_status_t;
|
||||
xmem_wait : STD_LOGIC;
|
||||
end record;
|
||||
|
||||
type ctrl_lines_t is record
|
||||
@@ -132,6 +133,9 @@ package cpu_pkg is
|
||||
|
||||
type int_ctrl_in_t is record
|
||||
enable : std_logic;
|
||||
polarity : std_logic;
|
||||
edge_sens : std_logic;
|
||||
request : std_logic;
|
||||
end record;
|
||||
|
||||
type creg_ctrl_out_t is record
|
||||
@@ -330,11 +334,12 @@ package body cpu_pkg is
|
||||
|
||||
function idecoder(instr_name : instr_name_t; iphase : iphase_t; status : cpu_status_t) return ctrl_lines_t is
|
||||
variable result : ctrl_lines_t;
|
||||
variable ze, cy : STD_LOGIC;
|
||||
variable ze, cy, xmem_wait : STD_LOGIC;
|
||||
|
||||
begin
|
||||
ze := status.alu.zero;
|
||||
cy := status.alu.carry;
|
||||
xmem_wait := status.xmem_wait;
|
||||
|
||||
result := ctrl_lines_default;
|
||||
if iphase = 0 then
|
||||
@@ -430,6 +435,10 @@ package body cpu_pkg is
|
||||
if iphase = 0 then
|
||||
result.mem_write := '1';
|
||||
end if;
|
||||
if xmem_wait = '1' then
|
||||
result.mem_write := '1';
|
||||
result.pc_inc := '0';
|
||||
end if;
|
||||
when "MOVX|Ri|K " => -- [R(a)] <= kk
|
||||
result.mem_access := xmem_access;
|
||||
result.daddr_src_sel := reg_a;
|
||||
@@ -437,6 +446,10 @@ package body cpu_pkg is
|
||||
if iphase = 0 then
|
||||
result.mem_write := '1';
|
||||
end if;
|
||||
if xmem_wait = '1' then
|
||||
result.mem_write := '1';
|
||||
result.pc_inc := '0';
|
||||
end if;
|
||||
when "XOUT|Ri|K " => -- [R(a)] <= kk
|
||||
result.mem_access := xio_access;
|
||||
result.daddr_src_sel := reg_a;
|
||||
@@ -444,33 +457,55 @@ package body cpu_pkg is
|
||||
if iphase = 0 then
|
||||
result.mem_write := '1';
|
||||
end if;
|
||||
if xmem_wait = '1' then
|
||||
result.pc_inc := '0';
|
||||
result.mem_write := '1';
|
||||
end if;
|
||||
when "MOVX|R|Ri " => -- R(a) <= [R(b)]
|
||||
result.mem_access := xmem_access;
|
||||
result.reg_src_sel := xmem_src;
|
||||
result.daddr_src_sel := reg_b;
|
||||
if iphase = 0 then
|
||||
result.mem_read := '1';
|
||||
elsif iphase = 1 then
|
||||
end if;
|
||||
if xmem_wait = '0' then
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
else
|
||||
result.pc_inc := '0';
|
||||
result.mem_read := '1';
|
||||
end if;
|
||||
when "MOVX|R|Ki " => -- R(a) <= [#addr]
|
||||
result.mem_access := xmem_access;
|
||||
result.reg_src_sel := xmem_src;
|
||||
result.daddr_src_sel := const;
|
||||
if iphase = 0 then
|
||||
result.mem_read := '1';
|
||||
elsif iphase = 1 then
|
||||
end if;
|
||||
if xmem_wait = '0' then
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
else
|
||||
result.pc_inc := '0';
|
||||
result.mem_read := '1';
|
||||
end if;
|
||||
when "XIN|R|Ki " => -- R(a) <= [#addr]
|
||||
result.mem_access := xio_access;
|
||||
result.reg_src_sel := xmem_src;
|
||||
result.daddr_src_sel := const;
|
||||
if iphase = 0 then
|
||||
result.mem_read := '1';
|
||||
elsif iphase = 1 then
|
||||
end if;
|
||||
if xmem_wait = '0' then
|
||||
if iphase = 1 then
|
||||
result.reg_we := '1';
|
||||
end if;
|
||||
else
|
||||
result.pc_inc := '0';
|
||||
result.mem_read := '1';
|
||||
end if;
|
||||
when "MOVX|Ki|R " => -- [#addr] <= R(a)
|
||||
result.mem_access := xmem_access;
|
||||
result.daddr_src_sel := const;
|
||||
@@ -478,6 +513,10 @@ package body cpu_pkg is
|
||||
if iphase = 0 then
|
||||
result.mem_write := '1';
|
||||
end if;
|
||||
if xmem_wait = '1' then
|
||||
result.pc_inc := '0';
|
||||
result.mem_write := '1';
|
||||
end if;
|
||||
when "XOUT|Ki|R " => -- [#addr] <= R(a)
|
||||
result.mem_access := xio_access;
|
||||
result.daddr_src_sel := const;
|
||||
@@ -485,6 +524,10 @@ package body cpu_pkg is
|
||||
if iphase = 0 then
|
||||
result.mem_write := '1';
|
||||
end if;
|
||||
if xmem_wait = '1' then
|
||||
result.pc_inc := '0';
|
||||
result.mem_write := '1';
|
||||
end if;
|
||||
when "ADD|R|R " => -- R(a) <= R(a) + R(b)
|
||||
result.alu_opsel := op1_add_op2;
|
||||
result.alu_op1_src_sel := reg_a;
|
||||
@@ -812,6 +855,8 @@ package body cpu_pkg is
|
||||
status.alu.zero := addr(pos);
|
||||
pos := pos + 1;
|
||||
status.alu.carry := addr(pos);
|
||||
pos := pos + 1;
|
||||
status.xmem_wait := addr(pos);
|
||||
|
||||
result(i) := idecoder(opcode, iphase, status);
|
||||
end loop;
|
||||
@@ -822,7 +867,7 @@ package body cpu_pkg is
|
||||
function get_muromaddr (opcode : opcode_t; iphase : iphase_t; status : cpu_status_t) return unsigned is
|
||||
variable addr : unsigned(MUCODE_ADDR_WIDTH-1 downto 0);
|
||||
begin
|
||||
addr := status.alu.carry & status.alu.zero & to_unsigned(iphase, 1) & opcode;
|
||||
addr := status.xmem_wait & status.alu.carry & status.alu.zero & to_unsigned(iphase, 1) & opcode;
|
||||
return addr;
|
||||
|
||||
end get_muromaddr;
|
||||
|
||||
@@ -48,11 +48,13 @@ end int_ctrl;
|
||||
architecture Behavioral of int_ctrl is
|
||||
|
||||
type int_state_t is (int_idle, int_inject, int_active, int_release);
|
||||
type pin_state_t is (pin_s0, pin_s1, pin_s2);
|
||||
|
||||
signal int_state, int_state_next : int_state_t;
|
||||
signal pin_state, pin_state_next : pin_state_t;
|
||||
signal pc_load, int_ack, stk_push, stk_pop : STD_LOGIC;
|
||||
signal int_request : std_logic;
|
||||
|
||||
signal int_sampled : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
@@ -72,6 +74,7 @@ irg_ctrl_fsm:
|
||||
pc_load <= '0';
|
||||
stk_push <= '0';
|
||||
stk_pop <= '0';
|
||||
|
||||
case int_state is
|
||||
|
||||
when int_idle =>
|
||||
@@ -118,10 +121,46 @@ pin_sample:
|
||||
process (clk)
|
||||
begin
|
||||
if rising_edge(clk) then
|
||||
int_request <= '0';
|
||||
if ctrl_in.enable = '1' then
|
||||
int_request <= int_in;
|
||||
end if;
|
||||
int_sampled <= int_in xor (not ctrl_in.polarity);
|
||||
end if;
|
||||
end process;
|
||||
|
||||
-----------------------------------------------------------------------
|
||||
pin_fsm:
|
||||
process (pin_state, int_sampled, int_ack, ctrl_in)
|
||||
begin
|
||||
int_request <= '0';
|
||||
pin_state_next <= pin_state;
|
||||
case pin_state is
|
||||
when pin_s0 =>
|
||||
if int_sampled = '1' or ctrl_in.request = '1' then
|
||||
if ctrl_in.enable = '1' then
|
||||
pin_state_next <= pin_s1;
|
||||
end if;
|
||||
end if;
|
||||
when pin_s1 =>
|
||||
int_request <= '1';
|
||||
if int_ack = '1' then
|
||||
pin_state_next <= pin_s2;
|
||||
end if;
|
||||
when pin_s2 =>
|
||||
if ctrl_in.edge_sens = '0' then
|
||||
pin_state_next <= pin_s0;
|
||||
elsif int_sampled = '0' then
|
||||
pin_state_next <= pin_s0;
|
||||
end if;
|
||||
when others =>
|
||||
pin_state_next <= pin_s0;
|
||||
end case;
|
||||
end process;
|
||||
|
||||
pin_states:
|
||||
process (rst, clk, pin_state_next)
|
||||
begin
|
||||
if rst = '1' then
|
||||
pin_state <= pin_s0;
|
||||
elsif rising_edge(clk) then
|
||||
pin_state <= pin_state_next;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
TOOLS_DIR=../../tools
|
||||
|
||||
CFLAGS=-msoft-float -O2 -march=r3000 -I.
|
||||
LFLAGS=-M -T link.ld
|
||||
LIB_DIRS=-L . -L $(MIPS_TOOLS_PREFIX)/mipsel-elf/lib -L $(MIPS_TOOLS_PREFIX)/lib/gcc/mipsel-elf/$(MIPS_GCC_VER)
|
||||
LIB_DIRS=-L . -L /usr/local/mipsel-elf/lib -L /usr/local/lib/gcc/mipsel-elf/4.3.2
|
||||
LIBS=-lc -lm -lgcc
|
||||
|
||||
AS=mipsel-elf-as
|
||||
@@ -9,9 +11,9 @@ CC=mipsel-elf-gcc
|
||||
LD=mipsel-elf-ld
|
||||
OBJDUMP=mipsel-elf-objdump
|
||||
OBJCOPY=mipsel-elf-objcopy
|
||||
FLASHGEN=flashgen_el
|
||||
FLASHGEN=$(TOOLS_DIR)/flashgen_little
|
||||
|
||||
PROG = hello testbench test_irq dhry queens stanford paranoia rmd160_test Bessel whet phrasen dttl richards_benchmark test_exception
|
||||
PROG = hello testbench test_irq dhry queens stanford paranoia rmd160_test Bessel whet phrasen dttl richards_benchmark
|
||||
|
||||
all: $(PROG)
|
||||
|
||||
@@ -23,7 +25,7 @@ libsys: startup.S init.S kernel.S libsys.c xcpt.c irq.c
|
||||
$(CC) $(CFLAGS) -G 0 -c xcpt.c -o xcpt.o
|
||||
$(CC) $(CFLAGS) -G 0 -c irq.c -o irq.o
|
||||
$(AR) -r libsys.a init.o libsys.o xcpt.o irq.o
|
||||
|
||||
|
||||
hello: hello.c
|
||||
$(CC) $(CFLAGS) -c hello.c
|
||||
$(LD) $(LFLAGS) $(LIB_DIRS) hello.o -o $@.elf $(LIBS) >$@.map
|
||||
@@ -128,13 +130,5 @@ richards_benchmark: richards_benchmark.c
|
||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
||||
$(FLASHGEN) $@.bin
|
||||
|
||||
test_exception: test_exception.c
|
||||
$(CC) $(CFLAGS) -O1 -c test_exception.c
|
||||
$(LD) $(LFLAGS) $(LIB_DIRS) test_exception.o -o $@.elf $(LIBS) >$@.map
|
||||
$(OBJDUMP) -d $@.elf > $@.dis
|
||||
$(OBJCOPY) $@.elf -O binary $@.bin
|
||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
||||
$(FLASHGEN) $@.bin
|
||||
|
||||
clean:
|
||||
rm -rf *.a *.o *.bin *.map *.dis *.srec *.elf $(PROG) > /dev/null
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
ROM_WORDADDR_WIDTH=11
|
||||
TOOLS_DIR=../../../tools
|
||||
|
||||
CFLAGS=-Os -I. -I../ -msoft-float -march=r3000
|
||||
LFLAGS=-M -T bootloader.ld
|
||||
LIB_DIRS=-L $(MIPS_TOOLS_PREFIX)/mipsel-elf/lib -L $(MIPS_TOOLS_PREFIX)/lib/gcc/mipsel-elf/$(MIPS_GCC_VER)
|
||||
LIB_DIRS=-L /usr/local/mipsel-elf/lib -L /usr/local/lib/gcc/mipsel-elf/4.3.2
|
||||
LIBS=-lc -lgcc
|
||||
|
||||
CC=mipsel-elf-gcc
|
||||
@@ -24,7 +25,7 @@ bootloader: libsys bootloader.c
|
||||
$(OBJDUMP) -d bootloader.elf > bootloader.dis
|
||||
$(OBJCOPY) bootloader.elf -O binary bootloader.ROM.bin
|
||||
$(OBJCOPY) -O srec bootloader.elf bootloader.srec
|
||||
romgen bootloader.ROM.bin 10
|
||||
$(TOOLS_DIR)/romgen bootloader.ROM.bin 10
|
||||
|
||||
bootloader_flash: libsys bootloader_with_flash.c
|
||||
$(CC) $(CFLAGS) -g -c bootloader_with_flash.c
|
||||
@@ -33,7 +34,7 @@ bootloader_flash: libsys bootloader_with_flash.c
|
||||
$(OBJDUMP) -d bootloader.elf > bootloader.dis
|
||||
$(OBJCOPY) bootloader.elf -O binary bootloader.ROM.bin
|
||||
$(OBJCOPY) -O srec bootloader.elf bootloader.srec
|
||||
romgen bootloader.ROM.bin 11
|
||||
$(TOOLS_DIR)/romgen bootloader.ROM.bin 11
|
||||
|
||||
clean:
|
||||
rm -rf *.o *.bin *.map *.dis *.srec *.elf *.vhd* *.tcl bootloader > /dev/null
|
||||
|
||||
@@ -15,7 +15,7 @@ _init:
|
||||
|
||||
# set stack pointer
|
||||
la $sp, stack_ptr
|
||||
j $jmain
|
||||
# j $jmain
|
||||
|
||||
# TEST
|
||||
li $26, +5
|
||||
|
||||
@@ -13,7 +13,6 @@ int main (void)
|
||||
|
||||
*pGPIO0 = 0xAAAAAAAA;
|
||||
*pGPIO1 = 0xAAAAAAAA;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@@ -34,14 +34,12 @@ $zeroise:
|
||||
# addiu $8, 4
|
||||
|
||||
# jump main
|
||||
la $t0, main
|
||||
jalr $t0
|
||||
nop
|
||||
la $8, main
|
||||
jalr $8
|
||||
|
||||
_terminate:
|
||||
_terminate:
|
||||
nop
|
||||
j _terminate
|
||||
nop
|
||||
la $t0, exit
|
||||
jalr $t0
|
||||
move $a0, $v0
|
||||
|
||||
.set reorder
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
#include <sys/resource.h>
|
||||
#include <sys/stat.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "libsys.h"
|
||||
|
||||
@@ -151,8 +150,9 @@ void _cg_putchar(char c)
|
||||
|
||||
void _exit (int exitcode)
|
||||
{
|
||||
fflush(stdout);
|
||||
fflush(stderr);
|
||||
sputs("_exit(");
|
||||
print_word(exitcode);
|
||||
sputs(")\n");
|
||||
while(1);
|
||||
}
|
||||
|
||||
@@ -239,31 +239,29 @@ int settimeofday(const struct timeval *tp, const struct timezone *tzp)
|
||||
caddr_t sbrk(int incr)
|
||||
{
|
||||
extern char end;
|
||||
extern char stack_ptr;
|
||||
static char *heap_end;
|
||||
char *prev_heap_end;
|
||||
|
||||
if (heap_end == 0)
|
||||
{
|
||||
heap_end = &end;
|
||||
}
|
||||
|
||||
prev_heap_end = heap_end;
|
||||
if (heap_end + incr > &stack_ptr)
|
||||
{
|
||||
// sputs("Heap and stack collision\n");
|
||||
// sputs("Stack Ptr = ");print_word(&stack_ptr);sputs("\n");
|
||||
// sputs("Heap end = ");print_word(heap_end);sputs("\n");
|
||||
// sputs("Increment = ");print_word(incr);sputs("\n");
|
||||
exit(1);
|
||||
}
|
||||
// if (heap_end + incr > stack_ptr)
|
||||
// {
|
||||
// sputs("Heap and stack collision\r\n");
|
||||
// abort();
|
||||
// }
|
||||
|
||||
// sputs("\n");
|
||||
// print_word((int)prev_heap_end);
|
||||
// sputs("\n");
|
||||
heap_end += incr;
|
||||
return (caddr_t) prev_heap_end;
|
||||
}
|
||||
|
||||
int fstat(int file, struct stat *st)
|
||||
{
|
||||
// sputs("fstat\n");
|
||||
// sputs("Fstat()\n");
|
||||
st->st_mode = S_IFCHR;
|
||||
st->st_blksize = 0;
|
||||
return 0;
|
||||
@@ -271,49 +269,41 @@ int fstat(int file, struct stat *st)
|
||||
|
||||
int lseek(int file, int ptr, int dir)
|
||||
{
|
||||
// sputs("lseek\n");
|
||||
sputs("Lseek()\n");
|
||||
|
||||
errno = ESPIPE;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int open(const char *name, int flags, int mode)
|
||||
{
|
||||
// sputs("open\n");
|
||||
sputs("Open()\n");
|
||||
errno = EIO;
|
||||
return -1;
|
||||
}
|
||||
|
||||
int close(int file)
|
||||
{
|
||||
// sputs("close\n");
|
||||
sputs("Close()\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int read(int file, char *ptr, int len)
|
||||
{
|
||||
int i;
|
||||
char c;
|
||||
|
||||
// sputs("read\n");
|
||||
i = 0;
|
||||
while (i < len)
|
||||
// sputs("Read()\n");
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
c = readchar();
|
||||
if ((c == 0x0D) || (c == 0x0A))
|
||||
ptr[i] = readchar();
|
||||
if ((ptr[i] == '\n') || (ptr[i] == '\r'))
|
||||
{
|
||||
i++;
|
||||
writechar(0x0D);
|
||||
writechar(0x0A);
|
||||
if (i==0)
|
||||
continue;
|
||||
|
||||
ptr[i++] = c;
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
ptr[i++] = c;
|
||||
writechar(c);
|
||||
}
|
||||
writechar(ptr[i]);
|
||||
}
|
||||
return i;
|
||||
}
|
||||
|
||||
@@ -51,12 +51,8 @@
|
||||
//#define STDOUT_FUNCTION _cg_putchar // Video character
|
||||
//#define STDERR_FUNCTION _putchar // Serial output
|
||||
|
||||
#ifndef STDOUT_FUNCTION
|
||||
#define STDOUT_FUNCTION _putchar // Serial output
|
||||
#endif
|
||||
#ifndef STDERR_FUNCTION
|
||||
#define STDERR_FUNCTION _putchar // Serial output
|
||||
#endif
|
||||
|
||||
UINT32 CP0_SR_read(void);
|
||||
void CP0_SR_write(UINT32 val);
|
||||
|
||||
@@ -1,232 +0,0 @@
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include "libsys.h"
|
||||
|
||||
void _exc_break(void)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
"break 0x123\n"
|
||||
".set reorder\n"
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
void _exc_syscall(void)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
"syscall\n"
|
||||
".set reorder\n"
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
void _exc_arith(void)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
" li $t0, 0x7FFFFFFF\n"
|
||||
" addi $t1, $t0, 2\n"
|
||||
".set reorder\n"
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
void _exc_store_err(void)
|
||||
{
|
||||
volatile int *pSrc = (int*)sys_timer_sec;
|
||||
volatile int *pDst = (int*)0x40000001;
|
||||
|
||||
*pDst = *pSrc;
|
||||
|
||||
}
|
||||
|
||||
void _exc_load_err(void)
|
||||
{
|
||||
volatile int *pSrc = (int*)0x40000002;
|
||||
volatile int *pDst = (int*)sys_led_port;
|
||||
|
||||
*pDst = *pSrc;
|
||||
|
||||
}
|
||||
|
||||
void _exc_kaddr_err(void)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
" li $t0, 0x80000000\n"
|
||||
" jr $t0\n"
|
||||
"nop\n"
|
||||
".set reorder\n"
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
void _exc_iaddr_err(void)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
" li $t0, 0x80000003\n"
|
||||
" jr $t0\n"
|
||||
"nop\n"
|
||||
".set reorder\n"
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
void _exc_ri(void)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
" li $t0, 0x40010000\n"
|
||||
" li $t1, 0x9c563442\n"
|
||||
" sw $t1, 0($t0)\n"
|
||||
" jr $t0\n"
|
||||
"nop\n"
|
||||
".set reorder\n"
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
void _exc_ibe(void)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
" li $t1, 0xAc563440\n"
|
||||
" jr $t1\n"
|
||||
"nop\n"
|
||||
".set reorder\n"
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
void _exc_dbe(void)
|
||||
{
|
||||
__asm
|
||||
(
|
||||
".set noreorder\n"
|
||||
" li $t1, 0xAc563440\n"
|
||||
" lw $t0, 0($t1)\n"
|
||||
"nop\n"
|
||||
" jr $t0\n"
|
||||
"nop\n"
|
||||
".set reorder\n"
|
||||
|
||||
);
|
||||
|
||||
}
|
||||
|
||||
void handler0(void)
|
||||
{
|
||||
printf("Interrupt 0\n");
|
||||
interrupt_clr(0);
|
||||
}
|
||||
|
||||
void handler1(void)
|
||||
{
|
||||
printf("Interrupt 1\n");
|
||||
interrupt_clr(1);
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int buf[256];
|
||||
volatile int *pLED = (int*)sys_led_port;
|
||||
volatile int *pFlash = (int*)sys_flash_io;
|
||||
int i, sel;
|
||||
|
||||
interrupt_register(0, handler0);
|
||||
interrupt_enable(0);
|
||||
interrupt_register(1, handler1);
|
||||
interrupt_enable(1);
|
||||
|
||||
for (i=0; i < 8192; i++)
|
||||
*pLED = *pFlash;
|
||||
|
||||
while(1)
|
||||
{
|
||||
printf("Welche exception möchten Sie testen?\n");
|
||||
printf(" 1 : Reserved instruction\n");
|
||||
printf(" 2 : Privileged address\n");
|
||||
printf(" 3 : Arithmetic overflow\n");
|
||||
printf(" 4 : Syscall\n");
|
||||
printf(" 5 : Breakpoint\n");
|
||||
printf(" 6 : Load error on instruction\n");
|
||||
printf(" 7 : Load error on data\n");
|
||||
printf(" 8 : Store error on data\n");
|
||||
printf(" 9 : Bus error on instruction\n");
|
||||
printf("10 : Bus error on data\n");
|
||||
printf("11 : SW-interrupt 0\n");
|
||||
printf("12 : SW-interrupt 1\n");
|
||||
|
||||
scanf("%d", &sel);
|
||||
printf("Jetzt kommt die exception (%d)!\n", sel);
|
||||
|
||||
switch(sel)
|
||||
{
|
||||
case 1:
|
||||
_exc_ri();
|
||||
break;
|
||||
|
||||
case 2:
|
||||
_exc_kaddr_err();
|
||||
break;
|
||||
|
||||
case 3:
|
||||
_exc_arith();
|
||||
break;
|
||||
|
||||
case 4:
|
||||
_exc_syscall();
|
||||
break;
|
||||
|
||||
case 5:
|
||||
_exc_break();
|
||||
break;
|
||||
|
||||
case 6:
|
||||
_exc_iaddr_err();
|
||||
break;
|
||||
|
||||
case 7:
|
||||
_exc_load_err();
|
||||
break;
|
||||
|
||||
case 8:
|
||||
_exc_store_err();
|
||||
break;
|
||||
|
||||
case 9:
|
||||
printf("IBE: Exception not implemented in current CPU!\nPush reset to restart!\n");
|
||||
_exc_ibe();
|
||||
break;
|
||||
|
||||
case 10:
|
||||
printf("DBE: Exception not implemented in current CPU!\nPush reset to restart!\n");
|
||||
_exc_dbe();
|
||||
break;
|
||||
|
||||
case 11:
|
||||
case 12:
|
||||
interrupt_set(sel-11);
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
sel = 0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -3,8 +3,6 @@
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include <time.h>
|
||||
#include <sys/times.h>
|
||||
#include <sys/time.h>
|
||||
#include "libsys.h"
|
||||
|
||||
#define NO_ERROR 0x00000000
|
||||
@@ -24,14 +22,11 @@ void handler3(void)
|
||||
{
|
||||
volatile UINT32 *pUART_stat = (UINT32*)sys_uart_stat;
|
||||
volatile UINT32 *pUART_data = (UINT32*)sys_uart_data;
|
||||
volatile UINT32 *pLED = (UINT32*)sys_led_port;
|
||||
|
||||
while((0x10 & *pUART_stat))
|
||||
{
|
||||
buffer[i] = (char)*pUART_data;
|
||||
*pLED = buffer[i]*buffer[i];
|
||||
i = (i+1)%sizeof(buffer);
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
@@ -209,7 +204,7 @@ int Test10_LoadStore()
|
||||
}
|
||||
|
||||
|
||||
#define NUM_ELEMENTS 10000
|
||||
#define NUM_ELEMENTS 100000
|
||||
#define NUM_RUNS 3
|
||||
int Test11_AddSub()
|
||||
{
|
||||
@@ -304,7 +299,7 @@ int pi_calc()
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define TEST_SIZE (128*1024) // Bytes
|
||||
#define TEST_SIZE (32*1024*1024) // Bytes
|
||||
#define SMALL_TEST_SIZE (8192) // Bytes
|
||||
int main (void)
|
||||
{
|
||||
@@ -317,8 +312,7 @@ int main (void)
|
||||
time_t curr_date;
|
||||
struct tm *pDate, date;
|
||||
UINT32 start, end;
|
||||
char sel[80];
|
||||
struct timeval time_sec;
|
||||
char sel;
|
||||
|
||||
UINT8 *ram8 = NULL;
|
||||
UINT16 *ram16 = NULL;
|
||||
@@ -528,12 +522,9 @@ int main (void)
|
||||
sputs("\r\n");
|
||||
|
||||
printf("Datum und Uhrzeit setzen? [j/N]: ");
|
||||
scanf("%s", sel);
|
||||
if (toupper(sel[0]) == 'J')
|
||||
scanf("%c", &sel);
|
||||
if (toupper(sel) == 'J')
|
||||
{
|
||||
do
|
||||
{
|
||||
printf("Datum\n");
|
||||
printf("Jahr : ");
|
||||
scanf("%d", &date.tm_year);
|
||||
printf("Monat : ");
|
||||
@@ -541,30 +532,7 @@ int main (void)
|
||||
printf("Tag : ");
|
||||
scanf("%d", &date.tm_mday);
|
||||
|
||||
printf("Uhrzeit\n");
|
||||
printf("Stunde : ");
|
||||
scanf("%d", &date.tm_hour);
|
||||
printf("Minute : ");
|
||||
scanf("%d", &date.tm_min);
|
||||
printf("Sekunde : ");
|
||||
scanf("%d", &date.tm_sec);
|
||||
|
||||
date.tm_year -= 1900;
|
||||
date.tm_mon -= 1;
|
||||
time_sec.tv_sec = mktime(&date);
|
||||
time_sec.tv_usec = 0;
|
||||
settimeofday(&time_sec, NULL);
|
||||
|
||||
printf("Datum\n");
|
||||
curr_date = time(NULL);
|
||||
pDate = gmtime(&curr_date);
|
||||
puts(asctime(pDate));
|
||||
printf("\nOK? [J/n]: ");
|
||||
scanf("%s", sel);
|
||||
printf("sel=%d\n", (int)sel[0]);
|
||||
|
||||
|
||||
} while(toupper(sel[0]) == 'N');
|
||||
printf("Wir haben heute den %d. %d. %d\n", date.tm_mday, date.tm_mon, date.tm_year);
|
||||
}
|
||||
|
||||
interrupt_enable(3);
|
||||
|
||||
@@ -18,7 +18,7 @@ char *_xcpt_code_str[32] =
|
||||
#define PRINT_REG(tag_str, reg) \
|
||||
sputs(tag_str); \
|
||||
print_word(reg); \
|
||||
sputs(" ");
|
||||
sputs("\n");
|
||||
|
||||
int _xcpt_default_dispatch(struct xcptcontext * xcp)
|
||||
{
|
||||
@@ -55,57 +55,48 @@ int _xcpt_deliver(struct xcptcontext * _xcp)
|
||||
if (_xcpt_dispatch(_xcp))
|
||||
{
|
||||
sputs("\n");
|
||||
PRINT_REG(" Status : ", _xcp->sr);
|
||||
PRINT_REG(" Cause : ", _xcp->cr);
|
||||
PRINT_REG(" EPC : ", _xcp->epc);
|
||||
PRINT_REG("BadAddr : ", _xcp->baddr);
|
||||
sputs("\n");
|
||||
PRINT_REG(" MDLO : ", _xcp->mdlo);
|
||||
PRINT_REG(" MDHI : ", _xcp->mdhi);
|
||||
PRINT_REG("Status : ", _xcp->sr);
|
||||
PRINT_REG("Cause : ", _xcp->cr);
|
||||
PRINT_REG("EPC : ", _xcp->epc);
|
||||
PRINT_REG("BadAddr : ", _xcp->baddr);
|
||||
PRINT_REG("MDLO : ", _xcp->mdlo);
|
||||
PRINT_REG("MDHI : ", _xcp->mdhi);
|
||||
|
||||
sputs("\n");
|
||||
|
||||
sputs("Registers:\n");
|
||||
PRINT_REG(" 0 (ze) : ", _xcp->regs[0]);
|
||||
PRINT_REG(" 1 (at) : ", _xcp->regs[1]);
|
||||
PRINT_REG(" 2 (v0) : ", _xcp->regs[2]);
|
||||
PRINT_REG(" 3 (v1) : ", _xcp->regs[3]);
|
||||
sputs("\n");
|
||||
PRINT_REG(" 4 (a0) : ", _xcp->regs[4]);
|
||||
PRINT_REG(" 5 (a1) : ", _xcp->regs[5]);
|
||||
PRINT_REG(" 6 (a2) : ", _xcp->regs[6]);
|
||||
PRINT_REG(" 7 (a3) : ", _xcp->regs[7]);
|
||||
sputs("\n");
|
||||
PRINT_REG(" 8 (t0) : ", _xcp->regs[8]);
|
||||
PRINT_REG(" 9 (t1) : ", _xcp->regs[9]);
|
||||
PRINT_REG("10 (t2) : ", _xcp->regs[10]);
|
||||
PRINT_REG("11 (t3) : ", _xcp->regs[11]);
|
||||
sputs("\n");
|
||||
PRINT_REG("12 (t4) : ", _xcp->regs[12]);
|
||||
PRINT_REG("13 (t5) : ", _xcp->regs[13]);
|
||||
PRINT_REG("14 (t6) : ", _xcp->regs[14]);
|
||||
PRINT_REG("15 (t7) : ", _xcp->regs[15]);
|
||||
sputs("\n");
|
||||
PRINT_REG("16 (s0) : ", _xcp->regs[16]);
|
||||
PRINT_REG("17 (s1) : ", _xcp->regs[17]);
|
||||
PRINT_REG("18 (s2) : ", _xcp->regs[18]);
|
||||
PRINT_REG("19 (s3) : ", _xcp->regs[19]);
|
||||
sputs("\n");
|
||||
PRINT_REG("20 (s4) : ", _xcp->regs[20]);
|
||||
PRINT_REG("21 (s5) : ", _xcp->regs[21]);
|
||||
PRINT_REG("22 (s6) : ", _xcp->regs[22]);
|
||||
PRINT_REG("23 (s7) : ", _xcp->regs[23]);
|
||||
sputs("\n");
|
||||
PRINT_REG("24 (t8) : ", _xcp->regs[24]);
|
||||
PRINT_REG("25 (t9) : ", _xcp->regs[25]);
|
||||
PRINT_REG("26 (k0) : ", _xcp->regs[26]);
|
||||
PRINT_REG("27 (k1) : ", _xcp->regs[27]);
|
||||
sputs("\n");
|
||||
PRINT_REG("28 (gp) : ", _xcp->regs[28]);
|
||||
PRINT_REG("29 (sp) : ", _xcp->regs[29]);
|
||||
PRINT_REG("30 (fp) : ", _xcp->regs[30]);
|
||||
PRINT_REG("31 (ra) : ", _xcp->regs[31]);
|
||||
sputs("\n");
|
||||
PRINT_REG(" 0 (zero) : ", _xcp->regs[0]);
|
||||
PRINT_REG(" 1 (at) : ", _xcp->regs[1]);
|
||||
PRINT_REG(" 2 (v0) : ", _xcp->regs[2]);
|
||||
PRINT_REG(" 3 (v1) : ", _xcp->regs[3]);
|
||||
PRINT_REG(" 4 (a0) : ", _xcp->regs[4]);
|
||||
PRINT_REG(" 5 (a1) : ", _xcp->regs[5]);
|
||||
PRINT_REG(" 6 (a2) : ", _xcp->regs[6]);
|
||||
PRINT_REG(" 7 (a3) : ", _xcp->regs[7]);
|
||||
PRINT_REG(" 8 (t0) : ", _xcp->regs[8]);
|
||||
PRINT_REG(" 9 (t1) : ", _xcp->regs[9]);
|
||||
PRINT_REG("10 (t2) : ", _xcp->regs[10]);
|
||||
PRINT_REG("11 (t3) : ", _xcp->regs[11]);
|
||||
PRINT_REG("12 (t4) : ", _xcp->regs[12]);
|
||||
PRINT_REG("13 (t5) : ", _xcp->regs[13]);
|
||||
PRINT_REG("14 (t6) : ", _xcp->regs[14]);
|
||||
PRINT_REG("15 (t7) : ", _xcp->regs[15]);
|
||||
PRINT_REG("16 (s0) : ", _xcp->regs[16]);
|
||||
PRINT_REG("17 (s1) : ", _xcp->regs[17]);
|
||||
PRINT_REG("18 (s2) : ", _xcp->regs[18]);
|
||||
PRINT_REG("19 (s3) : ", _xcp->regs[19]);
|
||||
PRINT_REG("20 (s4) : ", _xcp->regs[20]);
|
||||
PRINT_REG("21 (s5) : ", _xcp->regs[21]);
|
||||
PRINT_REG("22 (s6) : ", _xcp->regs[22]);
|
||||
PRINT_REG("23 (s7) : ", _xcp->regs[23]);
|
||||
PRINT_REG("24 (t8) : ", _xcp->regs[24]);
|
||||
PRINT_REG("25 (t9) : ", _xcp->regs[25]);
|
||||
PRINT_REG("26 (k0) : ", _xcp->regs[26]);
|
||||
PRINT_REG("27 (k1) : ", _xcp->regs[27]);
|
||||
PRINT_REG("28 (gp) : ", _xcp->regs[28]);
|
||||
PRINT_REG("29 (sp) : ", _xcp->regs[29]);
|
||||
PRINT_REG("30 (fp) : ", _xcp->regs[30]);
|
||||
PRINT_REG("31 (ra) : ", _xcp->regs[31]);
|
||||
sputs("\n");
|
||||
|
||||
exc_code = (_xcp->cr >> 2) & 0x1F;
|
||||
|
||||
@@ -2,150 +2,46 @@
|
||||
TARGET=mipsel-elf
|
||||
PREFIX=/usr/local
|
||||
|
||||
SRC_BINUTILS=binutils-2.19
|
||||
SRC_GCC=gcc-4.3.3
|
||||
SRC_NEWLIB=newlib-1.16.0
|
||||
SRC_GMP=gmp-4.2.4
|
||||
SRC_MPFR=mpfr-2.4.0
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
# 1. Binutils bauen und installieren
|
||||
# ---------------------------------------------------------------
|
||||
if [ ! -e $SRC_BINUTILS.tar.bz2 ]; then
|
||||
echo Downloading $SRC_BINUTILS
|
||||
wget ftp://ftp-stud.fht-esslingen.de/pub/Mirrors/ftp.gnu.org/binutils/$SRC_BINUTILS.tar.bz2 || exit 1
|
||||
else
|
||||
echo Skipped downloading $SRC_BINUTILS
|
||||
fi
|
||||
|
||||
if [ ! -e ./$SRC_BINUTILS ]; then
|
||||
echo Unpacking $SRC_BINUTILS
|
||||
tar -xjf $SRC_BINUTILS.tar.bz2 || exit 1
|
||||
else
|
||||
echo Skipped unpacking $SRC_BINUTILS
|
||||
if [ ! -d ./binutils-2.19 ]; then
|
||||
tar -xjf binutils-2.19.tar.bz2
|
||||
fi
|
||||
|
||||
if [ ! -e ./$SRC_BINUTILS-build ]; then
|
||||
echo Building $SRC_BINUTILS
|
||||
mkdir -p $SRC_BINUTILS-build
|
||||
cd $SRC_BINUTILS-build
|
||||
../$SRC_BINUTILS/configure --target=$TARGET --prefix=$PREFIX || exit 1
|
||||
make || exit 1
|
||||
make install || exit 1
|
||||
if [ ! -d ./binutils-2.19_build ]; then
|
||||
mkdir -p binutils-2.19_build
|
||||
cd binutils-2.19_build
|
||||
../binutils-2.19/configure --target=$TARGET --prefix=$PREFIX
|
||||
make
|
||||
make install
|
||||
cd ..
|
||||
else
|
||||
echo $SRC_BINUTILS is already built.
|
||||
echo binutils is already built.
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
# 2. GMP bauen und installieren
|
||||
# 2. GCC & newlib bauen und installieren
|
||||
# ---------------------------------------------------------------
|
||||
if [ ! -e $SRC_GMP.tar.bz2 ]; then
|
||||
echo Downloading $SRC_GMP
|
||||
wget http://ftp.sunet.se/pub/gnu/gmp/$SRC_GMP.tar.bz2 || exit 1
|
||||
else
|
||||
echo Skipped downloading $SRC_GMP
|
||||
fi
|
||||
|
||||
if [ ! -e ./$SRC_GMP ]; then
|
||||
echo Unpacking $SRC_GMP
|
||||
tar -xjf $SRC_GMP.tar.bz2 || exit 1
|
||||
else
|
||||
echo Skipped unpacking $SRC_GMP
|
||||
if [ ! -d ./newlib-1.16.0 ]; then
|
||||
tar -xzf newlib-1.16.0.tar.gz
|
||||
fi
|
||||
|
||||
if [ ! -e ./$SRC_GMP-build ]; then
|
||||
echo Building $SRC_GMP
|
||||
mkdir -p $SRC_GMP-build
|
||||
cd $SRC_GMP-build
|
||||
../$SRC_GMP/configure --prefix=$PREFIX || exit 1
|
||||
make || exit 1
|
||||
make check || exit 1
|
||||
make install || exit 1
|
||||
if [ ! -d ./gcc-4.3.2 ]; then
|
||||
tar -xjf gcc-4.3.2.tar.bz2
|
||||
cd ./gcc-4.3.2
|
||||
ln -sf ../newlib-1.16.0/newlib/ .
|
||||
cd ..
|
||||
fi
|
||||
|
||||
if [ ! -d ./gcc-4.3.2_build ]; then
|
||||
mkdir -p gcc-4.3.2_build
|
||||
cd gcc-4.3.2_build
|
||||
../gcc-4.3.2/configure --target=$TARGET --prefix=$PREFIX --with-float=soft --with-newlib --verbose --enable-languages="c,c++"
|
||||
make all
|
||||
make info
|
||||
make install
|
||||
cd ..
|
||||
else
|
||||
echo $SRC_GMP is already built.
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
# 3. MPFR bauen und installieren
|
||||
# ---------------------------------------------------------------
|
||||
if [ ! -e $SRC_MPFR.tar.bz2 ]; then
|
||||
echo Downloading $SRC_MPFR
|
||||
wget http://www.mpfr.org/mpfr-current/$SRC_MPFR.tar.bz2 || exit 1
|
||||
else
|
||||
echo Skipped downloading $SRC_MPFR
|
||||
fi
|
||||
|
||||
if [ ! -e ./$SRC_MPFR ]; then
|
||||
echo Unpacking $SRC_MPFR
|
||||
tar -xjf $SRC_MPFR.tar.bz2 || exit 1
|
||||
else
|
||||
echo Skipped unpacking $SRC_MPFR
|
||||
fi
|
||||
|
||||
if [ ! -e ./$SRC_MPFR-build ]; then
|
||||
echo Building $SRC_MPFR
|
||||
mkdir -p $SRC_MPFR-build
|
||||
cd $SRC_MPFR-build
|
||||
../$SRC_MPFR/configure --prefix=$PREFIX || exit 1
|
||||
make || exit 1
|
||||
make check || exit 1
|
||||
make install || exit 1
|
||||
cd ..
|
||||
else
|
||||
echo $SRC_MPFR is already built.
|
||||
fi
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
# 4. GCC & newlib bauen und installieren
|
||||
# ---------------------------------------------------------------
|
||||
if [ ! -e $SRC_NEWLIB.tar.gz ]; then
|
||||
echo Downloading $SRC_NEWLIB
|
||||
wget ftp://sources.redhat.com/pub/newlib/$SRC_NEWLIB.tar.gz || exit 1
|
||||
else
|
||||
echo Skipped downloading $SRC_NEWLIB
|
||||
fi
|
||||
|
||||
if [ ! -e ./$SRC_NEWLIB ]; then
|
||||
echo Unpacking $SRC_NEWLIB
|
||||
tar -xzf $SRC_NEWLIB.tar.gz || exit 1
|
||||
if [ -e $SRC_NEWLIB-jens.patch ]; then
|
||||
echo Patching $SRC_NEWLIB
|
||||
patch -p0 < $SRC_NEWLIB-jens.patch || exit 1
|
||||
fi
|
||||
else
|
||||
echo Skipped unpacking $SRC_NEWLIB
|
||||
fi
|
||||
|
||||
if [ ! -e $SRC_GCC.tar.bz2 ]; then
|
||||
echo Downloading $SRC_GCC
|
||||
wget ftp://ftp-stud.fht-esslingen.de/pub/Mirrors/ftp.gnu.org/gcc/$SRC_GCC/$SRC_GCC.tar.bz2 || exit 1
|
||||
else
|
||||
echo Skipped downloading $SRC_GCC
|
||||
fi
|
||||
|
||||
if [ ! -e ./$SRC_GCC ]; then
|
||||
echo Unpacking $SRC_GCC
|
||||
tar -xjf $SRC_GCC.tar.bz2 || exit 1
|
||||
cd ./$SRC_GCC
|
||||
ln -sf ../$SRC_NEWLIB/newlib/ .
|
||||
cd ..
|
||||
else
|
||||
echo Skipped unpacking $SRC_GCC
|
||||
fi
|
||||
|
||||
if [ ! -e ./$SRC_GCC-build ]; then
|
||||
echo Building $SRC_GCC
|
||||
mkdir -p $SRC_GCC-build
|
||||
cd $SRC_GCC-build
|
||||
../$SRC_GCC/configure --target=$TARGET --prefix=$PREFIX --with-float=soft --with-newlib --verbose --enable-languages="c,c++" || exit 1
|
||||
LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$PREFIX/lib make all || exit 1
|
||||
make info || exit 1
|
||||
make install || exit 1
|
||||
cd ..
|
||||
echo $PREFIX/lib >/etc/ld.so.conf.d/local.conf
|
||||
ldconfig
|
||||
else
|
||||
echo $SRC_GCC is already built.
|
||||
echo GCC is already built.
|
||||
fi
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
diff -Naur newlib-1.16.0/newlib/libc/machine/mips/strlen.c newlib-1.16.0-fixed/newlib/libc/machine/mips/strlen.c
|
||||
--- newlib-1.16.0/newlib/libc/machine/mips/strlen.c 2002-03-14 03:41:43.000000000 +0100
|
||||
+++ newlib-1.16.0-fixed/newlib/libc/machine/mips/strlen.c 2009-02-14 15:52:58.000000000 +0100
|
||||
@@ -60,6 +60,7 @@
|
||||
" addiu $2,$4,1\n"
|
||||
"\n"
|
||||
"1: lbu $3,0($4)\n"
|
||||
+ " nop\n"
|
||||
" bnez $3,1b\n"
|
||||
" addiu $4,$4,1\n"
|
||||
"\n"
|
||||
@@ -1,11 +0,0 @@
|
||||
diff -Naur newlib-1.17.0/newlib/libc/machine/mips/strlen.c newlib-1.17.0-fixed/newlib/libc/machine/mips/strlen.c
|
||||
--- newlib-1.17.0/newlib/libc/machine/mips/strlen.c 2002-03-14 03:41:43.000000000 +0100
|
||||
+++ newlib-1.17.0-fixed/newlib/libc/machine/mips/strlen.c 2009-02-14 15:45:19.000000000 +0100
|
||||
@@ -60,6 +60,7 @@
|
||||
" addiu $2,$4,1\n"
|
||||
"\n"
|
||||
"1: lbu $3,0($4)\n"
|
||||
+ " nop\n"
|
||||
" bnez $3,1b\n"
|
||||
" addiu $4,$4,1\n"
|
||||
"\n"
|
||||
Vendored
+1
-3
@@ -2,7 +2,7 @@
|
||||
|
||||
PROJECT="mips_top"
|
||||
DIST_FILE="./files.dist"
|
||||
DIST_DIR="./release/mips.r11"
|
||||
DIST_DIR="./release/mips.r10a"
|
||||
|
||||
# ---------------------------------------------------------------
|
||||
mkdir -p $DIST_DIR/src
|
||||
@@ -16,11 +16,9 @@ cp -a ../doc/*.pdf $DIST_DIR/doc/
|
||||
cp -a ../doc/*.txt $DIST_DIR/doc/
|
||||
cp -a ../tools/* $DIST_DIR/tools/
|
||||
|
||||
cp -a ./tmpl/notes.txt $DIST_DIR/
|
||||
cp -a ./tmpl/gpl-3.0.txt $DIST_DIR/
|
||||
cp -a ./tmpl/tb_mips_top.wdo $DIST_DIR/sim/
|
||||
cp -a ./tmpl/hello.flash.bin $DIST_DIR/sim/
|
||||
cp -a ./tmpl/mips_sys.vhd $DIST_DIR/src/
|
||||
|
||||
for i in $(cat -s $DIST_FILE); do
|
||||
echo $i;
|
||||
|
||||
Vendored
-335
@@ -1,335 +0,0 @@
|
||||
-------------------------------------------------------------------------
|
||||
-- Project: JIPS, a portable 32-bit RISC CPU written in VHDL
|
||||
-- This file: Testbench for JCPU
|
||||
-- also writes 'opc.lst' for JASM-assembler
|
||||
--
|
||||
-- Copyright (C) 2007 J. Ahrensfeld
|
||||
--
|
||||
-- This program 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.
|
||||
--
|
||||
-- This program 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 this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
--
|
||||
-- For questions and ideas, please contact the author at jens@jayfield.org
|
||||
--
|
||||
--------------------------------------------------------------------------
|
||||
|
||||
LIBRARY ieee;
|
||||
use IEEE.STD_LOGIC_1164.ALL;
|
||||
USE ieee.numeric_std.ALL;
|
||||
|
||||
library work;
|
||||
use work.mips_types.all;
|
||||
use work.mips_instr.all;
|
||||
use work.async_types.all;
|
||||
use work.async_defs.all;
|
||||
|
||||
ENTITY mips_sys IS
|
||||
GENERIC
|
||||
(
|
||||
ICACHE_SIZE : natural := 512; -- words
|
||||
DCACHE_SIZE : natural := 512; -- words
|
||||
SRAM_ADDR_WIDTH : integer := 14;
|
||||
FLASH_ADDR_WIDTH : integer := 14
|
||||
);
|
||||
PORT
|
||||
(
|
||||
rst : in std_logic;
|
||||
clk : in std_logic;
|
||||
flash_cs_n : out std_logic;
|
||||
flash_oe_n : out std_logic;
|
||||
flash_we_n : out std_logic;
|
||||
flash_be_n : out unsigned(3 downto 0);
|
||||
sram_cs_n : out std_logic;
|
||||
sram_we_n : out std_logic;
|
||||
sram_oe_n : out std_logic;
|
||||
sram_be_n : out unsigned(3 downto 0);
|
||||
sram_a : out unsigned(SRAM_ADDR_WIDTH-1 downto 0);
|
||||
sram_d : inout unsigned(31 downto 0);
|
||||
flash_a : out unsigned(FLASH_ADDR_WIDTH-1 downto 0);
|
||||
flash_d : inout unsigned(31 downto 0);
|
||||
|
||||
gpo0 : out unsigned(31 downto 0);
|
||||
gpo1 : out unsigned(31 downto 0);
|
||||
gpi0 : in unsigned(31 downto 0);
|
||||
gpi1 : in unsigned(31 downto 0);
|
||||
|
||||
rx : in std_logic;
|
||||
tx : out std_logic;
|
||||
|
||||
debug : out unsigned(1 downto 0)
|
||||
);
|
||||
END mips_sys;
|
||||
|
||||
ARCHITECTURE behavior OF mips_sys IS
|
||||
|
||||
constant CLK_PERIOD : time := 10 ns;
|
||||
|
||||
-- Master
|
||||
signal ACK_I : STD_LOGIC := '0';
|
||||
signal SRDY_I : STD_LOGIC := '0';
|
||||
signal ADDR_O : unsigned(31 downto 0);
|
||||
signal DAT_I : unsigned(31 downto 0) := (others => '0');
|
||||
signal DAT_O : unsigned(31 downto 0);
|
||||
signal WE_O : STD_LOGIC;
|
||||
signal SEL_O : unsigned(3 downto 0);
|
||||
signal CYC_O : STD_LOGIC;
|
||||
signal STB_O : STD_LOGIC;
|
||||
signal MRDY_O : STD_LOGIC;
|
||||
signal INT : unsigned (5 downto 0) := (others => '0');
|
||||
|
||||
-- Slaves
|
||||
signal CYC_I_rom : std_logic;
|
||||
signal ACK_O_rom : std_logic;
|
||||
signal SRDY_O_rom : std_logic;
|
||||
signal DAT_O_rom : unsigned(31 downto 0);
|
||||
|
||||
signal CYC_I_flash : std_logic;
|
||||
signal ACK_O_flash : std_logic;
|
||||
signal SRDY_O_flash : std_logic;
|
||||
signal DAT_O_flash : unsigned(31 downto 0);
|
||||
|
||||
signal CYC_I_sram : std_logic;
|
||||
signal ACK_O_sram : std_logic;
|
||||
signal SRDY_O_sram : std_logic;
|
||||
signal DAT_O_sram : unsigned(31 downto 0);
|
||||
|
||||
signal CYC_I_gpio : std_logic;
|
||||
signal ACK_O_gpio : std_logic;
|
||||
signal SRDY_O_gpio : std_logic;
|
||||
signal DAT_O_gpio : unsigned(31 downto 0);
|
||||
|
||||
signal CYC_I_uart : std_logic;
|
||||
signal ACK_O_uart : std_logic;
|
||||
signal SRDY_O_uart : std_logic;
|
||||
signal DAT_O_uart : unsigned(31 downto 0);
|
||||
|
||||
signal int_uart_rx : std_logic;
|
||||
|
||||
type mem_area_t is (mem_dead, mem_flash, mem_sram, mem_rom, mem_gpio, mem_uart);
|
||||
signal mem_area : mem_area_t;
|
||||
|
||||
BEGIN
|
||||
|
||||
------------------------------------------------------------------
|
||||
-- Memory mux
|
||||
------------------------------------------------------------------
|
||||
mem_mux:
|
||||
process(ADDR_O)
|
||||
begin
|
||||
mem_area <= mem_dead;
|
||||
if ADDR_O(31 downto 28) = X"0" then
|
||||
mem_area <= mem_flash;
|
||||
elsif ADDR_O(31 downto 28) = X"A" then
|
||||
if ADDR_O(27 downto 26) = "00" then
|
||||
if ADDR_O(18 downto 16) = "000" then
|
||||
mem_area <= mem_gpio;
|
||||
elsif ADDR_O(18 downto 16) = "001" then
|
||||
mem_area <= mem_uart;
|
||||
end if;
|
||||
elsif ADDR_O(27 downto 26) = "01" then
|
||||
mem_area <= mem_flash;
|
||||
end if;
|
||||
elsif (ADDR_O(31 downto 28) = X"B" and ADDR_O(15) = '0') then
|
||||
mem_area <= mem_rom;
|
||||
elsif (ADDR_O(31 downto 28) = X"8" or ADDR_O(30) = '1') then
|
||||
mem_area <= mem_sram;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
signal_mux:
|
||||
process(mem_area, CYC_O)
|
||||
begin
|
||||
|
||||
CYC_I_uart <= '0';
|
||||
CYC_I_gpio <= '0';
|
||||
CYC_I_flash <= '0';
|
||||
CYC_I_rom <= '0';
|
||||
CYC_I_sram <= '0';
|
||||
|
||||
case mem_area is
|
||||
|
||||
when mem_gpio =>
|
||||
CYC_I_gpio <= CYC_O;
|
||||
|
||||
when mem_uart =>
|
||||
CYC_I_uart <= CYC_O;
|
||||
|
||||
when mem_flash =>
|
||||
CYC_I_flash <= CYC_O;
|
||||
|
||||
when mem_rom =>
|
||||
CYC_I_rom <= CYC_O;
|
||||
|
||||
when mem_sram =>
|
||||
CYC_I_sram <= CYC_O;
|
||||
|
||||
when others => null;
|
||||
|
||||
end case;
|
||||
|
||||
end process;
|
||||
|
||||
SRDY_I <= SRDY_O_flash or SRDY_O_sram or SRDY_O_rom or SRDY_O_uart or SRDY_O_gpio;
|
||||
ACK_I <= ACK_O_flash or ACK_O_sram or ACK_O_rom or ACK_O_uart or ACK_O_gpio;
|
||||
DAT_I <= DAT_O_sram when CYC_I_sram = '1' else
|
||||
DAT_O_rom when CYC_I_rom = '1' else
|
||||
DAT_O_flash when CYC_I_flash = '1' else
|
||||
DAT_O_uart when CYC_I_uart = '1' else
|
||||
DAT_O_gpio when CYC_I_gpio = '1' else X"DEADBEEF";
|
||||
|
||||
|
||||
------------------------------------------------------------------
|
||||
inst_mips_top: entity work.mips_top
|
||||
GENERIC MAP
|
||||
(
|
||||
icache_size => ICACHE_SIZE, -- words
|
||||
dcache_size => DCACHE_SIZE -- words
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
debug => debug,
|
||||
RST_I => rst,
|
||||
CLK_I => clk,
|
||||
ACK_I => ACK_I,
|
||||
SRDY_I => SRDY_I,
|
||||
ADDR_O => ADDR_O,
|
||||
DAT_I => DAT_I,
|
||||
DAT_O => DAT_O,
|
||||
WE_O => WE_O,
|
||||
SEL_O => SEL_O,
|
||||
CYC_O => CYC_O,
|
||||
STB_O => STB_O,
|
||||
MRDY_O => MRDY_O,
|
||||
INT => INT
|
||||
);
|
||||
INT(1) <= int_uart_rx;
|
||||
|
||||
inst_rom : entity work.rom_wb
|
||||
PORT MAP
|
||||
(
|
||||
CLK_I => clk,
|
||||
RST_I => rst,
|
||||
CYC_I => CYC_I_rom,
|
||||
STB_I => STB_O,
|
||||
ACK_O => ACK_O_rom,
|
||||
MRDY_I => MRDY_O,
|
||||
SRDY_O => SRDY_O_rom,
|
||||
ADDR_I => ADDR_O,
|
||||
DAT_O => DAT_O_rom
|
||||
);
|
||||
|
||||
inst_gpio : entity work.gpio_wb
|
||||
PORT MAP
|
||||
(
|
||||
CLK_I => clk,
|
||||
RST_I => rst,
|
||||
CYC_I => CYC_I_gpio,
|
||||
STB_I => STB_O,
|
||||
SEL_I => SEL_O,
|
||||
WE_I => WE_O,
|
||||
ACK_O => ACK_O_gpio,
|
||||
SRDY_O => SRDY_O_gpio,
|
||||
MRDY_I => MRDY_O,
|
||||
ADDR_I => ADDR_O,
|
||||
DAT_I => DAT_O,
|
||||
DAT_O => DAT_O_gpio,
|
||||
|
||||
sys_gpo0 => gpo0,
|
||||
sys_gpo1 => gpo1,
|
||||
sys_gpi0 => gpi0,
|
||||
sys_gpi1 => gpi1
|
||||
);
|
||||
|
||||
inst_flash_port : entity work.async_port_wb
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => FLASH_ADDR_WIDTH,
|
||||
data_width => 32,
|
||||
byte_sel_width => 4,
|
||||
async_timespec => ts_flash
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
CLK_I => clk,
|
||||
RST_I => rst,
|
||||
CYC_I => CYC_I_flash,
|
||||
STB_I => STB_O,
|
||||
WE_I => WE_O,
|
||||
ACK_O => ACK_O_flash,
|
||||
SRDY_O => SRDY_O_flash,
|
||||
MRDY_I => MRDY_O,
|
||||
SEL_I => SEL_O,
|
||||
ADDR_I => ADDR_O,
|
||||
DAT_I => DAT_O,
|
||||
DAT_O => DAT_O_flash,
|
||||
async_a => flash_a,
|
||||
async_d => flash_d,
|
||||
async_cs => flash_cs_n,
|
||||
async_wr => flash_we_n,
|
||||
async_rd => flash_oe_n,
|
||||
async_be => flash_be_n,
|
||||
async_rst => open
|
||||
);
|
||||
|
||||
inst_sram_port : entity work.async_port_wb
|
||||
GENERIC MAP
|
||||
(
|
||||
addr_width => SRAM_ADDR_WIDTH,
|
||||
data_width => 32,
|
||||
byte_sel_width => 4,
|
||||
async_timespec => ts_sram
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
CLK_I => clk,
|
||||
RST_I => rst,
|
||||
CYC_I => CYC_I_sram,
|
||||
STB_I => STB_O,
|
||||
WE_I => WE_O,
|
||||
ACK_O => ACK_O_sram,
|
||||
SRDY_O => SRDY_O_sram,
|
||||
MRDY_I => MRDY_O,
|
||||
SEL_I => SEL_O,
|
||||
ADDR_I => ADDR_O,
|
||||
DAT_I => DAT_O,
|
||||
DAT_O => DAT_O_sram,
|
||||
async_a => sram_a,
|
||||
async_d => sram_d,
|
||||
async_cs => sram_cs_n,
|
||||
async_wr => sram_we_n,
|
||||
async_rd => sram_oe_n,
|
||||
async_be => sram_be_n,
|
||||
async_rst => open
|
||||
);
|
||||
|
||||
inst_uart : entity work.uart_wb
|
||||
PORT MAP
|
||||
(
|
||||
CLK_I => clk,
|
||||
RST_I => rst,
|
||||
CYC_I => CYC_I_uart,
|
||||
STB_I => STB_O,
|
||||
SEL_I => SEL_O,
|
||||
WE_I => WE_O,
|
||||
ACK_O => ACK_O_uart,
|
||||
SRDY_O => SRDY_O_uart,
|
||||
MRDY_I => MRDY_O,
|
||||
ADDR_I => ADDR_O,
|
||||
DAT_I => DAT_O,
|
||||
DAT_O => DAT_O_uart,
|
||||
INT_RX_O => int_uart_rx,
|
||||
INT_TX_O => open,
|
||||
ser_rx => rx,
|
||||
ser_tx => tx
|
||||
);
|
||||
|
||||
END;
|
||||
Vendored
-36
@@ -1,36 +0,0 @@
|
||||
-----------------------------------------------------------------
|
||||
Changes in release 11
|
||||
-----------------------------------------------------------------
|
||||
- bug-fix in mips_pipeline: pc_is_branch is now initialized at reset
|
||||
(fixes CPU unrecoverable state after reset)
|
||||
- reverted "optimization" in mips_dcache, which behaved buggy during exceptions
|
||||
- new example source: test_exception
|
||||
- minor changes in libsys
|
||||
- added async_port_timing in doc
|
||||
- examples/testbench: date set now really works
|
||||
|
||||
-----------------------------------------------------------------
|
||||
Changes in release 10b
|
||||
-----------------------------------------------------------------
|
||||
- fixed compiler bug (missing nop after lw) in bootloader,
|
||||
which caused exception during boot
|
||||
|
||||
-----------------------------------------------------------------
|
||||
Changes in release 10a
|
||||
-----------------------------------------------------------------
|
||||
async_port_wb:
|
||||
- added byte enable for async_port
|
||||
|
||||
bootloader.c
|
||||
- fixed compiler bug (missing nop after lw)
|
||||
|
||||
mips-core
|
||||
- SEL_O lines are also asserted correctly during reads
|
||||
|
||||
tools/romgen
|
||||
- TCL-Jtage now compatible with Chipscope 10.1
|
||||
|
||||
mips_sys.c
|
||||
- use byte enable for sram and flash
|
||||
|
||||
|
||||
Binary file not shown.
@@ -39,37 +39,10 @@ add wave -noupdate -format Literal /tb_mips_top/sram_be_n
|
||||
add wave -noupdate -divider ALU
|
||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_pipeline/hdu
|
||||
add wave -noupdate -format Literal -expand /tb_mips_top/uut/inst_pipeline/sdu
|
||||
add wave -noupdate -divider PC
|
||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_pipeline/pc
|
||||
add wave -noupdate -divider COP0
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_pipeline/inst_cop/events
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_pipeline/inst_cop/ctrl_in
|
||||
add wave -noupdate -format Literal -expand /tb_mips_top/uut/inst_pipeline/inst_cop/ctrl_out
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/inst_cop/epc
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/inst_cop/cause
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/inst_cop/status
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/inst_cop/badvaddr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/inst_cop/exc_code
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_pipeline/inst_cop/stat_reg_we
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_pipeline/inst_cop/eflags_reg_we
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_pipeline/inst_cop/epc_reg_we
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_pipeline/inst_cop/code_reg_we
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_pipeline/inst_cop/ip_reg_we
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_pipeline/inst_cop/bd
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_pipeline/inst_cop/status_save
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_pipeline/inst_cop/status_rest
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_pipeline/inst_cop/exception
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_pipeline/inst_cop/exception_end
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_pipeline/inst_cop/eflags
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_pipeline/inst_cop/exc_enable
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_pipeline/inst_cop/cop_ex_en
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_pipeline/inst_cop/cop_pipe_id
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_pipeline/inst_cop/cop_pipe_ex
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_pipeline/inst_cop/exc_state
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_pipeline/inst_cop/exc_staten
|
||||
add wave -noupdate -divider Pipestages
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/pc
|
||||
add wave -noupdate -divider PC
|
||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_pipeline/id_stage
|
||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||
@@ -79,58 +52,12 @@ add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/i
|
||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_pipeline/wb_stage
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_pipeline/rst
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_pipeline/cpu_rst
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_pipeline/cpu_run
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/inst_reg_dual/reg_mem
|
||||
add wave -noupdate -divider I-Cache
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/cpu_en
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/cpu_addr
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/cpu_dout
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/cpu_busy
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_icache/s
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/cache_busy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/cache_miss
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/tag_match
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/word_index_reg
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/cache_index_reg
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_icache/tag_index_reg
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/cpu_reg_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_icache/was_miss
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_icache/cache_entry_out
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_icache/request_count
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_icache/fill_count
|
||||
add wave -noupdate -divider D-Cache
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/s
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/cpu_addr
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/cpu_din
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/cpu_dout
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/cpu_busy
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/tram_addr_rd
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/tram_addr_wr
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/tram_we
|
||||
add wave -noupdate -format Literal -expand /tb_mips_top/uut/inst_biu/inst_dcache/cache_entry_out
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/cache_busy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/cache_hit
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/tag_match
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/word_index_reg
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/addr_windex_reg
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/cache_index_reg
|
||||
add wave -noupdate -format Literal -radix hexadecimal /tb_mips_top/uut/inst_biu/inst_dcache/tag_index_reg
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/fill_count
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/fill_count_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/fill_count_rdy
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/flush_count
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/flush_count_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/flush_count_rdy
|
||||
add wave -noupdate -format Literal /tb_mips_top/uut/inst_biu/inst_dcache/request_count
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/request_count_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/request_count_rdy
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/cpu_reg_en
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/was_miss
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/cpu_hit_we
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_biu/inst_dcache/instant_raw
|
||||
add wave -noupdate -format Logic /tb_mips_top/uut/inst_pipeline/run_en
|
||||
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_pipeline/inst_reg_dual/reg_mem
|
||||
TreeUpdate [SetDefaultTree]
|
||||
WaveRestoreCursors {{Cursor 1} {2127774 ps} 0}
|
||||
WaveRestoreCursors {{Cursor 1} {1375665640 ps} 0}
|
||||
configure wave -namecolwidth 188
|
||||
configure wave -valuecolwidth 100
|
||||
configure wave -justifyvalue left
|
||||
@@ -144,4 +71,4 @@ configure wave -gridperiod 100
|
||||
configure wave -griddelta 40
|
||||
configure wave -timeline 1
|
||||
update
|
||||
WaveRestoreZoom {0 ps} {5031559 ps}
|
||||
WaveRestoreZoom {0 ps} {1680 us}
|
||||
|
||||
@@ -127,7 +127,7 @@ END COMPONENT;
|
||||
return result;
|
||||
end to_tram_data;
|
||||
|
||||
type cache_state_t is (init, ready, flush, mem_request, mem_access, mem_data, rd_cache);
|
||||
type cache_state_t is (init, ready, flush, mem_request, mem_access, mem_wait, mem_data, upd_cache, rd_cache);
|
||||
signal s, sn : cache_state_t;
|
||||
|
||||
signal cache_busy : std_logic;
|
||||
@@ -162,18 +162,17 @@ END COMPONENT;
|
||||
signal tram_we : std_logic;
|
||||
|
||||
signal fill_count : natural range 0 to 2**word_index_width-1;
|
||||
signal fill_count_en : std_logic;
|
||||
signal fill_count_rdy : std_logic;
|
||||
signal flush_count : natural range 0 to 2**cache_index_width-1;
|
||||
signal flush_count_en : std_logic;
|
||||
signal flush_count_rdy : std_logic;
|
||||
signal request_count : natural range 0 to 2**word_index_width-1;
|
||||
signal request_count_en : std_logic;
|
||||
signal request_count_rdy : std_logic;
|
||||
signal cpu_reg_en : std_logic;
|
||||
signal was_miss : std_logic;
|
||||
signal cpu_hit_we : std_logic;
|
||||
signal instant_raw : std_logic;
|
||||
signal fill_count_rst : std_logic;
|
||||
signal flush_index_count : natural range 0 to 2**cache_index_width-1;
|
||||
signal flush_index_count_en : std_logic;
|
||||
signal request_count : natural range 0 to 2**word_index_width-1;
|
||||
signal request_count_en : std_logic;
|
||||
signal request_count_rst : std_logic;
|
||||
signal cpu_reg_en : std_logic;
|
||||
signal was_miss : std_logic;
|
||||
signal cache_fill : std_logic;
|
||||
signal cpu_hit_we : std_logic;
|
||||
signal instant_raw : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
@@ -183,7 +182,7 @@ cpu_index_register:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if fill_count_en = '1' then
|
||||
if cache_fill = '1' then
|
||||
if ACK_I = '1' then
|
||||
word_index_reg <= word_index_reg + 1;
|
||||
end if;
|
||||
@@ -199,10 +198,8 @@ addr_windex_register:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if request_count_en = '1'then
|
||||
if SRDY_I = '1' then
|
||||
addr_windex_reg <= addr_windex_reg + 1;
|
||||
end if;
|
||||
if request_count_en = '1' and SRDY_I = '1' then
|
||||
addr_windex_reg <= addr_windex_reg + 1;
|
||||
elsif cpu_reg_en = '1' and en = '1' and instant_raw = '0' then
|
||||
addr_windex_reg <= cpu_word_index;
|
||||
end if;
|
||||
@@ -249,13 +246,11 @@ instant_raw_logic:
|
||||
end process;
|
||||
|
||||
inst_tag_ram : dpram_1w1r
|
||||
GENERIC MAP
|
||||
(
|
||||
GENERIC MAP (
|
||||
addr_width => tram_addr_width,
|
||||
data_width => tram_data_width
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
PORT MAP (
|
||||
clka => CLK_I,
|
||||
clkb => CLK_I,
|
||||
en_a => '1',
|
||||
@@ -272,13 +267,11 @@ gen_data_ram:
|
||||
begin
|
||||
|
||||
inst_data_ram : dpram_2w2r
|
||||
GENERIC MAP
|
||||
(
|
||||
GENERIC MAP (
|
||||
addr_width => lg2(cache_size),
|
||||
data_width => word_t'length/4
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
PORT MAP (
|
||||
clk_a => CLK_I,
|
||||
clk_b => CLK_I,
|
||||
en_a => '1',
|
||||
@@ -312,28 +305,30 @@ cache_state_next:
|
||||
tag_match <= '1' when tag_index_reg = cache_entry_out.tag else '0';
|
||||
cache_hit <= tag_match and cache_entry_out.valid;
|
||||
tram_din <= to_tram_data(cache_entry_in);
|
||||
tram_addr_wr <= to_unsigned(flush_count, cache_index_width) when flush_count_en = '1' else cache_index_reg;
|
||||
tram_addr_rd <= cpu_cache_index when was_miss = '0' else cache_index_reg;
|
||||
cache_entry_out <= to_dcache_entry(tram_dout);
|
||||
|
||||
cpu_dram_addr <= (cpu_cache_index & cpu_word_index) when (was_miss = '0' and instant_raw = '0' and fill_count_en = '0') else (cache_index_reg & word_index_reg);
|
||||
cpu_dram_addr <= (cpu_cache_index & cpu_word_index) when (was_miss = '0'and instant_raw = '0' and cache_fill = '0') else (cache_index_reg & word_index_reg);
|
||||
ADDR_O <= tag_index_reg & cache_index_reg & addr_windex_reg & "00";
|
||||
ctrl_dram_addr <= cache_index_reg & word_index_reg;
|
||||
ctrl_dram_we <= (others => fill_count_en and ACK_I);
|
||||
ctrl_dram_we <= (others => cache_fill and ACK_I);
|
||||
cpu_dram_we <= cpu_be_reg when (cpu_hit_we = '1') else (others => '0');
|
||||
|
||||
cache_state:
|
||||
process(s, instant_raw, cache_hit, flush_count_rdy, fill_count_rdy, request_count_rdy, tag_index_reg, cpu_en, SRDY_I, cpu_en2, cpu_we_reg)
|
||||
process(s, instant_raw, cache_hit, flush_index_count, fill_count, request_count, cache_index_reg, ACK_I, tag_index_reg, cpu_en, SRDY_I, cpu_en2, cpu_we_reg)
|
||||
begin
|
||||
cpu_reg_en <= '0';
|
||||
cache_busy <= '1';
|
||||
tram_we <= '0';
|
||||
flush_count_en <= '0';
|
||||
flush_index_count_en <= '0';
|
||||
fill_count_rst <= '0';
|
||||
request_count_en <= '0';
|
||||
fill_count_en <= '0';
|
||||
request_count_rst <= '0';
|
||||
CYC_O <= '0';
|
||||
STB_O <= '0';
|
||||
was_miss <= '0';
|
||||
cache_fill <= '0';
|
||||
tram_addr_wr <= to_unsigned(flush_index_count, cache_index_width);
|
||||
cache_entry_in.tv_p <= (others => '0');
|
||||
cache_entry_in.tag <= tag_index_reg;
|
||||
cache_entry_in.valid <= '0';
|
||||
@@ -354,39 +349,47 @@ cache_state:
|
||||
end if;
|
||||
end if;
|
||||
when flush =>
|
||||
flush_count_en <= '1';
|
||||
tram_we <= '1';
|
||||
flush_index_count_en <= '1';
|
||||
tram_addr_wr <= to_unsigned(flush_index_count, cache_index_width);
|
||||
tram_we <= '1';
|
||||
cache_entry_in.valid <= '0';
|
||||
cache_entry_in.tag <= (others => '0');
|
||||
if flush_count_rdy = '1' then
|
||||
tram_we <= '0';
|
||||
if flush_index_count = 0 then
|
||||
sn <= ready;
|
||||
if cpu_en = '1' then
|
||||
cpu_reg_en <= '1';
|
||||
end if;
|
||||
end if;
|
||||
when mem_request =>
|
||||
fill_count_rst <= '1';
|
||||
request_count_rst <= '1';
|
||||
CYC_O <= '1';
|
||||
if SRDY_I = '1' then
|
||||
sn <= mem_access;
|
||||
end if;
|
||||
when mem_access =>
|
||||
fill_count_en <= '1';
|
||||
cache_fill <= '1';
|
||||
request_count_en <= '1';
|
||||
CYC_O <= '1';
|
||||
STB_O <= '1';
|
||||
if request_count_rdy = '1' then
|
||||
STB_O <= '0';
|
||||
sn <= mem_data;
|
||||
if request_count = 0 then
|
||||
if SRDY_I = '1' then
|
||||
sn <= mem_data;
|
||||
end if;
|
||||
end if;
|
||||
when mem_data =>
|
||||
CYC_O <= '1';
|
||||
fill_count_en <= '1';
|
||||
if fill_count_rdy = '1' then
|
||||
tram_we <= '1';
|
||||
cache_entry_in.valid <= '1';
|
||||
sn <= rd_cache;
|
||||
CYC_O <= '1';
|
||||
cache_fill <= '1';
|
||||
if fill_count = 0 then
|
||||
if ACK_I = '1' then
|
||||
sn <= upd_cache;
|
||||
end if;
|
||||
end if;
|
||||
when upd_cache =>
|
||||
tram_addr_wr <= cache_index_reg;
|
||||
tram_we <= '1';
|
||||
cache_entry_in.valid <= '1';
|
||||
sn <= rd_cache;
|
||||
when rd_cache =>
|
||||
was_miss <= '1';
|
||||
sn <= ready;
|
||||
@@ -394,59 +397,43 @@ cache_state:
|
||||
when others =>
|
||||
sn <= ready;
|
||||
end case;
|
||||
|
||||
end process;
|
||||
|
||||
flush_counter:
|
||||
flush_index_counter:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if flush_count_en = '0' then
|
||||
flush_count_rdy <= '0';
|
||||
flush_count <= 2**cache_index_width-1;
|
||||
else
|
||||
if flush_count /= 0 then
|
||||
flush_count <= flush_count - 1;
|
||||
else
|
||||
flush_count_rdy <= '1';
|
||||
end if;
|
||||
if flush_index_count_en = '0' then
|
||||
flush_index_count <= 2**cache_index_width-1;
|
||||
elsif flush_index_count /= 0 then
|
||||
flush_index_count <= flush_index_count - 1;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
request_counter:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if request_count_en = '0' then
|
||||
request_count_rdy <= '0';
|
||||
request_count <= 2**word_index_width-1;
|
||||
else
|
||||
if SRDY_I = '1' then
|
||||
if request_count /= 0 then
|
||||
request_count <= request_count - 1;
|
||||
else
|
||||
request_count_rdy <= '1';
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
fill_counter:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if fill_count_en = '0' then
|
||||
fill_count_rdy <= '0';
|
||||
fill_count <= 2**word_index_width-1;
|
||||
else
|
||||
if ACK_I = '1' then
|
||||
if fill_count /= 0 then
|
||||
fill_count <= fill_count - 1;
|
||||
else
|
||||
fill_count_rdy <= '1';
|
||||
end if;
|
||||
if fill_count_rst = '1' then
|
||||
fill_count <= 2**word_index_width-1;
|
||||
elsif cache_fill = '1' and ACK_I = '1' then
|
||||
if fill_count /= 0 then
|
||||
fill_count <= fill_count - 1;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
request_counter:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if request_count_rst = '1' then
|
||||
request_count <= 2**word_index_width-1;
|
||||
elsif request_count_en = '1' and SRDY_I = '1' then
|
||||
if request_count /= 0 then
|
||||
request_count <= request_count - 1;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
@@ -101,14 +101,13 @@ END COMPONENT;
|
||||
return result;
|
||||
end to_tag_ram_data;
|
||||
|
||||
type cache_state_t is (init, ready, flush, mem_request, mem_access, mem_data, rd_cache);
|
||||
type cache_state_t is (init, ready, flush, mem_request, mem_access, mem_wait, mem_data, upd_cache, rd_cache);
|
||||
signal s, sn : cache_state_t;
|
||||
|
||||
signal cache_busy : std_logic;
|
||||
signal cache_miss : std_logic;
|
||||
signal tag_match : std_logic;
|
||||
signal word_index_reg : unsigned(word_index_width-1 downto 0);
|
||||
signal addr_windex_reg : unsigned(word_index_width-1 downto 0);
|
||||
signal cache_index_reg : unsigned(cache_index_width-1 downto 0);
|
||||
signal tag_index_reg : unsigned(tag_width-1 downto 0);
|
||||
|
||||
@@ -125,20 +124,18 @@ END COMPONENT;
|
||||
signal tag_ram_data_rd : tag_ram_data_t;
|
||||
signal tag_ram_addr_wr : unsigned(cache_index_width-1 downto 0);
|
||||
signal tag_ram_data_wr : tag_ram_data_t;
|
||||
signal tag_ram_re : std_logic;
|
||||
signal tag_ram_we : std_logic;
|
||||
|
||||
signal fill_count : natural range 0 to 2**word_index_width-1;
|
||||
signal fill_count_en : std_logic;
|
||||
signal fill_count_rdy : std_logic;
|
||||
signal flush_count : natural range 0 to 2**cache_index_width-1;
|
||||
signal flush_count_en : std_logic;
|
||||
signal flush_count_rdy : std_logic;
|
||||
signal request_count : natural range 0 to 2**word_index_width-1;
|
||||
signal request_count_en : std_logic;
|
||||
signal request_count_rdy : std_logic;
|
||||
signal cpu_reg_en : std_logic;
|
||||
signal was_miss : std_logic;
|
||||
signal ram_index_count : natural range 0 to 2**word_index_width-1;
|
||||
signal ram_index_count_rst : std_logic;
|
||||
signal cache_index_count : natural range 0 to 2**cache_index_width-1;
|
||||
signal cache_index_count_en : std_logic;
|
||||
signal mem_index_count : natural range 0 to 2**word_index_width-1;
|
||||
signal mem_index_count_en : std_logic;
|
||||
signal mem_index_count_rst : std_logic;
|
||||
signal cpu_reg_en : std_logic;
|
||||
signal was_miss : std_logic;
|
||||
signal data_write : std_logic;
|
||||
|
||||
begin
|
||||
|
||||
@@ -150,10 +147,6 @@ cpu_index_reg:
|
||||
if RST_I = '1' then
|
||||
cache_index_reg <= (others => '0');
|
||||
tag_index_reg <= (others => '0');
|
||||
elsif fill_count_en = '1' then
|
||||
if ACK_I = '1' then
|
||||
word_index_reg <= word_index_reg + 1;
|
||||
end if;
|
||||
elsif cpu_reg_en = '1' then
|
||||
word_index_reg <= cpu_word_index;
|
||||
cache_index_reg <= cpu_cache_index;
|
||||
@@ -162,32 +155,16 @@ cpu_index_reg:
|
||||
end if;
|
||||
end process;
|
||||
|
||||
addr_windex_register:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if request_count_en = '1'then
|
||||
if SRDY_I = '1' then
|
||||
addr_windex_reg <= addr_windex_reg + 1;
|
||||
end if;
|
||||
elsif cpu_reg_en = '1' then
|
||||
addr_windex_reg <= cpu_word_index;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
inst_tag_ram : dpram_1w1r
|
||||
GENERIC MAP
|
||||
(
|
||||
GENERIC MAP (
|
||||
addr_width => tag_ram_addr_width,
|
||||
data_width => tag_ram_data_width
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
PORT MAP (
|
||||
clka => CLK_I,
|
||||
clkb => CLK_I,
|
||||
en_a => '1',
|
||||
en_b => tag_ram_re,
|
||||
en_b => '1',
|
||||
we_a => tag_ram_we,
|
||||
addr_a => tag_ram_addr_wr,
|
||||
addr_b => tag_ram_addr_rd,
|
||||
@@ -196,13 +173,11 @@ inst_tag_ram : dpram_1w1r
|
||||
);
|
||||
|
||||
inst_data_ram : dpram_1w1r
|
||||
GENERIC MAP
|
||||
(
|
||||
GENERIC MAP (
|
||||
addr_width => lg2(cache_size),
|
||||
data_width => word_t'length
|
||||
)
|
||||
PORT MAP
|
||||
(
|
||||
PORT MAP (
|
||||
clka => CLK_I,
|
||||
clkb => CLK_I,
|
||||
en_a => '1',
|
||||
@@ -233,29 +208,30 @@ cache_state_next:
|
||||
tag_match <= '1' when tag_index_reg = cache_entry_out.tag else '0';
|
||||
cache_miss <= not (tag_match and cache_entry_out.valid);
|
||||
tag_ram_data_wr <= to_tag_ram_data(cache_entry_in);
|
||||
tag_ram_addr_wr <= to_unsigned(flush_count, cache_index_width) when flush_count_en = '1' else cache_index_reg;
|
||||
tag_ram_addr_rd <= cpu_cache_index when was_miss = '0' else cache_index_reg;
|
||||
cache_entry_out <= to_icache_entry(tag_ram_data_rd);
|
||||
data_ram_addr_rd <= (cpu_cache_index & cpu_word_index) when was_miss = '0' else (cache_index_reg & word_index_reg);
|
||||
ADDR_O <= tag_index_reg & cache_index_reg & addr_windex_reg & "00";
|
||||
data_ram_addr_wr <= cache_index_reg & word_index_reg;
|
||||
ADDR_O <= tag_index_reg & cache_index_reg & to_unsigned(mem_index_count, word_index_width) & "00";
|
||||
data_ram_addr_wr <= cache_index_reg & to_unsigned(ram_index_count, word_index_width);
|
||||
data_ram_data_wr <= DAT_I;
|
||||
data_ram_we <= fill_count_en and ACK_I;
|
||||
data_ram_we <= data_write and ACK_I;
|
||||
|
||||
cache_state:
|
||||
process(s, cache_miss, flush_count_rdy, fill_count_rdy, request_count_rdy, tag_index_reg, cpu_en, SRDY_I, en)
|
||||
process(s, cache_miss, cache_index_count, ram_index_count, mem_index_count, cache_index_reg, ACK_I, tag_index_reg, cpu_en, SRDY_I, en)
|
||||
begin
|
||||
cpu_reg_en <= '0';
|
||||
cache_busy <= '1';
|
||||
tag_ram_we <= '0';
|
||||
flush_count_en <= '0';
|
||||
request_count_en <= '0';
|
||||
fill_count_en <= '0';
|
||||
cache_index_count_en <= '0';
|
||||
ram_index_count_rst <= '0';
|
||||
mem_index_count_en <= '0';
|
||||
mem_index_count_rst <= '0';
|
||||
CYC_O <= '0';
|
||||
STB_O <= '0';
|
||||
data_ram_re <= '0';
|
||||
tag_ram_re <= '0';
|
||||
was_miss <= '0';
|
||||
data_write <= '0';
|
||||
tag_ram_addr_wr <= to_unsigned(cache_index_count, cache_index_width);
|
||||
cache_entry_in.tv_p <= (others => '0');
|
||||
cache_entry_in.tag <= tag_index_reg;
|
||||
cache_entry_in.valid <= '0';
|
||||
@@ -275,107 +251,96 @@ cache_state:
|
||||
elsif cpu_en = '1' then
|
||||
cpu_reg_en <= '1';
|
||||
data_ram_re <= '1';
|
||||
tag_ram_re <= '1';
|
||||
end if;
|
||||
end if;
|
||||
when flush =>
|
||||
flush_count_en <= '1';
|
||||
cache_index_count_en <= '1';
|
||||
tag_ram_addr_wr <= to_unsigned(cache_index_count, cache_index_width);
|
||||
tag_ram_we <= '1';
|
||||
cache_entry_in.valid <= '0';
|
||||
cache_entry_in.tag <= (others => '0');
|
||||
if flush_count_rdy = '1' then
|
||||
tag_ram_we <= '0';
|
||||
if cache_index_count = 0 then
|
||||
sn <= ready;
|
||||
if cpu_en = '1' then
|
||||
cpu_reg_en <= '1';
|
||||
data_ram_re <= '1';
|
||||
tag_ram_re <= '1';
|
||||
end if;
|
||||
end if;
|
||||
when mem_request =>
|
||||
ram_index_count_rst <= '1';
|
||||
mem_index_count_rst <= '1';
|
||||
CYC_O <= '1';
|
||||
if SRDY_I = '1' then
|
||||
sn <= mem_access;
|
||||
end if;
|
||||
when mem_access =>
|
||||
request_count_en <= '1';
|
||||
fill_count_en <= '1';
|
||||
CYC_O <= '1';
|
||||
STB_O <= '1';
|
||||
if request_count_rdy = '1' then
|
||||
STB_O <= '0';
|
||||
sn <= mem_data;
|
||||
mem_index_count_en <= '1';
|
||||
data_write <= '1';
|
||||
CYC_O <= '1';
|
||||
STB_O <= '1';
|
||||
if mem_index_count = 2**word_index_width-1 then
|
||||
if SRDY_I = '1' then
|
||||
sn <= mem_data;
|
||||
end if;
|
||||
end if;
|
||||
when mem_data =>
|
||||
CYC_O <= '1';
|
||||
fill_count_en <= '1';
|
||||
if fill_count_rdy = '1' then
|
||||
tag_ram_we <= '1';
|
||||
cache_entry_in.valid <= '1';
|
||||
sn <= rd_cache;
|
||||
CYC_O <= '1';
|
||||
data_write <= '1';
|
||||
if ram_index_count = 2**word_index_width-1 then
|
||||
if ACK_I = '1' then
|
||||
sn <= upd_cache;
|
||||
end if;
|
||||
end if;
|
||||
when upd_cache =>
|
||||
tag_ram_addr_wr <= cache_index_reg;
|
||||
tag_ram_we <= '1';
|
||||
cache_entry_in.valid <= '1';
|
||||
sn <= rd_cache;
|
||||
|
||||
when rd_cache =>
|
||||
tag_ram_re <= '1';
|
||||
data_ram_re <= '1';
|
||||
was_miss <= '1';
|
||||
sn <= ready;
|
||||
|
||||
when others =>
|
||||
sn <= ready;
|
||||
end case;
|
||||
|
||||
end process;
|
||||
|
||||
flush_counter:
|
||||
cache_index_counter:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if flush_count_en = '0' then
|
||||
flush_count_rdy <= '0';
|
||||
flush_count <= 2**cache_index_width-1;
|
||||
else
|
||||
if flush_count /= 0 then
|
||||
flush_count <= flush_count - 1;
|
||||
else
|
||||
flush_count_rdy <= '1';
|
||||
end if;
|
||||
if cache_index_count_en = '0' then
|
||||
cache_index_count <= 2**cache_index_width-1;
|
||||
elsif cache_index_count /= 0 then
|
||||
cache_index_count <= cache_index_count - 1;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
request_counter:
|
||||
ram_index_counter:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if request_count_en = '0' then
|
||||
request_count_rdy <= '0';
|
||||
request_count <= 2**word_index_width-1;
|
||||
else
|
||||
if SRDY_I = '1' then
|
||||
if request_count /= 0 then
|
||||
request_count <= request_count - 1;
|
||||
else
|
||||
request_count_rdy <= '1';
|
||||
end if;
|
||||
end if;
|
||||
if ram_index_count_rst = '1' then
|
||||
ram_index_count <= 0;
|
||||
elsif data_write = '1' and ACK_I = '1' then
|
||||
if ram_index_count /= 2**word_index_width-1 then
|
||||
ram_index_count <= ram_index_count + 1;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
end process;
|
||||
|
||||
fill_counter:
|
||||
mem_index_counter:
|
||||
process(CLK_I)
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if fill_count_en = '0' then
|
||||
fill_count_rdy <= '0';
|
||||
fill_count <= 2**word_index_width-1;
|
||||
else
|
||||
if ACK_I = '1' then
|
||||
if fill_count /= 0 then
|
||||
fill_count <= fill_count - 1;
|
||||
else
|
||||
fill_count_rdy <= '1';
|
||||
end if;
|
||||
if mem_index_count_rst = '1' then
|
||||
mem_index_count <= 0;
|
||||
elsif mem_index_count_en = '1' and SRDY_I = '1' then
|
||||
if mem_index_count /= 2**word_index_width-1 then
|
||||
mem_index_count <= mem_index_count + 1;
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
|
||||
@@ -179,6 +179,9 @@ architecture Behavioral of pipeline is
|
||||
signal ctrl_lines : ctrl_lines_t;
|
||||
signal branch_ce : STD_LOGIC;
|
||||
signal cpu_run : STD_LOGIC;
|
||||
signal mul_dep : STD_LOGIC;
|
||||
signal imem_dep : STD_LOGIC;
|
||||
signal dmem_dep : STD_LOGIC;
|
||||
signal cop_ctrl : cop_ctrl_in_t;
|
||||
signal cop_stat : cop_ctrl_out_t;
|
||||
signal cop_din : word_t;
|
||||
@@ -211,21 +214,21 @@ begin
|
||||
cpu_run <= ce;
|
||||
|
||||
-- Stall Detection Unit ---------------------------------------------------
|
||||
sdu.ID_nop <= sdu.imem_dep or cop_stat.exc_pending or EX_stage.exc or MEM_stage.exc;
|
||||
sdu.EX_nop <= sdu.mul_dep or ID_stage.nop or ID_stage.exc;
|
||||
sdu.ID_nop <= imem_dep or cop_stat.exc_pending or EX_stage.exc or MEM_stage.exc;
|
||||
sdu.EX_nop <= mul_dep or ID_stage.nop or ID_stage.exc;
|
||||
sdu.MEM_nop <= EX_stage.nop or EX_stage.exc;
|
||||
sdu.WB_nop <= sdu.dmem_dep or MEM_stage.nop;
|
||||
sdu.WB_nop <= dmem_dep or MEM_stage.nop;
|
||||
|
||||
sdu.ID_stall <= sdu.dmem_dep or sdu.imem_dep or sdu.mul_dep or ID_stage.exc;
|
||||
sdu.EX_stall <= sdu.dmem_dep;
|
||||
sdu.MEM_stall <= sdu.dmem_dep;
|
||||
sdu.ID_stall <= dmem_dep or imem_dep or mul_dep or ID_stage.exc;
|
||||
sdu.EX_stall <= dmem_dep;
|
||||
sdu.MEM_stall <= dmem_dep;
|
||||
sdu.WB_stall <= '0';
|
||||
|
||||
sdu.mul_dep <= ID_stage.ctrl.mul_access and (EX_stage.ctrl.mul_start or mul_busy);
|
||||
sdu.imem_dep <= not imem_rdy;
|
||||
sdu.dmem_dep <= not dmem_rdy and MEM_stage.ctrl.dmem_en;
|
||||
mul_dep <= ID_stage.ctrl.mul_access and (EX_stage.ctrl.mul_start or mul_busy);
|
||||
imem_dep <= not imem_rdy;
|
||||
dmem_dep <= not dmem_rdy and MEM_stage.ctrl.dmem_en;
|
||||
---------------------------------------------------------------------------
|
||||
imem_en <= cpu_run and not (sdu.mul_dep or sdu.dmem_dep or cop_stat.exc_commit);
|
||||
imem_en <= cpu_run and not (mul_dep or dmem_dep or cop_stat.exc_commit);
|
||||
|
||||
--------------------------------------------------------------------------
|
||||
-- Muldiv
|
||||
@@ -303,13 +306,12 @@ proc_stage_pc_next:
|
||||
process(clk_1)
|
||||
begin
|
||||
if rising_edge(clk_1) then
|
||||
branch_ce <= '0';
|
||||
cop_ctrl.exc_left <= '0';
|
||||
if rst = '1' then
|
||||
pc.nxt <= pc.curr;
|
||||
pc.last <= pc.curr;
|
||||
branch_ce <= '1';
|
||||
else
|
||||
branch_ce <= '0';
|
||||
if cop_stat.exc_commit = '1' then
|
||||
pc.nxt <= cop_stat.exc_vec;
|
||||
elsif sdu.ID_stall = '0' then
|
||||
|
||||
@@ -30,7 +30,7 @@ use IEEE.numeric_std.ALL;
|
||||
package mips_types is
|
||||
|
||||
-- Revision of the CPU
|
||||
constant REVISION : integer := 11;
|
||||
constant REVISION : integer := 10;
|
||||
constant WORD_WIDTH : integer := 32;
|
||||
|
||||
--Types
|
||||
@@ -220,9 +220,6 @@ package mips_types is
|
||||
end record;
|
||||
|
||||
type sdu_t is record
|
||||
imem_dep : STD_LOGIC;
|
||||
dmem_dep : STD_LOGIC;
|
||||
mul_dep : STD_LOGIC;
|
||||
ID_nop : STD_LOGIC;
|
||||
EX_nop : STD_LOGIC;
|
||||
MEM_nop : STD_LOGIC;
|
||||
|
||||
@@ -38,8 +38,8 @@ END tb_mips_top;
|
||||
ARCHITECTURE behavior OF tb_mips_top IS
|
||||
|
||||
constant CLK_PERIOD : time := 10 ns;
|
||||
constant SRAM_ADDR_WIDTH : integer := 15; -- bits
|
||||
constant FLASH_ADDR_WIDTH : integer := 15; -- bits
|
||||
constant SRAM_ADDR_WIDTH : integer := 14; -- bits
|
||||
constant FLASH_ADDR_WIDTH : integer := 14; -- bits
|
||||
|
||||
signal debug : unsigned(1 downto 0);
|
||||
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
CFLAGS=-O2
|
||||
|
||||
CC=gcc
|
||||
PREFIX=/usr/local
|
||||
|
||||
all: romgen ramgen flashgen
|
||||
|
||||
romgen: ./src/romgen.c
|
||||
@@ -10,13 +11,8 @@ ramgen: ./src/ramgen.c
|
||||
$(CC) $(CFLAGS) ./src/ramgen.c -lm -o ./ramgen
|
||||
|
||||
flashgen: ./src/flashgen.c
|
||||
$(CC) $(CFLAGS) ./src/flashgen.c -lm -o ./flashgen_el
|
||||
$(CC) $(CFLAGS) -DTARGET_IS_BIG_ENDIAN ./src/flashgen.c -lm -o ./flashgen_eb
|
||||
$(CC) $(CFLAGS) ./src/flashgen.c -lm -o ./flashgen_little
|
||||
$(CC) $(CFLAGS) -DTARGET_IS_BIG_ENDIAN ./src/flashgen.c -lm -o ./flashgen_big
|
||||
|
||||
install:
|
||||
cp romgen $(PREFIX)/bin
|
||||
cp ramgen $(PREFIX)/bin
|
||||
cp flashgen_el $(PREFIX)/bin
|
||||
cp flashgen_eb $(PREFIX)/bin
|
||||
clean:
|
||||
rm -rf romgen* ramgen* flashgen*
|
||||
|
||||
@@ -321,19 +321,26 @@ read_counter:
|
||||
|
||||
pixel_counter:
|
||||
process(CLK_I)
|
||||
variable pixel_cnt : natural range 0 to MAX_REQUEST_CNT-1;
|
||||
variable pixel_cntx : natural range 0 to tsvga.ts_h.ncyc_scan-1;
|
||||
variable pixel_cnty : natural range 0 to tsvga.ts_h.ncyc_scan*(tsvga.ts_v.ncyc_scan-1);
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if pixel_cnt_rst = '1' then
|
||||
pixel_cnt := 0;
|
||||
pixel_cntx := 0;
|
||||
pixel_cnty := tsvga.ts_h.ncyc_scan*(tsvga.ts_v.ncyc_scan-1);
|
||||
elsif request_cnt_en = '1' and SRDY_I = '1' then
|
||||
if pixel_cnt /= MAX_REQUEST_CNT-1 then
|
||||
pixel_cnt := pixel_cnt + 1;
|
||||
if pixel_cntx /= tsvga.ts_h.ncyc_scan-1 then
|
||||
pixel_cntx := pixel_cntx + 1;
|
||||
else
|
||||
pixel_cnt := 0;
|
||||
end if;
|
||||
end if;
|
||||
ADDR_O <= vga_mem_offset + (to_unsigned(pixel_cnt, 30) & "00");
|
||||
pixel_cntx := 0;
|
||||
if pixel_cnty /= 0 then
|
||||
pixel_cnty := pixel_cnty - tsvga.ts_h.ncyc_scan;
|
||||
else
|
||||
pixel_cnty := tsvga.ts_h.ncyc_scan*(tsvga.ts_v.ncyc_scan-1);
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
ADDR_O <= vga_mem_offset + (to_unsigned(pixel_cntx, 30) & "00") + (to_unsigned(pixel_cnty, 30) & "00");
|
||||
end if;
|
||||
end process;
|
||||
|
||||
|
||||
@@ -325,19 +325,26 @@ read_counter:
|
||||
|
||||
pixel_counter:
|
||||
process(CLK_I)
|
||||
variable pixel_cnt : natural range 0 to MAX_REQUEST_CNT/2-1;
|
||||
variable pixel_cntx : natural range 0 to tsvga.ts_h.ncyc_scan/2-1;
|
||||
variable pixel_cnty : natural range 0 to tsvga.ts_h.ncyc_scan*(tsvga.ts_v.ncyc_scan-1);
|
||||
begin
|
||||
if rising_edge(CLK_I) then
|
||||
if pixel_cnt_rst = '1' then
|
||||
pixel_cnt := 0;
|
||||
pixel_cntx := 0;
|
||||
pixel_cnty := tsvga.ts_h.ncyc_scan*(tsvga.ts_v.ncyc_scan-1);
|
||||
elsif request_cnt_en = '1' and SRDY_I = '1' then
|
||||
if pixel_cnt /= MAX_REQUEST_CNT/2-1 then
|
||||
pixel_cnt := pixel_cnt + 1;
|
||||
if pixel_cntx /= tsvga.ts_h.ncyc_scan/2-1 then
|
||||
pixel_cntx := pixel_cntx + 1;
|
||||
else
|
||||
pixel_cnt := 0;
|
||||
end if;
|
||||
end if;
|
||||
ADDR_O <= vga_mem_offset + (to_unsigned(pixel_cnt, 29) & "000");
|
||||
pixel_cntx := 0;
|
||||
if pixel_cnty /= 0 then
|
||||
pixel_cnty := pixel_cnty - tsvga.ts_h.ncyc_scan;
|
||||
else
|
||||
pixel_cnty := tsvga.ts_h.ncyc_scan*(tsvga.ts_v.ncyc_scan-1);
|
||||
end if;
|
||||
end if;
|
||||
end if;
|
||||
ADDR_O <= vga_mem_offset + (to_unsigned(pixel_cntx, 29) & "000") + (to_unsigned(pixel_cnty, 30) & "00");
|
||||
end if;
|
||||
end process;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user