Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
78b2eb28cb |
@@ -68,13 +68,19 @@ proc_reg_write:
|
|||||||
reg_cmem_high <= (others => '0');
|
reg_cmem_high <= (others => '0');
|
||||||
reg_bank_sel <= (others => '0');
|
reg_bank_sel <= (others => '0');
|
||||||
reg_int_ctrl.enable <= '0';
|
reg_int_ctrl.enable <= '0';
|
||||||
|
reg_int_ctrl.polarity <= '1';
|
||||||
|
reg_int_ctrl.edge_sens <= '1';
|
||||||
elsif rising_edge(clk) then
|
elsif rising_edge(clk) then
|
||||||
|
reg_int_ctrl.request <= '0';
|
||||||
if we = '1' then
|
if we = '1' then
|
||||||
case addr is
|
case addr is
|
||||||
when X"01" =>
|
when X"01" =>
|
||||||
reg_bank_sel(bank_sel_t'range) <= din(bank_sel_t'range);
|
reg_bank_sel(bank_sel_t'range) <= din(bank_sel_t'range);
|
||||||
when X"03" =>
|
when X"03" =>
|
||||||
reg_int_ctrl.enable <= din(0);
|
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" =>
|
when X"04" =>
|
||||||
reg_cmem_high <= din(IMEM_ADDR_WIDTH-DMEM_ADDR_WIDTH-1 downto 0);
|
reg_cmem_high <= din(IMEM_ADDR_WIDTH-DMEM_ADDR_WIDTH-1 downto 0);
|
||||||
when X"05" =>
|
when X"05" =>
|
||||||
@@ -97,7 +103,7 @@ proc_reg_read:
|
|||||||
when X"02" => -- CPU status
|
when X"02" => -- CPU status
|
||||||
dout <= "000000" & ctrl_in.alu.carry & ctrl_in.alu.zero;
|
dout <= "000000" & ctrl_in.alu.carry & ctrl_in.alu.zero;
|
||||||
when X"03" => -- Interrupt control
|
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
|
when X"04" => -- Upper stack bits out
|
||||||
dout <= "0000" & reg_cmem_high;
|
dout <= "0000" & reg_cmem_high;
|
||||||
when X"05" => -- Upper cmem bits out
|
when X"05" => -- Upper cmem bits out
|
||||||
|
|||||||
@@ -39,6 +39,7 @@ entity cpu is
|
|||||||
ce : in STD_LOGIC;
|
ce : in STD_LOGIC;
|
||||||
int_in : in STD_LOGIC;
|
int_in : in STD_LOGIC;
|
||||||
int_ack : out STD_LOGIC;
|
int_ack : out STD_LOGIC;
|
||||||
|
xmem_wait : in STD_LOGIC;
|
||||||
xmem_we : out STD_LOGIC;
|
xmem_we : out STD_LOGIC;
|
||||||
xmem_re : out STD_LOGIC;
|
xmem_re : out STD_LOGIC;
|
||||||
instr_din : in unsigned (IMEM_DATA_WIDTH-1 downto 0);
|
instr_din : in unsigned (IMEM_DATA_WIDTH-1 downto 0);
|
||||||
@@ -214,6 +215,7 @@ begin
|
|||||||
pc_inc <= cpu_active and ctrl.lines.pc_inc;
|
pc_inc <= cpu_active and ctrl.lines.pc_inc;
|
||||||
stk_addr <= '0' & stk_ptr;
|
stk_addr <= '0' & stk_ptr;
|
||||||
cpu_status.alu <= alu_status;
|
cpu_status.alu <= alu_status;
|
||||||
|
cpu_status.xmem_wait <= xmem_wait;
|
||||||
creg_ctrl_in.alu <= alu_status;
|
creg_ctrl_in.alu <= alu_status;
|
||||||
|
|
||||||
xmem_dout <= mem_data;
|
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;
|
constant IMEM_DATA_WIDTH : integer := INST_OPCODE_WIDTH + DMEM_DATA_WIDTH + REG_SIZE_BITS;
|
||||||
|
|
||||||
-- Microcode ROM
|
-- Microcode ROM
|
||||||
constant MUCODE_ADDR_WIDTH : integer := 9;
|
constant MUCODE_ADDR_WIDTH : integer := 10;
|
||||||
|
|
||||||
-- Stack depth (uses lower half of CHIPRAM)
|
-- Stack depth (uses lower half of CHIPRAM)
|
||||||
constant STACK_SIZE_BITS : integer := CHIPRAM_SIZE_BITS-1;
|
constant STACK_SIZE_BITS : integer := CHIPRAM_SIZE_BITS-1;
|
||||||
@@ -100,6 +100,7 @@ package cpu_pkg is
|
|||||||
|
|
||||||
type cpu_status_t is record
|
type cpu_status_t is record
|
||||||
alu : alu_status_t;
|
alu : alu_status_t;
|
||||||
|
xmem_wait : STD_LOGIC;
|
||||||
end record;
|
end record;
|
||||||
|
|
||||||
type ctrl_lines_t is record
|
type ctrl_lines_t is record
|
||||||
@@ -132,6 +133,9 @@ package cpu_pkg is
|
|||||||
|
|
||||||
type int_ctrl_in_t is record
|
type int_ctrl_in_t is record
|
||||||
enable : std_logic;
|
enable : std_logic;
|
||||||
|
polarity : std_logic;
|
||||||
|
edge_sens : std_logic;
|
||||||
|
request : std_logic;
|
||||||
end record;
|
end record;
|
||||||
|
|
||||||
type creg_ctrl_out_t is 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
|
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 result : ctrl_lines_t;
|
||||||
variable ze, cy : STD_LOGIC;
|
variable ze, cy, xmem_wait : STD_LOGIC;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
ze := status.alu.zero;
|
ze := status.alu.zero;
|
||||||
cy := status.alu.carry;
|
cy := status.alu.carry;
|
||||||
|
xmem_wait := status.xmem_wait;
|
||||||
|
|
||||||
result := ctrl_lines_default;
|
result := ctrl_lines_default;
|
||||||
if iphase = 0 then
|
if iphase = 0 then
|
||||||
@@ -430,6 +435,10 @@ package body cpu_pkg is
|
|||||||
if iphase = 0 then
|
if iphase = 0 then
|
||||||
result.mem_write := '1';
|
result.mem_write := '1';
|
||||||
end if;
|
end if;
|
||||||
|
if xmem_wait = '1' then
|
||||||
|
result.mem_write := '1';
|
||||||
|
result.pc_inc := '0';
|
||||||
|
end if;
|
||||||
when "MOVX|Ri|K " => -- [R(a)] <= kk
|
when "MOVX|Ri|K " => -- [R(a)] <= kk
|
||||||
result.mem_access := xmem_access;
|
result.mem_access := xmem_access;
|
||||||
result.daddr_src_sel := reg_a;
|
result.daddr_src_sel := reg_a;
|
||||||
@@ -437,6 +446,10 @@ package body cpu_pkg is
|
|||||||
if iphase = 0 then
|
if iphase = 0 then
|
||||||
result.mem_write := '1';
|
result.mem_write := '1';
|
||||||
end if;
|
end if;
|
||||||
|
if xmem_wait = '1' then
|
||||||
|
result.mem_write := '1';
|
||||||
|
result.pc_inc := '0';
|
||||||
|
end if;
|
||||||
when "XOUT|Ri|K " => -- [R(a)] <= kk
|
when "XOUT|Ri|K " => -- [R(a)] <= kk
|
||||||
result.mem_access := xio_access;
|
result.mem_access := xio_access;
|
||||||
result.daddr_src_sel := reg_a;
|
result.daddr_src_sel := reg_a;
|
||||||
@@ -444,33 +457,55 @@ package body cpu_pkg is
|
|||||||
if iphase = 0 then
|
if iphase = 0 then
|
||||||
result.mem_write := '1';
|
result.mem_write := '1';
|
||||||
end if;
|
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)]
|
when "MOVX|R|Ri " => -- R(a) <= [R(b)]
|
||||||
result.mem_access := xmem_access;
|
result.mem_access := xmem_access;
|
||||||
result.reg_src_sel := xmem_src;
|
result.reg_src_sel := xmem_src;
|
||||||
result.daddr_src_sel := reg_b;
|
result.daddr_src_sel := reg_b;
|
||||||
if iphase = 0 then
|
if iphase = 0 then
|
||||||
result.mem_read := '1';
|
result.mem_read := '1';
|
||||||
elsif iphase = 1 then
|
end if;
|
||||||
|
if xmem_wait = '0' then
|
||||||
|
if iphase = 1 then
|
||||||
result.reg_we := '1';
|
result.reg_we := '1';
|
||||||
end if;
|
end if;
|
||||||
|
else
|
||||||
|
result.pc_inc := '0';
|
||||||
|
result.mem_read := '1';
|
||||||
|
end if;
|
||||||
when "MOVX|R|Ki " => -- R(a) <= [#addr]
|
when "MOVX|R|Ki " => -- R(a) <= [#addr]
|
||||||
result.mem_access := xmem_access;
|
result.mem_access := xmem_access;
|
||||||
result.reg_src_sel := xmem_src;
|
result.reg_src_sel := xmem_src;
|
||||||
result.daddr_src_sel := const;
|
result.daddr_src_sel := const;
|
||||||
if iphase = 0 then
|
if iphase = 0 then
|
||||||
result.mem_read := '1';
|
result.mem_read := '1';
|
||||||
elsif iphase = 1 then
|
end if;
|
||||||
|
if xmem_wait = '0' then
|
||||||
|
if iphase = 1 then
|
||||||
result.reg_we := '1';
|
result.reg_we := '1';
|
||||||
end if;
|
end if;
|
||||||
|
else
|
||||||
|
result.pc_inc := '0';
|
||||||
|
result.mem_read := '1';
|
||||||
|
end if;
|
||||||
when "XIN|R|Ki " => -- R(a) <= [#addr]
|
when "XIN|R|Ki " => -- R(a) <= [#addr]
|
||||||
result.mem_access := xio_access;
|
result.mem_access := xio_access;
|
||||||
result.reg_src_sel := xmem_src;
|
result.reg_src_sel := xmem_src;
|
||||||
result.daddr_src_sel := const;
|
result.daddr_src_sel := const;
|
||||||
if iphase = 0 then
|
if iphase = 0 then
|
||||||
result.mem_read := '1';
|
result.mem_read := '1';
|
||||||
elsif iphase = 1 then
|
end if;
|
||||||
|
if xmem_wait = '0' then
|
||||||
|
if iphase = 1 then
|
||||||
result.reg_we := '1';
|
result.reg_we := '1';
|
||||||
end if;
|
end if;
|
||||||
|
else
|
||||||
|
result.pc_inc := '0';
|
||||||
|
result.mem_read := '1';
|
||||||
|
end if;
|
||||||
when "MOVX|Ki|R " => -- [#addr] <= R(a)
|
when "MOVX|Ki|R " => -- [#addr] <= R(a)
|
||||||
result.mem_access := xmem_access;
|
result.mem_access := xmem_access;
|
||||||
result.daddr_src_sel := const;
|
result.daddr_src_sel := const;
|
||||||
@@ -478,6 +513,10 @@ package body cpu_pkg is
|
|||||||
if iphase = 0 then
|
if iphase = 0 then
|
||||||
result.mem_write := '1';
|
result.mem_write := '1';
|
||||||
end if;
|
end if;
|
||||||
|
if xmem_wait = '1' then
|
||||||
|
result.pc_inc := '0';
|
||||||
|
result.mem_write := '1';
|
||||||
|
end if;
|
||||||
when "XOUT|Ki|R " => -- [#addr] <= R(a)
|
when "XOUT|Ki|R " => -- [#addr] <= R(a)
|
||||||
result.mem_access := xio_access;
|
result.mem_access := xio_access;
|
||||||
result.daddr_src_sel := const;
|
result.daddr_src_sel := const;
|
||||||
@@ -485,6 +524,10 @@ package body cpu_pkg is
|
|||||||
if iphase = 0 then
|
if iphase = 0 then
|
||||||
result.mem_write := '1';
|
result.mem_write := '1';
|
||||||
end if;
|
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)
|
when "ADD|R|R " => -- R(a) <= R(a) + R(b)
|
||||||
result.alu_opsel := op1_add_op2;
|
result.alu_opsel := op1_add_op2;
|
||||||
result.alu_op1_src_sel := reg_a;
|
result.alu_op1_src_sel := reg_a;
|
||||||
@@ -812,6 +855,8 @@ package body cpu_pkg is
|
|||||||
status.alu.zero := addr(pos);
|
status.alu.zero := addr(pos);
|
||||||
pos := pos + 1;
|
pos := pos + 1;
|
||||||
status.alu.carry := addr(pos);
|
status.alu.carry := addr(pos);
|
||||||
|
pos := pos + 1;
|
||||||
|
status.xmem_wait := addr(pos);
|
||||||
|
|
||||||
result(i) := idecoder(opcode, iphase, status);
|
result(i) := idecoder(opcode, iphase, status);
|
||||||
end loop;
|
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
|
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);
|
variable addr : unsigned(MUCODE_ADDR_WIDTH-1 downto 0);
|
||||||
begin
|
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;
|
return addr;
|
||||||
|
|
||||||
end get_muromaddr;
|
end get_muromaddr;
|
||||||
|
|||||||
@@ -48,11 +48,13 @@ end int_ctrl;
|
|||||||
architecture Behavioral of int_ctrl is
|
architecture Behavioral of int_ctrl is
|
||||||
|
|
||||||
type int_state_t is (int_idle, int_inject, int_active, int_release);
|
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 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 pc_load, int_ack, stk_push, stk_pop : STD_LOGIC;
|
||||||
signal int_request : std_logic;
|
signal int_request : std_logic;
|
||||||
|
signal int_sampled : std_logic;
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
@@ -72,6 +74,7 @@ irg_ctrl_fsm:
|
|||||||
pc_load <= '0';
|
pc_load <= '0';
|
||||||
stk_push <= '0';
|
stk_push <= '0';
|
||||||
stk_pop <= '0';
|
stk_pop <= '0';
|
||||||
|
|
||||||
case int_state is
|
case int_state is
|
||||||
|
|
||||||
when int_idle =>
|
when int_idle =>
|
||||||
@@ -118,10 +121,46 @@ pin_sample:
|
|||||||
process (clk)
|
process (clk)
|
||||||
begin
|
begin
|
||||||
if rising_edge(clk) then
|
if rising_edge(clk) then
|
||||||
int_request <= '0';
|
int_sampled <= int_in xor (not ctrl_in.polarity);
|
||||||
if ctrl_in.enable = '1' then
|
end if;
|
||||||
int_request <= int_in;
|
end process;
|
||||||
end if;
|
|
||||||
|
-----------------------------------------------------------------------
|
||||||
|
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 if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,8 @@
|
|||||||
|
TOOLS_DIR=../../tools
|
||||||
|
|
||||||
CFLAGS=-msoft-float -O2 -march=r3000 -I.
|
CFLAGS=-msoft-float -O2 -march=r3000 -I.
|
||||||
LFLAGS=-M -T link.ld
|
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
|
LIBS=-lc -lm -lgcc
|
||||||
|
|
||||||
AS=mipsel-elf-as
|
AS=mipsel-elf-as
|
||||||
@@ -9,9 +11,9 @@ CC=mipsel-elf-gcc
|
|||||||
LD=mipsel-elf-ld
|
LD=mipsel-elf-ld
|
||||||
OBJDUMP=mipsel-elf-objdump
|
OBJDUMP=mipsel-elf-objdump
|
||||||
OBJCOPY=mipsel-elf-objcopy
|
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)
|
all: $(PROG)
|
||||||
|
|
||||||
@@ -128,13 +130,5 @@ richards_benchmark: richards_benchmark.c
|
|||||||
$(OBJCOPY) -O srec $@.elf $@.srec
|
$(OBJCOPY) -O srec $@.elf $@.srec
|
||||||
$(FLASHGEN) $@.bin
|
$(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:
|
clean:
|
||||||
rm -rf *.a *.o *.bin *.map *.dis *.srec *.elf $(PROG) > /dev/null
|
rm -rf *.a *.o *.bin *.map *.dis *.srec *.elf $(PROG) > /dev/null
|
||||||
|
|||||||
@@ -1,8 +1,9 @@
|
|||||||
ROM_WORDADDR_WIDTH=11
|
ROM_WORDADDR_WIDTH=11
|
||||||
|
TOOLS_DIR=../../../tools
|
||||||
|
|
||||||
CFLAGS=-Os -I. -I../ -msoft-float -march=r3000
|
CFLAGS=-Os -I. -I../ -msoft-float -march=r3000
|
||||||
LFLAGS=-M -T bootloader.ld
|
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
|
LIBS=-lc -lgcc
|
||||||
|
|
||||||
CC=mipsel-elf-gcc
|
CC=mipsel-elf-gcc
|
||||||
@@ -24,7 +25,7 @@ bootloader: libsys bootloader.c
|
|||||||
$(OBJDUMP) -d bootloader.elf > bootloader.dis
|
$(OBJDUMP) -d bootloader.elf > bootloader.dis
|
||||||
$(OBJCOPY) bootloader.elf -O binary bootloader.ROM.bin
|
$(OBJCOPY) bootloader.elf -O binary bootloader.ROM.bin
|
||||||
$(OBJCOPY) -O srec bootloader.elf bootloader.srec
|
$(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
|
bootloader_flash: libsys bootloader_with_flash.c
|
||||||
$(CC) $(CFLAGS) -g -c 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
|
$(OBJDUMP) -d bootloader.elf > bootloader.dis
|
||||||
$(OBJCOPY) bootloader.elf -O binary bootloader.ROM.bin
|
$(OBJCOPY) bootloader.elf -O binary bootloader.ROM.bin
|
||||||
$(OBJCOPY) -O srec bootloader.elf bootloader.srec
|
$(OBJCOPY) -O srec bootloader.elf bootloader.srec
|
||||||
romgen bootloader.ROM.bin 11
|
$(TOOLS_DIR)/romgen bootloader.ROM.bin 11
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
rm -rf *.o *.bin *.map *.dis *.srec *.elf *.vhd* *.tcl bootloader > /dev/null
|
rm -rf *.o *.bin *.map *.dis *.srec *.elf *.vhd* *.tcl bootloader > /dev/null
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ _init:
|
|||||||
|
|
||||||
# set stack pointer
|
# set stack pointer
|
||||||
la $sp, stack_ptr
|
la $sp, stack_ptr
|
||||||
j $jmain
|
# j $jmain
|
||||||
|
|
||||||
# TEST
|
# TEST
|
||||||
li $26, +5
|
li $26, +5
|
||||||
|
|||||||
@@ -13,7 +13,6 @@ int main (void)
|
|||||||
|
|
||||||
*pGPIO0 = 0xAAAAAAAA;
|
*pGPIO0 = 0xAAAAAAAA;
|
||||||
*pGPIO1 = 0xAAAAAAAA;
|
*pGPIO1 = 0xAAAAAAAA;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -34,14 +34,12 @@ $zeroise:
|
|||||||
# addiu $8, 4
|
# addiu $8, 4
|
||||||
|
|
||||||
# jump main
|
# jump main
|
||||||
la $t0, main
|
la $8, main
|
||||||
jalr $t0
|
jalr $8
|
||||||
nop
|
|
||||||
|
|
||||||
_terminate:
|
_terminate:
|
||||||
nop
|
nop
|
||||||
la $t0, exit
|
j _terminate
|
||||||
jalr $t0
|
nop
|
||||||
move $a0, $v0
|
|
||||||
|
|
||||||
.set reorder
|
.set reorder
|
||||||
|
|||||||
@@ -3,7 +3,6 @@
|
|||||||
#include <sys/resource.h>
|
#include <sys/resource.h>
|
||||||
#include <sys/stat.h>
|
#include <sys/stat.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdio.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include "libsys.h"
|
#include "libsys.h"
|
||||||
|
|
||||||
@@ -151,8 +150,9 @@ void _cg_putchar(char c)
|
|||||||
|
|
||||||
void _exit (int exitcode)
|
void _exit (int exitcode)
|
||||||
{
|
{
|
||||||
fflush(stdout);
|
sputs("_exit(");
|
||||||
fflush(stderr);
|
print_word(exitcode);
|
||||||
|
sputs(")\n");
|
||||||
while(1);
|
while(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -239,31 +239,29 @@ int settimeofday(const struct timeval *tp, const struct timezone *tzp)
|
|||||||
caddr_t sbrk(int incr)
|
caddr_t sbrk(int incr)
|
||||||
{
|
{
|
||||||
extern char end;
|
extern char end;
|
||||||
extern char stack_ptr;
|
|
||||||
static char *heap_end;
|
static char *heap_end;
|
||||||
char *prev_heap_end;
|
char *prev_heap_end;
|
||||||
|
|
||||||
if (heap_end == 0)
|
if (heap_end == 0)
|
||||||
{
|
|
||||||
heap_end = &end;
|
heap_end = &end;
|
||||||
}
|
|
||||||
|
|
||||||
prev_heap_end = heap_end;
|
prev_heap_end = heap_end;
|
||||||
if (heap_end + incr > &stack_ptr)
|
// if (heap_end + incr > stack_ptr)
|
||||||
{
|
// {
|
||||||
// sputs("Heap and stack collision\n");
|
// sputs("Heap and stack collision\r\n");
|
||||||
// sputs("Stack Ptr = ");print_word(&stack_ptr);sputs("\n");
|
// abort();
|
||||||
// sputs("Heap end = ");print_word(heap_end);sputs("\n");
|
// }
|
||||||
// sputs("Increment = ");print_word(incr);sputs("\n");
|
|
||||||
exit(1);
|
// sputs("\n");
|
||||||
}
|
// print_word((int)prev_heap_end);
|
||||||
|
// sputs("\n");
|
||||||
heap_end += incr;
|
heap_end += incr;
|
||||||
return (caddr_t) prev_heap_end;
|
return (caddr_t) prev_heap_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
int fstat(int file, struct stat *st)
|
int fstat(int file, struct stat *st)
|
||||||
{
|
{
|
||||||
// sputs("fstat\n");
|
// sputs("Fstat()\n");
|
||||||
st->st_mode = S_IFCHR;
|
st->st_mode = S_IFCHR;
|
||||||
st->st_blksize = 0;
|
st->st_blksize = 0;
|
||||||
return 0;
|
return 0;
|
||||||
@@ -271,49 +269,41 @@ int fstat(int file, struct stat *st)
|
|||||||
|
|
||||||
int lseek(int file, int ptr, int dir)
|
int lseek(int file, int ptr, int dir)
|
||||||
{
|
{
|
||||||
// sputs("lseek\n");
|
sputs("Lseek()\n");
|
||||||
|
|
||||||
errno = ESPIPE;
|
errno = ESPIPE;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int open(const char *name, int flags, int mode)
|
int open(const char *name, int flags, int mode)
|
||||||
{
|
{
|
||||||
// sputs("open\n");
|
sputs("Open()\n");
|
||||||
errno = EIO;
|
errno = EIO;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int close(int file)
|
int close(int file)
|
||||||
{
|
{
|
||||||
// sputs("close\n");
|
sputs("Close()\n");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int read(int file, char *ptr, int len)
|
int read(int file, char *ptr, int len)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char c;
|
|
||||||
|
|
||||||
// sputs("read\n");
|
// sputs("Read()\n");
|
||||||
i = 0;
|
for (i = 0; i < len; i++)
|
||||||
while (i < len)
|
|
||||||
{
|
{
|
||||||
c = readchar();
|
ptr[i] = readchar();
|
||||||
if ((c == 0x0D) || (c == 0x0A))
|
if ((ptr[i] == '\n') || (ptr[i] == '\r'))
|
||||||
{
|
{
|
||||||
|
i++;
|
||||||
writechar(0x0D);
|
writechar(0x0D);
|
||||||
writechar(0x0A);
|
writechar(0x0A);
|
||||||
if (i==0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
ptr[i++] = c;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else
|
writechar(ptr[i]);
|
||||||
{
|
|
||||||
ptr[i++] = c;
|
|
||||||
writechar(c);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return i;
|
return i;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -51,12 +51,8 @@
|
|||||||
//#define STDOUT_FUNCTION _cg_putchar // Video character
|
//#define STDOUT_FUNCTION _cg_putchar // Video character
|
||||||
//#define STDERR_FUNCTION _putchar // Serial output
|
//#define STDERR_FUNCTION _putchar // Serial output
|
||||||
|
|
||||||
#ifndef STDOUT_FUNCTION
|
|
||||||
#define STDOUT_FUNCTION _putchar // Serial output
|
#define STDOUT_FUNCTION _putchar // Serial output
|
||||||
#endif
|
|
||||||
#ifndef STDERR_FUNCTION
|
|
||||||
#define STDERR_FUNCTION _putchar // Serial output
|
#define STDERR_FUNCTION _putchar // Serial output
|
||||||
#endif
|
|
||||||
|
|
||||||
UINT32 CP0_SR_read(void);
|
UINT32 CP0_SR_read(void);
|
||||||
void CP0_SR_write(UINT32 val);
|
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 <string.h>
|
||||||
#include <math.h>
|
#include <math.h>
|
||||||
#include <time.h>
|
#include <time.h>
|
||||||
#include <sys/times.h>
|
|
||||||
#include <sys/time.h>
|
|
||||||
#include "libsys.h"
|
#include "libsys.h"
|
||||||
|
|
||||||
#define NO_ERROR 0x00000000
|
#define NO_ERROR 0x00000000
|
||||||
@@ -24,14 +22,11 @@ void handler3(void)
|
|||||||
{
|
{
|
||||||
volatile UINT32 *pUART_stat = (UINT32*)sys_uart_stat;
|
volatile UINT32 *pUART_stat = (UINT32*)sys_uart_stat;
|
||||||
volatile UINT32 *pUART_data = (UINT32*)sys_uart_data;
|
volatile UINT32 *pUART_data = (UINT32*)sys_uart_data;
|
||||||
volatile UINT32 *pLED = (UINT32*)sys_led_port;
|
|
||||||
|
|
||||||
while((0x10 & *pUART_stat))
|
while((0x10 & *pUART_stat))
|
||||||
{
|
{
|
||||||
buffer[i] = (char)*pUART_data;
|
buffer[i] = (char)*pUART_data;
|
||||||
*pLED = buffer[i]*buffer[i];
|
|
||||||
i = (i+1)%sizeof(buffer);
|
i = (i+1)%sizeof(buffer);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -209,7 +204,7 @@ int Test10_LoadStore()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#define NUM_ELEMENTS 10000
|
#define NUM_ELEMENTS 100000
|
||||||
#define NUM_RUNS 3
|
#define NUM_RUNS 3
|
||||||
int Test11_AddSub()
|
int Test11_AddSub()
|
||||||
{
|
{
|
||||||
@@ -304,7 +299,7 @@ int pi_calc()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define TEST_SIZE (128*1024) // Bytes
|
#define TEST_SIZE (32*1024*1024) // Bytes
|
||||||
#define SMALL_TEST_SIZE (8192) // Bytes
|
#define SMALL_TEST_SIZE (8192) // Bytes
|
||||||
int main (void)
|
int main (void)
|
||||||
{
|
{
|
||||||
@@ -317,8 +312,7 @@ int main (void)
|
|||||||
time_t curr_date;
|
time_t curr_date;
|
||||||
struct tm *pDate, date;
|
struct tm *pDate, date;
|
||||||
UINT32 start, end;
|
UINT32 start, end;
|
||||||
char sel[80];
|
char sel;
|
||||||
struct timeval time_sec;
|
|
||||||
|
|
||||||
UINT8 *ram8 = NULL;
|
UINT8 *ram8 = NULL;
|
||||||
UINT16 *ram16 = NULL;
|
UINT16 *ram16 = NULL;
|
||||||
@@ -528,12 +522,9 @@ int main (void)
|
|||||||
sputs("\r\n");
|
sputs("\r\n");
|
||||||
|
|
||||||
printf("Datum und Uhrzeit setzen? [j/N]: ");
|
printf("Datum und Uhrzeit setzen? [j/N]: ");
|
||||||
scanf("%s", sel);
|
scanf("%c", &sel);
|
||||||
if (toupper(sel[0]) == 'J')
|
if (toupper(sel) == 'J')
|
||||||
{
|
{
|
||||||
do
|
|
||||||
{
|
|
||||||
printf("Datum\n");
|
|
||||||
printf("Jahr : ");
|
printf("Jahr : ");
|
||||||
scanf("%d", &date.tm_year);
|
scanf("%d", &date.tm_year);
|
||||||
printf("Monat : ");
|
printf("Monat : ");
|
||||||
@@ -541,30 +532,7 @@ int main (void)
|
|||||||
printf("Tag : ");
|
printf("Tag : ");
|
||||||
scanf("%d", &date.tm_mday);
|
scanf("%d", &date.tm_mday);
|
||||||
|
|
||||||
printf("Uhrzeit\n");
|
printf("Wir haben heute den %d. %d. %d\n", date.tm_mday, date.tm_mon, date.tm_year);
|
||||||
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');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
interrupt_enable(3);
|
interrupt_enable(3);
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ char *_xcpt_code_str[32] =
|
|||||||
#define PRINT_REG(tag_str, reg) \
|
#define PRINT_REG(tag_str, reg) \
|
||||||
sputs(tag_str); \
|
sputs(tag_str); \
|
||||||
print_word(reg); \
|
print_word(reg); \
|
||||||
sputs(" ");
|
sputs("\n");
|
||||||
|
|
||||||
int _xcpt_default_dispatch(struct xcptcontext * xcp)
|
int _xcpt_default_dispatch(struct xcptcontext * xcp)
|
||||||
{
|
{
|
||||||
@@ -55,57 +55,48 @@ int _xcpt_deliver(struct xcptcontext * _xcp)
|
|||||||
if (_xcpt_dispatch(_xcp))
|
if (_xcpt_dispatch(_xcp))
|
||||||
{
|
{
|
||||||
sputs("\n");
|
sputs("\n");
|
||||||
PRINT_REG(" Status : ", _xcp->sr);
|
PRINT_REG("Status : ", _xcp->sr);
|
||||||
PRINT_REG(" Cause : ", _xcp->cr);
|
PRINT_REG("Cause : ", _xcp->cr);
|
||||||
PRINT_REG(" EPC : ", _xcp->epc);
|
PRINT_REG("EPC : ", _xcp->epc);
|
||||||
PRINT_REG("BadAddr : ", _xcp->baddr);
|
PRINT_REG("BadAddr : ", _xcp->baddr);
|
||||||
sputs("\n");
|
PRINT_REG("MDLO : ", _xcp->mdlo);
|
||||||
PRINT_REG(" MDLO : ", _xcp->mdlo);
|
PRINT_REG("MDHI : ", _xcp->mdhi);
|
||||||
PRINT_REG(" MDHI : ", _xcp->mdhi);
|
|
||||||
|
|
||||||
sputs("\n");
|
sputs("\n");
|
||||||
|
|
||||||
sputs("Registers:\n");
|
sputs("Registers:\n");
|
||||||
PRINT_REG(" 0 (ze) : ", _xcp->regs[0]);
|
PRINT_REG(" 0 (zero) : ", _xcp->regs[0]);
|
||||||
PRINT_REG(" 1 (at) : ", _xcp->regs[1]);
|
PRINT_REG(" 1 (at) : ", _xcp->regs[1]);
|
||||||
PRINT_REG(" 2 (v0) : ", _xcp->regs[2]);
|
PRINT_REG(" 2 (v0) : ", _xcp->regs[2]);
|
||||||
PRINT_REG(" 3 (v1) : ", _xcp->regs[3]);
|
PRINT_REG(" 3 (v1) : ", _xcp->regs[3]);
|
||||||
sputs("\n");
|
PRINT_REG(" 4 (a0) : ", _xcp->regs[4]);
|
||||||
PRINT_REG(" 4 (a0) : ", _xcp->regs[4]);
|
PRINT_REG(" 5 (a1) : ", _xcp->regs[5]);
|
||||||
PRINT_REG(" 5 (a1) : ", _xcp->regs[5]);
|
PRINT_REG(" 6 (a2) : ", _xcp->regs[6]);
|
||||||
PRINT_REG(" 6 (a2) : ", _xcp->regs[6]);
|
PRINT_REG(" 7 (a3) : ", _xcp->regs[7]);
|
||||||
PRINT_REG(" 7 (a3) : ", _xcp->regs[7]);
|
PRINT_REG(" 8 (t0) : ", _xcp->regs[8]);
|
||||||
sputs("\n");
|
PRINT_REG(" 9 (t1) : ", _xcp->regs[9]);
|
||||||
PRINT_REG(" 8 (t0) : ", _xcp->regs[8]);
|
PRINT_REG("10 (t2) : ", _xcp->regs[10]);
|
||||||
PRINT_REG(" 9 (t1) : ", _xcp->regs[9]);
|
PRINT_REG("11 (t3) : ", _xcp->regs[11]);
|
||||||
PRINT_REG("10 (t2) : ", _xcp->regs[10]);
|
PRINT_REG("12 (t4) : ", _xcp->regs[12]);
|
||||||
PRINT_REG("11 (t3) : ", _xcp->regs[11]);
|
PRINT_REG("13 (t5) : ", _xcp->regs[13]);
|
||||||
sputs("\n");
|
PRINT_REG("14 (t6) : ", _xcp->regs[14]);
|
||||||
PRINT_REG("12 (t4) : ", _xcp->regs[12]);
|
PRINT_REG("15 (t7) : ", _xcp->regs[15]);
|
||||||
PRINT_REG("13 (t5) : ", _xcp->regs[13]);
|
PRINT_REG("16 (s0) : ", _xcp->regs[16]);
|
||||||
PRINT_REG("14 (t6) : ", _xcp->regs[14]);
|
PRINT_REG("17 (s1) : ", _xcp->regs[17]);
|
||||||
PRINT_REG("15 (t7) : ", _xcp->regs[15]);
|
PRINT_REG("18 (s2) : ", _xcp->regs[18]);
|
||||||
sputs("\n");
|
PRINT_REG("19 (s3) : ", _xcp->regs[19]);
|
||||||
PRINT_REG("16 (s0) : ", _xcp->regs[16]);
|
PRINT_REG("20 (s4) : ", _xcp->regs[20]);
|
||||||
PRINT_REG("17 (s1) : ", _xcp->regs[17]);
|
PRINT_REG("21 (s5) : ", _xcp->regs[21]);
|
||||||
PRINT_REG("18 (s2) : ", _xcp->regs[18]);
|
PRINT_REG("22 (s6) : ", _xcp->regs[22]);
|
||||||
PRINT_REG("19 (s3) : ", _xcp->regs[19]);
|
PRINT_REG("23 (s7) : ", _xcp->regs[23]);
|
||||||
sputs("\n");
|
PRINT_REG("24 (t8) : ", _xcp->regs[24]);
|
||||||
PRINT_REG("20 (s4) : ", _xcp->regs[20]);
|
PRINT_REG("25 (t9) : ", _xcp->regs[25]);
|
||||||
PRINT_REG("21 (s5) : ", _xcp->regs[21]);
|
PRINT_REG("26 (k0) : ", _xcp->regs[26]);
|
||||||
PRINT_REG("22 (s6) : ", _xcp->regs[22]);
|
PRINT_REG("27 (k1) : ", _xcp->regs[27]);
|
||||||
PRINT_REG("23 (s7) : ", _xcp->regs[23]);
|
PRINT_REG("28 (gp) : ", _xcp->regs[28]);
|
||||||
sputs("\n");
|
PRINT_REG("29 (sp) : ", _xcp->regs[29]);
|
||||||
PRINT_REG("24 (t8) : ", _xcp->regs[24]);
|
PRINT_REG("30 (fp) : ", _xcp->regs[30]);
|
||||||
PRINT_REG("25 (t9) : ", _xcp->regs[25]);
|
PRINT_REG("31 (ra) : ", _xcp->regs[31]);
|
||||||
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");
|
|
||||||
sputs("\n");
|
sputs("\n");
|
||||||
|
|
||||||
exc_code = (_xcp->cr >> 2) & 0x1F;
|
exc_code = (_xcp->cr >> 2) & 0x1F;
|
||||||
|
|||||||
@@ -2,150 +2,46 @@
|
|||||||
TARGET=mipsel-elf
|
TARGET=mipsel-elf
|
||||||
PREFIX=/usr/local
|
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
|
# 1. Binutils bauen und installieren
|
||||||
# ---------------------------------------------------------------
|
# ---------------------------------------------------------------
|
||||||
if [ ! -e $SRC_BINUTILS.tar.bz2 ]; then
|
if [ ! -d ./binutils-2.19 ]; then
|
||||||
echo Downloading $SRC_BINUTILS
|
tar -xjf binutils-2.19.tar.bz2
|
||||||
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
|
fi
|
||||||
|
|
||||||
if [ ! -e ./$SRC_BINUTILS ]; then
|
if [ ! -d ./binutils-2.19_build ]; then
|
||||||
echo Unpacking $SRC_BINUTILS
|
mkdir -p binutils-2.19_build
|
||||||
tar -xjf $SRC_BINUTILS.tar.bz2 || exit 1
|
cd binutils-2.19_build
|
||||||
else
|
../binutils-2.19/configure --target=$TARGET --prefix=$PREFIX
|
||||||
echo Skipped unpacking $SRC_BINUTILS
|
make
|
||||||
fi
|
make install
|
||||||
|
|
||||||
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
|
|
||||||
cd ..
|
cd ..
|
||||||
else
|
else
|
||||||
echo $SRC_BINUTILS is already built.
|
echo binutils is already built.
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# ---------------------------------------------------------------
|
# ---------------------------------------------------------------
|
||||||
# 2. GMP bauen und installieren
|
# 2. GCC & newlib bauen und installieren
|
||||||
# ---------------------------------------------------------------
|
# ---------------------------------------------------------------
|
||||||
if [ ! -e $SRC_GMP.tar.bz2 ]; then
|
if [ ! -d ./newlib-1.16.0 ]; then
|
||||||
echo Downloading $SRC_GMP
|
tar -xzf newlib-1.16.0.tar.gz
|
||||||
wget http://ftp.sunet.se/pub/gnu/gmp/$SRC_GMP.tar.bz2 || exit 1
|
|
||||||
else
|
|
||||||
echo Skipped downloading $SRC_GMP
|
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -e ./$SRC_GMP ]; then
|
if [ ! -d ./gcc-4.3.2 ]; then
|
||||||
echo Unpacking $SRC_GMP
|
tar -xjf gcc-4.3.2.tar.bz2
|
||||||
tar -xjf $SRC_GMP.tar.bz2 || exit 1
|
cd ./gcc-4.3.2
|
||||||
else
|
ln -sf ../newlib-1.16.0/newlib/ .
|
||||||
echo Skipped unpacking $SRC_GMP
|
cd ..
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ ! -e ./$SRC_GMP-build ]; then
|
if [ ! -d ./gcc-4.3.2_build ]; then
|
||||||
echo Building $SRC_GMP
|
mkdir -p gcc-4.3.2_build
|
||||||
mkdir -p $SRC_GMP-build
|
cd gcc-4.3.2_build
|
||||||
cd $SRC_GMP-build
|
../gcc-4.3.2/configure --target=$TARGET --prefix=$PREFIX --with-float=soft --with-newlib --verbose --enable-languages="c,c++"
|
||||||
../$SRC_GMP/configure --prefix=$PREFIX || exit 1
|
make all
|
||||||
make || exit 1
|
make info
|
||||||
make check || exit 1
|
make install
|
||||||
make install || exit 1
|
|
||||||
cd ..
|
cd ..
|
||||||
else
|
else
|
||||||
echo $SRC_GMP is already built.
|
echo GCC 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.
|
|
||||||
fi
|
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"
|
PROJECT="mips_top"
|
||||||
DIST_FILE="./files.dist"
|
DIST_FILE="./files.dist"
|
||||||
DIST_DIR="./release/mips.r11"
|
DIST_DIR="./release/mips.r10a"
|
||||||
|
|
||||||
# ---------------------------------------------------------------
|
# ---------------------------------------------------------------
|
||||||
mkdir -p $DIST_DIR/src
|
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 ../doc/*.txt $DIST_DIR/doc/
|
||||||
cp -a ../tools/* $DIST_DIR/tools/
|
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/gpl-3.0.txt $DIST_DIR/
|
||||||
cp -a ./tmpl/tb_mips_top.wdo $DIST_DIR/sim/
|
cp -a ./tmpl/tb_mips_top.wdo $DIST_DIR/sim/
|
||||||
cp -a ./tmpl/hello.flash.bin $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
|
for i in $(cat -s $DIST_FILE); do
|
||||||
echo $i;
|
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 -divider ALU
|
||||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
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 /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 -divider PC
|
||||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
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 -format Literal -radix hexadecimal /tb_mips_top/uut/inst_pipeline/pc
|
||||||
add wave -noupdate -divider COP0
|
add wave -noupdate -divider PC
|
||||||
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 Logic /tb_mips_top/clk
|
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 Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_pipeline/id_stage
|
||||||
add wave -noupdate -format Logic /tb_mips_top/clk
|
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 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 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/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 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 -format Logic /tb_mips_top/uut/inst_pipeline/run_en
|
||||||
add wave -noupdate -divider I-Cache
|
add wave -noupdate -format Literal -radix hexadecimal -expand /tb_mips_top/uut/inst_pipeline/inst_reg_dual/reg_mem
|
||||||
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
|
|
||||||
TreeUpdate [SetDefaultTree]
|
TreeUpdate [SetDefaultTree]
|
||||||
WaveRestoreCursors {{Cursor 1} {2127774 ps} 0}
|
WaveRestoreCursors {{Cursor 1} {1375665640 ps} 0}
|
||||||
configure wave -namecolwidth 188
|
configure wave -namecolwidth 188
|
||||||
configure wave -valuecolwidth 100
|
configure wave -valuecolwidth 100
|
||||||
configure wave -justifyvalue left
|
configure wave -justifyvalue left
|
||||||
@@ -144,4 +71,4 @@ configure wave -gridperiod 100
|
|||||||
configure wave -griddelta 40
|
configure wave -griddelta 40
|
||||||
configure wave -timeline 1
|
configure wave -timeline 1
|
||||||
update
|
update
|
||||||
WaveRestoreZoom {0 ps} {5031559 ps}
|
WaveRestoreZoom {0 ps} {1680 us}
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ END COMPONENT;
|
|||||||
return result;
|
return result;
|
||||||
end to_tram_data;
|
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 s, sn : cache_state_t;
|
||||||
|
|
||||||
signal cache_busy : std_logic;
|
signal cache_busy : std_logic;
|
||||||
@@ -162,18 +162,17 @@ END COMPONENT;
|
|||||||
signal tram_we : std_logic;
|
signal tram_we : std_logic;
|
||||||
|
|
||||||
signal fill_count : natural range 0 to 2**word_index_width-1;
|
signal fill_count : natural range 0 to 2**word_index_width-1;
|
||||||
signal fill_count_en : std_logic;
|
signal fill_count_rst : std_logic;
|
||||||
signal fill_count_rdy : std_logic;
|
signal flush_index_count : natural range 0 to 2**cache_index_width-1;
|
||||||
signal flush_count : natural range 0 to 2**cache_index_width-1;
|
signal flush_index_count_en : std_logic;
|
||||||
signal flush_count_en : std_logic;
|
signal request_count : natural range 0 to 2**word_index_width-1;
|
||||||
signal flush_count_rdy : std_logic;
|
signal request_count_en : std_logic;
|
||||||
signal request_count : natural range 0 to 2**word_index_width-1;
|
signal request_count_rst : std_logic;
|
||||||
signal request_count_en : std_logic;
|
signal cpu_reg_en : std_logic;
|
||||||
signal request_count_rdy : std_logic;
|
signal was_miss : std_logic;
|
||||||
signal cpu_reg_en : std_logic;
|
signal cache_fill : std_logic;
|
||||||
signal was_miss : std_logic;
|
signal cpu_hit_we : std_logic;
|
||||||
signal cpu_hit_we : std_logic;
|
signal instant_raw : std_logic;
|
||||||
signal instant_raw : std_logic;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
@@ -183,7 +182,7 @@ cpu_index_register:
|
|||||||
process(CLK_I)
|
process(CLK_I)
|
||||||
begin
|
begin
|
||||||
if rising_edge(CLK_I) then
|
if rising_edge(CLK_I) then
|
||||||
if fill_count_en = '1' then
|
if cache_fill = '1' then
|
||||||
if ACK_I = '1' then
|
if ACK_I = '1' then
|
||||||
word_index_reg <= word_index_reg + 1;
|
word_index_reg <= word_index_reg + 1;
|
||||||
end if;
|
end if;
|
||||||
@@ -199,10 +198,8 @@ addr_windex_register:
|
|||||||
process(CLK_I)
|
process(CLK_I)
|
||||||
begin
|
begin
|
||||||
if rising_edge(CLK_I) then
|
if rising_edge(CLK_I) then
|
||||||
if request_count_en = '1'then
|
if request_count_en = '1' and SRDY_I = '1' then
|
||||||
if SRDY_I = '1' then
|
addr_windex_reg <= addr_windex_reg + 1;
|
||||||
addr_windex_reg <= addr_windex_reg + 1;
|
|
||||||
end if;
|
|
||||||
elsif cpu_reg_en = '1' and en = '1' and instant_raw = '0' then
|
elsif cpu_reg_en = '1' and en = '1' and instant_raw = '0' then
|
||||||
addr_windex_reg <= cpu_word_index;
|
addr_windex_reg <= cpu_word_index;
|
||||||
end if;
|
end if;
|
||||||
@@ -249,13 +246,11 @@ instant_raw_logic:
|
|||||||
end process;
|
end process;
|
||||||
|
|
||||||
inst_tag_ram : dpram_1w1r
|
inst_tag_ram : dpram_1w1r
|
||||||
GENERIC MAP
|
GENERIC MAP (
|
||||||
(
|
|
||||||
addr_width => tram_addr_width,
|
addr_width => tram_addr_width,
|
||||||
data_width => tram_data_width
|
data_width => tram_data_width
|
||||||
)
|
)
|
||||||
PORT MAP
|
PORT MAP (
|
||||||
(
|
|
||||||
clka => CLK_I,
|
clka => CLK_I,
|
||||||
clkb => CLK_I,
|
clkb => CLK_I,
|
||||||
en_a => '1',
|
en_a => '1',
|
||||||
@@ -272,13 +267,11 @@ gen_data_ram:
|
|||||||
begin
|
begin
|
||||||
|
|
||||||
inst_data_ram : dpram_2w2r
|
inst_data_ram : dpram_2w2r
|
||||||
GENERIC MAP
|
GENERIC MAP (
|
||||||
(
|
|
||||||
addr_width => lg2(cache_size),
|
addr_width => lg2(cache_size),
|
||||||
data_width => word_t'length/4
|
data_width => word_t'length/4
|
||||||
)
|
)
|
||||||
PORT MAP
|
PORT MAP (
|
||||||
(
|
|
||||||
clk_a => CLK_I,
|
clk_a => CLK_I,
|
||||||
clk_b => CLK_I,
|
clk_b => CLK_I,
|
||||||
en_a => '1',
|
en_a => '1',
|
||||||
@@ -312,28 +305,30 @@ cache_state_next:
|
|||||||
tag_match <= '1' when tag_index_reg = cache_entry_out.tag else '0';
|
tag_match <= '1' when tag_index_reg = cache_entry_out.tag else '0';
|
||||||
cache_hit <= tag_match and cache_entry_out.valid;
|
cache_hit <= tag_match and cache_entry_out.valid;
|
||||||
tram_din <= to_tram_data(cache_entry_in);
|
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;
|
tram_addr_rd <= cpu_cache_index when was_miss = '0' else cache_index_reg;
|
||||||
cache_entry_out <= to_dcache_entry(tram_dout);
|
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";
|
ADDR_O <= tag_index_reg & cache_index_reg & addr_windex_reg & "00";
|
||||||
ctrl_dram_addr <= cache_index_reg & word_index_reg;
|
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');
|
cpu_dram_we <= cpu_be_reg when (cpu_hit_we = '1') else (others => '0');
|
||||||
|
|
||||||
cache_state:
|
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
|
begin
|
||||||
cpu_reg_en <= '0';
|
cpu_reg_en <= '0';
|
||||||
cache_busy <= '1';
|
cache_busy <= '1';
|
||||||
tram_we <= '0';
|
tram_we <= '0';
|
||||||
flush_count_en <= '0';
|
flush_index_count_en <= '0';
|
||||||
|
fill_count_rst <= '0';
|
||||||
request_count_en <= '0';
|
request_count_en <= '0';
|
||||||
fill_count_en <= '0';
|
request_count_rst <= '0';
|
||||||
CYC_O <= '0';
|
CYC_O <= '0';
|
||||||
STB_O <= '0';
|
STB_O <= '0';
|
||||||
was_miss <= '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.tv_p <= (others => '0');
|
||||||
cache_entry_in.tag <= tag_index_reg;
|
cache_entry_in.tag <= tag_index_reg;
|
||||||
cache_entry_in.valid <= '0';
|
cache_entry_in.valid <= '0';
|
||||||
@@ -354,39 +349,47 @@ cache_state:
|
|||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
when flush =>
|
when flush =>
|
||||||
flush_count_en <= '1';
|
flush_index_count_en <= '1';
|
||||||
tram_we <= '1';
|
tram_addr_wr <= to_unsigned(flush_index_count, cache_index_width);
|
||||||
|
tram_we <= '1';
|
||||||
cache_entry_in.valid <= '0';
|
cache_entry_in.valid <= '0';
|
||||||
cache_entry_in.tag <= (others => '0');
|
cache_entry_in.tag <= (others => '0');
|
||||||
if flush_count_rdy = '1' then
|
if flush_index_count = 0 then
|
||||||
tram_we <= '0';
|
|
||||||
sn <= ready;
|
sn <= ready;
|
||||||
if cpu_en = '1' then
|
if cpu_en = '1' then
|
||||||
cpu_reg_en <= '1';
|
cpu_reg_en <= '1';
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
when mem_request =>
|
when mem_request =>
|
||||||
|
fill_count_rst <= '1';
|
||||||
|
request_count_rst <= '1';
|
||||||
CYC_O <= '1';
|
CYC_O <= '1';
|
||||||
if SRDY_I = '1' then
|
if SRDY_I = '1' then
|
||||||
sn <= mem_access;
|
sn <= mem_access;
|
||||||
end if;
|
end if;
|
||||||
when mem_access =>
|
when mem_access =>
|
||||||
fill_count_en <= '1';
|
cache_fill <= '1';
|
||||||
request_count_en <= '1';
|
request_count_en <= '1';
|
||||||
CYC_O <= '1';
|
CYC_O <= '1';
|
||||||
STB_O <= '1';
|
STB_O <= '1';
|
||||||
if request_count_rdy = '1' then
|
if request_count = 0 then
|
||||||
STB_O <= '0';
|
if SRDY_I = '1' then
|
||||||
sn <= mem_data;
|
sn <= mem_data;
|
||||||
|
end if;
|
||||||
end if;
|
end if;
|
||||||
when mem_data =>
|
when mem_data =>
|
||||||
CYC_O <= '1';
|
CYC_O <= '1';
|
||||||
fill_count_en <= '1';
|
cache_fill <= '1';
|
||||||
if fill_count_rdy = '1' then
|
if fill_count = 0 then
|
||||||
tram_we <= '1';
|
if ACK_I = '1' then
|
||||||
cache_entry_in.valid <= '1';
|
sn <= upd_cache;
|
||||||
sn <= rd_cache;
|
end if;
|
||||||
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 =>
|
when rd_cache =>
|
||||||
was_miss <= '1';
|
was_miss <= '1';
|
||||||
sn <= ready;
|
sn <= ready;
|
||||||
@@ -394,21 +397,29 @@ cache_state:
|
|||||||
when others =>
|
when others =>
|
||||||
sn <= ready;
|
sn <= ready;
|
||||||
end case;
|
end case;
|
||||||
|
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
flush_counter:
|
flush_index_counter:
|
||||||
process(CLK_I)
|
process(CLK_I)
|
||||||
begin
|
begin
|
||||||
if rising_edge(CLK_I) then
|
if rising_edge(CLK_I) then
|
||||||
if flush_count_en = '0' then
|
if flush_index_count_en = '0' then
|
||||||
flush_count_rdy <= '0';
|
flush_index_count <= 2**cache_index_width-1;
|
||||||
flush_count <= 2**cache_index_width-1;
|
elsif flush_index_count /= 0 then
|
||||||
else
|
flush_index_count <= flush_index_count - 1;
|
||||||
if flush_count /= 0 then
|
end if;
|
||||||
flush_count <= flush_count - 1;
|
end if;
|
||||||
else
|
end process;
|
||||||
flush_count_rdy <= '1';
|
|
||||||
|
fill_counter:
|
||||||
|
process(CLK_I)
|
||||||
|
begin
|
||||||
|
if rising_edge(CLK_I) then
|
||||||
|
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 if;
|
||||||
end if;
|
end if;
|
||||||
@@ -418,35 +429,11 @@ request_counter:
|
|||||||
process(CLK_I)
|
process(CLK_I)
|
||||||
begin
|
begin
|
||||||
if rising_edge(CLK_I) then
|
if rising_edge(CLK_I) then
|
||||||
if request_count_en = '0' then
|
if request_count_rst = '1' then
|
||||||
request_count_rdy <= '0';
|
request_count <= 2**word_index_width-1;
|
||||||
request_count <= 2**word_index_width-1;
|
elsif request_count_en = '1' and SRDY_I = '1' then
|
||||||
else
|
if request_count /= 0 then
|
||||||
if SRDY_I = '1' then
|
request_count <= request_count - 1;
|
||||||
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;
|
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
|
|||||||
@@ -101,14 +101,13 @@ END COMPONENT;
|
|||||||
return result;
|
return result;
|
||||||
end to_tag_ram_data;
|
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 s, sn : cache_state_t;
|
||||||
|
|
||||||
signal cache_busy : std_logic;
|
signal cache_busy : std_logic;
|
||||||
signal cache_miss : std_logic;
|
signal cache_miss : std_logic;
|
||||||
signal tag_match : std_logic;
|
signal tag_match : std_logic;
|
||||||
signal word_index_reg : unsigned(word_index_width-1 downto 0);
|
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 cache_index_reg : unsigned(cache_index_width-1 downto 0);
|
||||||
signal tag_index_reg : unsigned(tag_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_data_rd : tag_ram_data_t;
|
||||||
signal tag_ram_addr_wr : unsigned(cache_index_width-1 downto 0);
|
signal tag_ram_addr_wr : unsigned(cache_index_width-1 downto 0);
|
||||||
signal tag_ram_data_wr : tag_ram_data_t;
|
signal tag_ram_data_wr : tag_ram_data_t;
|
||||||
signal tag_ram_re : std_logic;
|
|
||||||
signal tag_ram_we : std_logic;
|
signal tag_ram_we : std_logic;
|
||||||
|
|
||||||
signal fill_count : natural range 0 to 2**word_index_width-1;
|
signal ram_index_count : natural range 0 to 2**word_index_width-1;
|
||||||
signal fill_count_en : std_logic;
|
signal ram_index_count_rst : std_logic;
|
||||||
signal fill_count_rdy : std_logic;
|
signal cache_index_count : natural range 0 to 2**cache_index_width-1;
|
||||||
signal flush_count : natural range 0 to 2**cache_index_width-1;
|
signal cache_index_count_en : std_logic;
|
||||||
signal flush_count_en : std_logic;
|
signal mem_index_count : natural range 0 to 2**word_index_width-1;
|
||||||
signal flush_count_rdy : std_logic;
|
signal mem_index_count_en : std_logic;
|
||||||
signal request_count : natural range 0 to 2**word_index_width-1;
|
signal mem_index_count_rst : std_logic;
|
||||||
signal request_count_en : std_logic;
|
signal cpu_reg_en : std_logic;
|
||||||
signal request_count_rdy : std_logic;
|
signal was_miss : std_logic;
|
||||||
signal cpu_reg_en : std_logic;
|
signal data_write : std_logic;
|
||||||
signal was_miss : std_logic;
|
|
||||||
|
|
||||||
begin
|
begin
|
||||||
|
|
||||||
@@ -150,10 +147,6 @@ cpu_index_reg:
|
|||||||
if RST_I = '1' then
|
if RST_I = '1' then
|
||||||
cache_index_reg <= (others => '0');
|
cache_index_reg <= (others => '0');
|
||||||
tag_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
|
elsif cpu_reg_en = '1' then
|
||||||
word_index_reg <= cpu_word_index;
|
word_index_reg <= cpu_word_index;
|
||||||
cache_index_reg <= cpu_cache_index;
|
cache_index_reg <= cpu_cache_index;
|
||||||
@@ -162,32 +155,16 @@ cpu_index_reg:
|
|||||||
end if;
|
end if;
|
||||||
end process;
|
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
|
inst_tag_ram : dpram_1w1r
|
||||||
GENERIC MAP
|
GENERIC MAP (
|
||||||
(
|
|
||||||
addr_width => tag_ram_addr_width,
|
addr_width => tag_ram_addr_width,
|
||||||
data_width => tag_ram_data_width
|
data_width => tag_ram_data_width
|
||||||
)
|
)
|
||||||
PORT MAP
|
PORT MAP (
|
||||||
(
|
|
||||||
clka => CLK_I,
|
clka => CLK_I,
|
||||||
clkb => CLK_I,
|
clkb => CLK_I,
|
||||||
en_a => '1',
|
en_a => '1',
|
||||||
en_b => tag_ram_re,
|
en_b => '1',
|
||||||
we_a => tag_ram_we,
|
we_a => tag_ram_we,
|
||||||
addr_a => tag_ram_addr_wr,
|
addr_a => tag_ram_addr_wr,
|
||||||
addr_b => tag_ram_addr_rd,
|
addr_b => tag_ram_addr_rd,
|
||||||
@@ -196,13 +173,11 @@ inst_tag_ram : dpram_1w1r
|
|||||||
);
|
);
|
||||||
|
|
||||||
inst_data_ram : dpram_1w1r
|
inst_data_ram : dpram_1w1r
|
||||||
GENERIC MAP
|
GENERIC MAP (
|
||||||
(
|
|
||||||
addr_width => lg2(cache_size),
|
addr_width => lg2(cache_size),
|
||||||
data_width => word_t'length
|
data_width => word_t'length
|
||||||
)
|
)
|
||||||
PORT MAP
|
PORT MAP (
|
||||||
(
|
|
||||||
clka => CLK_I,
|
clka => CLK_I,
|
||||||
clkb => CLK_I,
|
clkb => CLK_I,
|
||||||
en_a => '1',
|
en_a => '1',
|
||||||
@@ -233,29 +208,30 @@ cache_state_next:
|
|||||||
tag_match <= '1' when tag_index_reg = cache_entry_out.tag else '0';
|
tag_match <= '1' when tag_index_reg = cache_entry_out.tag else '0';
|
||||||
cache_miss <= not (tag_match and cache_entry_out.valid);
|
cache_miss <= not (tag_match and cache_entry_out.valid);
|
||||||
tag_ram_data_wr <= to_tag_ram_data(cache_entry_in);
|
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;
|
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);
|
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);
|
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";
|
ADDR_O <= tag_index_reg & cache_index_reg & to_unsigned(mem_index_count, word_index_width) & "00";
|
||||||
data_ram_addr_wr <= cache_index_reg & word_index_reg;
|
data_ram_addr_wr <= cache_index_reg & to_unsigned(ram_index_count, word_index_width);
|
||||||
data_ram_data_wr <= DAT_I;
|
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:
|
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
|
begin
|
||||||
cpu_reg_en <= '0';
|
cpu_reg_en <= '0';
|
||||||
cache_busy <= '1';
|
cache_busy <= '1';
|
||||||
tag_ram_we <= '0';
|
tag_ram_we <= '0';
|
||||||
flush_count_en <= '0';
|
cache_index_count_en <= '0';
|
||||||
request_count_en <= '0';
|
ram_index_count_rst <= '0';
|
||||||
fill_count_en <= '0';
|
mem_index_count_en <= '0';
|
||||||
|
mem_index_count_rst <= '0';
|
||||||
CYC_O <= '0';
|
CYC_O <= '0';
|
||||||
STB_O <= '0';
|
STB_O <= '0';
|
||||||
data_ram_re <= '0';
|
data_ram_re <= '0';
|
||||||
tag_ram_re <= '0';
|
|
||||||
was_miss <= '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.tv_p <= (others => '0');
|
||||||
cache_entry_in.tag <= tag_index_reg;
|
cache_entry_in.tag <= tag_index_reg;
|
||||||
cache_entry_in.valid <= '0';
|
cache_entry_in.valid <= '0';
|
||||||
@@ -275,107 +251,96 @@ cache_state:
|
|||||||
elsif cpu_en = '1' then
|
elsif cpu_en = '1' then
|
||||||
cpu_reg_en <= '1';
|
cpu_reg_en <= '1';
|
||||||
data_ram_re <= '1';
|
data_ram_re <= '1';
|
||||||
tag_ram_re <= '1';
|
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
when flush =>
|
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';
|
tag_ram_we <= '1';
|
||||||
cache_entry_in.valid <= '0';
|
cache_entry_in.valid <= '0';
|
||||||
cache_entry_in.tag <= (others => '0');
|
cache_entry_in.tag <= (others => '0');
|
||||||
if flush_count_rdy = '1' then
|
if cache_index_count = 0 then
|
||||||
tag_ram_we <= '0';
|
|
||||||
sn <= ready;
|
sn <= ready;
|
||||||
if cpu_en = '1' then
|
if cpu_en = '1' then
|
||||||
cpu_reg_en <= '1';
|
cpu_reg_en <= '1';
|
||||||
data_ram_re <= '1';
|
data_ram_re <= '1';
|
||||||
tag_ram_re <= '1';
|
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
when mem_request =>
|
when mem_request =>
|
||||||
|
ram_index_count_rst <= '1';
|
||||||
|
mem_index_count_rst <= '1';
|
||||||
CYC_O <= '1';
|
CYC_O <= '1';
|
||||||
if SRDY_I = '1' then
|
if SRDY_I = '1' then
|
||||||
sn <= mem_access;
|
sn <= mem_access;
|
||||||
end if;
|
end if;
|
||||||
when mem_access =>
|
when mem_access =>
|
||||||
request_count_en <= '1';
|
mem_index_count_en <= '1';
|
||||||
fill_count_en <= '1';
|
data_write <= '1';
|
||||||
CYC_O <= '1';
|
CYC_O <= '1';
|
||||||
STB_O <= '1';
|
STB_O <= '1';
|
||||||
if request_count_rdy = '1' then
|
if mem_index_count = 2**word_index_width-1 then
|
||||||
STB_O <= '0';
|
if SRDY_I = '1' then
|
||||||
sn <= mem_data;
|
sn <= mem_data;
|
||||||
|
end if;
|
||||||
end if;
|
end if;
|
||||||
when mem_data =>
|
when mem_data =>
|
||||||
CYC_O <= '1';
|
CYC_O <= '1';
|
||||||
fill_count_en <= '1';
|
data_write <= '1';
|
||||||
if fill_count_rdy = '1' then
|
if ram_index_count = 2**word_index_width-1 then
|
||||||
tag_ram_we <= '1';
|
if ACK_I = '1' then
|
||||||
cache_entry_in.valid <= '1';
|
sn <= upd_cache;
|
||||||
sn <= rd_cache;
|
end if;
|
||||||
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 =>
|
when rd_cache =>
|
||||||
tag_ram_re <= '1';
|
|
||||||
data_ram_re <= '1';
|
data_ram_re <= '1';
|
||||||
was_miss <= '1';
|
was_miss <= '1';
|
||||||
sn <= ready;
|
sn <= ready;
|
||||||
|
|
||||||
when others =>
|
when others =>
|
||||||
sn <= ready;
|
sn <= ready;
|
||||||
end case;
|
end case;
|
||||||
|
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
flush_counter:
|
cache_index_counter:
|
||||||
process(CLK_I)
|
process(CLK_I)
|
||||||
begin
|
begin
|
||||||
if rising_edge(CLK_I) then
|
if rising_edge(CLK_I) then
|
||||||
if flush_count_en = '0' then
|
if cache_index_count_en = '0' then
|
||||||
flush_count_rdy <= '0';
|
cache_index_count <= 2**cache_index_width-1;
|
||||||
flush_count <= 2**cache_index_width-1;
|
elsif cache_index_count /= 0 then
|
||||||
else
|
cache_index_count <= cache_index_count - 1;
|
||||||
if flush_count /= 0 then
|
end if;
|
||||||
flush_count <= flush_count - 1;
|
end if;
|
||||||
else
|
end process;
|
||||||
flush_count_rdy <= '1';
|
|
||||||
|
ram_index_counter:
|
||||||
|
process(CLK_I)
|
||||||
|
begin
|
||||||
|
if rising_edge(CLK_I) then
|
||||||
|
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 if;
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
request_counter:
|
mem_index_counter:
|
||||||
process(CLK_I)
|
process(CLK_I)
|
||||||
begin
|
begin
|
||||||
if rising_edge(CLK_I) then
|
if rising_edge(CLK_I) then
|
||||||
if request_count_en = '0' then
|
if mem_index_count_rst = '1' then
|
||||||
request_count_rdy <= '0';
|
mem_index_count <= 0;
|
||||||
request_count <= 2**word_index_width-1;
|
elsif mem_index_count_en = '1' and SRDY_I = '1' then
|
||||||
else
|
if mem_index_count /= 2**word_index_width-1 then
|
||||||
if SRDY_I = '1' then
|
mem_index_count <= mem_index_count + 1;
|
||||||
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;
|
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
end if;
|
end if;
|
||||||
|
|||||||
@@ -179,6 +179,9 @@ architecture Behavioral of pipeline is
|
|||||||
signal ctrl_lines : ctrl_lines_t;
|
signal ctrl_lines : ctrl_lines_t;
|
||||||
signal branch_ce : STD_LOGIC;
|
signal branch_ce : STD_LOGIC;
|
||||||
signal cpu_run : 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_ctrl : cop_ctrl_in_t;
|
||||||
signal cop_stat : cop_ctrl_out_t;
|
signal cop_stat : cop_ctrl_out_t;
|
||||||
signal cop_din : word_t;
|
signal cop_din : word_t;
|
||||||
@@ -211,21 +214,21 @@ begin
|
|||||||
cpu_run <= ce;
|
cpu_run <= ce;
|
||||||
|
|
||||||
-- Stall Detection Unit ---------------------------------------------------
|
-- Stall Detection Unit ---------------------------------------------------
|
||||||
sdu.ID_nop <= sdu.imem_dep or cop_stat.exc_pending or EX_stage.exc or MEM_stage.exc;
|
sdu.ID_nop <= 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.EX_nop <= mul_dep or ID_stage.nop or ID_stage.exc;
|
||||||
sdu.MEM_nop <= EX_stage.nop or EX_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.ID_stall <= dmem_dep or imem_dep or mul_dep or ID_stage.exc;
|
||||||
sdu.EX_stall <= sdu.dmem_dep;
|
sdu.EX_stall <= dmem_dep;
|
||||||
sdu.MEM_stall <= sdu.dmem_dep;
|
sdu.MEM_stall <= dmem_dep;
|
||||||
sdu.WB_stall <= '0';
|
sdu.WB_stall <= '0';
|
||||||
|
|
||||||
sdu.mul_dep <= ID_stage.ctrl.mul_access and (EX_stage.ctrl.mul_start or mul_busy);
|
mul_dep <= ID_stage.ctrl.mul_access and (EX_stage.ctrl.mul_start or mul_busy);
|
||||||
sdu.imem_dep <= not imem_rdy;
|
imem_dep <= not imem_rdy;
|
||||||
sdu.dmem_dep <= not dmem_rdy and MEM_stage.ctrl.dmem_en;
|
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
|
-- Muldiv
|
||||||
@@ -303,13 +306,12 @@ proc_stage_pc_next:
|
|||||||
process(clk_1)
|
process(clk_1)
|
||||||
begin
|
begin
|
||||||
if rising_edge(clk_1) then
|
if rising_edge(clk_1) then
|
||||||
|
branch_ce <= '0';
|
||||||
cop_ctrl.exc_left <= '0';
|
cop_ctrl.exc_left <= '0';
|
||||||
if rst = '1' then
|
if rst = '1' then
|
||||||
pc.nxt <= pc.curr;
|
pc.nxt <= pc.curr;
|
||||||
pc.last <= pc.curr;
|
pc.last <= pc.curr;
|
||||||
branch_ce <= '1';
|
|
||||||
else
|
else
|
||||||
branch_ce <= '0';
|
|
||||||
if cop_stat.exc_commit = '1' then
|
if cop_stat.exc_commit = '1' then
|
||||||
pc.nxt <= cop_stat.exc_vec;
|
pc.nxt <= cop_stat.exc_vec;
|
||||||
elsif sdu.ID_stall = '0' then
|
elsif sdu.ID_stall = '0' then
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ use IEEE.numeric_std.ALL;
|
|||||||
package mips_types is
|
package mips_types is
|
||||||
|
|
||||||
-- Revision of the CPU
|
-- Revision of the CPU
|
||||||
constant REVISION : integer := 11;
|
constant REVISION : integer := 10;
|
||||||
constant WORD_WIDTH : integer := 32;
|
constant WORD_WIDTH : integer := 32;
|
||||||
|
|
||||||
--Types
|
--Types
|
||||||
@@ -220,9 +220,6 @@ package mips_types is
|
|||||||
end record;
|
end record;
|
||||||
|
|
||||||
type sdu_t is record
|
type sdu_t is record
|
||||||
imem_dep : STD_LOGIC;
|
|
||||||
dmem_dep : STD_LOGIC;
|
|
||||||
mul_dep : STD_LOGIC;
|
|
||||||
ID_nop : STD_LOGIC;
|
ID_nop : STD_LOGIC;
|
||||||
EX_nop : STD_LOGIC;
|
EX_nop : STD_LOGIC;
|
||||||
MEM_nop : STD_LOGIC;
|
MEM_nop : STD_LOGIC;
|
||||||
|
|||||||
@@ -38,8 +38,8 @@ END tb_mips_top;
|
|||||||
ARCHITECTURE behavior OF tb_mips_top IS
|
ARCHITECTURE behavior OF tb_mips_top IS
|
||||||
|
|
||||||
constant CLK_PERIOD : time := 10 ns;
|
constant CLK_PERIOD : time := 10 ns;
|
||||||
constant SRAM_ADDR_WIDTH : integer := 15; -- bits
|
constant SRAM_ADDR_WIDTH : integer := 14; -- bits
|
||||||
constant FLASH_ADDR_WIDTH : integer := 15; -- bits
|
constant FLASH_ADDR_WIDTH : integer := 14; -- bits
|
||||||
|
|
||||||
signal debug : unsigned(1 downto 0);
|
signal debug : unsigned(1 downto 0);
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
CFLAGS=-O2
|
CFLAGS=-O2
|
||||||
|
|
||||||
CC=gcc
|
CC=gcc
|
||||||
PREFIX=/usr/local
|
|
||||||
all: romgen ramgen flashgen
|
all: romgen ramgen flashgen
|
||||||
|
|
||||||
romgen: ./src/romgen.c
|
romgen: ./src/romgen.c
|
||||||
@@ -10,13 +11,8 @@ ramgen: ./src/ramgen.c
|
|||||||
$(CC) $(CFLAGS) ./src/ramgen.c -lm -o ./ramgen
|
$(CC) $(CFLAGS) ./src/ramgen.c -lm -o ./ramgen
|
||||||
|
|
||||||
flashgen: ./src/flashgen.c
|
flashgen: ./src/flashgen.c
|
||||||
$(CC) $(CFLAGS) ./src/flashgen.c -lm -o ./flashgen_el
|
$(CC) $(CFLAGS) ./src/flashgen.c -lm -o ./flashgen_little
|
||||||
$(CC) $(CFLAGS) -DTARGET_IS_BIG_ENDIAN ./src/flashgen.c -lm -o ./flashgen_eb
|
$(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:
|
clean:
|
||||||
rm -rf romgen* ramgen* flashgen*
|
rm -rf romgen* ramgen* flashgen*
|
||||||
|
|||||||
@@ -321,19 +321,26 @@ read_counter:
|
|||||||
|
|
||||||
pixel_counter:
|
pixel_counter:
|
||||||
process(CLK_I)
|
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
|
begin
|
||||||
if rising_edge(CLK_I) then
|
if rising_edge(CLK_I) then
|
||||||
if pixel_cnt_rst = '1' 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
|
elsif request_cnt_en = '1' and SRDY_I = '1' then
|
||||||
if pixel_cnt /= MAX_REQUEST_CNT-1 then
|
if pixel_cntx /= tsvga.ts_h.ncyc_scan-1 then
|
||||||
pixel_cnt := pixel_cnt + 1;
|
pixel_cntx := pixel_cntx + 1;
|
||||||
else
|
else
|
||||||
pixel_cnt := 0;
|
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;
|
||||||
end if;
|
end if;
|
||||||
ADDR_O <= vga_mem_offset + (to_unsigned(pixel_cnt, 30) & "00");
|
ADDR_O <= vga_mem_offset + (to_unsigned(pixel_cntx, 30) & "00") + (to_unsigned(pixel_cnty, 30) & "00");
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
|
|||||||
@@ -325,19 +325,26 @@ read_counter:
|
|||||||
|
|
||||||
pixel_counter:
|
pixel_counter:
|
||||||
process(CLK_I)
|
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
|
begin
|
||||||
if rising_edge(CLK_I) then
|
if rising_edge(CLK_I) then
|
||||||
if pixel_cnt_rst = '1' 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
|
elsif request_cnt_en = '1' and SRDY_I = '1' then
|
||||||
if pixel_cnt /= MAX_REQUEST_CNT/2-1 then
|
if pixel_cntx /= tsvga.ts_h.ncyc_scan/2-1 then
|
||||||
pixel_cnt := pixel_cnt + 1;
|
pixel_cntx := pixel_cntx + 1;
|
||||||
else
|
else
|
||||||
pixel_cnt := 0;
|
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;
|
||||||
end if;
|
end if;
|
||||||
ADDR_O <= vga_mem_offset + (to_unsigned(pixel_cnt, 29) & "000");
|
ADDR_O <= vga_mem_offset + (to_unsigned(pixel_cntx, 29) & "000") + (to_unsigned(pixel_cnty, 30) & "00");
|
||||||
end if;
|
end if;
|
||||||
end process;
|
end process;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user