Skip to content

XuanTongYao/XT_RISC-V_Soc

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

132 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

XT_RISC-V 微控制器

个人学习作品,适合初学者食用。

一个极其简易的RV32I_Zicsr_Sdext指令集单核MCU,所有用户级与特权级指令支持,仅运行在机器模式或外部调试模式。

  1. RTL包含了所有Verilog代码,顶层文件在这里
  2. firmware_lib包含了本MCU的固件库,有C版本Rust版本
  3. rust_release/debug是rust程序默认的构建输出位置
  4. demo是C语言的示例程序代码,同时也是C程序构建脚本默认寻找主程序源文件的位置
  5. ACT4包含了架构认证测试相关的内容(最新的ACT4框架)

RISC-V架构认证测试(ACT4框架)

处理器内核消耗约2061个LUT4(参考)

PLL等IP核适用于LCMXO2-4000HC-4MG132CFPGA器件,IP核仅包含ipxlpc文件,请使用开发工具重新生成verilog文件。外设基本是围绕该核心板设计的,但是处理器内核可以很方便移植到其他FPGA上。

目录

MCU特性

架构图

地址映射

RV32I_Zicsr_Sdext内核

  • 三级流水线:取指、译码、执行
  • FENCE指令空实现(等效NOP)
  • ECALL指令跳转异常
  • WFI指令暂停流水线
  • 精简的CSR寄存器(详见RTL代码)
  • 支持外部调试(最小 RISC-V 调试规范)
  • 调试模式时始终禁用中断
  • 可配置为RV32E内核

异常/中断控制器

  • 支持标准中断:定时器中断、软件中断、外部中断
  • 所有外部中断,由自定义的外部中断控制器进行重定向,完成中断向量跳转
  • 不支持中断嵌套

调试模块

  • 遵循最小 RISC-V 调试规范
  • Jtag调试传输模块
  • 支持查询与控制内核运行状态(停止/恢复)
  • 在内核停止时可执行访问寄存器抽象命令,可访问所有允许软件访问的寄存器
  • 允许复位MCU上的所有非调试逻辑

时钟树

时钟频率可根据实际情况修改。

  • 内部振荡器频率2.15MHz,作为时钟监视器的独立时钟源
  • 时钟监视器监控PLL状态,若出现脱锁将自动重置PLL并发出全局RST信号
  • 时钟监视器可设置上电等待时间、PLL锁定等待时间,拥有一个外部重置源,通过按钮可重置系统
  • PLL输入时钟频率12MHz
  • 核心、高速总线、WISHBONE总线位于同一时钟域,基准频率12MHz
  • 机器计时器固定频率1MHz
  • UART采样频率153.846KHz,过采样率为8波特率19200误差0.16%
  • 低速总线频率100KHz

其他核心模块

外部中断控制器

  • 支持最多32条电平敏感型外部中断
  • 无优先级配置,但中断号越低越优先,0号外部中断先于其他外部中断触发
  • 不直接处理中断清零,通过读写外设寄存器清零

MTime和Mtimecmp(机器计时器)

  • 无跨时钟域时序惩罚
  • 硬件不处理非原子读取一致性问题,通过软件处理

外设列表

挂载于XT_HB32总线

  1. 自举控制器
  2. 外部中断控制器
  3. 64bit机器计时器
  4. UART通信接口
  5. 软件中断寄存器
  6. 复用GPIO

挂载于XT_LB总线

  1. 开关(3)与按钮(4)
  2. 8位LED灯
  3. 硬件解码7段LED数码管X2

挂载于WISHBONE总线

该总线的外设为EFB硬核

  1. 左PLL动态配置 TODO
  2. 右PLL动态配置 TODO
  3. 1号I2C接口
  4. 2号I2C接口
  5. SPI接口
  6. 16bit定时器/计数器
  7. 程序存储Flash

XT高速总线

XT_HB是内核访问外部数据必经的通道,承担内存地址映射、互联其他总线的职责。

  • 主设备通过直接访存接口来访问总线
  • 主设备还可以通过响应接口查询响应信息:仲裁准予、读写停顿请求等
  • 从设备也通过接口连接总线
  • 读与写独立,如果两个主设备读写不冲突,可以同时进行,读写启用信号本身就是总线请求信号
  • 如果对同一个从设备同时读写,从设备自行决定读取旧数据还是通过旁路读取写入数据。(通常是读取旧数据)

XT_HB读写时序

仲裁器使用轮询仲裁器,读写仲裁是独立的。

地址分配与MMIO

一个完整访问地址由两部分组成:高位的设备识别符,低位的偏移量。识别符占用位数是参数配置的,决定了最多能区分多少设备。偏移量占用位数构成固定大小寻址空间。

每个设备至少占用一个识别符,可以连续占用多个,占用的第一个识别符是基准识别符基准识别符与全0偏移量拼接为设备的基地址基地址必须在识别符上对齐。

  • 如果设备只占用一个识别符,可以直接使用偏移量作为访问地址。
  • 如果设备连续占用多个识别符,偏移量寻址空间不足,使用完整地址的识别符部分减去基准识别符,再与偏移量拼接得到访问地址。

