皋陶 发表于 2020-8-23 11:45:17

SCR1(RISC-V)介绍

本帖最后由 皋陶 于 2020-8-26 11:56 编辑

https://riscv.org/risc-v-cores/


百度了一下,Solderpad Hardware License v. 0.51许可证和Apache2.0软件许可证相关联,以它为基础但它包含了更多的ip。SCR1 的体系结构是RISC-V ,版本 user spec2.2, privileged spec 1.10
github上地址 https://github.com/syntacore/scr1
Key features
[*]RV32I|E ISA
[*]Machine privilege mode
[*]2 to 4 stage pipeline
[*]32-bit AXI4/AHB-Lite external interface
[*]Integrated IRQ controller and advanced debug
[*]Optimized for area and power
[*]Written in SystemVerilog
[*]Features a number of configurable parameters

For more information, see docs/scr1_eas.pdf.
打开scr1_eas.pdf,来聊聊软件相关部分,而RTL code不在我的工作范围中。
编译用版本 gnu-mcu-eclipse-riscv-none-gcc-8.2.0-2.2-20190521-0004 ,可选-LTO,使得 code size 小幅压缩。
对于我来说,它是个纯CPU替换,完全可以替ARM7 ARM926这个级别CPU, 有一块TCM ,最大可以64k,没有MMU。
RVC完美支持,(而picoRV32 在压缩指令上就是个坑)。
privilege仅有Machine,在一般soc平台中使用应该够了。
内部包括一个Timer和中断控制器(IPIC),IPIC可以替换掉ARM PrimeCell Vectored Interrupt Controller(PL192)的功能。
这个Timer可以选择 base 外部晶振 ,在freertos将它用于tick。
1,mstatus中,MIE位应利用mret指令enable interrupt,MPIE位应由硬件维护为1b'1,MPP位硬件强制拉线到2b'11
在exception/inerrupt发生时,硬件写mie=0 (disable interrupt),并且让mpie保存之前mie。
而在从exception/interrupt返回时,软件调用mret指令,mpie重写mie,大部分情况是enable interrupt。
所以想让mpie为0,除了软件写mpie=0之外,只有一种方法,就是软件写mie=0,然后发生了Exception 。
这里暂不讨论exception返回和中断嵌套。另外,其他所有位都没进行设计。

2,mie中,MSIE用于触发软中断和clear软中断,MTIE 用于enable/disable CPU timer interrupt,MEIE用于enable/disable SOC上的外部中断

3,mtvec,系统默认为mtvec=0x1c0,这是exception/interrupt的跳转地址,启动第一步应重写mtvec寄存器,指向你的trap代码地址,但在代码和ld里还是要保留0x1c0地址。trap地址要 .align    6对齐,base地址只有高26位。
这里有两种跳转方法,mode=0,是CPU直接跳转到base地址;mode=1,是利用base地址+4xcause进行跳转,这个方法更好,效率更高。软件要建立一个vector table,每个table项是个跳转指令,位置对应于cause寄存器,这里可以参考以下代码
https://github.com/syntacore/scr1/blob/master/sim/tests/vectored_isr_sample/v_isr_sample.S
把trap代码放入TCM当然是效率最高的办法。
但是要注意当编译选择压缩指令时 ,避免vector table被编译成16位指令。可以在你 vector table前后增加指示符option,这样保证vector table永远是非压缩的,而其他位置就根据编译选项来了。
    .option push
    .option norvc

    .align    6
trap_entry:

    j

   .option pop

4,mcause可以用于查询exception和Interrupt来源


5,TIMER_CTRL 寄存器,enable/disable timer,和选择时钟来源
      TIMER_DIV 寄存器,填写除频值获得时间单位,比如我是选择外部24M晶振,timer_ctrl写3,timer_div写23,timer base为24M/(23+1) = 1us
      MTIME/MTIMEH ,reset之后,timer value = 0
   MTIMECMP/MTIMECMPH ,设定timer interrupt触发值
    TIMER_BASE =0x490000 我的系统使用了默认地址
Memory-mapped CSRs do not support byte and halfword access, an
corresponding attempt will cause a load/store access fault exception.Timer memory-mapped CSRs addresses are given below relative to the
TIMER_BASE = SCR1_TIMER_ADDR_PATTERN (see SCR1 configurable
options).
timer寄存器地址属于memory-mapped csrs(MMIO),在使用lb lh sb sh指令时产生exception。只有CPU 内部bus上的MMIO才会发exception,如果是AHB AHP上的并不会产生exception,但也许会有数据错误,要小心。
timer base地址可以配置。
[标准的CSRs是12位地址0x000~0xFFF,寄存器指令csrrs/csrrc/csrrw就能访问这么大范围。而SCR1 timer使用的是总线上地址,访问方法和io访问一致,使用lw/sw指令]
6,IPIC base地址在0xbf0 ,共8个寄存器

前四个用于获取状态,后四个用于设定状态。
IPIC_CISV    返回当前isr 编号,共支持16个interrupt,从0~0xf,而0x10代表无任何interrupt源被触发IPIC_CICSR    返回当前interrupt状态,就两个bit,一个是interrupt pengding状态,一个是interrupt enable状态IPIC_IPR    返回当前是哪些个源在pendingIPIC_ISVR    返回当前是哪个源正在触发,实际和IPIC_CISV作用一样,一个按bit map显示,一个按编号显示IPIC_EOI    ISR结束时调用,clear 中断,并更新前四个状态寄存器IPIC_SOI    ISR开始调用,更新前四个状态寄存器IPIC_IDX    配合IPIC_ICSR,在初始化中断源时,填写其number。IPIC_ICSR    配合IPIC_IDX,在初始化中断源时,设定中断触发方式和开关。
举例初始化某中断源,其 number = IrqNo
write_csr(IPIC_IDX,IrqNo);
write_csr(IPIC_ICSR,(IPIC_ICSR_IE | IPIC_ICSR_IM));Write access to the IPIC control status registers is implemented only through
the use of the CSRRW(I) instructions, the CSRRS(I) and CSRRC(I) instructions
are not supported.
IPIC的操作 ,不能使用csrrs和csrrc,只能使用csrrw,同时扩展到立即数指令。
注意其他csr伪指令都是以上三对指令的简化应用。
7,Reset
Core begins instruction fetch at address 0x200
General-purpose registers are reset to zero
本篇完,感谢关注:RISC-V单片机中文网
页: [1]
查看完整版本: SCR1(RISC-V)介绍