diff --git a/lib/CPUs/MIPS/bsp/toolchain/newlib-1.16.0-jens.patch b/lib/CPUs/MIPS/bsp/toolchain/newlib-1.16.0-jens.patch new file mode 100644 index 0000000..bf61a14 --- /dev/null +++ b/lib/CPUs/MIPS/bsp/toolchain/newlib-1.16.0-jens.patch @@ -0,0 +1,11 @@ +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" diff --git a/lib/CPUs/MIPS/bsp/toolchain/newlib-1.17.0-jens.patch b/lib/CPUs/MIPS/bsp/toolchain/newlib-1.17.0-jens.patch new file mode 100644 index 0000000..bc28abc --- /dev/null +++ b/lib/CPUs/MIPS/bsp/toolchain/newlib-1.17.0-jens.patch @@ -0,0 +1,11 @@ +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" diff --git a/lib/CPUs/MIPS/dist/tmpl/mips_sys.vhd b/lib/CPUs/MIPS/dist/tmpl/mips_sys.vhd new file mode 100644 index 0000000..9780661 --- /dev/null +++ b/lib/CPUs/MIPS/dist/tmpl/mips_sys.vhd @@ -0,0 +1,335 @@ +------------------------------------------------------------------------- +-- 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 . +-- +-- 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;