完整地址示例:

设备识别符 偏移量 说明
001 0000000000000 基地址/访问地址
101 0000000000000 基地址/访问地址
101 0000011100001 访问地址

设备也可以是其他总线,XT_HB只与各个抽象的设备进行数据交换,其他总线内部自行控制从设备。

为避免浪费过多的XT_HB识别符,将大多数高速外设挂载到32bit对齐总线上。对齐总线本身只占用一个识别符,上面的外设寄存器地址都是字对齐(32bit对齐)的。在32bit对齐总线内部,也使用识别符加偏移量的方式来分配地址,但每个设备只能占用一个识别符。

对齐总线对时序要求严格,在上面的设备,必须能够在一个周期完成写入,在读地址有效的下一个周期必须输出数据。

等待机制

总线提供了一个访问等待机制,从设备激活finish信号来告知此次访问已完成,如果从设备支持无等待访问,可以把finish硬连线到激活状态。

当主设备未被仲裁准予,或者访问未完成时,总线向主设备激活读写停顿请求stall,读写停顿也是独立的。当主设备收到finish后,如果不再对总线进行访问,它必须立刻响应此次finish,并撤销对应的读写请求,避免重复读写导致的副效应。从设备的读写副效应,只应该在激活finish信号时发生一次。

CPU内核在EX阶段访存需要流水线停顿,如果访问其他总线,则停顿周期会更长,XT_HB接收其他总线的finish信号。

XT低速总线

XT_HB通过CDC_MCP_Formulation模块跨时钟域,与XT_LB交换数据。

同样使用识别符+偏移量的地址分配策略,每个从设备平分地址空间,从设备只进行部分地址解码。

使用最简单的设计,半双工通信。若读写同时发生,先读后写。总线只输出部分地址。从机的读数据输出始终使用组合逻辑读取,不经过输出寄存器。总线内部根据识别符产生写片选独热码,分别路由到不同的从机,固定使用一个周期完成写入。

XT_LB读写时序

BOOTSTRAP

自举加载流程:

  1. 初始化加载ROM中的bootstrap程序
  2. 把FLASH中的数据逐个拷贝到指令存储器RAM中
  3. 指令地址跳转到0
  4. 触发脉冲将MUX切换到指令存储器RAM

编译工具链

SiFive riscv64-unknown-elf-gcc-8.3.0已停止更新但程序尺寸最小,自举程序由此编译

riscv-none-elf-gcc-xpack标准最新,默认情况下推荐使用

rust需要安装riscv32i-unknown-none-elf编译目标,同时为了在rust中使用异常处理函数,请选择nightly版本。

程序下载

1页 == 16字节 1 page == 16 byte

最大页数由Flash决定,当前器件为767

综合前请使用自举程序字符串文件重新生成rom_bootrom_strIP核

emoji提示💾下载 🛫启动 🔛开始 ✅完成 ❌错误

  1. 将下载开关(拨码开关1)拨动到高电平位置
  2. 连接电脑并打开串口程序
  3. 选择下载操作;操作提示:💾:0x56,🛫:0xF1
  4. 发送程序的页数(共两字节,先高位);操作提示:Len=
  5. 确认开始下载;操作提示:🔛:0x78
  6. 发送程序二进制文件(确保已经补零对齐到页长度)
  7. 确认下载完成;操作提示:✅:0x57
  8. 启动程序;操作提示:💾:0x56,🛫:0xF1

alt text

引脚与GPIO

引脚图来源于该核心板的参考资料

硬件对照图

每个GPIO可以从四个复用功能中,选中某一个复用功能进行复用,允许多个引脚复用相同的功能

当多个端口使用相同的输入功能时,得到的结果为它们的逻辑或。当多个端口使用相同的输出功能时,复用功能将在多个端口输出

功能前有"~"的表示低电平有效

GPIO功能复用

TODO_LIST

  • 其他异常处理函数
  • 修改XT_HB的时序,适配单周期原子读写的外设
  • 用一个小型控制器来加载Flash,而不是ROM,ROM太占用资源了 已通过高度优化自举程序解决
  • 系统外设整合到一个模块中
  • 为对齐的寄存器划分单独的地址空间,更加节省资源
  • DMA控制器
  • 尝试实现RV32C混合执行,把RV32C解码成RV32I指令
  • Rust重写外设固件库
  • 平台级中断控制器PLIC(考虑到资源消耗,可能性不大)
  • 调试器支持
  • FreeRTOS支持 不再考虑FreeRTOS,未来将支持Rust异步运行时(Embassy框架)
  • 跑分(低端设备没必要吧)

  • 这综合器真是死了棍木了,参数无默认值有警告,写了= '{default: 0}默认值又变成类型不匹配警告(实际上是匹配的),直接改成字面量传入又没有警告了
  • 害,这个核心板的下载程序有问题,EBR和UFM都无法初始化,JTAG被绑定到中介下载芯片上了,也无法使用逻辑分析仪等工具,唯一的下载方式就是使用模拟的USB大容量设备,并且只支持jed文件。

About

一个极其简易的RV32I指令集单核MCU,用户级与特权级支持,仅运行机器模式。

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors