~600行ANSI C代码实现RISC-V CPU核
今天在GitHub上看到一个C语言项目,用大约600行代码实现了一个RISC-V CPU核,甚为感叹,分享一下。不管是学习C,还是学习RISC-V,这个项目都有非常高的学习价值,开源万岁!
rv
用 ANSI C 编写的RISC-V CPU 内核。
特征:
- RV32IMC用户级实现
- 通过 riscv 测试中所有支持的测试
- ~600 行代码
- 不使用任何大于 32 位的整数类型,即使对于乘法也是如此
- 简单 API(两个函数,加上您提供的两个内存回调函数)
- 无内存分配
应用程序接口
/* Memory access callbacks: data is input/output, return RV_BAD on fault, 0 otherwise */
typedef rv_res (*rv_store_cb)(void *user, rv_u32 addr, rv_u8 data);
typedef rv_res (*rv_load_cb)(void *user, rv_u32 addr, rv_u8 *data);/* Initialize CPU. */
void rv_init(rv *cpu, void *user, rv_load_cb load_cb, rv_store_cb store_cb);/* Single-step CPU. Returns 0 on success, one of RV_E* on exception. */
rv_u32 rv_step(rv *cpu);
用法
#include <stdio.h>
#include <string.h>#include "rv.h"rv_res load_cb(void *user, rv_u32 addr, rv_u8 *data) {if (addr - 0x80000000 > 0x10000) /* Reset vector is 0x80000000 */return RV_BAD;*data = ((rv_u8 *)(user))[addr - 0x80000000];return RV_OK;
}rv_res store_cb(void *user, rv_u32 addr, rv_u8 data) {if (addr - 0x80000000 > 0x10000)return RV_BAD;((rv_u8 *)(user))[addr - 0x80000000] = data;return RV_OK;
}rv_u32 program[2] = {/* _start: */0x02A88893, /* add a7, a7, 42 */0x00000073 /* ecall */
};int main(void) {rv_u8 mem[0x10000];rv cpu;rv_init(&cpu, (void *)mem, &load_cb, &store_cb);memcpy((void *)mem, (void *)program, sizeof(program));while (rv_step(&cpu) != RV_EECALL) {}printf("Environment call @ %08X: %u\n", cpu.pc, cpu.r[17]);return 0;
}
为rv编译程序
使用 riscv-gnu-toolchain 工具链和 rv链接脚本。
建议使用gcc命令行:
riscv64-unknown-elf-gcc example.S -nostdlib -nostartfiles -Tlink.ld -march=rv32imc -mabi=ilp32 -o example.o -e _start -g -no-pie
然后用obj工具将0x80000000起始的二进制代码生成能被rv加载的二进制文件:
riscv64-unknown-elf-objcopy -g -O binary example.o example.bin
支持的指令列表
参见 支持指令列表。
公众号 | FunIO
微信搜一搜 “funio”,发现更多精彩内容。
个人博客 | blog.boringhex.top
相关文章:
~600行ANSI C代码实现RISC-V CPU核
今天在GitHub上看到一个C语言项目,用大约600行代码实现了一个RISC-V CPU核,甚为感叹,分享一下。不管是学习C,还是学习RISC-V,这个项目都有非常高的学习价值,开源万岁! rv 用 ANSI C 编写的RISC…...
【从零学习python 】55.Python中的序列化和反序列化,JSON与pickle模块的应用
文章目录 序列化和反序列化JSON模块pickle模块进阶案例 序列化和反序列化 通过文件操作,我们可以将字符串写入到一个本地文件。但是,如果是一个对象(例如列表、字典、元组等),就无法直接写入到一个文件里,需要对这个对象进行序列…...
【C++】详解内存中的堆和栈
2023年8月20日,周日早上 感觉很多东西还没吃透,很多疑问还没解决。 这篇文章可能会不定期更新。 还没解释为什么栈的空间有限,而堆的空间很大 还没解释栈和堆在内存中的位置 ...... 目录 怎么申请栈空间语法举例说明 怎么申请堆空间语法…...
QCustomPlot横坐标为毫秒级的时间轴数据展示的实时刷新数据功能
头文件 #ifndef WIDGET_H #define WIDGET_H#include <QWidget> #include <QTimer>QT_BEGIN_NAMESPACE namespace Ui { class Widget; } QT_END_NAMESPACEclass Widget : public QWidget {Q_OBJECTpublic:Widget(QWidget *parent nullptr);~Widget();int realtime…...
STM32/AT32 MCO管脚输出时钟配置
前言:最近在学以太网通讯,发现RMII接口配置的时钟管脚有MCU自己输出,想要看看是怎么输出的,对此进行记录 1、交接项目项目上使用的是PA8管脚来输出时钟50MHZ,提供给上面refclk。 先看手册 PA8的复用功能具备将MCU时钟…...
“SRP模型+”多技术融合在生态环境脆弱性评价模型构建、时空格局演变分析与RSEI 指数的生态质量评价
近年来,国内外学者在生态系统的敏感性、适应能力和潜在影响等方面开展了大量的生态脆弱性研究,他们普遍将生态脆弱性概念与农牧交错带、喀斯特地区、黄土高原区、流域、城市等相结合,评价不同类型研究区的生态脆弱特征,其研究内容…...
【大虾送书第六期】搞懂大模型的智能基因,RLHF系统设计关键问答
目录 ✨1、RLHF是什么? ✨2、RLHF适用于哪些任务? ✨3、RLHF和其他构建奖励模型的方法相比有何优劣? ✨4、什么样的人类反馈才是好的反馈 ✨5、RLHF算法有哪些类别,各有什么优缺点? ✨6、RLHF采用人类反馈会带来哪些局…...
超越函数界限:探索JavaScript函数的无限可能
🎬 岸边的风:个人主页 🔥 个人专栏 :《 VUE 》 《 javaScript 》 ⛺️ 生活的理想,就是为了理想的生活 ! 目录 📚 前言 📘 1. 函数的基本概念 📟 1.1 函数的定义和调用 📟 1.2 …...
PHP实现轻量级WEB服务器接收HTTP提交的RFID刷卡信息并回应驱动读卡器显示播报语音
本示例使用的读卡器:RFID网络WIFI无线TCP/UDP/HTTP可编程二次开发读卡器POE供电语音-淘宝网 (taobao.com) <?php mb_http_output(utf-8); $port88; $socket socket_create(AF_INET, SOCK_STREAM, SOL_TCP); $bool socket_bind($socket, "0.0.0.0",…...
Neo4j之with基础
WITH 语句在 Cypher 查询中用于将之前的查询结果传递给后续的查询操作。它可以用来控制查询的流程,并且常常与其他语句如 MATCH、RETURN、CREATE、DELETE 等一起使用。以下是一些常用的示例和解释: 基本用法: MATCH (p:Person) WITH p RETU…...
60页数字政府智慧政务大数据资源平台项目可研方案PPT
导读:原文《60页数字政府智慧政务大数据资源平台项目可研方案PPT》(获取来源见文尾),本文精选其中精华及架构部分,逻辑清晰、内容完整,为快速形成售前方案提供参考。 项目需求分析 项目建设原则和基本策略…...
循环神经网络RNN完全解析:从基础理论到PyTorch实战
目录 一、循环神经网络全解1.1 什么是循环神经网络网络结构工作原理数学模型RNN的优缺点总结 1.2 循环神经网络的工作原理RNN的时间展开数学表述信息流动实现示例梯度问题:梯度消失和爆炸总结 1.3 循环神经网络的应用场景文本分析与生成1.3.1 自然语言处理1.3.2 机器…...
【SA8295P 源码分析】52 - 答疑之 QNX 创建镜像、Android修改CMDLINE
【SA8295P 源码分析】52 - 答疑之 QNX 创建镜像、Android修改CMDLINE 一、QNX 侧创建 img 镜像二、QNX 侧指定只编译某一个版本三、Android定制修改selinux权限,user版本采用enforcing,userdebug版本permissive系列文章汇总见:《【SA8295P 源码分析】00 - 系列文章链接汇总》…...
网络安全法律
立法的必要性:网络渗透,网络入侵,网络诈骗,网上钓鱼侵犯知识产权,宣传恐怖主义,极端主义等伤害共鸣利益的行为越发猖狂 信息系统运维安全管理规定(范文)| 资料 过程: 14-16 草案初…...
Redis缓存问题(穿透, 击穿, 雪崩, 污染, 一致性)
目录 1.什么是Redis缓存问题? 2.缓存穿透 3.缓存击穿 4.缓存雪崩 5.缓存污染(或满了) 5.1 最大缓存设置多大 5.2 缓存淘汰策略 6.数据库和缓存一致性 6.1 4种相关模式 6.2 方案:队列重试机制 6.3 方案:异步更新缓…...
网络时代拟态环境的复杂化
信息在网络上的制作、编码、传播机制和传统媒介有本质的区别,即传播者和 受传者的角色交叉,而且互联网本身可看作另一个有别于现实环境的虚拟世界,因 此网络媒介所营造出的拟态环境在一定程度上独立于传统大众传播的拟态环境。 一个是传统…...
湘潭大学 湘大 XTU OJ 1055 整数分类 题解(非常详细)
链接 整数分类 题目 Description 按照下面方法对整数x进行分类:如果x是一个个位数,则x属于x类;否则将x的各位上的数码累加,得到一个新的x,依次迭代,可以得到x的所属类。比如说24,246&#…...
什么是视频的编码和解码
这段描述中,视频解码能力和视频编码能力指的是不同的处理过程。视频解码是将压缩过的视频数据解开并还原为可播放的视频流,而视频编码是将原始视频数据压缩成更小的尺寸,以减少存储空间和传输带宽。在这个上下文中,解码能力和编码…...
LeetCode 2681. Power of Heroes【排序,数学,贡献法】2060
本文属于「征服LeetCode」系列文章之一,这一系列正式开始于2021/08/12。由于LeetCode上部分题目有锁,本系列将至少持续到刷完所有无锁题之日为止;由于LeetCode还在不断地创建新题,本系列的终止日期可能是永远。在这一系列刷题文章…...
AVL树的讲解
算法拾遗三十八AVL树 AVL树AVL树平衡性AVL树加入节点AVL删除节点AVL树代码 AVL树 AVL树具有最严苛的平衡性,(增、删、改、查)时间复杂度为O(logN),AVL树任何一个节点,左树的高度和右树的高度差…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...
页面渲染流程与性能优化
页面渲染流程与性能优化详解(完整版) 一、现代浏览器渲染流程(详细说明) 1. 构建DOM树 浏览器接收到HTML文档后,会逐步解析并构建DOM(Document Object Model)树。具体过程如下: (…...
MySQL 8.0 OCP 英文题库解析(十三)
Oracle 为庆祝 MySQL 30 周年,截止到 2025.07.31 之前。所有人均可以免费考取原价245美元的MySQL OCP 认证。 从今天开始,将英文题库免费公布出来,并进行解析,帮助大家在一个月之内轻松通过OCP认证。 本期公布试题111~120 试题1…...
用docker来安装部署freeswitch记录
今天刚才测试一个callcenter的项目,所以尝试安装freeswitch 1、使用轩辕镜像 - 中国开发者首选的专业 Docker 镜像加速服务平台 编辑下面/etc/docker/daemon.json文件为 {"registry-mirrors": ["https://docker.xuanyuan.me"] }同时可以进入轩…...
CSS设置元素的宽度根据其内容自动调整
width: fit-content 是 CSS 中的一个属性值,用于设置元素的宽度根据其内容自动调整,确保宽度刚好容纳内容而不会超出。 效果对比 默认情况(width: auto): 块级元素(如 <div>)会占满父容器…...
「全栈技术解析」推客小程序系统开发:从架构设计到裂变增长的完整解决方案
在移动互联网营销竞争白热化的当下,推客小程序系统凭借其裂变传播、精准营销等特性,成为企业抢占市场的利器。本文将深度解析推客小程序系统开发的核心技术与实现路径,助力开发者打造具有市场竞争力的营销工具。 一、系统核心功能架构&…...
书籍“之“字形打印矩阵(8)0609
题目 给定一个矩阵matrix,按照"之"字形的方式打印这个矩阵,例如: 1 2 3 4 5 6 7 8 9 10 11 12 ”之“字形打印的结果为:1,…...
Vue3中的computer和watch
computed的写法 在页面中 <div>{{ calcNumber }}</div>script中 写法1 常用 import { computed, ref } from vue; let price ref(100);const priceAdd () > { //函数方法 price 1price.value ; }//计算属性 let calcNumber computed(() > {return ${p…...
2.3 物理层设备
在这个视频中,我们要学习工作在物理层的两种网络设备,分别是中继器和集线器。首先来看中继器。在计算机网络中两个节点之间,需要通过物理传输媒体或者说物理传输介质进行连接。像同轴电缆、双绞线就是典型的传输介质,假设A节点要给…...
【大模型】RankRAG:基于大模型的上下文排序与检索增强生成的统一框架
文章目录 A 论文出处B 背景B.1 背景介绍B.2 问题提出B.3 创新点 C 模型结构C.1 指令微调阶段C.2 排名与生成的总和指令微调阶段C.3 RankRAG推理:检索-重排-生成 D 实验设计E 个人总结 A 论文出处 论文题目:RankRAG:Unifying Context Ranking…...
