mirror of
https://github.com/enjoy-digital/litex.git
synced 2025-01-04 09:52:26 -05:00
sor/cores/cpu: Add CDIM MIPS CPU
CQU Dual Issue Machine, Dual issue 5-stage pipeline MIPS32 CPU capable for running Linux. https://github.com/Maxpicca-Li/CDIM Signed-off-by: Jiaxun Yang <jiaxun.yang@flygoat.com>
This commit is contained in:
parent
bffbb4ffea
commit
b7ed16b190
6 changed files with 242 additions and 0 deletions
1
litex/soc/cores/cpu/cdim/__init__.py
Normal file
1
litex/soc/cores/cpu/cdim/__init__.py
Normal file
|
@ -0,0 +1 @@
|
|||
from litex.soc.cores.cpu.cdim.core import CDIM
|
4
litex/soc/cores/cpu/cdim/boot-helper.S
Normal file
4
litex/soc/cores/cpu/cdim/boot-helper.S
Normal file
|
@ -0,0 +1,4 @@
|
|||
.section .text, "ax", @progbits
|
||||
.global boot_helper
|
||||
boot_helper:
|
||||
jr $a3
|
129
litex/soc/cores/cpu/cdim/core.py
Normal file
129
litex/soc/cores/cpu/cdim/core.py
Normal file
|
@ -0,0 +1,129 @@
|
|||
#
|
||||
# This file is part of LiteX.
|
||||
#
|
||||
# Copyright (c) 2024 Jiaxun Yang <jiaxun.yang@flygoat.com>
|
||||
# SPDX-License-Identifier: BSD-2-Clause
|
||||
|
||||
import os
|
||||
|
||||
from migen import *
|
||||
from litex.gen import *
|
||||
|
||||
from litex.soc.interconnect import axi
|
||||
from litex.soc.cores.cpu import CPU, CPU_GCC_TRIPLE_MIPS
|
||||
|
||||
class CDIM(CPU):
|
||||
category = "softcore"
|
||||
family = "mips"
|
||||
name = "cdim"
|
||||
human_name = "CQU CDIM"
|
||||
variants = ["standard"]
|
||||
data_width = 32
|
||||
endianness = "little"
|
||||
gcc_triple = CPU_GCC_TRIPLE_MIPS
|
||||
linker_output_format = "elf32-tradlittlemips"
|
||||
nop = "nop"
|
||||
io_regions = {0x1000_0000: 0x0c00_0000} # Origin, Length.
|
||||
|
||||
# GCC Flags.
|
||||
@property
|
||||
def gcc_flags(self):
|
||||
flags = "-march=mips32 -mabi=32 -EL -msoft-float"
|
||||
flags += " -D__cdim__ "
|
||||
flags += " -DUART_POLLING"
|
||||
return flags
|
||||
|
||||
# Memory Mapping.
|
||||
@property
|
||||
def mem_map(self):
|
||||
# Based on vanilla sysmap.h
|
||||
return {
|
||||
"main_ram" : 0x0000_0000,
|
||||
"csr" : 0x1800_0000,
|
||||
"sram" : 0x1c00_0000,
|
||||
"rom" : 0x1fc0_0000,
|
||||
}
|
||||
|
||||
def __init__(self, platform, variant="standard"):
|
||||
self.platform = platform
|
||||
self.variant = variant
|
||||
self.reset = Signal()
|
||||
self.interrupt = Signal(6)
|
||||
# Peripheral bus (Connected to main SoC's bus).
|
||||
axi_if = axi.AXIInterface(data_width=32, address_width=32, id_width=4)
|
||||
self.periph_buses = [axi_if]
|
||||
# Memory buses (Connected directly to LiteDRAM).
|
||||
self.memory_buses = []
|
||||
|
||||
# CPU Instance.
|
||||
self.cpu_params = dict(
|
||||
# Clk / Rst
|
||||
i_aclk = ClockSignal("sys"),
|
||||
i_aresetn = ~ResetSignal("sys") & ~self.reset,
|
||||
|
||||
# Interrupts
|
||||
i_ext_int= self.interrupt,
|
||||
|
||||
# AXI interface
|
||||
o_arid = axi_if.ar.id,
|
||||
o_araddr = axi_if.ar.addr,
|
||||
o_arlen = axi_if.ar.len,
|
||||
o_arsize = axi_if.ar.size,
|
||||
o_arburst = axi_if.ar.burst,
|
||||
o_arlock = axi_if.ar.lock,
|
||||
o_arcache = axi_if.ar.cache,
|
||||
o_arprot = axi_if.ar.prot,
|
||||
o_arvalid = axi_if.ar.valid,
|
||||
i_arready = axi_if.ar.ready,
|
||||
|
||||
i_rid = axi_if.r.id,
|
||||
i_rdata = axi_if.r.data,
|
||||
i_rresp = axi_if.r.resp,
|
||||
i_rlast = axi_if.r.last,
|
||||
i_rvalid = axi_if.r.valid,
|
||||
o_rready = axi_if.r.ready,
|
||||
|
||||
o_awid = axi_if.aw.id,
|
||||
o_awaddr = axi_if.aw.addr,
|
||||
o_awlen = axi_if.aw.len,
|
||||
o_awsize = axi_if.aw.size,
|
||||
o_awburst = axi_if.aw.burst,
|
||||
o_awlock = axi_if.aw.lock,
|
||||
o_awcache = axi_if.aw.cache,
|
||||
o_awprot = axi_if.aw.prot,
|
||||
o_awvalid = axi_if.aw.valid,
|
||||
i_awready = axi_if.aw.ready,
|
||||
|
||||
o_wid = axi_if.w.id,
|
||||
o_wdata = axi_if.w.data,
|
||||
o_wstrb = axi_if.w.strb,
|
||||
o_wlast = axi_if.w.last,
|
||||
o_wvalid = axi_if.w.valid,
|
||||
i_wready = axi_if.w.ready,
|
||||
|
||||
i_bid = axi_if.b.id,
|
||||
i_bresp = axi_if.b.resp,
|
||||
i_bvalid = axi_if.b.valid,
|
||||
o_bready = axi_if.b.ready,
|
||||
)
|
||||
|
||||
# Add sources
|
||||
basedir = os.path.join("CDIM", "mycpu")
|
||||
self.platform.add_source_dir(basedir)
|
||||
platform.add_verilog_include_path(basedir)
|
||||
|
||||
def set_reset_address(self, reset_address):
|
||||
# Hardcoded reset address.
|
||||
assert reset_address == 0x1fc0_0000
|
||||
self.reset_address = reset_address
|
||||
|
||||
def bios_map(self, addr, cached):
|
||||
# We can't access beyond KSEG0/1 in BIOS
|
||||
assert addr < 0x2000_0000
|
||||
if cached:
|
||||
return addr + 0x8000_0000
|
||||
else:
|
||||
return addr + 0xa000_0000
|
||||
|
||||
def do_finalize(self):
|
||||
self.specials += Instance("mycpu_top", **self.cpu_params)
|
44
litex/soc/cores/cpu/cdim/crt0.S
Normal file
44
litex/soc/cores/cpu/cdim/crt0.S
Normal file
|
@ -0,0 +1,44 @@
|
|||
.global main
|
||||
.global isr
|
||||
.global _start
|
||||
|
||||
_start:
|
||||
j crt_init
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
nop
|
||||
|
||||
crt_init:
|
||||
la $sp, _fstack
|
||||
|
||||
data_init:
|
||||
la $t0, _fdata
|
||||
la $t1, _edata
|
||||
la $t2, _fdata_rom
|
||||
data_loop:
|
||||
beq $t0, $t1, data_done
|
||||
lw $t3, 0($t2)
|
||||
sw $t3, 0($t0)
|
||||
addiu $t0, $t0,4
|
||||
addiu $t2, $t2,4
|
||||
b data_loop
|
||||
data_done:
|
||||
|
||||
bss_init:
|
||||
la $t0, _fbss
|
||||
la $t1, _ebss
|
||||
bss_loop:
|
||||
beq $t0, $t1, bss_done
|
||||
sw $zero, 0($t0)
|
||||
addiu $t0, $t0, 4
|
||||
b bss_loop
|
||||
bss_done:
|
||||
|
||||
la $t9, main
|
||||
jalr $t9
|
||||
inf_loop:
|
||||
b inf_loop
|
45
litex/soc/cores/cpu/cdim/irq.h
Normal file
45
litex/soc/cores/cpu/cdim/irq.h
Normal file
|
@ -0,0 +1,45 @@
|
|||
#ifndef __IRQ_H
|
||||
#define __IRQ_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include "system.h"
|
||||
#include "generated/soc.h"
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
|
||||
static inline unsigned int irq_getie(void)
|
||||
{
|
||||
return 0; /* FIXME */
|
||||
}
|
||||
|
||||
static inline void irq_setie(unsigned int ie)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
static inline unsigned int irq_getmask(void)
|
||||
{
|
||||
return (1 << UART_INTERRUPT); // FIXME
|
||||
}
|
||||
|
||||
static inline void irq_setmask(unsigned int mask)
|
||||
{
|
||||
/* TODO */
|
||||
}
|
||||
|
||||
static inline unsigned int irq_pending(void)
|
||||
{
|
||||
/* TODO */
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __IRQ_H */
|
19
litex/soc/cores/cpu/cdim/system.h
Normal file
19
litex/soc/cores/cpu/cdim/system.h
Normal file
|
@ -0,0 +1,19 @@
|
|||
#ifndef __SYSTEM_H
|
||||
#define __SYSTEM_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
__attribute__((unused)) static void flush_cpu_icache(void){}; /* No instruction cache */
|
||||
__attribute__((unused)) static void flush_cpu_dcache(void){}; /* No instruction cache */
|
||||
void flush_l2_cache(void);
|
||||
|
||||
void busy_wait(unsigned int ms);
|
||||
void busy_wait_us(unsigned int us);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif /* __SYSTEM_H */
|
Loading…
Reference in a new issue