Add lm32 "lite" variant, remove mult/div from "minimal" and update compiler flags accordingly.
This commit is contained in:
parent
05c7b9daf4
commit
ed507d618d
|
@ -7,7 +7,7 @@ from litex.soc.interconnect import wishbone
|
||||||
|
|
||||||
class LM32(Module):
|
class LM32(Module):
|
||||||
def __init__(self, platform, eba_reset, variant=None):
|
def __init__(self, platform, eba_reset, variant=None):
|
||||||
assert variant in (None, "minimal"), "Unsupported variant %s" % variant
|
assert variant in (None, "lite", "minimal"), "Unsupported variant %s" % variant
|
||||||
self.reset = Signal()
|
self.reset = Signal()
|
||||||
self.ibus = i = wishbone.Interface()
|
self.ibus = i = wishbone.Interface()
|
||||||
self.dbus = d = wishbone.Interface()
|
self.dbus = d = wishbone.Interface()
|
||||||
|
@ -84,5 +84,7 @@ class LM32(Module):
|
||||||
"lm32_dtlb.v")
|
"lm32_dtlb.v")
|
||||||
if variant == "minimal":
|
if variant == "minimal":
|
||||||
platform.add_verilog_include_path(os.path.join(vdir, "config_minimal"))
|
platform.add_verilog_include_path(os.path.join(vdir, "config_minimal"))
|
||||||
|
elif variant == "lite":
|
||||||
|
platform.add_verilog_include_path(os.path.join(vdir, "config_lite"))
|
||||||
else:
|
else:
|
||||||
platform.add_verilog_include_path(os.path.join(vdir, "config"))
|
platform.add_verilog_include_path(os.path.join(vdir, "config"))
|
||||||
|
|
|
@ -0,0 +1,199 @@
|
||||||
|
`ifdef LM32_CONFIG_V
|
||||||
|
`else
|
||||||
|
`define LM32_CONFIG_V
|
||||||
|
|
||||||
|
//
|
||||||
|
// EXCEPTION VECTORS BASE ADDRESS
|
||||||
|
//
|
||||||
|
|
||||||
|
// Base address for exception vectors
|
||||||
|
`define CFG_EBA_RESET 32'h00000000
|
||||||
|
|
||||||
|
// Base address for the debug exception vectors. If the DC_RE flag is
|
||||||
|
// set or the at_debug signal is asserted (see CFG_ALTERNATE_EBA) this
|
||||||
|
// will also be used for normal exception vectors.
|
||||||
|
`define CFG_DEBA_RESET 32'h10000000
|
||||||
|
|
||||||
|
// Enable exception vector remapping by external signal
|
||||||
|
//`define CFG_ALTERNATE_EBA
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// ALU OPTIONS
|
||||||
|
//
|
||||||
|
|
||||||
|
// Enable sign-extension instructions
|
||||||
|
`define CFG_SIGN_EXTEND_ENABLED
|
||||||
|
|
||||||
|
// Shifter
|
||||||
|
// You may either enable the piplined or the multi-cycle barrel
|
||||||
|
// shifter. The multi-cycle shifter will stall the pipeline until
|
||||||
|
// the result is available after 32 cycles.
|
||||||
|
// If both options are disabled, only "right shift by one bit" is
|
||||||
|
// available.
|
||||||
|
`define CFG_MC_BARREL_SHIFT_ENABLED
|
||||||
|
//`define CFG_PL_BARREL_SHIFT_ENABLED
|
||||||
|
|
||||||
|
// Multiplier
|
||||||
|
// The multiplier is available either in a multi-cycle version or
|
||||||
|
// in a pipelined one. The multi-cycle multiplier stalls the pipe
|
||||||
|
// for 32 cycles. If both options are disabled, multiply operations
|
||||||
|
// are not supported.
|
||||||
|
`define CFG_MC_MULTIPLY_ENABLED
|
||||||
|
//`define CFG_PL_MULTIPLY_ENABLED
|
||||||
|
|
||||||
|
// Enable the multi-cycle divider. Stalls the pipe until the result
|
||||||
|
// is ready after 32 cycles. If disabled, the divide operation is not
|
||||||
|
// supported.
|
||||||
|
`define CFG_MC_DIVIDE_ENABLED
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// INTERRUPTS
|
||||||
|
//
|
||||||
|
|
||||||
|
// Enable support for 32 hardware interrupts
|
||||||
|
`define CFG_INTERRUPTS_ENABLED
|
||||||
|
|
||||||
|
// Enable level-sensitive interrupts. The interrupt line status is
|
||||||
|
// reflected in the IP register, which is then read-only.
|
||||||
|
`define CFG_LEVEL_SENSITIVE_INTERRUPTS
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// USER INSTRUCTION
|
||||||
|
//
|
||||||
|
|
||||||
|
// Enable support for the user opcode.
|
||||||
|
//`define CFG_USER_ENABLED
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// MEMORY MANAGEMENT UNIT
|
||||||
|
//
|
||||||
|
|
||||||
|
// Enable instruction and data translation lookaside buffers and
|
||||||
|
// restricted user mode.
|
||||||
|
//`define CFG_MMU_ENABLED
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// CACHE
|
||||||
|
//
|
||||||
|
|
||||||
|
// Instruction cache
|
||||||
|
`define CFG_ICACHE_ENABLED
|
||||||
|
`define CFG_ICACHE_ASSOCIATIVITY 1
|
||||||
|
`define CFG_ICACHE_SETS 128
|
||||||
|
`define CFG_ICACHE_BYTES_PER_LINE 16
|
||||||
|
`define CFG_ICACHE_BASE_ADDRESS 32'h00000000
|
||||||
|
`define CFG_ICACHE_LIMIT 32'h7fffffff
|
||||||
|
|
||||||
|
// Data cache
|
||||||
|
//`define CFG_DCACHE_ENABLED
|
||||||
|
`define CFG_DCACHE_ASSOCIATIVITY 1
|
||||||
|
`define CFG_DCACHE_SETS 256
|
||||||
|
`define CFG_DCACHE_BYTES_PER_LINE 16
|
||||||
|
`define CFG_DCACHE_BASE_ADDRESS 32'h00000000
|
||||||
|
`define CFG_DCACHE_LIMIT 32'h7fffffff
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// DEBUG OPTION
|
||||||
|
//
|
||||||
|
|
||||||
|
// Globally enable debugging
|
||||||
|
//`define CFG_DEBUG_ENABLED
|
||||||
|
|
||||||
|
// Enable the hardware JTAG debugging interface.
|
||||||
|
// Note: to use this, there must be a special JTAG module for your
|
||||||
|
// device. At the moment, there is only support for the
|
||||||
|
// Spartan-6.
|
||||||
|
//`define CFG_JTAG_ENABLED
|
||||||
|
|
||||||
|
// JTAG UART is a communication channel which uses JTAG to transmit
|
||||||
|
// and receive bytes to and from the host computer.
|
||||||
|
//`define CFG_JTAG_UART_ENABLED
|
||||||
|
|
||||||
|
// Enable reading and writing to the memory and writing CSRs using
|
||||||
|
// the JTAG interface.
|
||||||
|
//`define CFG_HW_DEBUG_ENABLED
|
||||||
|
|
||||||
|
// Number of hardware watchpoints, max. 4
|
||||||
|
//`define CFG_WATCHPOINTS 32'h4
|
||||||
|
|
||||||
|
// Enable hardware breakpoints
|
||||||
|
//`define CFG_ROM_DEBUG_ENABLED
|
||||||
|
|
||||||
|
// Number of hardware breakpoints, max. 4
|
||||||
|
//`define CFG_BREAKPOINTS 32'h4
|
||||||
|
|
||||||
|
// Put the processor into debug mode by an external signal. That is,
|
||||||
|
// raise a breakpoint exception. This is useful if you have a debug
|
||||||
|
// monitor and a serial line and you want to trap into the monitor on a
|
||||||
|
// BREAK symbol on the serial line.
|
||||||
|
//`define CFG_EXTERNAL_BREAK_ENABLED
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// REGISTER FILE
|
||||||
|
//
|
||||||
|
|
||||||
|
// The following option explicitly infers block RAM for the register
|
||||||
|
// file. There is extra logic to avoid parallel writes and reads.
|
||||||
|
// Normally, if your synthesizer is smart enough, this should not be
|
||||||
|
// necessary because it will automatically infer block RAM for you.
|
||||||
|
//`define CFG_EBR_POSEDGE_REGISTER_FILE
|
||||||
|
|
||||||
|
// Explicitly infers block RAM, too. But it uses two different clocks,
|
||||||
|
// one being shifted by 180deg, for the read and write port. Therefore,
|
||||||
|
// no additional logic to avoid the parallel write/reads.
|
||||||
|
//`define CFG_EBR_NEGEDGE_REGISTER_FILE
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// MISCELLANEOUS
|
||||||
|
//
|
||||||
|
|
||||||
|
// Exceptions on wishbone bus errors
|
||||||
|
//`define CFG_BUS_ERRORS_ENABLED
|
||||||
|
|
||||||
|
// Enable the cycle counter
|
||||||
|
`define CFG_CYCLE_COUNTER_ENABLED
|
||||||
|
|
||||||
|
// Embedded instruction ROM using on-chip block RAM
|
||||||
|
//`define CFG_IROM_ENABLED
|
||||||
|
//`define CFG_IROM_INIT_FILE "NONE"
|
||||||
|
//`define CFG_IROM_BASE_ADDRESS 32'h10000000
|
||||||
|
//`define CFG_IROM_LIMIT 32'h10000fff
|
||||||
|
|
||||||
|
// Embedded data RAM using on-chip block RAM
|
||||||
|
//`define CFG_DRAM_ENABLED
|
||||||
|
//`define CFG_DRAM_INIT_FILE "NONE"
|
||||||
|
//`define CFG_DRAM_BASE_ADDRESS 32'h20000000
|
||||||
|
//`define CFG_DRAM_LIMIT 32'h20000fff
|
||||||
|
|
||||||
|
// Trace unit
|
||||||
|
//`define CFG_TRACE_ENABLED
|
||||||
|
|
||||||
|
// Resolve unconditional branches already in the X stage (UNTESTED!)
|
||||||
|
//`define CFG_FAST_UNCONDITIONAL_BRANCH
|
||||||
|
|
||||||
|
// log2 function
|
||||||
|
// If your simulator/synthesizer does not support the $clog2 system
|
||||||
|
// function you can use a constant function instead.
|
||||||
|
|
||||||
|
function integer clog2;
|
||||||
|
input integer value;
|
||||||
|
begin
|
||||||
|
value = value - 1;
|
||||||
|
for (clog2 = 0; value > 0; clog2 = clog2 + 1)
|
||||||
|
value = value >> 1;
|
||||||
|
end
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
`define CLOG2 clog2
|
||||||
|
|
||||||
|
//`define CLOG2 $clog2
|
||||||
|
|
||||||
|
`endif
|
|
@ -39,13 +39,13 @@
|
||||||
// in a pipelined one. The multi-cycle multiplier stalls the pipe
|
// in a pipelined one. The multi-cycle multiplier stalls the pipe
|
||||||
// for 32 cycles. If both options are disabled, multiply operations
|
// for 32 cycles. If both options are disabled, multiply operations
|
||||||
// are not supported.
|
// are not supported.
|
||||||
`define CFG_MC_MULTIPLY_ENABLED
|
//`define CFG_MC_MULTIPLY_ENABLED
|
||||||
//`define CFG_PL_MULTIPLY_ENABLED
|
//`define CFG_PL_MULTIPLY_ENABLED
|
||||||
|
|
||||||
// Enable the multi-cycle divider. Stalls the pipe until the result
|
// Enable the multi-cycle divider. Stalls the pipe until the result
|
||||||
// is ready after 32 cycles. If disabled, the divide operation is not
|
// is ready after 32 cycles. If disabled, the divide operation is not
|
||||||
// supported.
|
// supported.
|
||||||
`define CFG_MC_DIVIDE_ENABLED
|
//`define CFG_MC_DIVIDE_ENABLED
|
||||||
|
|
||||||
|
|
||||||
//
|
//
|
||||||
|
|
|
@ -56,6 +56,7 @@ class Builder:
|
||||||
|
|
||||||
def _generate_includes(self):
|
def _generate_includes(self):
|
||||||
cpu_type = self.soc.cpu_type
|
cpu_type = self.soc.cpu_type
|
||||||
|
cpu_variant = self.soc.cpu_variant
|
||||||
memory_regions = self.soc.get_memory_regions()
|
memory_regions = self.soc.get_memory_regions()
|
||||||
flash_boot_address = getattr(self.soc, "flash_boot_address", None)
|
flash_boot_address = getattr(self.soc, "flash_boot_address", None)
|
||||||
csr_regions = self.soc.get_csr_regions()
|
csr_regions = self.soc.get_csr_regions()
|
||||||
|
@ -68,7 +69,7 @@ class Builder:
|
||||||
variables_contents = []
|
variables_contents = []
|
||||||
def define(k, v):
|
def define(k, v):
|
||||||
variables_contents.append("{}={}\n".format(k, _makefile_escape(v)))
|
variables_contents.append("{}={}\n".format(k, _makefile_escape(v)))
|
||||||
for k, v in cpu_interface.get_cpu_mak(cpu_type):
|
for k, v in cpu_interface.get_cpu_mak(cpu_type, cpu_variant):
|
||||||
define(k, v)
|
define(k, v)
|
||||||
define("SOC_DIRECTORY", soc_directory)
|
define("SOC_DIRECTORY", soc_directory)
|
||||||
variables_contents.append("export BUILDINC_DIRECTORY\n")
|
variables_contents.append("export BUILDINC_DIRECTORY\n")
|
||||||
|
|
|
@ -13,7 +13,7 @@ cpu_endianness = {
|
||||||
"vexriscv": "little"
|
"vexriscv": "little"
|
||||||
}
|
}
|
||||||
|
|
||||||
def get_cpu_mak(cpu):
|
def get_cpu_mak(cpu, variant):
|
||||||
clang = os.getenv("CLANG", "")
|
clang = os.getenv("CLANG", "")
|
||||||
if clang != "":
|
if clang != "":
|
||||||
clang = bool(int(clang))
|
clang = bool(int(clang))
|
||||||
|
@ -23,6 +23,9 @@ def get_cpu_mak(cpu):
|
||||||
if cpu == "lm32":
|
if cpu == "lm32":
|
||||||
assert not clang, "lm32 not supported with clang."
|
assert not clang, "lm32 not supported with clang."
|
||||||
triple = "lm32-elf"
|
triple = "lm32-elf"
|
||||||
|
if variant == "minimal":
|
||||||
|
cpuflags = "-mbarrel-shift-enabled -msign-extend-enabled"
|
||||||
|
else:
|
||||||
cpuflags = "-mbarrel-shift-enabled -mmultiply-enabled -mdivide-enabled -msign-extend-enabled"
|
cpuflags = "-mbarrel-shift-enabled -mmultiply-enabled -mdivide-enabled -msign-extend-enabled"
|
||||||
clang = False
|
clang = False
|
||||||
elif cpu == "or1k":
|
elif cpu == "or1k":
|
||||||
|
|
|
@ -15,7 +15,7 @@ all: libcompiler_rt.a
|
||||||
|
|
||||||
libcompiler_rt.a: $(OBJECTS)
|
libcompiler_rt.a: $(OBJECTS)
|
||||||
$(CC) -c $(CFLAGS) $(1) $(SOC_DIRECTORY)/software/libcompiler_rt/mulsi3.c -o mulsi3.o
|
$(CC) -c $(CFLAGS) $(1) $(SOC_DIRECTORY)/software/libcompiler_rt/mulsi3.c -o mulsi3.o
|
||||||
$(AR) crs libcompiler_rt.a $(OBJECTS)
|
$(AR) crs libcompiler_rt.a $(OBJECTS) mulsi3.o
|
||||||
|
|
||||||
# pull in dependency info for *existing* .o files
|
# pull in dependency info for *existing* .o files
|
||||||
-include $(OBJECTS:.o=.d)
|
-include $(OBJECTS:.o=.d)
|
||||||
|
|
Loading…
Reference in New Issue