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:
Jiaxun Yang 2024-06-17 14:56:05 +01:00
parent bffbb4ffea
commit b7ed16b190
No known key found for this signature in database
GPG Key ID: 43710C7DD77729C3
6 changed files with 242 additions and 0 deletions

View File

@ -0,0 +1 @@
from litex.soc.cores.cpu.cdim.core import CDIM

View File

@ -0,0 +1,4 @@
.section .text, "ax", @progbits
.global boot_helper
boot_helper:
jr $a3

View 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)

View 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

View 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 */

View 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 */